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

com.alogic.load.Loader Maven / Gradle / Ivy

There is a newer version: 1.6.17
Show newest version
package com.alogic.load;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang3.StringUtils;
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.Configurable;
import com.anysoft.util.Factory;
import com.anysoft.util.IOTools;
import com.anysoft.util.JsonTools;
import com.anysoft.util.Properties;
import com.anysoft.util.Settings;
import com.anysoft.util.XmlElementProperties;
import com.anysoft.util.Reportable;
import com.anysoft.util.Watcher;
import com.anysoft.util.XMLConfigurable;
import com.anysoft.util.XmlTools;
import com.anysoft.util.resource.ResourceFactory;

/**
 * 通用装载框架
 * 
 * @author duanyy
 * @version 1.6.5.13 [20160612 duanyy] 
* - 增加对象过期判断功能
* * @version 1.6.7.9 [20170201 duanyy]
* - 采用SLF4j日志框架输出日志
*/ public interface Loader extends Configurable,XMLConfigurable,Reportable{ /** * 按照id装载指定的对象 * * @param id 对象id * @param cacheAllowed 是否允许缓存 * @return 对象实例 */ public O load(String id,boolean cacheAllowed); /** * 注册监听器 * * @param watcher 监听器 */ public void addWatcher(Watcher watcher); /** * 注销监听器 * @param watcher 监听器 */ public void removeWatcher(Watcher watcher); /** * 虚基类 * * @author duanyy * * @param */ public abstract static class Abstract implements Loader{ /** * a logger of log4j */ protected static final Logger LOG = LoggerFactory.getLogger(Loader.class); @Override public void configure(Properties p) { // nothing to do } @Override public void configure(Element e, Properties p) { Properties props = new XmlElementProperties(e,p); configure(props); } @Override public void report(Element xml) { if (xml != null){ XmlTools.setString(xml,"module",getClass().getName()); } } @Override public void report(Map json) { if (json != null){ JsonTools.setString(json,"module",getClass().getName()); } } @Override public void addWatcher(Watcher watcher) { // nothing to do } @Override public void removeWatcher(Watcher watcher) { // nothing to do } } /** * Sinkable * @author duanyy * */ public abstract static class Sinkable extends Abstract { protected List> loaders = new ArrayList>(); @Override public void configure(Element e, Properties p) { Properties props = new XmlElementProperties(e,p); configure(props); NodeList nodeList = XmlTools.getNodeListByPath(e, "sink"); Factory> factory = new Factory>(); for (int i = 0 ;i < nodeList.getLength() ; i ++){ Node n = nodeList.item(i); if (Node.ELEMENT_NODE != n.getNodeType()){ continue; } Element elem = (Element)n; try { Loader loader = factory.newInstance(elem, props, "module"); if (loader != null){ loaders.add(loader); } }catch (Exception ex){ LOG.error("Can not create loader from element:" + XmlTools.node2String(elem)); } } } @Override public O load(String id, boolean cacheAllowed) { O found = loadFromSelf(id,cacheAllowed); if (found == null){ found = loadFromSink(id,cacheAllowed); } return found; } protected O loadFromSink(String id,boolean cacheAllowed){ for (Loader l:loaders){ O found = l.load(id, cacheAllowed); if (found != null){ return found; } } return null; } @Override public void report(Element xml) { if (xml != null){ super.report(xml); if (!loaders.isEmpty()){ Document doc = xml.getOwnerDocument(); for (Loader l:loaders){ Element elem = doc.createElement("sink"); l.report(elem); xml.appendChild(elem); } } } } @Override public void report(Map json) { if (json != null){ super.report(json); if (!loaders.isEmpty()){ List list = new ArrayList(); for (Loader l:loaders){ Map map = new HashMap(); l.report(map); list.add(map); } json.put("sink", list); } } } protected abstract O loadFromSelf(String id,boolean cacheAllowed); } /** * 缓存过的 * @author duanyy * * @param */ public static class Cached extends Sinkable{ /** * 缓存的对象 */ private Map cachedObjects = new ConcurrentHashMap(); @Override public O load(String id, boolean cacheAllowed) { O found = loadFromSelf(id,cacheAllowed); if (found == null){ synchronized (this){ found = loadFromSelf(id,cacheAllowed); if (found == null){ found = loadFromSink(id,cacheAllowed); if (found != null){ cachedObjects.put(id, found); } } } } return found; } @Override protected O loadFromSelf(String id, boolean cacheAllowed) { O found = null; if (cacheAllowed){ found = cachedObjects.get(id); if (found != null && found.isExpired()){ cachedObjects.remove(id); found = null; } } return found; } } /** * 容器 * * @author duanyy * * @param */ public static class Container extends Sinkable{ private Map objects = new ConcurrentHashMap(); public void add(String id,O o){ objects.put(id, o); } public void remove(String id){ objects.remove(id); } public void clear(){ objects.clear(); } @Override protected O loadFromSelf(String id, boolean cacheAllowed) { return objects.get(id); } } /** * 基于XML配置的容器 * * @author duanyy * * @param */ public abstract static class XmlResource extends Container{ protected abstract String getObjectXmlTag(); protected abstract String getObjectDftClass(); @Override public void configure(Element root, Properties p) { super.configure(root, p); NodeList nodeList = XmlTools.getNodeListByPath(root, getObjectXmlTag()); Factory factory = new Factory(); for (int i = 0 ;i < nodeList.getLength() ; i ++){ Node n = nodeList.item(i); if (Node.ELEMENT_NODE != n.getNodeType()){ continue; } Element e = (Element)n; O instance = factory.newInstance(e, p, "module", getObjectDftClass()); if (StringUtils.isNotEmpty(instance.getId())){ add(instance.getId(), instance); } } } } /** * 管理器 * * @author duanyy * * @param */ public static class Manager extends Cached{ /** * 通过XML Document来配置 * @param doc XML文档 * @param p 变量集 */ protected void configure(Document doc,Properties p){ if (doc != null && doc.getDocumentElement() != null){ configure(doc.getDocumentElement(),p); } } /** * 通过一个XML资源来配置 * * @param src XML资源地址 */ protected void configure(String src){ configure(src,null); } /** * 通过XML资源来配置 * @param src XML资源地址 * @param secondary 备用资源地址 */ protected void configure(String src,String secondary){ ResourceFactory rf = Settings.getResourceFactory(); InputStream in = null; try { in = rf.load(src, secondary, null); Document doc = XmlTools.loadFromInputStream(in); configure(doc,Settings.get()); } catch (Exception ex) { LOG.error("Error occurs when load xml file,source=" + src, ex); } finally { IOTools.closeStream(in); } } } }