--- /dev/null 2014-09-08 10:45:56.830930409 -0700 +++ new/test/javax/xml/jaxp/libs/org/apache/qetest/xslwrapper/TransformWrapperHelper.java 2014-12-31 11:41:19.734148208 -0800 @@ -0,0 +1,197 @@ +/* + * 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.util.HashMap; +import javax.xml.transform.Transformer; + +/** + * A few default implementations of TransformWrapper methods. + * + * A TransformWrapperHelper implements a few of the common methods from + * TransformWrapper that don't directly interact with the underlying processor. + * Individual wrapper implementations are free to extend this class to get some + * free code. + */ +public abstract class TransformWrapperHelper implements TransformWrapper { + + /** + * Constant denoting that indent should not be set. + */ + private static final int NO_INDENT = -2; + + /** + * Set of stylesheet parameters for use in transforms. + */ + protected final HashMap m_params = new HashMap<>(); + + /** + * If our wrapper has a built stylesheet ready. + */ + protected volatile boolean m_stylesheetReady = false; + + /** + * Current number of spaces to indent, default: NO_INDENT. Users call + * setAttribute(ATTRIBUTE_INDENT, int) to set this. If it is set, it will be + * applied to an underlying processor during each transform operation, where + * supported. + */ + protected int m_indent = NO_INDENT; + + /** + * Reports if a pre-built/pre-compiled stylesheet is ready; presumably built + * by calling buildStylesheet(xslName). + * + * @return true if one is ready; false otherwise + * + * @see #buildStylesheet(String xslName) + */ + @Override + public boolean isStylesheetReady() { + return m_stylesheetReady; + } + + /** + * Set a stylesheet parameter for use in later transforms. + * + * This method merely stores the triple for use later in a transform + * operation. Note that the actual mechanisims for setting parameters in + * implementation differ, especially with regards to namespaces. + * + * Note that the namespace may not contain the "{" or "}" characters, since + * these would be illegal XML namespaces anyways; an + * IllegalArgumentException will be thrown. Note that the name may not begin + * with the "{" character, since it would likely be an illegal XML name + * anyways; an IllegalArgumentException will be thrown. + * + * @param namespace for the parameter + * @param name of the parameter + * @param value of the parameter + * + * @throws IllegalArgumentException thrown if the namespace appears to be + * illegal. + */ + @Override + public void setParameter(String namespace, String name, String value) + throws IllegalArgumentException { + if (null != namespace) { + if ((namespace.contains("{")) + || (namespace.contains("}"))) { + throw new IllegalArgumentException("setParameter: illegal namespace includes brackets: " + namespace); + } + } + if (null != name) { + if (name.startsWith("{")) { + throw new IllegalArgumentException( + "setParameter: illegal name begins with bracket: " + name); + } + } + + if (null != namespace) { + m_params.put("{" + namespace + "}" + name, value); + } else { + m_params.put(name, value); + } + } + + /** + * Get a parameter that was set with setParameter. + * + * Only returns parameters set locally, not parameters exposed by the + * underlying processor implementation. Not terribly useful but I always + * like providing gets for any sets I define. + * + * @param namespace for the parameter + * @param name of the parameter + */ + @Override + public Object getParameter(String namespace, String name) { + if (null == m_params) { + return null; + } + + if (null != namespace) { + return m_params.get("{" + namespace + "}" + name); + } else { + return m_params.get(name); + } + } + + /** + * Apply the parameters that were set with setParameter to our underlying + * processor implementation. + * + * Subclasses may call this to apply all set parameters during each + * transform if they override the applyParameter() method to set a single + * parameter. + * + * This is a convenience method for getting data out of m_params that was + * encoded by our setParameter(). + * + * @param transformer a Transformer object. + */ + protected void applyParameters(Transformer transformer) { + m_params.forEach((key, value) -> { + String namespace = null; + String name; + if (key.startsWith("{")) { + int idx = key.indexOf("}"); + namespace = key.substring(1, idx); + name = key.substring(idx + 1); + } else { + // namespace stays null + name = key; + } + // Call subclassed worker method for each parameter + applyParameter(transformer, namespace, name, value); + }); + } + + /** + * Apply a single parameter to our underlying processor implementation: must + * be overridden. + * + * Subclasses must override; this class will throw an IllegalStateException + * since we can't do anything. + * + * @param transformer a Transformer object. + * @param namespace for the parameter, may be null + * @param name for the parameter, should not be null + * @param value for the parameter, may be null + */ + protected abstract void applyParameter(Transformer transformer, String namespace, + String name, String value); + + /** + * Reset our parameters and wrapper state, and optionally force creation of + * a new underlying processor implementation. + * + * This class clears the indent and any parameters. Subclasses are free to + * call us to get this default behavior or not. Note that subclasses must + * clear m_stylesheetReady themselves if needed. + * + * @param newProcessor ignored in this class + */ + @Override + public void reset(boolean newProcessor) { + m_params.clear(); + m_indent = NO_INDENT; + } +}