/* * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.tools.internal.xjc.reader.xmlschema; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.xml.namespace.QName; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerFactory; import com.sun.codemodel.internal.JCodeModel; import com.sun.codemodel.internal.fmt.JTextFile; import com.sun.istack.internal.NotNull; import com.sun.istack.internal.Nullable; import com.sun.tools.internal.xjc.ErrorReceiver; import com.sun.tools.internal.xjc.Options; import com.sun.tools.internal.xjc.Plugin; import com.sun.tools.internal.xjc.generator.bean.field.FieldRendererFactory; import com.sun.tools.internal.xjc.model.CClassInfoParent; import com.sun.tools.internal.xjc.model.Model; import com.sun.tools.internal.xjc.reader.ModelChecker; import com.sun.tools.internal.xjc.reader.Ring; import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIDeclaration; import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIDom; import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIGlobalBinding; import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BISchemaBinding; import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BISerializable; import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BindInfo; import com.sun.tools.internal.xjc.util.CodeModelClassFactory; import com.sun.tools.internal.xjc.util.ErrorReceiverFilter; import com.sun.xml.internal.bind.api.impl.NameConverter; import com.sun.xml.internal.bind.v2.util.XmlFactory; import com.sun.xml.internal.xsom.XSAnnotation; import com.sun.xml.internal.xsom.XSAttributeUse; import com.sun.xml.internal.xsom.XSComponent; import com.sun.xml.internal.xsom.XSDeclaration; import com.sun.xml.internal.xsom.XSParticle; import com.sun.xml.internal.xsom.XSSchema; import com.sun.xml.internal.xsom.XSSchemaSet; import com.sun.xml.internal.xsom.XSSimpleType; import com.sun.xml.internal.xsom.XSTerm; import com.sun.xml.internal.xsom.XSType; import com.sun.xml.internal.xsom.XSWildcard; import com.sun.xml.internal.xsom.util.XSFinder; import org.xml.sax.Locator; /** * Root of the XML Schema binder. * *
* * @author Kohsuke Kawaguchi */ public class BGMBuilder extends BindingComponent { /** * Entry point. */ public static Model build( XSSchemaSet _schemas, JCodeModel codeModel, ErrorReceiver _errorReceiver, Options opts ) { // set up a ring final Ring old = Ring.begin(); try { ErrorReceiverFilter ef = new ErrorReceiverFilter(_errorReceiver); Ring.add(XSSchemaSet.class,_schemas); Ring.add(codeModel); Model model = new Model(opts, codeModel, null/*set later*/, opts.classNameAllocator, _schemas); Ring.add(model); Ring.add(ErrorReceiver.class,ef); Ring.add(CodeModelClassFactory.class,new CodeModelClassFactory(ef)); BGMBuilder builder = new BGMBuilder(opts.defaultPackage,opts.defaultPackage2, opts.isExtensionMode(),opts.getFieldRendererFactory(), opts.activePlugins); builder._build(); if(ef.hadError()) return null; else return model; } finally { Ring.end(old); } } /** * True if the compiler is running in the extension mode * (as opposed to the strict conformance mode.) */ public final boolean inExtensionMode; /** * If this is non-null, this package name takes over * all the schema customizations. */ public final String defaultPackage1; /** * If this is non-null, this package name will be * used when no customization is specified. */ public final String defaultPackage2; private final BindGreen green = Ring.get(BindGreen.class); private final BindPurple purple = Ring.get(BindPurple.class); public final Model model = Ring.get(Model.class); public final FieldRendererFactory fieldRendererFactory; /** * Lazily computed {@link RefererFinder}. * * @see #getReferer */ private RefererFinder refFinder; private List
* This object should be used to perform any name conversion
* needs, instead of the JJavaName class in CodeModel.
*/
public NameConverter getNameConverter() { return model.getNameConverter(); }
/** Fill-in the contents of each classes. */
private void buildContents() {
ClassSelector cs = getClassSelector();
SimpleTypeBuilder stb = Ring.get(SimpleTypeBuilder.class);
for( XSSchema s : Ring.get(XSSchemaSet.class).getSchemas() ) {
BISchemaBinding sb = getBindInfo(s).get(BISchemaBinding.class);
if(sb!=null && !sb.map) {
sb.markAsAcknowledged();
continue; // no mapping for this package
}
getClassSelector().pushClassScope( new CClassInfoParent.Package(
getClassSelector().getPackage(s.getTargetNamespace())) );
checkMultipleSchemaBindings(s);
processPackageJavadoc(s);
populate(s.getAttGroupDecls(),s);
populate(s.getAttributeDecls(),s);
populate(s.getElementDecls(),s);
populate(s.getModelGroupDecls(),s);
// fill in typeUses
for (XSType t : s.getTypes().values()) {
stb.refererStack.push(t);
model.typeUses().put( getName(t), cs.bindToType(t,s) );
stb.refererStack.pop();
}
getClassSelector().popClassScope();
}
}
/** Reports an error if there are more than one jaxb:schemaBindings customization. */
private void checkMultipleSchemaBindings( XSSchema schema ) {
ArrayListpackage.html
if the customization
* says so.
*/
private void processPackageJavadoc( XSSchema s ) {
// look for the schema-wide customization
BISchemaBinding cust = getBindInfo(s).get(BISchemaBinding.class);
if(cust==null) return; // not present
cust.markAsAcknowledged();
if( cust.getJavadoc()==null ) return; // no javadoc customization
// produce a HTML file
JTextFile html = new JTextFile("package.html");
html.setContents(cust.getJavadoc());
getClassSelector().getPackage(s.getTargetNamespace()).addResourceFile(html);
}
/**
* Gets or creates the BindInfo object associated to a schema component.
*
* @return
* Always return a non-null valid BindInfo object.
* Even if no declaration was specified, this method creates
* a new BindInfo so that new decls can be added.
*/
public BindInfo getOrCreateBindInfo( XSComponent schemaComponent ) {
BindInfo bi = _getBindInfoReadOnly(schemaComponent);
if(bi!=null) return bi;
// XSOM is read-only, so we cannot add new annotations.
// for components that didn't have annotations,
// we maintain an external map.
bi = new BindInfo();
bi.setOwner(this,schemaComponent);
externalBindInfos.put(schemaComponent,bi);
return bi;
}
/**
* Used as a constant instance to represent the empty {@link BindInfo}.
*/
private final BindInfo emptyBindInfo = new BindInfo();
/**
* Gets the BindInfo object associated to a schema component.
*
* @return
* always return a valid {@link BindInfo} object. If none
* is specified for the given component, a dummy empty BindInfo
* will be returned.
*/
public BindInfo getBindInfo( XSComponent schemaComponent ) {
BindInfo bi = _getBindInfoReadOnly(schemaComponent);
if(bi!=null) return bi;
else return emptyBindInfo;
}
/**
* Gets the BindInfo object associated to a schema component.
*
* @return
* null if no bind info is associated to this schema component.
*/
private BindInfo _getBindInfoReadOnly( XSComponent schemaComponent ) {
BindInfo bi = externalBindInfos.get(schemaComponent);
if(bi!=null) return bi;
XSAnnotation annon = schemaComponent.getAnnotation();
if(annon!=null) {
bi = (BindInfo)annon.getAnnotation();
if(bi!=null) {
if(bi.getOwner()==null)
bi.setOwner(this,schemaComponent);
return bi;
}
}
return null;
}
/**
* A map that stores binding declarations augmented by XJC.
*/
private final Map