ohair@286: /* alanb@368: * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. ohair@286: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ohair@286: * ohair@286: * This code is free software; you can redistribute it and/or modify it ohair@286: * under the terms of the GNU General Public License version 2 only, as ohair@286: * published by the Free Software Foundation. Oracle designates this ohair@286: * particular file as subject to the "Classpath" exception as provided ohair@286: * by Oracle in the LICENSE file that accompanied this code. ohair@286: * ohair@286: * This code is distributed in the hope that it will be useful, but WITHOUT ohair@286: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ohair@286: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ohair@286: * version 2 for more details (a copy is included in the LICENSE file that ohair@286: * accompanied this code). ohair@286: * ohair@286: * You should have received a copy of the GNU General Public License version ohair@286: * 2 along with this work; if not, write to the Free Software Foundation, ohair@286: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ohair@286: * ohair@286: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@286: * or visit www.oracle.com if you need additional information or have any ohair@286: * questions. ohair@286: */ ohair@286: ohair@286: package com.sun.xml.internal.bind.v2.runtime.unmarshaller; ohair@286: ohair@286: import java.io.IOException; ohair@286: import java.io.InputStream; ohair@286: ohair@286: import javax.xml.bind.JAXBContext; ohair@286: import javax.xml.bind.JAXBElement; ohair@286: import javax.xml.bind.JAXBException; ohair@286: import javax.xml.bind.PropertyException; ohair@286: import javax.xml.bind.UnmarshalException; ohair@286: import javax.xml.bind.Unmarshaller; ohair@286: import javax.xml.bind.UnmarshallerHandler; ohair@286: import javax.xml.bind.ValidationEvent; ohair@286: import javax.xml.bind.ValidationEventHandler; ohair@286: import javax.xml.bind.annotation.adapters.XmlAdapter; ohair@286: import javax.xml.bind.attachment.AttachmentUnmarshaller; ohair@286: import javax.xml.bind.helpers.AbstractUnmarshallerImpl; ohair@286: import javax.xml.stream.XMLEventReader; ohair@286: import javax.xml.stream.XMLStreamConstants; ohair@286: import javax.xml.stream.XMLStreamException; ohair@286: import javax.xml.stream.XMLStreamReader; ohair@286: import javax.xml.stream.events.XMLEvent; ohair@286: import javax.xml.transform.Source; ohair@286: import javax.xml.transform.dom.DOMSource; ohair@286: import javax.xml.transform.sax.SAXSource; ohair@286: import javax.xml.transform.stream.StreamSource; ohair@286: import javax.xml.validation.Schema; ohair@286: ohair@286: import com.sun.xml.internal.bind.IDResolver; ohair@286: import com.sun.xml.internal.bind.api.ClassResolver; ohair@286: import com.sun.xml.internal.bind.unmarshaller.DOMScanner; ohair@286: import com.sun.xml.internal.bind.unmarshaller.InfosetScanner; ohair@286: import com.sun.xml.internal.bind.unmarshaller.Messages; ohair@286: import com.sun.xml.internal.bind.v2.ClassFactory; ohair@286: import com.sun.xml.internal.bind.v2.runtime.AssociationMap; ohair@286: import com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl; ohair@286: import com.sun.xml.internal.bind.v2.runtime.JaxBeanInfo; alanb@368: import com.sun.xml.internal.bind.v2.util.XmlFactory; ohair@286: ohair@286: import java.io.Closeable; alanb@368: import javax.xml.parsers.ParserConfigurationException; alanb@368: import javax.xml.parsers.SAXParserFactory; ohair@286: import org.w3c.dom.Document; ohair@286: import org.w3c.dom.Element; ohair@286: import org.w3c.dom.Node; ohair@286: import org.xml.sax.InputSource; ohair@286: import org.xml.sax.SAXException; ohair@286: import org.xml.sax.XMLReader; ohair@286: import org.xml.sax.helpers.DefaultHandler; ohair@286: ohair@286: /** ohair@286: * Default Unmarshaller implementation. ohair@286: * ohair@286: *

ohair@286: * This class can be extended by the generated code to provide ohair@286: * type-safe unmarshall methods. ohair@286: * ohair@286: * @author ohair@286: * Kohsuke KAWAGUCHI ohair@286: */ alanb@368: public final class UnmarshallerImpl extends AbstractUnmarshallerImpl implements ValidationEventHandler, Closeable ohair@286: { ohair@286: /** Owning {@link JAXBContext} */ ohair@286: protected final JAXBContextImpl context; ohair@286: ohair@286: /** ohair@286: * schema which will be used to validate during calls to unmarshal ohair@286: */ ohair@286: private Schema schema; ohair@286: ohair@286: public final UnmarshallingContext coordinator; ohair@286: ohair@286: /** Unmarshaller.Listener */ ohair@286: private Listener externalListener; ohair@286: ohair@286: /** ohair@286: * The attachment unmarshaller used to support MTOM and swaRef. ohair@286: */ ohair@286: private AttachmentUnmarshaller attachmentUnmarshaller; ohair@286: private IDResolver idResolver = new DefaultIDResolver(); ohair@286: ohair@286: public UnmarshallerImpl( JAXBContextImpl context, AssociationMap assoc ) { ohair@286: this.context = context; ohair@286: this.coordinator = new UnmarshallingContext( this, assoc ); ohair@286: ohair@286: try { ohair@286: setEventHandler(this); ohair@286: } catch (JAXBException e) { ohair@286: throw new AssertionError(e); // impossible ohair@286: } ohair@286: } ohair@286: ohair@286: public UnmarshallerHandler getUnmarshallerHandler() { ohair@286: return getUnmarshallerHandler(true,null); ohair@286: } ohair@286: alanb@368: private XMLReader reader = null; alanb@368: alanb@368: /** alanb@368: * Obtains a configured XMLReader. alanb@368: * alanb@368: * This method is used when the client-specified alanb@368: * {@link SAXSource} object doesn't have XMLReader. alanb@368: * alanb@368: * {@link Unmarshaller} is not re-entrant, so we will alanb@368: * only use one instance of XMLReader. alanb@368: * alanb@368: * Overriden in order to fix potential security issue. alanb@368: */ alanb@368: @Override alanb@368: protected XMLReader getXMLReader() throws JAXBException { alanb@368: if (reader == null) { alanb@368: try { alanb@368: SAXParserFactory parserFactory = XmlFactory.createParserFactory(context.disableSecurityProcessing); alanb@368: // there is no point in asking a validation because alanb@368: // there is no guarantee that the document will come with alanb@368: // a proper schemaLocation. alanb@368: parserFactory.setValidating(false); alanb@368: reader = parserFactory.newSAXParser().getXMLReader(); alanb@368: } catch (ParserConfigurationException e) { alanb@368: throw new JAXBException(e); alanb@368: } catch (SAXException e) { alanb@368: throw new JAXBException(e); alanb@368: } alanb@368: } alanb@368: return reader; alanb@368: } alanb@368: ohair@286: private SAXConnector getUnmarshallerHandler( boolean intern, JaxBeanInfo expectedType ) { alanb@368: XmlVisitor h = createUnmarshallerHandler(null, false, expectedType); alanb@368: if (intern) { ohair@286: h = new InterningXmlVisitor(h); alanb@368: } ohair@286: return new SAXConnector(h,null); ohair@286: } ohair@286: ohair@286: /** ohair@286: * Creates and configures a new unmarshalling pipe line. ohair@286: * Depending on the setting, we put a validator as a filter. ohair@286: * ohair@286: * @return ohair@286: * A component that implements both {@link UnmarshallerHandler} ohair@286: * and {@link ValidationEventHandler}. All the parsing errors ohair@286: * should be reported to this error handler for the unmarshalling ohair@286: * process to work correctly. ohair@286: * ohair@286: * Also, returned handler expects all the XML names to be interned. ohair@286: * ohair@286: */ ohair@286: public final XmlVisitor createUnmarshallerHandler(InfosetScanner scanner, boolean inplace, JaxBeanInfo expectedType ) { ohair@286: ohair@286: coordinator.reset(scanner,inplace,expectedType,idResolver); ohair@286: XmlVisitor unmarshaller = coordinator; ohair@286: ohair@286: // delegate to JAXP 1.3 for validation if the client provided a schema alanb@368: if (schema != null) { ohair@286: unmarshaller = new ValidatingUnmarshaller(schema,unmarshaller); alanb@368: } ohair@286: alanb@368: if(attachmentUnmarshaller!=null && attachmentUnmarshaller.isXOPPackage()) { ohair@286: unmarshaller = new MTOMDecorator(this,unmarshaller,attachmentUnmarshaller); alanb@368: } ohair@286: ohair@286: return unmarshaller; ohair@286: } ohair@286: ohair@286: private static final DefaultHandler dummyHandler = new DefaultHandler(); ohair@286: ohair@286: public static boolean needsInterning( XMLReader reader ) { ohair@286: // attempt to set it to true, which could fail ohair@286: try { ohair@286: reader.setFeature("http://xml.org/sax/features/string-interning",true); ohair@286: } catch (SAXException e) { ohair@286: // if it fails that's fine. we'll work around on our side ohair@286: } ohair@286: ohair@286: try { alanb@368: if (reader.getFeature("http://xml.org/sax/features/string-interning")) { ohair@286: return false; // no need for intern alanb@368: } ohair@286: } catch (SAXException e) { ohair@286: // unrecognized/unsupported ohair@286: } ohair@286: // otherwise we need intern ohair@286: return true; ohair@286: } ohair@286: ohair@286: protected Object unmarshal( XMLReader reader, InputSource source ) throws JAXBException { ohair@286: return unmarshal0(reader,source,null); ohair@286: } ohair@286: ohair@286: protected JAXBElement unmarshal( XMLReader reader, InputSource source, Class expectedType ) throws JAXBException { alanb@368: if(expectedType==null) { ohair@286: throw new IllegalArgumentException(); alanb@368: } ohair@286: return (JAXBElement)unmarshal0(reader,source,getBeanInfo(expectedType)); ohair@286: } ohair@286: ohair@286: private Object unmarshal0( XMLReader reader, InputSource source, JaxBeanInfo expectedType ) throws JAXBException { ohair@286: ohair@286: SAXConnector connector = getUnmarshallerHandler(needsInterning(reader),expectedType); ohair@286: ohair@286: reader.setContentHandler(connector); ohair@286: // saxErrorHandler will be set by the getUnmarshallerHandler method. ohair@286: // configure XMLReader so that the error will be sent to it. ohair@286: // This is essential for the UnmarshallerHandler to be able to abort ohair@286: // unmarshalling when an error is found. ohair@286: // ohair@286: // Note that when this XMLReader is provided by the client code, ohair@286: // it might be already configured to call a client error handler. ohair@286: // This will clobber such handler, if any. ohair@286: // ohair@286: // Ryan noted that we might want to report errors to such a client ohair@286: // error handler as well. ohair@286: reader.setErrorHandler(coordinator); ohair@286: ohair@286: try { ohair@286: reader.parse(source); ohair@286: } catch( IOException e ) { ohair@286: coordinator.clearStates(); ohair@286: throw new UnmarshalException(e); ohair@286: } catch( SAXException e ) { ohair@286: coordinator.clearStates(); ohair@286: throw createUnmarshalException(e); ohair@286: } ohair@286: ohair@286: Object result = connector.getResult(); ohair@286: ohair@286: // avoid keeping unnecessary references too long to let the GC ohair@286: // reclaim more memory. ohair@286: // setting null upsets some parsers, so use a dummy instance instead. ohair@286: reader.setContentHandler(dummyHandler); ohair@286: reader.setErrorHandler(dummyHandler); ohair@286: ohair@286: return result; ohair@286: } ohair@286: ohair@286: @Override ohair@286: public JAXBElement unmarshal( Source source, Class expectedType ) throws JAXBException { alanb@368: if (source instanceof SAXSource) { alanb@368: SAXSource ss = (SAXSource) source; ohair@286: alanb@368: XMLReader locReader = ss.getXMLReader(); alanb@368: if (locReader == null) { alanb@368: locReader = getXMLReader(); alanb@368: } ohair@286: alanb@368: return unmarshal(locReader, ss.getInputSource(), expectedType); ohair@286: } alanb@368: if (source instanceof StreamSource) { alanb@368: return unmarshal(getXMLReader(), streamSourceToInputSource((StreamSource) source), expectedType); ohair@286: } alanb@368: if (source instanceof DOMSource) { alanb@368: return unmarshal(((DOMSource) source).getNode(), expectedType); alanb@368: } ohair@286: ohair@286: // we don't handle other types of Source ohair@286: throw new IllegalArgumentException(); ohair@286: } ohair@286: ohair@286: public Object unmarshal0( Source source, JaxBeanInfo expectedType ) throws JAXBException { alanb@368: if (source instanceof SAXSource) { alanb@368: SAXSource ss = (SAXSource) source; ohair@286: alanb@368: XMLReader locReader = ss.getXMLReader(); alanb@368: if (locReader == null) { alanb@368: locReader = getXMLReader(); alanb@368: } ohair@286: alanb@368: return unmarshal0(locReader, ss.getInputSource(), expectedType); ohair@286: } alanb@368: if (source instanceof StreamSource) { alanb@368: return unmarshal0(getXMLReader(), streamSourceToInputSource((StreamSource) source), expectedType); ohair@286: } alanb@368: if (source instanceof DOMSource) { alanb@368: return unmarshal0(((DOMSource) source).getNode(), expectedType); alanb@368: } ohair@286: ohair@286: // we don't handle other types of Source ohair@286: throw new IllegalArgumentException(); ohair@286: } ohair@286: ohair@286: ohair@286: @Override ohair@286: public final ValidationEventHandler getEventHandler() { ohair@286: try { ohair@286: return super.getEventHandler(); ohair@286: } catch (JAXBException e) { ohair@286: // impossible ohair@286: throw new AssertionError(); ohair@286: } ohair@286: } ohair@286: ohair@286: /** ohair@286: * Returns true if an event handler is installed. ohair@286: *

ohair@286: * The default handler ignores any errors, and for that this method returns false. ohair@286: */ ohair@286: public final boolean hasEventHandler() { ohair@286: return getEventHandler()!=this; ohair@286: } ohair@286: ohair@286: @Override ohair@286: public JAXBElement unmarshal(Node node, Class expectedType) throws JAXBException { alanb@368: if (expectedType == null) { ohair@286: throw new IllegalArgumentException(); alanb@368: } ohair@286: return (JAXBElement)unmarshal0(node,getBeanInfo(expectedType)); ohair@286: } ohair@286: ohair@286: public final Object unmarshal( Node node ) throws JAXBException { ohair@286: return unmarshal0(node,null); ohair@286: } ohair@286: ohair@286: // just to make the the test harness happy by making this method accessible ohair@286: @Deprecated ohair@286: public final Object unmarshal( SAXSource source ) throws JAXBException { ohair@286: return super.unmarshal(source); ohair@286: } ohair@286: ohair@286: public final Object unmarshal0( Node node, JaxBeanInfo expectedType ) throws JAXBException { ohair@286: try { ohair@286: final DOMScanner scanner = new DOMScanner(); ohair@286: ohair@286: InterningXmlVisitor handler = new InterningXmlVisitor(createUnmarshallerHandler(null,false,expectedType)); ohair@286: scanner.setContentHandler(new SAXConnector(handler,scanner)); ohair@286: alanb@368: if(node.getNodeType() == Node.ELEMENT_NODE) { ohair@286: scanner.scan((Element)node); alanb@368: } else if(node.getNodeType() == Node.DOCUMENT_NODE) { ohair@286: scanner.scan((Document)node); alanb@368: } else { ohair@286: throw new IllegalArgumentException("Unexpected node type: "+node); alanb@368: } ohair@286: ohair@286: Object retVal = handler.getContext().getResult(); ohair@286: handler.getContext().clearResult(); ohair@286: return retVal; ohair@286: } catch( SAXException e ) { ohair@286: throw createUnmarshalException(e); ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public Object unmarshal(XMLStreamReader reader) throws JAXBException { ohair@286: return unmarshal0(reader,null); ohair@286: } ohair@286: ohair@286: @Override ohair@286: public JAXBElement unmarshal(XMLStreamReader reader, Class expectedType) throws JAXBException { alanb@368: if (expectedType==null) { ohair@286: throw new IllegalArgumentException(); alanb@368: } ohair@286: return (JAXBElement)unmarshal0(reader,getBeanInfo(expectedType)); ohair@286: } ohair@286: ohair@286: public Object unmarshal0(XMLStreamReader reader, JaxBeanInfo expectedType) throws JAXBException { ohair@286: if (reader == null) { ohair@286: throw new IllegalArgumentException( ohair@286: Messages.format(Messages.NULL_READER)); ohair@286: } ohair@286: ohair@286: int eventType = reader.getEventType(); ohair@286: if (eventType != XMLStreamConstants.START_ELEMENT ohair@286: && eventType != XMLStreamConstants.START_DOCUMENT) { ohair@286: // TODO: convert eventType into event name ohair@286: throw new IllegalStateException( ohair@286: Messages.format(Messages.ILLEGAL_READER_STATE,eventType)); ohair@286: } ohair@286: ohair@286: XmlVisitor h = createUnmarshallerHandler(null,false,expectedType); ohair@286: StAXConnector connector=StAXStreamConnector.create(reader,h); ohair@286: ohair@286: try { ohair@286: connector.bridge(); ohair@286: } catch (XMLStreamException e) { ohair@286: throw handleStreamException(e); ohair@286: } ohair@286: ohair@286: Object retVal = h.getContext().getResult(); ohair@286: h.getContext().clearResult(); ohair@286: return retVal; ohair@286: } ohair@286: ohair@286: @Override ohair@286: public JAXBElement unmarshal(XMLEventReader reader, Class expectedType) throws JAXBException { alanb@368: if(expectedType==null) { ohair@286: throw new IllegalArgumentException(); alanb@368: } ohair@286: return (JAXBElement)unmarshal0(reader,getBeanInfo(expectedType)); ohair@286: } ohair@286: ohair@286: @Override ohair@286: public Object unmarshal(XMLEventReader reader) throws JAXBException { ohair@286: return unmarshal0(reader,null); ohair@286: } ohair@286: ohair@286: private Object unmarshal0(XMLEventReader reader,JaxBeanInfo expectedType) throws JAXBException { ohair@286: if (reader == null) { ohair@286: throw new IllegalArgumentException( ohair@286: Messages.format(Messages.NULL_READER)); ohair@286: } ohair@286: ohair@286: try { ohair@286: XMLEvent event = reader.peek(); ohair@286: ohair@286: if (!event.isStartElement() && !event.isStartDocument()) { ohair@286: // TODO: convert event into event name ohair@286: throw new IllegalStateException( ohair@286: Messages.format( ohair@286: Messages.ILLEGAL_READER_STATE,event.getEventType())); ohair@286: } ohair@286: ohair@286: // Quick hack until SJSXP fixes 6270116 ohair@286: boolean isZephyr = reader.getClass().getName().equals("com.sun.xml.internal.stream.XMLReaderImpl"); ohair@286: XmlVisitor h = createUnmarshallerHandler(null,false,expectedType); alanb@368: if(!isZephyr) { ohair@286: h = new InterningXmlVisitor(h); alanb@368: } ohair@286: new StAXEventConnector(reader,h).bridge(); ohair@286: return h.getContext().getResult(); ohair@286: } catch (XMLStreamException e) { ohair@286: throw handleStreamException(e); ohair@286: } ohair@286: } ohair@286: ohair@286: public Object unmarshal0( InputStream input, JaxBeanInfo expectedType ) throws JAXBException { ohair@286: return unmarshal0(getXMLReader(),new InputSource(input),expectedType); ohair@286: } ohair@286: ohair@286: private static JAXBException handleStreamException(XMLStreamException e) { ohair@286: // StAXStreamConnector wraps SAXException to XMLStreamException. ohair@286: // XMLStreamException doesn't print its nested stack trace when it prints ohair@286: // its stack trace, so if we wrap XMLStreamException in JAXBException, ohair@286: // it becomes harder to find out the real problem. ohair@286: // So we unwrap them here. But we don't want to unwrap too eagerly, because ohair@286: // that could throw away some meaningful exception information. ohair@286: Throwable ne = e.getNestedException(); alanb@368: if(ne instanceof JAXBException) { ohair@286: return (JAXBException)ne; alanb@368: } alanb@368: if(ne instanceof SAXException) { ohair@286: return new UnmarshalException(ne); alanb@368: } ohair@286: return new UnmarshalException(e); ohair@286: } ohair@286: ohair@286: @Override ohair@286: public Object getProperty(String name) throws PropertyException { ohair@286: if(name.equals(IDResolver.class.getName())) { ohair@286: return idResolver; ohair@286: } ohair@286: return super.getProperty(name); ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void setProperty(String name, Object value) throws PropertyException { ohair@286: if(name.equals(FACTORY)) { ohair@286: coordinator.setFactories(value); ohair@286: return; ohair@286: } ohair@286: if(name.equals(IDResolver.class.getName())) { ohair@286: idResolver = (IDResolver)value; ohair@286: return; ohair@286: } ohair@286: if(name.equals(ClassResolver.class.getName())) { ohair@286: coordinator.classResolver = (ClassResolver)value; ohair@286: return; ohair@286: } ohair@286: if(name.equals(ClassLoader.class.getName())) { ohair@286: coordinator.classLoader = (ClassLoader)value; ohair@286: return; ohair@286: } ohair@286: super.setProperty(name, value); ohair@286: } ohair@286: ohair@286: public static final String FACTORY = "com.sun.xml.internal.bind.ObjectFactory"; ohair@286: ohair@286: @Override ohair@286: public void setSchema(Schema schema) { ohair@286: this.schema = schema; ohair@286: } ohair@286: ohair@286: @Override ohair@286: public Schema getSchema() { ohair@286: return schema; ohair@286: } ohair@286: ohair@286: @Override ohair@286: public AttachmentUnmarshaller getAttachmentUnmarshaller() { ohair@286: return attachmentUnmarshaller; ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void setAttachmentUnmarshaller(AttachmentUnmarshaller au) { ohair@286: this.attachmentUnmarshaller = au; ohair@286: } ohair@286: ohair@286: /** ohair@286: * @deprecated since 2.0 ohair@286: */ ohair@286: @Override ohair@286: public boolean isValidating() { ohair@286: throw new UnsupportedOperationException(); ohair@286: } ohair@286: ohair@286: /** ohair@286: * @deprecated since 2.0 ohair@286: */ ohair@286: @Override ohair@286: public void setValidating(boolean validating) { ohair@286: throw new UnsupportedOperationException(); ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void setAdapter(Class type, A adapter) { alanb@368: if (type==null) { ohair@286: throw new IllegalArgumentException(); alanb@368: } ohair@286: coordinator.putAdapter(type,adapter); ohair@286: } ohair@286: ohair@286: @Override ohair@286: public A getAdapter(Class type) { alanb@368: if(type==null) { ohair@286: throw new IllegalArgumentException(); alanb@368: } alanb@368: if(coordinator.containsAdapter(type)) { ohair@286: return coordinator.getAdapter(type); alanb@368: } else { ohair@286: return null; alanb@368: } ohair@286: } ohair@286: ohair@286: // opening up for public use ohair@286: @Override ohair@286: public UnmarshalException createUnmarshalException( SAXException e ) { ohair@286: return super.createUnmarshalException(e); ohair@286: } ohair@286: ohair@286: ohair@286: /** ohair@286: * Default error handling behavior for {@link Unmarshaller}. ohair@286: */ ohair@286: public boolean handleEvent(ValidationEvent event) { ohair@286: return event.getSeverity()!=ValidationEvent.FATAL_ERROR; ohair@286: } ohair@286: ohair@286: private static InputSource streamSourceToInputSource( StreamSource ss ) { ohair@286: InputSource is = new InputSource(); ohair@286: is.setSystemId( ss.getSystemId() ); ohair@286: is.setByteStream( ss.getInputStream() ); ohair@286: is.setCharacterStream( ss.getReader() ); ohair@286: ohair@286: return is; ohair@286: } ohair@286: ohair@286: public JaxBeanInfo getBeanInfo(Class clazz) throws JAXBException { ohair@286: return context.getBeanInfo(clazz,true); ohair@286: } ohair@286: ohair@286: @Override ohair@286: public Listener getListener() { ohair@286: return externalListener; ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void setListener(Listener listener) { ohair@286: externalListener = listener; ohair@286: } ohair@286: ohair@286: public UnmarshallingContext getContext() { ohair@286: return coordinator; ohair@286: } ohair@286: ohair@286: @Override ohair@286: @SuppressWarnings("FinalizeDeclaration") ohair@286: protected void finalize() throws Throwable { ohair@286: try { ohair@286: ClassFactory.cleanCache(); ohair@286: } finally { ohair@286: super.finalize(); ohair@286: } ohair@286: } ohair@286: ohair@286: /** ohair@286: * Must be called from same thread which created the UnmarshallerImpl instance. ohair@286: * @throws IOException ohair@286: */ ohair@286: public void close() throws IOException { ohair@286: ClassFactory.cleanCache(); ohair@286: } ohair@286: ohair@286: }