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

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

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

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
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.PropertiesConstants;
import com.anysoft.util.Reportable;
import com.anysoft.util.Settings;
import com.anysoft.util.XMLConfigurable;
import com.anysoft.util.XmlElementProperties;
import com.anysoft.util.XmlTools;

/**
 * 扫描器,用于列表性数据的加载
 * 
 * @author duanyy
 * @since 1.6.12.30 [20190425 duanyy] 
*/ public interface Scanner extends Configurable,XMLConfigurable,Reportable{ /** * 获取id * @return id */ public String getId(); /** * 开始扫描 * @param listener */ public void scan(Listener listener); /** * 虚基类 * * @author duanyy * * @param 数据对象 */ public abstract static class Abstract implements Scanner{ /** * a logger of log4j */ protected static final Logger LOG = LoggerFactory.getLogger(Loader.class); protected String id = "default"; @Override public void configure(Element e, Properties p) { Properties props = new XmlElementProperties(e,p); configure(props); } @Override public void configure(Properties p) { id = PropertiesConstants.getString(p,"id",id,true); } @Override public String getId() { return null; } @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()); } } } /** * Sinkable * @author duanyy * * @param 数据对象 */ public static class Sinkable extends Abstract { /** * 子scanner */ protected List> scanners = new ArrayList>(); @Override public void configure(Element e, Properties p) { Properties props = new XmlElementProperties(e,p); configure(props); NodeList nodeList = XmlTools.getNodeListByPath(e, getSinkTag()); Factory> factory = new Factory>(); String scope = PropertiesConstants.getString(p, "ketty.scope", "runtime"); for (int i = 0 ;i < nodeList.getLength() ; i ++){ Node n = nodeList.item(i); if (Node.ELEMENT_NODE != n.getNodeType()){ continue; } Element elem = (Element)n; String itemScope = XmlTools.getString(elem, "scope", ""); if (StringUtils.isNotEmpty(itemScope) && !itemScope.equals(scope)){ continue; } try { Scanner loader = factory.newInstance(elem, props, "module"); if (loader != null){ scanners.add(loader); } }catch (Exception ex){ LOG.error("Can not create loader from element:" + XmlTools.node2String(elem)); LOG.error(ExceptionUtils.getStackTrace(ex)); } } } /** * 获取Sink的tag名 * @return tag名 */ protected String getSinkTag(){ return "sink"; } @Override public void scan(Listener listener) { if (listener != null){ Object cookie = listener.begin(this.getId()); scanSelf(cookie,listener); scanSinks(cookie,listener); listener.end(cookie, this.getId()); } } protected void scanSelf(Object cookie,Listener listener){ } protected void scanSinks(Object cookie,Listener listener){ for (Scanner scanner:scanners){ try { scanner.scan(listener); }catch (Exception ex){ LOG.error(String.format("Failed to scan scanner:%s",scanner.getId())); LOG.error(ExceptionUtils.getStackTrace(ex)); } } } } /** * Cached * @author duanyy * * @param 数据对象 */ public static class Cached extends Sinkable implements Listener{ /** * 子scanner */ protected List> scanners = new ArrayList>(); protected List cached = new ArrayList(); protected long ttl = 60 * 10000; protected long lastTimestamp = 0; @Override public void configure(Properties p) { super.configure(p); ttl = (PropertiesConstants.getLong(p, "ttl", 60))*1000; } protected boolean isExpired(long now){ return now - this.lastTimestamp > ttl; } @Override protected void scanSelf(Object cookie,Listener listener){ long now = System.currentTimeMillis(); if (isExpired(now)){ //缓存数据过期,重新加载 synchronized(this){ cached.clear(); scanSinks(cookie,this); this.lastTimestamp = now; } } for (O data:cached){ listener.found(cookie, data); } } @Override public void scan(Listener listener) { if (listener != null){ Object cookie = listener.begin(this.getId()); scanSelf(cookie,listener); listener.end(cookie, this.getId()); } } @Override public Object begin(String scannerId) { return this; } @Override public void found(Object cookie, O data) { cached.add(data); } @Override public void end(Object cookie, String scannerId) { } } /** * 热部署文件 * * @author yyduan * */ public static abstract class HotFile extends Abstract implements Runnable{ protected String digest = ""; protected String filePath; protected ScheduledThreadPoolExecutor threadPool = new ScheduledThreadPoolExecutor(1); protected long interval = 10; protected long delay = 10; protected List cached = new ArrayList(); @Override public void configure(Properties p){ super.configure(p); filePath = PropertiesConstants.getString(p, "path", ""); interval = PropertiesConstants.getLong(p,"interval",interval); delay = PropertiesConstants.getLong(p,"delay",delay); loadFromPath(cached,filePath); threadPool.scheduleAtFixedRate(this, delay, interval, TimeUnit.SECONDS); } @Override public void scan(Listener listener) { if (listener != null){ Object cookie = listener.begin(this.getId()); for (O data:cached){ listener.found(cookie, data); } listener.end(cookie, this.getId()); } } /** * 从指定路径装入信息 * * @param path */ protected void loadFromPath(final List container,final String path){ File file = new File(path); if (file.exists() && file.isFile()){ digest = getFileDigest(file); loadFromFile(container,file); }else{ LOG.warn("File does not exist :" + path); } } protected synchronized void loadFromFile(final List container,final File file){ InputStream in = null; try { in = new FileInputStream(file); Document doc = XmlTools.loadFromInputStream(in); if (doc != null){ loadFromElement(container,doc.getDocumentElement(),Settings.get()); } } catch (Exception e) { LOG.error("Can not open file : " + file.getPath()); LOG.error(ExceptionUtils.getStackTrace(e)); } finally{ IOTools.close(in); } } protected void loadFromElement(final List container,Element root,Properties 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()); objectFound(container,instance); } } protected void objectFound(final List container,O instance){ if (StringUtils.isNotEmpty(instance.getId())){ container.add(instance); } } protected String getObjectXmlTag() { return "model"; } protected abstract String getObjectDftClass(); @Override public void run() { File file = new File(filePath); if (file.exists() && file.isFile()){ String md5 = getFileDigest(file); if (md5 != null && ! md5.equals(digest)){ digest = md5; LOG.info("File has been changed:" + filePath); List temp = new ArrayList(); loadFromFile(temp,file); cached = temp; } } } protected synchronized String getFileDigest(File file){ String digest = null; InputStream in; try { in = new FileInputStream(file); digest = DigestUtils.md5Hex(in); } catch (Exception e) { LOG.error("Can not open file : " + file.getPath()); LOG.error(ExceptionUtils.getStackTrace(e)); } return digest; } } /** * 扫描监听器 * @author duanyy * * @param 数据对象 */ public static interface Listener { public Object begin(String scannerId); public void found(Object cookie,O data); public void end(Object cookie,String scannerId); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy