/** * Copyright (C) 2004 Orbeon, Inc. * * This program is free software; you can redistribute it and/or modify it under the terms of the * GNU Lesser General Public License as published by the Free Software Foundation; either version * 2.1 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * The full text of the license is available at http://www.gnu.org/copyleft/lesser.html */ package org.orbeon.oxf.processor.converter; import org.orbeon.dom.Element; import org.orbeon.dom.QName; import org.orbeon.oxf.common.OXFException; import org.orbeon.oxf.pipeline.api.PipelineContext; import org.orbeon.oxf.processor.*; import org.orbeon.oxf.xml.TransformerUtils; import org.orbeon.oxf.xml.XPathUtils; import org.orbeon.oxf.xml.dom4j.Dom4jUtils; /** * Base class for converters. */ public abstract class ConverterBase extends ProcessorImpl { public static final String STANDARD_TEXT_CONVERTER_CONFIG_NAMESPACE_URI = "http://www.orbeon.com/oxf/converter/standard-text"; public static final String DEFAULT_ENCODING = TransformerUtils.DEFAULT_OUTPUT_ENCODING; public static final boolean DEFAULT_OMIT_XML_DECLARATION = false; public static final boolean DEFAULT_INDENT = true; public static final int DEFAULT_INDENT_AMOUNT = 0; //private static Logger logger = LoggerFactory.createLogger(ConverterBase.class); protected ConverterBase() { addInputInfo(new ProcessorInputOutputInfo(INPUT_CONFIG, getConfigSchemaNamespaceURI())); addOutputInfo(new ProcessorInputOutputInfo(OUTPUT_DATA)); } /** * Return the default content type for this converter. Must be overridden by subclasses. */ protected abstract String getDefaultContentType(); /** * Return the namespace URI of the schema validating the config input. Must be overridden by subclasses. */ protected abstract String getConfigSchemaNamespaceURI(); protected Config readConfig(PipelineContext pipelineContext) { return readCacheInputAsObject(pipelineContext, getInputByName(INPUT_CONFIG), new CacheableInputReader<Config>() { public Config read(PipelineContext pipelineContext, ProcessorInput input) { final Element configElement = readInputAsOrbeonDom(pipelineContext, input).getRootElement(); try { final Config config = new Config(); // Support a QName as method value final Element methodElement = (Element) XPathUtils.selectSingleNode(configElement, "/config/method"); if (methodElement != null) { final QName methodQName = Dom4jUtils.extractTextValueQName(methodElement, true); config.method = Dom4jUtils.qNameToExplodedQName(methodQName); } config.contentType = XPathUtils.selectStringValueNormalize(configElement, "/config/content-type"); config.encoding = XPathUtils.selectStringValueNormalize(configElement, "/config/encoding"); config.version = XPathUtils.selectStringValueNormalize(configElement, "/config/version"); config.publicDoctype = XPathUtils.selectStringValueNormalize(configElement, "/config/public-doctype"); config.systemDoctype = XPathUtils.selectStringValueNormalize(configElement, "/config/system-doctype"); config.omitXMLDeclaration = ProcessorUtils.selectBooleanValue(configElement, "/config/omit-xml-declaration", DEFAULT_OMIT_XML_DECLARATION); String standaloneString = XPathUtils.selectStringValueNormalize(configElement, "/config/standalone"); config.standalone = (standaloneString == null) ? null : new Boolean(standaloneString); config.indent = ProcessorUtils.selectBooleanValue(configElement, "/config/indent", DEFAULT_INDENT); final Integer indentAmount = XPathUtils.selectIntegerValue(configElement, "/config/indent-amount"); if (indentAmount != null) config.indentAmount = indentAmount.intValue(); return config; } catch (Exception e) { throw new OXFException(e); } } }); } /** * Represent the complete converter configuration. */ protected static class Config { public String method; public String contentType; public String encoding = DEFAULT_ENCODING; public String version; public String publicDoctype; public String systemDoctype; public boolean omitXMLDeclaration = DEFAULT_OMIT_XML_DECLARATION; public Boolean standalone; public boolean indent = DEFAULT_INDENT; public int indentAmount = DEFAULT_INDENT_AMOUNT; } /** * Implement the content type determination algorithm. * * @param config current HTTP converter configuration * @param defaultContentType content type to return if none can be found * @return content type determined */ protected static String getContentType(Config config, String defaultContentType) { return (config.contentType != null) ? config.contentType : defaultContentType; } /** * Implement the encoding determination algorithm. * * @param config current HTTP converter configuration * @param defaultEncoding encoding to return if none can be found * @return encoding determined */ protected static String getEncoding(Config config, String defaultEncoding) { return (config.encoding != null) ? config.encoding : defaultEncoding; } }