Save This Page
Home » openjdk-7 » com.sun.tools.internal » xjc » reader » xmlschema » bindinfo » [javadoc | source]
    1   /*
    2    * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package com.sun.tools.internal.xjc.reader.xmlschema.bindinfo;
   27   
   28   import java.util.Collections;
   29   
   30   import javax.xml.bind.JAXBContext;
   31   import javax.xml.bind.JAXBException;
   32   import javax.xml.bind.Unmarshaller;
   33   import javax.xml.bind.UnmarshallerHandler;
   34   import javax.xml.bind.helpers.DefaultValidationEventHandler;
   35   import javax.xml.validation.ValidatorHandler;
   36   
   37   import com.sun.tools.internal.xjc.Options;
   38   import com.sun.tools.internal.xjc.SchemaCache;
   39   import com.sun.tools.internal.xjc.reader.Const;
   40   import com.sun.xml.internal.bind.api.TypeReference;
   41   import com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl;
   42   import com.sun.xml.internal.xsom.parser.AnnotationContext;
   43   import com.sun.xml.internal.xsom.parser.AnnotationParser;
   44   import com.sun.xml.internal.xsom.parser.AnnotationParserFactory;
   45   
   46   import org.xml.sax.Attributes;
   47   import org.xml.sax.ContentHandler;
   48   import org.xml.sax.EntityResolver;
   49   import org.xml.sax.ErrorHandler;
   50   import org.xml.sax.SAXException;
   51   import org.xml.sax.helpers.XMLFilterImpl;
   52   
   53   /**
   54    * Implementation of XSOM {@link AnnotationParserFactory} that
   55    * parses JAXB customization declarations.
   56    *
   57    * @author
   58    *     Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
   59    */
   60   public class AnnotationParserFactoryImpl implements AnnotationParserFactory {
   61       public AnnotationParserFactoryImpl(Options opts) {
   62           this.options=opts;
   63       }
   64   
   65       private final Options options;
   66       /**
   67        * Lazily created validator, so that the schema for binding won't be
   68        * prepared unless absolutely necessary.
   69        */
   70       private ValidatorHandler validator;
   71   
   72       /**
   73        * Lazily parsed schema for the binding file.
   74        */
   75       private static final SchemaCache bindingFileSchema = new SchemaCache(AnnotationParserFactoryImpl.class.getResource("binding.xsd"));
   76   
   77       /**
   78        * Lazily prepared {@link JAXBContext}.
   79        */
   80       private static JAXBContextImpl customizationContext;
   81   
   82       private static JAXBContextImpl getJAXBContext() {
   83           synchronized(AnnotationParserFactoryImpl.class) {
   84               try {
   85                   if(customizationContext==null)
   86                       customizationContext = new JAXBContextImpl(
   87                           new Class[] {
   88                               BindInfo.class, // for xs:annotation
   89                               BIClass.class,
   90                               BIConversion.User.class,
   91                               BIConversion.UserAdapter.class,
   92                               BIDom.class,
   93                               BIXDom.class,
   94                               BIEnum.class,
   95                               BIEnumMember.class,
   96                               BIGlobalBinding.class,
   97                               BIProperty.class,
   98                               BISchemaBinding.class
   99                           }, Collections.<TypeReference>emptyList(), null, false);
  100                   return customizationContext;
  101               } catch (JAXBException e) {
  102                   throw new AssertionError(e);
  103               }
  104           }
  105       }
  106   
  107       public AnnotationParser create() {
  108           return new AnnotationParser() {
  109               private Unmarshaller u = getJAXBContext().createUnmarshaller();
  110   
  111               private UnmarshallerHandler handler;
  112   
  113               public ContentHandler getContentHandler(
  114                   AnnotationContext context, String parentElementName,
  115                   final ErrorHandler errorHandler, EntityResolver entityResolver ) {
  116   
  117                   // return a ContentHandler that validates the customization and also
  118                   // parses them into the internal structure.
  119                   if(handler!=null)
  120                       // interface contract violation.
  121                       // this method will be called only once.
  122                       throw new AssertionError();
  123   
  124                   if(options.debugMode)
  125                       try {
  126                           u.setEventHandler(new DefaultValidationEventHandler());
  127                       } catch (JAXBException e) {
  128                           throw new AssertionError(e);    // ridiculous!
  129                       }
  130   
  131                   handler = u.getUnmarshallerHandler();
  132   
  133                   // configure so that the validator will receive events for JAXB islands
  134                   return new ForkingFilter(handler) {
  135                       @Override
  136                       public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
  137                           super.startElement(uri, localName, qName, atts);
  138                           if((uri.equals(Const.JAXB_NSURI) || uri.equals(Const.XJC_EXTENSION_URI))
  139                           && getSideHandler()==null) {
  140                               // set up validator
  141                               if(validator==null)
  142                                   validator = bindingFileSchema.newValidator();
  143                               validator.setErrorHandler(errorHandler);
  144                               startForking(uri,localName,qName,atts,new ValidatorProtecter(validator));
  145                           }
  146                       }
  147                   };
  148               }
  149   
  150               public Object getResult( Object existing ) {
  151                   if(handler==null)
  152                       // interface contract violation.
  153                       // the getContentHandler method must have been called.
  154                       throw new AssertionError();
  155   
  156                   try {
  157                       BindInfo result = (BindInfo)handler.getResult();
  158   
  159                       if(existing!=null) {
  160                           BindInfo bie = (BindInfo)existing;
  161                           bie.absorb(result);
  162                           return bie;
  163                       } else {
  164                           if(!result.isPointless())
  165                               return result;   // just annotation. no meaningful customization
  166                           else
  167                               return null;
  168                       }
  169                   } catch (JAXBException e) {
  170                       throw new AssertionError(e);
  171                   }
  172               }
  173           };
  174       }
  175   
  176       private static final class ValidatorProtecter extends XMLFilterImpl {
  177           public ValidatorProtecter(ContentHandler h) {
  178               setContentHandler(h);
  179           }
  180   
  181           public void startPrefixMapping(String prefix, String uri) throws SAXException {
  182               // work around a bug in the validator implementation in Tiger
  183               super.startPrefixMapping(prefix.intern(),uri);
  184           }
  185       }
  186   }

Save This Page
Home » openjdk-7 » com.sun.tools.internal » xjc » reader » xmlschema » bindinfo » [javadoc | source]