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

org.apache.uima.adapter.jms.service.Dd2spring Maven / Gradle / Ivy

/*
 * 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.uima.adapter.jms.service;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;

import org.apache.uima.UIMAFramework;
import org.apache.uima.aae.UIMAEE_Constants;
import org.apache.uima.adapter.jms.JmsConstants;
import org.apache.uima.util.Level;

public class Dd2spring {

  private static final Class THIS_CLASS = Dd2spring.class;

  private ClassLoader saxonClassLoader;
  
  /**
   * Test driver arg = path_to_source, path_to_xslt, path_to_saxon_jar, uima-as-debug flag
   * 
   * @param args
   */
  public static void main(String[] args) {
	  try {
		    new Dd2spring().convertDd2Spring(args[0], args[1], args[2], args[3]);
		  
	  } catch ( Exception e) {
		  e.printStackTrace();
	  }
  }

  public File convertDd2Spring(String ddFilePath, String dd2SpringXsltFilePath,
          String saxonClasspath, String uimaAsDebug) throws Exception {

    URL urlForSaxonClassPath;
    try {
      urlForSaxonClassPath = new URL(saxonClasspath);
    } catch (MalformedURLException e) {
      e.printStackTrace();
      UIMAFramework.getLogger(THIS_CLASS).logrb(Level.CONFIG, THIS_CLASS.getName(),
              "convertDD2Spring", JmsConstants.JMS_LOG_RESOURCE_BUNDLE,
              "UIMA_dd2spring_Cannot_convert_saxon_classpath_to_a_URL_SEVERE",
              new Object[] { saxonClasspath });
      return null;
    }

    File tempFile;
    try {
      tempFile = File.createTempFile("UIMAdd2springOutput", ".xml");
    } catch (IOException e) {
      e.printStackTrace();
      UIMAFramework.getLogger(THIS_CLASS).logrb(Level.CONFIG, THIS_CLASS.getName(),
              "convertDD2Spring", JmsConstants.JMS_LOG_RESOURCE_BUNDLE,
              "UIMA_dd2spring_cant_create_temp_output_file_SEVERE");
      return null;
    }

    // UIMA-5022 No longer capture output and scan for "ERROR: " as that hid
    // errors that Saxon followed by calling exit!
    // Processing now terminates on the first error.
    convertDd2Spring(tempFile, ddFilePath, dd2SpringXsltFilePath, urlForSaxonClassPath);

    // delete the file when terminating if
    // a) uimaAsDebug is not specified (is null) or
    // b) uimaAsDebug is specified, but is ""
    if (null == uimaAsDebug || uimaAsDebug.equals("")) {
      tempFile.deleteOnExit();
    }

    return tempFile;
  }

  /**
   *
   * @param tempFile
   *          file to hold generated Spring from dd2spring transform
   * @param ddFilePath
   *          file path to UIMA Deployment Descriptor - passed to saxon
   * @param dd2SpringXsltFilePath
   *          file path to dd2spring.xslt transformation file - passed to saxon
   * @param saxonClasspathURL
   *          classpath for saxon8.jar
   */
  public void convertDd2Spring(File tempFile, String ddFilePath, String dd2SpringXsltFilePath,
          URL saxonClasspathURL) throws Exception {

    // UIMA-5117 Check for saxon9.  If it is in the users's classpath an NPE is thrown in 
    // net.sf.saxon.event.ReceivingContentHandler.getNodeName while handling a getMeta request.
    try {
      Class saxonVersionClass = Class.forName("net.sf.saxon.Version");
      Method versionMethod = saxonVersionClass.getMethod("getProductVersion");
      String version = (String) versionMethod.invoke(null);
      if (version.startsWith("9")) {
        UIMAFramework.getLogger(THIS_CLASS).logrb(Level.SEVERE, THIS_CLASS.getName(), "convertDD2Spring", 
                UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE, "UIMAEE_exception__SEVERE",
                new Object[] { "saxon9 must not be in classpath" });
        throw new Dd2springException("saxon9 found in classpath - dd2spring transformation and UIMA-AS do not support saxon9");
      }
    } catch (ClassNotFoundException e) {
      // OK - saxon not in classpath
    }
    
    // UIMA-5117 - Add shutdown hook so can log when saxon gives up and calls exit :(
    ShutdownHook shutdownHook = new ShutdownHook();
    Runtime.getRuntime().addShutdownHook(shutdownHook);
    
    // Create a classloader with saxon8 that delegates to the user's classloader
    ClassLoader currentClassloader = Thread.currentThread().getContextClassLoader();
    if (null == saxonClassLoader) {
      URL[] classLoaderUrls = new URL[] { saxonClasspathURL };
      saxonClassLoader = new URLClassLoader(classLoaderUrls, currentClassloader);
    }
      
    // args for saxon
    // -l -s deployment_descriptor} -o output_file_path dd2spring.xsl_file_path <-x sax_parser_class>
    // If a custom framework includes a custom XML parser we may also need a custom parser for Saxon,
    // so check for the existence of a class with "_SAXParser" appended to the framework name.

    List argsForSaxon = new ArrayList();
    String uimaFrameworkClass = System.getProperty("uima.framework_impl");
    if (uimaFrameworkClass != null) {
      String saxonParserClass = uimaFrameworkClass + "_SAXParser";
      try {
        saxonClassLoader.loadClass(saxonParserClass);
        argsForSaxon.add("-x");
        argsForSaxon.add(saxonParserClass);
      } catch (ClassNotFoundException e) {
        // No parser class defined
      }
    }
    argsForSaxon.add("-l"); // turn on line numbers
    argsForSaxon.add("-s"); // source file
    argsForSaxon.add(ddFilePath); // source file
    argsForSaxon.add("-o"); // output file
    argsForSaxon.add(tempFile.getAbsolutePath()); // output file
    argsForSaxon.add(dd2SpringXsltFilePath); // xslt transform to apply

    UIMAFramework.getLogger(THIS_CLASS).log(Level.INFO, "Saxon args: " + argsForSaxon);

    // Set the thread classloader so that all classes are loaded from this
    Thread.currentThread().setContextClassLoader(saxonClassLoader);
    Class mainStartClass = null;
    try {
      mainStartClass = Class.forName("net.sf.saxon.Transform", true, saxonClassLoader);
      Method mainMethod = mainStartClass.getMethod("main", String[].class);
      mainMethod.invoke(null, new Object[] { argsForSaxon.toArray(new String[argsForSaxon.size()]) });
    } catch (ClassNotFoundException e) {
      System.err.println("Error - can't load Saxon jar from " + saxonClasspathURL + " for dd2spring transformation.");
      e.printStackTrace();
      UIMAFramework.getLogger(THIS_CLASS).logrb(Level.SEVERE, THIS_CLASS.getName(), "convertDD2Spring", 
              JmsConstants.JMS_LOG_RESOURCE_BUNDLE, "UIMA_dd2spring_saxon_missing_SEVERE");
      throw e;
    } catch (Exception e) {
      System.err.println("Error - dd2spring transformation failed:");
      e.printStackTrace();
      UIMAFramework.getLogger(THIS_CLASS).logrb(Level.SEVERE, THIS_CLASS.getName(), "convertDD2Spring", 
              JmsConstants.JMS_LOG_RESOURCE_BUNDLE, "UIMA_dd2spring_internal_error_calling_saxon");
      throw e;
    } finally {
      // Restore original classloader and remove used shutdown hook
      Thread.currentThread().setContextClassLoader(currentClassloader);
      Runtime.getRuntime().removeShutdownHook(shutdownHook);
    }
    return;
  }

  // Shutdown hook that reports when Saxon calls exit!
  private class ShutdownHook extends Thread {
    public void run() {
      System.err.println("ERROR in dd2spring Saxon transformation ... System.exit called");
      System.err.flush();
    }
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy