blob: 5c28509f701396240ae2d3e116e666e6f06b8a2e [file] [log] [blame]
/* Copyright 2004 The Apache Software Foundation
*
* Licensed 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.xmlbeans;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Node;
import javax.xml.stream.XMLStreamReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.lang.ref.SoftReference;
/**
* A hook for the XML Bean Factory mechanism.
* Provided for advanced users who wish to provide their own
* implementation of the Factory.parse methods. This is used, for example,
* to defer reading XML streams until needed.
* <p>
* To use the hook, call XmlFactoryHook.ThreadContext.setHook(), passing
* your own XmlFactoryHook implementation. Then every call to a Factory
* method will be delgated to your hook.
*
* <pre>
* MyHook hook = new MyHook();
* XmlFactoryHook.ThreadContext.setHook(hook);
* // this results in a call to hook.parse(...)
* XmlObject.Factory.parse(new File("test.xml"));
* </pre>
* <p>
* If the hook needs to turn around and invoke the built-in parsers, then
* it should do so by calling the appropriate method on the passed
* SchemaTypeLoader. Since SchemaTypeLoader.parse() methods delegate
* to the registered hook, a hook that wishes to actually invoke the
* default parser without having itself called back again should
* unregister itself before calling loader.parse(), and then re-register
* itself again after the call.
* <pre>
* void parse(SchemaTypeLoader loader, ...)
* {
* XmlFactoryHook remember = XmlFactoryHook.ThreadContext.getHook();
* XmlFactoryHook.ThreadContext.setHook(null);
* loader.parse(...); // isn't hooked.
* XmlFactoryHook.ThreadContext.setHook(remember);
* }
* </pre>
*/
public interface XmlFactoryHook {
/**
* Hooks Factory.newInstance calls
*/
XmlObject newInstance(SchemaTypeLoader loader, SchemaType type, XmlOptions options);
/**
* Hooks Factory.parse calls
*/
XmlObject parse(SchemaTypeLoader loader, String xmlText, SchemaType type, XmlOptions options) throws XmlException;
/**
* Hooks Factory.parse calls
*/
XmlObject parse(SchemaTypeLoader loader, InputStream jiois, SchemaType type, XmlOptions options) throws XmlException, IOException;
/**
* Hooks Factory.parse calls
*/
XmlObject parse(SchemaTypeLoader loader, XMLStreamReader xsr, SchemaType type, XmlOptions options) throws XmlException;
/**
* Hooks Factory.parse calls
*/
XmlObject parse(SchemaTypeLoader loader, Reader jior, SchemaType type, XmlOptions options) throws XmlException, IOException;
/**
* Hooks Factory.parse calls
*/
XmlObject parse(SchemaTypeLoader loader, Node node, SchemaType type, XmlOptions options) throws XmlException;
/**
* Hooks Factory.newXmlSaxHandler calls
*/
XmlSaxHandler newXmlSaxHandler(SchemaTypeLoader loader, SchemaType type, XmlOptions options);
/**
* Hooks Factory.newDomImplementation calls
*/
DOMImplementation newDomImplementation(SchemaTypeLoader loader, XmlOptions options);
/**
* Used to manage the XmlFactoryHook for the current thread.
*/
final class ThreadContext {
private static final ThreadLocal<SoftReference<XmlFactoryHook>> threadHook = new ThreadLocal<>();
public static void clearThreadLocals() {
threadHook.remove();
}
/**
* Returns the current thread's hook, or null if none.
*/
public static XmlFactoryHook getHook() {
SoftReference<XmlFactoryHook> softRef = threadHook.get();
return softRef == null ? null : softRef.get();
}
/**
* Sets the hook for the current thread.
*/
public static void setHook(XmlFactoryHook hook) {
threadHook.set(new SoftReference<>(hook));
}
// provided to prevent unwanted construction
private ThreadContext() {
}
}
}