src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/xmlschema/bindinfo/BindInfo.java

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 368
0989ad8c0860
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 1997, 2011, Oracle and/or its affiliates. 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.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package com.sun.tools.internal.xjc.reader.xmlschema.bindinfo;
    28 import java.io.FilterWriter;
    29 import java.io.IOException;
    30 import java.io.StringWriter;
    31 import java.io.Writer;
    32 import java.util.ArrayList;
    33 import java.util.Iterator;
    34 import java.util.List;
    36 import javax.xml.bind.JAXBContext;
    37 import javax.xml.bind.JAXBException;
    38 import javax.xml.bind.Unmarshaller;
    39 import javax.xml.bind.annotation.XmlAnyElement;
    40 import javax.xml.bind.annotation.XmlElement;
    41 import javax.xml.bind.annotation.XmlMixed;
    42 import javax.xml.bind.annotation.XmlRootElement;
    43 import javax.xml.bind.annotation.XmlType;
    44 import javax.xml.transform.Transformer;
    45 import javax.xml.transform.TransformerException;
    46 import javax.xml.transform.dom.DOMSource;
    47 import javax.xml.transform.stream.StreamResult;
    49 import com.sun.codemodel.internal.JDocComment;
    50 import com.sun.xml.internal.bind.v2.WellKnownNamespace;
    51 import com.sun.tools.internal.xjc.SchemaCache;
    52 import com.sun.tools.internal.xjc.model.CCustomizations;
    53 import com.sun.tools.internal.xjc.model.CPluginCustomization;
    54 import com.sun.tools.internal.xjc.model.Model;
    55 import com.sun.tools.internal.xjc.reader.Ring;
    56 import com.sun.tools.internal.xjc.reader.xmlschema.BGMBuilder;
    57 import com.sun.xml.internal.bind.annotation.XmlLocation;
    58 import com.sun.xml.internal.bind.marshaller.MinimumEscapeHandler;
    59 import com.sun.xml.internal.xsom.XSComponent;
    61 import org.w3c.dom.Element;
    62 import org.xml.sax.Locator;
    64 /**
    65  * Container for customization declarations.
    66  *
    67  * We use JAXB ourselves and parse this object from "xs:annotation".
    68  *
    69  * @author
    70  *     Kohsuke Kawaguchi (kohsuke,kawaguchi@sun.com)
    71  */
    72 @XmlRootElement(namespace= WellKnownNamespace.XML_SCHEMA,name="annotation")
    73 @XmlType(namespace=WellKnownNamespace.XML_SCHEMA,name="foobar")
    74 public final class BindInfo implements Iterable<BIDeclaration> {
    76     private BGMBuilder builder;
    78     @XmlLocation
    79     private Locator location;
    81     /**
    82      * Documentation taken from &lt;xs:documentation>s.
    83      */
    84     @XmlElement(namespace=WellKnownNamespace.XML_SCHEMA)
    85     private Documentation documentation;
    87     /**
    88      * Returns true if this {@link BindInfo} doesn't contain any useful
    89      * information.
    90      *
    91      * This flag is used to discard unused {@link BindInfo}s early to save memory footprint.
    92      */
    93     public boolean isPointless() {
    94         if(size()>0)     return false;
    95         if(documentation!=null && !documentation.contents.isEmpty())
    96             return false;
    98         return true;
    99     }
   101     private static final class Documentation {
   102         @XmlAnyElement
   103         @XmlMixed
   104         List<Object> contents = new ArrayList<Object>();
   106         void addAll(Documentation rhs) {
   107             if(rhs==null)   return;
   109             if(contents==null)
   110                 contents = new ArrayList<Object>();
   111             if(!contents.isEmpty())
   112                 contents.add("\n\n");
   113             contents.addAll(rhs.contents);
   114         }
   115     }
   117     /** list of individual declarations. */
   118     private final List<BIDeclaration> decls = new ArrayList<BIDeclaration>();
   120     private static final class AppInfo {
   121         /**
   122          * Receives {@link BIDeclaration}s and other DOMs.
   123          */
   124         @XmlAnyElement(lax=true,value=DomHandlerEx.class)
   125         List<Object> contents = new ArrayList<Object>();
   127         public void addTo(BindInfo bi) {
   128             if(contents==null)  return;
   130             for (Object o : contents) {
   131                 if(o instanceof BIDeclaration)
   132                     bi.addDecl((BIDeclaration)o);
   133                 // this is really PITA! I can't get the source location
   134                 if(o instanceof DomHandlerEx.DomAndLocation) {
   135                     DomHandlerEx.DomAndLocation e = (DomHandlerEx.DomAndLocation)o;
   136                     String nsUri = e.element.getNamespaceURI();
   137                     if(nsUri==null || nsUri.equals("")
   138                     || nsUri.equals(WellKnownNamespace.XML_SCHEMA))
   139                         continue;   // this is definitely not a customization
   140                     bi.addDecl(new BIXPluginCustomization(e.element,e.loc));
   141                 }
   142             }
   143         }
   144     }
   147     // only used by JAXB
   148     @XmlElement(namespace=WellKnownNamespace.XML_SCHEMA)
   149     void setAppinfo(AppInfo aib) {
   150         aib.addTo(this);
   151     }
   155     /**
   156      * Gets the location of this annotation in the source file.
   157      *
   158      * @return
   159      *      If the declarations are in fact specified in the source
   160      *      code, a non-null valid object will be returned.
   161      *      If this BindInfo is generated internally by XJC, then
   162      *      null will be returned.
   163      */
   164     public Locator getSourceLocation() { return location; }
   167     private XSComponent owner;
   168     /**
   169      * Sets the owner schema component and a reference to BGMBuilder.
   170      * This method is called from the BGMBuilder before
   171      * any BIDeclaration inside it is used.
   172      */
   173     public void setOwner( BGMBuilder _builder, XSComponent _owner ) {
   174         this.owner = _owner;
   175         this.builder = _builder;
   176         for (BIDeclaration d : decls)
   177             d.onSetOwner();
   178     }
   179     public XSComponent getOwner() { return owner; }
   181     /**
   182      * Back pointer to the BGMBuilder which is building
   183      * a BGM from schema components including this customization.
   184      */
   185     public BGMBuilder getBuilder() { return builder; }
   187     /** Adds a new declaration. */
   188     public void addDecl( BIDeclaration decl ) {
   189         if(decl==null)  throw new IllegalArgumentException();
   190         decl.setParent(this);
   191         decls.add(decl);
   192     }
   194     /**
   195      * Gets the first declaration with a given name, or null
   196      * if none is found.
   197      */
   198     public <T extends BIDeclaration>
   199     T get( Class<T> kind ) {
   200         for( BIDeclaration decl : decls ) {
   201             if( kind.isInstance(decl) )
   202                 return kind.cast(decl);
   203         }
   204         return null; // not found
   205     }
   207     /**
   208      * Gets all the declarations
   209      */
   210     public BIDeclaration[] getDecls() {
   211         return decls.toArray(new BIDeclaration[decls.size()]);
   212     }
   214     /**
   215      * Gets the documentation parsed from &lt;xs:documentation>s.
   216      * The returned collection is to be added to {@link JDocComment#append(Object)}.
   217      * @return  maybe null.
   218      */
   219     public String getDocumentation() {
   220         // TODO: FIXME: correctly turn individual items to String including DOM
   221         if(documentation==null || documentation.contents==null) return null;
   223         StringBuilder buf = new StringBuilder();
   224         for (Object c : documentation.contents) {
   225             if(c instanceof String) {
   226                 buf.append(c.toString());
   227             }
   228             if(c instanceof Element) {
   229                 Transformer t = builder.getIdentityTransformer();
   230                 StringWriter w = new StringWriter();
   231                 try {
   232                     Writer fw = new FilterWriter(w) {
   233                         char[] buf = new char[1];
   235                         public void write(int c) throws IOException {
   236                             buf[0] = (char)c;
   237                             write(buf,0,1);
   238                         }
   240                         public void write(char[] cbuf, int off, int len) throws IOException {
   241                             MinimumEscapeHandler.theInstance.escape(cbuf,off,len,false,out);
   242                         }
   244                         public void write(String str, int off, int len) throws IOException {
   245                             write(str.toCharArray(),off,len);
   246                         }
   247                     };
   248                     t.transform(new DOMSource((Element)c),new StreamResult(fw));
   249                 } catch (TransformerException e) {
   250                     throw new Error(e); // impossible
   251                 }
   252                 buf.append("\n<pre>\n");
   253                 buf.append(w);
   254                 buf.append("\n</pre>\n");
   255             }
   256         }
   257         return buf.toString();
   258     }
   260     /**
   261      * Merges all the declarations inside the given BindInfo
   262      * to this BindInfo.
   263      */
   264     public void absorb( BindInfo bi ) {
   265         for( BIDeclaration d : bi )
   266             d.setParent(this);
   267         this.decls.addAll( bi.decls );
   269         if(this.documentation==null)
   270             this.documentation = bi.documentation;
   271         else
   272             this.documentation.addAll(bi.documentation);
   273     }
   275     /** Gets the number of declarations. */
   276     public int size() { return decls.size(); }
   278     public BIDeclaration get( int idx ) { return decls.get(idx); }
   280     public Iterator<BIDeclaration> iterator() {
   281         return decls.iterator();
   282     }
   284     /**
   285      * Gets the list of {@link CPluginCustomization}s from this.
   286      *
   287      * <p>
   288      * Note that calling this method marks all those plug-in customizations
   289      * as 'used'. So call it only when it's really necessary.
   290      */
   291     public CCustomizations toCustomizationList() {
   292         CCustomizations r=null;
   293         for( BIDeclaration d : this ) {
   294             if(d instanceof BIXPluginCustomization) {
   295                 BIXPluginCustomization pc = (BIXPluginCustomization) d;
   296                 pc.markAsAcknowledged();
   297                 if(!Ring.get(Model.class).options.pluginURIs.contains(pc.getName().getNamespaceURI()))
   298                     continue;   // this isn't a plugin customization
   299                 if(r==null)
   300                     r = new CCustomizations();
   301                 r.add(new CPluginCustomization(pc.element,pc.getLocation()));
   302             }
   303         }
   305         if(r==null)     r = CCustomizations.EMPTY;
   306         return new CCustomizations(r);
   307     }
   308     /** An instance with the empty contents. */
   309     public final static BindInfo empty = new BindInfo();
   311     /**
   312      * Lazily prepared {@link JAXBContext}.
   313      */
   314     private static volatile JAXBContext customizationContext;
   316     public static JAXBContext getCustomizationContext() {
   317         try {
   318             if (customizationContext == null) {
   319                 synchronized (BindInfo.class) {
   320                     if (customizationContext == null) {
   321                         customizationContext = JAXBContext.newInstance(
   322                                 BindInfo.class, // for xs:annotation
   323                                 BIClass.class,
   324                                 BIConversion.User.class,
   325                                 BIConversion.UserAdapter.class,
   326                                 BIDom.class,
   327                                 BIFactoryMethod.class,
   328                                 BIInlineBinaryData.class,
   329                                 BIXDom.class,
   330                                 BIXSubstitutable.class,
   331                                 BIEnum.class,
   332                                 BIEnumMember.class,
   333                                 BIGlobalBinding.class,
   334                                 BIProperty.class,
   335                                 BISchemaBinding.class);
   336                     }
   337                 }
   338             }
   339             return customizationContext;
   340         } catch (JAXBException e) {
   341             throw new AssertionError(e);
   342         }
   343     }
   345     public static Unmarshaller getCustomizationUnmarshaller() {
   346         try {
   347             return getCustomizationContext().createUnmarshaller();
   348         } catch (JAXBException e) {
   349             throw new AssertionError(e);
   350         }
   351     }
   353     /**
   354      * Lazily parsed schema for the binding file.
   355      */
   356     public static final SchemaCache bindingFileSchema = new SchemaCache(BindInfo.class.getResource("binding.xsd"));
   357 }

mercurial