--- /dev/null 2014-09-08 10:45:56.830930409 -0700 +++ new/test/javax/xml/jaxp/libs/org/apache/qetest/xslwrapper/TraxWrapperUtils.java 2015-01-09 15:42:30.717201280 -0800 @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2015, 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; + } + } +}