/* * 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; } }