blob: 02bbe00e39b05820e7d97e009f2ce810af116101 [file] [log] [blame]
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache
* XMLBeans", nor may "Apache" appear in their name, without prior
* written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000-2003 BEA Systems
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/
package org.apache.xmlbeans;
import org.xml.sax.EntityResolver;
import java.util.HashMap;
import java.util.Map;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import javax.xml.namespace.QName;
/**
* Used to supply options for loading, saving, and compiling, and validating.
* <p>
* There are two styles for using XmlOptions: multiline setup, and single-line use.
* Here are two examples. First, multiline style:
* <pre>
* XmlOptions opts = new XmlOptions();
* opts.setSavePrettyPrint();
* opts.setSavePrettyPrintIndent(4);
* System.out.println(xobj.xmlText(opts));
* </pre>
*
* The alternative is single-line usage:
* <pre>
* System.out.println(xobj.xmlText(
* new XmlOptions().setSavePrettyPrint().setSavePrettyPrintIndent(4)));
* </pre>
*/
public class XmlOptions implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
private Map _map = new HashMap();
/**
* Construct a new blank XmlOptions.
*/
public XmlOptions ( ) { }
/**
* Construct a new XmlOptions, copying the options.
*/
public XmlOptions (XmlOptions other) {
if (other != null) _map.putAll(other._map);
}
//
// Handy-dandy helper methods for setting some options
//
/**
* This option will cause the saver to save namespace attributes first.
*
* @see XmlTokenSource#save(java.io.File, XmlOptions)
* @see XmlTokenSource#xmlText(XmlOptions)
*/
public XmlOptions setSaveNamespacesFirst() {
return set( SAVE_NAMESPACES_FIRST );
}
/**
* This option will cause the saver to reformat white space for easier reading.
*
* @see XmlTokenSource#save(java.io.File, XmlOptions)
* @see XmlTokenSource#xmlText(XmlOptions)
*/
public XmlOptions setSavePrettyPrint() {
return set( SAVE_PRETTY_PRINT );
}
/**
* When used with <code>setSavePrettyPrint</code> this sets the indent
* amount to use.
*
* @param indent the indent amount to use
* @see #setSavePrettyPrint
* @see XmlTokenSource#save(java.io.File, XmlOptions)
* @see XmlTokenSource#xmlText(XmlOptions)
*/
public XmlOptions setSavePrettyPrintIndent(int indent) {
return set( SAVE_PRETTY_PRINT_INDENT, indent );
}
/**
* When used with <code>setSavePrettyPrint</code> this sets the offset
* amount to use.
*
* @param offset the offset amount to use
* @see #setSavePrettyPrint
* @see XmlTokenSource#save(java.io.File, XmlOptions)
* @see XmlTokenSource#xmlText(XmlOptions)
*/
public XmlOptions setSavePrettyPrintOffset(int offset) {
return set( SAVE_PRETTY_PRINT_OFFSET, offset );
}
/**
* When parsing or writing a document, this sets the character
* encoding to use.
*
* @param encoding the character encoding
* @see XmlObject.Factory#parse(java.io.File, XmlOptions)
* @see XmlTokenSource#save(java.io.File, XmlOptions)
*/
public XmlOptions setCharacterEncoding(String encoding) {
return set( CHARACTER_ENCODING, encoding );
}
/**
* When parsing a document, this sets the type of the root
* element. If this is set, the parser will not try to guess
* the type based on the document's <code>QName</code>.
*
* @param type The root element's document type.
* @see XmlObject.Factory#parse(java.io.File, XmlOptions)
*/
public XmlOptions setDocumentType(SchemaType type) {
return set( DOCUMENT_TYPE, type );
}
/**
* <p>Sets a collection object for collecting {@link XmlError} objects
* during parsing, validation, and compilation. When set, the collection
* will contain all the errors after the operation takes place. Notice that
* the errors will only have line numbers if the document was
* loaded with line numbers enabled.</p>
*
* <p>The following simple example illustrates using an error listener
* during validation.</p>
*
* <pre>
* // Create an XmlOptions instance and set the error listener.
* XmlOptions validateOptions = new XmlOptions();
* ArrayList errorList = new ArrayList();
* validateOptions.setErrorListener(errorList);
*
* // Validate the XML.
* boolean isValid = newEmp.validate(validateOptions);
*
* // If the XML isn't valid, loop through the listener's contents,
* // printing contained messages.
* if (!isValid)
* {
* for (int i = 0; i < errorList.size(); i++)
* {
* XmlError error = (XmlError)errorList.get(i);
*
* System.out.println("\n");
* System.out.println("Message: " + error.getMessage() + "\n");
* System.out.println("Location of invalid XML: " +
* error.getCursorLocation().xmlText() + "\n");
* }
* }
* </pre>
*
* @param c A collection that will be filled with {@link XmlError} objects
* via {@link Collection#add}
*
* @see XmlError
* @see XmlObject.Factory#parse(java.io.File, XmlOptions)
* @see XmlObject#validate(XmlOptions)
* @see XmlBeans#compileXsd
* @see XmlOptions#setLoadLineNumbers
*/
public XmlOptions setErrorListener (Collection c) {
return set( ERROR_LISTENER, c );
}
/**
* Causes the saver to reduce the number of namespace prefix declarations.
* The saver will do this by passing over the document twice, first to
* collect the set of needed namespace declarations, and then second
* to actually save the document with the declarations collected
* at the root.
*
* @see XmlTokenSource#save(java.io.File, XmlOptions)
* @see XmlTokenSource#xmlText(XmlOptions)
*/
public XmlOptions setSaveAggresiveNamespaces() {
return set( SAVE_AGGRESSIVE_NAMESPACES );
}
/**
* This option causes the saver to wrap the current fragment in
* an element with the given name.
*
* @param name the name to use for the top level element
*
* @see XmlTokenSource#save(java.io.File, XmlOptions)
* @see XmlTokenSource#xmlText(XmlOptions)
*/
public XmlOptions setSaveSyntheticDocumentElement (QName name) {
return set( SAVE_SYNTHETIC_DOCUMENT_ELEMENT, name );
}
/**
* If this option is set, the saver will try to use the default
* namespace for the most commonly used URI. If it is not set
* the saver will always created named prefixes.
*
* @see XmlTokenSource#save(java.io.File, XmlOptions)
* @see XmlTokenSource#xmlText(XmlOptions)
*/
public XmlOptions setUseDefaultNamespace () {
return set( SAVE_USE_DEFAULT_NAMESPACE );
}
/**
* If namespaces have already been declared outside the scope of the
* fragment being saved, this allows those mappings to be passed
* down to the saver, so the prefixes are not re-declared.
*
* @param implicitNamespaces a map of prefixes to uris that can be
* used by the saver without being declared
*
* @see XmlTokenSource#save(java.io.File, XmlOptions)
* @see XmlTokenSource#xmlText(XmlOptions)
*/
public XmlOptions setSaveImplicitNamespaces (Map implicitNamespaces) {
return set( SAVE_IMPLICIT_NAMESPACES, implicitNamespaces );
}
/**
* A map of hints to pass to the saver for which prefixes to use
* for which namespace URI.
*
* @param suggestedPrefixes a map from URIs to prefixes
*
* @see XmlTokenSource#save(java.io.File, XmlOptions)
* @see XmlTokenSource#xmlText(XmlOptions)
*/
public XmlOptions setSaveSuggestedPrefixes (Map suggestedPrefixes) {
return set( SAVE_SUGGESTED_PREFIXES, suggestedPrefixes );
}
/**
* This option causes the saver to filter a Processing Instruction
* with the given target
*
* @param filterProcinst the name of a Processing Instruction to filter
* on save
*
* @see XmlTokenSource#save(java.io.File, XmlOptions)
* @see XmlTokenSource#xmlText(XmlOptions)
*/
public XmlOptions setSaveFilterProcinst (String filterProcinst) {
return set( SAVE_FILTER_PROCINST, filterProcinst );
}
/**
* When saving a fragment, this option changes the qname of the synthesized
* root element. Normally &lt;xml-fragment&gt; is used.
*
* @see XmlTokenSource#save(java.io.File, XmlOptions)
* @see XmlTokenSource#xmlText(XmlOptions)
*/
public XmlOptions setSaveUseOpenFrag () {
return set( SAVE_USE_OPEN_FRAGMENT );
}
/**
* This option controls whether saving begins on the element or its contents
*
* @see XmlTokenSource#save(java.io.File, XmlOptions)
* @see XmlTokenSource#xmlText(XmlOptions)
*/
public XmlOptions setSaveOuter () {
return set( SAVE_OUTER );
}
/**
* This option controls whether saving begins on the element or its contents
*
* @see XmlTokenSource#save(java.io.File, XmlOptions)
* @see XmlTokenSource#xmlText(XmlOptions)
*/
public XmlOptions setSaveInner () {
return set( SAVE_INNER );
}
/**
* If this option is set, the document element is replaced with the
* given QName when parsing. If null is supplied, the document element
* is removed.
*
* @see XmlObject.Factory#parse(java.io.File, XmlOptions)
*/
public XmlOptions setLoadReplaceDocumentElement ( QName replacement ) {
return set( LOAD_REPLACE_DOCUMENT_ELEMENT, replacement );
}
/**
* If this option is set, all insignificant whitespace is stripped
* when parsing a document. Can be used to save memory on large
* documents when you know there is no mixed content.
*
* @see XmlObject.Factory#parse(java.io.File, XmlOptions)
*/
public XmlOptions setLoadStripWhitespace () {
return set( LOAD_STRIP_WHITESPACE);
}
/**
* If this option is set, all comments are stripped when parsing
* a document.
*
* @see XmlObject.Factory#parse(java.io.File, XmlOptions)
*/
public XmlOptions setLoadStripComments() {
return set( LOAD_STRIP_COMMENTS );
}
/**
* If this option is set, all processing instructions
* are stripped when parsing a document.
*
* @see XmlObject.Factory#parse(java.io.File, XmlOptions)
*/
public XmlOptions setLoadStripProcinsts () {
return set( LOAD_STRIP_PROCINSTS );
}
/**
* If this option is set, line number annotations are placed
* in the store when parsing a document. This is particularly
* useful when you want {@link XmlError} objects to contain
* line numbers.
*
* @see XmlObject.Factory#parse(java.io.File, XmlOptions)
* @see XmlError
*/
public XmlOptions setLoadLineNumbers () {
return set( LOAD_LINE_NUMBERS );
}
/**
* This option sets a map of namespace uri substitutions that happen
* when parsing a document.
* <p>
* This is particularly useful if you
* have documents that use no namespace, but you wish to avoid
* the name collision problems that occur when you introduce
* schema definitions without a target namespace.
* <p>
* By mapping the empty string "" (the absence of a URI) to a specific
* namespace, you can force the parser to behave as if a no-namespace
* document were actually in the specified namespace. This allows you
* to type the instance according to a schema in a nonempty namespace,
* and therefore avoid the problematic practice of using schema
* definitions without a target namespace.
*
* @param substNamespaces a map of document URIs to replacement URIs
*
* @see XmlObject.Factory#parse(java.io.File, XmlOptions)
*/
public XmlOptions setLoadSubstituteNamespaces (Map substNamespaces) {
return set( LOAD_SUBSTITUTE_NAMESPACES, substNamespaces );
}
/**
* If this option is set, the underlying xml text buffer is trimmed
* immediately after parsing a document resulting in a smaller memory
* footprint. Use this option if you are loading a large number
* of unchanging documents that will stay in memory for some time.
*
* @see XmlObject.Factory#parse(java.io.File, XmlOptions)
*/
public XmlOptions setLoadTrimTextBuffer () {
return set( LOAD_TRIM_TEXT_BUFFER );
}
/**
* Set additional namespace mappings to be added when parsing
* a document.
*
* @param nses additional namespace mappings
*
* @see XmlObject.Factory#parse(java.io.File, XmlOptions)
*/
public XmlOptions setLoadAdditionalNamespaces (Map nses) {
return set( LOAD_ADDITIONAL_NAMESPACES, nses );
}
/**
* If this option is set when loading from an InputStream or File, then
* the loader will compute a 160-bit SHA-1 message digest of the XML
* file while loading it and make it available via
* XmlObject.documentProperties().getMessageDigest();
* <br>
* The schema compiler uses message digests to detect and eliminate
* duplicate imported xsd files.
*
* @see XmlObject.Factory#parse(java.io.File, XmlOptions)
*/
public XmlOptions setLoadMessageDigest () {
return set( LOAD_MESSAGE_DIGEST );
}
/**
* Sets the name of the variable that represents
* the current node in a query expression.
*
* @param varName The new variable name to use for the query.
*
* @see XmlObject#execQuery
* @see XmlCursor#execQuery
*/
public XmlOptions setXqueryCurrentNodeVar (String varName) {
return set( XQUERY_CURRENT_NODE_VAR, varName );
}
/**
* This option sets the document source name into the xml store
* when parsing a document. If a document is parsed from a
* File or URI, it is automatically set to the URI of the
* source; otherwise, for example, when parsing a String,
* you can use this option to specify the source name yourself.
*
* @see XmlObject.Factory#parse(java.lang.String, XmlOptions)
*/
public XmlOptions setDocumentSourceName (String documentSourceName) {
return set( DOCUMENT_SOURCE_NAME, documentSourceName );
}
/**
* This option allows for <code>QName</code> substitution during schema compilation.
*
* @param nameMap a map from <code>QName</code>s to substitute <code>QName</code>s.
*
* @see XmlBeans#compileXsd
*/
public XmlOptions setCompileSubstituteNames (Map nameMap) {
return set( COMPILE_SUBSTITUTE_NAMES, nameMap );
}
/**
* If this option is set, validation is not done on the Schema XmlBeans
* when building a <code>SchemaTypeSystem</code>
*
* @see XmlBeans#compileXsd
*/
public XmlOptions setCompileNoValidation () {
return set( COMPILE_NO_VALIDATION );
}
/**
* If this option is set, the unique particle attribution rule is not
* enforced when building a <code>SchemaTypeSystem</code>. See
* <a target="_blank" href="http://www.w3.org/TR/xmlschema-1/#non-ambig">Appendix H of the XML Schema specification</a>
* for information on the UPA rule.
*
* @see XmlBeans#compileXsd
*/
public XmlOptions setCompileNoUpaRule () {
return set( COMPILE_NO_UPA_RULE );
}
/**
* If this option is set, the particle valid (restriciton) rule is not
* enforced when building a <code>SchemaTypeSystem</code>. See
* <a target="_blank" href="http://www.w3.org/TR/xmlschema-1/#cos-particle-restrict">Section 3.9.6 of the XML Schema specification</a>
* for information on the PVR rule.
*
* @see XmlBeans#compileXsd
*/
public XmlOptions setCompileNoPvrRule () {
return set( COMPILE_NO_PVR_RULE );
}
/**
* If this option is set, then the schema compiler will try to download
* schemas that appear in imports and includes from network based URLs.
*
* @see XmlBeans#compileXsd
*/
public XmlOptions setCompileDownloadUrls () {
return set( COMPILE_DOWNLOAD_URLS);
}
/**
* If this option is set, then the schema compiler will permit and
* ignore multiple definitions of the same component (element, attribute,
* type, etc) names in the given namespaces. If multiple definitions
* with the same name appear, the definitions that happen to be processed
* last will be ignored.
*
* @param mdefNamespaces a set of namespace URIs as Strings
*
* @see XmlBeans#compileXsd
*/
public XmlOptions setCompileMdefNamespaces(Set mdefNamespaces)
{
return set( COMPILE_MDEF_NAMESPACES, mdefNamespaces );
}
/**
* If this option is set when an instance is created, then value
* facets will be checked on each call to a setter or getter
* method on instances of XmlObject within the instance document.
* If the facets are not satisfied, then an unchecked exception is
* thrown immediately. This option is useful for finding code that
* is introducing invalid values in an XML document, but it
* slows performance.
*
* @see XmlObject.Factory#parse(java.io.File, XmlOptions)
*/
public XmlOptions setValidateOnSet() {
return set( VALIDATE_ON_SET );
}
/**
* If this option is set when compiling a schema, then the given
* EntityResolver will be consulted in order to resolve any
* URIs while downloading imported schemas.
*
* EntityResolvers are currently only used by compileXsd; they
* are not consulted by other functions, for example, parse.
* This will likely change in the future.
*
* @see XmlBeans#compileXsd
*/
public XmlOptions setEntityResolver(EntityResolver resolver) {
return set( ENTITY_RESOLVER, resolver );
}
//
// Complete set of XmlOption's
//
// TODO - Add selectPath option to track the seletion (deault is to clean selections fast).
/** @exclude */
public static final String SAVE_NAMESPACES_FIRST = "SAVE_NAMESPACES_FIRST";
/** @exclude */
public static final String SAVE_SYNTHETIC_DOCUMENT_ELEMENT = "SAVE_SYNTHETIC_DOCUMENT_ELEMENT";
/** @exclude */
public static final String SAVE_PRETTY_PRINT = "SAVE_PRETTY_PRINT";
/** @exclude */
public static final String SAVE_PRETTY_PRINT_INDENT = "SAVE_PRETTY_PRINT_INDENT";
/** @exclude */
public static final String SAVE_PRETTY_PRINT_OFFSET = "SAVE_PRETTY_PRINT_OFFSET";
/** @exclude */
public static final String SAVE_AGGRESSIVE_NAMESPACES = "SAVE_AGGRESSIVE_NAMESPACES";
/** @exclude */
public static final String SAVE_USE_DEFAULT_NAMESPACE = "SAVE_USE_DEFAULT_NAMESPACE";
/** @exclude */
public static final String SAVE_IMPLICIT_NAMESPACES = "SAVE_IMPLICIT_NAMESPACES";
/** @exclude */
public static final String SAVE_SUGGESTED_PREFIXES = "SAVE_SUGGESTED_PREFIXES";
/** @exclude */
public static final String SAVE_FILTER_PROCINST = "SAVE_FILTER_PROCINST";
/** @exclude */
public static final String SAVE_USE_OPEN_FRAGMENT = "SAVE_USE_OPEN_FRAGMENT";
/** @exclude */
public static final String SAVE_OUTER = "SAVE_OUTER";
/** @exclude */
public static final String SAVE_INNER = "SAVE_INNER";
/** @exclude */
public static final String LOAD_REPLACE_DOCUMENT_ELEMENT = "LOAD_REPLACE_DOCUMENT_ELEMENT";
/** @exclude */
public static final String LOAD_STRIP_WHITESPACE = "LOAD_STRIP_WHITESPACE";
/** @exclude */
public static final String LOAD_STRIP_COMMENTS = "LOAD_STRIP_COMMENTS";
/** @exclude */
public static final String LOAD_STRIP_PROCINSTS = "LOAD_STRIP_PROCINSTS";
/** @exclude */
public static final String LOAD_LINE_NUMBERS = "LOAD_LINE_NUMBERS";
/** @exclude */
public static final String LOAD_SUBSTITUTE_NAMESPACES = "LOAD_SUBSTITUTE_NAMESPACES";
/** @exclude */
public static final String LOAD_TRIM_TEXT_BUFFER = "LOAD_TRIM_TEXT_BUFFER";
/** @exclude */
public static final String LOAD_ADDITIONAL_NAMESPACES = "LOAD_ADDITIONAL_NAMESPACES";
/** @exclude */
public static final String LOAD_MESSAGE_DIGEST = "LOAD_MESSAGE_DIGEST";
/** @exclude */
public static final String XQUERY_CURRENT_NODE_VAR = "XQUERY_CURRENT_NODE_VAR";
/** @exclude */
public static final String CHARACTER_ENCODING = "CHARACTER_ENCODING";
/** @exclude */
public static final String ERROR_LISTENER = "ERROR_LISTENER";
/** @exclude */
public static final String DOCUMENT_TYPE = "DOCUMENT_TYPE";
/** @exclude */
public static final String DOCUMENT_SOURCE_NAME = "DOCUMENT_SOURCE_NAME";
/** @exclude */
public static final String COMPILE_SUBSTITUTE_NAMES = "COMPILE_SUBSTITUTE_NAMES";
/** @exclude */
public static final String COMPILE_NO_VALIDATION = "COMPILE_NO_VALIDATION";
/** @exclude */
public static final String COMPILE_NO_UPA_RULE = "COMPILE_NO_UPA_RULE";
/** @exclude */
public static final String COMPILE_NO_PVR_RULE = "COMPILE_NO_PVR_RULE";
/** @exclude */
public static final String COMPILE_DOWNLOAD_URLS = "COMPILE_DOWNLOAD_URLS";
/** @exclude */
public static final String COMPILE_MDEF_NAMESPACES = "COMPILE_MDEF_NAMESPACES";
/** @exclude */
public static final String VALIDATE_ON_SET = "VALIDATE_ON_SET";
/** @exclude */
public static final String ENTITY_RESOLVER = "ENTITY_RESOLVER";
private static final XmlOptions EMPTY_OPTIONS;
static {
EMPTY_OPTIONS = new XmlOptions();
EMPTY_OPTIONS._map = Collections.unmodifiableMap(EMPTY_OPTIONS._map);
}
/** If passed null, returns an empty options object. Otherwise, returns its argument. */
public static XmlOptions maskNull(XmlOptions o) {
return (o == null) ? EMPTY_OPTIONS : o;
}
/** Used to set a generic option */
public void put ( Object option ) { put( option, null ); }
/** Used to set a generic option */
public void put ( Object option, Object value ) { _map.put(option, value); }
/** Used to set a generic option */
public void put ( Object option, int value ) { put( option, new Integer( value ) ); }
private XmlOptions set(Object option) { return set(option, null); }
private XmlOptions set(Object option, Object value) { _map.put(option, value); return this;}
private XmlOptions set(Object option, int value) { return set(option, new Integer(value)); }
/** Used to test a generic option */
public boolean hasOption ( Object option ) { return _map.containsKey( option ); }
/** Used to get a generic option */
public Object get ( Object option ) { return _map.get( option ); }
/** Used to test a generic option on an options object that may be null */
public static Object safeGet(XmlOptions o, Object option) {
return o == null ? null : o.get(option);
}
}