Package org.apache.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http

Source Code of org.apache.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http.XSLTProcessor

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.   
*/
package org.apache.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;

import javax.management.MBeanException;
import javax.management.ReflectionException;
import javax.management.RuntimeMBeanException;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.w3c.dom.Document;

import org.osgi.framework.ServiceReference;

import org.osgi.service.log.LogService;

import org.apache.felix.mosgi.jmx.httpconnector.HttpConnectorActivator;


/**
* XSLTPostProcessor pass the document through an XSLT transformation
*
* @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
* @version $Revision: 1.1.1.1 $
* the HttpAdaptor through a XSL transformation" extends="mx4j.tools.adaptor.http.ProcessorMBean"
*/
public class XSLTProcessor
  implements ProcessorMBean, XSLTProcessorMBean, URIResolver
{
  TransformerFactory factory = null;

  private Map templatesCache = new HashMap();

  private String path = "mx4j/tools/adaptor/http/xsl";

  private File root = null;

  private Map mimeTypes = new HashMap();

  /** Indicated whether the file are read from a file */
  private boolean useJar = true;

  private boolean useCache = true;

  private ClassLoader targetClassLoader = ClassLoader.getSystemClassLoader();

  private String defaultPage = "serverbydomain";

  /**
   * The locale is set with the default as en_US since it is the
   * one bundled
   */
  private Locale locale = new Locale("en", "");

  public XSLTProcessor()
  {
    factory = TransformerFactory.newInstance();
    factory.setURIResolver(this);
    mimeTypes.put(".gif", "image/gif");
    mimeTypes.put(".jpg", "image/jpg");
    mimeTypes.put(".png", "image/png");
    mimeTypes.put(".tif", "image/tiff");
    mimeTypes.put(".tiff", "image/tiff");
    mimeTypes.put(".ico", "image/ico");
    mimeTypes.put(".html", "text/html");
    mimeTypes.put(".htm", "text/html");
    mimeTypes.put(".txt", "text/plain");
    mimeTypes.put(".xml", "text/xml");
    mimeTypes.put(".xsl", "text/xsl");
    mimeTypes.put(".css", "text/css");
    mimeTypes.put(".js", "text/x-javascript");
    mimeTypes.put(".jar", "application/java-archive");
  }

  public void writeResponse(HttpOutputStream out, HttpInputStream in, Document document) throws IOException
  {
    out.setCode(HttpConstants.STATUS_OKAY);
    out.setHeader("Content-Type", "text/html");
    // added some caching attributes to fornce not to cache
    out.setHeader("Cache-Control", "no-cache");
    out.setHeader("expires", "now");
    out.setHeader("pragma", "no-cache");
    out.sendHeaders();
    Transformer transformer = null;
    String path = preProcess(in.getPath());

    if (in.getVariable("template") != null)
    {
      transformer = createTransformer(in.getVariable("template") + ".xsl");
    }
    else
    {
      transformer = createTransformer(path + ".xsl");
    }

    if (transformer != null)
    {
      // added so that the document() function works
      transformer.setURIResolver(this);
      // The variables are passed to the XSLT as (param.name, value)
      Map variables = in.getVariables();
      Iterator j = variables.keySet().iterator();
      while (j.hasNext())
      {
        String key = (String)j.next();
        Object value = variables.get(key);
        if (value instanceof String) {
          transformer.setParameter("request." + key, value);
        }
        if (value instanceof String[]) {
          String[] allvalues = (String[])value;
          // not a good solution, only the first one is presented
          transformer.setParameter("request." + key, allvalues[0]);
        }

      }
      if (!variables.containsKey("locale"))
      {
        transformer.setParameter("request.locale", locale.toString());
      }
      try
      {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        XSLTProcessor.log(LogService.LOG_DEBUG,"transforming " + path,null);
        transformer.transform(new DOMSource(document), new StreamResult(output));
        output.writeTo(out);
      }
      catch (TransformerException e)
      {
        XSLTProcessor.log(LogService.LOG_ERROR,"Transformation exception ", e);
      }
    }
    else
    {
      XSLTProcessor.log(LogService.LOG_WARNING,"Transformer for path " + path + " not found",null);
    }
  }

  protected Transformer createTransformer(String path)
  {
    Transformer transformer = null;
    try
    {
      if (useCache && templatesCache.containsKey(path))
      {
        transformer = ((Templates)templatesCache.get(path)).newTransformer();
      }
      else
      {
        InputStream file = getInputStream(path);
        if (file != null)
        {
          XSLTProcessor.log(LogService.LOG_INFO,"Creating template for path "+path, null);
          Templates template = factory.newTemplates(new StreamSource(file));
          transformer = template.newTransformer();
          if (useCache)
          {
            templatesCache.put(path, template);
          }
        }
        else
        {
          XSLTProcessor.log(LogService.LOG_WARNING,"template for path "+path+" not found", null);
        }
      }
    }
    catch (TransformerConfigurationException e)
    {
      XSLTProcessor.log(LogService.LOG_ERROR,"Exception during template construction", e);
    }
    return transformer;
  }

  protected void processHttpException(HttpInputStream in, HttpOutputStream out, HttpException e) throws IOException
  {
    out.setCode(e.getCode());
    out.setHeader("Content-Type", "text/html");
    out.sendHeaders();
    // hardcoded dir :-P
    Transformer transformer = createTransformer("error.xsl");
    transformer.setURIResolver(this);
    Document doc = e.getResponseDoc();
    if (doc != null)
    {
      try
      {
        if (!in.getVariables().containsKey("locale"))
        {
          transformer.setParameter("request.locale", locale.toString());
        }
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        transformer.transform(new DOMSource(doc), new StreamResult(output));
        output.writeTo(out);
      }
      catch (TransformerException ex)
      {
        XSLTProcessor.log(LogService.LOG_ERROR,"Exception during error output", ex);
      }
    }
  }

  public void writeError(HttpOutputStream out, HttpInputStream in, Exception e) throws IOException
  {
    Exception t = e;
    if (e instanceof RuntimeMBeanException)
    {
      t = ((RuntimeMBeanException)e).getTargetException();
    }
    XSLTProcessor.log(LogService.LOG_INFO,"Processing error " + t.getMessage(),null);
    if (t instanceof HttpException)
    {
      processHttpException(in, out, (HttpException)e);
    }
    else if ((t instanceof MBeanException) && (((MBeanException)t).getTargetException() instanceof HttpException))
    {
      processHttpException(in, out, (HttpException)((MBeanException)t).getTargetException());
    }
    else if ((t instanceof ReflectionException) && (((ReflectionException)t).getTargetException() instanceof HttpException))
    {
      processHttpException(in, out, (HttpException)((ReflectionException)t).getTargetException());
    }
    else
    {
      out.setCode(HttpConstants.STATUS_INTERNAL_ERROR);
      out.setHeader("Content-Type", "text/html");
      out.sendHeaders();
    }
  }

  public String preProcess(String path) {
    if (path.equals("/"))
    {
      path = "/" + defaultPage;
    }
    return path;
  }

  public String notFoundElement(String path, HttpOutputStream out, HttpInputStream in) throws IOException, HttpException
  {
    File file = new File(this.path, path);
    XSLTProcessor.log(LogService.LOG_INFO,"Processing file request " + file,null);
    String name = file.getName();
    int extensionIndex = name.lastIndexOf('.');
    String mime = null;
    if (extensionIndex < 0)
    {
      XSLTProcessor.log(LogService.LOG_WARNING,"Filename has no extensions " + file.toString(),null);
      mime = "text/plain";
    }
    else
    {
      String extension = name.substring(extensionIndex, name.length());
      if (mimeTypes.containsKey(extension))
      {
        mime = (String)mimeTypes.get(extension);
      } else {
        XSLTProcessor.log(LogService.LOG_WARNING,"MIME type not found " + extension,null);
        mime = "text/plain";
      }
    }
    try
    {
      XSLTProcessor.log(LogService.LOG_DEBUG,"Trying to read file " + file,null);
      BufferedInputStream fileIn = new BufferedInputStream(getInputStream(path));
      ByteArrayOutputStream outArray = new ByteArrayOutputStream();
      BufferedOutputStream outBuffer = new BufferedOutputStream(outArray);
      int piece = 0;
      while ((piece = fileIn.read()) >= 0)
      {
        outBuffer.write(piece);
      }
      outBuffer.flush();
      out.setCode(HttpConstants.STATUS_OKAY);
      out.setHeader("Content-type", mime);
      out.sendHeaders();
      XSLTProcessor.log(LogService.LOG_DEBUG,"File output " + mime,null);
      outArray.writeTo(out);
      fileIn.close();
    }
    catch (Exception e)
    {
      XSLTProcessor.log(LogService.LOG_WARNING,"Exception loading file " + file, e);
      throw new HttpException(HttpConstants.STATUS_NOT_FOUND, "file " + file + " not found");
    }
    return null;
  }

  protected InputStream getInputStream(String path)
  {
    InputStream file = null;
    if (!useJar)
    {
      try
      {
        // load from a dir
        file = new FileInputStream(new File(this.root, path));
      }
      catch (FileNotFoundException e)
      {
        XSLTProcessor.log(LogService.LOG_ERROR,"File not found", e);
      }
    }
    else
    {
      // load from a jar
      String targetFile = this.path;
      // workaround, should tought of somehting better
      if (path.startsWith("/"))
      {
        targetFile += path;
      } else {
        targetFile += "/" + path;
      }
      if (root != null)
      {
        file = targetClassLoader.getResourceAsStream(targetFile);
      }
      if (file == null)
      {
        ClassLoader cl=getClass().getClassLoader();
        if (cl == null)
        {
          file = ClassLoader.getSystemClassLoader().getResourceAsStream(targetFile);
        }
        else
        {
          file = getClass().getClassLoader().getResourceAsStream(targetFile);
        }
        file = getClass().getClassLoader().getResourceAsStream(targetFile);
      }
    }

    return file;
  }

  public Source resolve(String href, String base)
  {
    StreamSource source = new StreamSource(getInputStream(href));
    // this works with saxon7/saxon6.5.2/xalan
    source.setSystemId(href);
    return source;
  }

  public void setFile(String file)
  {
    if (file != null)
    {

      File target = new File(file);
      if (!target.exists())
      {
        XSLTProcessor.log(LogService.LOG_WARNING,"Target file " + file + " does not exist, defaulting to previous",null);
        return;
      }
      if (target.isDirectory())
      {
        useJar = false;
        XSLTProcessor.log(LogService.LOG_INFO, "Using " + file + " as the root dir", null);
        this.root = target;
        return;
      }
      if (target.isFile() && (target.getName().endsWith(".jar") ||
        (target.getName().endsWith(".zip"))))
      {
        try {
          URL url = target.toURL();
          targetClassLoader = new URLClassLoader(new URL[] {url});
          XSLTProcessor.log(LogService.LOG_INFO,"Using compressed file " + url + " as the root file",null);
          this.root = target;
          useJar = true;
        } catch (MalformedURLException e) {
          XSLTProcessor.log(LogService.LOG_WARNING,"Unable to create class loader", e);
        }
      }
      else
      {
        XSLTProcessor.log(LogService.LOG_WARNING,"Target file " + file + " does not exist, defaulting to previous",null);
      }
    }
  }

  public String getFile()
  {
    return (root != null)?root.getName():null;
  }

  public String getPathInJar()
  {
    return path;
  }

  public void setPathInJar(String path)
  {
    this.path = path;
  }

  public String getDefaultPage()
  {
    return defaultPage;
  }

  public void setDefaultPage(String defaultPage)
  {
    this.defaultPage = defaultPage;
  }

  public boolean isUseJar()
  {
    return useJar;
  }

  public boolean isUsePath()
  {
    return !useJar;
  }

  public void addMimeType(String extension, String type)
  {
    if (extension != null && type != null)
    {
      XSLTProcessor.log(LogService.LOG_INFO,"Added MIME type " + type + " for extension " + extension,null);
      mimeTypes.put(extension, type);
    }
  }

  public void setUseCache(boolean useCache)
  {
    this.useCache = useCache;
  }

  public boolean isUseCache()
  {
    return useCache;
  }

  public String getName()
  {
    return "XSLT Processor";
  }

  public Locale getLocale() {
    return locale;
  }

  public void setLocale(Locale locale) {
    this.locale = locale;
  }

  public void setLocaleString(String locale) {
    if (locale == null || locale.length()==0) {
      this.locale = new Locale("en", "");
    }
    else
    {
      // split locale based on underbar
      StringTokenizer tknzr = new StringTokenizer(locale,"_");
      String language = tknzr.nextToken();
      String country = "";
      String variant = "";
      if (tknzr.hasMoreTokens())
        country = tknzr.nextToken();
      if (tknzr.hasMoreTokens())
        variant = tknzr.nextToken();
      this.locale = new Locale(language,country,variant);
    }
  }

    private static void log(int prio, String message, Throwable t){
    if (HttpConnectorActivator.bc!=null){
    ServiceReference logSR=HttpConnectorActivator.bc.getServiceReference(LogService.class.getName());
    if (logSR!=null){
      ((LogService)HttpConnectorActivator.bc.getService(logSR)).log(prio, message, t);
    }else{
      System.out.println("No Log Service");
    }
    }else{
      System.out.println("mx4j.tools.adapatoir.http.XSLTProcessor.log: No bundleContext");
    }
  }

}
TOP

Related Classes of org.apache.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http.XSLTProcessor

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.