325N/A/*
325N/A * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
325N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
325N/A *
325N/A * This code is free software; you can redistribute it and/or modify it
325N/A * under the terms of the GNU General Public License version 2 only, as
325N/A * published by the Free Software Foundation. Oracle designates this
325N/A * particular file as subject to the "Classpath" exception as provided
325N/A * by Oracle in the LICENSE file that accompanied this code.
325N/A *
325N/A * This code is distributed in the hope that it will be useful, but WITHOUT
325N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
325N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
325N/A * version 2 for more details (a copy is included in the LICENSE file that
325N/A * accompanied this code).
325N/A *
325N/A * You should have received a copy of the GNU General Public License version
325N/A * 2 along with this work; if not, write to the Free Software Foundation,
325N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
325N/A *
325N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
325N/A * or visit www.oracle.com if you need additional information or have any
325N/A * questions.
325N/A */
325N/A
325N/Apackage com.sun.tools.internal.xjc.reader.xmlschema.bindinfo;
325N/A
325N/Aimport javax.xml.bind.JAXBException;
325N/Aimport javax.xml.bind.Unmarshaller;
325N/Aimport javax.xml.bind.UnmarshallerHandler;
325N/Aimport javax.xml.bind.helpers.DefaultValidationEventHandler;
325N/Aimport javax.xml.validation.ValidatorHandler;
325N/A
325N/Aimport com.sun.tools.internal.xjc.Options;
325N/Aimport com.sun.tools.internal.xjc.reader.Const;
325N/Aimport com.sun.xml.internal.xsom.parser.AnnotationContext;
325N/Aimport com.sun.xml.internal.xsom.parser.AnnotationParser;
325N/Aimport com.sun.xml.internal.xsom.parser.AnnotationParserFactory;
325N/Aimport com.sun.xml.internal.bind.v2.WellKnownNamespace;
325N/A
325N/Aimport org.xml.sax.Attributes;
325N/Aimport org.xml.sax.ContentHandler;
325N/Aimport org.xml.sax.EntityResolver;
325N/Aimport org.xml.sax.ErrorHandler;
325N/Aimport org.xml.sax.SAXException;
325N/Aimport org.xml.sax.SAXParseException;
325N/Aimport org.xml.sax.helpers.XMLFilterImpl;
325N/A
325N/A/**
325N/A * Implementation of XSOM {@link AnnotationParserFactory} that
325N/A * parses JAXB customization declarations.
325N/A *
325N/A * @author
325N/A * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
325N/A */
325N/Apublic class AnnotationParserFactoryImpl implements AnnotationParserFactory {
325N/A public AnnotationParserFactoryImpl(Options opts) {
325N/A this.options=opts;
325N/A }
325N/A
325N/A private final Options options;
325N/A /**
325N/A * Lazily created validator, so that the schema for binding won't be
325N/A * prepared unless absolutely necessary.
325N/A */
325N/A private ValidatorHandler validator;
325N/A
325N/A public AnnotationParser create() {
325N/A return new AnnotationParser() {
325N/A private Unmarshaller u = BindInfo.getJAXBContext().createUnmarshaller();
325N/A
325N/A private UnmarshallerHandler handler;
325N/A
325N/A public ContentHandler getContentHandler(
325N/A AnnotationContext context, String parentElementName,
325N/A final ErrorHandler errorHandler, EntityResolver entityResolver ) {
325N/A
325N/A // return a ContentHandler that validates the customization and also
325N/A // parses them into the internal structure.
325N/A if(handler!=null)
325N/A // interface contract violation.
325N/A // this method will be called only once.
325N/A throw new AssertionError();
325N/A
325N/A if(options.debugMode)
325N/A try {
325N/A u.setEventHandler(new DefaultValidationEventHandler());
325N/A } catch (JAXBException e) {
325N/A throw new AssertionError(e); // ridiculous!
325N/A }
325N/A
325N/A handler = u.getUnmarshallerHandler();
325N/A
325N/A // configure so that the validator will receive events for JAXB islands
325N/A return new ForkingFilter(handler) {
325N/A @Override
325N/A public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
325N/A super.startElement(uri, localName, qName, atts);
325N/A if((uri.equals(Const.JAXB_NSURI) || uri.equals(Const.XJC_EXTENSION_URI))
325N/A && getSideHandler()==null) {
325N/A // set up validator
325N/A if(validator==null)
325N/A validator = BindInfo.bindingFileSchema.newValidator();
325N/A validator.setErrorHandler(errorHandler);
325N/A startForking(uri,localName,qName,atts,new ValidatorProtecter(validator));
325N/A }
325N/A
325N/A // check for xmime:expectedContentTypes attributes in annotations and report them
325N/A for( int i=atts.getLength()-1; i>=0; i-- ) {
325N/A if(atts.getURI(i).equals(WellKnownNamespace.XML_MIME_URI)
325N/A && atts.getLocalName(i).equals(Const.EXPECTED_CONTENT_TYPES))
325N/A errorHandler.warning(new SAXParseException(
325N/A com.sun.tools.internal.xjc.reader.xmlschema.Messages.format(
325N/A com.sun.tools.internal.xjc.reader.xmlschema.Messages.WARN_UNUSED_EXPECTED_CONTENT_TYPES),
325N/A getDocumentLocator()
325N/A ));
325N/A }
325N/A }
325N/A };
325N/A }
325N/A
325N/A public BindInfo getResult( Object existing ) {
325N/A if(handler==null)
325N/A // interface contract violation.
325N/A // the getContentHandler method must have been called.
325N/A throw new AssertionError();
325N/A
325N/A try {
325N/A BindInfo result = (BindInfo)handler.getResult();
325N/A
325N/A if(existing!=null) {
325N/A BindInfo bie = (BindInfo)existing;
325N/A bie.absorb(result);
325N/A return bie;
325N/A } else {
325N/A if(!result.isPointless())
325N/A return result; // just annotation. no meaningful customization
325N/A else
325N/A return null;
325N/A }
325N/A } catch (JAXBException e) {
325N/A throw new AssertionError(e);
325N/A }
325N/A }
325N/A };
325N/A }
325N/A
325N/A private static final class ValidatorProtecter extends XMLFilterImpl {
325N/A public ValidatorProtecter(ContentHandler h) {
325N/A setContentHandler(h);
325N/A }
325N/A
325N/A @Override
325N/A public void startPrefixMapping(String prefix, String uri) throws SAXException {
325N/A // work around a bug in the validator implementation in Tiger
325N/A super.startPrefixMapping(prefix.intern(),uri);
325N/A }
325N/A }
325N/A}