1 /* 2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 3 */ 4 /* 5 * Licensed to the Apache Software Foundation (ASF) under one or more 6 * contributor license agreements. See the NOTICE file distributed with 7 * this work for additional information regarding copyright ownership. 8 * The ASF licenses this file to You under the Apache License, Version 2.0 9 * (the "License"); you may not use this file except in compliance with 10 * the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 package org.apache.qetest.xslwrapper; 21 22 import java.lang.reflect.Field; 23 import java.util.Enumeration; 24 import java.util.Properties; 25 26 import javax.xml.transform.ErrorListener; 27 import javax.xml.transform.Transformer; 28 import javax.xml.transform.TransformerFactory; 29 import javax.xml.transform.URIResolver; 30 31 /** 32 * Cheap-o utilities for Trax*Wrapper implementations. 33 * 34 */ 35 public abstract class TraxWrapperUtils { 36 37 /** 38 * Get a generic description of the TrAX related info. 39 * 40 * @return Properties block with basic info about any TrAX implementing 41 * processor, plus specific version information about Xalan-J 2.x or 42 * Xerces-J 1.x if found. 43 */ 44 public static Properties getTraxInfo() { 45 Properties p = new Properties(); 46 p.put("traxwrapper.api", "trax"); 47 p.put("traxwrapper.language", "java"); 48 try { 49 Properties sysProps = System.getProperties(); 50 p.put("traxwrapper.jaxp.transform", 51 sysProps.getProperty("javax.xml.transform.TransformerFactory", "unset")); 52 p.put("traxwrapper.jaxp.parser.dom", 53 sysProps.getProperty("javax.xml.parsers.DocumentBuilderFactory", "unset")); 54 p.put("traxwrapper.jaxp.parser.sax", 55 sysProps.getProperty("javax.xml.parsers.SAXParserFactory", "unset")); 56 } /* In case we're in an Applet */ 57 catch (SecurityException ignore) { /* no-op, ignore */ } 58 59 // Look for some Xalan/Xerces specific version info 60 try { 61 Class clazz = Class.forName("org.apache.xerces.framework.Version"); 62 // Found 1.x, grab it's version fields 63 Field f = clazz.getField("fVersion"); 64 p.put("traxwrapper.xerces.version", (String) f.get(null)); 65 } catch (ClassNotFoundException | IllegalAccessException 66 | IllegalArgumentException | NoSuchFieldException 67 | SecurityException ignore) {} 68 69 try { 70 Class clazz = Class.forName("org.apache.xalan.processor.XSLProcessorVersion"); 71 Field f = clazz.getField("S_VERSION"); 72 p.put("traxwrapper.xalan.version", (String) f.get(null)); 73 } catch (ClassNotFoundException | IllegalAccessException 74 | IllegalArgumentException | NoSuchFieldException 75 | SecurityException ignore) {} 76 77 return p; 78 } 79 80 /** 81 * Apply specific Attributes to a TransformerFactory OR Transformer, OR call 82 * specific setFoo() API's on a TransformerFactory OR Transformer. 83 * 84 * Filters on hash keys.startsWith("Processor.setAttribute"). Most Attributes 85 * are simply passed to factory.setAttribute(), however certain special 86 * cases are handled: setURIResolver, setErrorListener. Exceptions thrown by 87 * underlying transformer are propagated. 88 * 89 * This takes an Object so that an underlying worker method can process 90 * either a TransformerFactory or a Transformer. 91 * 92 * @param setPropsOn 93 * @param attrs potential attributes to set. 94 */ 95 public static void setAttributes(Object setPropsOn, 96 Properties attrs) throws IllegalArgumentException { 97 if ((null == setPropsOn) || (null == attrs)) { 98 return; 99 } 100 101 Enumeration attrKeys; 102 try { 103 // Attempt to use as a Properties block.. 104 attrKeys = attrs.propertyNames(); 105 } catch (ClassCastException cce) { 106 // .. but fallback to get as Hashtable instead 107 attrKeys = attrs.keys(); 108 } 109 110 while (attrKeys.hasMoreElements()) { 111 String key = (String) attrKeys.nextElement(); 112 // Only attempt to set the attr if it matches our marker 113 if ((null != key) 114 && (key.startsWith(TransformWrapper.SET_PROCESSOR_ATTRIBUTES))) { 115 Object value; 116 try { 117 // Attempt to use as a Properties block.. 118 value = attrs.getProperty(key); 119 // But, if null, then try getting as hash anyway 120 if (null == value) { 121 value = attrs.get(key); 122 } 123 } catch (ClassCastException cce) { 124 // .. but fallback to get as Hashtable instead 125 value = attrs.get(key); 126 } 127 // Strip off our marker for the property name 128 String processorKey = key.substring(TransformWrapper.SET_PROCESSOR_ATTRIBUTES.length()); 129 // Ugly, but it works -sc 130 if (setPropsOn instanceof TransformerFactory) { 131 setAttribute((TransformerFactory) setPropsOn, processorKey, value); 132 } else if (setPropsOn instanceof Transformer) { 133 setAttribute((Transformer) setPropsOn, processorKey, value); 134 } 135 } 136 } 137 138 } 139 140 /** 141 * Token specifying a call to setURIResolver. 142 */ 143 private final static String SET_URI_RESOLVER = "setURIResolver"; 144 145 /** 146 * Token specifying a call to setErrorListener. 147 */ 148 private final static String SET_ERROR_LISTENER = "setErrorListener"; 149 150 /** 151 * Apply specific Attributes to a TransformerFactory OR call specific 152 * setFoo() API's on a TransformerFactory. 153 * 154 * Filters on keys.startsWith("Processor.setAttribute.") Most Attributes 155 * are simply passed to factory.setAttribute(), however certain special 156 * cases are handled: setURIResolver, setErrorListener. Exceptions thrown by 157 * underlying transformer are propagated. 158 * 159 * @see setAttribute(Transformer, String, Object) 160 * @param factory TransformerFactory to call setAttributes on. 161 * @param key specific attribute or special case attribute. 162 * @param value to set for key. 163 */ 164 private static void setAttribute(TransformerFactory factory, 165 String key, Object value) throws IllegalArgumentException { 166 if ((null == factory) || (null == key)) { 167 return; 168 } 169 170 // Note: allow exceptions to propagate here 171 // Check if this is a special case to call a specific 172 // API, or the general case to call setAttribute(key...) 173 switch(key) { 174 case SET_URI_RESOLVER: 175 factory.setURIResolver((URIResolver) value); 176 break; 177 case SET_ERROR_LISTENER: 178 factory.setErrorListener((ErrorListener) value);; 179 break; 180 default: 181 // General case; just call setAttribute 182 factory.setAttribute(key, value); 183 break; 184 } 185 } 186 187 /** 188 * Apply specific Attributes to a Transformer OR call specific setFoo() 189 * API's on a Transformer. 190 * 191 * Filters on keys.startsWith("Processor.setAttribute.") Only certain 192 * special cases are handled: setURIResolver, setErrorListener. Exceptions 193 * thrown by underlying transformer are propagated. 194 * 195 * @see setAttribute(TransformerFactory, String, Object) 196 * @param factory TransformerFactory to call setAttributes on. 197 * @param key specific attribute or special case attribute. 198 * @param value to set for key. 199 */ 200 private static void setAttribute(Transformer transformer, 201 String key, Object value) throws IllegalArgumentException { 202 if ((null == transformer) || (null == key)) { 203 return; 204 } 205 206 // Note: allow exceptions to propagate here 207 // Check if this is a special case to call a specific 208 // API, or the general case to call setAttribute(key...) 209 switch(key) { 210 case SET_URI_RESOLVER: 211 transformer.setURIResolver((URIResolver) value); 212 break; 213 case SET_ERROR_LISTENER: 214 transformer.setErrorListener((ErrorListener) value); 215 break; 216 } 217 } 218 }