Java tutorial
/** * GroupServiceImpl.java * * Copyright 2012 Niolex, Inc. * * Niolex licenses this file to you under the Apache License, version 2.0 * (the "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package org.apache.niolex.config.service.impl; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.niolex.config.bean.ConfigGroup; import org.apache.niolex.config.bean.ConfigItem; import org.apache.niolex.config.bean.SyncBean; import org.apache.niolex.config.config.AttachKey; import org.apache.niolex.config.core.CodeMap; import org.apache.niolex.config.core.MemoryStorage; import org.apache.niolex.config.core.PacketTranslater; import org.apache.niolex.config.dao.GroupDao; import org.apache.niolex.config.dao.ItemDao; import org.apache.niolex.config.event.ConfigEventDispatcher; import org.apache.niolex.config.service.AuthenService; import org.apache.niolex.config.service.GroupService; import org.apache.niolex.network.IPacketWriter; import org.apache.niolex.network.PacketData; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * @author <a href="mailto:xiejiyun@gmail.com">Xie, Jiyun</a> * @version 1.0.0 * @since 2012-7-5 */ @Service public class GroupServiceImpl implements GroupService { private static final Logger LOG = LoggerFactory.getLogger(GroupServiceImpl.class); /** * Use this field to sync with DB. */ private long lastSyncTime = 0; /** * Dispatch event to clients. */ @Autowired private ConfigEventDispatcher dispatcher; /** * Store all the configurations. */ @Autowired private MemoryStorage storage; /** * Do all the authentication works. */ @Autowired private AuthenService service; /** * The Dao managing config groups. */ @Autowired private GroupDao groupDao; /** * The Dao managing config items. */ @Autowired private ItemDao itemDao; /** * Override super method * * @see org.apache.niolex.config.service.GroupService#cliSubscribeGroup(java.lang.String, * org.apache.niolex.network.IPacketWriter) */ @Override public boolean cliSubscribeGroup(String groupName, IPacketWriter wt) { ConfigGroup group = storage.get(groupName); if (group != null) { // Authenticate Group Read. if (service.hasReadAuth(group, wt)) { wt.handleWrite(PacketTranslater.translate(group)); dispatcher.addListener(groupName, wt); // Add this group into set. Set<String> set = getCachedGroupSet(wt); set.add(groupName); return true; } else { // Has no right to read this group. wt.handleWrite(new PacketData(CodeMap.GROUP_NOA, groupName)); } } else { // Group not found. wt.handleWrite(new PacketData(CodeMap.GROUP_NOF, groupName)); } return false; } /** * Get the cached config group set from writer. * @param wt * @return */ private Set<String> getCachedGroupSet(IPacketWriter wt) { // This client may already has some groups, so we merge them. synchronized (wt) { Set<String> set = wt.getAttached(AttachKey.GROUP_SET); if (set == null) { set = new HashSet<String>(); // Attach group list. For close this client and remove listener. wt.attachData(AttachKey.GROUP_SET, set); } return set; } } /** * Override super method * @see org.apache.niolex.config.service.GroupService#cliSyncGroup(org.apache.niolex.config.bean.SyncBean, org.apache.niolex.network.IPacketWriter) */ @Override public void cliSyncGroup(SyncBean bean, IPacketWriter wt) { String groupName = bean.getGroupName(); ConfigGroup group = storage.get(groupName); if (group != null) { // Authenticate Group Read. if (service.hasReadAuth(group, wt)) { Map<String, Long> groupData = bean.getGroupData(); for (ConfigItem item : group.getGroupData().values()) { Long time = groupData.get(item.getKey()); if (time == null || time.longValue() < item.getUpdateTime()) { // This item is new at server side, so dispatch it. wt.handleWrite(PacketTranslater.translate(item)); } } } else { // Has no right to read this group. wt.handleWrite(new PacketData(CodeMap.GROUP_NOA, groupName)); } } else { // Group not found. wt.handleWrite(new PacketData(CodeMap.GROUP_NOF, groupName)); } } /** * Override super method * @see org.apache.niolex.config.service.GroupService#syncAllGroupsWithDB() */ @Override public void syncAllGroupsWithDB() { // Store the current DB time. long tmpTime = groupDao.loadDBTime(); // Load all the group names. List<ConfigGroup> allGroups = groupDao.loadAllGroups(); List<ConfigItem> allItems = itemDao.loadAllConfigItems(lastSyncTime); // Renew last sync time. lastSyncTime = tmpTime; allGroups = assembleGroups(allGroups, allItems); // Store new groups into memory storage. for (ConfigGroup conf : allGroups) { storeInternalGroup(conf); } } /** * Assemble config items into group config. * @param allGroups * @param allItems * @return the assembled groups */ private List<ConfigGroup> assembleGroups(List<ConfigGroup> allGroups, List<ConfigItem> allItems) { int j = 0, groupId = 0; ConfigGroup gConf = null; Map<String, ConfigItem> groupData = null; // item list must order by groupId for (ConfigItem item : allItems) { // group list must order by groupId if (item.getGroupId() != groupId) { // Find the correct group. while (j < allGroups.size()) { gConf = allGroups.get(j); // In case we can not found that group, that Id will be jumped. if (gConf.getGroupId() >= item.getGroupId()) { break; } ++j; } // Check whether we find it. if (gConf.getGroupId() == item.getGroupId()) { groupId = gConf.getGroupId(); groupData = gConf.getGroupData(); } else { // We can not find the group for this item at all. continue; } } groupData.put(item.getKey(), item); } return allGroups; } /** * Store this group config into memory storage. * Dispatch event only to clients connected to this server. * @param group */ private void storeInternalGroup(ConfigGroup conf) { List<ConfigItem> clist = storage.store(conf); if (clist != null) { // Fire event to notify clients. for (ConfigItem item : clist) { dispatcher.fireClientEvent(conf.getGroupName(), item); } } } /** * Override super method * @see org.apache.niolex.config.service.GroupService#svrSendDiff(org.apache.niolex.config.bean.ConfigItem) */ @Override public void svrSendDiff(ConfigItem diff) { String groupName = storage.findGroupName(diff.getGroupId()); if (groupName != null) { boolean b = storage.updateConfigItem(groupName, diff); if (b) { // This is from other server, so we will not fire it to any server. dispatcher.fireClientEvent(groupName, diff); } } else { LOG.warn("Config Diff received from other server but not found in local: {}", diff); } } /** * Override super method * @see org.apache.niolex.config.service.GroupService#svrSendGroup(java.lang.String) */ @Override public void svrSendGroup(String groupName) { ConfigGroup group = groupDao.loadGroup(groupName); if (group != null) { List<ConfigItem> allItems = itemDao.loadGroupItems(group.getGroupId()); if (allItems != null && allItems.size() != 0) { Map<String, ConfigItem> groupData = group.getGroupData(); for (ConfigItem item : allItems) { groupData.put(item.getKey(), item); } } storeInternalGroup(group); } } /** * Override super method * @see org.apache.niolex.config.service.GroupService#adminRefreshGroup(java.lang.String) */ @Override public String adminRefreshGroup(String groupName) { String s = null; ConfigGroup group = groupDao.loadGroup(groupName); if (group != null) { List<ConfigItem> allItems = itemDao.loadGroupItems(group.getGroupId()); if (allItems != null && allItems.size() != 0) { Map<String, ConfigItem> groupData = group.getGroupData(); for (ConfigItem item : allItems) { groupData.put(item.getKey(), item); } s = "Refresh Group Success."; } else { s = "This group has no config item."; } storeGroup(group); return s; } else { return "Group not found."; } } /** * Store this group config into memory storage. * @param group */ private void storeGroup(ConfigGroup conf) { List<ConfigItem> clist = storage.store(conf); if (clist != null) { // Fire event to notify clients. for (ConfigItem item : clist) { dispatcher.fireEvent(conf.getGroupName(), item); } } } /** * Override super method * @see org.apache.niolex.config.service.GroupService#addGroup(java.lang.String, org.apache.niolex.network.IPacketWriter) */ @Override public String addGroup(String groupName, IPacketWriter wt) { if (service.hasConfigAuth(wt)) { ConfigGroup group = groupDao.loadGroup(groupName); if (group == null) { // This group not exist, and this user has the right to add. if (groupDao.addGroup(groupName)) { // Group now added into DB, we need to load it into memory. group = groupDao.loadGroup(groupName); storage.store(group); dispatcher.fireAddEvent(groupName); return "Add group success."; } else { return "Failed to add due to DB error."; } } else { return "The group already exist."; } } else { return "You do not have the right to add group."; } } /** * Override super method * @see org.apache.niolex.config.service.GroupService#addItem(org.apache.niolex.config.bean.ConfigItem, org.apache.niolex.network.IPacketWriter) */ @Override public String addItem(ConfigItem item, IPacketWriter wt) { String groupName = storage.findGroupName(item.getGroupId()); if (groupName == null) { return "The group doesn't exist."; } if (service.hasConfigAuth(wt)) { int userId = service.getUserId(wt); item.setcUid(userId); item.setuUid(userId); if (itemDao.addConfig(item)) { // Config Item added into DB now. item = itemDao.getConfig(item.getGroupId(), item.getKey()); storage.updateConfigItem(groupName, item); dispatcher.fireEvent(groupName, item); return "Add item success."; } else { return "Failed to add due to DB error."; } } else { return "You do not have the right to add config item."; } } /** * Override super method * @see org.apache.niolex.config.service.GroupService#updateItem(org.apache.niolex.config.bean.ConfigItem, org.apache.niolex.network.IPacketWriter) */ @Override public String updateItem(ConfigItem item, IPacketWriter wt) { String groupName = storage.findGroupName(item.getGroupId()); if (groupName == null) { return "The group doesn't exist."; } if (service.hasConfigAuth(wt)) { int userId = service.getUserId(wt); ConfigItem newitem = storage.get(groupName).getGroupData().get(item.getKey()); if (newitem == null) { return "The item key doesn't exist."; } newitem.setuUid(userId); newitem.setValue(item.getValue()); if (itemDao.updateConfig(newitem)) { // Config Item added into DB now. item = itemDao.getConfig(item.getGroupId(), item.getKey()); storage.updateConfigItem(groupName, item); dispatcher.fireEvent(groupName, item); return "Update item success."; } else { return "Failed to update due to DB error."; } } else { return "You do not have the right to update config item."; } } }