/* * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. */ /* * 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.qetest.xslwrapper; import java.lang.reflect.Field; import java.util.Enumeration; import java.util.Properties; import javax.xml.transform.ErrorListener; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.URIResolver; /** * Cheap-o utilities for Trax*Wrapper implementations. * */ public abstract class TraxWrapperUtils { /** * Get a generic description of the TrAX related info. * * @return Properties block with basic info about any TrAX implementing * processor, plus specific version information about Xalan-J 2.x or * Xerces-J 1.x if found. */ public static Properties getTraxInfo() { Properties p = new Properties(); p.put("traxwrapper.api", "trax"); p.put("traxwrapper.language", "java"); try { Properties sysProps = System.getProperties(); p.put("traxwrapper.jaxp.transform", sysProps.getProperty("javax.xml.transform.TransformerFactory", "unset")); p.put("traxwrapper.jaxp.parser.dom", sysProps.getProperty("javax.xml.parsers.DocumentBuilderFactory", "unset")); p.put("traxwrapper.jaxp.parser.sax", sysProps.getProperty("javax.xml.parsers.SAXParserFactory", "unset")); } /* In case we're in an Applet */ catch (SecurityException ignore) { /* no-op, ignore */ } // Look for some Xalan/Xerces specific version info try { Class clazz = Class.forName("org.apache.xerces.framework.Version"); // Found 1.x, grab it's version fields Field f = clazz.getField("fVersion"); p.put("traxwrapper.xerces.version", (String) f.get(null)); } catch (ClassNotFoundException | IllegalAccessException | IllegalArgumentException | NoSuchFieldException | SecurityException ignore) {} try { Class clazz = Class.forName("org.apache.xalan.processor.XSLProcessorVersion"); Field f = clazz.getField("S_VERSION"); p.put("traxwrapper.xalan.version", (String) f.get(null)); } catch (ClassNotFoundException | IllegalAccessException | IllegalArgumentException | NoSuchFieldException | SecurityException ignore) {} return p; } /** * Apply specific Attributes to a TransformerFactory OR Transformer, OR call * specific setFoo() API's on a TransformerFactory OR Transformer. * * Filters on hash keys.startsWith("Processor.setAttribute"). Most Attributes * are simply passed to factory.setAttribute(), however certain special * cases are handled: setURIResolver, setErrorListener. Exceptions thrown by * underlying transformer are propagated. * * This takes an Object so that an underlying worker method can process * either a TransformerFactory or a Transformer. * * @param setPropsOn * @param attrs potential attributes to set. */ public static void setAttributes(Object setPropsOn, Properties attrs) throws IllegalArgumentException { if ((null == setPropsOn) || (null == attrs)) { return; } Enumeration attrKeys; try { // Attempt to use as a Properties block.. attrKeys = attrs.propertyNames(); } catch (ClassCastException cce) { // .. but fallback to get as Hashtable instead attrKeys = attrs.keys(); } while (attrKeys.hasMoreElements()) { String key = (String) attrKeys.nextElement(); // Only attempt to set the attr if it matches our marker if ((null != key) && (key.startsWith(TransformWrapper.SET_PROCESSOR_ATTRIBUTES))) { Object value; try { // Attempt to use as a Properties block.. value = attrs.getProperty(key); // But, if null, then try getting as hash anyway if (null == value) { value = attrs.get(key); } } catch (ClassCastException cce) { // .. but fallback to get as Hashtable instead value = attrs.get(key); } // Strip off our marker for the property name String processorKey = key.substring(TransformWrapper.SET_PROCESSOR_ATTRIBUTES.length()); // Ugly, but it works -sc if (setPropsOn instanceof TransformerFactory) { setAttribute((TransformerFactory) setPropsOn, processorKey, value); } else if (setPropsOn instanceof Transformer) { setAttribute((Transformer) setPropsOn, processorKey, value); } } } } /** * Token specifying a call to setURIResolver. */ private final static String SET_URI_RESOLVER = "setURIResolver"; /** * Token specifying a call to setErrorListener. */ private final static String SET_ERROR_LISTENER = "setErrorListener"; /** * Apply specific Attributes to a TransformerFactory OR call specific * setFoo() API's on a TransformerFactory. * * Filters on keys.startsWith("Processor.setAttribute.") Most Attributes * are simply passed to factory.setAttribute(), however certain special * cases are handled: setURIResolver, setErrorListener. Exceptions thrown by * underlying transformer are propagated. * * @see setAttribute(Transformer, String, Object) * @param factory TransformerFactory to call setAttributes on. * @param key specific attribute or special case attribute. * @param value to set for key. */ private static void setAttribute(TransformerFactory factory, String key, Object value) throws IllegalArgumentException { if ((null == factory) || (null == key)) { return; } // Note: allow exceptions to propagate here // Check if this is a special case to call a specific // API, or the general case to call setAttribute(key...) switch(key) { case SET_URI_RESOLVER: factory.setURIResolver((URIResolver) value); break; case SET_ERROR_LISTENER: factory.setErrorListener((ErrorListener) value);; break; default: // General case; just call setAttribute factory.setAttribute(key, value); break; } } /** * Apply specific Attributes to a Transformer OR call specific setFoo() * API's on a Transformer. * * Filters on keys.startsWith("Processor.setAttribute.") Only certain * special cases are handled: setURIResolver, setErrorListener. Exceptions * thrown by underlying transformer are propagated. * * @see setAttribute(TransformerFactory, String, Object) * @param factory TransformerFactory to call setAttributes on. * @param key specific attribute or special case attribute. * @param value to set for key. */ private static void setAttribute(Transformer transformer, String key, Object value) throws IllegalArgumentException { if ((null == transformer) || (null == key)) { return; } // Note: allow exceptions to propagate here // Check if this is a special case to call a specific // API, or the general case to call setAttribute(key...) switch(key) { case SET_URI_RESOLVER: transformer.setURIResolver((URIResolver) value); break; case SET_ERROR_LISTENER: transformer.setErrorListener((ErrorListener) value); break; } } }