Package org.xmlBlaster.contrib

Source Code of org.xmlBlaster.contrib.VersionTransformerCache

/*------------------------------------------------------------------------------
Name:      ReplicationConverter.java
Project:   org.xmlBlasterProject:   xmlBlaster.org
Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
------------------------------------------------------------------------------*/
package org.xmlBlaster.contrib;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.xmlBlaster.contrib.replication.ReplicationConstants;


/**
* Holds Transformers cached.
*
* @author Michele Laghi
*/
public class VersionTransformerCache {

   private static Logger log = Logger.getLogger(VersionTransformerCache.class.getName());

   private Map transformers;
   private Set checkedTransformers;
  
   public VersionTransformerCache() {
      this.transformers = new HashMap();
      this.checkedTransformers = new HashSet();
   }
  
   public void verifyTransformerName(String xslFile) {
      // TODO: check on startup if XSL file exists
   }

   /**
    *
    * @param filename
    * @return
    */
   private synchronized Transformer getTransformerAlsoFromCache(String filename, String secondChoice, String thirdChoice, ClassLoader cl) {
      Transformer ret = (Transformer)this.transformers.get(filename);
      if (ret != null)
         return ret;

      if (this.checkedTransformers.contains(filename))
         return null;
      try {
         ret = newTransformer(filename, cl);
      }
      catch (Throwable ex) {
         if (secondChoice == null && thirdChoice == null)
            log.severe("The search for file '" + filename + "' resulted in an exception. " + InfoHelper.getStackTraceAsString(ex));
      }
      this.checkedTransformers.add(filename);
      if (ret != null)
         this.transformers.put(filename, ret);
      else {
         if (secondChoice != null) {
            ret = getTransformerAlsoFromCache(secondChoice, thirdChoice, null, cl);
            if (ret != null)
               return ret;
            else {
               if (thirdChoice != null) {
                  ret = getTransformerAlsoFromCache(thirdChoice, null, null, cl);
               }
            }
         }
      }
      if (ret != null)
         this.transformers.put(filename, ret);
      return ret;
   }
  
   /**
    * Note that this method searches for the stripped name in the classpath.
    *
    * @param filenamePrefix
    * @return
    * @throws Exception
    */
   private static String getXslStringFromFile(String filenamePrefix, ClassLoader extraCl) throws Exception {
      String filename = getStrippedString(filenamePrefix) + ".xsl";
      ClassLoader cl = VersionTransformerCache.class.getClassLoader();
     
      InputStream xslInputStream = cl.getResourceAsStream(filename);
      if(xslInputStream == null) {
          String txt = "The xsl resource '" + filename
              + "' could not be found in the specific classpath: trying the system class loader";
         log.severe(txt);
          xslInputStream = ClassLoader.getSystemResourceAsStream(filename);
          if(xslInputStream == null) {
             if (extraCl != null)
                xslInputStream = extraCl.getResourceAsStream(filename);

             if (xslInputStream == null) {
                txt = "VersionTransformerCache.getXslStringFromFile: The xsl resource '" + filename
                + "' could not be found in the system classpath: check your classpath";
                throw new Exception(txt);
             }
          }
      }

      InputStreamReader reader = new InputStreamReader(xslInputStream);
      BufferedReader br = new BufferedReader(reader);
      StringBuffer buf = new StringBuffer();
      String line = "";

      while((line = br.readLine()) != null)
         buf.append(line).append("\n");
      return buf.toString();
   }


   private static Transformer newTransformer(String systemId, String xslString, URIResolver uriResolver, Map params) throws Exception {
      TransformerFactory transformerFactory = TransformerFactory.newInstance();
      if (uriResolver != null)
         transformerFactory.setURIResolver(uriResolver);
      StreamSource xslStreamSource = null;
      if(systemId != null)
          xslStreamSource = new StreamSource(new StringReader(xslString), systemId);
      else
          xslStreamSource = new StreamSource(new StringReader(xslString));

      Transformer transformer = transformerFactory.newTransformer(xslStreamSource);
      if(params != null) {
          Iterator iter = params.entrySet().iterator();
          while(iter.hasNext()) {
              Map.Entry entry = (Map.Entry)iter.next();
              transformer.setParameter((String)entry.getKey(), (String)entry.getValue());
          }
      }
      return transformer;
   }
      
   private static Transformer newTransformer(String filename, ClassLoader cl) throws Exception {
      final String systemId = null;
      final URIResolver uriResolver = null;
      final Map map = null;
      String xslt = getXslStringFromFile(filename, cl);
      return newTransformer(systemId, xslt, uriResolver, map);
   }

   private byte[] doXSLTransformation(String filename, String secondChoice, String thirdChoice, byte[] in, ClassLoader cl) throws Exception {
      Transformer transformer = getTransformerAlsoFromCache(filename, secondChoice, thirdChoice, cl);
      if (transformer == null) {
         log.warning("Transformer for file '" + filename + "' not found (where second choice was '" + secondChoice + "' and third choice was '" + thirdChoice +  "', will return it without modification");
         return in;
      }
      else {
         StreamSource xmlStreamSource = new StreamSource(new ByteArrayInputStream(in));
         ByteArrayOutputStream baos = new ByteArrayOutputStream(in.length);
         StreamResult resultStream = new StreamResult(baos);
         transformer.transform(xmlStreamSource, resultStream);
         return baos.toByteArray();
      }
   }
  
   public InputStream doXSLTransformation(String filename, InputStream in,
                  ClassLoader cl) throws Exception {
      // TODO: Add a cache!
      Transformer transformer = newTransformer(filename, cl);
      if (transformer == null) {
         log.warning("Transformer for file '" + filename + "' not found");
         return in;
      } else {
         StreamSource xmlStreamSource = new StreamSource(in);
         ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
         StreamResult resultStream = new StreamResult(baos);
         transformer.transform(xmlStreamSource, resultStream);
         ByteArrayInputStream bin = new ByteArrayInputStream(baos.toByteArray());
         return bin;
      }
   }
  
   public synchronized void clearCache() {
      this.checkedTransformers.clear();
      this.transformers.clear();
   }
  
   /**
    * Taken from the Global.
    *
    * @param text
    * @return
    */
   public static final String getStrippedString(String text) {
      if (text == null) return null;
      String strippedId = org.xmlBlaster.util.ReplaceVariable.replaceAll(text, "/", "");
      // JMX does not like commas, but we can't introduce this change in 1.0.5
      // as the persistent queue names would change and this is not backward compatible
      //strippedId = org.xmlBlaster.util.ReplaceVariable.replaceAll(strippedId, ",", "_");
      strippedId = org.xmlBlaster.util.ReplaceVariable.replaceAll(strippedId, " ", "_");
      strippedId = org.xmlBlaster.util.ReplaceVariable.replaceAll(strippedId, ".", "_");
      strippedId = org.xmlBlaster.util.ReplaceVariable.replaceAll(strippedId, ":", "_");
      strippedId = org.xmlBlaster.util.ReplaceVariable.replaceAll(strippedId, "[", "_");
      strippedId = org.xmlBlaster.util.ReplaceVariable.replaceAll(strippedId, "]", "_");
      return org.xmlBlaster.util.ReplaceVariable.replaceAll(strippedId, "\\", "");
   }
  
   /**
    * Performs an xslt transformation according to the parameters passed and the stylesheet associated to the combination
    * of such parameters.
    *
    * @param replPrefix The replication prefix used.
    * @param srcVersion The version is actual on the source
    * @param destVersion The version which is wanted on the destination.
    * @param destination The Session name of the destination (can also be a subject name)
    * @param srcData The source string to be transformed.
    * @param cl can be null. Used to find the xsl resources (this is an additional class loader to use)
    * @return
    * @throws Exception
    */
   public byte[] transform(String replPrefix, String srcVersion, String destVersion, String destination, byte[] srcData, ClassLoader cl) throws Exception {
      String thirdChoice = replPrefix + "_" + srcVersion + "_" + destVersion;
      int pos = destination.lastIndexOf("/");
      String secondChoice = null;
      String firstChoice = null;
      if (pos < 0) {
         secondChoice = thirdChoice + "_" + destination;
         firstChoice = secondChoice;
      }
      else {
         String pre = destination.substring(0, pos);
         secondChoice = thirdChoice + "_" + pre;
         firstChoice = thirdChoice + "_" + destination;
      }
      return doXSLTransformation(firstChoice, secondChoice, thirdChoice, srcData, cl);
   }

   /**
    * Returns the prefix of the complete name. It only returns null if the input string was null.
    * @param replicationPrefix
    * @return
    */
   public static String stripReplicationPrefix(String replicationPrefix) {
      if (replicationPrefix == null)
         return null;
      int pos = replicationPrefix.lastIndexOf(ReplicationConstants.VERSION_TOKEN);
      if (pos < 0)
         return replicationPrefix;
      String ret = replicationPrefix.substring(0, pos);
      return ret.trim();
   }
  
   /**
    * Can return null if no version token (_Ver_) was found.
    * @param replicationPrefix
    * @return
    */
   public static String stripReplicationVersion(String replicationPrefix) {
      int pos = replicationPrefix.lastIndexOf(ReplicationConstants.VERSION_TOKEN);
      if (pos < 0)
         return null;
      String ret = replicationPrefix.substring(pos + ReplicationConstants.VERSION_TOKEN.length());
     
      pos = ret.lastIndexOf(ReplicationConstants.DUMP_POSTFIX);
      if (pos < 0)
         return ret.trim();
      ret = ret.substring(0, pos);
      return ret.trim();
   }
  
   public static String buildFilename(String replicationPrefix, String version) {
      return replicationPrefix + ReplicationConstants.VERSION_TOKEN + version + ReplicationConstants.DUMP_POSTFIX;
   }
  
}
TOP

Related Classes of org.xmlBlaster.contrib.VersionTransformerCache

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.