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.util.HashMap; 23 import javax.xml.transform.Transformer; 24 25 /** 26 * A few default implementations of TransformWrapper methods. 27 * 28 * A TransformWrapperHelper implements a few of the common methods from 29 * TransformWrapper that don't directly interact with the underlying processor. 30 * Individual wrapper implementations are free to extend this class to get some 31 * free code. 32 */ 33 public abstract class TransformWrapperHelper implements TransformWrapper { 34 35 /** 36 * Constant denoting that indent should not be set. 37 */ 38 private static final int NO_INDENT = -2; 39 40 /** 41 * Set of stylesheet parameters for use in transforms. 42 */ 43 protected final HashMap<String,String> m_params = new HashMap<>(); 44 45 /** 46 * If our wrapper has a built stylesheet ready. 47 */ 48 protected volatile boolean m_stylesheetReady = false; 49 50 /** 51 * Current number of spaces to indent, default: NO_INDENT. Users call 52 * setAttribute(ATTRIBUTE_INDENT, int) to set this. If it is set, it will be 53 * applied to an underlying processor during each transform operation, where 54 * supported. 55 */ 56 protected int m_indent = NO_INDENT; 57 58 /** 59 * Reports if a pre-built/pre-compiled stylesheet is ready; presumably built 60 * by calling buildStylesheet(xslName). 61 * 62 * @return true if one is ready; false otherwise 63 * 64 * @see #buildStylesheet(String xslName) 65 */ 66 @Override 67 public boolean isStylesheetReady() { 68 return m_stylesheetReady; 69 } 70 71 /** 72 * Set a stylesheet parameter for use in later transforms. 73 * 74 * This method merely stores the triple for use later in a transform 75 * operation. Note that the actual mechanisims for setting parameters in 76 * implementation differ, especially with regards to namespaces. 77 * 78 * Note that the namespace may not contain the "{" or "}" characters, since 79 * these would be illegal XML namespaces anyways; an 80 * IllegalArgumentException will be thrown. Note that the name may not begin 81 * with the "{" character, since it would likely be an illegal XML name 82 * anyways; an IllegalArgumentException will be thrown. 83 * 84 * @param namespace for the parameter 85 * @param name of the parameter 86 * @param value of the parameter 87 * 88 * @throws IllegalArgumentException thrown if the namespace appears to be 89 * illegal. 90 */ 91 @Override 92 public void setParameter(String namespace, String name, String value) 93 throws IllegalArgumentException { 94 if (null != namespace) { 95 if ((namespace.contains("{")) 96 || (namespace.contains("}"))) { 97 throw new IllegalArgumentException("setParameter: illegal namespace includes brackets: " + namespace); 98 } 99 } 100 if (null != name) { 101 if (name.startsWith("{")) { 102 throw new IllegalArgumentException( 103 "setParameter: illegal name begins with bracket: " + name); 104 } 105 } 106 107 if (null != namespace) { 108 m_params.put("{" + namespace + "}" + name, value); 109 } else { 110 m_params.put(name, value); 111 } 112 } 113 114 /** 115 * Get a parameter that was set with setParameter. 116 * 117 * Only returns parameters set locally, not parameters exposed by the 118 * underlying processor implementation. Not terribly useful but I always 119 * like providing gets for any sets I define. 120 * 121 * @param namespace for the parameter 122 * @param name of the parameter 123 */ 124 @Override 125 public Object getParameter(String namespace, String name) { 126 if (null == m_params) { 127 return null; 128 } 129 130 if (null != namespace) { 131 return m_params.get("{" + namespace + "}" + name); 132 } else { 133 return m_params.get(name); 134 } 135 } 136 137 /** 138 * Apply the parameters that were set with setParameter to our underlying 139 * processor implementation. 140 * 141 * Subclasses may call this to apply all set parameters during each 142 * transform if they override the applyParameter() method to set a single 143 * parameter. 144 * 145 * This is a convenience method for getting data out of m_params that was 146 * encoded by our setParameter(). 147 * 148 * @param transformer a Transformer object. 149 */ 150 protected void applyParameters(Transformer transformer) { 151 m_params.forEach((key, value) -> { 152 String namespace = null; 153 String name; 154 if (key.startsWith("{")) { 155 int idx = key.indexOf("}"); 156 namespace = key.substring(1, idx); 157 name = key.substring(idx + 1); 158 } else { 159 // namespace stays null 160 name = key; 161 } 162 // Call subclassed worker method for each parameter 163 applyParameter(transformer, namespace, name, value); 164 }); 165 } 166 167 /** 168 * Apply a single parameter to our underlying processor implementation: must 169 * be overridden. 170 * 171 * Subclasses must override; this class will throw an IllegalStateException 172 * since we can't do anything. 173 * 174 * @param transformer a Transformer object. 175 * @param namespace for the parameter, may be null 176 * @param name for the parameter, should not be null 177 * @param value for the parameter, may be null 178 */ 179 protected abstract void applyParameter(Transformer transformer, String namespace, 180 String name, String value); 181 182 /** 183 * Reset our parameters and wrapper state, and optionally force creation of 184 * a new underlying processor implementation. 185 * 186 * This class clears the indent and any parameters. Subclasses are free to 187 * call us to get this default behavior or not. Note that subclasses must 188 * clear m_stylesheetReady themselves if needed. 189 * 190 * @param newProcessor ignored in this class 191 */ 192 @Override 193 public void reset(boolean newProcessor) { 194 m_params.clear(); 195 m_indent = NO_INDENT; 196 } 197 }