All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.anysoft.context.Source Maven / Gradle / Ivy

There is a newer version: 1.6.17
Show newest version
package com.anysoft.context;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.anysoft.util.IOTools;
import com.anysoft.util.Properties;
import com.anysoft.util.Reportable;
import com.anysoft.util.Watcher;
import com.anysoft.util.WatcherHub;
import com.anysoft.util.XmlElementProperties;
import com.anysoft.util.XmlTools;

/**
 * 通用配置来源
 * 
 * @author duanyy
 *
 * @param 
 * 
 * @since 1.5.0
 * 
 * @version 1.5.2 [20141017 duanyy] 
* - 实现Reportable接口
* * @version 1.6.4.4 [20150910 duanyy]
* - 增加获取当前缓存对象列表的接口
* - Report不在输出缓存对象列表
* * @version 1.6.4.20 [20151222 duanyy]
* - 根据sonar建议优化代码
* * @version 1.6.6.5 [20161121 duanyy]
* - 增加allChanged方法,以便通知Watcher所有对象已经改变
* * @version 1.6.7.9 [20170201 duanyy]
* - 采用SLF4j日志框架输出日志
*/ public abstract class Source implements Context,Watcher { /** * logger of log4j */ protected static final Logger logger = LoggerFactory.getLogger(Source.class); /** * Watcher Hub */ protected WatcherHub watcherHub = new WatcherHub(); // NOSONAR /** * 缓存的对象 */ protected Hashtable caches = new Hashtable(); // NOSONAR /** * 配置来源 */ protected List> sources = new ArrayList>(); // NOSONAR @Override public void configure(Element root, Properties props){ Properties p = new XmlElementProperties(root,props); NodeList children = XmlTools.getNodeListByPath(root, getContextName()); for (int i = 0 ; i < children.getLength() ; i ++){ Node n = children.item(i); if (n.getNodeType() != Node.ELEMENT_NODE){ continue; } Element e = (Element)n; try { Context source = newInstance(e, p,"module"); // NOSONAR if (source != null){ source.addWatcher(this); sources.add(source); } }catch (Exception ex){ logger.error("Can not create context instance,check your configuration.",ex); } } } /** * 获取当前的cache列表 * @return cache列表 */ public Collection current(){ return caches.values(); } /** * 创建实例 * * @param e XML配置根节点 * @param p 环境变量集 * @param attrName XML属性名 * @return Context */ public abstract Context newInstance(Element e, Properties p, String attrName); protected String getContextName(){ return "context"; } @Override public void close(){ caches.clear(); for (Context s:sources){ s.removeWatcher(this); IOTools.close(s); } sources.clear(); } @Override public O get(String id) { O found = caches.get(id); if (found == null){ synchronized (caches){ found = caches.get(id); if (found == null){ found = load(id); if (found != null){ caches.put(id, found); } } } } return found; } private O load(String id) { for (Context c:sources){ O found = c.get(id); if (found != null){ return found; } } return null; } @Override public void addWatcher(Watcher watcher) { watcherHub.addWatcher(watcher); } @Override public void removeWatcher(Watcher watcher) { watcherHub.removeWatcher(watcher); } @Override public void added(String id, O _data) { if (watcherHub != null){ watcherHub.added(id, _data); } } @Override public void removed(String id, O _data) { caches.remove(id); if (watcherHub != null){ watcherHub.removed(id, _data); } } @Override public void changed(String id, O _data) { caches.remove(id); if (watcherHub != null){ watcherHub.changed(id, _data); } } @Override public void allChanged(){ caches.clear(); if (watcherHub != null){ watcherHub.allChanged(); } } @Override public void report(Element xml) { if (xml != null) { xml.setAttribute("module", getClass().getName()); xml.setAttribute("ctxName", getContextName()); Document doc = xml.getOwnerDocument(); for (Context c : sources) { Element context = doc.createElement(getContextName()); c.report(context); xml.appendChild(context); } } } @Override public void report(Map json){ if (json != null){ json.put("module", getClass().getName()); json.put("ctxName", getContextName()); List contexts = new ArrayList(); // NOSONAR for (Context c:sources){ Map ctx = new HashMap(); // NOSONAR c.report(ctx); contexts.add(ctx); } json.put(getContextName(), contexts); } } }