⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xpathfilter.java

📁 java开源的企业总线.xmlBlaster
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------------Name:      XPathFilter.javaProject:   xmlBlaster.orgCopyright: xmlBlaster.org, see xmlBlaster-LICENSE fileComment:   Support check of message content with XPath expressions.------------------------------------------------------------------------------*/package org.xmlBlaster.engine.mime.xpath;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.logging.Logger;import java.util.logging.Level;import org.xmlBlaster.util.plugin.I_Plugin;import org.xmlBlaster.util.plugin.PluginInfo;import org.xmlBlaster.util.property.Args;import org.xmlBlaster.util.FileLocator;import org.xmlBlaster.util.Global;import org.xmlBlaster.util.Timestamp;import org.xmlBlaster.util.XmlBlasterException;import org.xmlBlaster.util.XslTransformer;import org.xmlBlaster.util.def.ErrorCode;import org.xmlBlaster.authentication.SessionInfo;import org.xmlBlaster.util.def.Constants;import org.xmlBlaster.util.MsgUnit;import org.xmlBlaster.engine.mime.I_AccessFilter;import org.xmlBlaster.engine.mime.Query;import org.xmlBlaster.engine.ServerScope;import java.util.ArrayList;import java.util.LinkedList;import java.util.Map;import java.util.Properties;import java.util.StringTokenizer;import java.util.TreeMap;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.DocumentBuilder;import org.xml.sax.InputSource;import org.w3c.dom.Document;import org.jaxen.SimpleFunctionContext;import org.jaxen.XPathFunctionContext;import org.jaxen.Function;import org.jaxen.JaxenException;import org.jaxen.dom.DOMXPath;/** * Filter content on an XPath expression. * *<p>Filter on the content of an xml mime message. * <br /> * The applicable mime types for this filter can be specified using the  * <code>engine.mime.xpath.types</code> parameter with semi-colon separated mime types * e.g. engine.mime.xpath.types=text/xml;image/svg+xml;application/xml * <br /> * The filter will cache the message dom tree it produces, * keyd on message oid and message timestamp, and reuse it. * For example if there is 1000 subscribers with an XPathFilter, * it will not create 1000 DOM trees for each message, but one that will be reused in each match(). * The backlog is 10 by default, and old entries will be discarded. * This is settable with the paramater <code>engine.mime.xpath.maxcachesize</code>. * </p> * <p> * For example: * </p> * <pre> * MimeAccessPlugin[XPathFilter][1.0]=org.xmlBlaster.engine.mime.xpath.XPathFilter,engine.mime.xpath.maxcachesize=20. * </pre> * * <p> * Additional xpath functions can be loaded by setting the parameter <code>engine.mime.xpath.extension_functions</code>. * For a description of the parameter syntax and implementation requirements, see {@link #loadXPathExtensionFunctions(String) loadXPathExtensionFunctions} * </p> * * @author Peter Antman * @author Jens Askengren * @author Robert Leftwich <robert@leftwich.info> * @author Marcel Ruff * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/mime.plugin.access.xpath.html">The mime.plugin.access.xpath requirement</a> */public class XPathFilter implements I_Plugin, I_AccessFilter {   public static final String MAX_DOM_CACHE_SIZE = "engine.mime.xpath.maxcachesize";   public static final String DEFAULT_MAX_CACHE_SIZE = "10";   public static final String MATCH_AGAINST_QOS = "matchAgainstQos";   public static final String XSL_CONTENT_TRANSFORMER_FILE_NAME = "xslContentTransformerFileName";   //public static final String XSL_QOS_TRANSFORMER_FILE_NAME = "xslQosTransformerFileName";   public static final String XPATH_EXTENSTION_FUNCTIONS = "engine.mime.xpath.extension_functions";   public static final String XPATH_MIME_TYPES = "engine.mime.xpath.types";   private final String ME = "XPathFilter";   private Global glob;   private static Logger log = Logger.getLogger(XPathFilter.class.getName());   private int maxCacheSize = 10;   private LinkedList domCache;   private String [] mimeTypes;   private PluginInfo pluginInfo;   private boolean matchAgainstQos;   private String xslContentTransformerFileName;   //private String xslQosTransformerFileName;   /**    * This is called after instantiation of the plugin     * @param glob The Global handle of this xmlBlaster server instance.    */   public void initialize(ServerScope glob) {      this.glob = glob;      log.info("Filter is initialized, we check xml mime types");   }      /**    * This method is called by the PluginManager (enforced by I_Plugin).     * @see org.xmlBlaster.util.plugin.I_Plugin#init(org.xmlBlaster.util.Global,org.xmlBlaster.util.plugin.PluginInfo)    */   public void init(Global glob, PluginInfo pluginInfo) throws XmlBlasterException {      this.pluginInfo = pluginInfo;      Properties prop = pluginInfo.getParameters();      maxCacheSize = Integer.parseInt( prop.getProperty(MAX_DOM_CACHE_SIZE,                                                        DEFAULT_MAX_CACHE_SIZE));      loadXPathExtensionFunctions(prop.getProperty(XPATH_EXTENSTION_FUNCTIONS));      this.matchAgainstQos = Boolean.valueOf(            prop.getProperty(MATCH_AGAINST_QOS, ""+this.matchAgainstQos)            ).booleanValue();            this.xslContentTransformerFileName = prop.getProperty(XSL_CONTENT_TRANSFORMER_FILE_NAME, this.xslContentTransformerFileName);      //this.xslQosTransformerFileName = prop.getProperty(XSL_QOS_TRANSFORMER_FILE_NAME, this.xslQosTransformerFileName);      domCache = new LinkedList();      // attempt to get the mime types from the init properties      String someMimeTypes = prop.getProperty(XPATH_MIME_TYPES, "text/xml;image/svg+xml");      StringTokenizer st = new StringTokenizer(someMimeTypes, ";");      ArrayList list = new ArrayList(st.countTokens() + 1);      while (st.hasMoreTokens()) {          list.add(st.nextToken());      }      mimeTypes = (String[])list.toArray(new String[list.size()]);   }   /**    * Return plugin type for Plugin loader    * @return "GnuRegexFilter"    */   public String getType() {      return (this.pluginInfo==null) ? "XPathFilter" : this.pluginInfo.getType();   }   /**    * Return plugin version for Plugin loader    * @return "1.0"    */   public String getVersion() {      return (this.pluginInfo==null) ? "1.0" : this.pluginInfo.getVersion();   }   /**    * Get a human readable name of this filter implementation    * @return "GnuRegexFilter"    */   public String getName() {      return getType(); //"XPathFilter";   }   /**    * Get the content MIME type for which this plugin applies,    * currently "text/xml" and "image/svg+xml".    * Is configurable with    * <tt>engine.mime.xpath.types=text/xml;image/svg+xml;application/xml</tt>    * @return "*" This plugin handles all mime types    */   public String[] getMimeTypes() {      //String[] mimeTypes = { "text/xml", "image/svg+xml" };      return mimeTypes;   }   /**    * Get the content MIME version number for which this plugin applies    * @return "1.0" (this is the default version number)    */   public String[] getMimeExtended() {      String[] mimeExtended = { Constants.DEFAULT_CONTENT_MIME_EXTENDED, Constants.DEFAULT_CONTENT_MIME_EXTENDED }; // "1.0"      return mimeExtended;   }   /**    * Check if the filter rule matches for this message.    *    * <p>The dom tree generated will be cached for each message, to be used for other queries against the same message.</p>    * @param publisher The subject object describing the publisher    * @param receiver The subject object describing the receiver    * @param msgUnit The message to check    * @param query   The Query instance holding the xpath expression from your filter.<br />    * @return true   The filter xpath expression matches the message content.    * @exception XmlBlasterException Is thrown on problems, for example if the MIME type    *            does not fit to message content.<br />    *            Take care throwing an exception, as the    *            exception is routed back to the publisher. Subscribers which where served before    *            may receive the update, subscribers which are served after us won't get it.    *            For the publisher it looks as if the publish failed completely. Probably it is    *            best to return 'false' instead and log the situation.    *            Further the current subscription is destroyed when exception is thrown.    */   public boolean match(SessionInfo receiver, MsgUnit msgUnit, Query query) throws XmlBlasterException {      if (msgUnit == null) {         Thread.dumpStack();         throw new XmlBlasterException(glob, ErrorCode.INTERNAL_ILLEGALARGUMENT, ME, "Illegal argument in xpath match() call");      }            // Access cached query ...      DOMXPath expression;            try {         if (query.getPreparedQuery() == null) {            try {               expression = new DOMXPath(query.getQuery());               query.setPreparedQuery(expression);             } catch (JaxenException e) {               log.warning("Can't compile XPath filter expression '" + query + "':" + e.toString());               throw new XmlBlasterException(glob, ErrorCode.USER_CONFIGURATION, ME, "Can't compile XPath filter expression '" + query + "'", e);            }         }         else            expression = (DOMXPath)query.getPreparedQuery();                  // Access cached xsl transformation         XslTransformer xslContentTransformer = null;         if (this.xslContentTransformerFileName != null) {            xslContentTransformer = (XslTransformer)query.getTransformer();            if (xslContentTransformer == null) {               Map xslProps = new TreeMap(); // TODO: Where to get them from               xslContentTransformer = new XslTransformer(glob, this.xslContentTransformerFileName, null, null, xslProps);            }         }                  String xml = getXml(msgUnit).trim(); // Content or QoS                  if (xml.length() == 0) {            log.warning("Provided XML string is empty, query does not match.");            return false;         }                  Document doc = null;         try {            doc = getDocument(msgUnit);         }         catch (Throwable e) {            log.warning("The msgUnit can't be parsed, we reject it for this subscriber: " + e.toString());            return false;         }                  if ( log.isLoggable(Level.FINEST))            log.finest("Matching query " + query.getQuery() + " against document: " + getXml(msgUnit));                  boolean match = expression.booleanValueOf(doc);         if (log.isLoggable(Level.FINE))            log.fine("Query "+query.getQuery()+" did" + (match ? " match" : " not match"));                  if (match == true && xslContentTransformer != null) {            String tmp = (this.matchAgainstQos) ? msgUnit.getContentStr() : xml;            String ret = xslContentTransformer.doXSLTransformation(tmp);            msgUnit.setContent(ret.getBytes());         }                  return match;      }      catch (JaxenException e) {         log.warning("Error in querying dom tree with query " + query + ": " + e.toString());         throw new XmlBlasterException(glob, ErrorCode.USER_CONFIGURATION, ME, "Error in querying dom tree with query " + query, e);      }      catch (Throwable e) {         log.warning("Error in handling XPath filter with query='" + query + "' and xml='" + getXml(msgUnit) + "': " + e.toString());         e.printStackTrace();         throw new XmlBlasterException(glob, ErrorCode.USER_CONFIGURATION, ME, "Error in querying dom tree with query " + query, e);      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -