feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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> {
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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 &lt;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;
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
// }
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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";
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}

View File

@@ -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 &lt;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" };
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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" );
}

View File

@@ -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 &lt;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;
}
}
}

View File

@@ -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();
}

View File

@@ -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");
}

View File

@@ -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 &lt;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;
}
}

View File

@@ -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" );
}

View File

@@ -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");
}

View File

@@ -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 &lt;xjc:superClass> extension is specified,
* returns the specified root class. Otherwise null.
*/
@XmlElement(namespace=Const.XJC_EXTENSION_URI)
ClassNameBean superClass = null;
/**
* If &lt;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 &lt;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 &lt;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);
}
}

View File

@@ -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");
}

View File

@@ -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;
}
}

View File

@@ -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
* &lt;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" );
}

View File

@@ -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;
}

View File

@@ -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 &lt;xjc:dom> as &lt;jaxb:dom>.
*
* @author Kohsuke Kawaguchi
*/
@XmlRootElement(name="dom",namespace=Const.XJC_EXTENSION_URI)
public class BIXDom extends BIDom {
// unsupported yet
@XmlAttribute
String type = "w3c";
}

View File

@@ -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;
}
}

View File

@@ -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");
}

View File

@@ -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 &lt;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 &lt;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"));
}

View File

@@ -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));
}
}

View File

@@ -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);
}
}
}

View File

@@ -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 &lt;jaxb:enum> customization.
*/
public EnumMemberMode getModeWithEnum() {
if(this==SKIP) return ERROR;
return this;
}
}

View File

@@ -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);
}
}

View File

@@ -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
}

View File

@@ -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);
}
}

View File

@@ -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
}

View File

@@ -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;

View File

@@ -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()));
}
}

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -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");
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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 );
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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));
}
}
}

View File

@@ -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);
}
}

View File

@@ -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 &lt;jaxb:property> customization is given under
* the &lt;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 &lt;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 &lt;xs:simpleType>
* element, and for complex types they are allowed only under the
* &lt;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;
}
}

View File

@@ -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;
}
}

View File

@@ -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
}
}

View File

@@ -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";
}

View File

@@ -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);
}
}

View File

@@ -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 &lt;xs:import> and &lt;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;
}
}