feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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 com.sun.tools.internal.xjc.model.CElement;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
|
||||
/**
|
||||
* {@link ClassBinder} that marks abstract components as abstract.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi (kk@kohsuke.org)
|
||||
*/
|
||||
class Abstractifier extends ClassBinderFilter {
|
||||
public Abstractifier(ClassBinder core) {
|
||||
super(core);
|
||||
}
|
||||
|
||||
public CElement complexType(XSComplexType xs) {
|
||||
CElement ci = super.complexType(xs);
|
||||
if(ci!=null && xs.isAbstract())
|
||||
ci.setAbstract();
|
||||
return ci;
|
||||
}
|
||||
|
||||
public CElement elementDecl(XSElementDecl xs) {
|
||||
CElement ci = super.elementDecl(xs);
|
||||
if(ci!=null && xs.isAbstract())
|
||||
ci.setAbstract();
|
||||
return ci;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,568 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.
|
||||
*
|
||||
* <div><img src="doc-files/binding_chart.png"/></div>
|
||||
*
|
||||
* @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<Plugin> activePlugins;
|
||||
|
||||
protected BGMBuilder(String defaultPackage1, String defaultPackage2,
|
||||
boolean _inExtensionMode, FieldRendererFactory fieldRendererFactory,
|
||||
List<Plugin> activePlugins) {
|
||||
this.inExtensionMode = _inExtensionMode;
|
||||
this.defaultPackage1 = defaultPackage1;
|
||||
this.defaultPackage2 = defaultPackage2;
|
||||
this.fieldRendererFactory = fieldRendererFactory;
|
||||
this.activePlugins = activePlugins;
|
||||
promoteGlobalBindings();
|
||||
}
|
||||
|
||||
private void _build() {
|
||||
// do the binding
|
||||
buildContents();
|
||||
getClassSelector().executeTasks();
|
||||
|
||||
// additional error check
|
||||
// Reports unused customizations to the user as errors.
|
||||
Ring.get(UnusedCustomizationChecker.class).run();
|
||||
|
||||
Ring.get(ModelChecker.class).check();
|
||||
|
||||
for( Plugin ma : activePlugins )
|
||||
ma.postProcessModel(model, Ring.get(ErrorReceiver.class));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** List up all the global bindings. */
|
||||
private void promoteGlobalBindings() {
|
||||
// promote any global bindings in the schema
|
||||
XSSchemaSet schemas = Ring.get(XSSchemaSet.class);
|
||||
|
||||
for( XSSchema s : schemas.getSchemas() ) {
|
||||
BindInfo bi = getBindInfo(s);
|
||||
|
||||
// collect all global customizations
|
||||
model.getCustomizations().addAll(bi.toCustomizationList());
|
||||
|
||||
BIGlobalBinding gb = bi.get(BIGlobalBinding.class);
|
||||
if(gb==null)
|
||||
continue;
|
||||
|
||||
gb.markAsAcknowledged();
|
||||
|
||||
if(globalBinding==null) {
|
||||
globalBinding = gb;
|
||||
} else {
|
||||
if (!globalBinding.isEqual(gb)) { // see Issue 687 - this may happen with syntactically imported documents
|
||||
// acknowledge this customization and report an error
|
||||
// otherwise the user will see "customization is attached to a wrong place" error,
|
||||
// which is incorrect
|
||||
getErrorReporter().error( gb.getLocation(),
|
||||
Messages.ERR_MULTIPLE_GLOBAL_BINDINGS);
|
||||
getErrorReporter().error( globalBinding.getLocation(),
|
||||
Messages.ERR_MULTIPLE_GLOBAL_BINDINGS_OTHER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( globalBinding==null ) {
|
||||
// no global customization is present.
|
||||
// use the default one
|
||||
globalBinding = new BIGlobalBinding();
|
||||
BindInfo big = new BindInfo();
|
||||
big.addDecl(globalBinding);
|
||||
big.setOwner(this,null);
|
||||
}
|
||||
|
||||
// code generation mode
|
||||
model.strategy = globalBinding.getCodeGenerationStrategy();
|
||||
model.rootClass = globalBinding.getSuperClass();
|
||||
model.rootInterface = globalBinding.getSuperInterface();
|
||||
|
||||
particleBinder = globalBinding.isSimpleMode() ? new ExpressionParticleBinder() : new DefaultParticleBinder();
|
||||
|
||||
// check XJC extensions and realize them
|
||||
BISerializable serial = globalBinding.getSerializable();
|
||||
if(serial!=null) {
|
||||
model.serializable = true;
|
||||
model.serialVersionUID = serial.uid;
|
||||
}
|
||||
|
||||
// obtain the name conversion mode
|
||||
if (globalBinding.nameConverter!=null)
|
||||
model.setNameConverter(globalBinding.nameConverter);
|
||||
|
||||
// attach global conversions to the appropriate simple types
|
||||
globalBinding.dispatchGlobalConversions(schemas);
|
||||
|
||||
globalBinding.errorCheck();
|
||||
}
|
||||
|
||||
/**
|
||||
* Global bindings.
|
||||
*
|
||||
* The empty global binding is set as the default, so that
|
||||
* there will be no need to test if the value is null.
|
||||
*/
|
||||
private BIGlobalBinding globalBinding;
|
||||
|
||||
/**
|
||||
* Gets the global bindings.
|
||||
*/
|
||||
public @NotNull BIGlobalBinding getGlobalBinding() { return globalBinding; }
|
||||
|
||||
|
||||
private ParticleBinder particleBinder;
|
||||
|
||||
/**
|
||||
* Gets the particle binder for this binding.
|
||||
*/
|
||||
public @NotNull ParticleBinder getParticleBinder() { return particleBinder; }
|
||||
|
||||
|
||||
/**
|
||||
* Name converter that implements "XML->Java name conversion"
|
||||
* as specified in the spec.
|
||||
*
|
||||
* This object abstracts the detail that we use different name
|
||||
* conversion depending on the customization.
|
||||
*
|
||||
* <p>
|
||||
* 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 ) {
|
||||
ArrayList<Locator> locations = new ArrayList<Locator>();
|
||||
|
||||
BindInfo bi = getBindInfo(schema);
|
||||
for( BIDeclaration bid : bi ) {
|
||||
if( bid.getName()==BISchemaBinding.NAME )
|
||||
locations.add( bid.getLocation() );
|
||||
}
|
||||
if(locations.size()<=1) return; // OK
|
||||
|
||||
// error
|
||||
getErrorReporter().error( locations.get(0),
|
||||
Messages.ERR_MULTIPLE_SCHEMA_BINDINGS,
|
||||
schema.getTargetNamespace() );
|
||||
for( int i=1; i<locations.size(); i++ )
|
||||
getErrorReporter().error( (Locator)locations.get(i),
|
||||
Messages.ERR_MULTIPLE_SCHEMA_BINDINGS_LOCATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link ClassSelector} for each item in the iterator
|
||||
* to populate class items if there is any.
|
||||
*/
|
||||
private void populate( Map<String,? extends XSComponent> col, XSSchema schema ) {
|
||||
ClassSelector cs = getClassSelector();
|
||||
for( XSComponent sc : col.values() )
|
||||
cs.bindToType(sc,schema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates <code>package.html</code> 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<XSComponent,BindInfo> externalBindInfos = new HashMap<XSComponent,BindInfo>();
|
||||
|
||||
/**
|
||||
* Gets the {@link BIDom} object that applies to the given particle.
|
||||
*/
|
||||
protected final BIDom getLocalDomCustomization( XSParticle p ) {
|
||||
if (p == null) {
|
||||
return null;
|
||||
}
|
||||
BIDom dom = getBindInfo(p).get(BIDom.class);
|
||||
if(dom!=null) return dom;
|
||||
|
||||
// if not, the term might have one.
|
||||
dom = getBindInfo(p.getTerm()).get(BIDom.class);
|
||||
if(dom!=null) return dom;
|
||||
|
||||
XSTerm t = p.getTerm();
|
||||
// type could also have one, in case of the dom customization
|
||||
if(t.isElementDecl())
|
||||
return getBindInfo(t.asElementDecl().getType()).get(BIDom.class);
|
||||
// similarly the model group in a model group definition may have one.
|
||||
if(t.isModelGroupDecl())
|
||||
return getBindInfo(t.asModelGroupDecl().getModelGroup()).get(BIDom.class);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the component should be processed by purple.
|
||||
*/
|
||||
private final XSFinder toPurple = new XSFinder() {
|
||||
@Override
|
||||
public Boolean attributeUse(XSAttributeUse use) {
|
||||
// attribute use always maps to a property
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean simpleType(XSSimpleType xsSimpleType) {
|
||||
// simple type always maps to a type, hence we should take purple
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean wildcard(XSWildcard xsWildcard) {
|
||||
// attribute wildcards always maps to a property.
|
||||
// element wildcards should have been processed with particle binders
|
||||
return true;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* If the component maps to a property, forwards to purple, otherwise to green.
|
||||
*
|
||||
* If the component is mapped to a type, this method needs to return true.
|
||||
* See the chart at the class javadoc.
|
||||
*/
|
||||
public void ying( XSComponent sc, @Nullable XSComponent referer ) {
|
||||
if(sc.apply(toPurple)==true || getClassSelector().bindToType(sc,referer)!=null)
|
||||
sc.visit(purple);
|
||||
else
|
||||
sc.visit(green);
|
||||
}
|
||||
|
||||
private Transformer identityTransformer;
|
||||
|
||||
/**
|
||||
* Gets the shared instance of the identity transformer.
|
||||
*/
|
||||
public Transformer getIdentityTransformer() {
|
||||
try {
|
||||
if(identityTransformer==null) {
|
||||
TransformerFactory tf = XmlFactory.createTransformerFactory(model.options.disableXmlSecurity);
|
||||
identityTransformer = tf.newTransformer();
|
||||
}
|
||||
return identityTransformer;
|
||||
} catch (TransformerConfigurationException e) {
|
||||
throw new Error(e); // impossible
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all types that refer to the given complex type.
|
||||
*/
|
||||
public Set<XSComponent> getReferer(XSType c) {
|
||||
if(refFinder==null) {
|
||||
refFinder = new RefererFinder();
|
||||
refFinder.schemaSet(Ring.get(XSSchemaSet.class));
|
||||
}
|
||||
return refFinder.getReferer(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the QName of the declaration.
|
||||
* @return null
|
||||
* if the declaration is anonymous.
|
||||
*/
|
||||
public static QName getName(XSDeclaration decl) {
|
||||
String local = decl.getName();
|
||||
if(local==null) return null;
|
||||
return new QName(decl.getTargetNamespace(),local);
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives a name from a schema component.
|
||||
*
|
||||
* This method handles prefix/suffix modification and
|
||||
* XML-to-Java name conversion.
|
||||
*
|
||||
* @param name
|
||||
* The base name. This should be things like element names
|
||||
* or type names.
|
||||
* @param comp
|
||||
* The component from which the base name was taken.
|
||||
* Used to determine how names are modified.
|
||||
*/
|
||||
public String deriveName( String name, XSComponent comp ) {
|
||||
XSSchema owner = comp.getOwnerSchema();
|
||||
|
||||
name = getNameConverter().toClassName(name);
|
||||
|
||||
if( owner!=null ) {
|
||||
BISchemaBinding sb = getBindInfo(owner).get(BISchemaBinding.class);
|
||||
|
||||
if(sb!=null) name = sb.mangleClassName(name,comp);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isGenerateMixedExtensions() {
|
||||
if (globalBinding != null) {
|
||||
return globalBinding.isGenerateMixedExtensions();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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 com.sun.xml.internal.xsom.XSAttGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSAttributeDecl;
|
||||
import com.sun.xml.internal.xsom.XSAttributeUse;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSContentType;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
import com.sun.xml.internal.xsom.XSModelGroup;
|
||||
import com.sun.xml.internal.xsom.XSModelGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSParticle;
|
||||
import com.sun.xml.internal.xsom.XSSimpleType;
|
||||
import com.sun.xml.internal.xsom.XSWildcard;
|
||||
|
||||
/**
|
||||
* This is the first color invoked from the parent component.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
final class BindBlue extends ColorBinder {
|
||||
|
||||
public void complexType(XSComplexType ct) {
|
||||
// TODO: implement this method later
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void elementDecl(XSElementDecl e) {
|
||||
// TODO: implement this method later
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void wildcard(XSWildcard xsWildcard) {
|
||||
// TODO: implement this method later
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void attGroupDecl(XSAttGroupDecl xsAttGroupDecl) {
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void attributeDecl(XSAttributeDecl xsAttributeDecl) {
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void attributeUse(XSAttributeUse use) {
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void modelGroupDecl(XSModelGroupDecl xsModelGroupDecl) {
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void modelGroup(XSModelGroup xsModelGroup) {
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void particle(XSParticle xsParticle) {
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void empty(XSContentType xsContentType) {
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Components that always map to a type
|
||||
*/
|
||||
public void simpleType(XSSimpleType type) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.Iterator;
|
||||
|
||||
import com.sun.tools.internal.xjc.reader.Ring;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.ct.ComplexTypeFieldBuilder;
|
||||
import com.sun.xml.internal.xsom.XSAttContainer;
|
||||
import com.sun.xml.internal.xsom.XSAttGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSAttributeDecl;
|
||||
import com.sun.xml.internal.xsom.XSAttributeUse;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSContentType;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
import com.sun.xml.internal.xsom.XSModelGroup;
|
||||
import com.sun.xml.internal.xsom.XSModelGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSParticle;
|
||||
import com.sun.xml.internal.xsom.XSSimpleType;
|
||||
import com.sun.xml.internal.xsom.XSWildcard;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public final class BindGreen extends ColorBinder {
|
||||
|
||||
private final ComplexTypeFieldBuilder ctBuilder = Ring.get(ComplexTypeFieldBuilder.class);
|
||||
|
||||
public void attGroupDecl(XSAttGroupDecl ag) {
|
||||
attContainer(ag);
|
||||
}
|
||||
|
||||
public void attContainer(XSAttContainer cont) {
|
||||
// inline
|
||||
Iterator itr = cont.iterateDeclaredAttributeUses();
|
||||
while(itr.hasNext())
|
||||
builder.ying((XSAttributeUse)itr.next(),cont);
|
||||
itr = cont.iterateAttGroups();
|
||||
while(itr.hasNext())
|
||||
builder.ying((XSAttGroupDecl)itr.next(),cont);
|
||||
|
||||
XSWildcard w = cont.getAttributeWildcard();
|
||||
if(w!=null)
|
||||
builder.ying(w,cont);
|
||||
}
|
||||
|
||||
public void complexType(XSComplexType ct) {
|
||||
ctBuilder.build(ct);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void attributeDecl(XSAttributeDecl xsAttributeDecl) {
|
||||
// TODO: implement this method later
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void wildcard(XSWildcard xsWildcard) {
|
||||
// TODO: implement this method later
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void modelGroupDecl(XSModelGroupDecl xsModelGroupDecl) {
|
||||
// TODO: implement this method later
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void modelGroup(XSModelGroup xsModelGroup) {
|
||||
// TODO: implement this method later
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void elementDecl(XSElementDecl xsElementDecl) {
|
||||
// TODO: implement this method later
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void particle(XSParticle xsParticle) {
|
||||
// TODO: implement this method later
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void empty(XSContentType xsContentType) {
|
||||
// TODO: implement this method later
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Components for which ying should yield to purple.
|
||||
|
||||
*/
|
||||
public void simpleType(XSSimpleType xsSimpleType) {
|
||||
// simple type always maps to a type, so this is never possible
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public void attributeUse(XSAttributeUse use) {
|
||||
// attribute use always maps to a property
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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 com.sun.tools.internal.xjc.model.CClassInfo;
|
||||
import com.sun.tools.internal.xjc.model.CDefaultValue;
|
||||
import com.sun.tools.internal.xjc.model.CPropertyInfo;
|
||||
import com.sun.tools.internal.xjc.model.TypeUse;
|
||||
import com.sun.tools.internal.xjc.model.CClass;
|
||||
import com.sun.tools.internal.xjc.reader.Ring;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIProperty;
|
||||
import com.sun.xml.internal.xsom.XSAttGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSAttributeDecl;
|
||||
import com.sun.xml.internal.xsom.XSAttributeUse;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSContentType;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
import com.sun.xml.internal.xsom.XSModelGroup;
|
||||
import com.sun.xml.internal.xsom.XSModelGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSParticle;
|
||||
import com.sun.xml.internal.xsom.XSSimpleType;
|
||||
import com.sun.xml.internal.xsom.XSWildcard;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public class BindPurple extends ColorBinder {
|
||||
public void attGroupDecl(XSAttGroupDecl xsAttGroupDecl) {
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void attributeDecl(XSAttributeDecl xsAttributeDecl) {
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attribute use always becomes a property.
|
||||
*/
|
||||
public void attributeUse(XSAttributeUse use) {
|
||||
boolean hasFixedValue = use.getFixedValue()!=null;
|
||||
BIProperty pc = BIProperty.getCustomization(use);
|
||||
|
||||
// map to a constant property ?
|
||||
boolean toConstant = pc.isConstantProperty() && hasFixedValue;
|
||||
TypeUse attType = bindAttDecl(use.getDecl());
|
||||
|
||||
CPropertyInfo prop = pc.createAttributeProperty( use, attType );
|
||||
|
||||
if(toConstant) {
|
||||
prop.defaultValue = CDefaultValue.create(attType,use.getFixedValue());
|
||||
prop.realization = builder.fieldRendererFactory.getConst(prop.realization);
|
||||
} else
|
||||
if(!attType.isCollection() && (prop.baseType == null ? true : !prop.baseType.isPrimitive())) {
|
||||
// don't support a collection default value. That's difficult to do.
|
||||
// primitive types default value is problematic too - we can't check whether it has been set or no ( ==null) isn't possible TODO: emit a waring in these cases
|
||||
|
||||
if(use.getDefaultValue()!=null) {
|
||||
// this attribute use has a default value.
|
||||
// the item type is guaranteed to be a leaf type... or TODO: is it really so?
|
||||
// don't support default values if it's a list
|
||||
prop.defaultValue = CDefaultValue.create(attType,use.getDefaultValue());
|
||||
} else
|
||||
if(use.getFixedValue()!=null) {
|
||||
prop.defaultValue = CDefaultValue.create(attType,use.getFixedValue());
|
||||
}
|
||||
} else if(prop.baseType != null && prop.baseType.isPrimitive()) {
|
||||
ErrorReporter errorReporter = Ring.get(ErrorReporter.class);
|
||||
|
||||
errorReporter.warning(prop.getLocator(), Messages.WARN_DEFAULT_VALUE_PRIMITIVE_TYPE, prop.baseType.name());
|
||||
}
|
||||
|
||||
getCurrentBean().addProperty(prop);
|
||||
}
|
||||
|
||||
private TypeUse bindAttDecl(XSAttributeDecl decl) {
|
||||
SimpleTypeBuilder stb = Ring.get(SimpleTypeBuilder.class);
|
||||
stb.refererStack.push( decl );
|
||||
try {
|
||||
return stb.build(decl.getType());
|
||||
} finally {
|
||||
stb.refererStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void complexType(XSComplexType ct) {
|
||||
CClass ctBean = selector.bindToType(ct,null,false);
|
||||
if(getCurrentBean()!=ctBean)
|
||||
// in some case complex type and element binds to the same class
|
||||
// don't make it has-a. Just make it is-a.
|
||||
getCurrentBean().setBaseClass(ctBean);
|
||||
}
|
||||
|
||||
public void wildcard(XSWildcard xsWildcard) {
|
||||
// element wildcards are processed by particle binders,
|
||||
// so this one is for attribute wildcard.
|
||||
|
||||
getCurrentBean().hasAttributeWildcard(true);
|
||||
}
|
||||
|
||||
public void modelGroupDecl(XSModelGroupDecl xsModelGroupDecl) {
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void modelGroup(XSModelGroup xsModelGroup) {
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void elementDecl(XSElementDecl xsElementDecl) {
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void simpleType(XSSimpleType type) {
|
||||
createSimpleTypeProperty(type,"Value");
|
||||
}
|
||||
|
||||
public void particle(XSParticle xsParticle) {
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void empty(XSContentType ct) {
|
||||
// empty generates nothing
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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 com.sun.tools.internal.xjc.reader.Ring;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.ct.ComplexTypeFieldBuilder;
|
||||
import com.sun.xml.internal.bind.v2.TODO;
|
||||
import com.sun.xml.internal.xsom.XSAttGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSAttributeDecl;
|
||||
import com.sun.xml.internal.xsom.XSAttributeUse;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSContentType;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
import com.sun.xml.internal.xsom.XSModelGroup;
|
||||
import com.sun.xml.internal.xsom.XSModelGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSParticle;
|
||||
import com.sun.xml.internal.xsom.XSSimpleType;
|
||||
import com.sun.xml.internal.xsom.XSWildcard;
|
||||
|
||||
/**
|
||||
* This is where a binding of a new class starts.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public final class BindRed extends ColorBinder {
|
||||
|
||||
private final ComplexTypeFieldBuilder ctBuilder = Ring.get(ComplexTypeFieldBuilder.class);
|
||||
|
||||
public void complexType(XSComplexType ct) {
|
||||
ctBuilder.build(ct);
|
||||
}
|
||||
|
||||
public void wildcard(XSWildcard xsWildcard) {
|
||||
// TODO: implement this method later
|
||||
// I guess we might allow this to be mapped to a generic element property ---
|
||||
// not sure exactly how do we do it.
|
||||
TODO.checkSpec();
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void elementDecl(XSElementDecl e) {
|
||||
SimpleTypeBuilder stb = Ring.get(SimpleTypeBuilder.class);
|
||||
stb.refererStack.push(e); // referer is element
|
||||
builder.ying(e.getType(),e);
|
||||
stb.refererStack.pop();
|
||||
}
|
||||
|
||||
public void simpleType(XSSimpleType type) {
|
||||
SimpleTypeBuilder stb = Ring.get(SimpleTypeBuilder.class);
|
||||
stb.refererStack.push(type); // referer is itself
|
||||
createSimpleTypeProperty(type,"Value");
|
||||
stb.refererStack.pop();
|
||||
}
|
||||
|
||||
/*
|
||||
Components that can never be mapped to a class
|
||||
*/
|
||||
public void attGroupDecl(XSAttGroupDecl ag) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
public void attributeDecl(XSAttributeDecl ad) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
public void attributeUse(XSAttributeUse au) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
public void empty(XSContentType xsContentType) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
public void modelGroupDecl(XSModelGroupDecl xsModelGroupDecl) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
public void modelGroup(XSModelGroup xsModelGroup) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
public void particle(XSParticle p) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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 com.sun.xml.internal.xsom.XSAttGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSAttributeDecl;
|
||||
import com.sun.xml.internal.xsom.XSAttributeUse;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSContentType;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
import com.sun.xml.internal.xsom.XSModelGroup;
|
||||
import com.sun.xml.internal.xsom.XSModelGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSParticle;
|
||||
import com.sun.xml.internal.xsom.XSSimpleType;
|
||||
import com.sun.xml.internal.xsom.XSWildcard;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public final class BindYellow extends ColorBinder {
|
||||
public void complexType(XSComplexType ct) {
|
||||
}
|
||||
|
||||
public void wildcard(XSWildcard xsWildcard) {
|
||||
// TODO: implement this method later
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void elementDecl(XSElementDecl xsElementDecl) {
|
||||
// TODO: implement this method later
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void simpleType(XSSimpleType xsSimpleType) {
|
||||
// TODO: implement this method later
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void attributeDecl(XSAttributeDecl xsAttributeDecl) {
|
||||
// TODO: implement this method later
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Components that can never map to a type
|
||||
|
||||
*/
|
||||
public void attGroupDecl(XSAttGroupDecl xsAttGroupDecl) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public void attributeUse(XSAttributeUse use) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public void modelGroupDecl(XSModelGroupDecl xsModelGroupDecl) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public void modelGroup(XSModelGroup xsModelGroup) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public void particle(XSParticle xsParticle) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public void empty(XSContentType xsContentType) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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 com.sun.tools.internal.xjc.reader.Ring;
|
||||
|
||||
/**
|
||||
* Component accessible from {@link Ring}.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public abstract class BindingComponent {
|
||||
protected BindingComponent() {
|
||||
Ring.add(this);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// Accessor to common components.
|
||||
//
|
||||
//
|
||||
|
||||
protected final ErrorReporter getErrorReporter() {
|
||||
return Ring.get(ErrorReporter.class);
|
||||
}
|
||||
protected final ClassSelector getClassSelector() {
|
||||
return Ring.get(ClassSelector.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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 com.sun.tools.internal.xjc.model.CClassInfo;
|
||||
import com.sun.tools.internal.xjc.model.CElement;
|
||||
import com.sun.tools.internal.xjc.model.CElementInfo;
|
||||
import com.sun.xml.internal.xsom.visitor.XSFunction;
|
||||
|
||||
/**
|
||||
* Marker interface for an object that determines how to map
|
||||
* a component to a class. If a component is mapped to a class,
|
||||
* this object returns a {@link CClassInfo} pr {@link CElementInfo} object.
|
||||
*
|
||||
* Otherwise, return null.
|
||||
*/
|
||||
interface ClassBinder extends XSFunction<CElement> {
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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 com.sun.tools.internal.xjc.model.CElement;
|
||||
import com.sun.xml.internal.xsom.XSAnnotation;
|
||||
import com.sun.xml.internal.xsom.XSAttGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSAttributeDecl;
|
||||
import com.sun.xml.internal.xsom.XSAttributeUse;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSContentType;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
import com.sun.xml.internal.xsom.XSFacet;
|
||||
import com.sun.xml.internal.xsom.XSIdentityConstraint;
|
||||
import com.sun.xml.internal.xsom.XSModelGroup;
|
||||
import com.sun.xml.internal.xsom.XSModelGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSNotation;
|
||||
import com.sun.xml.internal.xsom.XSParticle;
|
||||
import com.sun.xml.internal.xsom.XSSchema;
|
||||
import com.sun.xml.internal.xsom.XSSimpleType;
|
||||
import com.sun.xml.internal.xsom.XSWildcard;
|
||||
import com.sun.xml.internal.xsom.XSXPath;
|
||||
|
||||
/**
|
||||
* {@link ClassBinder} that delegates the call to another {@link ClassBinder}.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi (kk@kohsuke.org)
|
||||
*/
|
||||
abstract class ClassBinderFilter implements ClassBinder {
|
||||
private final ClassBinder core;
|
||||
|
||||
protected ClassBinderFilter(ClassBinder core) {
|
||||
this.core = core;
|
||||
}
|
||||
|
||||
public CElement annotation(XSAnnotation xsAnnotation) {
|
||||
return core.annotation(xsAnnotation);
|
||||
}
|
||||
|
||||
public CElement attGroupDecl(XSAttGroupDecl xsAttGroupDecl) {
|
||||
return core.attGroupDecl(xsAttGroupDecl);
|
||||
}
|
||||
|
||||
public CElement attributeDecl(XSAttributeDecl xsAttributeDecl) {
|
||||
return core.attributeDecl(xsAttributeDecl);
|
||||
}
|
||||
|
||||
public CElement attributeUse(XSAttributeUse xsAttributeUse) {
|
||||
return core.attributeUse(xsAttributeUse);
|
||||
}
|
||||
|
||||
public CElement complexType(XSComplexType xsComplexType) {
|
||||
return core.complexType(xsComplexType);
|
||||
}
|
||||
|
||||
public CElement schema(XSSchema xsSchema) {
|
||||
return core.schema(xsSchema);
|
||||
}
|
||||
|
||||
public CElement facet(XSFacet xsFacet) {
|
||||
return core.facet(xsFacet);
|
||||
}
|
||||
|
||||
public CElement notation(XSNotation xsNotation) {
|
||||
return core.notation(xsNotation);
|
||||
}
|
||||
|
||||
public CElement simpleType(XSSimpleType xsSimpleType) {
|
||||
return core.simpleType(xsSimpleType);
|
||||
}
|
||||
|
||||
public CElement particle(XSParticle xsParticle) {
|
||||
return core.particle(xsParticle);
|
||||
}
|
||||
|
||||
public CElement empty(XSContentType xsContentType) {
|
||||
return core.empty(xsContentType);
|
||||
}
|
||||
|
||||
public CElement wildcard(XSWildcard xsWildcard) {
|
||||
return core.wildcard(xsWildcard);
|
||||
}
|
||||
|
||||
public CElement modelGroupDecl(XSModelGroupDecl xsModelGroupDecl) {
|
||||
return core.modelGroupDecl(xsModelGroupDecl);
|
||||
}
|
||||
|
||||
public CElement modelGroup(XSModelGroup xsModelGroup) {
|
||||
return core.modelGroup(xsModelGroup);
|
||||
}
|
||||
|
||||
public CElement elementDecl(XSElementDecl xsElementDecl) {
|
||||
return core.elementDecl(xsElementDecl);
|
||||
}
|
||||
|
||||
public CElement identityConstraint(XSIdentityConstraint xsIdentityConstraint) {
|
||||
return core.identityConstraint(xsIdentityConstraint);
|
||||
}
|
||||
|
||||
public CElement xpath(XSXPath xsxPath) {
|
||||
return core.xpath(xsxPath);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,485 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.io.StringWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
import com.sun.codemodel.internal.JCodeModel;
|
||||
import com.sun.codemodel.internal.JJavaName;
|
||||
import com.sun.codemodel.internal.JPackage;
|
||||
import com.sun.codemodel.internal.util.JavadocEscapeWriter;
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.tools.internal.xjc.model.CBuiltinLeafInfo;
|
||||
import com.sun.tools.internal.xjc.model.CClassInfo;
|
||||
import com.sun.tools.internal.xjc.model.CClassInfoParent;
|
||||
import com.sun.tools.internal.xjc.model.CElement;
|
||||
import com.sun.tools.internal.xjc.model.CElementInfo;
|
||||
import com.sun.tools.internal.xjc.model.CTypeInfo;
|
||||
import com.sun.tools.internal.xjc.model.TypeUse;
|
||||
import com.sun.tools.internal.xjc.model.CClass;
|
||||
import com.sun.tools.internal.xjc.model.CNonElement;
|
||||
import com.sun.tools.internal.xjc.reader.Ring;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIProperty;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BISchemaBinding;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.LocalScoping;
|
||||
import com.sun.xml.internal.bind.v2.WellKnownNamespace;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSComponent;
|
||||
import com.sun.xml.internal.xsom.XSDeclaration;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
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.XSType;
|
||||
import com.sun.xml.internal.xsom.impl.util.SchemaWriter;
|
||||
import com.sun.xml.internal.xsom.util.ComponentNameFunction;
|
||||
|
||||
import org.xml.sax.Locator;
|
||||
|
||||
/**
|
||||
* Manages association between {@link XSComponent}s and generated
|
||||
* {@link CTypeInfo}s.
|
||||
*
|
||||
* <p>
|
||||
* This class determines which component is mapped to (or is not mapped to)
|
||||
* what types.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public final class ClassSelector extends BindingComponent {
|
||||
/** Center of owner classes. */
|
||||
private final BGMBuilder builder = Ring.get(BGMBuilder.class);
|
||||
|
||||
|
||||
/**
|
||||
* Map from XSComponents to {@link Binding}s. Keeps track of all
|
||||
* content interfaces that are already built or being built.
|
||||
*/
|
||||
private final Map<XSComponent,Binding> bindMap = new HashMap<XSComponent,Binding>();
|
||||
|
||||
/**
|
||||
* UGLY HACK.
|
||||
* <p>
|
||||
* To avoid cyclic dependency between binding elements and types,
|
||||
* we need additional markers that tell which elements are definitely not bound
|
||||
* to a class.
|
||||
* <p>
|
||||
* the cyclic dependency is as follows:
|
||||
* elements need to bind its types first, because otherwise it can't
|
||||
* determine T of JAXBElement<T>.
|
||||
* OTOH, types need to know whether its parent is bound to a class to decide
|
||||
* which class name to use.
|
||||
*/
|
||||
/*package*/ final Map<XSComponent,CElementInfo> boundElements = new HashMap<XSComponent,CElementInfo>();
|
||||
|
||||
/**
|
||||
* A list of {@link Binding}s object that needs to be built.
|
||||
*/
|
||||
private final Stack<Binding> bindQueue = new Stack<Binding>();
|
||||
|
||||
/**
|
||||
* {@link CClassInfo}s that are already {@link Binding#build() built}.
|
||||
*/
|
||||
private final Set<CClassInfo> built = new HashSet<CClassInfo>();
|
||||
|
||||
/**
|
||||
* Object that determines components that are mapped
|
||||
* to classes.
|
||||
*/
|
||||
private final ClassBinder classBinder;
|
||||
|
||||
/**
|
||||
* {@link CClassInfoParent}s that determines where a new class
|
||||
* should be created.
|
||||
*/
|
||||
private final Stack<CClassInfoParent> classScopes = new Stack<CClassInfoParent>();
|
||||
|
||||
/**
|
||||
* The component that is being bound to {@link #currentBean}.
|
||||
*/
|
||||
private XSComponent currentRoot;
|
||||
/**
|
||||
* The bean representation we are binding right now.
|
||||
*/
|
||||
private CClassInfo currentBean;
|
||||
|
||||
|
||||
private final class Binding {
|
||||
private final XSComponent sc;
|
||||
private final CTypeInfo bean;
|
||||
|
||||
public Binding(XSComponent sc, CTypeInfo bean) {
|
||||
this.sc = sc;
|
||||
this.bean = bean;
|
||||
}
|
||||
|
||||
void build() {
|
||||
if(!(this.bean instanceof CClassInfo))
|
||||
return; // no need to "build"
|
||||
|
||||
CClassInfo bean = (CClassInfo)this.bean;
|
||||
|
||||
if(!built.add(bean))
|
||||
return; // already built
|
||||
|
||||
for( String reservedClassName : reservedClassNames ) {
|
||||
if( bean.getName().equals(reservedClassName) ) {
|
||||
getErrorReporter().error( sc.getLocator(),
|
||||
Messages.ERR_RESERVED_CLASS_NAME, reservedClassName );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if this schema component is an element declaration
|
||||
// and it satisfies a set of conditions specified in the spec,
|
||||
// this class will receive a constructor.
|
||||
if(needValueConstructor(sc)) {
|
||||
// TODO: fragile. There is no guarantee that the property name
|
||||
// is in fact "value".
|
||||
bean.addConstructor("value");
|
||||
}
|
||||
|
||||
if(bean.javadoc==null)
|
||||
addSchemaFragmentJavadoc(bean,sc);
|
||||
|
||||
// build the body
|
||||
if(builder.getGlobalBinding().getFlattenClasses()==LocalScoping.NESTED)
|
||||
pushClassScope(bean);
|
||||
else
|
||||
pushClassScope(bean.parent());
|
||||
XSComponent oldRoot = currentRoot;
|
||||
CClassInfo oldBean = currentBean;
|
||||
currentRoot = sc;
|
||||
currentBean = bean;
|
||||
sc.visit(Ring.get(BindRed.class));
|
||||
currentBean = oldBean;
|
||||
currentRoot = oldRoot;
|
||||
popClassScope();
|
||||
|
||||
// acknowledge property customization on this schema component,
|
||||
// since it is OK to have a customization at the point of declaration
|
||||
// even when no one is using it.
|
||||
BIProperty prop = builder.getBindInfo(sc).get(BIProperty.class);
|
||||
if(prop!=null) prop.markAsAcknowledged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// should be instanciated only from BGMBuilder.
|
||||
public ClassSelector() {
|
||||
classBinder = new Abstractifier(new DefaultClassBinder());
|
||||
Ring.add(ClassBinder.class,classBinder);
|
||||
|
||||
classScopes.push(null); // so that the getClassFactory method returns null
|
||||
|
||||
XSComplexType anyType = Ring.get(XSSchemaSet.class).getComplexType(WellKnownNamespace.XML_SCHEMA,"anyType");
|
||||
bindMap.put(anyType,new Binding(anyType,CBuiltinLeafInfo.ANYTYPE));
|
||||
}
|
||||
|
||||
/** Gets the current class scope. */
|
||||
public final CClassInfoParent getClassScope() {
|
||||
assert !classScopes.isEmpty();
|
||||
return classScopes.peek();
|
||||
}
|
||||
|
||||
public final void pushClassScope( CClassInfoParent clsFctry ) {
|
||||
assert clsFctry!=null;
|
||||
classScopes.push(clsFctry);
|
||||
}
|
||||
|
||||
public final void popClassScope() {
|
||||
classScopes.pop();
|
||||
}
|
||||
|
||||
public XSComponent getCurrentRoot() {
|
||||
return currentRoot;
|
||||
}
|
||||
|
||||
public CClassInfo getCurrentBean() {
|
||||
return currentBean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given component is bound to a class.
|
||||
*/
|
||||
public final CElement isBound( XSElementDecl x, XSComponent referer ) {
|
||||
CElementInfo r = boundElements.get(x);
|
||||
if(r!=null)
|
||||
return r;
|
||||
return bindToType(x,referer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given component is being mapped to a type.
|
||||
* If so, build that type and return that object.
|
||||
* If it is not being mapped to a type item, return null.
|
||||
*/
|
||||
public CTypeInfo bindToType( XSComponent sc, XSComponent referer ) {
|
||||
return _bindToClass(sc,referer,false);
|
||||
}
|
||||
|
||||
//
|
||||
// some schema components are guaranteed to map to a particular CTypeInfo.
|
||||
// the following versions capture those constraints in the signature
|
||||
// and making the bindToType invocation more type safe.
|
||||
//
|
||||
|
||||
public CElement bindToType( XSElementDecl e, XSComponent referer ) {
|
||||
return (CElement)_bindToClass(e,referer,false);
|
||||
}
|
||||
|
||||
public CClass bindToType( XSComplexType t, XSComponent referer, boolean cannotBeDelayed ) {
|
||||
// this assumption that a complex type always binds to a ClassInfo
|
||||
// does not hold for xs:anyType --- our current approach of handling
|
||||
// this idiosynchracy is to make sure that xs:anyType doesn't use
|
||||
// this codepath.
|
||||
return (CClass)_bindToClass(t,referer,cannotBeDelayed);
|
||||
}
|
||||
|
||||
public TypeUse bindToType( XSType t, XSComponent referer ) {
|
||||
if(t instanceof XSSimpleType) {
|
||||
return Ring.get(SimpleTypeBuilder.class).build((XSSimpleType)t);
|
||||
} else
|
||||
return (CNonElement)_bindToClass(t,referer,false);
|
||||
}
|
||||
|
||||
/**
|
||||
* The real meat of the "bindToType" code.
|
||||
*
|
||||
* @param cannotBeDelayed
|
||||
* if the binding of the body of the class cannot be defered
|
||||
* and needs to be done immediately. If the flag is false,
|
||||
* the binding of the body will be done later, to avoid
|
||||
* cyclic binding problem.
|
||||
* @param referer
|
||||
* The component that refers to <tt>sc</tt>. This can be null,
|
||||
* if figuring out the referer is too hard, in which case
|
||||
* the error message might be less user friendly.
|
||||
*/
|
||||
// TODO: consider getting rid of "cannotBeDelayed"
|
||||
CTypeInfo _bindToClass( @NotNull XSComponent sc, XSComponent referer, boolean cannotBeDelayed ) {
|
||||
// check if this class is already built.
|
||||
if(!bindMap.containsKey(sc)) {
|
||||
// craete a bind task
|
||||
|
||||
// if this is a global declaration, make sure they will be generated
|
||||
// under a package.
|
||||
boolean isGlobal = false;
|
||||
if( sc instanceof XSDeclaration ) {
|
||||
isGlobal = ((XSDeclaration)sc).isGlobal();
|
||||
if( isGlobal )
|
||||
pushClassScope( new CClassInfoParent.Package(
|
||||
getPackage(((XSDeclaration)sc).getTargetNamespace())) );
|
||||
}
|
||||
|
||||
// otherwise check if this component should become a class.
|
||||
CElement bean = sc.apply(classBinder);
|
||||
|
||||
if( isGlobal )
|
||||
popClassScope();
|
||||
|
||||
if(bean==null)
|
||||
return null;
|
||||
|
||||
// can this namespace generate a class?
|
||||
if (bean instanceof CClassInfo) {
|
||||
XSSchema os = sc.getOwnerSchema();
|
||||
BISchemaBinding sb = builder.getBindInfo(os).get(BISchemaBinding.class);
|
||||
if(sb!=null && !sb.map) {
|
||||
// nope
|
||||
getErrorReporter().error(sc.getLocator(),
|
||||
Messages.ERR_REFERENCE_TO_NONEXPORTED_CLASS, sc.apply( new ComponentNameFunction() ) );
|
||||
getErrorReporter().error(sb.getLocation(),
|
||||
Messages.ERR_REFERENCE_TO_NONEXPORTED_CLASS_MAP_FALSE, os.getTargetNamespace() );
|
||||
if(referer!=null)
|
||||
getErrorReporter().error(referer.getLocator(),
|
||||
Messages.ERR_REFERENCE_TO_NONEXPORTED_CLASS_REFERER, referer.apply( new ComponentNameFunction() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
queueBuild( sc, bean );
|
||||
}
|
||||
|
||||
Binding bind = bindMap.get(sc);
|
||||
if( cannotBeDelayed )
|
||||
bind.build();
|
||||
|
||||
return bind.bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs all the pending build tasks.
|
||||
*/
|
||||
public void executeTasks() {
|
||||
while( bindQueue.size()!=0 )
|
||||
bindQueue.pop().build();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Determines if the given component needs to have a value
|
||||
* constructor (a constructor that takes a parmater.) on ObjectFactory.
|
||||
*/
|
||||
private boolean needValueConstructor( XSComponent sc ) {
|
||||
if(!(sc instanceof XSElementDecl)) return false;
|
||||
|
||||
XSElementDecl decl = (XSElementDecl)sc;
|
||||
if(!decl.getType().isSimpleType()) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static final String[] reservedClassNames = new String[]{"ObjectFactory"};
|
||||
|
||||
public void queueBuild( XSComponent sc, CElement bean ) {
|
||||
// it is an error if the same component is built twice,
|
||||
// or the association is modified.
|
||||
Binding b = new Binding(sc,bean);
|
||||
bindQueue.push(b);
|
||||
Binding old = bindMap.put(sc, b);
|
||||
assert old==null || old.bean==bean;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copies a schema fragment into the javadoc of the generated class.
|
||||
*/
|
||||
private void addSchemaFragmentJavadoc( CClassInfo bean, XSComponent sc ) {
|
||||
|
||||
// first, pick it up from <documentation> if any.
|
||||
String doc = builder.getBindInfo(sc).getDocumentation();
|
||||
if(doc!=null)
|
||||
append(bean, doc);
|
||||
|
||||
// then the description of where this component came from
|
||||
Locator loc = sc.getLocator();
|
||||
String fileName = null;
|
||||
if(loc!=null) {
|
||||
fileName = loc.getPublicId();
|
||||
if(fileName==null)
|
||||
fileName = loc.getSystemId();
|
||||
}
|
||||
if(fileName==null) fileName="";
|
||||
|
||||
String lineNumber=Messages.format( Messages.JAVADOC_LINE_UNKNOWN);
|
||||
if(loc!=null && loc.getLineNumber()!=-1)
|
||||
lineNumber = String.valueOf(loc.getLineNumber());
|
||||
|
||||
String componentName = sc.apply( new ComponentNameFunction() );
|
||||
String jdoc = Messages.format( Messages.JAVADOC_HEADING, componentName, fileName, lineNumber );
|
||||
append(bean,jdoc);
|
||||
|
||||
// then schema fragment
|
||||
StringWriter out = new StringWriter();
|
||||
out.write("<pre>\n");
|
||||
SchemaWriter sw = new SchemaWriter(new JavadocEscapeWriter(out));
|
||||
sc.visit(sw);
|
||||
out.write("</pre>");
|
||||
append(bean,out.toString());
|
||||
}
|
||||
|
||||
private void append(CClassInfo bean, String doc) {
|
||||
if(bean.javadoc==null)
|
||||
bean.javadoc = doc+'\n';
|
||||
else
|
||||
bean.javadoc += '\n'+doc+'\n';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set of package names that are tested (set of <code>String</code>s.)
|
||||
*
|
||||
* This set is used to avoid duplicating "incorrect package name"
|
||||
* errors.
|
||||
*/
|
||||
private static Set<String> checkedPackageNames = new HashSet<String>();
|
||||
|
||||
/**
|
||||
* Gets the Java package to which classes from
|
||||
* this namespace should go.
|
||||
*
|
||||
* <p>
|
||||
* Usually, the getOuterClass method should be used
|
||||
* to determine where to put a class.
|
||||
*/
|
||||
public JPackage getPackage(String targetNamespace) {
|
||||
XSSchema s = Ring.get(XSSchemaSet.class).getSchema(targetNamespace);
|
||||
|
||||
BISchemaBinding sb =
|
||||
builder.getBindInfo(s).get(BISchemaBinding.class);
|
||||
if(sb!=null) sb.markAsAcknowledged();
|
||||
|
||||
String name = null;
|
||||
|
||||
// "-p" takes precedence over everything else
|
||||
if( builder.defaultPackage1 != null )
|
||||
name = builder.defaultPackage1;
|
||||
|
||||
// use the <jaxb:package> customization
|
||||
if( name == null && sb!=null && sb.getPackageName()!=null )
|
||||
name = sb.getPackageName();
|
||||
|
||||
// the JAX-RPC option goes below the <jaxb:package>
|
||||
if( name == null && builder.defaultPackage2 != null )
|
||||
name = builder.defaultPackage2;
|
||||
|
||||
// generate the package name from the targetNamespace
|
||||
if( name == null )
|
||||
name = builder.getNameConverter().toPackageName( targetNamespace );
|
||||
|
||||
// hardcode a package name because the code doesn't compile
|
||||
// if it generated into the default java package
|
||||
if( name == null )
|
||||
name = "generated"; // the last resort
|
||||
|
||||
|
||||
// check if the package name is a valid name.
|
||||
if( checkedPackageNames.add(name) ) {
|
||||
// this is the first time we hear about this package name.
|
||||
if( !JJavaName.isJavaPackageName(name) )
|
||||
// TODO: s.getLocator() is not very helpful.
|
||||
// ideally, we'd like to use the locator where this package name
|
||||
// comes from.
|
||||
getErrorReporter().error(s.getLocator(),
|
||||
Messages.ERR_INCORRECT_PACKAGE_NAME, targetNamespace, name );
|
||||
}
|
||||
|
||||
return Ring.get(JCodeModel.class)._package(name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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 org.xml.sax.Locator;
|
||||
|
||||
/**
|
||||
* Details of a name collision.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
final class CollisionInfo {
|
||||
private final String name;
|
||||
private final Locator source1;
|
||||
private final Locator source2;
|
||||
|
||||
public CollisionInfo(String name, Locator source1, Locator source2) {
|
||||
this.name = name;
|
||||
this.source1 = source1;
|
||||
this.source2 = source2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a localized message that describes the collision.
|
||||
*/
|
||||
public String toString() {
|
||||
return Messages.format( Messages.MSG_COLLISION_INFO,
|
||||
name, printLocator(source1), printLocator(source2) );
|
||||
}
|
||||
|
||||
private String printLocator(Locator loc) {
|
||||
if( loc==null ) return "";
|
||||
|
||||
int line = loc.getLineNumber();
|
||||
String sysId = loc.getSystemId();
|
||||
if(sysId==null) sysId = Messages.format(Messages.MSG_UNKNOWN_FILE);
|
||||
|
||||
if( line!=-1 )
|
||||
return Messages.format( Messages.MSG_LINE_X_OF_Y,
|
||||
Integer.toString(line), sysId );
|
||||
else
|
||||
return sysId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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 com.sun.tools.internal.xjc.model.CClassInfo;
|
||||
import com.sun.tools.internal.xjc.model.CPropertyInfo;
|
||||
import com.sun.tools.internal.xjc.reader.Ring;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIProperty;
|
||||
import com.sun.xml.internal.xsom.XSAnnotation;
|
||||
import com.sun.xml.internal.xsom.XSComponent;
|
||||
import com.sun.xml.internal.xsom.XSFacet;
|
||||
import com.sun.xml.internal.xsom.XSIdentityConstraint;
|
||||
import com.sun.xml.internal.xsom.XSNotation;
|
||||
import com.sun.xml.internal.xsom.XSSchema;
|
||||
import com.sun.xml.internal.xsom.XSSimpleType;
|
||||
import com.sun.xml.internal.xsom.XSXPath;
|
||||
import com.sun.xml.internal.xsom.visitor.XSVisitor;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
abstract class ColorBinder extends BindingComponent implements XSVisitor {
|
||||
protected final BGMBuilder builder = Ring.get(BGMBuilder.class);
|
||||
protected final ClassSelector selector = getClassSelector();
|
||||
|
||||
protected final CClassInfo getCurrentBean() {
|
||||
return selector.getCurrentBean();
|
||||
}
|
||||
protected final XSComponent getCurrentRoot() {
|
||||
return selector.getCurrentRoot();
|
||||
}
|
||||
|
||||
|
||||
protected final void createSimpleTypeProperty(XSSimpleType type,String propName) {
|
||||
BIProperty prop = BIProperty.getCustomization(type);
|
||||
|
||||
SimpleTypeBuilder stb = Ring.get(SimpleTypeBuilder.class);
|
||||
// since we are building the simple type here, use buildDef
|
||||
CPropertyInfo p = prop.createValueProperty(propName,false,type,stb.buildDef(type),BGMBuilder.getName(type));
|
||||
getCurrentBean().addProperty(p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public final void annotation(XSAnnotation xsAnnotation) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public final void schema(XSSchema xsSchema) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public final void facet(XSFacet xsFacet) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public final void notation(XSNotation xsNotation) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public final void identityConstraint(XSIdentityConstraint xsIdentityConstraint) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public final void xpath(XSXPath xsxPath) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,558 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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 static com.sun.tools.internal.xjc.reader.xmlschema.BGMBuilder.getName;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import com.sun.codemodel.internal.JJavaName;
|
||||
import com.sun.codemodel.internal.JPackage;
|
||||
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.model.CClassInfo;
|
||||
import com.sun.tools.internal.xjc.model.CClassInfoParent;
|
||||
import com.sun.tools.internal.xjc.model.CClassRef;
|
||||
import com.sun.tools.internal.xjc.model.CCustomizations;
|
||||
import com.sun.tools.internal.xjc.model.CElement;
|
||||
import com.sun.tools.internal.xjc.model.CElementInfo;
|
||||
import com.sun.tools.internal.xjc.model.Model;
|
||||
import com.sun.tools.internal.xjc.reader.Ring;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIClass;
|
||||
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.BindInfo;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIXSubstitutable;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.ct.ComplexTypeFieldBuilder;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.ct.ComplexTypeBindingMode;
|
||||
import com.sun.xml.internal.xsom.XSAnnotation;
|
||||
import com.sun.xml.internal.xsom.XSAttGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSAttributeDecl;
|
||||
import com.sun.xml.internal.xsom.XSAttributeUse;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSComponent;
|
||||
import com.sun.xml.internal.xsom.XSContentType;
|
||||
import com.sun.xml.internal.xsom.XSDeclaration;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
import com.sun.xml.internal.xsom.XSFacet;
|
||||
import com.sun.xml.internal.xsom.XSIdentityConstraint;
|
||||
import com.sun.xml.internal.xsom.XSModelGroup;
|
||||
import com.sun.xml.internal.xsom.XSModelGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSNotation;
|
||||
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.XSType;
|
||||
import com.sun.xml.internal.xsom.XSWildcard;
|
||||
import com.sun.xml.internal.xsom.XSXPath;
|
||||
|
||||
import org.xml.sax.Locator;
|
||||
|
||||
/**
|
||||
* Default classBinder implementation. Honors <jaxb:class> customizations
|
||||
* and default bindings.
|
||||
*/
|
||||
final class DefaultClassBinder implements ClassBinder
|
||||
{
|
||||
private final SimpleTypeBuilder stb = Ring.get(SimpleTypeBuilder.class);
|
||||
private final Model model = Ring.get(Model.class);
|
||||
|
||||
protected final BGMBuilder builder = Ring.get(BGMBuilder.class);
|
||||
protected final ClassSelector selector = Ring.get(ClassSelector.class);
|
||||
|
||||
protected final XSSchemaSet schemas = Ring.get(XSSchemaSet.class);
|
||||
|
||||
public CElement attGroupDecl(XSAttGroupDecl decl) {
|
||||
return allow(decl,decl.getName());
|
||||
}
|
||||
|
||||
public CElement attributeDecl(XSAttributeDecl decl) {
|
||||
return allow(decl,decl.getName());
|
||||
}
|
||||
|
||||
public CElement modelGroup(XSModelGroup mgroup) {
|
||||
return never();
|
||||
}
|
||||
|
||||
public CElement modelGroupDecl(XSModelGroupDecl decl) {
|
||||
return never();
|
||||
}
|
||||
|
||||
|
||||
public CElement complexType(XSComplexType type) {
|
||||
CElement ci = allow(type,type.getName());
|
||||
if(ci!=null) return ci;
|
||||
|
||||
// no customization is given -- do as the default binding.
|
||||
|
||||
BindInfo bi = builder.getBindInfo(type);
|
||||
|
||||
if(type.isGlobal()) {
|
||||
QName tagName = null;
|
||||
String className = deriveName(type);
|
||||
Locator loc = type.getLocator();
|
||||
|
||||
if(getGlobalBinding().isSimpleMode()) {
|
||||
// in the simple mode, we may optimize it away
|
||||
XSElementDecl referer = getSoleElementReferer(type);
|
||||
if(referer!=null && isCollapsable(referer)) {
|
||||
// if a global element contains
|
||||
// a collpsable complex type, we bind this element to a named one
|
||||
// and collapses element and complex type.
|
||||
tagName = getName(referer);
|
||||
className = deriveName(referer);
|
||||
loc = referer.getLocator();
|
||||
}
|
||||
}
|
||||
|
||||
// by default, global ones get their own classes.
|
||||
|
||||
JPackage pkg = selector.getPackage(type.getTargetNamespace());
|
||||
|
||||
return new CClassInfo(model,pkg,className, loc,getTypeName(type),tagName,type,bi.toCustomizationList());
|
||||
} else {
|
||||
XSElementDecl element = type.getScope();
|
||||
|
||||
if( element.isGlobal() && isCollapsable(element)) {
|
||||
if(builder.getBindInfo(element).get(BIClass.class)!=null)
|
||||
// the parent element was bound to a class. Don't bind this again to
|
||||
// cause unnecessary wrapping
|
||||
return null;
|
||||
|
||||
// generate one class from element and complex type together.
|
||||
// this needs to be done before selector.isBound to avoid infinite recursion.
|
||||
|
||||
// but avoid doing so when the element is mapped to a class,
|
||||
// which creates unnecessary classes
|
||||
return new CClassInfo( model, selector.getClassScope(),
|
||||
deriveName(element), element.getLocator(), null,
|
||||
getName(element), element, bi.toCustomizationList() );
|
||||
}
|
||||
|
||||
|
||||
CElement parentType = selector.isBound(element,type);
|
||||
|
||||
String className;
|
||||
CClassInfoParent scope;
|
||||
|
||||
|
||||
if( parentType!=null
|
||||
&& parentType instanceof CElementInfo
|
||||
&& ((CElementInfo)parentType).hasClass() ) {
|
||||
// special case where we put a nested 'Type' element
|
||||
scope = (CElementInfo)parentType;
|
||||
className = "Type";
|
||||
} else {
|
||||
// since the parent element isn't bound to a type, merge the customizations associated to it, too.
|
||||
// custs = CCustomizations.merge( custs, builder.getBindInfo(type.getScope()).toCustomizationList());
|
||||
className = builder.getNameConverter().toClassName(element.getName());
|
||||
|
||||
BISchemaBinding sb = builder.getBindInfo(
|
||||
type.getOwnerSchema() ).get(BISchemaBinding.class);
|
||||
if(sb!=null) className = sb.mangleAnonymousTypeClassName(className);
|
||||
scope = selector.getClassScope();
|
||||
}
|
||||
|
||||
return new CClassInfo(model, scope, className, type.getLocator(), null, null, type, bi.toCustomizationList() );
|
||||
}
|
||||
}
|
||||
|
||||
private QName getTypeName(XSComplexType type) {
|
||||
if(type.getRedefinedBy()!=null)
|
||||
return null;
|
||||
else
|
||||
return getName(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the complex type of the given element can be "optimized away"
|
||||
* and unified with its parent element decl to form a single class.
|
||||
*/
|
||||
private boolean isCollapsable(XSElementDecl decl) {
|
||||
XSType type = decl.getType();
|
||||
|
||||
if(!type.isComplexType())
|
||||
return false; // not a complex type
|
||||
|
||||
if(decl.getSubstitutables().size()>1 || decl.getSubstAffiliation()!=null)
|
||||
// because element substitution calls for a proper JAXBElement hierarchy
|
||||
return false;
|
||||
|
||||
if(decl.isNillable())
|
||||
// because nillable needs JAXBElement to represent correctly
|
||||
return false;
|
||||
|
||||
BIXSubstitutable bixSubstitutable = builder.getBindInfo(decl).get(BIXSubstitutable.class);
|
||||
if(bixSubstitutable !=null) {
|
||||
// see https://jaxb.dev.java.net/issues/show_bug.cgi?id=289
|
||||
// this customization forces non-collapsing behavior.
|
||||
bixSubstitutable.markAsAcknowledged();
|
||||
return false;
|
||||
}
|
||||
|
||||
if( getGlobalBinding().isSimpleMode() && decl.isGlobal()) {
|
||||
// in the simple mode, we do more aggressive optimization, and get rid of
|
||||
// a complex type class if it's only used once from a global element
|
||||
XSElementDecl referer = getSoleElementReferer(decl.getType());
|
||||
if(referer!=null) {
|
||||
assert referer==decl; // I must be the sole referer
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!type.isLocal() || !type.isComplexType())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* If only one global {@link XSElementDecl} is refering to {@link XSType},
|
||||
* return that element, otherwise null.
|
||||
*/
|
||||
private @Nullable XSElementDecl getSoleElementReferer(@NotNull XSType t) {
|
||||
Set<XSComponent> referer = builder.getReferer(t);
|
||||
|
||||
XSElementDecl sole = null;
|
||||
for (XSComponent r : referer) {
|
||||
if(r instanceof XSElementDecl) {
|
||||
XSElementDecl x = (XSElementDecl) r;
|
||||
if(!x.isGlobal())
|
||||
// local element references can be ignored, as their names are either given
|
||||
// by the property, or by the JAXBElement (for things like mixed contents)
|
||||
continue;
|
||||
if(sole==null) sole=x;
|
||||
else return null; // more than one
|
||||
} else {
|
||||
// if another type refers to this type, that means
|
||||
// this type has a sub-type, so type substitution is possible now.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return sole;
|
||||
}
|
||||
|
||||
public CElement elementDecl(XSElementDecl decl) {
|
||||
CElement r = allow(decl,decl.getName());
|
||||
|
||||
if(r==null) {
|
||||
QName tagName = getName(decl);
|
||||
CCustomizations custs = builder.getBindInfo(decl).toCustomizationList();
|
||||
|
||||
if(decl.isGlobal()) {
|
||||
if(isCollapsable(decl)) {
|
||||
// we want the returned type to be built as a complex type,
|
||||
// so the binding cannot be delayed.
|
||||
return selector.bindToType(decl.getType().asComplexType(),decl,true);
|
||||
} else {
|
||||
String className = null;
|
||||
if(getGlobalBinding().isGenerateElementClass())
|
||||
className = deriveName(decl);
|
||||
|
||||
// otherwise map global elements to JAXBElement
|
||||
CElementInfo cei = new CElementInfo(
|
||||
model, tagName, selector.getClassScope(), className, custs, decl.getLocator());
|
||||
selector.boundElements.put(decl,cei);
|
||||
|
||||
stb.refererStack.push(decl); // referer is element
|
||||
cei.initContentType( selector.bindToType(decl.getType(),decl), decl, decl.getDefaultValue() );
|
||||
stb.refererStack.pop();
|
||||
r = cei;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// have the substitution member derive from the substitution head
|
||||
XSElementDecl top = decl.getSubstAffiliation();
|
||||
if(top!=null) {
|
||||
CElement topci = selector.bindToType(top,decl);
|
||||
|
||||
if(r instanceof CClassInfo && topci instanceof CClassInfo)
|
||||
((CClassInfo)r).setBaseClass((CClassInfo)topci);
|
||||
if (r instanceof CElementInfo && topci instanceof CElementInfo)
|
||||
((CElementInfo)r).setSubstitutionHead((CElementInfo)topci);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
public CClassInfo empty( XSContentType ct ) { return null; }
|
||||
|
||||
public CClassInfo identityConstraint(XSIdentityConstraint xsIdentityConstraint) {
|
||||
return never();
|
||||
}
|
||||
|
||||
public CClassInfo xpath(XSXPath xsxPath) {
|
||||
return never();
|
||||
}
|
||||
|
||||
public CClassInfo attributeUse(XSAttributeUse use) {
|
||||
return never();
|
||||
}
|
||||
|
||||
public CElement simpleType(XSSimpleType type) {
|
||||
CElement c = allow(type,type.getName());
|
||||
if(c!=null) return c;
|
||||
|
||||
if(getGlobalBinding().isSimpleTypeSubstitution() && type.isGlobal()) {
|
||||
return new CClassInfo(model,selector.getClassScope(),
|
||||
deriveName(type), type.getLocator(), getName(type), null, type, null );
|
||||
}
|
||||
|
||||
return never();
|
||||
}
|
||||
|
||||
public CClassInfo particle(XSParticle particle) {
|
||||
return never();
|
||||
}
|
||||
|
||||
public CClassInfo wildcard(XSWildcard wc) {
|
||||
return never();
|
||||
}
|
||||
|
||||
|
||||
// these methods won't be used
|
||||
public CClassInfo annotation(XSAnnotation annon) {
|
||||
assert false;
|
||||
return null;
|
||||
}
|
||||
|
||||
public CClassInfo notation(XSNotation not) {
|
||||
assert false;
|
||||
return null;
|
||||
}
|
||||
|
||||
public CClassInfo facet(XSFacet decl) {
|
||||
assert false;
|
||||
return null;
|
||||
}
|
||||
public CClassInfo schema(XSSchema schema) {
|
||||
assert false;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Makes sure that the component doesn't carry a {@link BIClass}
|
||||
* customization.
|
||||
*
|
||||
* @return
|
||||
* return value is unused. Since most of the caller needs to
|
||||
* return null, to make the code a little bit shorter, this
|
||||
* method always return null (so that the caller can always
|
||||
* say <code>return never(sc);</code>.
|
||||
*/
|
||||
private CClassInfo never() {
|
||||
// all we need to do here is just not to acknowledge
|
||||
// any class customization. Then this class customization
|
||||
// will be reported as an error later when we check all
|
||||
// unacknowledged customizations.
|
||||
|
||||
|
||||
// BIDeclaration cust=owner.getBindInfo(component).get(BIClass.NAME);
|
||||
// if(cust!=null) {
|
||||
// // error
|
||||
// owner.errorReporter.error(
|
||||
// cust.getLocation(),
|
||||
// "test {0}", NameGetter.get(component) );
|
||||
// }
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a component carries a customization to map it to a class.
|
||||
* If so, make it a class.
|
||||
*
|
||||
* @param defaultBaseName
|
||||
* The token which will be used as the basis of the class name
|
||||
* if the class name is not specified in the customization.
|
||||
* This is usually the name of an element declaration, and so on.
|
||||
*
|
||||
* This parameter can be null, in that case it would be an error
|
||||
* if a name is not given by the customization.
|
||||
*/
|
||||
private CElement allow( XSComponent component, String defaultBaseName ) {
|
||||
|
||||
BIClass decl = null;
|
||||
|
||||
if(component instanceof XSComplexType) {
|
||||
XSType complexType = (XSType)component;
|
||||
|
||||
BIClass lastFoundRecursiveBiClass = null;
|
||||
|
||||
if(complexType.getName() != null) {
|
||||
while( ! schemas.getAnyType().equals(complexType)) {
|
||||
BindInfo bindInfo = builder.getBindInfo(complexType);
|
||||
BIClass biClass = bindInfo.get(BIClass.class);
|
||||
|
||||
if(biClass != null && "true".equals(biClass.getRecursive()))
|
||||
lastFoundRecursiveBiClass = biClass;
|
||||
|
||||
complexType = complexType.getBaseType();
|
||||
}
|
||||
}
|
||||
|
||||
// use this as biclass for current component
|
||||
decl = lastFoundRecursiveBiClass;
|
||||
|
||||
}
|
||||
|
||||
BindInfo bindInfo = builder.getBindInfo(component);
|
||||
if(decl == null) {
|
||||
decl = bindInfo.get(BIClass.class);
|
||||
if(decl==null) return null;
|
||||
}
|
||||
|
||||
decl.markAsAcknowledged();
|
||||
|
||||
// first consider binding to the class reference.
|
||||
String ref = decl.getExistingClassRef();
|
||||
if(ref!=null) {
|
||||
if(!JJavaName.isFullyQualifiedClassName(ref)) {
|
||||
Ring.get(ErrorReceiver.class).error( decl.getLocation(),
|
||||
Messages.format(Messages.ERR_INCORRECT_CLASS_NAME,ref) );
|
||||
// recover by ignoring @ref
|
||||
} else {
|
||||
if(component instanceof XSComplexType) {
|
||||
// UGLY UGLY UGLY
|
||||
// since we are not going to bind this complex type, we need to figure out
|
||||
// its binding mode without actually binding it (and also expose this otherwise
|
||||
// hidden mechanism into this part of the code.)
|
||||
//
|
||||
// this code is potentially dangerous as the base class might have been bound
|
||||
// in different ways. To be correct, we need to figure out how the content type
|
||||
// would have been bound, from the schema.
|
||||
Ring.get(ComplexTypeFieldBuilder.class).recordBindingMode(
|
||||
(XSComplexType)component, ComplexTypeBindingMode.NORMAL
|
||||
);
|
||||
}
|
||||
return new CClassRef(model, component, decl, bindInfo.toCustomizationList() );
|
||||
}
|
||||
}
|
||||
|
||||
String clsName = decl.getClassName();
|
||||
if(clsName==null) {
|
||||
// if the customiztion doesn't give us a name, derive one
|
||||
// from the current component.
|
||||
if( defaultBaseName==null ) {
|
||||
Ring.get(ErrorReceiver.class).error( decl.getLocation(),
|
||||
Messages.format(Messages.ERR_CLASS_NAME_IS_REQUIRED) );
|
||||
|
||||
// recover by generating a pseudo-random name
|
||||
defaultBaseName = "undefined"+component.hashCode();
|
||||
}
|
||||
clsName = builder.deriveName( defaultBaseName, component );
|
||||
} else {
|
||||
if( !JJavaName.isJavaIdentifier(clsName) ) {
|
||||
// not a valid Java class name
|
||||
Ring.get(ErrorReceiver.class).error( decl.getLocation(),
|
||||
Messages.format( Messages.ERR_INCORRECT_CLASS_NAME, clsName ));
|
||||
// recover by a dummy name
|
||||
clsName = "Undefined"+component.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
QName typeName = null;
|
||||
QName elementName = null;
|
||||
|
||||
if(component instanceof XSType) {
|
||||
XSType t = (XSType) component;
|
||||
typeName = getName(t);
|
||||
}
|
||||
|
||||
if (component instanceof XSElementDecl) {
|
||||
XSElementDecl e = (XSElementDecl) component;
|
||||
elementName = getName(e);
|
||||
}
|
||||
|
||||
if (component instanceof XSElementDecl && !isCollapsable((XSElementDecl)component)) {
|
||||
XSElementDecl e = ((XSElementDecl)component);
|
||||
|
||||
CElementInfo cei = new CElementInfo(model, elementName,
|
||||
selector.getClassScope(), clsName,
|
||||
bindInfo.toCustomizationList(), decl.getLocation() );
|
||||
selector.boundElements.put(e,cei);
|
||||
|
||||
stb.refererStack.push(component); // referer is element
|
||||
cei.initContentType(
|
||||
selector.bindToType(e.getType(),e),
|
||||
e,e.getDefaultValue());
|
||||
stb.refererStack.pop();
|
||||
return cei;
|
||||
// TODO: support javadoc and userSpecifiedImplClass
|
||||
} else {
|
||||
CClassInfo bt = new CClassInfo(model,selector.getClassScope(),
|
||||
clsName, decl.getLocation(), typeName, elementName, component, bindInfo.toCustomizationList() );
|
||||
|
||||
// set javadoc class comment.
|
||||
if(decl.getJavadoc()!=null )
|
||||
bt.javadoc = decl.getJavadoc()+"\n\n";
|
||||
// add extra blank lines so that the schema fragment
|
||||
// and user-specified javadoc would be separated
|
||||
|
||||
|
||||
// if the implClass is given, set it to ClassItem
|
||||
String implClass = decl.getUserSpecifiedImplClass();
|
||||
if( implClass!=null )
|
||||
bt.setUserSpecifiedImplClass( implClass );
|
||||
|
||||
return bt;
|
||||
}
|
||||
}
|
||||
|
||||
private BIGlobalBinding getGlobalBinding() {
|
||||
return builder.getGlobalBinding();
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives a name from a schema component.
|
||||
* Use the name of the schema component as the default name.
|
||||
*/
|
||||
private String deriveName( XSDeclaration comp ) {
|
||||
return builder.deriveName( comp.getName(), comp );
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives a name from a schema component.
|
||||
* For complex types, we take redefinition into account when
|
||||
* deriving a default name.
|
||||
*/
|
||||
private String deriveName( XSComplexType comp ) {
|
||||
String seed = builder.deriveName( comp.getName(), comp );
|
||||
int cnt = comp.getRedefinedCount();
|
||||
for( ; cnt>0; cnt-- )
|
||||
seed = "Original"+seed;
|
||||
return seed;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,392 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.tools.internal.xjc.model.CClassInfo;
|
||||
import com.sun.tools.internal.xjc.model.CPropertyInfo;
|
||||
import com.sun.tools.internal.xjc.model.CReferencePropertyInfo;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIProperty;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
import com.sun.xml.internal.xsom.XSModelGroup;
|
||||
import com.sun.xml.internal.xsom.XSModelGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSParticle;
|
||||
import com.sun.xml.internal.xsom.XSTerm;
|
||||
import com.sun.xml.internal.xsom.XSWildcard;
|
||||
import com.sun.xml.internal.xsom.visitor.XSTermVisitor;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* {@link ParticleBinder} that follows the JAXB spec.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
final class DefaultParticleBinder extends ParticleBinder {
|
||||
|
||||
@Override
|
||||
public void build( XSParticle p, Collection<XSParticle> forcedProps ) {
|
||||
Checker checker = checkCollision(p,forcedProps);
|
||||
|
||||
if(checker.hasNameCollision()) {
|
||||
CReferencePropertyInfo prop = new CReferencePropertyInfo(
|
||||
getCurrentBean().getBaseClass()==null?"Content":"Rest",
|
||||
true, false, false, p,
|
||||
builder.getBindInfo(p).toCustomizationList(),
|
||||
p.getLocator(), false, false, false);
|
||||
RawTypeSetBuilder.build(p,false).addTo(prop);
|
||||
prop.javadoc = Messages.format( Messages.MSG_FALLBACK_JAVADOC,
|
||||
checker.getCollisionInfo().toString() );
|
||||
|
||||
getCurrentBean().addProperty(prop);
|
||||
} else {
|
||||
new Builder(checker.markedParticles).particle(p);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkFallback( XSParticle p ) {
|
||||
return checkCollision(p,Collections.<XSParticle>emptyList()).hasNameCollision();
|
||||
}
|
||||
|
||||
private Checker checkCollision( XSParticle p, Collection<XSParticle> forcedProps ) {
|
||||
// scan the tree by a checker.
|
||||
Checker checker = new Checker(forcedProps);
|
||||
|
||||
CClassInfo superClass = getCurrentBean().getBaseClass();
|
||||
|
||||
if(superClass!=null)
|
||||
checker.readSuperClass(superClass);
|
||||
checker.particle(p);
|
||||
|
||||
return checker;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Marks particles that need to be mapped to properties,
|
||||
* by reading customization info.
|
||||
*/
|
||||
private final class Checker implements XSTermVisitor {
|
||||
|
||||
Checker(Collection<XSParticle> forcedProps) {
|
||||
this.forcedProps = forcedProps;
|
||||
}
|
||||
|
||||
boolean hasNameCollision() {
|
||||
return collisionInfo!=null;
|
||||
}
|
||||
|
||||
CollisionInfo getCollisionInfo() {
|
||||
return collisionInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a collision is found, this field will be non-null.
|
||||
*/
|
||||
private CollisionInfo collisionInfo = null;
|
||||
|
||||
/** Used to check name collision. */
|
||||
private final NameCollisionChecker cchecker = new NameCollisionChecker();
|
||||
|
||||
/**
|
||||
* @see DefaultParticleBinder#build(XSParticle, Collection<com.sun.xml.internal.xsom.XSParticle>)
|
||||
*/
|
||||
private final Collection<XSParticle> forcedProps;
|
||||
|
||||
public void particle( XSParticle p ) {
|
||||
|
||||
if(getLocalPropCustomization(p)!=null
|
||||
|| builder.getLocalDomCustomization(p)!=null) {
|
||||
// if a property customization is specfied,
|
||||
// check that value and turn around.
|
||||
check(p);
|
||||
mark(p);
|
||||
return;
|
||||
}
|
||||
|
||||
XSTerm t = p.getTerm();
|
||||
|
||||
if(p.isRepeated() && (t.isModelGroup() || t.isModelGroupDecl())) {
|
||||
// a repeated model group gets its own property
|
||||
mark(p);
|
||||
return;
|
||||
}
|
||||
|
||||
if(forcedProps.contains(p)) {
|
||||
// this particle must become a property
|
||||
mark(p);
|
||||
return;
|
||||
}
|
||||
|
||||
outerParticle = p;
|
||||
t.visit(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This field points to the parent XSParticle.
|
||||
* The value is only valid when we are processing XSTerm.
|
||||
*/
|
||||
private XSParticle outerParticle;
|
||||
|
||||
public void elementDecl(XSElementDecl decl) {
|
||||
check(outerParticle);
|
||||
mark(outerParticle);
|
||||
}
|
||||
|
||||
public void modelGroup(XSModelGroup mg) {
|
||||
// choice gets mapped to a property
|
||||
if(mg.getCompositor()== XSModelGroup.Compositor.CHOICE && builder.getGlobalBinding().isChoiceContentPropertyEnabled()) {
|
||||
mark(outerParticle);
|
||||
return;
|
||||
}
|
||||
|
||||
for( XSParticle child : mg.getChildren() )
|
||||
particle(child);
|
||||
}
|
||||
|
||||
public void modelGroupDecl(XSModelGroupDecl decl) {
|
||||
modelGroup(decl.getModelGroup());
|
||||
}
|
||||
|
||||
public void wildcard(XSWildcard wc) {
|
||||
mark(outerParticle);
|
||||
}
|
||||
|
||||
void readSuperClass( CClassInfo ci ) {
|
||||
cchecker.readSuperClass(ci);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Checks the name collision of a newly found particle.
|
||||
*/
|
||||
private void check( XSParticle p ) {
|
||||
if( collisionInfo==null )
|
||||
collisionInfo = cchecker.check(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks a particle that it's going to be mapped to a property.
|
||||
*/
|
||||
private void mark( XSParticle p ) {
|
||||
markedParticles.put(p,computeLabel(p));
|
||||
}
|
||||
|
||||
/**
|
||||
* Marked particles.
|
||||
*
|
||||
* A map from XSParticle to its label.
|
||||
*/
|
||||
public final Map<XSParticle,String> markedParticles = new HashMap<XSParticle,String>();
|
||||
|
||||
|
||||
/**
|
||||
* Checks name collisions among particles that belong to sequences.
|
||||
*/
|
||||
private final class NameCollisionChecker {
|
||||
|
||||
/**
|
||||
* Checks the label conflict of a particle.
|
||||
* This method shall be called for each marked particle.
|
||||
*
|
||||
* @return
|
||||
* a description of a collision if a name collision is
|
||||
* found. Otherwise null.
|
||||
*/
|
||||
CollisionInfo check( XSParticle p ) {
|
||||
// this can be used for particles with a property customization,
|
||||
// which may not have element declaration as its term.
|
||||
// // we only check particles with element declarations.
|
||||
// _assert( p.getTerm().isElementDecl() );
|
||||
|
||||
String label = computeLabel(p);
|
||||
if( occupiedLabels.containsKey(label) ) {
|
||||
// collide with occupied labels
|
||||
return new CollisionInfo(label,p.getLocator(),
|
||||
occupiedLabels.get(label).locator);
|
||||
}
|
||||
|
||||
for( XSParticle jp : particles ) {
|
||||
if(!check( p, jp )) {
|
||||
// problem was found. no need to check further
|
||||
return new CollisionInfo( label, p.getLocator(), jp.getLocator() );
|
||||
}
|
||||
}
|
||||
particles.add(p);
|
||||
return null;
|
||||
}
|
||||
|
||||
/** List of particles reported through the check method. */
|
||||
private final List<XSParticle> particles = new ArrayList<XSParticle>();
|
||||
|
||||
/**
|
||||
* Label names already used in the base type.
|
||||
*/
|
||||
private final Map<String,CPropertyInfo> occupiedLabels = new HashMap<String,CPropertyInfo>();
|
||||
|
||||
/**
|
||||
* Checks the conflict of two particles.
|
||||
* @return
|
||||
* true if the check was successful.
|
||||
*/
|
||||
private boolean check( XSParticle p1, XSParticle p2 ) {
|
||||
return !computeLabel(p1).equals(computeLabel(p2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads fields of the super class and includes them
|
||||
* to name collision tests.
|
||||
*/
|
||||
void readSuperClass( CClassInfo base ) {
|
||||
for( ; base!=null; base=base.getBaseClass() ) {
|
||||
for( CPropertyInfo p : base.getProperties() )
|
||||
occupiedLabels.put(p.getName(true),p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Keep the computed label names for particles. */
|
||||
private final Map<XSParticle,String> labelCache = new Hashtable<XSParticle,String>();
|
||||
|
||||
/**
|
||||
* Hides the computeLabel method of the outer class
|
||||
* and adds caching.
|
||||
*/
|
||||
private String computeLabel( XSParticle p ) {
|
||||
String label = labelCache.get(p);
|
||||
if(label==null)
|
||||
labelCache.put( p, label=DefaultParticleBinder.this.computeLabel(p) );
|
||||
return label;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Builds properties by using the result computed by Checker
|
||||
*/
|
||||
private final class Builder implements XSTermVisitor {
|
||||
Builder( Map<XSParticle,String> markedParticles ) {
|
||||
this.markedParticles = markedParticles;
|
||||
}
|
||||
|
||||
/** All marked particles. */
|
||||
private final Map<XSParticle,String/*label*/> markedParticles;
|
||||
|
||||
/**
|
||||
* When we are visiting inside an optional particle, this flag
|
||||
* is set to true.
|
||||
*
|
||||
* <p>
|
||||
* This allows us to correctly generate primitive/boxed types.
|
||||
*/
|
||||
private boolean insideOptionalParticle;
|
||||
|
||||
|
||||
/** Returns true if a particle is marked. */
|
||||
private boolean marked( XSParticle p ) {
|
||||
return markedParticles.containsKey(p);
|
||||
}
|
||||
/** Gets a label of a particle. */
|
||||
private String getLabel( XSParticle p ) {
|
||||
return markedParticles.get(p);
|
||||
}
|
||||
|
||||
public void particle( XSParticle p ) {
|
||||
XSTerm t = p.getTerm();
|
||||
|
||||
if(marked(p)) {
|
||||
BIProperty cust = BIProperty.getCustomization(p);
|
||||
CPropertyInfo prop = cust.createElementOrReferenceProperty(
|
||||
getLabel(p), false, p, RawTypeSetBuilder.build(p,insideOptionalParticle));
|
||||
getCurrentBean().addProperty(prop);
|
||||
} else {
|
||||
// repeated model groups should have been marked already
|
||||
assert !p.isRepeated();
|
||||
|
||||
boolean oldIOP = insideOptionalParticle;
|
||||
insideOptionalParticle |= BigInteger.ZERO.equals(p.getMinOccurs());
|
||||
// this is an unmarked particle
|
||||
t.visit(this);
|
||||
insideOptionalParticle = oldIOP;
|
||||
}
|
||||
}
|
||||
|
||||
public void elementDecl( XSElementDecl e ) {
|
||||
// because the corresponding particle must be marked.
|
||||
assert false;
|
||||
}
|
||||
|
||||
public void wildcard( XSWildcard wc ) {
|
||||
// because the corresponding particle must be marked.
|
||||
assert false;
|
||||
}
|
||||
|
||||
public void modelGroupDecl( XSModelGroupDecl decl ) {
|
||||
modelGroup(decl.getModelGroup());
|
||||
}
|
||||
|
||||
public void modelGroup( XSModelGroup mg ) {
|
||||
boolean oldIOP = insideOptionalParticle;
|
||||
insideOptionalParticle |= mg.getCompositor()==XSModelGroup.CHOICE;
|
||||
|
||||
for( XSParticle p : mg.getChildren())
|
||||
particle(p);
|
||||
|
||||
insideOptionalParticle = oldIOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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 com.sun.tools.internal.xjc.ErrorReceiver;
|
||||
import com.sun.tools.internal.xjc.reader.Ring;
|
||||
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.Locator;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
/**
|
||||
* Provides error report capability to other owner components
|
||||
* by encapsulating user-specified {@link ErrorHandler}
|
||||
* and exposing utlity methods.
|
||||
*
|
||||
* <p>
|
||||
* This class also wraps SAXException to a RuntimeException
|
||||
* so that the exception thrown inside the error handler
|
||||
* can abort the process.
|
||||
*
|
||||
* <p>
|
||||
* At the end of the day, we need to know if there was any error.
|
||||
* So it is important that all the error messages go through this
|
||||
* object. This is done by hiding the errorHandler from the rest
|
||||
* of the components.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public final class ErrorReporter extends BindingComponent {
|
||||
|
||||
/**
|
||||
* Error handler to report any binding error to.
|
||||
* To report errors, use the error method.
|
||||
*/
|
||||
private final ErrorReceiver errorReceiver = Ring.get(ErrorReceiver.class);
|
||||
|
||||
|
||||
//
|
||||
// helper methods for classes in this package.
|
||||
// properties are localized through the Messages.properties file
|
||||
// in this package
|
||||
//
|
||||
void error( Locator loc, String prop, Object... args ) {
|
||||
errorReceiver.error( loc, Messages.format(prop,args) );
|
||||
}
|
||||
|
||||
void warning( Locator loc, String prop, Object... args ) {
|
||||
errorReceiver.warning( new SAXParseException(
|
||||
Messages.format(prop,args), loc ));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
private String format( String prop, Object[] args ) {
|
||||
// use a bit verbose code to make it portable.
|
||||
String className = this.getClass().getName();
|
||||
int idx = className.lastIndexOf('.');
|
||||
String packageName = className.substring(0,idx);
|
||||
|
||||
String fmt = ResourceBundle.getBundle(packageName+".Messages").getString(prop);
|
||||
|
||||
return MessageFormat.format(fmt,args);
|
||||
}
|
||||
*/
|
||||
|
||||
////
|
||||
////
|
||||
//// ErrorHandler implementation
|
||||
////
|
||||
////
|
||||
// public void error(SAXParseException exception) {
|
||||
// errorReceiver.error(exception);
|
||||
// }
|
||||
//
|
||||
// public void fatalError(SAXParseException exception) {
|
||||
// errorReceiver.fatalError(exception);
|
||||
// }
|
||||
//
|
||||
// public void warning(SAXParseException exception) {
|
||||
// errorReceiver.warning(exception);
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAnyElement;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import com.sun.tools.internal.xjc.reader.gbind.Choice;
|
||||
import com.sun.tools.internal.xjc.reader.gbind.Element;
|
||||
import com.sun.tools.internal.xjc.reader.gbind.Expression;
|
||||
import com.sun.tools.internal.xjc.reader.gbind.OneOrMore;
|
||||
import com.sun.tools.internal.xjc.reader.gbind.Sequence;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
import com.sun.xml.internal.xsom.XSModelGroup;
|
||||
import com.sun.xml.internal.xsom.XSModelGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSParticle;
|
||||
import com.sun.xml.internal.xsom.XSWildcard;
|
||||
import com.sun.xml.internal.xsom.visitor.XSTermFunction;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Visits {@link XSParticle} and creates a corresponding {@link Expression} tree.
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public final class ExpressionBuilder implements XSTermFunction<Expression> {
|
||||
|
||||
public static Expression createTree(XSParticle p) {
|
||||
return new ExpressionBuilder().particle(p);
|
||||
}
|
||||
|
||||
private ExpressionBuilder() {}
|
||||
|
||||
/**
|
||||
* Wildcard instance needs to be consolidated to one,
|
||||
* and this is such instance (if any.)
|
||||
*/
|
||||
private GWildcardElement wildcard = null;
|
||||
|
||||
private final Map<QName,GElementImpl> decls = new HashMap<QName,GElementImpl>();
|
||||
|
||||
private XSParticle current;
|
||||
|
||||
/**
|
||||
* We can only have one {@link XmlAnyElement} property,
|
||||
* so all the wildcards need to be treated as one node.
|
||||
*/
|
||||
public Expression wildcard(XSWildcard wc) {
|
||||
if(wildcard==null)
|
||||
wildcard = new GWildcardElement();
|
||||
wildcard.merge(wc);
|
||||
wildcard.particles.add(current);
|
||||
return wildcard;
|
||||
}
|
||||
|
||||
public Expression modelGroupDecl(XSModelGroupDecl decl) {
|
||||
return modelGroup(decl.getModelGroup());
|
||||
}
|
||||
|
||||
public Expression modelGroup(XSModelGroup group) {
|
||||
XSModelGroup.Compositor comp = group.getCompositor();
|
||||
if(comp==XSModelGroup.CHOICE) {
|
||||
// empty choice is not epsilon, but empty set,
|
||||
// so this initial value is incorrect. But this
|
||||
// kinda works.
|
||||
// properly handling empty set requires more work.
|
||||
Expression e = Expression.EPSILON;
|
||||
for (XSParticle p : group.getChildren()) {
|
||||
if(e==null) e = particle(p);
|
||||
else e = new Choice(e,particle(p));
|
||||
}
|
||||
return e;
|
||||
} else {
|
||||
Expression e = Expression.EPSILON;
|
||||
for (XSParticle p : group.getChildren()) {
|
||||
if(e==null) e = particle(p);
|
||||
else e = new Sequence(e,particle(p));
|
||||
}
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
public Element elementDecl(XSElementDecl decl) {
|
||||
QName n = BGMBuilder.getName(decl);
|
||||
|
||||
GElementImpl e = decls.get(n);
|
||||
if(e==null)
|
||||
decls.put(n,e=new GElementImpl(n,decl));
|
||||
|
||||
e.particles.add(current);
|
||||
assert current.getTerm()==decl;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
public Expression particle(XSParticle p) {
|
||||
current = p;
|
||||
Expression e = p.getTerm().apply(this);
|
||||
|
||||
if(p.isRepeated())
|
||||
e = new OneOrMore(e);
|
||||
|
||||
if (BigInteger.ZERO.equals(p.getMinOccurs()))
|
||||
e = new Choice(e,Expression.EPSILON);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.Collection;
|
||||
|
||||
import com.sun.tools.internal.xjc.model.CPropertyInfo;
|
||||
import com.sun.tools.internal.xjc.model.Multiplicity;
|
||||
import com.sun.tools.internal.xjc.reader.RawTypeSet;
|
||||
import com.sun.tools.internal.xjc.reader.gbind.ConnectedComponent;
|
||||
import com.sun.tools.internal.xjc.reader.gbind.Element;
|
||||
import com.sun.tools.internal.xjc.reader.gbind.Expression;
|
||||
import com.sun.tools.internal.xjc.reader.gbind.Graph;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIProperty;
|
||||
import com.sun.xml.internal.bind.v2.model.core.WildcardMode;
|
||||
import com.sun.xml.internal.xsom.XSParticle;
|
||||
|
||||
/**
|
||||
* {@link ParticleBinder} that uses {@link ExpressionBuilder} et al
|
||||
* for better, more intuitive (but non spec-conforming) binding.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
final class ExpressionParticleBinder extends ParticleBinder {
|
||||
public void build(XSParticle p, Collection<XSParticle> forcedProps) {
|
||||
// this class isn't about spec conformance, but
|
||||
// for the ease of use.
|
||||
// so we don't give a damn about 'forcedProps'.
|
||||
// although, for a future note, it's conceivable to expand
|
||||
// the binding algorithm to cover this notion.
|
||||
|
||||
Expression tree = ExpressionBuilder.createTree(p);
|
||||
Graph g = new Graph(tree);
|
||||
for (ConnectedComponent cc : g) {
|
||||
buildProperty(cc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a property ouf ot a connected component.
|
||||
*/
|
||||
private void buildProperty(ConnectedComponent cc) {
|
||||
StringBuilder propName = new StringBuilder(); // property name
|
||||
int nameTokenCount = 0; // combine only up to 3
|
||||
|
||||
RawTypeSetBuilder rtsb = new RawTypeSetBuilder();
|
||||
for (Element e : cc) {
|
||||
GElement ge = (GElement)e;
|
||||
|
||||
if(nameTokenCount<3) {
|
||||
if(nameTokenCount!=0)
|
||||
propName.append("And");
|
||||
propName.append(makeJavaName(cc.isCollection(),ge.getPropertyNameSeed()));
|
||||
nameTokenCount++;
|
||||
}
|
||||
|
||||
if(e instanceof GElementImpl) {
|
||||
GElementImpl ei = (GElementImpl) e;
|
||||
rtsb.elementDecl(ei.decl);
|
||||
continue;
|
||||
}
|
||||
if(e instanceof GWildcardElement) {
|
||||
GWildcardElement w = (GWildcardElement)e;
|
||||
rtsb.getRefs().add(new RawTypeSetBuilder.WildcardRef(
|
||||
w.isStrict() ? WildcardMode.STRICT : WildcardMode.SKIP));
|
||||
continue;
|
||||
}
|
||||
assert false : e; // no other kind should be here
|
||||
}
|
||||
|
||||
Multiplicity m = Multiplicity.ONE;
|
||||
if(cc.isCollection())
|
||||
m = m.makeRepeated();
|
||||
if(!cc.isRequired())
|
||||
m = m.makeOptional();
|
||||
|
||||
RawTypeSet rts = new RawTypeSet(rtsb.getRefs(),m);
|
||||
|
||||
XSParticle p = findSourceParticle(cc);
|
||||
|
||||
BIProperty cust = BIProperty.getCustomization(p);
|
||||
CPropertyInfo prop = cust.createElementOrReferenceProperty(
|
||||
propName.toString(), false, p, rts );
|
||||
getCurrentBean().addProperty(prop);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a {@link XSParticle} that can serve as the representative property of
|
||||
* the given {@link ConnectedComponent}.
|
||||
*
|
||||
* The representative property is used for reporting an error location and
|
||||
* taking {@link BIProperty} customization. Right now, the algorithm is just pick
|
||||
* the first one with {@link BIProperty}, but one can think of a better algorithm,
|
||||
* such as taking a choice of (A|B) if CC={A,B}.
|
||||
*/
|
||||
private XSParticle findSourceParticle(ConnectedComponent cc) {
|
||||
XSParticle first = null;
|
||||
|
||||
for (Element e : cc) {
|
||||
GElement ge = (GElement)e;
|
||||
for (XSParticle p : ge.particles) {
|
||||
if(first==null)
|
||||
first = p;
|
||||
if(getLocalPropCustomization(p)!=null)
|
||||
return p;
|
||||
}
|
||||
// if there are multiple property customizations,
|
||||
// all but one will be left unused, which will be detected as an error
|
||||
// later, so no need to check that now.
|
||||
}
|
||||
|
||||
// if no customization was found, just use the first one.
|
||||
return first;
|
||||
}
|
||||
|
||||
public boolean checkFallback(XSParticle p) {
|
||||
// this algorithm never falls back to 'getContent'.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sun.tools.internal.xjc.reader.gbind.Element;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
import com.sun.xml.internal.xsom.XSParticle;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
abstract class GElement extends Element {
|
||||
/**
|
||||
* All the {@link XSParticle}s (whose term is {@link XSElementDecl})
|
||||
* that are coereced into a single {@link Element}.
|
||||
*/
|
||||
final Set<XSParticle> particles = new HashSet<XSParticle>();
|
||||
|
||||
/**
|
||||
* Gets the seed (raw XML name) to be used to generate a property name.
|
||||
*/
|
||||
abstract String getPropertyNameSeed();
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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 javax.xml.namespace.QName;
|
||||
|
||||
import com.sun.tools.internal.xjc.reader.gbind.Element;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
|
||||
/**
|
||||
* {@link Element} that wraps {@link XSElementDecl}.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
final class GElementImpl extends GElement {
|
||||
public final QName tagName;
|
||||
|
||||
/**
|
||||
* The representative {@link XSElementDecl}.
|
||||
*
|
||||
* Even though multiple {@link XSElementDecl}s maybe represented by
|
||||
* a single {@link GElementImpl} (especially when they are local),
|
||||
* the schema spec requires that they share the same type and other
|
||||
* characteristic.
|
||||
*
|
||||
* (To be really precise, you may have different default values,
|
||||
* nillability, all that, so if that becomes a real issue we have
|
||||
* to reconsider this design.)
|
||||
*/
|
||||
public final XSElementDecl decl;
|
||||
|
||||
public GElementImpl(QName tagName, XSElementDecl decl) {
|
||||
this.tagName = tagName;
|
||||
this.decl = decl;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return tagName.toString();
|
||||
}
|
||||
|
||||
String getPropertyNameSeed() {
|
||||
return tagName.getLocalPart();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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 com.sun.tools.internal.xjc.reader.gbind.Element;
|
||||
import com.sun.xml.internal.xsom.XSWildcard;
|
||||
|
||||
/**
|
||||
* {@link Element} that represents a wildcard,
|
||||
* for the "ease of binding" we always just bind this to DOM elements.
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
final class GWildcardElement extends GElement {
|
||||
|
||||
/**
|
||||
* If true, bind to <tt>Object</tt> for eager JAXB unmarshalling.
|
||||
* Otherwise bind to DOM (I hate "you can put both" semantics,
|
||||
* so I'm not going to do that in this binding mode.)
|
||||
*/
|
||||
private boolean strict = true;
|
||||
|
||||
public String toString() {
|
||||
return "#any";
|
||||
}
|
||||
|
||||
String getPropertyNameSeed() {
|
||||
return "any";
|
||||
}
|
||||
|
||||
public void merge(XSWildcard wc) {
|
||||
switch(wc.getMode()) {
|
||||
case XSWildcard.LAX:
|
||||
case XSWildcard.SKIP:
|
||||
strict = false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isStrict() {
|
||||
return strict;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, 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.text.MessageFormat;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* Formats error messages.
|
||||
*/
|
||||
public class Messages
|
||||
{
|
||||
/** Loads a string resource and formats it with specified arguments. */
|
||||
public static String format( String property, Object... args ) {
|
||||
String text = ResourceBundle.getBundle(Messages.class.getPackage().getName() +".MessageBundle").getString(property);
|
||||
return MessageFormat.format(text,args);
|
||||
}
|
||||
|
||||
|
||||
static final String WARN_NO_GLOBAL_ELEMENT =
|
||||
"BGMBuilder.NoGlobalElement";
|
||||
|
||||
public static final String WARN_UNUSED_EXPECTED_CONTENT_TYPES =
|
||||
"UnusedCustomizationChecker.WarnUnusedExpectedContentTypes";
|
||||
|
||||
static final String ERR_MULTIPLE_SCHEMA_BINDINGS =
|
||||
"BGMBuilder.MultipleSchemaBindings"; // arg:1
|
||||
|
||||
static final String ERR_MULTIPLE_SCHEMA_BINDINGS_LOCATION =
|
||||
"BGMBuilder.MultipleSchemaBindings.Location"; // arg:0
|
||||
|
||||
static final String JAVADOC_HEADING = // 1 arg
|
||||
"ClassSelector.JavadocHeading";
|
||||
|
||||
static final String ERR_RESERVED_CLASS_NAME = // 1 arg
|
||||
"ClassSelector.ReservedClassName";
|
||||
|
||||
static final String ERR_CLASS_NAME_IS_REQUIRED =
|
||||
"ClassSelector.ClassNameIsRequired"; // arg:0
|
||||
|
||||
static final String ERR_INCORRECT_CLASS_NAME =
|
||||
"ClassSelector.IncorrectClassName"; // arg:1
|
||||
|
||||
static final String ERR_INCORRECT_PACKAGE_NAME =
|
||||
"ClassSelector.IncorrectPackageName"; // arg:2
|
||||
|
||||
static final String ERR_CANNOT_BE_TYPE_SAFE_ENUM =
|
||||
"ConversionFinder.CannotBeTypeSafeEnum"; // arg:0
|
||||
|
||||
static final String ERR_CANNOT_BE_TYPE_SAFE_ENUM_LOCATION =
|
||||
"ConversionFinder.CannotBeTypeSafeEnum.Location"; // arg:0
|
||||
|
||||
static final String ERR_NO_ENUM_NAME_AVAILABLE =
|
||||
"ConversionFinder.NoEnumNameAvailable"; // arg:0
|
||||
|
||||
static final String ERR_NO_ENUM_FACET =
|
||||
"ConversionFinder.NoEnumFacet"; // arg:0
|
||||
|
||||
static final String ERR_ILLEGAL_EXPECTED_MIME_TYPE =
|
||||
"ERR_ILLEGAL_EXPECTED_MIME_TYPE"; // args:2
|
||||
|
||||
static final String ERR_DATATYPE_ERROR =
|
||||
"DatatypeBuilder.DatatypeError"; // arg:1
|
||||
|
||||
static final String ERR_UNABLE_TO_GENERATE_NAME_FROM_MODELGROUP =
|
||||
"DefaultParticleBinder.UnableToGenerateNameFromModelGroup"; // arg:0
|
||||
|
||||
static final String ERR_INCORRECT_FIXED_VALUE =
|
||||
"FieldBuilder.IncorrectFixedValue"; // arg:1
|
||||
|
||||
static final String ERR_INCORRECT_DEFAULT_VALUE =
|
||||
"FieldBuilder.IncorrectDefaultValue"; // arg:1
|
||||
|
||||
static final String ERR_CONFLICT_BETWEEN_USERTYPE_AND_ACTUALTYPE_ATTUSE =
|
||||
"FieldBuilder.ConflictBetweenUserTypeAndActualType.AttUse"; // arg:2
|
||||
|
||||
static final String ERR_CONFLICT_BETWEEN_USERTYPE_AND_ACTUALTYPE_ATTUSE_SOURCE =
|
||||
"FieldBuilder.ConflictBetweenUserTypeAndActualType.AttUse.Source"; // arg:0
|
||||
|
||||
static final String ERR_UNNESTED_JAVATYPE_CUSTOMIZATION_ON_SIMPLETYPE =
|
||||
"SimpleTypeBuilder.UnnestedJavaTypeCustomization"; // arg:0
|
||||
|
||||
static final String JAVADOC_NIL_PROPERTY =
|
||||
"FieldBuilder.Javadoc.NilProperty"; // arg:1
|
||||
|
||||
static final String JAVADOC_LINE_UNKNOWN = // 0 args
|
||||
"ClassSelector.JavadocLineUnknown";
|
||||
|
||||
static final String JAVADOC_VALUEOBJECT_PROPERTY =
|
||||
"FieldBuilder.Javadoc.ValueObject"; // args:2
|
||||
|
||||
static final String MSG_COLLISION_INFO =
|
||||
"CollisionInfo.CollisionInfo"; // args:3
|
||||
|
||||
static final String MSG_UNKNOWN_FILE =
|
||||
"CollisionInfo.UnknownFile"; // arg:1
|
||||
|
||||
static final String MSG_LINE_X_OF_Y =
|
||||
"CollisionInfo.LineXOfY"; // args:2
|
||||
|
||||
static final String MSG_FALLBACK_JAVADOC =
|
||||
"DefaultParticleBinder.FallbackJavadoc"; // arg:1
|
||||
|
||||
static final String ERR_ENUM_MEMBER_NAME_COLLISION =
|
||||
"ERR_ENUM_MEMBER_NAME_COLLISION";
|
||||
static final String ERR_ENUM_MEMBER_NAME_COLLISION_RELATED =
|
||||
"ERR_ENUM_MEMBER_NAME_COLLISION_RELATED";
|
||||
static final String ERR_CANNOT_GENERATE_ENUM_NAME =
|
||||
"ERR_CANNOT_GENERATE_ENUM_NAME";
|
||||
static final String WARN_ENUM_MEMBER_SIZE_CAP =
|
||||
"WARN_ENUM_MEMBER_SIZE_CAP"; // args: 3
|
||||
|
||||
|
||||
// they are shared from the model
|
||||
public static final String ERR_UNACKNOWLEDGED_CUSTOMIZATION =
|
||||
"UnusedCustomizationChecker.UnacknolwedgedCustomization"; // arg:1
|
||||
public static final String ERR_UNACKNOWLEDGED_CUSTOMIZATION_LOCATION =
|
||||
"UnusedCustomizationChecker.UnacknolwedgedCustomization.Relevant"; // arg:0
|
||||
|
||||
public static final String ERR_MULTIPLE_GLOBAL_BINDINGS =
|
||||
"ERR_MULTIPLE_GLOBAL_BINDINGS";
|
||||
public static final String ERR_MULTIPLE_GLOBAL_BINDINGS_OTHER =
|
||||
"ERR_MULTIPLE_GLOBAL_BINDINGS_OTHER";
|
||||
|
||||
public static final String ERR_REFERENCE_TO_NONEXPORTED_CLASS =
|
||||
"ERR_REFERENCE_TO_NONEXPORTED_CLASS";
|
||||
public static final String ERR_REFERENCE_TO_NONEXPORTED_CLASS_MAP_FALSE =
|
||||
"ERR_REFERENCE_TO_NONEXPORTED_CLASS_MAP_FALSE";
|
||||
public static final String ERR_REFERENCE_TO_NONEXPORTED_CLASS_REFERER =
|
||||
"ERR_REFERENCE_TO_NONEXPORTED_CLASS_REFERER";
|
||||
|
||||
static final String WARN_DEFAULT_VALUE_PRIMITIVE_TYPE =
|
||||
"WARN_DEFAULT_VALUE_PRIMITIVE_TYPE";
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.math.BigInteger;
|
||||
import com.sun.tools.internal.xjc.model.Multiplicity;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
import com.sun.xml.internal.xsom.XSModelGroup;
|
||||
import com.sun.xml.internal.xsom.XSModelGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSParticle;
|
||||
import com.sun.xml.internal.xsom.XSWildcard;
|
||||
import com.sun.xml.internal.xsom.visitor.XSTermFunction;
|
||||
|
||||
import static com.sun.tools.internal.xjc.model.Multiplicity.ONE;
|
||||
import static com.sun.tools.internal.xjc.model.Multiplicity.ZERO;
|
||||
|
||||
/**
|
||||
* Counts {@link Multiplicity} for a particle/term.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public final class MultiplicityCounter implements XSTermFunction<Multiplicity> {
|
||||
|
||||
public static final MultiplicityCounter theInstance = new MultiplicityCounter();
|
||||
|
||||
private MultiplicityCounter() {}
|
||||
|
||||
public Multiplicity particle( XSParticle p ) {
|
||||
Multiplicity m = p.getTerm().apply(this);
|
||||
|
||||
BigInteger max;
|
||||
if (m.max==null || (BigInteger.valueOf(XSParticle.UNBOUNDED).equals(p.getMaxOccurs())))
|
||||
max=null;
|
||||
else
|
||||
max=p.getMaxOccurs();
|
||||
|
||||
return Multiplicity.multiply( m, Multiplicity.create(p.getMinOccurs(),max) );
|
||||
}
|
||||
|
||||
public Multiplicity wildcard(XSWildcard wc) {
|
||||
return ONE;
|
||||
}
|
||||
|
||||
public Multiplicity modelGroupDecl(XSModelGroupDecl decl) {
|
||||
return modelGroup(decl.getModelGroup());
|
||||
}
|
||||
|
||||
public Multiplicity modelGroup(XSModelGroup group) {
|
||||
boolean isChoice = group.getCompositor() == XSModelGroup.CHOICE;
|
||||
|
||||
Multiplicity r = ZERO;
|
||||
|
||||
for( XSParticle p : group.getChildren()) {
|
||||
Multiplicity m = particle(p);
|
||||
|
||||
if(r==null) {
|
||||
r=m;
|
||||
continue;
|
||||
}
|
||||
if(isChoice) {
|
||||
r = Multiplicity.choice(r,m);
|
||||
} else {
|
||||
r = Multiplicity.group(r,m);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public Multiplicity elementDecl(XSElementDecl decl) {
|
||||
return ONE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.text.ParseException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import com.sun.codemodel.internal.JJavaName;
|
||||
import com.sun.tools.internal.xjc.model.CClassInfo;
|
||||
import com.sun.tools.internal.xjc.model.CPropertyInfo;
|
||||
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.BIProperty;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
import com.sun.xml.internal.xsom.XSModelGroup;
|
||||
import com.sun.xml.internal.xsom.XSModelGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSParticle;
|
||||
import com.sun.xml.internal.xsom.XSTerm;
|
||||
import com.sun.xml.internal.xsom.XSWildcard;
|
||||
import com.sun.xml.internal.xsom.visitor.XSTermVisitor;
|
||||
|
||||
/**
|
||||
* Binds the content models of {@link XSParticle} as properties of the class that's being built.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public abstract class ParticleBinder {
|
||||
|
||||
protected final BGMBuilder builder = Ring.get(BGMBuilder.class);
|
||||
|
||||
protected ParticleBinder() {
|
||||
// make sure that this object is available as ParticleBinder, not as their actual implementation classes
|
||||
Ring.add(ParticleBinder.class,this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the {@link CPropertyInfo}s from the given particle
|
||||
* (and its descendants), and set them to the class returned by
|
||||
* {@link ClassSelector#getCurrentBean()}.
|
||||
*/
|
||||
public final void build( XSParticle p ) {
|
||||
build(p, Collections.<XSParticle>emptySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* The version of the build method that forces a specified set of particles
|
||||
* to become a property.
|
||||
*/
|
||||
public abstract void build( XSParticle p, Collection<XSParticle> forcedProps );
|
||||
|
||||
/**
|
||||
* Similar to the build method but this method only checks if
|
||||
* the BGM that will be built by the build method will
|
||||
* do the fallback (map all the properties into one list) or not.
|
||||
*
|
||||
* @return
|
||||
* false if the fallback will not happen.
|
||||
*/
|
||||
public abstract boolean checkFallback( XSParticle p );
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
// convenient utility methods
|
||||
//
|
||||
//
|
||||
|
||||
protected final CClassInfo getCurrentBean() {
|
||||
return getClassSelector().getCurrentBean();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the BIProperty object that applies to the given particle.
|
||||
*/
|
||||
protected final BIProperty getLocalPropCustomization( XSParticle p ) {
|
||||
return getLocalCustomization(p,BIProperty.class);
|
||||
}
|
||||
|
||||
protected final <T extends BIDeclaration> T getLocalCustomization( XSParticle p, Class<T> type ) {
|
||||
// check the property customization of this component first
|
||||
T cust = builder.getBindInfo(p).get(type);
|
||||
if(cust!=null) return cust;
|
||||
|
||||
// if not, the term might have one.
|
||||
cust = builder.getBindInfo(p.getTerm()).get(type);
|
||||
if(cust!=null) return cust;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the label of a given particle.
|
||||
* Usually, the getLabel method should be used instead.
|
||||
*/
|
||||
protected final String computeLabel( XSParticle p ) {
|
||||
// if the particle carries a customization, use that value.
|
||||
// since we are binding content models, it's always non-constant properties.
|
||||
BIProperty cust = getLocalPropCustomization(p);
|
||||
if(cust!=null && cust.getPropertyName(false)!=null)
|
||||
return cust.getPropertyName(false);
|
||||
|
||||
// no explicit property name is given. Compute one.
|
||||
|
||||
XSTerm t = p.getTerm();
|
||||
|
||||
// // first, check if a term is going to be a class, if so, use that name.
|
||||
// ClassItem ci = owner.selector.select(t);
|
||||
// if(ci!=null) {
|
||||
// return makeJavaName(ci.getTypeAsDefined().name());
|
||||
// }
|
||||
|
||||
// if it fails, compute the default name according to the spec.
|
||||
if(t.isElementDecl())
|
||||
// for element, take the element name.
|
||||
return makeJavaName(p,t.asElementDecl().getName());
|
||||
if(t.isModelGroupDecl())
|
||||
// for named model groups, take that name
|
||||
return makeJavaName(p,t.asModelGroupDecl().getName());
|
||||
if(t.isWildcard())
|
||||
// the spec says it will map to "any" by default.
|
||||
return makeJavaName(p,"Any");
|
||||
if(t.isModelGroup()) {
|
||||
try {
|
||||
return getSpecDefaultName(t.asModelGroup(),p.isRepeated());
|
||||
} catch( ParseException e ) {
|
||||
// unable to generate a name.
|
||||
getErrorReporter().error(t.getLocator(),
|
||||
Messages.ERR_UNABLE_TO_GENERATE_NAME_FROM_MODELGROUP);
|
||||
return "undefined"; // recover from error by assuming something
|
||||
}
|
||||
}
|
||||
|
||||
// there are only four types of XSTerm.
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
/** Converts an XML name to the corresponding Java name. */
|
||||
protected final String makeJavaName( boolean isRepeated, String xmlName ) {
|
||||
String name = builder.getNameConverter().toPropertyName(xmlName);
|
||||
if(builder.getGlobalBinding().isSimpleMode() && isRepeated )
|
||||
name = JJavaName.getPluralForm(name);
|
||||
return name;
|
||||
}
|
||||
|
||||
protected final String makeJavaName( XSParticle p, String xmlName ) {
|
||||
return makeJavaName(p.isRepeated(),xmlName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a name from unnamed model group by following the spec.
|
||||
*
|
||||
* Taking first three elements and combine them.
|
||||
*
|
||||
* @param repeated
|
||||
* if the said model group is repeated more than once
|
||||
*
|
||||
* @exception ParseException
|
||||
* If the method cannot generate a name. For example, when
|
||||
* a model group doesn't contain any element reference/declaration
|
||||
* at all.
|
||||
*/
|
||||
protected final String getSpecDefaultName( XSModelGroup mg, final boolean repeated ) throws ParseException {
|
||||
|
||||
final StringBuilder name = new StringBuilder();
|
||||
|
||||
mg.visit(new XSTermVisitor() {
|
||||
/**
|
||||
* Count the number of tokens we combined.
|
||||
* We will concat up to 3.
|
||||
*/
|
||||
private int count=0;
|
||||
|
||||
/**
|
||||
* Is the current particple/term repeated?
|
||||
*/
|
||||
private boolean rep = repeated;
|
||||
|
||||
public void wildcard(XSWildcard wc) {
|
||||
append("any");
|
||||
}
|
||||
|
||||
public void modelGroupDecl(XSModelGroupDecl mgd) {
|
||||
modelGroup(mgd.getModelGroup());
|
||||
}
|
||||
|
||||
public void modelGroup(XSModelGroup mg) {
|
||||
String operator;
|
||||
if(mg.getCompositor()==XSModelGroup.CHOICE) operator = "Or";
|
||||
else operator = "And";
|
||||
|
||||
int size = mg.getSize();
|
||||
for( int i=0; i<size; i++ ) {
|
||||
XSParticle p = mg.getChild(i);
|
||||
boolean oldRep = rep;
|
||||
rep |= p.isRepeated();
|
||||
p.getTerm().visit(this);
|
||||
rep = oldRep;
|
||||
|
||||
if(count==3) return; // we have enough
|
||||
if(i!=size-1) name.append(operator);
|
||||
}
|
||||
}
|
||||
|
||||
public void elementDecl(XSElementDecl ed) {
|
||||
append(ed.getName());
|
||||
}
|
||||
|
||||
private void append(String token) {
|
||||
if( count<3 ) {
|
||||
name.append(makeJavaName(rep,token));
|
||||
count++;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(name.length()==0) throw new ParseException("no element",-1);
|
||||
|
||||
return name.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected final ErrorReporter getErrorReporter() {
|
||||
return Ring.get(ErrorReporter.class);
|
||||
}
|
||||
protected final ClassSelector getClassSelector() {
|
||||
return Ring.get(ClassSelector.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,379 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.activation.MimeType;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import com.sun.tools.internal.xjc.model.CAdapter;
|
||||
import com.sun.tools.internal.xjc.model.CClass;
|
||||
import com.sun.tools.internal.xjc.model.CClassInfo;
|
||||
import com.sun.tools.internal.xjc.model.CCustomizations;
|
||||
import com.sun.tools.internal.xjc.model.CElement;
|
||||
import com.sun.tools.internal.xjc.model.CElementInfo;
|
||||
import com.sun.tools.internal.xjc.model.CElementPropertyInfo;
|
||||
import com.sun.tools.internal.xjc.model.CReferencePropertyInfo;
|
||||
import com.sun.tools.internal.xjc.model.CTypeRef;
|
||||
import com.sun.tools.internal.xjc.model.Model;
|
||||
import com.sun.tools.internal.xjc.model.Multiplicity;
|
||||
import com.sun.tools.internal.xjc.model.TypeUse;
|
||||
import com.sun.tools.internal.xjc.reader.RawTypeSet;
|
||||
import com.sun.tools.internal.xjc.reader.Ring;
|
||||
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.BIXSubstitutable;
|
||||
import com.sun.xml.internal.bind.v2.model.core.ID;
|
||||
import com.sun.xml.internal.bind.v2.model.core.WildcardMode;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
import com.sun.xml.internal.xsom.XSModelGroup;
|
||||
import com.sun.xml.internal.xsom.XSModelGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSParticle;
|
||||
import com.sun.xml.internal.xsom.XSWildcard;
|
||||
import com.sun.xml.internal.xsom.visitor.XSTermVisitor;
|
||||
|
||||
/**
|
||||
* Builds {@link RawTypeSet} for XML Schema.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public class RawTypeSetBuilder implements XSTermVisitor {
|
||||
/**
|
||||
* @param optional
|
||||
* if this whole property is optional due to the
|
||||
* occurrence constraints on ancestors, set this to true.
|
||||
* this will prevent the primitive types to be generated.
|
||||
*/
|
||||
public static RawTypeSet build( XSParticle p, boolean optional ) {
|
||||
RawTypeSetBuilder rtsb = new RawTypeSetBuilder();
|
||||
rtsb.particle(p);
|
||||
Multiplicity mul = MultiplicityCounter.theInstance.particle(p);
|
||||
|
||||
if(optional)
|
||||
mul = mul.makeOptional();
|
||||
|
||||
return new RawTypeSet(rtsb.refs,mul);
|
||||
}
|
||||
|
||||
/**
|
||||
* To avoid declaring the same element twice for a content model like
|
||||
* (A,A), we keep track of element names here while we are building up
|
||||
* this instance.
|
||||
*/
|
||||
private final Set<QName> elementNames = new LinkedHashSet<QName>();
|
||||
|
||||
private final Set<RawTypeSet.Ref> refs = new LinkedHashSet<RawTypeSet.Ref>();
|
||||
|
||||
protected final BGMBuilder builder = Ring.get(BGMBuilder.class);
|
||||
|
||||
public RawTypeSetBuilder() {}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the {@link RawTypeSet.Ref}s that were built.
|
||||
*/
|
||||
public Set<RawTypeSet.Ref> getRefs() {
|
||||
return refs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build up {@link #refs} and compute the total multiplicity of this {@link RawTypeSet.Ref} set.
|
||||
*/
|
||||
private void particle( XSParticle p ) {
|
||||
// if the DOM customization is present, bind it like a wildcard
|
||||
BIDom dom = builder.getLocalDomCustomization(p);
|
||||
if(dom!=null) {
|
||||
dom.markAsAcknowledged();
|
||||
refs.add(new WildcardRef(WildcardMode.SKIP));
|
||||
} else {
|
||||
p.getTerm().visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void wildcard(XSWildcard wc) {
|
||||
refs.add(new WildcardRef(wc));
|
||||
}
|
||||
|
||||
public void modelGroupDecl(XSModelGroupDecl decl) {
|
||||
modelGroup(decl.getModelGroup());
|
||||
}
|
||||
|
||||
public void modelGroup(XSModelGroup group) {
|
||||
for( XSParticle p : group.getChildren())
|
||||
particle(p);
|
||||
}
|
||||
|
||||
public void elementDecl(XSElementDecl decl) {
|
||||
|
||||
QName n = BGMBuilder.getName(decl);
|
||||
if(elementNames.add(n)) {
|
||||
CElement elementBean = Ring.get(ClassSelector.class).bindToType(decl,null);
|
||||
if(elementBean==null)
|
||||
refs.add(new XmlTypeRef(decl));
|
||||
else {
|
||||
// yikes!
|
||||
if(elementBean instanceof CClass)
|
||||
refs.add(new CClassRef(decl,(CClass)elementBean));
|
||||
else
|
||||
refs.add(new CElementInfoRef(decl,(CElementInfo)elementBean));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reference to a wildcard.
|
||||
*/
|
||||
public static final class WildcardRef extends RawTypeSet.Ref {
|
||||
private final WildcardMode mode;
|
||||
|
||||
WildcardRef(XSWildcard wildcard) {
|
||||
this.mode = getMode(wildcard);
|
||||
}
|
||||
WildcardRef(WildcardMode mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
private static WildcardMode getMode(XSWildcard wildcard) {
|
||||
switch(wildcard.getMode()) {
|
||||
case XSWildcard.LAX:
|
||||
return WildcardMode.LAX;
|
||||
case XSWildcard.STRTICT:
|
||||
return WildcardMode.STRICT;
|
||||
case XSWildcard.SKIP:
|
||||
return WildcardMode.SKIP;
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
protected CTypeRef toTypeRef(CElementPropertyInfo ep) {
|
||||
// we don't allow a mapping to typeRef if the wildcard is present
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
protected void toElementRef(CReferencePropertyInfo prop) {
|
||||
prop.setWildcard(mode);
|
||||
}
|
||||
|
||||
protected RawTypeSet.Mode canBeType(RawTypeSet parent) {
|
||||
return RawTypeSet.Mode.MUST_BE_REFERENCE;
|
||||
}
|
||||
|
||||
protected boolean isListOfValues() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected ID id() {
|
||||
return ID.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reference to a class that maps from an element.
|
||||
*/
|
||||
public static final class CClassRef extends RawTypeSet.Ref {
|
||||
public final CClass target;
|
||||
public final XSElementDecl decl;
|
||||
|
||||
CClassRef(XSElementDecl decl, CClass target) {
|
||||
this.decl = decl;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
protected CTypeRef toTypeRef(CElementPropertyInfo ep) {
|
||||
return new CTypeRef(target,decl);
|
||||
}
|
||||
|
||||
protected void toElementRef(CReferencePropertyInfo prop) {
|
||||
prop.getElements().add(target);
|
||||
}
|
||||
|
||||
protected RawTypeSet.Mode canBeType(RawTypeSet parent) {
|
||||
// if element substitution can occur, no way it can be mapped to a list of types
|
||||
if(decl.getSubstitutables().size()>1)
|
||||
return RawTypeSet.Mode.MUST_BE_REFERENCE;
|
||||
|
||||
return RawTypeSet.Mode.SHOULD_BE_TYPEREF;
|
||||
}
|
||||
|
||||
protected boolean isListOfValues() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected ID id() {
|
||||
return ID.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reference to a class that maps from an element.
|
||||
*/
|
||||
public final class CElementInfoRef extends RawTypeSet.Ref {
|
||||
public final CElementInfo target;
|
||||
public final XSElementDecl decl;
|
||||
|
||||
CElementInfoRef(XSElementDecl decl, CElementInfo target) {
|
||||
this.decl = decl;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
protected CTypeRef toTypeRef(CElementPropertyInfo ep) {
|
||||
assert !target.isCollection();
|
||||
CAdapter a = target.getProperty().getAdapter();
|
||||
if(a!=null && ep!=null) ep.setAdapter(a);
|
||||
|
||||
return new CTypeRef(target.getContentType(),decl);
|
||||
}
|
||||
|
||||
protected void toElementRef(CReferencePropertyInfo prop) {
|
||||
prop.getElements().add(target);
|
||||
}
|
||||
|
||||
protected RawTypeSet.Mode canBeType(RawTypeSet parent) {
|
||||
// if element substitution can occur, no way it can be mapped to a list of types
|
||||
if(decl.getSubstitutables().size()>1)
|
||||
return RawTypeSet.Mode.MUST_BE_REFERENCE;
|
||||
// BIXSubstitutable also simulates this effect. Useful for separate compilation
|
||||
BIXSubstitutable subst = builder.getBindInfo(decl).get(BIXSubstitutable.class);
|
||||
if(subst!=null) {
|
||||
subst.markAsAcknowledged();
|
||||
return RawTypeSet.Mode.MUST_BE_REFERENCE;
|
||||
}
|
||||
|
||||
// we have no place to put an adater if this thing maps to a type
|
||||
CElementPropertyInfo p = target.getProperty();
|
||||
// if we have an adapter or IDness, which requires special
|
||||
// annotation, and there's more than one element,
|
||||
// we have no place to put the special annotation, so we need JAXBElement.
|
||||
if((parent.refs.size()>1 || !parent.mul.isAtMostOnce()) && p.id()!=ID.NONE)
|
||||
return RawTypeSet.Mode.MUST_BE_REFERENCE;
|
||||
if(parent.refs.size() > 1 && p.getAdapter() != null)
|
||||
return RawTypeSet.Mode.MUST_BE_REFERENCE;
|
||||
|
||||
if(target.hasClass())
|
||||
// if the CElementInfo was explicitly bound to a class (which happen if and only if
|
||||
// the user requested so, then map that to reference property so that the user sees a class
|
||||
return RawTypeSet.Mode.CAN_BE_TYPEREF;
|
||||
else
|
||||
return RawTypeSet.Mode.SHOULD_BE_TYPEREF;
|
||||
}
|
||||
|
||||
protected boolean isListOfValues() {
|
||||
return target.getProperty().isValueList();
|
||||
}
|
||||
|
||||
protected ID id() {
|
||||
return target.getProperty().id();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MimeType getExpectedMimeType() {
|
||||
return target.getProperty().getExpectedMimeType();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* References to a type. Could be global or local.
|
||||
*/
|
||||
public static final class XmlTypeRef extends RawTypeSet.Ref {
|
||||
private final XSElementDecl decl;
|
||||
private final TypeUse target;
|
||||
|
||||
public XmlTypeRef(XSElementDecl decl) {
|
||||
this.decl = decl;
|
||||
SimpleTypeBuilder stb = Ring.get(SimpleTypeBuilder.class);
|
||||
stb.refererStack.push(decl);
|
||||
TypeUse r = Ring.get(ClassSelector.class).bindToType(decl.getType(),decl);
|
||||
stb.refererStack.pop();
|
||||
target = r;
|
||||
}
|
||||
|
||||
protected CTypeRef toTypeRef(CElementPropertyInfo ep) {
|
||||
if(ep!=null && target.getAdapterUse()!=null)
|
||||
ep.setAdapter(target.getAdapterUse());
|
||||
return new CTypeRef(target.getInfo(),decl);
|
||||
}
|
||||
|
||||
/**
|
||||
* The whole type set can be later bound to a reference property,
|
||||
* in which case we need to generate additional code to wrap this
|
||||
* type reference into an element class.
|
||||
*
|
||||
* This method generates such an element class and returns it.
|
||||
*/
|
||||
protected void toElementRef(CReferencePropertyInfo prop) {
|
||||
CClassInfo scope = Ring.get(ClassSelector.class).getCurrentBean();
|
||||
Model model = Ring.get(Model.class);
|
||||
|
||||
CCustomizations custs = Ring.get(BGMBuilder.class).getBindInfo(decl).toCustomizationList();
|
||||
|
||||
if(target instanceof CClassInfo && Ring.get(BIGlobalBinding.class).isSimpleMode()) {
|
||||
CClassInfo bean = new CClassInfo(model,scope,
|
||||
model.getNameConverter().toClassName(decl.getName()),
|
||||
decl.getLocator(), null, BGMBuilder.getName(decl), decl,
|
||||
custs);
|
||||
bean.setBaseClass((CClassInfo)target);
|
||||
prop.getElements().add(bean);
|
||||
} else {
|
||||
CElementInfo e = new CElementInfo(model,BGMBuilder.getName(decl),scope,target,
|
||||
decl.getDefaultValue(), decl, custs, decl.getLocator());
|
||||
prop.getElements().add(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected RawTypeSet.Mode canBeType(RawTypeSet parent) {
|
||||
// if we have an adapter or IDness, which requires special
|
||||
// annotation, and there's more than one element,
|
||||
// we have no place to put the special annotation, so we need JAXBElement.
|
||||
if((parent.refs.size()>1 || !parent.mul.isAtMostOnce()) && target.idUse()!=ID.NONE)
|
||||
return RawTypeSet.Mode.MUST_BE_REFERENCE;
|
||||
if(parent.refs.size() > 1 && target.getAdapterUse() != null)
|
||||
return RawTypeSet.Mode.MUST_BE_REFERENCE;
|
||||
|
||||
// nillable and optional at the same time. needs an element wrapper to distinguish those
|
||||
// two states. But this is not a hard requirement.
|
||||
if(decl.isNillable() && parent.mul.isOptional())
|
||||
return RawTypeSet.Mode.CAN_BE_TYPEREF;
|
||||
|
||||
return RawTypeSet.Mode.SHOULD_BE_TYPEREF;
|
||||
}
|
||||
|
||||
protected boolean isListOfValues() {
|
||||
return target.isCollection();
|
||||
}
|
||||
|
||||
protected ID id() {
|
||||
return target.idUse();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MimeType getExpectedMimeType() {
|
||||
return target.getExpectedMimeType();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Collections;
|
||||
|
||||
import com.sun.xml.internal.xsom.XSAnnotation;
|
||||
import com.sun.xml.internal.xsom.XSAttGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSAttributeDecl;
|
||||
import com.sun.xml.internal.xsom.XSAttributeUse;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSComponent;
|
||||
import com.sun.xml.internal.xsom.XSContentType;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
import com.sun.xml.internal.xsom.XSFacet;
|
||||
import com.sun.xml.internal.xsom.XSIdentityConstraint;
|
||||
import com.sun.xml.internal.xsom.XSModelGroup;
|
||||
import com.sun.xml.internal.xsom.XSModelGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSNotation;
|
||||
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.XSType;
|
||||
import com.sun.xml.internal.xsom.XSWildcard;
|
||||
import com.sun.xml.internal.xsom.XSXPath;
|
||||
import com.sun.xml.internal.xsom.visitor.XSVisitor;
|
||||
|
||||
/**
|
||||
* Finds which {@link XSComponent}s refer to which {@link XSComplexType}s.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
final class RefererFinder implements XSVisitor {
|
||||
private final Set<Object> visited = new HashSet<Object>();
|
||||
|
||||
private final Map<XSComponent,Set<XSComponent>> referers = new HashMap<XSComponent,Set<XSComponent>>();
|
||||
|
||||
public Set<XSComponent> getReferer(XSComponent src) {
|
||||
Set<XSComponent> r = referers.get(src);
|
||||
if(r==null) return Collections.emptySet();
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
public void schemaSet(XSSchemaSet xss) {
|
||||
if(!visited.add(xss)) return;
|
||||
|
||||
for (XSSchema xs : xss.getSchemas()) {
|
||||
schema(xs);
|
||||
}
|
||||
}
|
||||
|
||||
public void schema(XSSchema xs) {
|
||||
if(!visited.add(xs)) return;
|
||||
|
||||
for (XSComplexType ct : xs.getComplexTypes().values()) {
|
||||
complexType(ct);
|
||||
}
|
||||
|
||||
for (XSElementDecl e : xs.getElementDecls().values()) {
|
||||
elementDecl(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void elementDecl(XSElementDecl e) {
|
||||
if(!visited.add(e)) return;
|
||||
|
||||
refer(e,e.getType());
|
||||
e.getType().visit(this);
|
||||
}
|
||||
|
||||
public void complexType(XSComplexType ct) {
|
||||
if(!visited.add(ct)) return;
|
||||
|
||||
refer(ct,ct.getBaseType());
|
||||
ct.getBaseType().visit(this);
|
||||
ct.getContentType().visit(this);
|
||||
}
|
||||
|
||||
public void modelGroupDecl(XSModelGroupDecl decl) {
|
||||
if(!visited.add(decl)) return;
|
||||
|
||||
modelGroup(decl.getModelGroup());
|
||||
}
|
||||
|
||||
public void modelGroup(XSModelGroup group) {
|
||||
if(!visited.add(group)) return;
|
||||
|
||||
for (XSParticle p : group.getChildren()) {
|
||||
particle(p);
|
||||
}
|
||||
}
|
||||
|
||||
public void particle(XSParticle particle) {
|
||||
// since the particle method is side-effect free, no need to check for double-visit.
|
||||
particle.getTerm().visit(this);
|
||||
}
|
||||
|
||||
|
||||
// things we don't care
|
||||
public void simpleType(XSSimpleType simpleType) {}
|
||||
public void annotation(XSAnnotation ann) {}
|
||||
public void attGroupDecl(XSAttGroupDecl decl) {}
|
||||
public void attributeDecl(XSAttributeDecl decl) {}
|
||||
public void attributeUse(XSAttributeUse use) {}
|
||||
public void facet(XSFacet facet) {}
|
||||
public void notation(XSNotation notation) {}
|
||||
public void identityConstraint(XSIdentityConstraint decl) {}
|
||||
public void xpath(XSXPath xp) {}
|
||||
public void wildcard(XSWildcard wc) {}
|
||||
public void empty(XSContentType empty) {}
|
||||
|
||||
/**
|
||||
* Called for each reference to record the fact.
|
||||
*
|
||||
* So far we only care about references to types.
|
||||
*/
|
||||
private void refer(XSComponent source, XSType target) {
|
||||
Set<XSComponent> r = referers.get(target);
|
||||
if(r==null) {
|
||||
r = new HashSet<XSComponent>();
|
||||
referers.put(target,r);
|
||||
}
|
||||
r.add(source);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,918 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.io.StringWriter;
|
||||
import java.math.BigInteger;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
import javax.activation.MimeTypeParseException;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
|
||||
import com.sun.codemodel.internal.JJavaName;
|
||||
import com.sun.codemodel.internal.util.JavadocEscapeWriter;
|
||||
import com.sun.xml.internal.bind.v2.WellKnownNamespace;
|
||||
import com.sun.tools.internal.xjc.ErrorReceiver;
|
||||
import com.sun.tools.internal.xjc.model.CBuiltinLeafInfo;
|
||||
import com.sun.tools.internal.xjc.model.CClassInfo;
|
||||
import com.sun.tools.internal.xjc.model.CClassInfoParent;
|
||||
import com.sun.tools.internal.xjc.model.CClassRef;
|
||||
import com.sun.tools.internal.xjc.model.CEnumConstant;
|
||||
import com.sun.tools.internal.xjc.model.CEnumLeafInfo;
|
||||
import com.sun.tools.internal.xjc.model.CNonElement;
|
||||
import com.sun.tools.internal.xjc.model.Model;
|
||||
import com.sun.tools.internal.xjc.model.TypeUse;
|
||||
import com.sun.tools.internal.xjc.model.TypeUseFactory;
|
||||
import com.sun.tools.internal.xjc.reader.Const;
|
||||
import com.sun.tools.internal.xjc.reader.Ring;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIConversion;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIEnum;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIEnumMember;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIProperty;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BindInfo;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.EnumMemberMode;
|
||||
import com.sun.tools.internal.xjc.util.MimeTypeRange;
|
||||
|
||||
import static com.sun.xml.internal.bind.v2.WellKnownNamespace.XML_MIME_URI;
|
||||
|
||||
import com.sun.xml.internal.bind.v2.runtime.SwaRefAdapterMarker;
|
||||
import com.sun.xml.internal.xsom.XSAttributeDecl;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSComponent;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
import com.sun.xml.internal.xsom.XSFacet;
|
||||
import com.sun.xml.internal.xsom.XSListSimpleType;
|
||||
import com.sun.xml.internal.xsom.XSRestrictionSimpleType;
|
||||
import com.sun.xml.internal.xsom.XSSimpleType;
|
||||
import com.sun.xml.internal.xsom.XSUnionSimpleType;
|
||||
import com.sun.xml.internal.xsom.XSVariety;
|
||||
import com.sun.xml.internal.xsom.impl.util.SchemaWriter;
|
||||
import com.sun.xml.internal.xsom.visitor.XSSimpleTypeFunction;
|
||||
import com.sun.xml.internal.xsom.visitor.XSVisitor;
|
||||
|
||||
import org.xml.sax.Locator;
|
||||
|
||||
/**
|
||||
* Builds {@link TypeUse} from simple types.
|
||||
*
|
||||
* <p>
|
||||
* This code consists of two main portions. The {@link #compose(XSSimpleType)} method
|
||||
* and {@link #composer} forms an outer cycle, which gradually ascends the type
|
||||
* inheritance chain until it finds the suitable binding. When it does this
|
||||
* {@link #initiatingType} is set to the type which started binding, so that we can refer
|
||||
* to the actual constraint facets and such that are applicable on the type.
|
||||
*
|
||||
* <p>
|
||||
* For each intermediate type in the chain, the {@link #find(XSSimpleType)} method
|
||||
* is used to find the binding on that type, sine the outer loop is doing the ascending,
|
||||
* this method only sees if the current type has some binding available.
|
||||
*
|
||||
* <p>
|
||||
* There is at least one ugly code that you need to aware of
|
||||
* when you are modifying the code. See the documentation
|
||||
* about <a href="package.html#stref_cust">
|
||||
* "simple type customization at the point of reference."</a>
|
||||
*
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public final class SimpleTypeBuilder extends BindingComponent {
|
||||
|
||||
protected final BGMBuilder builder = Ring.get(BGMBuilder.class);
|
||||
|
||||
private final Model model = Ring.get(Model.class);
|
||||
|
||||
/**
|
||||
* The component that is refering to the simple type
|
||||
* which we are building. This is ugly but necessary
|
||||
* to support the customization of simple types at
|
||||
* its point of reference. See my comment at the header
|
||||
* of this class for details.
|
||||
*
|
||||
* UGLY: Implemented as a Stack of XSComponent to fix a bug
|
||||
*/
|
||||
public final Stack<XSComponent> refererStack = new Stack<XSComponent>();
|
||||
|
||||
/**
|
||||
* Records what xmime:expectedContentTypes annotations we honored and processed,
|
||||
* so that we can later check if the user had these annotations in the places
|
||||
* where we didn't anticipate them.
|
||||
*/
|
||||
private final Set<XSComponent> acknowledgedXmimeContentTypes = new HashSet<XSComponent>();
|
||||
|
||||
/**
|
||||
* The type that was originally passed to this {@link SimpleTypeBuilder#build(XSSimpleType)}.
|
||||
* Never null.
|
||||
*/
|
||||
private XSSimpleType initiatingType;
|
||||
|
||||
/** {@link TypeUse}s for the built-in types. Read-only. */
|
||||
public static final Map<String,TypeUse> builtinConversions = new HashMap<String,TypeUse>();
|
||||
|
||||
|
||||
/**
|
||||
* Entry point from outside. Builds a BGM type expression
|
||||
* from a simple type schema component.
|
||||
*
|
||||
* @param type
|
||||
* the simple type to be bound.
|
||||
*/
|
||||
public TypeUse build( XSSimpleType type ) {
|
||||
XSSimpleType oldi = initiatingType;
|
||||
this.initiatingType = type;
|
||||
|
||||
TypeUse e = checkRefererCustomization(type);
|
||||
if(e==null)
|
||||
e = compose(type);
|
||||
|
||||
initiatingType = oldi;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* A version of the {@link #build(XSSimpleType)} method
|
||||
* used to bind the definition of a class generated from
|
||||
* the given simple type.
|
||||
*/
|
||||
public TypeUse buildDef( XSSimpleType type ) {
|
||||
XSSimpleType oldi = initiatingType;
|
||||
this.initiatingType = type;
|
||||
|
||||
TypeUse e = type.apply(composer);
|
||||
|
||||
initiatingType = oldi;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a javaType customization specified to the referer, if present.
|
||||
* @return can be null.
|
||||
*/
|
||||
private BIConversion getRefererCustomization() {
|
||||
BindInfo info = builder.getBindInfo(getReferer());
|
||||
BIProperty prop = info.get(BIProperty.class);
|
||||
if(prop==null) return null;
|
||||
return prop.getConv();
|
||||
}
|
||||
|
||||
public XSComponent getReferer() {
|
||||
return refererStack.peek();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the referer has a conversion customization or not.
|
||||
* If it does, use it to bind this simple type. Otherwise
|
||||
* return null;
|
||||
*/
|
||||
private TypeUse checkRefererCustomization( XSSimpleType type ) {
|
||||
|
||||
// assertion check. referer must be set properly
|
||||
// before the build method is called.
|
||||
// since the handling of the simple type point-of-reference
|
||||
// customization is very error prone, it deserves a strict
|
||||
// assertion check.
|
||||
// UGLY CODE WARNING
|
||||
XSComponent top = getReferer();
|
||||
|
||||
if( top instanceof XSElementDecl ) {
|
||||
// if the parent is element type, its content type must be us.
|
||||
XSElementDecl eref = (XSElementDecl)top;
|
||||
assert eref.getType()==type;
|
||||
|
||||
// for elements, you can't use <property>,
|
||||
// so we allow javaType to appear directly.
|
||||
BindInfo info = builder.getBindInfo(top);
|
||||
BIConversion conv = info.get(BIConversion.class);
|
||||
if(conv!=null) {
|
||||
conv.markAsAcknowledged();
|
||||
// the conversion is given.
|
||||
return conv.getTypeUse(type);
|
||||
}
|
||||
detectJavaTypeCustomization();
|
||||
} else
|
||||
if( top instanceof XSAttributeDecl ) {
|
||||
XSAttributeDecl aref = (XSAttributeDecl)top;
|
||||
assert aref.getType()==type;
|
||||
detectJavaTypeCustomization();
|
||||
} else
|
||||
if( top instanceof XSComplexType ) {
|
||||
XSComplexType tref = (XSComplexType)top;
|
||||
assert tref.getBaseType()==type || tref.getContentType()==type;
|
||||
detectJavaTypeCustomization();
|
||||
} else
|
||||
if( top == type ) {
|
||||
// this means the simple type is built by itself and
|
||||
// not because it's referenced by something.
|
||||
} else
|
||||
// unexpected referer type.
|
||||
assert false;
|
||||
|
||||
// now we are certain that the referer is OK.
|
||||
// see if it has a conversion customization.
|
||||
BIConversion conv = getRefererCustomization();
|
||||
if(conv!=null) {
|
||||
conv.markAsAcknowledged();
|
||||
// the conversion is given.
|
||||
return conv.getTypeUse(type);
|
||||
} else
|
||||
// not found
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect "javaType" customizations placed directly on simple types, rather
|
||||
* than being enclosed by "property" and "baseType" customizations (see
|
||||
* sec 6.8.1 of the spec).
|
||||
*
|
||||
* Report an error if any exist.
|
||||
*/
|
||||
private void detectJavaTypeCustomization() {
|
||||
BindInfo info = builder.getBindInfo(getReferer());
|
||||
BIConversion conv = info.get(BIConversion.class);
|
||||
|
||||
if( conv != null ) {
|
||||
// ack this conversion to prevent further error messages
|
||||
conv.markAsAcknowledged();
|
||||
|
||||
// report the error
|
||||
getErrorReporter().error( conv.getLocation(),
|
||||
Messages.ERR_UNNESTED_JAVATYPE_CUSTOMIZATION_ON_SIMPLETYPE );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively decend the type inheritance chain to find a binding.
|
||||
*/
|
||||
TypeUse compose( XSSimpleType t ) {
|
||||
TypeUse e = find(t);
|
||||
if(e!=null) return e;
|
||||
return t.apply(composer);
|
||||
}
|
||||
|
||||
public final XSSimpleTypeFunction<TypeUse> composer = new XSSimpleTypeFunction<TypeUse>() {
|
||||
|
||||
public TypeUse listSimpleType(XSListSimpleType type) {
|
||||
// bind item type individually and then compose them into a list
|
||||
// facets on the list shouldn't be taken account when binding item types,
|
||||
// so weed to call build(), not compose().
|
||||
XSSimpleType itemType = type.getItemType();
|
||||
refererStack.push(itemType);
|
||||
TypeUse tu = TypeUseFactory.makeCollection(build(type.getItemType()));
|
||||
refererStack.pop();
|
||||
return tu;
|
||||
}
|
||||
|
||||
public TypeUse unionSimpleType(XSUnionSimpleType type) {
|
||||
boolean isCollection = false;
|
||||
for( int i=0; i<type.getMemberSize(); i++ )
|
||||
if(type.getMember(i).getVariety()==XSVariety.LIST || type.getMember(i).getVariety()==XSVariety.UNION) {
|
||||
isCollection = true;
|
||||
break;
|
||||
}
|
||||
|
||||
TypeUse r = CBuiltinLeafInfo.STRING;
|
||||
if(isCollection)
|
||||
r = TypeUseFactory.makeCollection(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
public TypeUse restrictionSimpleType(XSRestrictionSimpleType type) {
|
||||
// just process the base type.
|
||||
return compose(type.getSimpleBaseType());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if there's any binding available on the given type.
|
||||
*
|
||||
* @return
|
||||
* null if not (which causes the {@link #compose(XSSimpleType)} method
|
||||
* to do ascending.
|
||||
*/
|
||||
private TypeUse find( XSSimpleType type ) {
|
||||
TypeUse r;
|
||||
boolean noAutoEnum = false;
|
||||
|
||||
// check for user specified conversion
|
||||
BindInfo info = builder.getBindInfo(type);
|
||||
BIConversion conv = info.get(BIConversion.class);
|
||||
|
||||
if( conv!=null ) {
|
||||
// a conversion was found
|
||||
conv.markAsAcknowledged();
|
||||
return conv.getTypeUse(type);
|
||||
}
|
||||
|
||||
// look for enum customization, which is another user specified conversion
|
||||
BIEnum en = info.get(BIEnum.class);
|
||||
if( en!=null ) {
|
||||
en.markAsAcknowledged();
|
||||
|
||||
if(!en.isMapped()) {
|
||||
noAutoEnum = true;
|
||||
} else {
|
||||
// if an enum customization is specified, make sure
|
||||
// the type is OK
|
||||
if( !canBeMappedToTypeSafeEnum(type) ) {
|
||||
getErrorReporter().error( en.getLocation(),
|
||||
Messages.ERR_CANNOT_BE_TYPE_SAFE_ENUM );
|
||||
getErrorReporter().error( type.getLocator(),
|
||||
Messages.ERR_CANNOT_BE_TYPE_SAFE_ENUM_LOCATION );
|
||||
// recover by ignoring this customization
|
||||
return null;
|
||||
}
|
||||
|
||||
// reference?
|
||||
if(en.ref!=null) {
|
||||
if(!JJavaName.isFullyQualifiedClassName(en.ref)) {
|
||||
Ring.get(ErrorReceiver.class).error( en.getLocation(),
|
||||
Messages.format(Messages.ERR_INCORRECT_CLASS_NAME, en.ref) );
|
||||
// recover by ignoring @ref
|
||||
return null;
|
||||
}
|
||||
|
||||
return new CClassRef(model, type, en, info.toCustomizationList() );
|
||||
}
|
||||
|
||||
// list and union cannot be mapped to a type-safe enum,
|
||||
// so in this stage we can safely cast it to XSRestrictionSimpleType
|
||||
return bindToTypeSafeEnum( (XSRestrictionSimpleType)type,
|
||||
en.className, en.javadoc, en.members,
|
||||
getEnumMemberMode().getModeWithEnum(),
|
||||
en.getLocation() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if the type is built in, look for the default binding
|
||||
if(type.getTargetNamespace().equals(WellKnownNamespace.XML_SCHEMA)) {
|
||||
String name = type.getName();
|
||||
if(name!=null) {
|
||||
r = lookupBuiltin(name);
|
||||
if(r!=null)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
// also check for swaRef
|
||||
if(type.getTargetNamespace().equals(WellKnownNamespace.SWA_URI)) {
|
||||
String name = type.getName();
|
||||
if(name!=null && name.equals("swaRef"))
|
||||
return CBuiltinLeafInfo.STRING.makeAdapted(SwaRefAdapterMarker.class,false);
|
||||
}
|
||||
|
||||
|
||||
// see if this type should be mapped to a type-safe enumeration by default.
|
||||
// if so, built a EnumXDucer from it and return it.
|
||||
if(type.isRestriction() && !noAutoEnum) {
|
||||
XSRestrictionSimpleType rst = type.asRestriction();
|
||||
if(shouldBeMappedToTypeSafeEnumByDefault(rst)) {
|
||||
r = bindToTypeSafeEnum(rst,null,null, Collections.<String, BIEnumMember>emptyMap(),
|
||||
getEnumMemberMode(),null);
|
||||
if(r!=null)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return (CNonElement)getClassSelector()._bindToClass(type,null,false);
|
||||
}
|
||||
|
||||
private static Set<XSRestrictionSimpleType> reportedEnumMemberSizeWarnings;
|
||||
|
||||
/**
|
||||
* Returns true if a type-safe enum should be created from
|
||||
* the given simple type by default without an explicit <jaxb:enum> customization.
|
||||
*/
|
||||
private boolean shouldBeMappedToTypeSafeEnumByDefault( XSRestrictionSimpleType type ) {
|
||||
|
||||
// if not, there will be a problem wrt the class name of this type safe enum type.
|
||||
if( type.isLocal() ) return false;
|
||||
|
||||
// if redefined, we should map the new definition, not the old one.
|
||||
if( type.getRedefinedBy()!=null ) return false;
|
||||
|
||||
List<XSFacet> facets = type.getDeclaredFacets(XSFacet.FACET_ENUMERATION);
|
||||
if( facets.isEmpty() )
|
||||
// if the type itself doesn't have the enumeration facet,
|
||||
// it won't be mapped to a type-safe enum.
|
||||
return false;
|
||||
|
||||
if(facets.size() > builder.getGlobalBinding().getDefaultEnumMemberSizeCap()) {
|
||||
// if there are too many facets, it's not very useful
|
||||
// produce warning when simple type is not mapped to enum
|
||||
// see issue https://jaxb.dev.java.net/issues/show_bug.cgi?id=711
|
||||
|
||||
if(reportedEnumMemberSizeWarnings == null)
|
||||
reportedEnumMemberSizeWarnings = new HashSet<XSRestrictionSimpleType>();
|
||||
|
||||
if(!reportedEnumMemberSizeWarnings.contains(type)) {
|
||||
getErrorReporter().warning(type.getLocator(), Messages.WARN_ENUM_MEMBER_SIZE_CAP,
|
||||
type.getName(), facets.size(), builder.getGlobalBinding().getDefaultEnumMemberSizeCap());
|
||||
|
||||
reportedEnumMemberSizeWarnings.add(type);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !canBeMappedToTypeSafeEnum(type) )
|
||||
// we simply can't map this to an enumeration
|
||||
return false;
|
||||
|
||||
// check for collisions among constant names. if a collision will happen,
|
||||
// don't try to bind it to an enum.
|
||||
|
||||
// return true only when this type is derived from one of the "enum base type".
|
||||
for( XSSimpleType t = type; t!=null; t=t.getSimpleBaseType() )
|
||||
if( t.isGlobal() && builder.getGlobalBinding().canBeMappedToTypeSafeEnum(t) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private static final Set<String> builtinTypeSafeEnumCapableTypes;
|
||||
|
||||
static {
|
||||
Set<String> s = new HashSet<String>();
|
||||
|
||||
// see a bullet of 6.5.1 of the spec.
|
||||
String[] typeNames = new String[] {
|
||||
"string", "boolean", "float", "decimal", "double", "anyURI"
|
||||
};
|
||||
s.addAll(Arrays.asList(typeNames));
|
||||
|
||||
builtinTypeSafeEnumCapableTypes = Collections.unmodifiableSet(s);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the given simple type can be mapped to a
|
||||
* type-safe enum class.
|
||||
*
|
||||
* <p>
|
||||
* JAXB spec places a restrictrion as to what type can be
|
||||
* mapped to a type-safe enum. This method enforces this
|
||||
* constraint.
|
||||
*/
|
||||
public static boolean canBeMappedToTypeSafeEnum( XSSimpleType type ) {
|
||||
do {
|
||||
if( WellKnownNamespace.XML_SCHEMA.equals(type.getTargetNamespace()) ) {
|
||||
// type must be derived from one of these types
|
||||
String localName = type.getName();
|
||||
if( localName!=null ) {
|
||||
if( localName.equals("anySimpleType") )
|
||||
return false; // catch all case
|
||||
if( localName.equals("ID") || localName.equals("IDREF") )
|
||||
return false; // not ID/IDREF
|
||||
|
||||
// other allowed list
|
||||
if( builtinTypeSafeEnumCapableTypes.contains(localName) )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
type = type.getSimpleBaseType();
|
||||
} while( type!=null );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Builds a type-safe enum conversion from a simple type
|
||||
* with enumeration facets.
|
||||
*
|
||||
* @param className
|
||||
* The class name of the type-safe enum. Or null to
|
||||
* create a default name.
|
||||
* @param javadoc
|
||||
* Additional javadoc that will be added at the beginning of the
|
||||
* class, or null if none is necessary.
|
||||
* @param members
|
||||
* A map from enumeration values (as String) to BIEnumMember objects.
|
||||
* if some of the value names need to be overrided.
|
||||
* Cannot be null, but the map may not contain entries
|
||||
* for all enumeration values.
|
||||
* @param loc
|
||||
* The source location where the above customizations are
|
||||
* specified, or null if none is available.
|
||||
*/
|
||||
private TypeUse bindToTypeSafeEnum( XSRestrictionSimpleType type,
|
||||
String className, String javadoc, Map<String,BIEnumMember> members,
|
||||
EnumMemberMode mode, Locator loc ) {
|
||||
|
||||
if( loc==null ) // use the location of the simple type as the default
|
||||
loc = type.getLocator();
|
||||
|
||||
if( className==null ) {
|
||||
// infer the class name. For this to be possible,
|
||||
// the simple type must be a global one.
|
||||
if( !type.isGlobal() ) {
|
||||
getErrorReporter().error( loc, Messages.ERR_NO_ENUM_NAME_AVAILABLE );
|
||||
// recover by returning a meaningless conversion
|
||||
return CBuiltinLeafInfo.STRING;
|
||||
}
|
||||
className = type.getName();
|
||||
}
|
||||
|
||||
// we apply name conversion in any case
|
||||
className = builder.deriveName(className,type);
|
||||
|
||||
{// compute Javadoc
|
||||
StringWriter out = new StringWriter();
|
||||
SchemaWriter sw = new SchemaWriter(new JavadocEscapeWriter(out));
|
||||
type.visit((XSVisitor)sw);
|
||||
|
||||
if(javadoc!=null) javadoc += "\n\n";
|
||||
else javadoc = "";
|
||||
|
||||
javadoc += Messages.format( Messages.JAVADOC_HEADING, type.getName() )
|
||||
+"\n<p>\n<pre>\n"+out.getBuffer()+"</pre>";
|
||||
|
||||
}
|
||||
|
||||
// build base type
|
||||
refererStack.push(type.getSimpleBaseType());
|
||||
TypeUse use = build(type.getSimpleBaseType());
|
||||
refererStack.pop();
|
||||
|
||||
if(use.isCollection())
|
||||
return null; // can't bind a list to enum constant
|
||||
|
||||
CNonElement baseDt = use.getInfo(); // for now just ignore that case
|
||||
|
||||
if(baseDt instanceof CClassInfo)
|
||||
return null; // can't bind to an enum if the base is a class, since we don't have the value constrctor
|
||||
|
||||
// if the member names collide, re-generate numbered constant names.
|
||||
XSFacet[] errorRef = new XSFacet[1];
|
||||
List<CEnumConstant> memberList = buildCEnumConstants(type, false, members, errorRef);
|
||||
if(memberList==null || checkMemberNameCollision(memberList)!=null) {
|
||||
switch(mode) {
|
||||
case SKIP:
|
||||
// abort
|
||||
return null;
|
||||
case ERROR:
|
||||
// error
|
||||
if(memberList==null) {
|
||||
getErrorReporter().error( errorRef[0].getLocator(),
|
||||
Messages.ERR_CANNOT_GENERATE_ENUM_NAME,
|
||||
errorRef[0].getValue() );
|
||||
} else {
|
||||
CEnumConstant[] collision = checkMemberNameCollision(memberList);
|
||||
getErrorReporter().error( collision[0].getLocator(),
|
||||
Messages.ERR_ENUM_MEMBER_NAME_COLLISION,
|
||||
collision[0].getName() );
|
||||
getErrorReporter().error( collision[1].getLocator(),
|
||||
Messages.ERR_ENUM_MEMBER_NAME_COLLISION_RELATED );
|
||||
}
|
||||
return null; // recover from error
|
||||
case GENERATE:
|
||||
// generate
|
||||
memberList = buildCEnumConstants(type,true,members,null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(memberList.isEmpty()) {
|
||||
getErrorReporter().error( loc, Messages.ERR_NO_ENUM_FACET );
|
||||
return null;
|
||||
}
|
||||
|
||||
// use the name of the simple type as the name of the class.
|
||||
CClassInfoParent scope;
|
||||
if(type.isGlobal())
|
||||
scope = new CClassInfoParent.Package(getClassSelector().getPackage(type.getTargetNamespace()));
|
||||
else
|
||||
scope = getClassSelector().getClassScope();
|
||||
CEnumLeafInfo xducer = new CEnumLeafInfo( model, BGMBuilder.getName(type), scope,
|
||||
className, baseDt, memberList, type,
|
||||
builder.getBindInfo(type).toCustomizationList(), loc );
|
||||
xducer.javadoc = javadoc;
|
||||
|
||||
BIConversion conv = new BIConversion.Static( type.getLocator(),xducer);
|
||||
conv.markAsAcknowledged();
|
||||
|
||||
// attach this new conversion object to this simple type
|
||||
// so that successive look up will use the same object.
|
||||
builder.getOrCreateBindInfo(type).addDecl(conv);
|
||||
|
||||
return conv.getTypeUse(type);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param errorRef
|
||||
* if constant names couldn't be generated, return a reference to that enum facet.
|
||||
* @return
|
||||
* null if unable to generate names for some of the constants.
|
||||
*/
|
||||
private List<CEnumConstant> buildCEnumConstants(XSRestrictionSimpleType type, boolean needsToGenerateMemberName, Map<String, BIEnumMember> members, XSFacet[] errorRef) {
|
||||
List<CEnumConstant> memberList = new ArrayList<CEnumConstant>();
|
||||
int idx=1;
|
||||
Set<String> enums = new HashSet<String>(); // to avoid duplicates. See issue #366
|
||||
|
||||
for( XSFacet facet : type.getDeclaredFacets(XSFacet.FACET_ENUMERATION)) {
|
||||
String name=null;
|
||||
String mdoc=builder.getBindInfo(facet).getDocumentation();
|
||||
|
||||
if(!enums.add(facet.getValue().value))
|
||||
continue; // ignore the 2nd occasion
|
||||
|
||||
if( needsToGenerateMemberName ) {
|
||||
// generate names for all member names.
|
||||
// this will even override names specified by the user. that's crazy.
|
||||
name = "VALUE_"+(idx++);
|
||||
} else {
|
||||
String facetValue = facet.getValue().value;
|
||||
BIEnumMember mem = members.get(facetValue);
|
||||
if( mem==null )
|
||||
// look at the one attached to the facet object
|
||||
mem = builder.getBindInfo(facet).get(BIEnumMember.class);
|
||||
|
||||
if (mem!=null) {
|
||||
name = mem.name;
|
||||
if (mdoc == null) {
|
||||
mdoc = mem.javadoc;
|
||||
}
|
||||
}
|
||||
|
||||
if(name==null) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for( int i=0; i<facetValue.length(); i++) {
|
||||
char ch = facetValue.charAt(i);
|
||||
if(Character.isJavaIdentifierPart(ch))
|
||||
sb.append(ch);
|
||||
else
|
||||
sb.append('_');
|
||||
}
|
||||
name = model.getNameConverter().toConstantName(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
if(!JJavaName.isJavaIdentifier(name)) {
|
||||
if(errorRef!=null) errorRef[0] = facet;
|
||||
return null; // unable to generate a name
|
||||
}
|
||||
|
||||
memberList.add(new CEnumConstant(name,mdoc,facet.getValue().value,facet,builder.getBindInfo(facet).toCustomizationList(),facet.getLocator()));
|
||||
}
|
||||
return memberList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns non-null if {@link CEnumConstant}s have name collisions among them.
|
||||
*
|
||||
* @return
|
||||
* if there's a collision, return two {@link CEnumConstant}s that collided.
|
||||
* otherwise return null.
|
||||
*/
|
||||
private CEnumConstant[] checkMemberNameCollision( List<CEnumConstant> memberList ) {
|
||||
Map<String,CEnumConstant> names = new HashMap<String,CEnumConstant>();
|
||||
for (CEnumConstant c : memberList) {
|
||||
CEnumConstant old = names.put(c.getName(),c);
|
||||
if(old!=null)
|
||||
// collision detected
|
||||
return new CEnumConstant[]{old,c};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private EnumMemberMode getEnumMemberMode() {
|
||||
return builder.getGlobalBinding().getEnumMemberMode();
|
||||
}
|
||||
|
||||
private TypeUse lookupBuiltin( String typeLocalName ) {
|
||||
if(typeLocalName.equals("integer") || typeLocalName.equals("long")) {
|
||||
/*
|
||||
attempt an optimization so that we can
|
||||
improve the binding for types like this:
|
||||
|
||||
<simpleType>
|
||||
<restriciton baseType="integer">
|
||||
<maxInclusive value="100" />
|
||||
</
|
||||
</
|
||||
|
||||
... to int, not BigInteger.
|
||||
*/
|
||||
|
||||
BigInteger xe = readFacet(XSFacet.FACET_MAXEXCLUSIVE,-1);
|
||||
BigInteger xi = readFacet(XSFacet.FACET_MAXINCLUSIVE,0);
|
||||
BigInteger max = min(xe,xi); // most restrictive one takes precedence
|
||||
|
||||
if(max!=null) {
|
||||
BigInteger ne = readFacet(XSFacet.FACET_MINEXCLUSIVE,+1);
|
||||
BigInteger ni = readFacet(XSFacet.FACET_MININCLUSIVE,0);
|
||||
BigInteger min = max(ne,ni);
|
||||
|
||||
if(min!=null) {
|
||||
if(min.compareTo(INT_MIN )>=0 && max.compareTo(INT_MAX )<=0)
|
||||
typeLocalName = "int";
|
||||
else
|
||||
if(min.compareTo(LONG_MIN)>=0 && max.compareTo(LONG_MAX)<=0)
|
||||
typeLocalName = "long";
|
||||
}
|
||||
}
|
||||
} else
|
||||
if(typeLocalName.equals("boolean") && isRestrictedTo0And1()) {
|
||||
// this is seen in the SOAP schema and too common to ignore
|
||||
return CBuiltinLeafInfo.BOOLEAN_ZERO_OR_ONE;
|
||||
} else
|
||||
if(typeLocalName.equals("base64Binary")) {
|
||||
return lookupBinaryTypeBinding();
|
||||
} else
|
||||
if(typeLocalName.equals("anySimpleType")) {
|
||||
if(getReferer() instanceof XSAttributeDecl || getReferer() instanceof XSSimpleType)
|
||||
return CBuiltinLeafInfo.STRING;
|
||||
else
|
||||
return CBuiltinLeafInfo.ANYTYPE;
|
||||
}
|
||||
return builtinConversions.get(typeLocalName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides the way xs:base64Binary binds.
|
||||
*
|
||||
* This method checks the expected media type.
|
||||
*/
|
||||
private TypeUse lookupBinaryTypeBinding() {
|
||||
XSComponent referer = getReferer();
|
||||
String emt = referer.getForeignAttribute(XML_MIME_URI, Const.EXPECTED_CONTENT_TYPES);
|
||||
if(emt!=null) {
|
||||
acknowledgedXmimeContentTypes.add(referer);
|
||||
try {
|
||||
// see http://www.xml.com/lpt/a/2004/07/21/dive.html
|
||||
List<MimeTypeRange> types = MimeTypeRange.parseRanges(emt);
|
||||
MimeTypeRange mt = MimeTypeRange.merge(types);
|
||||
|
||||
// see spec table I-1 in appendix I section 2.1.1 for bindings
|
||||
if(mt.majorType.equalsIgnoreCase("image"))
|
||||
return CBuiltinLeafInfo.IMAGE.makeMimeTyped(mt.toMimeType());
|
||||
|
||||
if(( mt.majorType.equalsIgnoreCase("application") || mt.majorType.equalsIgnoreCase("text"))
|
||||
&& isXml(mt.subType))
|
||||
return CBuiltinLeafInfo.XML_SOURCE.makeMimeTyped(mt.toMimeType());
|
||||
|
||||
if((mt.majorType.equalsIgnoreCase("text") && (mt.subType.equalsIgnoreCase("plain")) )) {
|
||||
return CBuiltinLeafInfo.STRING.makeMimeTyped(mt.toMimeType());
|
||||
}
|
||||
|
||||
return CBuiltinLeafInfo.DATA_HANDLER.makeMimeTyped(mt.toMimeType());
|
||||
} catch (ParseException e) {
|
||||
getErrorReporter().error( referer.getLocator(),
|
||||
Messages.format(Messages.ERR_ILLEGAL_EXPECTED_MIME_TYPE,emt, e.getMessage()) );
|
||||
// recover by using the default
|
||||
} catch (MimeTypeParseException e) {
|
||||
getErrorReporter().error( referer.getLocator(),
|
||||
Messages.format(Messages.ERR_ILLEGAL_EXPECTED_MIME_TYPE,emt, e.getMessage()) );
|
||||
}
|
||||
}
|
||||
// default
|
||||
return CBuiltinLeafInfo.BASE64_BYTE_ARRAY;
|
||||
}
|
||||
|
||||
public boolean isAcknowledgedXmimeContentTypes(XSComponent c) {
|
||||
return acknowledgedXmimeContentTypes.contains(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified sub-type is an XML type.
|
||||
*/
|
||||
private boolean isXml(String subType) {
|
||||
return subType.equals("xml") || subType.endsWith("+xml");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the {@link #initiatingType} is restricted
|
||||
* to '0' and '1'. This logic is not complete, but it at least
|
||||
* finds the such definition in SOAP @mustUnderstand.
|
||||
*/
|
||||
private boolean isRestrictedTo0And1() {
|
||||
XSFacet pattern = initiatingType.getFacet(XSFacet.FACET_PATTERN);
|
||||
if(pattern!=null) {
|
||||
String v = pattern.getValue().value;
|
||||
if(v.equals("0|1") || v.equals("1|0") || v.equals("\\d"))
|
||||
return true;
|
||||
}
|
||||
XSFacet enumf = initiatingType.getFacet(XSFacet.FACET_ENUMERATION);
|
||||
if(enumf!=null) {
|
||||
String v = enumf.getValue().value;
|
||||
if(v.equals("0") || v.equals("1"))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private BigInteger readFacet(String facetName,int offset) {
|
||||
XSFacet me = initiatingType.getFacet(facetName);
|
||||
if(me==null)
|
||||
return null;
|
||||
BigInteger bi = DatatypeConverter.parseInteger(me.getValue().value);
|
||||
if(offset!=0)
|
||||
bi = bi.add(BigInteger.valueOf(offset));
|
||||
return bi;
|
||||
}
|
||||
|
||||
private BigInteger min(BigInteger a, BigInteger b) {
|
||||
if(a==null) return b;
|
||||
if(b==null) return a;
|
||||
return a.min(b);
|
||||
}
|
||||
|
||||
private BigInteger max(BigInteger a, BigInteger b) {
|
||||
if(a==null) return b;
|
||||
if(b==null) return a;
|
||||
return a.max(b);
|
||||
}
|
||||
|
||||
private static final BigInteger LONG_MIN = BigInteger.valueOf(Long.MIN_VALUE);
|
||||
private static final BigInteger LONG_MAX = BigInteger.valueOf(Long.MAX_VALUE);
|
||||
private static final BigInteger INT_MIN = BigInteger.valueOf(Integer.MIN_VALUE);
|
||||
private static final BigInteger INT_MAX = BigInteger.valueOf(Integer.MAX_VALUE);
|
||||
|
||||
static {
|
||||
// list of datatypes which have built-in conversions.
|
||||
// note that although xs:token and xs:normalizedString are not
|
||||
// specified in the spec, they need to be here because they
|
||||
// have different whitespace normalization semantics.
|
||||
Map<String,TypeUse> m = builtinConversions;
|
||||
|
||||
// TODO: this is so dumb
|
||||
m.put("string", CBuiltinLeafInfo.STRING);
|
||||
m.put("anyURI", CBuiltinLeafInfo.STRING);
|
||||
m.put("boolean", CBuiltinLeafInfo.BOOLEAN);
|
||||
// we'll also look at the expected media type, so don't just add this to the map
|
||||
// m.put("base64Binary", CBuiltinLeafInfo.BASE64_BYTE_ARRAY);
|
||||
m.put("hexBinary", CBuiltinLeafInfo.HEXBIN_BYTE_ARRAY);
|
||||
m.put("float", CBuiltinLeafInfo.FLOAT);
|
||||
m.put("decimal", CBuiltinLeafInfo.BIG_DECIMAL);
|
||||
m.put("integer", CBuiltinLeafInfo.BIG_INTEGER);
|
||||
m.put("long", CBuiltinLeafInfo.LONG);
|
||||
m.put("unsignedInt", CBuiltinLeafInfo.LONG);
|
||||
m.put("int", CBuiltinLeafInfo.INT);
|
||||
m.put("unsignedShort", CBuiltinLeafInfo.INT);
|
||||
m.put("short", CBuiltinLeafInfo.SHORT);
|
||||
m.put("unsignedByte", CBuiltinLeafInfo.SHORT);
|
||||
m.put("byte", CBuiltinLeafInfo.BYTE);
|
||||
m.put("double", CBuiltinLeafInfo.DOUBLE);
|
||||
m.put("QName", CBuiltinLeafInfo.QNAME);
|
||||
m.put("NOTATION", CBuiltinLeafInfo.QNAME);
|
||||
m.put("dateTime", CBuiltinLeafInfo.CALENDAR);
|
||||
m.put("date", CBuiltinLeafInfo.CALENDAR);
|
||||
m.put("time", CBuiltinLeafInfo.CALENDAR);
|
||||
m.put("gYearMonth", CBuiltinLeafInfo.CALENDAR);
|
||||
m.put("gYear", CBuiltinLeafInfo.CALENDAR);
|
||||
m.put("gMonthDay", CBuiltinLeafInfo.CALENDAR);
|
||||
m.put("gDay", CBuiltinLeafInfo.CALENDAR);
|
||||
m.put("gMonth", CBuiltinLeafInfo.CALENDAR);
|
||||
m.put("duration", CBuiltinLeafInfo.DURATION);
|
||||
m.put("token", CBuiltinLeafInfo.TOKEN);
|
||||
m.put("normalizedString",CBuiltinLeafInfo.NORMALIZED_STRING);
|
||||
m.put("ID", CBuiltinLeafInfo.ID);
|
||||
m.put("IDREF", CBuiltinLeafInfo.IDREF);
|
||||
// TODO: handling dateTime, time, and date type
|
||||
// String[] names = {
|
||||
// "date", "dateTime", "time", "hexBinary" };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sun.tools.internal.xjc.reader.Const;
|
||||
import com.sun.tools.internal.xjc.reader.Ring;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIDeclaration;
|
||||
import com.sun.xml.internal.bind.v2.WellKnownNamespace;
|
||||
import com.sun.xml.internal.xsom.XSAnnotation;
|
||||
import com.sun.xml.internal.xsom.XSAttContainer;
|
||||
import com.sun.xml.internal.xsom.XSAttGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSAttributeDecl;
|
||||
import com.sun.xml.internal.xsom.XSAttributeUse;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSComponent;
|
||||
import com.sun.xml.internal.xsom.XSContentType;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
import com.sun.xml.internal.xsom.XSFacet;
|
||||
import com.sun.xml.internal.xsom.XSIdentityConstraint;
|
||||
import com.sun.xml.internal.xsom.XSListSimpleType;
|
||||
import com.sun.xml.internal.xsom.XSModelGroup;
|
||||
import com.sun.xml.internal.xsom.XSModelGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSNotation;
|
||||
import com.sun.xml.internal.xsom.XSParticle;
|
||||
import com.sun.xml.internal.xsom.XSRestrictionSimpleType;
|
||||
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.XSUnionSimpleType;
|
||||
import com.sun.xml.internal.xsom.XSWildcard;
|
||||
import com.sun.xml.internal.xsom.XSXPath;
|
||||
import com.sun.xml.internal.xsom.visitor.XSSimpleTypeVisitor;
|
||||
import com.sun.xml.internal.xsom.visitor.XSVisitor;
|
||||
|
||||
/**
|
||||
* Reports all unacknowledged customizations as errors.
|
||||
*
|
||||
* <p>
|
||||
* Since we scan the whole content tree, we use this to check for unused
|
||||
* <tt>xmime:expectedContentTypes</tt> attributes. TODO: if we find this kind of error checks more
|
||||
* common, use the visitors so that we don't have to mix everything in one class.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
class UnusedCustomizationChecker extends BindingComponent implements XSVisitor, XSSimpleTypeVisitor {
|
||||
private final BGMBuilder builder = Ring.get(BGMBuilder.class);
|
||||
private final SimpleTypeBuilder stb = Ring.get(SimpleTypeBuilder.class);
|
||||
|
||||
private final Set<XSComponent> visitedComponents = new HashSet<XSComponent>();
|
||||
|
||||
/**
|
||||
* Runs the check.
|
||||
*/
|
||||
void run() {
|
||||
for( XSSchema s : Ring.get(XSSchemaSet.class).getSchemas() ) {
|
||||
schema(s);
|
||||
run( s.getAttGroupDecls() );
|
||||
run( s.getAttributeDecls() );
|
||||
run( s.getComplexTypes() );
|
||||
run( s.getElementDecls() );
|
||||
run( s.getModelGroupDecls() );
|
||||
run( s.getNotations() );
|
||||
run( s.getSimpleTypes() );
|
||||
}
|
||||
}
|
||||
|
||||
private void run( Map<String,? extends XSComponent> col ) {
|
||||
for( XSComponent c : col.values() )
|
||||
c.visit(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks unused customizations on this component
|
||||
* and returns true if this is the first time this
|
||||
* component is checked.
|
||||
*/
|
||||
private boolean check( XSComponent c ) {
|
||||
if( !visitedComponents.add(c) )
|
||||
return false; // already processed
|
||||
|
||||
for( BIDeclaration decl : builder.getBindInfo(c).getDecls() )
|
||||
check(decl, c);
|
||||
|
||||
checkExpectedContentTypes(c);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void checkExpectedContentTypes(XSComponent c) {
|
||||
if(c.getForeignAttribute(WellKnownNamespace.XML_MIME_URI, Const.EXPECTED_CONTENT_TYPES)==null)
|
||||
return; // no such attribute
|
||||
if(c instanceof XSParticle)
|
||||
return; // particles get the same foreign attributes as local element decls,
|
||||
// so we need to skip them
|
||||
|
||||
if(!stb.isAcknowledgedXmimeContentTypes(c)) {
|
||||
// this is not used
|
||||
getErrorReporter().warning(c.getLocator(),Messages.WARN_UNUSED_EXPECTED_CONTENT_TYPES);
|
||||
}
|
||||
}
|
||||
|
||||
private void check(BIDeclaration decl, XSComponent c) {
|
||||
if( !decl.isAcknowledged() ) {
|
||||
getErrorReporter().error(
|
||||
decl.getLocation(),
|
||||
Messages.ERR_UNACKNOWLEDGED_CUSTOMIZATION,
|
||||
decl.getName().getLocalPart()
|
||||
);
|
||||
getErrorReporter().error(
|
||||
c.getLocator(),
|
||||
Messages.ERR_UNACKNOWLEDGED_CUSTOMIZATION_LOCATION);
|
||||
// mark it as acknowledged to avoid
|
||||
// duplicated error messages.
|
||||
decl.markAsAcknowledged();
|
||||
}
|
||||
for (BIDeclaration d : decl.getChildren())
|
||||
check(d,c);
|
||||
}
|
||||
|
||||
|
||||
public void annotation(XSAnnotation ann) {}
|
||||
|
||||
public void attGroupDecl(XSAttGroupDecl decl) {
|
||||
if(check(decl))
|
||||
attContainer(decl);
|
||||
}
|
||||
|
||||
public void attributeDecl(XSAttributeDecl decl) {
|
||||
if(check(decl))
|
||||
decl.getType().visit((XSSimpleTypeVisitor)this);
|
||||
}
|
||||
|
||||
public void attributeUse(XSAttributeUse use) {
|
||||
if(check(use))
|
||||
use.getDecl().visit(this);
|
||||
}
|
||||
|
||||
public void complexType(XSComplexType type) {
|
||||
if(check(type)) {
|
||||
// don't need to check the base type -- it must be global, thus
|
||||
// it is covered already
|
||||
type.getContentType().visit(this);
|
||||
attContainer(type);
|
||||
}
|
||||
}
|
||||
|
||||
private void attContainer( XSAttContainer cont ) {
|
||||
for( Iterator itr = cont.iterateAttGroups(); itr.hasNext(); )
|
||||
((XSAttGroupDecl)itr.next()).visit(this);
|
||||
|
||||
for( Iterator itr = cont.iterateDeclaredAttributeUses(); itr.hasNext(); )
|
||||
((XSAttributeUse)itr.next()).visit(this);
|
||||
|
||||
XSWildcard wc = cont.getAttributeWildcard();
|
||||
if(wc!=null) wc.visit(this);
|
||||
}
|
||||
|
||||
public void schema(XSSchema schema) {
|
||||
check(schema);
|
||||
}
|
||||
|
||||
public void facet(XSFacet facet) {
|
||||
check(facet);
|
||||
}
|
||||
|
||||
public void notation(XSNotation notation) {
|
||||
check(notation);
|
||||
}
|
||||
|
||||
public void wildcard(XSWildcard wc) {
|
||||
check(wc);
|
||||
}
|
||||
|
||||
public void modelGroupDecl(XSModelGroupDecl decl) {
|
||||
if(check(decl))
|
||||
decl.getModelGroup().visit(this);
|
||||
}
|
||||
|
||||
public void modelGroup(XSModelGroup group) {
|
||||
if(check(group)) {
|
||||
for( int i=0; i<group.getSize(); i++ )
|
||||
group.getChild(i).visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void elementDecl(XSElementDecl decl) {
|
||||
if(check(decl)) {
|
||||
decl.getType().visit(this);
|
||||
for( XSIdentityConstraint id : decl.getIdentityConstraints() )
|
||||
id.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void simpleType(XSSimpleType simpleType) {
|
||||
if(check(simpleType))
|
||||
simpleType.visit( (XSSimpleTypeVisitor)this );
|
||||
}
|
||||
|
||||
public void particle(XSParticle particle) {
|
||||
if(check(particle))
|
||||
particle.getTerm().visit(this);
|
||||
}
|
||||
|
||||
public void empty(XSContentType empty) {
|
||||
check(empty);
|
||||
}
|
||||
|
||||
public void listSimpleType(XSListSimpleType type) {
|
||||
if(check(type))
|
||||
type.getItemType().visit((XSSimpleTypeVisitor)this);
|
||||
}
|
||||
|
||||
public void restrictionSimpleType(XSRestrictionSimpleType type) {
|
||||
if(check(type))
|
||||
type.getBaseType().visit(this);
|
||||
}
|
||||
|
||||
public void unionSimpleType(XSUnionSimpleType type) {
|
||||
if(check(type)) {
|
||||
for( int i=0; i<type.getMemberSize(); i++ )
|
||||
type.getMember(i).visit((XSSimpleTypeVisitor)this);
|
||||
}
|
||||
}
|
||||
|
||||
public void identityConstraint(XSIdentityConstraint id) {
|
||||
if(check(id)) {
|
||||
id.getSelector().visit(this);
|
||||
for( XSXPath xp : id.getFields() )
|
||||
xp.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void xpath(XSXPath xp) {
|
||||
check(xp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.Iterator;
|
||||
|
||||
import com.sun.xml.internal.xsom.XSWildcard;
|
||||
import com.sun.xml.internal.xsom.visitor.XSWildcardFunction;
|
||||
|
||||
import com.sun.xml.internal.rngom.nc.AnyNameExceptNameClass;
|
||||
import com.sun.xml.internal.rngom.nc.ChoiceNameClass;
|
||||
import com.sun.xml.internal.rngom.nc.NameClass;
|
||||
import com.sun.xml.internal.rngom.nc.NsNameClass;
|
||||
|
||||
/**
|
||||
* Builds a name class representation of a wildcard.
|
||||
*
|
||||
* <p>
|
||||
* Singleton. Use the build method to create a NameClass.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public final class WildcardNameClassBuilder implements XSWildcardFunction<NameClass> {
|
||||
private WildcardNameClassBuilder() {}
|
||||
|
||||
private static final XSWildcardFunction<NameClass> theInstance =
|
||||
new WildcardNameClassBuilder();
|
||||
|
||||
public static NameClass build( XSWildcard wc ) {
|
||||
return wc.apply(theInstance);
|
||||
}
|
||||
|
||||
public NameClass any(XSWildcard.Any wc) {
|
||||
return NameClass.ANY;
|
||||
}
|
||||
|
||||
public NameClass other(XSWildcard.Other wc) {
|
||||
return new AnyNameExceptNameClass(
|
||||
new ChoiceNameClass(
|
||||
new NsNameClass(""),
|
||||
new NsNameClass(wc.getOtherNamespace())));
|
||||
}
|
||||
|
||||
public NameClass union(XSWildcard.Union wc) {
|
||||
NameClass nc = null;
|
||||
for (Iterator itr = wc.iterateNamespaces(); itr.hasNext();) {
|
||||
String ns = (String) itr.next();
|
||||
|
||||
if(nc==null) nc = new NsNameClass(ns);
|
||||
else
|
||||
nc = new ChoiceNameClass(nc,new NsNameClass(ns));
|
||||
}
|
||||
|
||||
// there should be at least one.
|
||||
assert nc!=null;
|
||||
|
||||
return nc;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import com.sun.codemodel.internal.JCodeModel;
|
||||
import com.sun.tools.internal.xjc.reader.Ring;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.BGMBuilder;
|
||||
import com.sun.xml.internal.bind.annotation.XmlLocation;
|
||||
import com.sun.xml.internal.xsom.XSComponent;
|
||||
|
||||
import org.xml.sax.Locator;
|
||||
|
||||
/**
|
||||
* Abstract partial implementation of {@link BIDeclaration}
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
abstract class AbstractDeclarationImpl implements BIDeclaration {
|
||||
|
||||
@Deprecated // eventually delete this in favor of using JAXB
|
||||
protected AbstractDeclarationImpl(Locator loc) {
|
||||
this.loc = loc;
|
||||
}
|
||||
|
||||
protected AbstractDeclarationImpl() {}
|
||||
|
||||
|
||||
@XmlLocation
|
||||
Locator loc; // set by JAXB
|
||||
public Locator getLocation() { return loc; }
|
||||
|
||||
protected BindInfo parent;
|
||||
public void setParent(BindInfo p) { this.parent=p; }
|
||||
|
||||
protected final XSComponent getOwner() {
|
||||
return parent.getOwner();
|
||||
}
|
||||
protected final BGMBuilder getBuilder() {
|
||||
return parent.getBuilder();
|
||||
}
|
||||
protected final JCodeModel getCodeModel() {
|
||||
return Ring.get(JCodeModel.class);
|
||||
}
|
||||
|
||||
|
||||
private boolean isAcknowledged = false;
|
||||
|
||||
public final boolean isAcknowledged() { return isAcknowledged; }
|
||||
|
||||
public void onSetOwner() {
|
||||
}
|
||||
|
||||
public Collection<BIDeclaration> getChildren() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public void markAsAcknowledged() {
|
||||
isAcknowledged = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.bind.UnmarshallerHandler;
|
||||
import javax.xml.bind.helpers.DefaultValidationEventHandler;
|
||||
import javax.xml.validation.ValidatorHandler;
|
||||
|
||||
import com.sun.tools.internal.xjc.Options;
|
||||
import com.sun.tools.internal.xjc.reader.Const;
|
||||
import com.sun.xml.internal.xsom.parser.AnnotationContext;
|
||||
import com.sun.xml.internal.xsom.parser.AnnotationParser;
|
||||
import com.sun.xml.internal.xsom.parser.AnnotationParserFactory;
|
||||
import com.sun.xml.internal.bind.v2.WellKnownNamespace;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.EntityResolver;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
import org.xml.sax.helpers.XMLFilterImpl;
|
||||
|
||||
/**
|
||||
* Implementation of XSOM {@link AnnotationParserFactory} that
|
||||
* parses JAXB customization declarations.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public class AnnotationParserFactoryImpl implements AnnotationParserFactory {
|
||||
public AnnotationParserFactoryImpl(Options opts) {
|
||||
this.options=opts;
|
||||
}
|
||||
|
||||
private final Options options;
|
||||
/**
|
||||
* Lazily created validator, so that the schema for binding won't be
|
||||
* prepared unless absolutely necessary.
|
||||
*/
|
||||
private ValidatorHandler validator;
|
||||
|
||||
public AnnotationParser create() {
|
||||
return new AnnotationParser() {
|
||||
private Unmarshaller u = BindInfo.getCustomizationUnmarshaller();
|
||||
|
||||
private UnmarshallerHandler handler;
|
||||
|
||||
public ContentHandler getContentHandler(
|
||||
AnnotationContext context, String parentElementName,
|
||||
final ErrorHandler errorHandler, EntityResolver entityResolver ) {
|
||||
|
||||
// return a ContentHandler that validates the customization and also
|
||||
// parses them into the internal structure.
|
||||
if(handler!=null)
|
||||
// interface contract violation.
|
||||
// this method will be called only once.
|
||||
throw new AssertionError();
|
||||
|
||||
if(options.debugMode)
|
||||
try {
|
||||
u.setEventHandler(new DefaultValidationEventHandler());
|
||||
} catch (JAXBException e) {
|
||||
throw new AssertionError(e); // ridiculous!
|
||||
}
|
||||
|
||||
handler = u.getUnmarshallerHandler();
|
||||
|
||||
// configure so that the validator will receive events for JAXB islands
|
||||
return new ForkingFilter(handler) {
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
|
||||
super.startElement(uri, localName, qName, atts);
|
||||
if((uri.equals(Const.JAXB_NSURI) || uri.equals(Const.XJC_EXTENSION_URI))
|
||||
&& getSideHandler()==null) {
|
||||
// set up validator
|
||||
if(validator==null)
|
||||
validator = BindInfo.bindingFileSchema.newValidator();
|
||||
validator.setErrorHandler(errorHandler);
|
||||
startForking(uri,localName,qName,atts,new ValidatorProtecter(validator));
|
||||
}
|
||||
|
||||
// check for xmime:expectedContentTypes attributes in annotations and report them
|
||||
for( int i=atts.getLength()-1; i>=0; i-- ) {
|
||||
if(atts.getURI(i).equals(WellKnownNamespace.XML_MIME_URI)
|
||||
&& atts.getLocalName(i).equals(Const.EXPECTED_CONTENT_TYPES))
|
||||
errorHandler.warning(new SAXParseException(
|
||||
com.sun.tools.internal.xjc.reader.xmlschema.Messages.format(
|
||||
com.sun.tools.internal.xjc.reader.xmlschema.Messages.WARN_UNUSED_EXPECTED_CONTENT_TYPES),
|
||||
getDocumentLocator()
|
||||
));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public BindInfo getResult( Object existing ) {
|
||||
if(handler==null)
|
||||
// interface contract violation.
|
||||
// the getContentHandler method must have been called.
|
||||
throw new AssertionError();
|
||||
|
||||
try {
|
||||
BindInfo result = (BindInfo)handler.getResult();
|
||||
|
||||
if(existing!=null) {
|
||||
BindInfo bie = (BindInfo)existing;
|
||||
bie.absorb(result);
|
||||
return bie;
|
||||
} else {
|
||||
if(!result.isPointless())
|
||||
return result; // just annotation. no meaningful customization
|
||||
else
|
||||
return null;
|
||||
}
|
||||
} catch (JAXBException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static final class ValidatorProtecter extends XMLFilterImpl {
|
||||
public ValidatorProtecter(ContentHandler h) {
|
||||
setContentHandler(h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startPrefixMapping(String prefix, String uri) throws SAXException {
|
||||
// work around a bug in the validator implementation in Tiger
|
||||
super.startPrefixMapping(prefix.intern(),uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import com.sun.tools.internal.xjc.reader.Const;
|
||||
import com.sun.xml.internal.bind.api.impl.NameConverter;
|
||||
import com.sun.istack.internal.Nullable;
|
||||
|
||||
/**
|
||||
* Class declaration.
|
||||
*
|
||||
* This customization turns arbitrary schema component into a Java
|
||||
* content interface.
|
||||
*
|
||||
* <p>
|
||||
* This customization is acknowledged by the ClassSelector.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
@XmlRootElement(name="class")
|
||||
public final class BIClass extends AbstractDeclarationImpl {
|
||||
protected BIClass() {
|
||||
}
|
||||
|
||||
@XmlAttribute(name="name")
|
||||
private String className;
|
||||
|
||||
/**
|
||||
* Gets the specified class name, or null if not specified.
|
||||
* (Not a fully qualified name.)
|
||||
*
|
||||
* @return
|
||||
* Returns a class name. The caller should <em>NOT</em>
|
||||
* apply XML-to-Java name conversion to the name
|
||||
* returned from this method.
|
||||
*/
|
||||
public @Nullable String getClassName() {
|
||||
if( className==null ) return null;
|
||||
|
||||
BIGlobalBinding gb = getBuilder().getGlobalBinding();
|
||||
NameConverter nc = getBuilder().model.getNameConverter();
|
||||
|
||||
if(gb.isJavaNamingConventionEnabled()) return nc.toClassName(className);
|
||||
else
|
||||
// don't change it
|
||||
return className;
|
||||
}
|
||||
|
||||
@XmlAttribute(name="implClass")
|
||||
private String userSpecifiedImplClass;
|
||||
|
||||
/**
|
||||
* Gets the fully qualified name of the
|
||||
* user-specified implementation class, if any.
|
||||
* Or null.
|
||||
*/
|
||||
public String getUserSpecifiedImplClass() {
|
||||
return userSpecifiedImplClass;
|
||||
}
|
||||
|
||||
@XmlAttribute(name="ref")
|
||||
private String ref;
|
||||
|
||||
@XmlAttribute(name="recursive", namespace=Const.XJC_EXTENSION_URI)
|
||||
private String recursive;
|
||||
|
||||
/**
|
||||
* Reference to the existing class, or null.
|
||||
* Fully qualified name.
|
||||
*
|
||||
* <p>
|
||||
* Caller needs to perform error check on this.
|
||||
*/
|
||||
public String getExistingClassRef() {
|
||||
return ref;
|
||||
}
|
||||
|
||||
public String getRecursive() {
|
||||
return recursive;
|
||||
}
|
||||
|
||||
@XmlElement
|
||||
private String javadoc;
|
||||
/**
|
||||
* Gets the javadoc comment specified in the customization.
|
||||
* Can be null if none is specified.
|
||||
*/
|
||||
public String getJavadoc() { return javadoc; }
|
||||
|
||||
public QName getName() { return NAME; }
|
||||
|
||||
public void setParent(BindInfo p) {
|
||||
super.setParent(p);
|
||||
// if this specifies a reference to external class,
|
||||
// then it's OK even if noone actually refers this class.
|
||||
if(ref!=null)
|
||||
markAsAcknowledged();
|
||||
}
|
||||
|
||||
/** Name of this declaration. */
|
||||
public static final QName NAME = new QName( Const.JAXB_NSURI, "class" );
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import com.sun.codemodel.internal.JClass;
|
||||
import com.sun.codemodel.internal.JClassAlreadyExistsException;
|
||||
import com.sun.codemodel.internal.JCodeModel;
|
||||
import com.sun.codemodel.internal.JDefinedClass;
|
||||
import com.sun.codemodel.internal.JExpr;
|
||||
import com.sun.codemodel.internal.JExpression;
|
||||
import com.sun.codemodel.internal.JMethod;
|
||||
import com.sun.codemodel.internal.JMod;
|
||||
import com.sun.codemodel.internal.JPackage;
|
||||
import com.sun.codemodel.internal.JType;
|
||||
import com.sun.codemodel.internal.JVar;
|
||||
import com.sun.codemodel.internal.JConditional;
|
||||
import com.sun.tools.internal.xjc.ErrorReceiver;
|
||||
import com.sun.tools.internal.xjc.model.CAdapter;
|
||||
import com.sun.tools.internal.xjc.model.CBuiltinLeafInfo;
|
||||
import com.sun.tools.internal.xjc.model.TypeUse;
|
||||
import com.sun.tools.internal.xjc.model.TypeUseFactory;
|
||||
import com.sun.tools.internal.xjc.reader.Const;
|
||||
import com.sun.tools.internal.xjc.reader.Ring;
|
||||
import com.sun.tools.internal.xjc.reader.TypeUtil;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.ClassSelector;
|
||||
import com.sun.xml.internal.bind.v2.WellKnownNamespace;
|
||||
import com.sun.xml.internal.xsom.XSSimpleType;
|
||||
|
||||
import org.xml.sax.Locator;
|
||||
|
||||
/**
|
||||
* Conversion declaration.
|
||||
*
|
||||
* <p>
|
||||
* A conversion declaration specifies how an XML type gets mapped
|
||||
* to a Java type.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public abstract class BIConversion extends AbstractDeclarationImpl {
|
||||
@Deprecated
|
||||
public BIConversion( Locator loc ) {
|
||||
super(loc);
|
||||
}
|
||||
|
||||
protected BIConversion() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link TypeUse} object that this conversion represents.
|
||||
* <p>
|
||||
* The returned {@link TypeUse} object is properly adapted.
|
||||
*
|
||||
* @param owner
|
||||
* A {@link BIConversion} is always associated with one
|
||||
* {@link XSSimpleType}, but that's not always available
|
||||
* when a {@link BIConversion} is built. So we pass this
|
||||
* as a parameter to this method.
|
||||
*/
|
||||
public abstract TypeUse getTypeUse( XSSimpleType owner );
|
||||
|
||||
public QName getName() { return NAME; }
|
||||
|
||||
/** Name of the conversion declaration. */
|
||||
public static final QName NAME = new QName(
|
||||
Const.JAXB_NSURI, "conversion" );
|
||||
|
||||
/**
|
||||
* Implementation that returns a statically-determined constant {@link TypeUse}.
|
||||
*/
|
||||
public static final class Static extends BIConversion {
|
||||
/**
|
||||
* Always non-null.
|
||||
*/
|
||||
private final TypeUse transducer;
|
||||
|
||||
public Static(Locator loc, TypeUse transducer) {
|
||||
super(loc);
|
||||
this.transducer = transducer;
|
||||
}
|
||||
|
||||
public TypeUse getTypeUse(XSSimpleType owner) {
|
||||
return transducer;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* User-specified <javaType> customization.
|
||||
*
|
||||
* The parse/print methods are allowed to be null,
|
||||
* and their default values are determined based on the
|
||||
* owner of the token.
|
||||
*/
|
||||
@XmlRootElement(name="javaType")
|
||||
public static class User extends BIConversion {
|
||||
@XmlAttribute
|
||||
private String parseMethod;
|
||||
@XmlAttribute
|
||||
private String printMethod;
|
||||
@XmlAttribute(name="name")
|
||||
private String type = "java.lang.String";
|
||||
|
||||
/**
|
||||
* If null, computed from {@link #type}.
|
||||
* Sometimes this can be set instead of {@link #type}.
|
||||
*/
|
||||
private JType inMemoryType;
|
||||
|
||||
public User(Locator loc, String parseMethod, String printMethod, JType inMemoryType) {
|
||||
super(loc);
|
||||
this.parseMethod = parseMethod;
|
||||
this.printMethod = printMethod;
|
||||
this.inMemoryType = inMemoryType;
|
||||
}
|
||||
|
||||
public User() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache used by {@link #getTypeUse(XSSimpleType)} to improve the performance.
|
||||
*/
|
||||
private TypeUse typeUse;
|
||||
|
||||
public TypeUse getTypeUse(XSSimpleType owner) {
|
||||
if(typeUse!=null)
|
||||
return typeUse;
|
||||
|
||||
JCodeModel cm = getCodeModel();
|
||||
|
||||
if(inMemoryType==null)
|
||||
inMemoryType = TypeUtil.getType(cm,type,Ring.get(ErrorReceiver.class),getLocation());
|
||||
|
||||
JDefinedClass adapter = generateAdapter(parseMethodFor(owner),printMethodFor(owner),owner);
|
||||
|
||||
// XmlJavaType customization always converts between string and an user-defined type.
|
||||
typeUse = TypeUseFactory.adapt(CBuiltinLeafInfo.STRING,new CAdapter(adapter));
|
||||
|
||||
return typeUse;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate the adapter class.
|
||||
*/
|
||||
private JDefinedClass generateAdapter(String parseMethod, String printMethod,XSSimpleType owner) {
|
||||
JDefinedClass adapter = null;
|
||||
|
||||
int id = 1;
|
||||
while(adapter==null) {
|
||||
try {
|
||||
JPackage pkg = Ring.get(ClassSelector.class).getClassScope().getOwnerPackage();
|
||||
adapter = pkg._class("Adapter"+id);
|
||||
} catch (JClassAlreadyExistsException e) {
|
||||
// try another name in search for an unique name.
|
||||
// this isn't too efficient, but we expect people to usually use
|
||||
// a very small number of adapters.
|
||||
id++;
|
||||
}
|
||||
}
|
||||
|
||||
JClass bim = inMemoryType.boxify();
|
||||
|
||||
adapter._extends(getCodeModel().ref(XmlAdapter.class).narrow(String.class).narrow(bim));
|
||||
|
||||
JMethod unmarshal = adapter.method(JMod.PUBLIC, bim, "unmarshal");
|
||||
JVar $value = unmarshal.param(String.class, "value");
|
||||
|
||||
JExpression inv;
|
||||
|
||||
if( parseMethod.equals("new") ) {
|
||||
// "new" indicates that the constructor of the target type
|
||||
// will do the unmarshalling.
|
||||
|
||||
// RESULT: new <type>()
|
||||
inv = JExpr._new(bim).arg($value);
|
||||
} else {
|
||||
int idx = parseMethod.lastIndexOf('.');
|
||||
if(idx<0) {
|
||||
// parseMethod specifies the static method of the target type
|
||||
// which will do the unmarshalling.
|
||||
|
||||
// because of an error check at the constructor,
|
||||
// we can safely assume that this cast works.
|
||||
inv = bim.staticInvoke(parseMethod).arg($value);
|
||||
} else {
|
||||
inv = JExpr.direct(parseMethod+"(value)");
|
||||
}
|
||||
}
|
||||
unmarshal.body()._return(inv);
|
||||
|
||||
|
||||
JMethod marshal = adapter.method(JMod.PUBLIC, String.class, "marshal");
|
||||
$value = marshal.param(bim,"value");
|
||||
|
||||
if(printMethod.startsWith("javax.xml.bind.DatatypeConverter.")) {
|
||||
// UGLY: if this conversion is the system-driven conversion,
|
||||
// check for null
|
||||
marshal.body()._if($value.eq(JExpr._null()))._then()._return(JExpr._null());
|
||||
}
|
||||
|
||||
int idx = printMethod.lastIndexOf('.');
|
||||
if(idx<0) {
|
||||
// printMethod specifies a method in the target type
|
||||
// which performs the serialization.
|
||||
|
||||
// RESULT: <value>.<method>()
|
||||
inv = $value.invoke(printMethod);
|
||||
|
||||
// check value is not null ... if(value == null) return null;
|
||||
JConditional jcon = marshal.body()._if($value.eq(JExpr._null()));
|
||||
jcon._then()._return(JExpr._null());
|
||||
} else {
|
||||
// RESULT: <className>.<method>(<value>)
|
||||
if(this.printMethod==null) {
|
||||
// HACK HACK HACK
|
||||
JType t = inMemoryType.unboxify();
|
||||
inv = JExpr.direct(printMethod+"(("+findBaseConversion(owner).toLowerCase()+")("+t.fullName()+")value)");
|
||||
} else
|
||||
inv = JExpr.direct(printMethod+"(value)");
|
||||
}
|
||||
marshal.body()._return(inv);
|
||||
|
||||
return adapter;
|
||||
}
|
||||
|
||||
private String printMethodFor(XSSimpleType owner) {
|
||||
if(printMethod!=null) return printMethod;
|
||||
|
||||
if(inMemoryType.unboxify().isPrimitive()) {
|
||||
String method = getConversionMethod("print",owner);
|
||||
if(method!=null)
|
||||
return method;
|
||||
}
|
||||
|
||||
return "toString";
|
||||
}
|
||||
|
||||
private String parseMethodFor(XSSimpleType owner) {
|
||||
if(parseMethod!=null) return parseMethod;
|
||||
|
||||
if(inMemoryType.unboxify().isPrimitive()) {
|
||||
String method = getConversionMethod("parse", owner);
|
||||
if(method!=null) {
|
||||
// this cast is necessary for conversion between primitive Java types
|
||||
return '('+inMemoryType.unboxify().fullName()+')'+method;
|
||||
}
|
||||
}
|
||||
|
||||
return "new";
|
||||
}
|
||||
|
||||
private static final String[] knownBases = new String[]{
|
||||
"Float", "Double", "Byte", "Short", "Int", "Long", "Boolean"
|
||||
};
|
||||
|
||||
private String getConversionMethod(String methodPrefix, XSSimpleType owner) {
|
||||
String bc = findBaseConversion(owner);
|
||||
if(bc==null) return null;
|
||||
|
||||
return DatatypeConverter.class.getName()+'.'+methodPrefix+bc;
|
||||
}
|
||||
|
||||
private String findBaseConversion(XSSimpleType owner) {
|
||||
// find the base simple type mapping.
|
||||
for( XSSimpleType st=owner; st!=null; st = st.getSimpleBaseType() ) {
|
||||
if( !WellKnownNamespace.XML_SCHEMA.equals(st.getTargetNamespace()) )
|
||||
continue; // user-defined type
|
||||
|
||||
String name = st.getName().intern();
|
||||
for( String s : knownBases )
|
||||
if(name.equalsIgnoreCase(s))
|
||||
return s;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public QName getName() { return NAME; }
|
||||
|
||||
/** Name of the conversion declaration. */
|
||||
public static final QName NAME = new QName(
|
||||
Const.JAXB_NSURI, "javaType" );
|
||||
}
|
||||
|
||||
@XmlRootElement(name="javaType",namespace=Const.XJC_EXTENSION_URI)
|
||||
public static class UserAdapter extends BIConversion {
|
||||
@XmlAttribute(name="name")
|
||||
private String type = null;
|
||||
|
||||
@XmlAttribute
|
||||
private String adapter = null;
|
||||
|
||||
private TypeUse typeUse;
|
||||
|
||||
public TypeUse getTypeUse(XSSimpleType owner) {
|
||||
if(typeUse!=null)
|
||||
return typeUse;
|
||||
|
||||
JCodeModel cm = getCodeModel();
|
||||
|
||||
JDefinedClass a;
|
||||
try {
|
||||
a = cm._class(adapter);
|
||||
a.hide(); // we assume this is given by the user
|
||||
a._extends(cm.ref(XmlAdapter.class).narrow(String.class).narrow(
|
||||
cm.ref(type)));
|
||||
} catch (JClassAlreadyExistsException e) {
|
||||
a = e.getExistingClass();
|
||||
}
|
||||
|
||||
// TODO: it's not correct to say that it adapts from String,
|
||||
// but OTOH I don't think we can compute that.
|
||||
typeUse = TypeUseFactory.adapt(
|
||||
CBuiltinLeafInfo.STRING,
|
||||
new CAdapter(a));
|
||||
|
||||
return typeUse;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.BGMBuilder;
|
||||
|
||||
import org.xml.sax.Locator;
|
||||
|
||||
/**
|
||||
* Base interface for all binding customization declarations.
|
||||
*
|
||||
* <p>
|
||||
* Because of the setParent method, one customization declaration
|
||||
* can be attached to one component alone.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public interface BIDeclaration {
|
||||
|
||||
/**
|
||||
* Sets the parent BindInfo object of this declaration.
|
||||
* A declaration object can use this pointer to access
|
||||
* context information, such as other customizations.
|
||||
*
|
||||
* <p>
|
||||
* This method can be only called from {@link BindInfo},
|
||||
* and only once. This is a good opportunity to do some
|
||||
* follow-up initialization after JAXB unmarshalling
|
||||
* populated {@link BIDeclaration}.
|
||||
*/
|
||||
void setParent( BindInfo parent );
|
||||
|
||||
/**
|
||||
* Gets the name of this binding declaration,
|
||||
* which is the same as the tag name of the binding element.
|
||||
*/
|
||||
QName getName();
|
||||
|
||||
/**
|
||||
* Gets the source location where this declaration was written.
|
||||
* For declarations that are generated by XJC itself,
|
||||
* this method returns null.
|
||||
*/
|
||||
Locator getLocation();
|
||||
|
||||
/**
|
||||
* Marks this declaration to be acknowledged -- either actually
|
||||
* used or the existence is admitted (for example when
|
||||
* a property customization is given at the point of definition.)
|
||||
*
|
||||
* <p>
|
||||
* Declarations that are not acknowledged will be considered
|
||||
* as an error.
|
||||
*/
|
||||
void markAsAcknowledged();
|
||||
|
||||
/**
|
||||
* Checks if this declaration was acknowledged.
|
||||
*/
|
||||
boolean isAcknowledged();
|
||||
|
||||
/**
|
||||
* Called when the parent {@link BindInfo} got its owner set.
|
||||
*
|
||||
* This is when declarations are connected to {@link BGMBuilder} and
|
||||
* its sibling components.
|
||||
*/
|
||||
void onSetOwner();
|
||||
|
||||
/**
|
||||
* Gets child {@link BIDeclaration}s if any.
|
||||
*
|
||||
* @return
|
||||
* can be empty but always non-null. read-only.
|
||||
*/
|
||||
Collection<BIDeclaration> getChildren();
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import com.sun.tools.internal.xjc.reader.Const;
|
||||
|
||||
/**
|
||||
* DOM customization.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
@XmlRootElement(name="dom")
|
||||
public class BIDom extends AbstractDeclarationImpl {
|
||||
|
||||
// unsupported yet
|
||||
@XmlAttribute
|
||||
String type;
|
||||
|
||||
public final QName getName() { return NAME; }
|
||||
|
||||
/** Name of the conversion declaration. */
|
||||
public static final QName NAME = new QName(Const.JAXB_NSURI,"dom");
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import com.sun.tools.internal.xjc.reader.Const;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.SimpleTypeBuilder;
|
||||
|
||||
/**
|
||||
* Enumeration customization.
|
||||
* <p>
|
||||
* This customization binds a simple type to a type-safe enum class.
|
||||
* The actual binding process takes place in {@link SimpleTypeBuilder}.
|
||||
*
|
||||
* <p>
|
||||
* This customization is acknowledged by {@link SimpleTypeBuilder}.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
@XmlRootElement(name="typesafeEnumClass")
|
||||
public final class BIEnum extends AbstractDeclarationImpl {
|
||||
|
||||
/**
|
||||
* If false, it means not to bind to a type-safe enum.
|
||||
*
|
||||
* this takes precedence over all the other properties of this class.
|
||||
*/
|
||||
@XmlAttribute(name="map")
|
||||
private boolean map = true;
|
||||
|
||||
/** Gets the specified class name, or null if not specified. */
|
||||
@XmlAttribute(name="name")
|
||||
public String className = null;
|
||||
|
||||
/**
|
||||
* @see BIClass#getExistingClassRef()
|
||||
*/
|
||||
@XmlAttribute(name="ref")
|
||||
public String ref;
|
||||
|
||||
/**
|
||||
* Gets the javadoc comment specified in the customization.
|
||||
* Can be null if none is specified.
|
||||
*/
|
||||
@XmlElement
|
||||
public final String javadoc = null;
|
||||
|
||||
public boolean isMapped() {
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the map that contains XML value->BIEnumMember pairs.
|
||||
* This table is built from <enumMember> customizations.
|
||||
*
|
||||
* Always return non-null.
|
||||
*/
|
||||
@XmlTransient
|
||||
public final Map<String,BIEnumMember> members = new HashMap<String,BIEnumMember>();
|
||||
|
||||
public QName getName() { return NAME; }
|
||||
|
||||
public void setParent(BindInfo p) {
|
||||
super.setParent(p);
|
||||
for( BIEnumMember mem : members.values() )
|
||||
mem.setParent(p);
|
||||
|
||||
// if this specifies a reference to external class,
|
||||
// then it's OK even if noone actually refers this class.
|
||||
if(ref!=null)
|
||||
markAsAcknowledged();
|
||||
}
|
||||
|
||||
/** Name of this declaration. */
|
||||
public static final QName NAME = new QName(
|
||||
Const.JAXB_NSURI, "enum" );
|
||||
|
||||
// setter method for JAXB runtime
|
||||
@XmlElement(name="typesafeEnumMember")
|
||||
private void setMembers(BIEnumMember2[] mems) {
|
||||
for (BIEnumMember2 e : mems)
|
||||
members.put(e.value,e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* {@link BIEnumMember} used inside {@link BIEnum} has additional 'value' attribute.
|
||||
*/
|
||||
static class BIEnumMember2 extends BIEnumMember {
|
||||
/**
|
||||
* The lexical representaion of the constant to which we are attaching.
|
||||
*/
|
||||
@XmlAttribute(required=true)
|
||||
String value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import com.sun.tools.internal.xjc.reader.Const;
|
||||
|
||||
/**
|
||||
* Enumeration member customization.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
@XmlRootElement(name="typesafeEnumMember")
|
||||
public class BIEnumMember extends AbstractDeclarationImpl {
|
||||
protected BIEnumMember() {
|
||||
name = null;
|
||||
javadoc = null;
|
||||
}
|
||||
|
||||
/** Gets the specified class name, or null if not specified. */
|
||||
// regardless of the BIGlobalBinding.isJavaNamingConventionEnabled flag,
|
||||
// we don't modify the constant name.
|
||||
@XmlAttribute
|
||||
public final String name;
|
||||
|
||||
/**
|
||||
* Gets the javadoc comment specified in the customization.
|
||||
* Can be null if none is specified.
|
||||
*/
|
||||
@XmlElement
|
||||
public final String javadoc;
|
||||
|
||||
public QName getName() { return NAME; }
|
||||
|
||||
/** Name of this declaration. */
|
||||
public static final QName NAME = new QName(
|
||||
Const.JAXB_NSURI, "typesafeEnumMember" );
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import com.sun.xml.internal.xsom.XSComponent;
|
||||
import com.sun.tools.internal.xjc.model.CPropertyInfo;
|
||||
import com.sun.tools.internal.xjc.reader.Ring;
|
||||
import com.sun.tools.internal.xjc.reader.Const;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.BGMBuilder;
|
||||
|
||||
/**
|
||||
* Controls the <tt>ObjectFactory</tt> method name.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@XmlRootElement(name="factoryMethod")
|
||||
public class BIFactoryMethod extends AbstractDeclarationImpl {
|
||||
@XmlAttribute
|
||||
public String name;
|
||||
|
||||
/**
|
||||
* If the given component has {@link BIInlineBinaryData} customization,
|
||||
* reflect that to the specified property.
|
||||
*/
|
||||
public static void handle(XSComponent source, CPropertyInfo prop) {
|
||||
BIInlineBinaryData inline = Ring.get(BGMBuilder.class).getBindInfo(source).get(BIInlineBinaryData.class);
|
||||
if(inline!=null) {
|
||||
prop.inlineBinaryData = true;
|
||||
inline.markAsAcknowledged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public final QName getName() { return NAME; }
|
||||
|
||||
/** Name of the declaration. */
|
||||
public static final QName NAME = new QName(Const.JAXB_NSURI,"factoryMethod");
|
||||
}
|
||||
@@ -0,0 +1,577 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlEnumValue;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import com.sun.codemodel.internal.ClassType;
|
||||
import com.sun.codemodel.internal.JClassAlreadyExistsException;
|
||||
import com.sun.codemodel.internal.JCodeModel;
|
||||
import com.sun.codemodel.internal.JDefinedClass;
|
||||
import com.sun.tools.internal.xjc.ErrorReceiver;
|
||||
import com.sun.tools.internal.xjc.generator.bean.ImplStructureStrategy;
|
||||
import static com.sun.tools.internal.xjc.generator.bean.ImplStructureStrategy.BEAN_ONLY;
|
||||
import com.sun.tools.internal.xjc.model.Model;
|
||||
import com.sun.tools.internal.xjc.reader.Const;
|
||||
import com.sun.tools.internal.xjc.reader.Ring;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.SimpleTypeBuilder;
|
||||
import com.sun.tools.internal.xjc.util.ReadOnlyAdapter;
|
||||
import com.sun.xml.internal.bind.api.impl.NameConverter;
|
||||
import com.sun.xml.internal.bind.v2.WellKnownNamespace;
|
||||
import com.sun.xml.internal.xsom.XSDeclaration;
|
||||
import com.sun.xml.internal.xsom.XSSchemaSet;
|
||||
import com.sun.xml.internal.xsom.XSSimpleType;
|
||||
|
||||
/**
|
||||
* Global binding customization. The code is highly temporary.
|
||||
*
|
||||
* <p>
|
||||
* One of the information contained in a global customization
|
||||
* is the default binding for properties. This object contains a
|
||||
* BIProperty object to keep this information.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
@XmlRootElement(name="globalBindings")
|
||||
public final class BIGlobalBinding extends AbstractDeclarationImpl {
|
||||
|
||||
|
||||
/**
|
||||
* Gets the name converter that will govern the XML->Java
|
||||
* name conversion process for this compilation.
|
||||
*
|
||||
* <p>
|
||||
* The "underscoreBinding" customization will determine
|
||||
* the exact object returned from this method. The rest of XJC
|
||||
* should just use the NameConverter interface.
|
||||
*
|
||||
* <p>
|
||||
* Always non-null.
|
||||
*/
|
||||
@XmlTransient
|
||||
public NameConverter nameConverter = NameConverter.standard;
|
||||
|
||||
// JAXB will use this property to set nameConverter
|
||||
@XmlAttribute
|
||||
void setUnderscoreBinding( UnderscoreBinding ub ) {
|
||||
nameConverter = ub.nc;
|
||||
}
|
||||
|
||||
UnderscoreBinding getUnderscoreBinding() {
|
||||
throw new IllegalStateException(); // no need for this
|
||||
}
|
||||
|
||||
public JDefinedClass getSuperClass() {
|
||||
if(superClass==null) return null;
|
||||
return superClass.getClazz(ClassType.CLASS);
|
||||
}
|
||||
|
||||
public JDefinedClass getSuperInterface() {
|
||||
if(superInterface==null) return null;
|
||||
return superInterface.getClazz(ClassType.INTERFACE);
|
||||
}
|
||||
|
||||
public BIProperty getDefaultProperty() {
|
||||
return defaultProperty;
|
||||
}
|
||||
|
||||
public boolean isJavaNamingConventionEnabled() {
|
||||
return isJavaNamingConventionEnabled;
|
||||
}
|
||||
|
||||
public BISerializable getSerializable() {
|
||||
return serializable;
|
||||
}
|
||||
|
||||
public boolean isGenerateElementClass() {
|
||||
return generateElementClass;
|
||||
}
|
||||
|
||||
public boolean isGenerateMixedExtensions() {
|
||||
return generateMixedExtensions;
|
||||
}
|
||||
|
||||
public boolean isChoiceContentPropertyEnabled() {
|
||||
return choiceContentProperty;
|
||||
}
|
||||
|
||||
public int getDefaultEnumMemberSizeCap() {
|
||||
return defaultEnumMemberSizeCap;
|
||||
}
|
||||
|
||||
public boolean isSimpleMode() {
|
||||
return simpleMode!=null;
|
||||
}
|
||||
|
||||
public boolean isRestrictionFreshType() {
|
||||
return treatRestrictionLikeNewType !=null;
|
||||
}
|
||||
|
||||
public EnumMemberMode getEnumMemberMode() {
|
||||
return generateEnumMemberName;
|
||||
}
|
||||
|
||||
public boolean isSimpleTypeSubstitution() {
|
||||
return simpleTypeSubstitution;
|
||||
}
|
||||
|
||||
public ImplStructureStrategy getCodeGenerationStrategy() {
|
||||
return codeGenerationStrategy;
|
||||
}
|
||||
|
||||
public LocalScoping getFlattenClasses() {
|
||||
return flattenClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs error check
|
||||
*/
|
||||
public void errorCheck() {
|
||||
ErrorReceiver er = Ring.get(ErrorReceiver.class);
|
||||
for (QName n : enumBaseTypes) {
|
||||
XSSchemaSet xs = Ring.get(XSSchemaSet.class);
|
||||
XSSimpleType st = xs.getSimpleType(n.getNamespaceURI(), n.getLocalPart());
|
||||
if(st==null) {
|
||||
er.error(loc,Messages.ERR_UNDEFINED_SIMPLE_TYPE.format(n));
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!SimpleTypeBuilder.canBeMappedToTypeSafeEnum(st)) {
|
||||
er.error(loc,Messages.ERR_CANNOT_BE_BOUND_TO_SIMPLETYPE.format(n));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static enum UnderscoreBinding {
|
||||
@XmlEnumValue("asWordSeparator")
|
||||
WORD_SEPARATOR(NameConverter.standard),
|
||||
@XmlEnumValue("asCharInWord")
|
||||
CHAR_IN_WORD(NameConverter.jaxrpcCompatible);
|
||||
|
||||
final NameConverter nc;
|
||||
|
||||
UnderscoreBinding(NameConverter nc) {
|
||||
this.nc = nc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the "isJavaNamingConventionEnabled" option is turned on.
|
||||
*
|
||||
* In this mode, the compiler is expected to apply XML-to-Java name
|
||||
* conversion algorithm even to names given by customizations.
|
||||
*
|
||||
* This method is intended to be called by other BIXXX classes.
|
||||
* The effect of this switch should be hidden inside this package.
|
||||
* IOW, the reader.xmlschema package shouldn't be aware of this switch.
|
||||
*/
|
||||
@XmlAttribute(name="enableJavaNamingConventions")
|
||||
/*package*/ boolean isJavaNamingConventionEnabled = true;
|
||||
|
||||
/**
|
||||
* True to generate classes for every simple type.
|
||||
*/
|
||||
@XmlAttribute(name="mapSimpleTypeDef")
|
||||
boolean simpleTypeSubstitution = false;
|
||||
|
||||
/**
|
||||
* Gets the default defaultProperty customization.
|
||||
*/
|
||||
@XmlTransient
|
||||
private BIProperty defaultProperty;
|
||||
|
||||
/*
|
||||
Three properties used to construct a default property
|
||||
*/
|
||||
@XmlAttribute
|
||||
private boolean fixedAttributeAsConstantProperty = false;
|
||||
@XmlAttribute
|
||||
private CollectionTypeAttribute collectionType = new CollectionTypeAttribute();
|
||||
@XmlAttribute
|
||||
void setGenerateIsSetMethod(boolean b) {
|
||||
optionalProperty = b ? OptionalPropertyMode.ISSET : OptionalPropertyMode.WRAPPER;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the compiler needs to generate type-safe enum
|
||||
* member names when enumeration values cannot be used as constant names.
|
||||
*/
|
||||
@XmlAttribute(name="typesafeEnumMemberName")
|
||||
EnumMemberMode generateEnumMemberName = EnumMemberMode.SKIP;
|
||||
|
||||
/**
|
||||
* The code generation strategy.
|
||||
*/
|
||||
@XmlAttribute(name="generateValueClass")
|
||||
ImplStructureStrategy codeGenerationStrategy = BEAN_ONLY;
|
||||
|
||||
/**
|
||||
* Set of datatype names. For a type-safe enum class
|
||||
* to be generated, the underlying XML datatype must be derived from
|
||||
* one of the types in this set.
|
||||
*/
|
||||
// default value is set in the post-init action
|
||||
@XmlAttribute(name="typesafeEnumBase")
|
||||
private Set<QName> enumBaseTypes;
|
||||
|
||||
/**
|
||||
* Returns {@link BISerializable} if the extension is specified,
|
||||
* or null otherwise.
|
||||
*/
|
||||
@XmlElement
|
||||
private BISerializable serializable = null;
|
||||
|
||||
/**
|
||||
* If <xjc:superClass> extension is specified,
|
||||
* returns the specified root class. Otherwise null.
|
||||
*/
|
||||
@XmlElement(namespace=Const.XJC_EXTENSION_URI)
|
||||
ClassNameBean superClass = null;
|
||||
|
||||
/**
|
||||
* If <xjc:superInterface> extension is specified,
|
||||
* returns the specified root class. Otherwise null.
|
||||
*/
|
||||
@XmlElement(namespace=Const.XJC_EXTENSION_URI)
|
||||
ClassNameBean superInterface = null;
|
||||
|
||||
/**
|
||||
* Generate the simpler optimized code, but not necessarily
|
||||
* conforming to the spec.
|
||||
*/
|
||||
@XmlElement(name="simple",namespace=Const.XJC_EXTENSION_URI)
|
||||
String simpleMode = null;
|
||||
|
||||
/**
|
||||
* Handles complex type restriction as if it were a new type.
|
||||
*/
|
||||
@XmlElement(name="treatRestrictionLikeNewType",namespace=Const.XJC_EXTENSION_URI)
|
||||
String treatRestrictionLikeNewType = null;
|
||||
|
||||
/**
|
||||
* True to generate a class for elements by default.
|
||||
*/
|
||||
@XmlAttribute
|
||||
boolean generateElementClass = false;
|
||||
|
||||
@XmlAttribute
|
||||
boolean generateMixedExtensions = false;
|
||||
|
||||
@XmlElement(namespace=Const.XJC_EXTENSION_URI)
|
||||
Boolean generateElementProperty = null;
|
||||
|
||||
@XmlAttribute(name="generateElementProperty") // for JAXB unmarshaller
|
||||
private void setGenerateElementPropertyStd(boolean value) {
|
||||
generateElementProperty = value;
|
||||
}
|
||||
|
||||
@XmlAttribute
|
||||
boolean choiceContentProperty = false;
|
||||
|
||||
@XmlAttribute
|
||||
OptionalPropertyMode optionalProperty = OptionalPropertyMode.WRAPPER;
|
||||
|
||||
/**
|
||||
* Default cap to the number of constants in the enum.
|
||||
* We won't attempt to produce a type-safe enum by default
|
||||
* if there are more enumeration facets than specified in this field.
|
||||
*/
|
||||
@XmlAttribute(name="typesafeEnumMaxMembers")
|
||||
int defaultEnumMemberSizeCap = 256;
|
||||
|
||||
/**
|
||||
* If true, interfaces/classes that are normally generated as a nested interface/class
|
||||
* will be generated into the package, allowing the generated classes to be flat.
|
||||
*
|
||||
* See <a href="http://monaco.sfbay/detail.jsf?cr=4969415">Bug 4969415</a> for the motivation.
|
||||
*/
|
||||
@XmlAttribute(name="localScoping")
|
||||
LocalScoping flattenClasses = LocalScoping.NESTED;
|
||||
|
||||
/**
|
||||
* Globally-defined conversion customizations.
|
||||
*
|
||||
* @see #setGlobalConversions
|
||||
*/
|
||||
@XmlTransient
|
||||
private final Map<QName,BIConversion> globalConversions = new HashMap<QName, BIConversion>();
|
||||
|
||||
// method for JAXB unmarshaller
|
||||
@XmlElement(name="javaType")
|
||||
private void setGlobalConversions(GlobalStandardConversion[] convs) {
|
||||
for (GlobalStandardConversion u : convs) {
|
||||
globalConversions.put(u.xmlType,u);
|
||||
}
|
||||
}
|
||||
|
||||
@XmlElement(name="javaType",namespace=Const.XJC_EXTENSION_URI)
|
||||
private void setGlobalConversions2(GlobalVendorConversion[] convs) {
|
||||
for (GlobalVendorConversion u : convs) {
|
||||
globalConversions.put(u.xmlType,u);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// these customizations were valid in 1.0, but in 2.0 we don't
|
||||
// use them. OTOH, we don't want to issue an error for them,
|
||||
// so we just define a mapping and ignore the value.
|
||||
//
|
||||
@XmlElement(namespace=Const.XJC_EXTENSION_URI)
|
||||
String noMarshaller = null;
|
||||
@XmlElement(namespace=Const.XJC_EXTENSION_URI)
|
||||
String noUnmarshaller = null;
|
||||
@XmlElement(namespace=Const.XJC_EXTENSION_URI)
|
||||
String noValidator = null;
|
||||
@XmlElement(namespace=Const.XJC_EXTENSION_URI)
|
||||
String noValidatingUnmarshaller = null;
|
||||
@XmlElement(namespace=Const.XJC_EXTENSION_URI)
|
||||
TypeSubstitutionElement typeSubstitution = null;
|
||||
|
||||
/**
|
||||
* Another 1.0 compatibility customization (but we accept it
|
||||
* and treat it as {@link #serializable})
|
||||
*/
|
||||
@XmlElement(name="serializable",namespace=Const.XJC_EXTENSION_URI)
|
||||
void setXjcSerializable(BISerializable s) {
|
||||
this.serializable = s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static final class TypeSubstitutionElement {
|
||||
@XmlAttribute
|
||||
String type;
|
||||
}
|
||||
|
||||
public void onSetOwner() {
|
||||
super.onSetOwner();
|
||||
// if one is given by options, use that
|
||||
NameConverter nc = Ring.get(Model.class).options.getNameConverter();
|
||||
if(nc!=null)
|
||||
nameConverter = nc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a bind info object with the default values
|
||||
*/
|
||||
public BIGlobalBinding() {
|
||||
}
|
||||
|
||||
public void setParent(BindInfo parent) {
|
||||
super.setParent(parent);
|
||||
// fill in the remaining default values
|
||||
if(enumBaseTypes==null)
|
||||
enumBaseTypes = Collections.singleton(new QName(WellKnownNamespace.XML_SCHEMA,"string"));
|
||||
|
||||
this.defaultProperty = new BIProperty(getLocation(),null,null,null,
|
||||
collectionType, fixedAttributeAsConstantProperty, optionalProperty, generateElementProperty );
|
||||
defaultProperty.setParent(parent); // don't forget to initialize the defaultProperty
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves global BIConversion to the right object.
|
||||
*/
|
||||
public void dispatchGlobalConversions( XSSchemaSet schema ) {
|
||||
// also set parent to the global conversions
|
||||
for( Map.Entry<QName,BIConversion> e : globalConversions.entrySet() ) {
|
||||
|
||||
QName name = e.getKey();
|
||||
BIConversion conv = e.getValue();
|
||||
|
||||
XSSimpleType st = schema.getSimpleType(name.getNamespaceURI(),name.getLocalPart());
|
||||
if(st==null) {
|
||||
Ring.get(ErrorReceiver.class).error(
|
||||
getLocation(),
|
||||
Messages.ERR_UNDEFINED_SIMPLE_TYPE.format(name)
|
||||
);
|
||||
continue; // abort
|
||||
}
|
||||
|
||||
getBuilder().getOrCreateBindInfo(st).addDecl(conv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the given XML Schema built-in type can be mapped to
|
||||
* a type-safe enum class.
|
||||
*
|
||||
* @param typeName
|
||||
*/
|
||||
public boolean canBeMappedToTypeSafeEnum( QName typeName ) {
|
||||
return enumBaseTypes.contains(typeName);
|
||||
}
|
||||
|
||||
public boolean canBeMappedToTypeSafeEnum( String nsUri, String localName ) {
|
||||
return canBeMappedToTypeSafeEnum(new QName(nsUri,localName));
|
||||
}
|
||||
|
||||
public boolean canBeMappedToTypeSafeEnum( XSDeclaration decl ) {
|
||||
return canBeMappedToTypeSafeEnum( decl.getTargetNamespace(), decl.getName() );
|
||||
}
|
||||
|
||||
|
||||
public QName getName() { return NAME; }
|
||||
public static final QName NAME = new QName(
|
||||
Const.JAXB_NSURI, "globalBindings" );
|
||||
|
||||
|
||||
/**
|
||||
* Used to unmarshal
|
||||
* <xmp>
|
||||
* <[element] name="className" />
|
||||
* </xmp>
|
||||
*/
|
||||
static final class ClassNameBean {
|
||||
@XmlAttribute(required=true)
|
||||
String name;
|
||||
|
||||
/**
|
||||
* Computed from {@link #name} on demand.
|
||||
*/
|
||||
@XmlTransient
|
||||
JDefinedClass clazz;
|
||||
|
||||
JDefinedClass getClazz(ClassType t) {
|
||||
if (clazz != null) return clazz;
|
||||
try {
|
||||
JCodeModel codeModel = Ring.get(JCodeModel.class);
|
||||
clazz = codeModel._class(name, t);
|
||||
clazz.hide();
|
||||
return clazz;
|
||||
} catch (JClassAlreadyExistsException e) {
|
||||
return e.getExistingClass();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static final class ClassNameAdapter extends ReadOnlyAdapter<ClassNameBean,String> {
|
||||
public String unmarshal(ClassNameBean bean) throws Exception {
|
||||
return bean.name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Global <jaxb:javaType>.
|
||||
*/
|
||||
static final class GlobalStandardConversion extends BIConversion.User {
|
||||
@XmlAttribute
|
||||
QName xmlType;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(obj instanceof GlobalStandardConversion) {
|
||||
return ((GlobalStandardConversion)obj).xmlType.equals(xmlType);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 73 * hash + (this.xmlType != null ? this.xmlType.hashCode() : 0);
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Global <xjc:javaType>.
|
||||
*/
|
||||
static final class GlobalVendorConversion extends BIConversion.UserAdapter {
|
||||
@XmlAttribute
|
||||
QName xmlType;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(obj instanceof GlobalVendorConversion) {
|
||||
return ((GlobalVendorConversion)obj).xmlType.equals(xmlType);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 73 * hash + (this.xmlType != null ? this.xmlType.hashCode() : 0);
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
/* don't want to override equals to avoid overriding hashcode for this complex object, too */
|
||||
public boolean isEqual(BIGlobalBinding b) {
|
||||
boolean equal =
|
||||
this.isJavaNamingConventionEnabled == b.isJavaNamingConventionEnabled &&
|
||||
this.simpleTypeSubstitution == b.simpleTypeSubstitution &&
|
||||
this.fixedAttributeAsConstantProperty == b.fixedAttributeAsConstantProperty &&
|
||||
this.generateEnumMemberName == b.generateEnumMemberName &&
|
||||
this.codeGenerationStrategy == b.codeGenerationStrategy &&
|
||||
this.serializable == b.serializable &&
|
||||
this.superClass == b.superClass &&
|
||||
this.superInterface == b.superInterface &&
|
||||
this.generateElementClass == b.generateElementClass &&
|
||||
this.generateMixedExtensions == b.generateMixedExtensions &&
|
||||
this.generateElementProperty == b.generateElementProperty &&
|
||||
this.choiceContentProperty == b.choiceContentProperty &&
|
||||
this.optionalProperty == b.optionalProperty &&
|
||||
this.defaultEnumMemberSizeCap == b.defaultEnumMemberSizeCap &&
|
||||
this.flattenClasses == b.flattenClasses;
|
||||
|
||||
if (!equal) return false;
|
||||
|
||||
return isEqual(this.nameConverter, b.nameConverter) &&
|
||||
isEqual(this.noMarshaller, b.noMarshaller) &&
|
||||
isEqual(this.noUnmarshaller, b.noUnmarshaller) &&
|
||||
isEqual(this.noValidator, b.noValidator) &&
|
||||
isEqual(this.noValidatingUnmarshaller, b.noValidatingUnmarshaller) &&
|
||||
isEqual(this.typeSubstitution, b.typeSubstitution) &&
|
||||
isEqual(this.simpleMode, b.simpleMode) &&
|
||||
isEqual(this.enumBaseTypes, b.enumBaseTypes) &&
|
||||
isEqual(this.treatRestrictionLikeNewType, b.treatRestrictionLikeNewType) &&
|
||||
isEqual(this.globalConversions, b.globalConversions);
|
||||
}
|
||||
|
||||
private boolean isEqual(Object a, Object b) {
|
||||
if (a != null) {
|
||||
return a.equals(b);
|
||||
}
|
||||
return (b == null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlInlineBinaryData;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import com.sun.tools.internal.xjc.reader.Const;
|
||||
import com.sun.tools.internal.xjc.reader.Ring;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.BGMBuilder;
|
||||
import com.sun.tools.internal.xjc.model.CPropertyInfo;
|
||||
import com.sun.xml.internal.xsom.XSComponent;
|
||||
|
||||
/**
|
||||
* Generates {@link @XmlInlineBinaryData}.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@XmlRootElement(name="inlineBinaryData")
|
||||
public class BIInlineBinaryData extends AbstractDeclarationImpl {
|
||||
|
||||
/**
|
||||
* If the given component has {@link BIInlineBinaryData} customization,
|
||||
* reflect that to the specified property.
|
||||
*/
|
||||
public static void handle(XSComponent source, CPropertyInfo prop) {
|
||||
BIInlineBinaryData inline = Ring.get(BGMBuilder.class).getBindInfo(source).get(BIInlineBinaryData.class);
|
||||
if(inline!=null) {
|
||||
prop.inlineBinaryData = true;
|
||||
inline.markAsAcknowledged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public final QName getName() { return NAME; }
|
||||
|
||||
/** Name of the declaration. */
|
||||
public static final QName NAME = new QName(Const.JAXB_NSURI,"inlineBinaryData");
|
||||
}
|
||||
@@ -0,0 +1,754 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlElementRef;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import com.sun.codemodel.internal.JJavaName;
|
||||
import com.sun.codemodel.internal.JType;
|
||||
import com.sun.tools.internal.xjc.ErrorReceiver;
|
||||
import com.sun.tools.internal.xjc.generator.bean.field.FieldRenderer;
|
||||
import com.sun.tools.internal.xjc.generator.bean.field.FieldRendererFactory;
|
||||
import com.sun.tools.internal.xjc.generator.bean.field.IsSetFieldRenderer;
|
||||
import com.sun.tools.internal.xjc.model.CAttributePropertyInfo;
|
||||
import com.sun.tools.internal.xjc.model.CCustomizations;
|
||||
import com.sun.tools.internal.xjc.model.CElementPropertyInfo;
|
||||
import com.sun.tools.internal.xjc.model.CPropertyInfo;
|
||||
import com.sun.tools.internal.xjc.model.CReferencePropertyInfo;
|
||||
import com.sun.tools.internal.xjc.model.CValuePropertyInfo;
|
||||
import com.sun.tools.internal.xjc.model.TypeUse;
|
||||
import com.sun.tools.internal.xjc.reader.Const;
|
||||
import com.sun.tools.internal.xjc.reader.RawTypeSet;
|
||||
import com.sun.tools.internal.xjc.reader.Ring;
|
||||
import com.sun.tools.internal.xjc.reader.TypeUtil;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.BGMBuilder;
|
||||
import com.sun.xml.internal.bind.api.impl.NameConverter;
|
||||
import com.sun.xml.internal.xsom.XSAnnotation;
|
||||
import com.sun.xml.internal.xsom.XSAttGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSAttributeDecl;
|
||||
import com.sun.xml.internal.xsom.XSAttributeUse;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSComponent;
|
||||
import com.sun.xml.internal.xsom.XSContentType;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
import com.sun.xml.internal.xsom.XSFacet;
|
||||
import com.sun.xml.internal.xsom.XSIdentityConstraint;
|
||||
import com.sun.xml.internal.xsom.XSModelGroup;
|
||||
import com.sun.xml.internal.xsom.XSModelGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSNotation;
|
||||
import com.sun.xml.internal.xsom.XSParticle;
|
||||
import com.sun.xml.internal.xsom.XSSchema;
|
||||
import com.sun.xml.internal.xsom.XSSimpleType;
|
||||
import com.sun.xml.internal.xsom.XSWildcard;
|
||||
import com.sun.xml.internal.xsom.XSXPath;
|
||||
import com.sun.xml.internal.xsom.util.XSFinder;
|
||||
import com.sun.xml.internal.xsom.visitor.XSFunction;
|
||||
|
||||
import org.xml.sax.Locator;
|
||||
|
||||
/**
|
||||
* Property customization.
|
||||
*
|
||||
* This customization turns an arbitrary schema component
|
||||
* into a Java property (some restrictions apply.)
|
||||
*
|
||||
* <p>
|
||||
* All the getter methods (such as <code>getBaseType</code> or
|
||||
* <code>getBindStyle</code>) honors the delegation chain of
|
||||
* property customization specified in the spec. Namely,
|
||||
* if two property customizations are attached to an attribute
|
||||
* use and an attribute decl, then anything unspecified in the
|
||||
* attribute use defaults to attribute decl.
|
||||
*
|
||||
* <p>
|
||||
* Property customizations are acknowledged
|
||||
* (1) when they are actually used, and
|
||||
* (2) when they are given at the component, which is mapped to a class.
|
||||
* (so-called "point of declaration" customization)
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
@XmlRootElement(name="property")
|
||||
public final class BIProperty extends AbstractDeclarationImpl {
|
||||
|
||||
// can be null
|
||||
@XmlAttribute
|
||||
private String name = null;
|
||||
|
||||
// can be null
|
||||
@XmlElement
|
||||
private String javadoc = null;
|
||||
|
||||
// can be null
|
||||
@XmlElement
|
||||
private BaseTypeBean baseType = null;
|
||||
|
||||
// TODO: report 'unsupported' error if this is true
|
||||
@XmlAttribute
|
||||
private boolean generateFailFastSetterMethod = false;
|
||||
|
||||
|
||||
|
||||
public BIProperty(Locator loc, String _propName, String _javadoc,
|
||||
BaseTypeBean _baseType, CollectionTypeAttribute collectionType, Boolean isConst,
|
||||
OptionalPropertyMode optionalProperty, Boolean genElemProp) {
|
||||
super(loc);
|
||||
|
||||
this.name = _propName;
|
||||
this.javadoc = _javadoc;
|
||||
this.baseType = _baseType;
|
||||
this.collectionType = collectionType;
|
||||
this.isConstantProperty = isConst;
|
||||
this.optionalProperty = optionalProperty;
|
||||
this.generateElementProperty = genElemProp;
|
||||
}
|
||||
|
||||
protected BIProperty() {}
|
||||
|
||||
@Override
|
||||
public Collection<BIDeclaration> getChildren() {
|
||||
BIConversion conv = getConv();
|
||||
if(conv==null)
|
||||
return super.getChildren();
|
||||
else
|
||||
return Collections.<BIDeclaration>singleton(conv);
|
||||
}
|
||||
|
||||
public void setParent( BindInfo parent ) {
|
||||
super.setParent(parent);
|
||||
if(baseType!=null && baseType.conv!=null)
|
||||
baseType.conv.setParent(parent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the customized property name.
|
||||
*
|
||||
* This method honors the "enableJavaNamingConvention" customization
|
||||
* and formats the property name accordingly if necessary.
|
||||
*
|
||||
* Thus the caller should <em>NOT</em> apply the XML-to-Java name
|
||||
* conversion algorithm to the value returned from this method.
|
||||
*
|
||||
* @param forConstant
|
||||
* If the property name is intended for a constant property name,
|
||||
* set to true. This will change the result
|
||||
*
|
||||
* @return
|
||||
* This method can return null if the customization doesn't
|
||||
* specify the name.
|
||||
*/
|
||||
public String getPropertyName( boolean forConstant ) {
|
||||
if(name!=null) {
|
||||
BIGlobalBinding gb = getBuilder().getGlobalBinding();
|
||||
NameConverter nc = getBuilder().model.getNameConverter();
|
||||
|
||||
if( gb.isJavaNamingConventionEnabled() && !forConstant )
|
||||
// apply XML->Java conversion
|
||||
return nc.toPropertyName(name);
|
||||
else
|
||||
return name; // ... or don't change the value
|
||||
}
|
||||
BIProperty next = getDefault();
|
||||
if(next!=null) return next.getPropertyName(forConstant);
|
||||
else return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the associated javadoc.
|
||||
*
|
||||
* @return
|
||||
* null if none is specfieid.
|
||||
*/
|
||||
public String getJavadoc() {
|
||||
return javadoc;
|
||||
}
|
||||
|
||||
// can be null
|
||||
public JType getBaseType() {
|
||||
if(baseType!=null && baseType.name!=null) {
|
||||
return TypeUtil.getType(getCodeModel(),
|
||||
baseType.name,
|
||||
Ring.get(ErrorReceiver.class),getLocation());
|
||||
}
|
||||
BIProperty next = getDefault();
|
||||
if(next!=null) return next.getBaseType();
|
||||
else return null;
|
||||
}
|
||||
|
||||
|
||||
// can be null
|
||||
@XmlAttribute
|
||||
private CollectionTypeAttribute collectionType = null;
|
||||
|
||||
/**
|
||||
* Gets the realization of this field.
|
||||
* @return Always return non-null.
|
||||
*/
|
||||
CollectionTypeAttribute getCollectionType() {
|
||||
if(collectionType!=null) return collectionType;
|
||||
return getDefault().getCollectionType();
|
||||
}
|
||||
|
||||
|
||||
@XmlAttribute
|
||||
private OptionalPropertyMode optionalProperty = null;
|
||||
|
||||
// virtual property for @generateIsSetMethod
|
||||
@XmlAttribute
|
||||
void setGenerateIsSetMethod(boolean b) {
|
||||
optionalProperty = b ? OptionalPropertyMode.ISSET : OptionalPropertyMode.WRAPPER;
|
||||
}
|
||||
|
||||
public OptionalPropertyMode getOptionalPropertyMode() {
|
||||
if(optionalProperty!=null) return optionalProperty;
|
||||
return getDefault().getOptionalPropertyMode();
|
||||
}
|
||||
|
||||
// null if delegated
|
||||
@XmlAttribute
|
||||
private Boolean generateElementProperty = null;
|
||||
/**
|
||||
* If true, the property will automatically be a reference property.
|
||||
* (Talk about confusing names!)
|
||||
*/
|
||||
private Boolean generateElementProperty() {
|
||||
if(generateElementProperty!=null) return generateElementProperty;
|
||||
BIProperty next = getDefault();
|
||||
if(next!=null) return next.generateElementProperty();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// true, false, or null (which means the value should be inherited.)
|
||||
@XmlAttribute(name="fixedAttributeAsConstantProperty")
|
||||
private Boolean isConstantProperty;
|
||||
/**
|
||||
* Gets the inherited value of the "fixedAttrToConstantProperty" customization.
|
||||
*
|
||||
* <p>
|
||||
* Note that returning true from this method doesn't necessarily mean
|
||||
* that a property needs to be mapped to a constant property.
|
||||
* It just means that it's mapped to a constant property
|
||||
* <b>if an attribute use carries a fixed value.</b>
|
||||
*
|
||||
* <p>
|
||||
* I don't like this semantics but that's what the spec implies.
|
||||
*/
|
||||
public boolean isConstantProperty() {
|
||||
if(isConstantProperty!=null) return isConstantProperty;
|
||||
|
||||
BIProperty next = getDefault();
|
||||
if(next!=null) return next.isConstantProperty();
|
||||
|
||||
// globalBinding always has true or false in this property,
|
||||
// so this can't happen
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
public CValuePropertyInfo createValueProperty(String defaultName,boolean forConstant,
|
||||
XSComponent source,TypeUse tu, QName typeName) {
|
||||
|
||||
markAsAcknowledged();
|
||||
constantPropertyErrorCheck();
|
||||
|
||||
String name = getPropertyName(forConstant);
|
||||
if(name==null) {
|
||||
name = defaultName;
|
||||
if(tu.isCollection() && getBuilder().getGlobalBinding().isSimpleMode())
|
||||
name = JJavaName.getPluralForm(name);
|
||||
}
|
||||
|
||||
CValuePropertyInfo prop = wrapUp(new CValuePropertyInfo(name, source, getCustomizations(source), source.getLocator(), tu, typeName), source);
|
||||
BIInlineBinaryData.handle(source, prop);
|
||||
return prop;
|
||||
}
|
||||
|
||||
public CAttributePropertyInfo createAttributeProperty( XSAttributeUse use, TypeUse tu ) {
|
||||
|
||||
boolean forConstant =
|
||||
getCustomization(use).isConstantProperty() &&
|
||||
use.getFixedValue()!=null;
|
||||
|
||||
String name = getPropertyName(forConstant);
|
||||
if(name==null) {
|
||||
NameConverter conv = getBuilder().getNameConverter();
|
||||
if(forConstant)
|
||||
name = conv.toConstantName(use.getDecl().getName());
|
||||
else
|
||||
name = conv.toPropertyName(use.getDecl().getName());
|
||||
if(tu.isCollection() && getBuilder().getGlobalBinding().isSimpleMode())
|
||||
name = JJavaName.getPluralForm(name);
|
||||
}
|
||||
|
||||
markAsAcknowledged();
|
||||
constantPropertyErrorCheck();
|
||||
|
||||
return wrapUp(new CAttributePropertyInfo(name,use,getCustomizations(use),use.getLocator(),
|
||||
BGMBuilder.getName(use.getDecl()), tu,
|
||||
BGMBuilder.getName(use.getDecl().getType()), use.isRequired() ),use);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param defaultName
|
||||
* If the name is not customized, this name will be used
|
||||
* as the default. Note that the name conversion <b>MUST</b>
|
||||
* be applied before this method is called if necessary.
|
||||
* @param source
|
||||
* Source schema component from which a field is built.
|
||||
*/
|
||||
public CElementPropertyInfo createElementProperty(String defaultName, boolean forConstant, XSParticle source,
|
||||
RawTypeSet types) {
|
||||
|
||||
if(!types.refs.isEmpty())
|
||||
// if this property is empty, don't acknowleedge the customization
|
||||
// this allows pointless property customization to be reported as an error
|
||||
markAsAcknowledged();
|
||||
constantPropertyErrorCheck();
|
||||
|
||||
String name = getPropertyName(forConstant);
|
||||
if(name==null)
|
||||
name = defaultName;
|
||||
|
||||
CElementPropertyInfo prop = wrapUp(
|
||||
new CElementPropertyInfo(
|
||||
name, types.getCollectionMode(),
|
||||
types.id(),
|
||||
types.getExpectedMimeType(),
|
||||
source, getCustomizations(source),
|
||||
source.getLocator(), types.isRequired()),
|
||||
source);
|
||||
|
||||
types.addTo(prop);
|
||||
|
||||
BIInlineBinaryData.handle(source.getTerm(), prop);
|
||||
return prop;
|
||||
}
|
||||
|
||||
public CReferencePropertyInfo createDummyExtendedMixedReferenceProperty(
|
||||
String defaultName, XSComponent source, RawTypeSet types) {
|
||||
return createReferenceProperty(
|
||||
defaultName,
|
||||
false,
|
||||
source,
|
||||
types,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true);
|
||||
}
|
||||
|
||||
public CReferencePropertyInfo createContentExtendedMixedReferenceProperty(
|
||||
String defaultName, XSComponent source, RawTypeSet types) {
|
||||
return createReferenceProperty(
|
||||
defaultName,
|
||||
false,
|
||||
source,
|
||||
types,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true);
|
||||
}
|
||||
|
||||
public CReferencePropertyInfo createReferenceProperty(
|
||||
String defaultName, boolean forConstant, XSComponent source,
|
||||
RawTypeSet types, boolean isMixed, boolean dummy, boolean content, boolean isMixedExtended) {
|
||||
|
||||
if (types == null) { // this is a special case where we need to generate content because potential subtypes would need to be able to override what's store inside
|
||||
content = true;
|
||||
} else {
|
||||
if(!types.refs.isEmpty())
|
||||
// if this property is empty, don't acknowleedge the customization
|
||||
// this allows pointless property customization to be reported as an error
|
||||
markAsAcknowledged();
|
||||
}
|
||||
constantPropertyErrorCheck();
|
||||
|
||||
String name = getPropertyName(forConstant);
|
||||
if(name==null)
|
||||
name = defaultName;
|
||||
|
||||
CReferencePropertyInfo prop = wrapUp(
|
||||
new CReferencePropertyInfo(
|
||||
name,
|
||||
(types == null) ? true : types.getCollectionMode().isRepeated()||isMixed,
|
||||
(types == null) ? false : types.isRequired(),
|
||||
isMixed,
|
||||
source,
|
||||
getCustomizations(source), source.getLocator(), dummy, content, isMixedExtended),
|
||||
source);
|
||||
if (types != null) {
|
||||
types.addTo(prop);
|
||||
}
|
||||
|
||||
BIInlineBinaryData.handle(source, prop);
|
||||
return prop;
|
||||
}
|
||||
|
||||
public CPropertyInfo createElementOrReferenceProperty(
|
||||
String defaultName, boolean forConstant, XSParticle source,
|
||||
RawTypeSet types) {
|
||||
|
||||
boolean generateRef;
|
||||
|
||||
switch(types.canBeTypeRefs) {
|
||||
case CAN_BE_TYPEREF:
|
||||
case SHOULD_BE_TYPEREF:
|
||||
// it's up to the use
|
||||
Boolean b = generateElementProperty();
|
||||
if(b==null) // follow XJC recommendation
|
||||
generateRef = types.canBeTypeRefs== RawTypeSet.Mode.CAN_BE_TYPEREF;
|
||||
else // use the value user gave us
|
||||
generateRef = b;
|
||||
break;
|
||||
case MUST_BE_REFERENCE:
|
||||
generateRef = true;
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
if(generateRef) {
|
||||
return createReferenceProperty(defaultName,forConstant,source,types, false, false, false, false);
|
||||
} else {
|
||||
return createElementProperty(defaultName,forConstant,source,types);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Common finalization of {@link CPropertyInfo} for the create***Property methods.
|
||||
*/
|
||||
private <T extends CPropertyInfo> T wrapUp(T prop, XSComponent source) {
|
||||
prop.javadoc = concat(javadoc,
|
||||
getBuilder().getBindInfo(source).getDocumentation());
|
||||
if(prop.javadoc==null)
|
||||
prop.javadoc="";
|
||||
|
||||
// decide the realization.
|
||||
FieldRenderer r;
|
||||
OptionalPropertyMode opm = getOptionalPropertyMode();
|
||||
if(prop.isCollection()) {
|
||||
CollectionTypeAttribute ct = getCollectionType();
|
||||
r = ct.get(getBuilder().model);
|
||||
} else {
|
||||
FieldRendererFactory frf = getBuilder().fieldRendererFactory;
|
||||
|
||||
if(prop.isOptionalPrimitive()) {
|
||||
// the property type can be primitive type if we are to ignore absence
|
||||
switch(opm) {
|
||||
case PRIMITIVE:
|
||||
r = frf.getRequiredUnboxed();
|
||||
break;
|
||||
case WRAPPER:
|
||||
// force the wrapper type
|
||||
r = frf.getSingle();
|
||||
break;
|
||||
case ISSET:
|
||||
r = frf.getSinglePrimitiveAccess();
|
||||
break;
|
||||
default:
|
||||
throw new Error();
|
||||
}
|
||||
} else {
|
||||
r = frf.getDefault();
|
||||
}
|
||||
}
|
||||
if(opm==OptionalPropertyMode.ISSET) {
|
||||
// only isSet is allowed on a collection. these 3 modes aren't really symmetric.
|
||||
|
||||
// if the property is a primitive type, we need an explicit unset because
|
||||
// we can't overload the meaning of set(null).
|
||||
// if it's a collection, we need to be able to unset it so that we can distinguish
|
||||
// null list and empty list.
|
||||
r = new IsSetFieldRenderer( r, prop.isOptionalPrimitive()||prop.isCollection(), true );
|
||||
}
|
||||
|
||||
prop.realization = r;
|
||||
|
||||
JType bt = getBaseType();
|
||||
if(bt!=null)
|
||||
prop.baseType = bt;
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
private CCustomizations getCustomizations( XSComponent src ) {
|
||||
return getBuilder().getBindInfo(src).toCustomizationList();
|
||||
}
|
||||
|
||||
private CCustomizations getCustomizations( XSComponent... src ) {
|
||||
CCustomizations c = null;
|
||||
for (XSComponent s : src) {
|
||||
CCustomizations r = getCustomizations(s);
|
||||
if(c==null) c = r;
|
||||
else c = CCustomizations.merge(c,r);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
private CCustomizations getCustomizations( XSAttributeUse src ) {
|
||||
// customizations for an attribute use should include those defined in the local attribute.
|
||||
// this is so that the schema like:
|
||||
//
|
||||
// <xs:attribute name="foo" type="xs:int">
|
||||
// <xs:annotation><xs:appinfo>
|
||||
// <hyperjaxb:... />
|
||||
//
|
||||
// would be picked up
|
||||
if(src.getDecl().isLocal())
|
||||
return getCustomizations(src,src.getDecl());
|
||||
else
|
||||
return getCustomizations((XSComponent)src);
|
||||
}
|
||||
|
||||
private CCustomizations getCustomizations( XSParticle src ) {
|
||||
// customizations for a particle should include those defined in the term unless it's global
|
||||
// this is so that the schema like:
|
||||
//
|
||||
// <xs:sequence>
|
||||
// <xs:element name="foo" type="xs:int">
|
||||
// <xs:annotation><xs:appinfo>
|
||||
// <hyperjaxb:... />
|
||||
//
|
||||
// would be picked up
|
||||
if(src.getTerm().isElementDecl()) {
|
||||
XSElementDecl xed = src.getTerm().asElementDecl();
|
||||
if(xed.isGlobal())
|
||||
return getCustomizations((XSComponent)src);
|
||||
}
|
||||
|
||||
return getCustomizations(src,src.getTerm());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void markAsAcknowledged() {
|
||||
if( isAcknowledged() ) return;
|
||||
|
||||
// mark the parent as well.
|
||||
super.markAsAcknowledged();
|
||||
|
||||
BIProperty def = getDefault();
|
||||
if(def!=null) def.markAsAcknowledged();
|
||||
}
|
||||
|
||||
private void constantPropertyErrorCheck() {
|
||||
if( isConstantProperty!=null && getOwner()!=null ) {
|
||||
// run additional check on the isCOnstantProperty value.
|
||||
// this value is not allowed if the schema component doesn't have
|
||||
// a fixed value constraint.
|
||||
//
|
||||
// the setParent method associates a customization with the rest of
|
||||
// XSOM object graph, so this is the earliest possible moment where
|
||||
// we can test this.
|
||||
|
||||
if( !hasFixedValue.find(getOwner()) ) {
|
||||
Ring.get(ErrorReceiver.class).error(
|
||||
getLocation(),
|
||||
Messages.ERR_ILLEGAL_FIXEDATTR.format()
|
||||
);
|
||||
// set this value to null to avoid the same error to be reported more than once.
|
||||
isConstantProperty = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function object that returns true if a component has
|
||||
* a fixed value constraint.
|
||||
*/
|
||||
private final XSFinder hasFixedValue = new XSFinder() {
|
||||
public Boolean attributeDecl(XSAttributeDecl decl) {
|
||||
return decl.getFixedValue()!=null;
|
||||
}
|
||||
|
||||
public Boolean attributeUse(XSAttributeUse use) {
|
||||
return use.getFixedValue()!=null;
|
||||
}
|
||||
|
||||
public Boolean schema(XSSchema s) {
|
||||
// we allow globalBindings to have isConstantProperty==true,
|
||||
// so this method returns true to allow this.
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Finds a BIProperty which this object should delegate to.
|
||||
*
|
||||
* @return
|
||||
* always return non-null for normal BIProperties.
|
||||
* If this object is contained in the BIGlobalBinding, then
|
||||
* this method returns null to indicate that there's no more default.
|
||||
*/
|
||||
protected BIProperty getDefault() {
|
||||
if(getOwner()==null) return null;
|
||||
BIProperty next = getDefault(getBuilder(),getOwner());
|
||||
if(next==this) return null; // global.
|
||||
else return next;
|
||||
}
|
||||
|
||||
private static BIProperty getDefault( BGMBuilder builder, XSComponent c ) {
|
||||
while(c!=null) {
|
||||
c = c.apply(defaultCustomizationFinder);
|
||||
if(c!=null) {
|
||||
BIProperty prop = builder.getBindInfo(c).get(BIProperty.class);
|
||||
if(prop!=null) return prop;
|
||||
}
|
||||
}
|
||||
|
||||
// default to the global one
|
||||
return builder.getGlobalBinding().getDefaultProperty();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds a property customization that describes how the given
|
||||
* component should be mapped to a property (if it's mapped to
|
||||
* a property at all.)
|
||||
*
|
||||
* <p>
|
||||
* Consider an attribute use that does NOT carry a property
|
||||
* customization. This schema component is nonetheless considered
|
||||
* to carry a (sort of) implicit property customization, whose values
|
||||
* are defaulted.
|
||||
*
|
||||
* <p>
|
||||
* This method can be think of the method that returns this implied
|
||||
* property customization.
|
||||
*
|
||||
* <p>
|
||||
* Note that this doesn't mean the given component needs to be
|
||||
* mapped to a property. But if it does map to a property, it needs
|
||||
* to follow this customization.
|
||||
*
|
||||
* I think this semantics is next to non-sense but I couldn't think
|
||||
* of any other way to follow the spec.
|
||||
*
|
||||
* @param c
|
||||
* A customization effective on this component will be returned.
|
||||
* Can be null just to get the global customization.
|
||||
* @return
|
||||
* Always return non-null valid object.
|
||||
*/
|
||||
public static BIProperty getCustomization( XSComponent c ) {
|
||||
BGMBuilder builder = Ring.get(BGMBuilder.class);
|
||||
|
||||
// look for a customization on this component
|
||||
if( c!=null ) {
|
||||
BIProperty prop = builder.getBindInfo(c).get(BIProperty.class);
|
||||
if(prop!=null) return prop;
|
||||
}
|
||||
|
||||
// if no such thing exists, defeault.
|
||||
return getDefault(builder,c);
|
||||
}
|
||||
|
||||
private final static XSFunction<XSComponent> defaultCustomizationFinder = new XSFunction<XSComponent>() {
|
||||
|
||||
public XSComponent attributeUse(XSAttributeUse use) {
|
||||
return use.getDecl(); // inherit from the declaration
|
||||
}
|
||||
|
||||
public XSComponent particle(XSParticle particle) {
|
||||
return particle.getTerm(); // inherit from the term
|
||||
}
|
||||
|
||||
public XSComponent schema(XSSchema schema) {
|
||||
// no more delegation
|
||||
return null;
|
||||
}
|
||||
|
||||
// delegates to the context schema object
|
||||
public XSComponent attributeDecl(XSAttributeDecl decl) { return decl.getOwnerSchema(); }
|
||||
public XSComponent wildcard(XSWildcard wc) { return wc.getOwnerSchema(); }
|
||||
public XSComponent modelGroupDecl(XSModelGroupDecl decl) { return decl.getOwnerSchema(); }
|
||||
public XSComponent modelGroup(XSModelGroup group) { return group.getOwnerSchema(); }
|
||||
public XSComponent elementDecl(XSElementDecl decl) { return decl.getOwnerSchema(); }
|
||||
public XSComponent complexType(XSComplexType type) { return type.getOwnerSchema(); }
|
||||
public XSComponent simpleType(XSSimpleType st) { return st.getOwnerSchema(); }
|
||||
|
||||
// property customizations are not allowed on these components.
|
||||
public XSComponent attGroupDecl(XSAttGroupDecl decl) { throw new IllegalStateException(); }
|
||||
public XSComponent empty(XSContentType empty) { throw new IllegalStateException(); }
|
||||
public XSComponent annotation(XSAnnotation xsAnnotation) { throw new IllegalStateException(); }
|
||||
public XSComponent facet(XSFacet xsFacet) { throw new IllegalStateException(); }
|
||||
public XSComponent notation(XSNotation xsNotation) { throw new IllegalStateException(); }
|
||||
public XSComponent identityConstraint(XSIdentityConstraint x) { throw new IllegalStateException(); }
|
||||
public XSComponent xpath(XSXPath xsxPath) { throw new IllegalStateException(); }
|
||||
};
|
||||
|
||||
|
||||
private static String concat( String s1, String s2 ) {
|
||||
if(s1==null) return s2;
|
||||
if(s2==null) return s1;
|
||||
return s1+"\n\n"+s2;
|
||||
}
|
||||
|
||||
public QName getName() { return NAME; }
|
||||
|
||||
/** Name of this declaration. */
|
||||
public static final QName NAME = new QName(
|
||||
Const.JAXB_NSURI, "property" );
|
||||
|
||||
public BIConversion getConv() {
|
||||
if(baseType!=null)
|
||||
return baseType.conv;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final class BaseTypeBean {
|
||||
/**
|
||||
* If there's a nested javaType customization, this field
|
||||
* will keep that customization. Otherwise null.
|
||||
*
|
||||
* This customization, if present, is used to customize
|
||||
* the simple type mapping at the point of reference.
|
||||
*/
|
||||
@XmlElementRef
|
||||
BIConversion conv;
|
||||
|
||||
/**
|
||||
* Java type name.
|
||||
*/
|
||||
@XmlAttribute
|
||||
String name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import com.sun.tools.internal.xjc.reader.Const;
|
||||
import com.sun.xml.internal.xsom.XSAttributeDecl;
|
||||
import com.sun.xml.internal.xsom.XSComponent;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
import com.sun.xml.internal.xsom.XSModelGroup;
|
||||
import com.sun.xml.internal.xsom.XSModelGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSType;
|
||||
|
||||
/**
|
||||
* Schema-wide binding customization.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
@XmlRootElement(name="schemaBindings")
|
||||
public final class BISchemaBinding extends AbstractDeclarationImpl {
|
||||
|
||||
/**
|
||||
* Name conversion rules. All defaults to {@link BISchemaBinding#defaultNamingRule}.
|
||||
*/
|
||||
@XmlType(propOrder={})
|
||||
private static final class NameRules {
|
||||
@XmlElement
|
||||
NamingRule typeName = defaultNamingRule;
|
||||
@XmlElement
|
||||
NamingRule elementName = defaultNamingRule;
|
||||
@XmlElement
|
||||
NamingRule attributeName = defaultNamingRule;
|
||||
@XmlElement
|
||||
NamingRule modelGroupName = defaultNamingRule;
|
||||
@XmlElement
|
||||
NamingRule anonymousTypeName = defaultNamingRule;
|
||||
}
|
||||
|
||||
@XmlElement
|
||||
private NameRules nameXmlTransform = new NameRules();
|
||||
|
||||
private static final class PackageInfo {
|
||||
@XmlAttribute
|
||||
String name;
|
||||
@XmlElement
|
||||
String javadoc;
|
||||
}
|
||||
|
||||
@XmlElement(name="package")
|
||||
private PackageInfo packageInfo = new PackageInfo();
|
||||
|
||||
/**
|
||||
* If false, it means not to generate any classes from this namespace.
|
||||
* No ObjectFactory, no classes (the only way to bind them is by using
|
||||
* <jaxb:class ref="..."/>)
|
||||
*/
|
||||
@XmlAttribute(name="map")
|
||||
public boolean map = true;
|
||||
|
||||
/**
|
||||
* Default naming rule, that doesn't change the name.
|
||||
*/
|
||||
private static final NamingRule defaultNamingRule = new NamingRule("","");
|
||||
|
||||
|
||||
/**
|
||||
* Default naming rules of the generated interfaces.
|
||||
*
|
||||
* It simply adds prefix and suffix to the name, but
|
||||
* the caller shouldn't care how the name mangling is
|
||||
* done.
|
||||
*/
|
||||
public static final class NamingRule {
|
||||
@XmlAttribute
|
||||
private String prefix = "";
|
||||
@XmlAttribute
|
||||
private String suffix = "";
|
||||
|
||||
public NamingRule( String _prefix, String _suffix ) {
|
||||
this.prefix = _prefix;
|
||||
this.suffix = _suffix;
|
||||
}
|
||||
|
||||
public NamingRule() {
|
||||
}
|
||||
|
||||
/** Changes the name according to the rule. */
|
||||
public String mangle( String originalName ) {
|
||||
return prefix+originalName+suffix;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the default name produced from XML name
|
||||
* by following the customization.
|
||||
*
|
||||
* This shouldn't be applied to a class name specified
|
||||
* by a customization.
|
||||
*
|
||||
* @param cmp
|
||||
* The schema component from which the default name is derived.
|
||||
*/
|
||||
public String mangleClassName( String name, XSComponent cmp ) {
|
||||
if( cmp instanceof XSType )
|
||||
return nameXmlTransform.typeName.mangle(name);
|
||||
if( cmp instanceof XSElementDecl )
|
||||
return nameXmlTransform.elementName.mangle(name);
|
||||
if( cmp instanceof XSAttributeDecl )
|
||||
return nameXmlTransform.attributeName.mangle(name);
|
||||
if( cmp instanceof XSModelGroup || cmp instanceof XSModelGroupDecl )
|
||||
return nameXmlTransform.modelGroupName.mangle(name);
|
||||
|
||||
// otherwise no modification
|
||||
return name;
|
||||
}
|
||||
|
||||
public String mangleAnonymousTypeClassName( String name ) {
|
||||
return nameXmlTransform.anonymousTypeName.mangle(name);
|
||||
}
|
||||
|
||||
|
||||
public String getPackageName() { return packageInfo.name; }
|
||||
|
||||
public String getJavadoc() { return packageInfo.javadoc; }
|
||||
|
||||
public QName getName() { return NAME; }
|
||||
public static final QName NAME = new QName(
|
||||
Const.JAXB_NSURI, "schemaBinding" );
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
|
||||
|
||||
/**
|
||||
* This customization will enable serialization support on XJC.
|
||||
* This is used as a child of a {@link BIGlobalBinding} object,
|
||||
* and this doesn't implement BIDeclaration by itself.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public final class BISerializable {
|
||||
|
||||
/** serial version UID, or null to avoid generating the serialVersionUID field. */
|
||||
@XmlAttribute
|
||||
public Long uid;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.sun.tools.internal.xjc.reader.Const;
|
||||
|
||||
/**
|
||||
* Compatibility with 1.0.
|
||||
*
|
||||
* Read <xjc:dom> as <jaxb:dom>.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@XmlRootElement(name="dom",namespace=Const.XJC_EXTENSION_URI)
|
||||
public class BIXDom extends BIDom {
|
||||
|
||||
// unsupported yet
|
||||
@XmlAttribute
|
||||
String type = "w3c";
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import com.sun.tools.internal.xjc.Plugin;
|
||||
import com.sun.tools.internal.xjc.model.Model;
|
||||
import com.sun.tools.internal.xjc.reader.Ring;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
import org.xml.sax.Locator;
|
||||
|
||||
/**
|
||||
* Customization specified via {@link Plugin#getCustomizationURIs()}.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public final class BIXPluginCustomization extends AbstractDeclarationImpl {
|
||||
|
||||
/**
|
||||
* Customization element.
|
||||
*/
|
||||
public final Element element;
|
||||
|
||||
private QName name;
|
||||
|
||||
public BIXPluginCustomization(Element e, Locator _loc) {
|
||||
super(_loc);
|
||||
element = e;
|
||||
}
|
||||
|
||||
public void onSetOwner() {
|
||||
super.onSetOwner();
|
||||
if(!Ring.get(Model.class).options.pluginURIs.contains(element.getNamespaceURI()))
|
||||
markAsAcknowledged();
|
||||
}
|
||||
|
||||
public final QName getName() {
|
||||
if(name==null)
|
||||
name = new QName(element.getNamespaceURI(),element.getLocalName());
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import com.sun.tools.internal.xjc.reader.Const;
|
||||
|
||||
/**
|
||||
* Forces a non-collapsing behavior to allow extension schemas
|
||||
* to perform element substitutions.
|
||||
*
|
||||
* See https://jaxb.dev.java.net/issues/show_bug.cgi?id=289
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @since 2.1.1
|
||||
*/
|
||||
@XmlRootElement(name="substitutable",namespace= Const.XJC_EXTENSION_URI)
|
||||
public final class BIXSubstitutable extends AbstractDeclarationImpl {
|
||||
public final QName getName() { return NAME; }
|
||||
|
||||
/** Name of the conversion declaration. */
|
||||
public static final QName NAME = new QName(Const.XJC_EXTENSION_URI,"substitutable");
|
||||
}
|
||||
@@ -0,0 +1,357 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import java.io.FilterWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.bind.annotation.XmlAnyElement;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlMixed;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
|
||||
import com.sun.codemodel.internal.JDocComment;
|
||||
import com.sun.xml.internal.bind.v2.WellKnownNamespace;
|
||||
import com.sun.tools.internal.xjc.SchemaCache;
|
||||
import com.sun.tools.internal.xjc.model.CCustomizations;
|
||||
import com.sun.tools.internal.xjc.model.CPluginCustomization;
|
||||
import com.sun.tools.internal.xjc.model.Model;
|
||||
import com.sun.tools.internal.xjc.reader.Ring;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.BGMBuilder;
|
||||
import com.sun.xml.internal.bind.annotation.XmlLocation;
|
||||
import com.sun.xml.internal.bind.marshaller.MinimumEscapeHandler;
|
||||
import com.sun.xml.internal.xsom.XSComponent;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
import org.xml.sax.Locator;
|
||||
|
||||
/**
|
||||
* Container for customization declarations.
|
||||
*
|
||||
* We use JAXB ourselves and parse this object from "xs:annotation".
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke,kawaguchi@sun.com)
|
||||
*/
|
||||
@XmlRootElement(namespace= WellKnownNamespace.XML_SCHEMA,name="annotation")
|
||||
@XmlType(namespace=WellKnownNamespace.XML_SCHEMA,name="foobar")
|
||||
public final class BindInfo implements Iterable<BIDeclaration> {
|
||||
|
||||
private BGMBuilder builder;
|
||||
|
||||
@XmlLocation
|
||||
private Locator location;
|
||||
|
||||
/**
|
||||
* Documentation taken from <xs:documentation>s.
|
||||
*/
|
||||
@XmlElement(namespace=WellKnownNamespace.XML_SCHEMA)
|
||||
private Documentation documentation;
|
||||
|
||||
/**
|
||||
* Returns true if this {@link BindInfo} doesn't contain any useful
|
||||
* information.
|
||||
*
|
||||
* This flag is used to discard unused {@link BindInfo}s early to save memory footprint.
|
||||
*/
|
||||
public boolean isPointless() {
|
||||
if(size()>0) return false;
|
||||
if(documentation!=null && !documentation.contents.isEmpty())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static final class Documentation {
|
||||
@XmlAnyElement
|
||||
@XmlMixed
|
||||
List<Object> contents = new ArrayList<Object>();
|
||||
|
||||
void addAll(Documentation rhs) {
|
||||
if(rhs==null) return;
|
||||
|
||||
if(contents==null)
|
||||
contents = new ArrayList<Object>();
|
||||
if(!contents.isEmpty())
|
||||
contents.add("\n\n");
|
||||
contents.addAll(rhs.contents);
|
||||
}
|
||||
}
|
||||
|
||||
/** list of individual declarations. */
|
||||
private final List<BIDeclaration> decls = new ArrayList<BIDeclaration>();
|
||||
|
||||
private static final class AppInfo {
|
||||
/**
|
||||
* Receives {@link BIDeclaration}s and other DOMs.
|
||||
*/
|
||||
@XmlAnyElement(lax=true,value=DomHandlerEx.class)
|
||||
List<Object> contents = new ArrayList<Object>();
|
||||
|
||||
public void addTo(BindInfo bi) {
|
||||
if(contents==null) return;
|
||||
|
||||
for (Object o : contents) {
|
||||
if(o instanceof BIDeclaration)
|
||||
bi.addDecl((BIDeclaration)o);
|
||||
// this is really PITA! I can't get the source location
|
||||
if(o instanceof DomHandlerEx.DomAndLocation) {
|
||||
DomHandlerEx.DomAndLocation e = (DomHandlerEx.DomAndLocation)o;
|
||||
String nsUri = e.element.getNamespaceURI();
|
||||
if(nsUri==null || nsUri.equals("")
|
||||
|| nsUri.equals(WellKnownNamespace.XML_SCHEMA))
|
||||
continue; // this is definitely not a customization
|
||||
bi.addDecl(new BIXPluginCustomization(e.element,e.loc));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// only used by JAXB
|
||||
@XmlElement(namespace=WellKnownNamespace.XML_SCHEMA)
|
||||
void setAppinfo(AppInfo aib) {
|
||||
aib.addTo(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Gets the location of this annotation in the source file.
|
||||
*
|
||||
* @return
|
||||
* If the declarations are in fact specified in the source
|
||||
* code, a non-null valid object will be returned.
|
||||
* If this BindInfo is generated internally by XJC, then
|
||||
* null will be returned.
|
||||
*/
|
||||
public Locator getSourceLocation() { return location; }
|
||||
|
||||
|
||||
private XSComponent owner;
|
||||
/**
|
||||
* Sets the owner schema component and a reference to BGMBuilder.
|
||||
* This method is called from the BGMBuilder before
|
||||
* any BIDeclaration inside it is used.
|
||||
*/
|
||||
public void setOwner( BGMBuilder _builder, XSComponent _owner ) {
|
||||
this.owner = _owner;
|
||||
this.builder = _builder;
|
||||
for (BIDeclaration d : decls)
|
||||
d.onSetOwner();
|
||||
}
|
||||
public XSComponent getOwner() { return owner; }
|
||||
|
||||
/**
|
||||
* Back pointer to the BGMBuilder which is building
|
||||
* a BGM from schema components including this customization.
|
||||
*/
|
||||
public BGMBuilder getBuilder() { return builder; }
|
||||
|
||||
/** Adds a new declaration. */
|
||||
public void addDecl( BIDeclaration decl ) {
|
||||
if(decl==null) throw new IllegalArgumentException();
|
||||
decl.setParent(this);
|
||||
decls.add(decl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first declaration with a given name, or null
|
||||
* if none is found.
|
||||
*/
|
||||
public <T extends BIDeclaration>
|
||||
T get( Class<T> kind ) {
|
||||
for( BIDeclaration decl : decls ) {
|
||||
if( kind.isInstance(decl) )
|
||||
return kind.cast(decl);
|
||||
}
|
||||
return null; // not found
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the declarations
|
||||
*/
|
||||
public BIDeclaration[] getDecls() {
|
||||
return decls.toArray(new BIDeclaration[decls.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the documentation parsed from <xs:documentation>s.
|
||||
* The returned collection is to be added to {@link JDocComment#append(Object)}.
|
||||
* @return maybe null.
|
||||
*/
|
||||
public String getDocumentation() {
|
||||
// TODO: FIXME: correctly turn individual items to String including DOM
|
||||
if(documentation==null || documentation.contents==null) return null;
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (Object c : documentation.contents) {
|
||||
if(c instanceof String) {
|
||||
buf.append(c.toString());
|
||||
}
|
||||
if(c instanceof Element) {
|
||||
Transformer t = builder.getIdentityTransformer();
|
||||
StringWriter w = new StringWriter();
|
||||
try {
|
||||
Writer fw = new FilterWriter(w) {
|
||||
char[] buf = new char[1];
|
||||
|
||||
public void write(int c) throws IOException {
|
||||
buf[0] = (char)c;
|
||||
write(buf,0,1);
|
||||
}
|
||||
|
||||
public void write(char[] cbuf, int off, int len) throws IOException {
|
||||
MinimumEscapeHandler.theInstance.escape(cbuf,off,len,false,out);
|
||||
}
|
||||
|
||||
public void write(String str, int off, int len) throws IOException {
|
||||
write(str.toCharArray(),off,len);
|
||||
}
|
||||
};
|
||||
t.transform(new DOMSource((Element)c),new StreamResult(fw));
|
||||
} catch (TransformerException e) {
|
||||
throw new Error(e); // impossible
|
||||
}
|
||||
buf.append("\n<pre>\n");
|
||||
buf.append(w);
|
||||
buf.append("\n</pre>\n");
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges all the declarations inside the given BindInfo
|
||||
* to this BindInfo.
|
||||
*/
|
||||
public void absorb( BindInfo bi ) {
|
||||
for( BIDeclaration d : bi )
|
||||
d.setParent(this);
|
||||
this.decls.addAll( bi.decls );
|
||||
|
||||
if(this.documentation==null)
|
||||
this.documentation = bi.documentation;
|
||||
else
|
||||
this.documentation.addAll(bi.documentation);
|
||||
}
|
||||
|
||||
/** Gets the number of declarations. */
|
||||
public int size() { return decls.size(); }
|
||||
|
||||
public BIDeclaration get( int idx ) { return decls.get(idx); }
|
||||
|
||||
public Iterator<BIDeclaration> iterator() {
|
||||
return decls.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of {@link CPluginCustomization}s from this.
|
||||
*
|
||||
* <p>
|
||||
* Note that calling this method marks all those plug-in customizations
|
||||
* as 'used'. So call it only when it's really necessary.
|
||||
*/
|
||||
public CCustomizations toCustomizationList() {
|
||||
CCustomizations r=null;
|
||||
for( BIDeclaration d : this ) {
|
||||
if(d instanceof BIXPluginCustomization) {
|
||||
BIXPluginCustomization pc = (BIXPluginCustomization) d;
|
||||
pc.markAsAcknowledged();
|
||||
if(!Ring.get(Model.class).options.pluginURIs.contains(pc.getName().getNamespaceURI()))
|
||||
continue; // this isn't a plugin customization
|
||||
if(r==null)
|
||||
r = new CCustomizations();
|
||||
r.add(new CPluginCustomization(pc.element,pc.getLocation()));
|
||||
}
|
||||
}
|
||||
|
||||
if(r==null) r = CCustomizations.EMPTY;
|
||||
return new CCustomizations(r);
|
||||
}
|
||||
/** An instance with the empty contents. */
|
||||
public final static BindInfo empty = new BindInfo();
|
||||
|
||||
/**
|
||||
* Lazily prepared {@link JAXBContext}.
|
||||
*/
|
||||
private static volatile JAXBContext customizationContext;
|
||||
|
||||
public static JAXBContext getCustomizationContext() {
|
||||
try {
|
||||
if (customizationContext == null) {
|
||||
synchronized (BindInfo.class) {
|
||||
if (customizationContext == null) {
|
||||
customizationContext = JAXBContext.newInstance(
|
||||
BindInfo.class, // for xs:annotation
|
||||
BIClass.class,
|
||||
BIConversion.User.class,
|
||||
BIConversion.UserAdapter.class,
|
||||
BIDom.class,
|
||||
BIFactoryMethod.class,
|
||||
BIInlineBinaryData.class,
|
||||
BIXDom.class,
|
||||
BIXSubstitutable.class,
|
||||
BIEnum.class,
|
||||
BIEnumMember.class,
|
||||
BIGlobalBinding.class,
|
||||
BIProperty.class,
|
||||
BISchemaBinding.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
return customizationContext;
|
||||
} catch (JAXBException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Unmarshaller getCustomizationUnmarshaller() {
|
||||
try {
|
||||
return getCustomizationContext().createUnmarshaller();
|
||||
} catch (JAXBException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazily parsed schema for the binding file.
|
||||
*/
|
||||
public static final SchemaCache bindingFileSchema = new SchemaCache(BindInfo.class.getResource("binding.xsd"));
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
import javax.xml.bind.annotation.XmlValue;
|
||||
|
||||
import com.sun.tools.internal.xjc.generator.bean.field.FieldRenderer;
|
||||
import com.sun.tools.internal.xjc.generator.bean.field.UntypedListFieldRenderer;
|
||||
import com.sun.tools.internal.xjc.generator.bean.field.FieldRendererFactory;
|
||||
import com.sun.tools.internal.xjc.model.Model;
|
||||
|
||||
/**
|
||||
* Bean used by JAXB to bind a collection type attribute to our {@link FieldRenderer}.
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
final class CollectionTypeAttribute {
|
||||
@XmlValue
|
||||
String collectionType = null;
|
||||
|
||||
/**
|
||||
* Computed from {@link #collectionType} on demand.
|
||||
*/
|
||||
@XmlTransient
|
||||
private FieldRenderer fr;
|
||||
|
||||
FieldRenderer get(Model m) {
|
||||
if(fr==null)
|
||||
fr = calcFr(m);
|
||||
return fr;
|
||||
}
|
||||
|
||||
private FieldRenderer calcFr(Model m) {
|
||||
FieldRendererFactory frf = m.options.getFieldRendererFactory();
|
||||
if (collectionType==null)
|
||||
return frf.getDefault();
|
||||
|
||||
if (collectionType.equals("indexed"))
|
||||
return frf.getArray();
|
||||
|
||||
return frf.getList(m.codeModel.ref(collectionType));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.bindinfo;
|
||||
|
||||
import javax.xml.bind.ValidationEventHandler;
|
||||
import javax.xml.bind.annotation.DomHandler;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.sax.SAXResult;
|
||||
|
||||
import com.sun.xml.internal.bind.marshaller.SAX2DOMEx;
|
||||
|
||||
import com.sun.xml.internal.bind.v2.util.XmlFactory;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.xml.sax.Locator;
|
||||
import org.xml.sax.helpers.LocatorImpl;
|
||||
import org.xml.sax.helpers.XMLFilterImpl;
|
||||
|
||||
/**
|
||||
* {@link DomHandler} that produces a W3C DOM but with a location information.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
final class DomHandlerEx implements DomHandler<DomHandlerEx.DomAndLocation,DomHandlerEx.ResultImpl> {
|
||||
|
||||
public static final class DomAndLocation {
|
||||
public final Element element;
|
||||
public final Locator loc;
|
||||
|
||||
public DomAndLocation(Element element, Locator loc) {
|
||||
this.element = element;
|
||||
this.loc = loc;
|
||||
}
|
||||
}
|
||||
|
||||
public ResultImpl createUnmarshaller(ValidationEventHandler errorHandler) {
|
||||
return new ResultImpl();
|
||||
}
|
||||
|
||||
public DomAndLocation getElement(ResultImpl r) {
|
||||
return new DomAndLocation( ((Document)r.s2d.getDOM()).getDocumentElement(), r.location );
|
||||
}
|
||||
|
||||
public Source marshal(DomAndLocation domAndLocation, ValidationEventHandler errorHandler) {
|
||||
return new DOMSource(domAndLocation.element);
|
||||
}
|
||||
|
||||
public static final class ResultImpl extends SAXResult {
|
||||
final SAX2DOMEx s2d;
|
||||
|
||||
Locator location = null;
|
||||
|
||||
ResultImpl() {
|
||||
try {
|
||||
DocumentBuilderFactory factory = XmlFactory.createDocumentBuilderFactory(false); // safe - only used for BI
|
||||
s2d = new SAX2DOMEx(factory);
|
||||
} catch (ParserConfigurationException e) {
|
||||
throw new AssertionError(e); // impossible
|
||||
}
|
||||
|
||||
XMLFilterImpl f = new XMLFilterImpl() {
|
||||
@Override
|
||||
public void setDocumentLocator(Locator locator) {
|
||||
super.setDocumentLocator(locator);
|
||||
location = new LocatorImpl(locator);
|
||||
}
|
||||
};
|
||||
f.setContentHandler(s2d);
|
||||
|
||||
setHandler(f);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import javax.xml.bind.annotation.XmlEnum;
|
||||
import javax.xml.bind.annotation.XmlEnumValue;
|
||||
|
||||
/**
|
||||
* Enum member name handling mode.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@XmlEnum
|
||||
public enum EnumMemberMode {
|
||||
@XmlEnumValue("skipGeneration")
|
||||
SKIP,
|
||||
@XmlEnumValue("generateError")
|
||||
ERROR,
|
||||
@XmlEnumValue("generateName")
|
||||
GENERATE
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* The mode will change to this when there's <jaxb:enum> customization.
|
||||
*/
|
||||
public EnumMemberMode getModeWithEnum() {
|
||||
if(this==SKIP) return ERROR;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import com.sun.xml.internal.bind.v2.WellKnownNamespace;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.Locator;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLFilter;
|
||||
import org.xml.sax.helpers.XMLFilterImpl;
|
||||
|
||||
/**
|
||||
* {@link XMLFilter} that can fork an event to another {@link ContentHandler}
|
||||
* in the middle.
|
||||
*
|
||||
* <p>
|
||||
* The side handler receives SAX events before the next handler in the filter chain does.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public class ForkingFilter extends XMLFilterImpl {
|
||||
|
||||
/**
|
||||
* Non-null if we are also forking events to this handler.
|
||||
*/
|
||||
private ContentHandler side;
|
||||
|
||||
/**
|
||||
* The depth of the current element that the {@link #side} handler
|
||||
* is seeing.
|
||||
*/
|
||||
private int depth;
|
||||
|
||||
/**
|
||||
* In-scope namespace mapping.
|
||||
* namespaces[2n ] := prefix
|
||||
* namespaces[2n+1] := namespace URI
|
||||
*/
|
||||
private final ArrayList<String> namespaces = new ArrayList<String>();
|
||||
|
||||
private Locator loc;
|
||||
|
||||
public ForkingFilter() {
|
||||
}
|
||||
|
||||
public ForkingFilter(ContentHandler next) {
|
||||
setContentHandler(next);
|
||||
}
|
||||
|
||||
public ContentHandler getSideHandler() {
|
||||
return side;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDocumentLocator(Locator locator) {
|
||||
super.setDocumentLocator(locator);
|
||||
this.loc = locator;
|
||||
}
|
||||
|
||||
public Locator getDocumentLocator() {
|
||||
return loc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startDocument() throws SAXException {
|
||||
reset();
|
||||
super.startDocument();
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
namespaces.clear();
|
||||
side = null;
|
||||
depth = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endDocument() throws SAXException {
|
||||
loc = null;
|
||||
reset();
|
||||
super.endDocument();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startPrefixMapping(String prefix, String uri) throws SAXException {
|
||||
if (WellKnownNamespace.XML_NAMESPACE_URI.equals(uri)) return; //xml prefix shall not be declared based on jdk api javadoc
|
||||
if(side!=null)
|
||||
side.startPrefixMapping(prefix,uri);
|
||||
namespaces.add(prefix);
|
||||
namespaces.add(uri);
|
||||
super.startPrefixMapping(prefix,uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endPrefixMapping(String prefix) throws SAXException {
|
||||
if ("xml".equals(prefix)) return; //xml prefix shall not be declared based on jdk api javadoc
|
||||
if(side!=null)
|
||||
side.endPrefixMapping(prefix);
|
||||
super.endPrefixMapping(prefix);
|
||||
namespaces.remove(namespaces.size()-1);
|
||||
namespaces.remove(namespaces.size()-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
|
||||
if(side!=null) {
|
||||
side.startElement(uri,localName,qName,atts);
|
||||
depth++;
|
||||
}
|
||||
super.startElement(uri, localName, qName, atts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the event forking.
|
||||
*/
|
||||
public void startForking(String uri, String localName, String qName, Attributes atts, ContentHandler side) throws SAXException {
|
||||
if(this.side!=null) throw new IllegalStateException(); // can't fork to two handlers
|
||||
|
||||
this.side = side;
|
||||
depth = 1;
|
||||
side.setDocumentLocator(loc);
|
||||
side.startDocument();
|
||||
for( int i=0; i<namespaces.size(); i+=2 )
|
||||
side.startPrefixMapping(namespaces.get(i),namespaces.get(i+1));
|
||||
side.startElement(uri,localName,qName,atts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||
if(side!=null) {
|
||||
side.endElement(uri,localName,qName);
|
||||
depth--;
|
||||
if(depth==0) {
|
||||
for( int i=namespaces.size()-2; i>=0; i-=2 )
|
||||
side.endPrefixMapping(namespaces.get(i));
|
||||
side.endDocument();
|
||||
side = null;
|
||||
}
|
||||
}
|
||||
super.endElement(uri, localName, qName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void characters(char ch[], int start, int length) throws SAXException {
|
||||
if(side!=null)
|
||||
side.characters(ch, start, length);
|
||||
super.characters(ch, start, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ignorableWhitespace(char ch[], int start, int length) throws SAXException {
|
||||
if(side!=null)
|
||||
side.ignorableWhitespace(ch, start, length);
|
||||
super.ignorableWhitespace(ch, start, length);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import javax.xml.bind.annotation.XmlEnumValue;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public enum LocalScoping {
|
||||
@XmlEnumValue("nested")
|
||||
NESTED,
|
||||
@XmlEnumValue("toplevel")
|
||||
TOPLEVEL
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* Formats error messages.
|
||||
*/
|
||||
enum Messages
|
||||
{
|
||||
ERR_CANNOT_BE_BOUND_TO_SIMPLETYPE,
|
||||
ERR_UNDEFINED_SIMPLE_TYPE,
|
||||
ERR_ILLEGAL_FIXEDATTR
|
||||
;
|
||||
|
||||
/** Loads a string resource and formats it with specified arguments. */
|
||||
String format( Object... args ) {
|
||||
String text = ResourceBundle.getBundle(Messages.class.getPackage().getName() + ".MessageBundle").getString(name());
|
||||
return MessageFormat.format(text,args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.bindinfo;
|
||||
|
||||
import javax.xml.bind.annotation.XmlEnumValue;
|
||||
|
||||
/**
|
||||
* Represents three constants of globalBindings/@optionalProperty.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public enum OptionalPropertyMode {
|
||||
@XmlEnumValue("primitive")
|
||||
PRIMITIVE,
|
||||
@XmlEnumValue("wrapper")
|
||||
WRAPPER,
|
||||
@XmlEnumValue("isSet")
|
||||
ISSET
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.
|
||||
*/
|
||||
|
||||
@XmlSchema(elementFormDefault = QUALIFIED, namespace=Const.JAXB_NSURI)
|
||||
package com.sun.tools.internal.xjc.reader.xmlschema.bindinfo;
|
||||
|
||||
import javax.xml.bind.annotation.XmlSchema;
|
||||
|
||||
import com.sun.tools.internal.xjc.reader.Const;
|
||||
|
||||
import static javax.xml.bind.annotation.XmlNsForm.QUALIFIED;
|
||||
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.ct;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.WildcardNameClassBuilder;
|
||||
import com.sun.xml.internal.xsom.XSAttributeUse;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSContentType;
|
||||
import com.sun.xml.internal.xsom.XSDeclaration;
|
||||
import com.sun.xml.internal.xsom.XSElementDecl;
|
||||
import com.sun.xml.internal.xsom.XSModelGroup;
|
||||
import com.sun.xml.internal.xsom.XSModelGroupDecl;
|
||||
import com.sun.xml.internal.xsom.XSParticle;
|
||||
import com.sun.xml.internal.xsom.XSType;
|
||||
import com.sun.xml.internal.xsom.XSWildcard;
|
||||
import com.sun.xml.internal.xsom.visitor.XSTermFunction;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import com.sun.xml.internal.rngom.nc.ChoiceNameClass;
|
||||
import com.sun.xml.internal.rngom.nc.NameClass;
|
||||
import com.sun.xml.internal.rngom.nc.SimpleNameClass;
|
||||
|
||||
/**
|
||||
* Binds a complex type derived from another complex type by extension.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
abstract class AbstractExtendedComplexTypeBuilder extends CTBuilder {
|
||||
|
||||
/**
|
||||
* Map from {@link XSComplexType} to {@link NameClass}[2] that
|
||||
* represents the names used in its child elements [0] and
|
||||
* attributes [1].
|
||||
*/
|
||||
protected final Map<XSComplexType, NameClass[]> characteristicNameClasses = new HashMap<XSComplexType, NameClass[]>();
|
||||
|
||||
/**
|
||||
* Computes a name class that represents everything in a given content model.
|
||||
*/
|
||||
protected final XSTermFunction<NameClass> contentModelNameClassBuilder = new XSTermFunction<NameClass>() {
|
||||
@Override
|
||||
public NameClass wildcard(XSWildcard wc) {
|
||||
return WildcardNameClassBuilder.build(wc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NameClass modelGroupDecl(XSModelGroupDecl decl) {
|
||||
return modelGroup(decl.getModelGroup());
|
||||
}
|
||||
|
||||
@Override
|
||||
public NameClass modelGroup(XSModelGroup group) {
|
||||
NameClass nc = NameClass.NULL;
|
||||
for( int i=0; i<group.getSize(); i++ )
|
||||
nc = new ChoiceNameClass(nc, group.getChild(i).getTerm().apply(this));
|
||||
return nc;
|
||||
}
|
||||
|
||||
public NameClass elementDecl(XSElementDecl decl) {
|
||||
return getNameClass(decl);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the particles/attributes defined in the type parameter
|
||||
* collides with the name classes of anc/enc.
|
||||
*
|
||||
* @return true if there's a collision.
|
||||
*/
|
||||
protected boolean checkCollision(NameClass anc, NameClass enc, XSComplexType type) {
|
||||
NameClass[] chnc = characteristicNameClasses.get(type);
|
||||
if (chnc == null) {
|
||||
chnc = new NameClass[2];
|
||||
chnc[0] = getNameClass(type.getContentType());
|
||||
|
||||
// build attribute name classes
|
||||
NameClass nc = NameClass.NULL;
|
||||
Iterator itr = type.iterateAttributeUses();
|
||||
while( itr.hasNext() )
|
||||
anc = new ChoiceNameClass(anc, getNameClass(((XSAttributeUse) itr.next()).getDecl()));
|
||||
XSWildcard wc = type.getAttributeWildcard();
|
||||
if(wc!=null)
|
||||
nc = new ChoiceNameClass(nc, WildcardNameClassBuilder.build(wc));
|
||||
chnc[1] = nc;
|
||||
|
||||
characteristicNameClasses.put(type, chnc);
|
||||
}
|
||||
|
||||
return chnc[0].hasOverlapWith(enc) || chnc[1].hasOverlapWith(anc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for the derivation chain t_1 > t_2 > ... > t
|
||||
* and find t_i such that t_i derives by restriction but
|
||||
* for every j>i, t_j derives by extension.
|
||||
*
|
||||
* @return null
|
||||
* If there's no such t_i or if t_i is any type.
|
||||
*/
|
||||
protected XSComplexType getLastRestrictedType(XSComplexType t) {
|
||||
if (t.getBaseType() == schemas.getAnyType()) {
|
||||
return null; // we don't count the restriction from anyType
|
||||
}
|
||||
if (t.getDerivationMethod() == XSType.RESTRICTION) {
|
||||
return t;
|
||||
}
|
||||
|
||||
XSComplexType baseType = t.getBaseType().asComplexType();
|
||||
if (baseType != null) {
|
||||
return getLastRestrictedType(baseType);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this new extension is safe.
|
||||
*
|
||||
* UGLY.
|
||||
* <p>
|
||||
* If you have ctA extending ctB and ctB restricting ctC, our
|
||||
* Java classes will look like CtAImpl extending CtBImpl
|
||||
* extending CtCImpl.
|
||||
*
|
||||
* <p>
|
||||
* Since a derived class unmarshaller uses the base class unmarshaller,
|
||||
* this could potentially result in incorrect unmarshalling.
|
||||
* We used to just reject such a case, but then we found that
|
||||
* there are schemas that are using it.
|
||||
*
|
||||
* <p>
|
||||
* One generalized observation that we reached is that if the extension
|
||||
* is only adding new elements/attributes which has never been used
|
||||
* in any of its base class (IOW, if none of the particle / attribute use /
|
||||
* attribute wildcard can match the name of newly added elements/attributes)
|
||||
* then it is safe to add them.
|
||||
*
|
||||
* <p>
|
||||
* This function checks if the derivation chain to this type is
|
||||
* not using restriction, and if it is, then checks if it is safe
|
||||
* according to the above condition.
|
||||
*
|
||||
* @return false
|
||||
* If this complex type needs to be rejected.
|
||||
*/
|
||||
protected boolean checkIfExtensionSafe(XSComplexType baseType, XSComplexType thisType) {
|
||||
XSComplexType lastType = getLastRestrictedType(baseType);
|
||||
|
||||
if (lastType == null) {
|
||||
return true; // no restriction in derivation chain
|
||||
}
|
||||
NameClass anc = NameClass.NULL;
|
||||
// build name class for attributes in new complex type
|
||||
Iterator itr = thisType.iterateDeclaredAttributeUses();
|
||||
while (itr.hasNext()) {
|
||||
anc = new ChoiceNameClass(anc, getNameClass(((XSAttributeUse) itr.next()).getDecl()));
|
||||
}
|
||||
// TODO: attribute wildcard
|
||||
|
||||
NameClass enc = getNameClass(thisType.getExplicitContent());
|
||||
|
||||
// check against every base type ... except the root anyType
|
||||
while (lastType != lastType.getBaseType()) {
|
||||
if (checkCollision(anc, enc, lastType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lastType.getBaseType().isSimpleType()) // if the base type is a simple type, there won't be
|
||||
// any further name collision.
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
lastType = lastType.getBaseType().asComplexType();
|
||||
}
|
||||
|
||||
return true; // OK
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link NameClass} that represents all the terms in the given content type.
|
||||
* If t is not a particle, just return an empty name class.
|
||||
*/
|
||||
private NameClass getNameClass(XSContentType t) {
|
||||
if(t==null) return NameClass.NULL;
|
||||
XSParticle p = t.asParticle();
|
||||
if(p==null) return NameClass.NULL;
|
||||
else return p.getTerm().apply(contentModelNameClassBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link SimpleNameClass} from the name of a {@link XSDeclaration}.
|
||||
*/
|
||||
private NameClass getNameClass(XSDeclaration decl) {
|
||||
return new SimpleNameClass(new QName(decl.getTargetNamespace(), decl.getName()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.ct;
|
||||
|
||||
import com.sun.tools.internal.xjc.ErrorReceiver;
|
||||
import com.sun.tools.internal.xjc.reader.Ring;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.BGMBuilder;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.BindGreen;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.ClassSelector;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.SimpleTypeBuilder;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSSchemaSet;
|
||||
|
||||
/**
|
||||
* Builds a field expression from a complex type.
|
||||
*
|
||||
* Depending on a "kind" of complex type, the binding is
|
||||
* quite different. For example, how a complex type is bound
|
||||
* when it is extended from another complex type is very
|
||||
* different from how it's bound when it has, say, mixed content model.
|
||||
*
|
||||
* Each different algorithm of binding a complex type is implemented
|
||||
* as an implementation of this interface.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
abstract class CTBuilder {
|
||||
/**
|
||||
* Returns true if this owner can handle the given complex type.
|
||||
*/
|
||||
abstract boolean isApplicable(XSComplexType ct);
|
||||
|
||||
/**
|
||||
* Binds the given complex type. This method will be called
|
||||
* only when the <code>isApplicable</code> method returns true.
|
||||
*/
|
||||
abstract void build(XSComplexType ct);
|
||||
|
||||
protected final ComplexTypeFieldBuilder builder = Ring.get(ComplexTypeFieldBuilder.class);
|
||||
protected final ClassSelector selector = Ring.get(ClassSelector.class);
|
||||
protected final SimpleTypeBuilder simpleTypeBuilder = Ring.get(SimpleTypeBuilder.class);
|
||||
protected final ErrorReceiver errorReceiver = Ring.get(ErrorReceiver.class);
|
||||
protected final BindGreen green = Ring.get(BindGreen.class);
|
||||
protected final XSSchemaSet schemas = Ring.get(XSSchemaSet.class);
|
||||
protected final BGMBuilder bgmBuilder = Ring.get(BGMBuilder.class);
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.ct;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static com.sun.tools.internal.xjc.reader.xmlschema.ct.ComplexTypeBindingMode.NORMAL;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSModelGroup;
|
||||
import com.sun.xml.internal.xsom.XSParticle;
|
||||
|
||||
/**
|
||||
* Binds a complex type whose immediate child is a choice
|
||||
* model group to a choice content interface.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
final class ChoiceContentComplexTypeBuilder extends CTBuilder {
|
||||
|
||||
public boolean isApplicable(XSComplexType ct) {
|
||||
if( !bgmBuilder.getGlobalBinding().isChoiceContentPropertyEnabled() )
|
||||
return false;
|
||||
|
||||
if( ct.getBaseType()!=schemas.getAnyType() )
|
||||
// My reading of the spec is that if a complex type is
|
||||
// derived from another complex type by extension,
|
||||
// its top level model group is always a sequence
|
||||
// that combines the base type content model and
|
||||
// the extension defined in the new complex type.
|
||||
return false;
|
||||
|
||||
XSParticle p = ct.getContentType().asParticle();
|
||||
if(p==null)
|
||||
return false;
|
||||
|
||||
XSModelGroup mg = getTopLevelModelGroup(p);
|
||||
|
||||
if( mg.getCompositor()!=XSModelGroup.CHOICE )
|
||||
return false;
|
||||
|
||||
if( p.isRepeated() )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private XSModelGroup getTopLevelModelGroup(XSParticle p) {
|
||||
XSModelGroup mg = p.getTerm().asModelGroup();
|
||||
if( p.getTerm().isModelGroupDecl() )
|
||||
mg = p.getTerm().asModelGroupDecl().getModelGroup();
|
||||
return mg;
|
||||
}
|
||||
|
||||
public void build(XSComplexType ct) {
|
||||
XSParticle p = ct.getContentType().asParticle();
|
||||
|
||||
builder.recordBindingMode(ct,NORMAL);
|
||||
|
||||
bgmBuilder.getParticleBinder().build(p,Collections.singleton(p));
|
||||
|
||||
green.attContainer(ct);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.ct;
|
||||
|
||||
/**
|
||||
* Three-state flag for a complex type.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public enum ComplexTypeBindingMode {
|
||||
|
||||
/**
|
||||
* Neither FALLBACK nor NOMOREEXTENSION.
|
||||
*/
|
||||
NORMAL,
|
||||
|
||||
/**
|
||||
* If a complex type has falled back to the general list content and
|
||||
* it is not NOMOREEXTENSION.
|
||||
*/
|
||||
FALLBACK_CONTENT,
|
||||
|
||||
/**
|
||||
* If a complex type has falled back to the rest content and
|
||||
* it is not NOMOREEXTENSION.
|
||||
*/
|
||||
FALLBACK_REST,
|
||||
|
||||
/**
|
||||
* If a complex type has fallen to the dummy property in order
|
||||
* to override previously inherited content.
|
||||
*/
|
||||
FALLBACK_EXTENSION
|
||||
|
||||
//
|
||||
// /**
|
||||
// * If a complex type is derived by restriction from a complex type
|
||||
// * other than the ur-type. Once this flag is turned on, no more
|
||||
// * derivation by extension is allowed.
|
||||
// */
|
||||
// static final ComplexTypeBindingMode NOMOREEXTENSION = new ComplexTypeBindingMode("noMoreExtension");
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.ct;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.BGMBuilder;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.BindingComponent;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
|
||||
/**
|
||||
* single entry point of building a field expression from a complex type.
|
||||
*
|
||||
* One object is created for one {@link BGMBuilder}.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public final class ComplexTypeFieldBuilder extends BindingComponent {
|
||||
|
||||
/**
|
||||
* All installed available complex type builders.
|
||||
*
|
||||
* <p>
|
||||
* Builders are tried in this order, to put specific ones first.
|
||||
*/
|
||||
private final CTBuilder[] complexTypeBuilders = new CTBuilder[]{
|
||||
new MultiWildcardComplexTypeBuilder(),
|
||||
new MixedExtendedComplexTypeBuilder(),
|
||||
new MixedComplexTypeBuilder(),
|
||||
new FreshComplexTypeBuilder(),
|
||||
new ExtendedComplexTypeBuilder(),
|
||||
new RestrictedComplexTypeBuilder(),
|
||||
new STDerivedComplexTypeBuilder()
|
||||
};
|
||||
|
||||
/** Records ComplexTypeBindingMode for XSComplexType. */
|
||||
private final Map<XSComplexType,ComplexTypeBindingMode> complexTypeBindingModes =
|
||||
new HashMap<XSComplexType,ComplexTypeBindingMode>();
|
||||
|
||||
/**
|
||||
* Binds a complex type to a field expression.
|
||||
*/
|
||||
public void build( XSComplexType type ) {
|
||||
for( CTBuilder ctb : complexTypeBuilders )
|
||||
if( ctb.isApplicable(type) ) {
|
||||
ctb.build(type);
|
||||
return;
|
||||
}
|
||||
|
||||
assert false; // shall never happen
|
||||
}
|
||||
|
||||
/**
|
||||
* Records the binding mode of the given complex type.
|
||||
*
|
||||
* <p>
|
||||
* Binding of a derived complex type often depends on that of the
|
||||
* base complex type. For example, when a base type is bound to
|
||||
* the getRest() method, all the derived complex types will be bound
|
||||
* in the same way.
|
||||
*
|
||||
* <p>
|
||||
* For this reason, we have to record how each complex type is being
|
||||
* bound.
|
||||
*/
|
||||
public void recordBindingMode( XSComplexType type, ComplexTypeBindingMode flag ) {
|
||||
// it is an error to override the flag.
|
||||
Object o = complexTypeBindingModes.put(type,flag);
|
||||
assert o==null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the binding mode recorded through
|
||||
* {@link #recordBindingMode(XSComplexType, ComplexTypeBindingMode)}.
|
||||
*/
|
||||
protected ComplexTypeBindingMode getBindingMode( XSComplexType type ) {
|
||||
ComplexTypeBindingMode r = complexTypeBindingModes.get(type);
|
||||
assert r!=null;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.ct;
|
||||
|
||||
|
||||
import com.sun.tools.internal.xjc.model.CClass;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSContentType;
|
||||
import com.sun.xml.internal.xsom.XSType;
|
||||
|
||||
|
||||
/**
|
||||
* Binds a complex type derived from another complex type by extension.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
final class ExtendedComplexTypeBuilder extends AbstractExtendedComplexTypeBuilder {
|
||||
|
||||
public boolean isApplicable(XSComplexType ct) {
|
||||
XSType baseType = ct.getBaseType();
|
||||
return baseType!=schemas.getAnyType()
|
||||
&& baseType.isComplexType()
|
||||
&& ct.getDerivationMethod()==XSType.EXTENSION;
|
||||
}
|
||||
|
||||
public void build(XSComplexType ct) {
|
||||
XSComplexType baseType = ct.getBaseType().asComplexType();
|
||||
|
||||
// build the base class
|
||||
CClass baseClass = selector.bindToType(baseType, ct, true);
|
||||
assert baseClass != null; // global complex type must map to a class
|
||||
|
||||
selector.getCurrentBean().setBaseClass(baseClass);
|
||||
|
||||
// derivation by extension.
|
||||
ComplexTypeBindingMode baseTypeFlag = builder.getBindingMode(baseType);
|
||||
|
||||
XSContentType explicitContent = ct.getExplicitContent();
|
||||
|
||||
if (!checkIfExtensionSafe(baseType, ct)) {
|
||||
// error. We can't handle any further extension
|
||||
errorReceiver.error(ct.getLocator(),
|
||||
Messages.ERR_NO_FURTHER_EXTENSION.format(
|
||||
baseType.getName(), ct.getName() )
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// explicit content is always either empty or a particle.
|
||||
if (explicitContent != null && explicitContent.asParticle() != null) {
|
||||
if (baseTypeFlag == ComplexTypeBindingMode.NORMAL) {
|
||||
// if we have additional explicit content, process them.
|
||||
builder.recordBindingMode(ct,
|
||||
bgmBuilder.getParticleBinder().checkFallback(explicitContent.asParticle())
|
||||
? ComplexTypeBindingMode.FALLBACK_REST
|
||||
: ComplexTypeBindingMode.NORMAL);
|
||||
|
||||
bgmBuilder.getParticleBinder().build(explicitContent.asParticle());
|
||||
|
||||
} else {
|
||||
// the base class has already done the fallback.
|
||||
// don't add anything new
|
||||
builder.recordBindingMode(ct, baseTypeFlag );
|
||||
}
|
||||
} else {
|
||||
// if it's empty, no additional processing is necessary
|
||||
builder.recordBindingMode(ct, baseTypeFlag);
|
||||
}
|
||||
|
||||
// adds attributes and we are through.
|
||||
green.attContainer(ct);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.ct;
|
||||
|
||||
import com.sun.tools.internal.xjc.model.CPropertyInfo;
|
||||
import com.sun.tools.internal.xjc.model.TypeUse;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIProperty;
|
||||
import static com.sun.tools.internal.xjc.reader.xmlschema.ct.ComplexTypeBindingMode.FALLBACK_CONTENT;
|
||||
import static com.sun.tools.internal.xjc.reader.xmlschema.ct.ComplexTypeBindingMode.NORMAL;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.BGMBuilder;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSContentType;
|
||||
import com.sun.xml.internal.xsom.XSModelGroup;
|
||||
import com.sun.xml.internal.xsom.XSParticle;
|
||||
import com.sun.xml.internal.xsom.XSSimpleType;
|
||||
import com.sun.xml.internal.xsom.XSTerm;
|
||||
import com.sun.xml.internal.xsom.visitor.XSContentTypeVisitor;
|
||||
|
||||
/**
|
||||
* Builds a complex type that inherits from the anyType complex type.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
final class FreshComplexTypeBuilder extends CTBuilder {
|
||||
|
||||
public boolean isApplicable(XSComplexType ct) {
|
||||
return ct.getBaseType()==schemas.getAnyType()
|
||||
&& !ct.isMixed(); // not mixed
|
||||
}
|
||||
|
||||
public void build(final XSComplexType ct) {
|
||||
XSContentType contentType = ct.getContentType();
|
||||
|
||||
contentType.visit(new XSContentTypeVisitor() {
|
||||
public void simpleType(XSSimpleType st) {
|
||||
builder.recordBindingMode(ct,ComplexTypeBindingMode.NORMAL);
|
||||
|
||||
simpleTypeBuilder.refererStack.push(ct);
|
||||
TypeUse use = simpleTypeBuilder.build(st);
|
||||
simpleTypeBuilder.refererStack.pop();
|
||||
|
||||
BIProperty prop = BIProperty.getCustomization(ct);
|
||||
CPropertyInfo p = prop.createValueProperty("Value",false,ct,use, BGMBuilder.getName(st));
|
||||
selector.getCurrentBean().addProperty(p);
|
||||
}
|
||||
|
||||
public void particle(XSParticle p) {
|
||||
// determine the binding of this complex type.
|
||||
|
||||
builder.recordBindingMode(ct,
|
||||
bgmBuilder.getParticleBinder().checkFallback(p)?FALLBACK_CONTENT:NORMAL);
|
||||
|
||||
bgmBuilder.getParticleBinder().build(p);
|
||||
|
||||
XSTerm term = p.getTerm();
|
||||
if(term.isModelGroup() && term.asModelGroup().getCompositor()==XSModelGroup.ALL)
|
||||
selector.getCurrentBean().setOrdered(false);
|
||||
|
||||
}
|
||||
|
||||
public void empty(XSContentType e) {
|
||||
builder.recordBindingMode(ct,NORMAL);
|
||||
}
|
||||
});
|
||||
|
||||
// adds attributes and we are through.
|
||||
green.attContainer(ct);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.ct;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* Message resources
|
||||
*/
|
||||
enum Messages {
|
||||
ERR_NO_FURTHER_EXTENSION;
|
||||
|
||||
private static final ResourceBundle rb = ResourceBundle.getBundle(Messages.class.getPackage().getName() + ".MessageBundle");
|
||||
|
||||
public String toString() {
|
||||
return format();
|
||||
}
|
||||
|
||||
public String format( Object... args ) {
|
||||
return MessageFormat.format( rb.getString(name()), args );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.ct;
|
||||
|
||||
import com.sun.tools.internal.xjc.model.CBuiltinLeafInfo;
|
||||
import com.sun.tools.internal.xjc.model.CClass;
|
||||
import com.sun.tools.internal.xjc.model.CPropertyInfo;
|
||||
import com.sun.tools.internal.xjc.reader.RawTypeSet;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.RawTypeSetBuilder;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIProperty;
|
||||
import static com.sun.tools.internal.xjc.reader.xmlschema.ct.ComplexTypeBindingMode.FALLBACK_CONTENT;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSContentType;
|
||||
import com.sun.xml.internal.xsom.XSType;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
final class MixedComplexTypeBuilder extends CTBuilder {
|
||||
|
||||
public boolean isApplicable(XSComplexType ct) {
|
||||
XSType bt = ct.getBaseType();
|
||||
if(bt ==schemas.getAnyType() && ct.isMixed())
|
||||
return true; // fresh mixed complex type
|
||||
|
||||
// there's no complex type in the inheritance tree yet
|
||||
if (bt.isComplexType() &&
|
||||
!bt.asComplexType().isMixed() &&
|
||||
ct.isMixed() &&
|
||||
ct.getDerivationMethod() == XSType.EXTENSION) {
|
||||
if (!bgmBuilder.isGenerateMixedExtensions() && (ct.getContentType().asParticle() == null)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void build(XSComplexType ct) {
|
||||
XSContentType contentType = ct.getContentType();
|
||||
|
||||
boolean generateMixedExtensions = bgmBuilder.isGenerateMixedExtensions();
|
||||
if (generateMixedExtensions) {
|
||||
if (!(ct.getBaseType() == schemas.getAnyType() && ct.isMixed())) {
|
||||
XSComplexType baseType = ct.getBaseType().asComplexType();
|
||||
// build the base class
|
||||
CClass baseClass = selector.bindToType(baseType, ct, true);
|
||||
selector.getCurrentBean().setBaseClass(baseClass);
|
||||
}
|
||||
}
|
||||
|
||||
builder.recordBindingMode(ct, FALLBACK_CONTENT);
|
||||
BIProperty prop = BIProperty.getCustomization(ct);
|
||||
|
||||
CPropertyInfo p;
|
||||
|
||||
if (generateMixedExtensions) {
|
||||
List<XSComplexType> cType = ct.getSubtypes();
|
||||
boolean isSubtyped = (cType != null) && (cType.size() > 0);
|
||||
|
||||
if (contentType.asEmpty() != null) {
|
||||
if (isSubtyped) {
|
||||
p = prop.createContentExtendedMixedReferenceProperty("Content", ct, null);
|
||||
} else {
|
||||
p = prop.createValueProperty("Content",false,ct,CBuiltinLeafInfo.STRING,null);
|
||||
}
|
||||
} else if (contentType.asParticle() == null) {
|
||||
p = prop.createContentExtendedMixedReferenceProperty("Content", ct, null);
|
||||
} else {
|
||||
RawTypeSet ts = RawTypeSetBuilder.build(contentType.asParticle(), false);
|
||||
p = prop.createContentExtendedMixedReferenceProperty("Content", ct, ts);
|
||||
}
|
||||
|
||||
} else {
|
||||
if(contentType.asEmpty()!=null) {
|
||||
p = prop.createValueProperty("Content",false,ct,CBuiltinLeafInfo.STRING,null);
|
||||
} else {
|
||||
RawTypeSet ts = RawTypeSetBuilder.build(contentType.asParticle(),false);
|
||||
p = prop.createReferenceProperty("Content", false, ct, ts, true, false, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
selector.getCurrentBean().addProperty(p);
|
||||
|
||||
// adds attributes and we are through.
|
||||
green.attContainer(ct);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.ct;
|
||||
|
||||
import com.sun.tools.internal.xjc.model.CClass;
|
||||
import com.sun.tools.internal.xjc.model.CPropertyInfo;
|
||||
import com.sun.tools.internal.xjc.reader.RawTypeSet;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.RawTypeSetBuilder;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIGlobalBinding;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIProperty;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSContentType;
|
||||
import com.sun.xml.internal.xsom.XSType;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
final class MixedExtendedComplexTypeBuilder extends AbstractExtendedComplexTypeBuilder {
|
||||
|
||||
public boolean isApplicable(XSComplexType ct) {
|
||||
|
||||
if (!bgmBuilder.isGenerateMixedExtensions()) return false;
|
||||
|
||||
XSType bt = ct.getBaseType();
|
||||
if (bt.isComplexType() &&
|
||||
bt.asComplexType().isMixed() &&
|
||||
ct.isMixed() &&
|
||||
ct.getDerivationMethod()==XSType.EXTENSION &&
|
||||
ct.getContentType().asParticle() != null &&
|
||||
ct.getExplicitContent().asEmpty() == null
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void build(XSComplexType ct) {
|
||||
XSComplexType baseType = ct.getBaseType().asComplexType();
|
||||
|
||||
// build the base class
|
||||
CClass baseClass = selector.bindToType(baseType, ct, true);
|
||||
assert baseClass != null; // global complex type must map to a class
|
||||
|
||||
if (!checkIfExtensionSafe(baseType, ct)) {
|
||||
// error. We can't handle any further extension
|
||||
errorReceiver.error(ct.getLocator(),
|
||||
Messages.ERR_NO_FURTHER_EXTENSION.format(
|
||||
baseType.getName(), ct.getName() )
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
selector.getCurrentBean().setBaseClass(baseClass);
|
||||
builder.recordBindingMode(ct, ComplexTypeBindingMode.FALLBACK_EXTENSION);
|
||||
|
||||
BIProperty prop = BIProperty.getCustomization(ct);
|
||||
CPropertyInfo p;
|
||||
|
||||
RawTypeSet ts = RawTypeSetBuilder.build(ct.getContentType().asParticle(), false);
|
||||
p = prop.createDummyExtendedMixedReferenceProperty("contentOverrideFor" + ct.getName(), ct, ts);
|
||||
|
||||
selector.getCurrentBean().addProperty(p);
|
||||
|
||||
// adds attributes and we are through.
|
||||
green.attContainer(ct);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.ct;
|
||||
|
||||
import com.sun.tools.internal.xjc.model.CBuiltinLeafInfo;
|
||||
import com.sun.tools.internal.xjc.model.CPropertyInfo;
|
||||
import com.sun.tools.internal.xjc.reader.RawTypeSet;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.RawTypeSetBuilder;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIProperty;
|
||||
import static com.sun.tools.internal.xjc.reader.xmlschema.ct.ComplexTypeBindingMode.FALLBACK_CONTENT;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSContentType;
|
||||
import com.sun.xml.internal.xsom.XSParticle;
|
||||
import com.sun.xml.internal.xsom.XSType;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
final class MultiWildcardComplexTypeBuilder extends CTBuilder {
|
||||
|
||||
public boolean isApplicable(XSComplexType ct) {
|
||||
if (!bgmBuilder.model.options.contentForWildcard) {
|
||||
return false;
|
||||
}
|
||||
XSType bt = ct.getBaseType();
|
||||
if (bt ==schemas.getAnyType() && ct.getContentType() != null) {
|
||||
XSParticle part = ct.getContentType().asParticle();
|
||||
if ((part != null) && (part.getTerm().isModelGroup())) {
|
||||
XSParticle[] parts = part.getTerm().asModelGroup().getChildren();
|
||||
int wildcardCount = 0;
|
||||
int i = 0;
|
||||
while ((i < parts.length) && (wildcardCount <= 1)) {
|
||||
if (parts[i].getTerm().isWildcard()) {
|
||||
wildcardCount += 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return (wildcardCount > 1);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void build(XSComplexType ct) {
|
||||
XSContentType contentType = ct.getContentType();
|
||||
|
||||
builder.recordBindingMode(ct, FALLBACK_CONTENT);
|
||||
BIProperty prop = BIProperty.getCustomization(ct);
|
||||
|
||||
CPropertyInfo p;
|
||||
|
||||
if(contentType.asEmpty()!=null) {
|
||||
p = prop.createValueProperty("Content",false,ct,CBuiltinLeafInfo.STRING,null);
|
||||
} else {
|
||||
RawTypeSet ts = RawTypeSetBuilder.build(contentType.asParticle(),false);
|
||||
p = prop.createReferenceProperty("Content", false, ct, ts, true, false, true, false);
|
||||
}
|
||||
|
||||
selector.getCurrentBean().addProperty(p);
|
||||
|
||||
// adds attributes and we are through.
|
||||
green.attContainer(ct);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.ct;
|
||||
|
||||
import com.sun.tools.internal.xjc.model.CClass;
|
||||
import com.sun.tools.internal.xjc.model.CPropertyInfo;
|
||||
import com.sun.tools.internal.xjc.reader.RawTypeSet;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.RawTypeSetBuilder;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIGlobalBinding;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIProperty;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSParticle;
|
||||
import com.sun.xml.internal.xsom.XSType;
|
||||
|
||||
/**
|
||||
* Binds a complex type derived from another complex type
|
||||
* by restriction.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
final class RestrictedComplexTypeBuilder extends CTBuilder {
|
||||
|
||||
public boolean isApplicable(XSComplexType ct) {
|
||||
XSType baseType = ct.getBaseType();
|
||||
return baseType!=schemas.getAnyType()
|
||||
&& baseType.isComplexType()
|
||||
&& ct.getDerivationMethod()==XSType.RESTRICTION;
|
||||
}
|
||||
|
||||
public void build(XSComplexType ct) {
|
||||
|
||||
if (bgmBuilder.getGlobalBinding().isRestrictionFreshType()) {
|
||||
// handle derivation-by-restriction like a whole new type
|
||||
new FreshComplexTypeBuilder().build(ct);
|
||||
return;
|
||||
}
|
||||
|
||||
XSComplexType baseType = ct.getBaseType().asComplexType();
|
||||
|
||||
// build the base class
|
||||
CClass baseClass = selector.bindToType(baseType,ct,true);
|
||||
assert baseClass!=null; // global complex type must map to a class
|
||||
|
||||
selector.getCurrentBean().setBaseClass(baseClass);
|
||||
|
||||
if (bgmBuilder.isGenerateMixedExtensions()) {
|
||||
boolean forceFallbackInExtension = baseType.isMixed() &&
|
||||
ct.isMixed() &&
|
||||
(ct.getExplicitContent() != null) &&
|
||||
bgmBuilder.inExtensionMode;
|
||||
if (forceFallbackInExtension) {
|
||||
builder.recordBindingMode(ct, ComplexTypeBindingMode.NORMAL);
|
||||
|
||||
BIProperty prop = BIProperty.getCustomization(ct);
|
||||
CPropertyInfo p;
|
||||
|
||||
XSParticle particle = ct.getContentType().asParticle();
|
||||
if (particle != null) {
|
||||
RawTypeSet ts = RawTypeSetBuilder.build(particle, false);
|
||||
p = prop.createDummyExtendedMixedReferenceProperty("Content", ct, ts);
|
||||
selector.getCurrentBean().addProperty(p);
|
||||
}
|
||||
} else {
|
||||
// determine the binding of this complex type.
|
||||
builder.recordBindingMode(ct,builder.getBindingMode(baseType));
|
||||
}
|
||||
} else {
|
||||
builder.recordBindingMode(ct,builder.getBindingMode(baseType));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.ct;
|
||||
|
||||
import com.sun.tools.internal.xjc.model.CPropertyInfo;
|
||||
import com.sun.tools.internal.xjc.model.TypeUse;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIProperty;
|
||||
import com.sun.tools.internal.xjc.reader.xmlschema.BGMBuilder;
|
||||
import com.sun.xml.internal.xsom.XSComplexType;
|
||||
import com.sun.xml.internal.xsom.XSSimpleType;
|
||||
import com.sun.xml.internal.xsom.XSType;
|
||||
|
||||
/**
|
||||
* Binds a complex type derived from a simple type.
|
||||
* When a complex type is derived from a simple type, it is always
|
||||
* by extension.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
final class STDerivedComplexTypeBuilder extends CTBuilder {
|
||||
|
||||
public boolean isApplicable(XSComplexType ct) {
|
||||
return ct.getBaseType().isSimpleType();
|
||||
}
|
||||
|
||||
public void build(XSComplexType ct) {
|
||||
assert ct.getDerivationMethod()==XSType.EXTENSION;
|
||||
|
||||
// base type is a simple type
|
||||
XSSimpleType baseType = ct.getBaseType().asSimpleType();
|
||||
|
||||
// determine the binding of this complex type.
|
||||
builder.recordBindingMode(ct,ComplexTypeBindingMode.NORMAL);
|
||||
|
||||
simpleTypeBuilder.refererStack.push(ct);
|
||||
TypeUse use = simpleTypeBuilder.build(baseType);
|
||||
simpleTypeBuilder.refererStack.pop();
|
||||
|
||||
BIProperty prop = BIProperty.getCustomization(ct);
|
||||
CPropertyInfo p = prop.createValueProperty("Value",false,baseType,use, BGMBuilder.getName(baseType));
|
||||
selector.getCurrentBean().addProperty(p);
|
||||
|
||||
// adds attributes and we are through.
|
||||
green.attContainer(ct);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.parser;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import com.sun.tools.internal.xjc.reader.Const;
|
||||
import com.sun.xml.internal.bind.v2.WellKnownNamespace;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.Locator;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
import org.xml.sax.helpers.XMLFilterImpl;
|
||||
|
||||
/**
|
||||
* Checks if binding declarations are placed where they are allowed.
|
||||
*
|
||||
* <p>
|
||||
* For example, if a <jaxb:property> customization is given under
|
||||
* the <xs:simpleContent> element, this class raises an error.
|
||||
*
|
||||
* <p>
|
||||
* our main checkpoint of misplaced customizations are in BGMBuilder.
|
||||
* There, we mark a customization whenever we use it. At the end of the
|
||||
* day, we look for unmarked customizations and raise errors for them.
|
||||
*
|
||||
* <p>
|
||||
* Between this approach and the JAXB spec 1.0 is a problem that
|
||||
* the spec allows/prohibits customizations at schema element level,
|
||||
* while BGMBuilder and XSOM works on schema component levels.
|
||||
*
|
||||
* <p>
|
||||
* For example, a property customization is allowed on a complex type
|
||||
* schema component, but it's only allowed on the <complexType>
|
||||
* element. The spec team informed us that they would consider resolving
|
||||
* this discrepancy in favor of RI, but meanwhile we need to detect
|
||||
* errors correctly.
|
||||
*
|
||||
* <p>
|
||||
* This filter is implemented for this purpose.
|
||||
*
|
||||
*
|
||||
* <h2>Customization and allowed locations</h2>
|
||||
*
|
||||
* - globalBinding/schemaBinding
|
||||
* schema
|
||||
*
|
||||
* - class
|
||||
* complexType(*), modelGroupDecl, modelGroup, element
|
||||
*
|
||||
* - property
|
||||
* attribute, element, any, modelGroup, modelGroupRef, complexType(*)
|
||||
*
|
||||
* - javaType
|
||||
* simpleType(*)
|
||||
*
|
||||
* - typesafeEnumClass
|
||||
* simpleType(*)
|
||||
*
|
||||
* - typesafeEnumMember
|
||||
* simpleType(*), enumeration
|
||||
*
|
||||
* Components marked with '*' needs a check by this component
|
||||
* since more than one schema element corresponds to one schema component
|
||||
* of that type.
|
||||
*
|
||||
* <p>
|
||||
* For simple types, customizations are allowed only under the <xs:simpleType>
|
||||
* element, and for complex types they are allowed only under the
|
||||
* <xs:cimplexType> element.
|
||||
*
|
||||
* <p>
|
||||
* So the bottom line is that it would be suffice if we just make sure
|
||||
* that no customization will be attached under other elements of
|
||||
* simple types and complex types. Those are:
|
||||
*
|
||||
* - simpleType/restriction
|
||||
* - list
|
||||
* - union
|
||||
* - complexType/(simple or complex)Content
|
||||
* - complexType/(simple or complex)Content/(restriction of extension)
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public class CustomizationContextChecker extends XMLFilterImpl {
|
||||
|
||||
/** Keep names of all the ancestor elements. */
|
||||
private final Stack<QName> elementNames = new Stack<QName>();
|
||||
|
||||
private final ErrorHandler errorHandler;
|
||||
|
||||
private Locator locator;
|
||||
|
||||
/** Set of element names that cannot have JAXB customizations. */
|
||||
private static final Set<String> prohibitedSchemaElementNames = new HashSet<String>();
|
||||
|
||||
/**
|
||||
* @param _errorHandler
|
||||
* Detected errors will be sent to this object.
|
||||
*/
|
||||
public CustomizationContextChecker( ErrorHandler _errorHandler ) {
|
||||
this.errorHandler = _errorHandler;
|
||||
}
|
||||
|
||||
static {
|
||||
prohibitedSchemaElementNames.add("restriction");
|
||||
prohibitedSchemaElementNames.add("extension");
|
||||
prohibitedSchemaElementNames.add("simpleContent");
|
||||
prohibitedSchemaElementNames.add("complexContent");
|
||||
prohibitedSchemaElementNames.add("list");
|
||||
prohibitedSchemaElementNames.add("union");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** Gets the stack top. */
|
||||
private QName top() {
|
||||
return elementNames.peek();
|
||||
}
|
||||
|
||||
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
|
||||
QName newElement = new QName(namespaceURI,localName);
|
||||
|
||||
if( newElement.getNamespaceURI().equals(Const.JAXB_NSURI)
|
||||
&& top().getNamespaceURI().equals(WellKnownNamespace.XML_SCHEMA) ) {
|
||||
// we hit a JAXB customization. the stack top should be
|
||||
// <xs:appinfo>
|
||||
if( elementNames.size()>=3 ) {
|
||||
// the above statement checks if the following statement doesn't
|
||||
// cause an exception.
|
||||
QName schemaElement = elementNames.get( elementNames.size()-3 );
|
||||
if( prohibitedSchemaElementNames.contains(schemaElement.getLocalPart()) ) {
|
||||
// the owner schema element is in the wanted list.
|
||||
errorHandler.error( new SAXParseException(
|
||||
Messages.format(
|
||||
Messages.ERR_UNACKNOWLEDGED_CUSTOMIZATION,
|
||||
localName ),
|
||||
locator ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
elementNames.push(newElement);
|
||||
|
||||
super.startElement(namespaceURI, localName, qName, atts );
|
||||
}
|
||||
|
||||
public void endElement(String namespaceURI, String localName, String qName)
|
||||
throws SAXException {
|
||||
|
||||
super.endElement(namespaceURI, localName, qName);
|
||||
|
||||
elementNames.pop();
|
||||
}
|
||||
|
||||
public void setDocumentLocator(Locator locator) {
|
||||
super.setDocumentLocator(locator);
|
||||
this.locator = locator;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.parser;
|
||||
|
||||
import com.sun.tools.internal.xjc.reader.Const;
|
||||
import com.sun.xml.internal.bind.v2.WellKnownNamespace;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.Locator;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
import org.xml.sax.helpers.XMLFilterImpl;
|
||||
|
||||
/**
|
||||
* This filter detects the use of incorrect JAXB namespace URI.
|
||||
*
|
||||
* When the binding compiler looks at a schema file, it always look
|
||||
* for the namespace URI of the elements (which is correct, BTW.)
|
||||
*
|
||||
* <p>
|
||||
* However, one unfortunate downside of this philosophically correct
|
||||
* behavior is that there is no provision or safety check when an user
|
||||
* misspelled JAXB binding customization namespace.
|
||||
*
|
||||
* <p>
|
||||
* This checker inspects the input document and look for the use of the
|
||||
* prefix "jaxb". If the document doesn't associate any prefix to the
|
||||
* JAXB customization URI and if it does associate the jaxb prefix,
|
||||
* this checker will issue a warning.
|
||||
*
|
||||
* <p>
|
||||
* This warning can happen to completely correct schema (because
|
||||
* nothing prevents you from using the prefix "jaxb" for other purpose
|
||||
* while using a JAXB compiler on the same schema) but in practice
|
||||
* this would be quite unlikely.
|
||||
*
|
||||
* <p>
|
||||
* This justifies the use of this filter.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public class IncorrectNamespaceURIChecker extends XMLFilterImpl {
|
||||
|
||||
public IncorrectNamespaceURIChecker( ErrorHandler handler ) {
|
||||
this.errorHandler = handler;
|
||||
}
|
||||
|
||||
private ErrorHandler errorHandler;
|
||||
|
||||
private Locator locator = null;
|
||||
|
||||
/** Sets to true once we see the jaxb prefix in use. */
|
||||
private boolean isJAXBPrefixUsed = false;
|
||||
/** Sets to true once we see the JAXB customization namespace URI. */
|
||||
private boolean isCustomizationUsed = false;
|
||||
|
||||
@Override
|
||||
public void endDocument() throws SAXException {
|
||||
if( isJAXBPrefixUsed && !isCustomizationUsed ) {
|
||||
SAXParseException e = new SAXParseException(
|
||||
Messages.format(Messages.WARN_INCORRECT_URI, Const.JAXB_NSURI),
|
||||
locator );
|
||||
errorHandler.warning(e);
|
||||
}
|
||||
|
||||
super.endDocument();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startPrefixMapping(String prefix, String uri) throws SAXException {
|
||||
if (WellKnownNamespace.XML_NAMESPACE_URI.equals(uri)) return; //xml prefix shall not be declared based on jdk api javadoc
|
||||
if( prefix.equals("jaxb") )
|
||||
isJAXBPrefixUsed = true;
|
||||
if( uri.equals(Const.JAXB_NSURI) )
|
||||
isCustomizationUsed = true;
|
||||
|
||||
super.startPrefixMapping(prefix, uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endPrefixMapping(String prefix) throws SAXException {
|
||||
if ("xml".equals(prefix)) return; //xml prefix shall not be declared based on jdk api javadoc
|
||||
super.endPrefixMapping(prefix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
|
||||
throws SAXException {
|
||||
super.startElement(namespaceURI, localName, qName, atts);
|
||||
|
||||
// I'm not sure if this is necessary (SAX might report the change of the default prefix
|
||||
// through the startPrefixMapping method, and I think it does indeed.)
|
||||
//
|
||||
// but better safe than sorry.
|
||||
|
||||
if( namespaceURI.equals(Const.JAXB_NSURI) )
|
||||
isCustomizationUsed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDocumentLocator( Locator locator ) {
|
||||
super.setDocumentLocator( locator );
|
||||
this.locator = locator;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.parser;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
|
||||
import org.w3c.dom.ls.LSInput;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
/**
|
||||
* LSInput implementation that wraps a SAX InputSource
|
||||
*
|
||||
* @author Ryan.Shoemaker@Sun.COM
|
||||
*/
|
||||
public class LSInputSAXWrapper implements LSInput {
|
||||
private InputSource core;
|
||||
|
||||
public LSInputSAXWrapper(InputSource inputSource) {
|
||||
assert inputSource!=null;
|
||||
core = inputSource;
|
||||
}
|
||||
|
||||
public Reader getCharacterStream() {
|
||||
return core.getCharacterStream();
|
||||
}
|
||||
|
||||
public void setCharacterStream(Reader characterStream) {
|
||||
core.setCharacterStream(characterStream);
|
||||
}
|
||||
|
||||
public InputStream getByteStream() {
|
||||
return core.getByteStream();
|
||||
}
|
||||
|
||||
public void setByteStream(InputStream byteStream) {
|
||||
core.setByteStream(byteStream);
|
||||
}
|
||||
|
||||
public String getStringData() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setStringData(String stringData) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
public String getSystemId() {
|
||||
return core.getSystemId();
|
||||
}
|
||||
|
||||
public void setSystemId(String systemId) {
|
||||
core.setSystemId(systemId);
|
||||
}
|
||||
|
||||
public String getPublicId() {
|
||||
return core.getPublicId();
|
||||
}
|
||||
|
||||
public void setPublicId(String publicId) {
|
||||
core.setPublicId(publicId);
|
||||
}
|
||||
|
||||
public String getBaseURI() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setBaseURI(String baseURI) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
public String getEncoding() {
|
||||
return core.getEncoding();
|
||||
}
|
||||
|
||||
public void setEncoding(String encoding) {
|
||||
core.setEncoding(encoding);
|
||||
}
|
||||
|
||||
public boolean getCertifiedText() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setCertifiedText(boolean certifiedText) {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.parser;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* Formats error messages.
|
||||
*/
|
||||
class Messages
|
||||
{
|
||||
/** Loads a string resource and formats it with specified arguments. */
|
||||
static String format( String property, Object... args ) {
|
||||
String text = ResourceBundle.getBundle(Messages.class.getPackage().getName() +".MessageBundle").getString(property);
|
||||
return MessageFormat.format(text,args);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static final String ERR_UNACKNOWLEDGED_CUSTOMIZATION =
|
||||
"CustomizationContextChecker.UnacknolwedgedCustomization"; // arg:1
|
||||
|
||||
static final String WARN_INCORRECT_URI = // 1 args
|
||||
"IncorrectNamespaceURIChecker.WarnIncorrectURI";
|
||||
|
||||
static final String WARN_UNABLE_TO_CHECK_CORRECTNESS = // 0 args
|
||||
"SchemaConstraintChecker.UnableToCheckCorrectness";
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.parser;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.sax.SAXSource;
|
||||
import javax.xml.validation.SchemaFactory;
|
||||
|
||||
import com.sun.tools.internal.xjc.ConsoleErrorReporter;
|
||||
import com.sun.tools.internal.xjc.ErrorReceiver;
|
||||
import com.sun.tools.internal.xjc.util.ErrorReceiverFilter;
|
||||
|
||||
import com.sun.xml.internal.bind.v2.util.XmlFactory;
|
||||
import org.w3c.dom.ls.LSInput;
|
||||
import org.w3c.dom.ls.LSResourceResolver;
|
||||
import org.xml.sax.EntityResolver;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
|
||||
|
||||
/**
|
||||
* Checks XML Schema XML representation constraints and
|
||||
* schema component constraints by using JAXP 1.3 validation framework.
|
||||
* <p/>
|
||||
*
|
||||
* @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
* @author Ryan Shoemaker (ryan.shoemaker@sun.com)
|
||||
*/
|
||||
public class SchemaConstraintChecker {
|
||||
|
||||
/**
|
||||
* @param schemas Schema files to be checked.
|
||||
* @param errorHandler detected errors will be reported to this handler.
|
||||
* @return true if there was no error, false if there were errors.
|
||||
*/
|
||||
public static boolean check(InputSource[] schemas,
|
||||
ErrorReceiver errorHandler,
|
||||
final EntityResolver entityResolver,
|
||||
boolean disableXmlSecurity) {
|
||||
|
||||
ErrorReceiverFilter errorFilter = new ErrorReceiverFilter(errorHandler);
|
||||
boolean hadErrors = false;
|
||||
|
||||
SchemaFactory sf = XmlFactory.createSchemaFactory(W3C_XML_SCHEMA_NS_URI, disableXmlSecurity);
|
||||
XmlFactory.allowExternalAccess(sf, "all", disableXmlSecurity);
|
||||
sf.setErrorHandler(errorFilter);
|
||||
if( entityResolver != null ) {
|
||||
sf.setResourceResolver(new LSResourceResolver() {
|
||||
public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {
|
||||
try {
|
||||
// XSOM passes the namespace URI to the publicID parameter.
|
||||
// we do the same here .
|
||||
InputSource is = entityResolver.resolveEntity(namespaceURI, systemId);
|
||||
if(is==null) return null;
|
||||
return new LSInputSAXWrapper(is);
|
||||
} catch (SAXException e) {
|
||||
// TODO: is this sufficient?
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
// TODO: is this sufficient?
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
XmlFactory.allowExternalDTDAccess(sf, "all", disableXmlSecurity);
|
||||
sf.newSchema(getSchemaSource(schemas, entityResolver));
|
||||
} catch (SAXException e) {
|
||||
// TODO: we haven't thrown exceptions from here before. should we just trap them and return false?
|
||||
hadErrors = true;
|
||||
} catch( OutOfMemoryError e) {
|
||||
errorHandler.warning(null,Messages.format(Messages.WARN_UNABLE_TO_CHECK_CORRECTNESS));
|
||||
}
|
||||
|
||||
return !(hadErrors || errorFilter.hadError());
|
||||
}
|
||||
|
||||
/**
|
||||
* convert an array of {@link InputSource InputSource} into an
|
||||
* array of {@link Source Source}
|
||||
*
|
||||
* @param schemas array of {@link InputSource InputSource}
|
||||
* @return array of {@link Source Source}
|
||||
*/
|
||||
private static Source[] getSchemaSource(InputSource[] schemas, EntityResolver entityResolver) throws SAXException {
|
||||
SAXSource[] sources = new SAXSource[schemas.length];
|
||||
for (int i = 0; i < schemas.length; i++) {
|
||||
sources[i] = new SAXSource(schemas[i]);
|
||||
// sources[i].getXMLReader().setEntityResolver(entityResolver);
|
||||
}
|
||||
return sources;
|
||||
}
|
||||
|
||||
// quick test
|
||||
public static void main(String[] args) throws IOException {
|
||||
InputSource[] sources = new InputSource[args.length];
|
||||
for (int i = 0; i < args.length; i++)
|
||||
sources[i] = new InputSource(new File(args[i]).toURL().toExternalForm());
|
||||
|
||||
check(sources, new ConsoleErrorReporter(), null, true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.parser;
|
||||
|
||||
import com.sun.tools.internal.xjc.reader.internalizer.AbstractReferenceFinderImpl;
|
||||
import com.sun.tools.internal.xjc.reader.internalizer.DOMForest;
|
||||
import com.sun.tools.internal.xjc.reader.internalizer.InternalizationLogic;
|
||||
import com.sun.tools.internal.xjc.util.DOMUtils;
|
||||
import com.sun.xml.internal.bind.v2.WellKnownNamespace;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.helpers.XMLFilterImpl;
|
||||
|
||||
/**
|
||||
* XML Schema specific internalization logic.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public class XMLSchemaInternalizationLogic implements InternalizationLogic {
|
||||
|
||||
/**
|
||||
* This filter looks for <xs:import> and <xs:include>
|
||||
* and parses those documents referenced by them.
|
||||
*/
|
||||
private static final class ReferenceFinder extends AbstractReferenceFinderImpl {
|
||||
ReferenceFinder( DOMForest parent ) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
protected String findExternalResource( String nsURI, String localName, Attributes atts) {
|
||||
if( WellKnownNamespace.XML_SCHEMA.equals(nsURI)
|
||||
&& ("import".equals(localName) || "include".equals(localName) ) )
|
||||
return atts.getValue("schemaLocation");
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public XMLFilterImpl createExternalReferenceFinder(DOMForest parent) {
|
||||
return new ReferenceFinder(parent);
|
||||
}
|
||||
|
||||
public boolean checkIfValidTargetNode(DOMForest parent, Element bindings, Element target) {
|
||||
return WellKnownNamespace.XML_SCHEMA.equals(target.getNamespaceURI());
|
||||
}
|
||||
|
||||
public Element refineTarget(Element target) {
|
||||
// look for existing xs:annotation
|
||||
Element annotation = DOMUtils.getFirstChildElement(target, WellKnownNamespace.XML_SCHEMA, "annotation");
|
||||
if(annotation==null)
|
||||
// none exists. need to make one
|
||||
annotation = insertXMLSchemaElement( target, "annotation" );
|
||||
|
||||
// then look for appinfo
|
||||
Element appinfo = DOMUtils.getFirstChildElement(annotation, WellKnownNamespace.XML_SCHEMA, "appinfo" );
|
||||
if(appinfo==null)
|
||||
// none exists. need to make one
|
||||
appinfo = insertXMLSchemaElement( annotation, "appinfo" );
|
||||
|
||||
return appinfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new XML Schema element of the given local name
|
||||
* and insert it as the first child of the given parent node.
|
||||
*
|
||||
* @return
|
||||
* Newly create element.
|
||||
*/
|
||||
private Element insertXMLSchemaElement( Element parent, String localName ) {
|
||||
// use the same prefix as the parent node to avoid modifying
|
||||
// the namespace binding.
|
||||
String qname = parent.getTagName();
|
||||
int idx = qname.indexOf(':');
|
||||
if(idx==-1) qname = localName;
|
||||
else qname = qname.substring(0,idx+1)+localName;
|
||||
|
||||
Element child = parent.getOwnerDocument().createElementNS( WellKnownNamespace.XML_SCHEMA, qname );
|
||||
|
||||
NodeList children = parent.getChildNodes();
|
||||
|
||||
if( children.getLength()==0 )
|
||||
parent.appendChild(child);
|
||||
else
|
||||
parent.insertBefore( child, children.item(0) );
|
||||
|
||||
return child;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user