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,50 @@
/*
* 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.dtd;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* @author Kohsuke Kawaguchi
*/
final class Block {
final boolean isOptional;
final boolean isRepeated;
/**
* {@link Element}s that belong to this block.
* <p>
* We want to preserve the order they are added, but we don't want
* dupliates.
*/
final Set<Element> elements = new LinkedHashSet<Element>();
Block(boolean optional, boolean repeated) {
isOptional = optional;
isRepeated = repeated;
}
}

View File

@@ -0,0 +1,314 @@
/*
* 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.dtd;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.xml.namespace.QName;
import com.sun.tools.internal.xjc.model.CBuiltinLeafInfo;
import com.sun.tools.internal.xjc.model.CClassInfo;
import com.sun.tools.internal.xjc.model.CElementPropertyInfo;
import static com.sun.tools.internal.xjc.model.CElementPropertyInfo.CollectionMode.*;
import com.sun.tools.internal.xjc.model.CPropertyInfo;
import com.sun.tools.internal.xjc.model.CReferencePropertyInfo;
import com.sun.tools.internal.xjc.model.CTypeRef;
import com.sun.tools.internal.xjc.model.CValuePropertyInfo;
import com.sun.tools.internal.xjc.model.TypeUse;
import com.sun.tools.internal.xjc.reader.dtd.bindinfo.BIConversion;
import com.sun.tools.internal.xjc.reader.dtd.bindinfo.BIElement;
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.dtdparser.DTDEventListener;
import org.xml.sax.Locator;
/**
* DTD Element.
*
* <p>
* This class extends {@link Term} to participate in the content model tree.
*
* <p>
* This class is repsonsible for binding the element.
*
* @author Kohsuke Kawaguchi
*/
final class Element extends Term implements Comparable<Element> {
/**
* Name of the element.
*/
final String name;
private final TDTDReader owner;
/**
* @see DTDEventListener#endContentModel(String, short)
*/
private short contentModelType;
private Term contentModel;
/**
* True if this element is referenced from another element.
*/
boolean isReferenced;
/**
* If this element maps to a class, that class representation.
* Otherwise null.
*/
private CClassInfo classInfo;
/**
* True if {@link #classInfo} field is computed.
*/
private boolean classInfoComputed;
/**
* List of attribute properties on this element
*/
final List<CPropertyInfo> attributes = new ArrayList<CPropertyInfo>();
/**
* Normalized blocks of the content model.
*/
private final List<Block> normalizedBlocks = new ArrayList<Block>();
/**
* True if this element needs to be a class.
*
* Currently, if an element is referenced from a construct like (A|B|C),
* we require those A,B, and C to be a class.
*/
private boolean mustBeClass;
/**
* The source location where this element is defined.
*/
private Locator locator;
public Element(TDTDReader owner,String name) {
this.owner = owner;
this.name = name;
}
void normalize(List<Block> r, boolean optional) {
Block o = new Block(optional,false);
o.elements.add(this);
r.add(o);
}
void addAllElements(Block b) {
b.elements.add(this);
}
boolean isOptional() {
return false;
}
boolean isRepeated() {
return false;
}
/**
* Define its content model.
*/
void define(short contentModelType, Term contentModel, Locator locator) {
assert this.contentModel==null; // may not be called twice
this.contentModelType = contentModelType;
this.contentModel = contentModel;
this.locator = locator;
contentModel.normalize(normalizedBlocks,false);
for( Block b : normalizedBlocks ) {
if(b.isRepeated || b.elements.size()>1) {
for( Element e : b.elements ) {
owner.getOrCreateElement(e.name).mustBeClass = true;
}
}
}
}
/**
* When this element is an PCDATA-only content model,
* returns the conversion for it. Otherwise the behavior is undefined.
*/
private TypeUse getConversion() {
assert contentModel == Term.EMPTY; // this is PCDATA-only element
BIElement e = owner.bindInfo.element(name);
if(e!=null) {
BIConversion conv = e.getConversion();
if(conv!=null)
return conv.getTransducer();
}
return CBuiltinLeafInfo.STRING;
}
/**
* Return null if this class is not bound to a class.
*/
CClassInfo getClassInfo() {
if(!classInfoComputed) {
classInfoComputed = true;
classInfo = calcClass();
}
return classInfo;
}
private CClassInfo calcClass() {
BIElement e = owner.bindInfo.element(name);
if(e==null) {
if(contentModelType!=DTDEventListener.CONTENT_MODEL_MIXED
|| !attributes.isEmpty()
|| mustBeClass)
return createDefaultClass();
if(contentModel!=Term.EMPTY) {
throw new UnsupportedOperationException("mixed content model not supported");
} else {
// just #PCDATA
if(isReferenced)
return null;
else
// if no one else is referencing, assumed to be the root.
return createDefaultClass();
}
} else {
return e.clazz;
}
}
private CClassInfo createDefaultClass() {
String className = owner.model.getNameConverter().toClassName(name);
QName tagName = new QName("",name);
return new CClassInfo(owner.model,owner.getTargetPackage(),className,locator,null,tagName,null,null/*TODO*/);
}
void bind() {
CClassInfo ci = getClassInfo();
assert ci!=null || attributes.isEmpty();
for( CPropertyInfo p : attributes )
ci.addProperty(p);
switch(contentModelType) {
case DTDEventListener.CONTENT_MODEL_ANY:
CReferencePropertyInfo rp = new CReferencePropertyInfo("Content",true,false,true,null,null/*TODO*/,locator, false, false, false);
rp.setWildcard(WildcardMode.SKIP);
ci.addProperty(rp);
return;
case DTDEventListener.CONTENT_MODEL_CHILDREN:
break; // handling follows
case DTDEventListener.CONTENT_MODEL_MIXED:
if(contentModel!=Term.EMPTY)
throw new UnsupportedOperationException("mixed content model unsupported yet");
if(ci!=null) {
// if this element is mapped to a class, just put one property
CValuePropertyInfo p = new CValuePropertyInfo("value", null,null/*TODO*/,locator,getConversion(),null);
ci.addProperty(p);
}
return;
case DTDEventListener.CONTENT_MODEL_EMPTY:
// no content model
assert ci!=null;
return;
}
// normalize
List<Block> n = new ArrayList<Block>();
contentModel.normalize(n,false);
{// check collision among Blocks
Set<String> names = new HashSet<String>();
boolean collision = false;
OUTER:
for( Block b : n )
for( Element e : b.elements )
if(!names.add(e.name)) {
collision = true;
break OUTER;
}
if(collision) {
// collapse all blocks into one
Block all = new Block(true,true);
for( Block b : n )
all.elements.addAll(b.elements);
n.clear();
n.add(all);
}
}
for( Block b : n ) {
CElementPropertyInfo p;
if(b.isRepeated || b.elements.size()>1) {
// collection
StringBuilder name = new StringBuilder();
for( Element e : b.elements ) {
if(name.length()>0)
name.append("Or");
name.append(owner.model.getNameConverter().toPropertyName(e.name));
}
p = new CElementPropertyInfo(name.toString(), REPEATED_ELEMENT, ID.NONE, null, null,null/*TODO*/, locator, !b.isOptional );
for( Element e : b.elements ) {
CClassInfo child = owner.getOrCreateElement(e.name).getClassInfo();
assert child!=null; // we are requiring them to be classes.
p.getTypes().add(new CTypeRef(child,new QName("",e.name),null,false,null));
}
} else {
// single property
String name = b.elements.iterator().next().name;
String propName = owner.model.getNameConverter().toPropertyName(name);
TypeUse refType;
Element ref = owner.getOrCreateElement(name);
if(ref.getClassInfo()!=null)
refType = ref.getClassInfo();
else {
refType = ref.getConversion().getInfo();
}
p = new CElementPropertyInfo(propName,
refType.isCollection()?REPEATED_VALUE:NOT_REPEATED, ID.NONE, null, null,null/*TODO*/, locator, !b.isOptional );
p.getTypes().add(new CTypeRef(refType.getInfo(),new QName("",name),null,false,null));
}
ci.addProperty(p);
}
}
public int compareTo(Element that) {
return this.name.compareTo(that.name);
}
}

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.dtd;
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);
}
public static final String ERR_NO_ROOT_ELEMENT = // arg:0
"TDTDReader.NoRootElement";
public static final String ERR_UNDEFINED_ELEMENT_IN_BINDINFO = // arg:1
"TDTDReader.UndefinedElementInBindInfo";
public static final String ERR_CONVERSION_FOR_NON_VALUE_ELEMENT = // arg:1
"TDTDReader.ConversionForNonValueElement";
public static final String ERR_CONTENT_PROPERTY_PARTICLE_MISMATCH = // arg:1
"TDTDReader.ContentProperty.ParticleMismatch";
public static final String ERR_CONTENT_PROPERTY_DECLARATION_TOO_SHORT = // arg:1
"TDTDReader.ContentProperty.DeclarationTooShort";
public static final String ERR_BINDINFO_NON_EXISTENT_ELEMENT_DECLARATION = // arg:1
"TDTDReader.BindInfo.NonExistentElementDeclaration";
public static final String ERR_BINDINFO_NON_EXISTENT_INTERFACE_MEMBER = // arg:1
"TDTDReader.BindInfo.NonExistentInterfaceMember";
}

View File

@@ -0,0 +1,138 @@
/*
* 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.dtd;
import java.util.ArrayList;
import java.util.List;
import com.sun.xml.internal.dtdparser.DTDEventListener;
/**
* @author Kohsuke Kawaguchi
*/
final class ModelGroup extends Term {
enum Kind {
CHOICE, SEQUENCE
}
Kind kind;
private final List<Term> terms = new ArrayList<Term>();
void normalize(List<Block> r, boolean optional) {
switch(kind) {
case SEQUENCE:
for( Term t : terms )
t.normalize(r,optional);
return;
case CHOICE:
Block b = new Block(isOptional()||optional,isRepeated());
addAllElements(b);
r.add(b);
return;
}
}
void addAllElements(Block b) {
for( Term t : terms )
t.addAllElements(b);
}
boolean isOptional() {
switch(kind) {
case SEQUENCE:
for( Term t : terms )
if(!t.isOptional())
return false;
return true;
case CHOICE:
for( Term t : terms )
if(t.isOptional())
return true;
return false;
default:
throw new IllegalArgumentException();
}
}
boolean isRepeated() {
switch(kind) {
case SEQUENCE:
return true;
case CHOICE:
for( Term t : terms )
if(t.isRepeated())
return true;
return false;
default:
throw new IllegalArgumentException();
}
}
void setKind(short connectorType) {
Kind k;
switch(connectorType) {
case DTDEventListener.SEQUENCE:
k = Kind.SEQUENCE;
break;
case DTDEventListener.CHOICE:
k = Kind.CHOICE;
break;
default:
throw new IllegalArgumentException();
}
assert kind==null || k==kind;
kind = k;
}
void addTerm(Term t) {
if (t instanceof ModelGroup) {
ModelGroup mg = (ModelGroup) t;
if(mg.kind==this.kind) {
terms.addAll(mg.terms);
return;
}
}
terms.add(t);
}
Term wrapUp() {
switch(terms.size()) {
case 0:
return EMPTY;
case 1:
assert kind==null;
return terms.get(0);
default:
assert kind!=null;
return this;
}
}
}

View File

@@ -0,0 +1,83 @@
/*
* 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.dtd;
import java.util.List;
import com.sun.xml.internal.dtdparser.DTDEventListener;
/**
* @author Kohsuke Kawaguchi
*/
final class Occurence extends Term {
final Term term;
final boolean isOptional;
final boolean isRepeated;
Occurence(Term term, boolean optional, boolean repeated) {
this.term = term;
isOptional = optional;
isRepeated = repeated;
}
static Term wrap( Term t, int occurence ) {
switch(occurence) {
case DTDEventListener.OCCURENCE_ONCE:
return t;
case DTDEventListener.OCCURENCE_ONE_OR_MORE:
return new Occurence(t,false,true);
case DTDEventListener.OCCURENCE_ZERO_OR_MORE:
return new Occurence(t,true,true);
case DTDEventListener.OCCURENCE_ZERO_OR_ONE:
return new Occurence(t,true,false);
default:
throw new IllegalArgumentException();
}
}
void normalize(List<Block> r, boolean optional) {
if(isRepeated) {
Block b = new Block(isOptional||optional,true);
addAllElements(b);
r.add(b);
} else {
term.normalize(r,optional||isOptional);
}
}
void addAllElements(Block b) {
term.addAllElements(b);
}
boolean isOptional() {
return isOptional||term.isOptional();
}
boolean isRepeated() {
return isRepeated||term.isRepeated();
}
}

View File

@@ -0,0 +1,463 @@
/*
* 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.dtd;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import javax.xml.namespace.QName;
import com.sun.codemodel.internal.JClass;
import com.sun.codemodel.internal.JCodeModel;
import com.sun.codemodel.internal.JDefinedClass;
import com.sun.codemodel.internal.JPackage;
import com.sun.tools.internal.xjc.AbortException;
import com.sun.tools.internal.xjc.ErrorReceiver;
import com.sun.tools.internal.xjc.Options;
import com.sun.tools.internal.xjc.model.CAttributePropertyInfo;
import com.sun.tools.internal.xjc.model.CBuiltinLeafInfo;
import com.sun.tools.internal.xjc.model.CClassInfo;
import com.sun.tools.internal.xjc.model.CPropertyInfo;
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.model.CDefaultValue;
import com.sun.tools.internal.xjc.reader.ModelChecker;
import com.sun.tools.internal.xjc.reader.Ring;
import com.sun.tools.internal.xjc.reader.dtd.bindinfo.BIAttribute;
import com.sun.tools.internal.xjc.reader.dtd.bindinfo.BIElement;
import com.sun.tools.internal.xjc.reader.dtd.bindinfo.BIInterface;
import com.sun.tools.internal.xjc.reader.dtd.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.dtdparser.DTDHandlerBase;
import com.sun.xml.internal.dtdparser.DTDParser;
import com.sun.xml.internal.dtdparser.InputEntity;
import com.sun.xml.internal.xsom.XmlString;
import com.sun.istack.internal.SAXParseException2;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.LocatorImpl;
/**
* Parses DTD grammar along with binding information into BGM.
*
* @author
* <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
*/
public class TDTDReader extends DTDHandlerBase
{
/**
* Parses DTD grammar and a binding information into BGM.
*
* <p>
* This method is just a utility method that covers 80% of the use
* cases.
*
* @param bindingInfo
* binding information file, if any. Can be null.
*/
public static Model parse(
InputSource dtd,
InputSource bindingInfo,
ErrorReceiver errorReceiver,
Options opts) {
try {
// set up a ring
final Ring old = Ring.begin();
try {
ErrorReceiverFilter ef = new ErrorReceiverFilter(errorReceiver);
JCodeModel cm = new JCodeModel();
Model model = new Model(opts,cm,NameConverter.standard,opts.classNameAllocator,null);
Ring.add(cm);
Ring.add(model);
Ring.add(ErrorReceiver.class,ef);
TDTDReader reader = new TDTDReader( ef, opts, bindingInfo);
DTDParser parser = new DTDParser();
parser.setDtdHandler(reader);
if( opts.entityResolver!=null )
parser.setEntityResolver(opts.entityResolver);
try {
parser.parse(dtd);
} catch (SAXParseException e) {
return null; // this error was already handled by GrammarReaderController
}
Ring.get(ModelChecker.class).check();
if(ef.hadError()) return null;
else return model;
} finally {
Ring.end(old);
}
} catch (IOException e) {
errorReceiver.error(new SAXParseException2(e.getMessage(),null,e));
return null;
} catch (SAXException e) {
errorReceiver.error(new SAXParseException2(e.getMessage(),null,e));
return null;
} catch (AbortException e) {
// parsing was aborted but the error was already reported
return null;
}
}
protected TDTDReader(ErrorReceiver errorReceiver, Options opts, InputSource _bindInfo)
throws AbortException {
this.entityResolver = opts.entityResolver;
this.errorReceiver = new ErrorReceiverFilter(errorReceiver);
bindInfo = new BindInfo(model,_bindInfo, this.errorReceiver);
classFactory = new CodeModelClassFactory(errorReceiver);
}
private final EntityResolver entityResolver;
/**
* binding information.
*
* <p>
* This is always non-null even if no binding information was specified.
* (In that case, a dummy object will be provided.)
*/
final BindInfo bindInfo;
final Model model = Ring.get(Model.class);
private final CodeModelClassFactory classFactory;
private final ErrorReceiverFilter errorReceiver;
/**
* Element name to its content model definition.
*/
private final Map<String,Element> elements = new HashMap<String,Element>();
public void startDTD(InputEntity entity) throws SAXException {
}
public void endDTD() throws SAXException {
// bind them all.
// we need to know how elements are referencing each other before we do this,
// so this can be only done at the endDTD method
for( Element e : elements.values() )
e.bind();
// if there was an error by now, just abort.
if (errorReceiver.hadError())
return;
processInterfaceDeclarations();
// check XJC extensions and realize them
model.serialVersionUID = bindInfo.getSerialVersionUID();
if(model.serialVersionUID!=null)
model.serializable=true;
model.rootClass = bindInfo.getSuperClass();
model.rootInterface = bindInfo.getSuperInterface();
// TODO: do we need to reimplement them?
// // performs annotation
// Annotator.annotate(model, this);
// FieldCollisionChecker.check( model, this );
processConstructorDeclarations();
}
/** Processes interface declarations. */
private void processInterfaceDeclarations() {
Map<String,InterfaceAcceptor> fromName = new HashMap<String,InterfaceAcceptor>();
// first, create empty InterfaceItem declaration for all interfaces
Map<BIInterface,JClass> decls = new HashMap<BIInterface,JClass>();
for( BIInterface decl : bindInfo.interfaces() ) {
final JDefinedClass intf = classFactory.createInterface(
bindInfo.getTargetPackage(), decl.name(), copyLocator() );
decls.put(decl,intf);
fromName.put(decl.name(),new InterfaceAcceptor() {
public void implement(JClass c) {
intf._implements(c);
}
});
}
for( final CClassInfo ci : model.beans().values() ) {
fromName.put(ci.getName(),new InterfaceAcceptor() {
public void implement(JClass c) {
ci._implements(c);
}
});
}
// traverse the interface declarations again
// and populate its expression according to the members attribute.
for( Map.Entry<BIInterface,JClass> e : decls.entrySet() ) {
BIInterface decl = e.getKey();
JClass c = e.getValue();
for (String member : decl.members()) {
InterfaceAcceptor acc = fromName.get(member);
if (acc == null) {
// there is no such class/interface
// TODO: error location
error(decl.getSourceLocation(),
Messages.ERR_BINDINFO_NON_EXISTENT_INTERFACE_MEMBER,
member);
continue;
}
acc.implement(c);
}
}
// TODO: check the cyclic interface definition
}
private static interface InterfaceAcceptor {
void implement( JClass c );
}
JPackage getTargetPackage() {
return bindInfo.getTargetPackage();
}
/**
* Creates constructor declarations as specified in the
* binding information.
*
* <p>
* Also checks that the binding file does not contain
* declarations for non-existent elements.
*/
private void processConstructorDeclarations() {
for( BIElement decl: bindInfo.elements() ) {
Element e = elements.get(decl.name());
if(e==null) {
error(decl.getSourceLocation(),
Messages.ERR_BINDINFO_NON_EXISTENT_ELEMENT_DECLARATION,decl.name());
continue; // continue to process next declaration
}
if(!decl.isClass())
// only element-class declaration has constructor definitions
continue;
decl.declareConstructors(e.getClassInfo());
}
}
public void attributeDecl(String elementName, String attributeName, String attributeType, String[] enumeration, short attributeUse, String defaultValue) throws SAXException {
getOrCreateElement(elementName).attributes.add(
createAttribute(elementName, attributeName, attributeType, enumeration, attributeUse, defaultValue)
);
}
protected CPropertyInfo createAttribute(
String elementName, String attributeName, String attributeType,
String[] enums, short attributeUse, String defaultValue )
throws SAXException {
boolean required = attributeUse==USE_REQUIRED;
// get the attribute-property declaration
BIElement edecl = bindInfo.element(elementName);
BIAttribute decl=null;
if(edecl!=null) decl=edecl.attribute(attributeName);
String propName;
if(decl==null) propName = model.getNameConverter().toPropertyName(attributeName);
else propName = decl.getPropertyName();
QName qname = new QName("",attributeName);
// if no declaration is specified, just wrap it by
// a FieldItem and let the normalizer handle its content.
TypeUse use;
if(decl!=null && decl.getConversion()!=null)
use = decl.getConversion().getTransducer();
else
use = builtinConversions.get(attributeType);
CPropertyInfo r = new CAttributePropertyInfo(
propName, null,null/*TODO*/, copyLocator(), qname, use, null, required );
if(defaultValue!=null)
r.defaultValue = CDefaultValue.create( use, new XmlString(defaultValue) );
return r;
}
Element getOrCreateElement( String elementName ) {
Element r = elements.get(elementName);
if(r==null) {
r = new Element(this,elementName);
elements.put(elementName,r);
}
return r;
}
public void startContentModel(String elementName, short contentModelType) throws SAXException {
assert modelGroups.isEmpty();
modelGroups.push(new ModelGroup());
}
public void endContentModel(String elementName, short contentModelType) throws SAXException {
assert modelGroups.size()==1;
Term term = modelGroups.pop().wrapUp();
Element e = getOrCreateElement(elementName);
e.define( contentModelType, term, copyLocator() );
}
private final Stack<ModelGroup> modelGroups = new Stack<ModelGroup>();
public void startModelGroup() throws SAXException {
modelGroups.push(new ModelGroup());
}
public void endModelGroup(short occurence) throws SAXException {
Term t = Occurence.wrap( modelGroups.pop().wrapUp(), occurence );
modelGroups.peek().addTerm(t);
}
public void connector(short connectorType) throws SAXException {
modelGroups.peek().setKind(connectorType);
}
// TODO: for now, we just ignore all the content model specification
// and treat it as (A,B,C,....)
public void childElement(String elementName, short occurence) throws SAXException {
Element child = getOrCreateElement(elementName);
modelGroups.peek().addTerm( Occurence.wrap( child, occurence ) );
child.isReferenced = true;
}
/**
* Mutable {@link Locator} instance that points to
* the current source line.
* <p>
* Use {@link #copyLocator()} to get a immutable clone.
*/
private Locator locator;
public void setDocumentLocator(Locator loc) {
this.locator = loc;
}
/**
* Creates a snapshot of the current {@link #locator} values.
*/
private Locator copyLocator(){
return new LocatorImpl(locator);
}
//
//
// builtin datatype handling
//
//
/** Transducers for the built-in types. Read-only. */
private static final Map<String,TypeUse> builtinConversions;
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 = new HashMap<String,TypeUse>();
m.put("CDATA", CBuiltinLeafInfo.NORMALIZED_STRING);
m.put("ENTITY", CBuiltinLeafInfo.TOKEN);
m.put("ENTITIES", CBuiltinLeafInfo.STRING.makeCollection());
m.put("NMTOKEN", CBuiltinLeafInfo.TOKEN);
m.put("NMTOKENS", CBuiltinLeafInfo.STRING.makeCollection());
m.put("ID", CBuiltinLeafInfo.ID);
m.put("IDREF", CBuiltinLeafInfo.IDREF);
m.put("IDREFS", TypeUseFactory.makeCollection(CBuiltinLeafInfo.IDREF));
m.put("ENUMERATION",CBuiltinLeafInfo.TOKEN);
builtinConversions = Collections.unmodifiableMap(m);
}
//
//
// error related utility methods
//
//
public void error(SAXParseException e) throws SAXException {
errorReceiver.error(e);
}
public void fatalError(SAXParseException e) throws SAXException {
errorReceiver.fatalError(e);
}
public void warning(SAXParseException e) throws SAXException {
errorReceiver.warning(e);
}
protected final void error( Locator loc, String prop, Object... args ) {
errorReceiver.error(loc,Messages.format(prop,args));
}
}

View File

@@ -0,0 +1,62 @@
/*
* 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.dtd;
import java.util.List;
/**
* @author Kohsuke Kawaguchi
*/
abstract class Term {
abstract void normalize( List<Block> r, boolean optional );
abstract void addAllElements(Block b);
abstract boolean isOptional();
abstract boolean isRepeated();
/**
* Represents empty term.
* <p>
* This special term is only used to represent #PCDATA-only content model.
*/
static final Term EMPTY = new Term() {
void normalize(List<Block> r, boolean optional) {
}
void addAllElements(Block b) {
}
boolean isOptional() {
return false;
}
boolean isRepeated() {
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.dtd.bindinfo;
import java.util.ArrayList;
import com.sun.tools.internal.xjc.generator.bean.field.FieldRenderer;
import com.sun.tools.internal.xjc.generator.bean.field.FieldRendererFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
/** &lt;attribute> declaration in the binding file. */
public class BIAttribute
{
/**
* Wraps a given &lt;attribute> element.
* <p>
* Should be created only from {@link BIElement}.
*/
BIAttribute( BIElement _parent, Element _e ) {
this.parent = _parent;
this.element = _e;
}
private final BIElement parent;
private final Element element;
/** Gets the name of this attribute-property declaration. */
public final String name() {
return element.getAttribute("name");
}
/**
* Gets the conversion method for this attribute, if any.
*
* @return
* If the convert attribute is not specified, this
* method returns null.
*/
public BIConversion getConversion() {
if (element.getAttributeNode("convert") == null)
return null;
String cnv = element.getAttribute("convert");
return parent.conversion(cnv);
}
/**
* Gets the realization of this particle, if any.
*
* @return
* null if the "collection" attribute was not specified.
*/
public final FieldRenderer getRealization() {
Attr a = element.getAttributeNode("collection");
if(a==null) return null;
String v = element.getAttribute("collection").trim();
FieldRendererFactory frf = parent.parent.model.options.getFieldRendererFactory();
if(v.equals("array")) return frf.getArray();
if(v.equals("list"))
return frf.getList(
parent.parent.codeModel.ref(ArrayList.class));
// the correctness of the attribute value must be
// checked by the validator.
throw new InternalError("unexpected collection value: "+v);
}
/**
* Gets the property name for this attribute.
*
* @return
* always a non-null, valid string.
*/
public final String getPropertyName() {
String r = DOMUtil.getAttribute(element,"property");
if(r!=null) return r;
else return name();
}
}

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.dtd.bindinfo;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import com.sun.tools.internal.xjc.model.CClassInfo;
import org.w3c.dom.Element;
import org.xml.sax.Locator;
/**
* &lt;constructor> declaration in the binding file.
*
* <p>
* Since JAXB will generate both interfaces and implementations,
* A constructor declaration will create:
*
* <ul>
* <li> a method declaration in the factory interface
* <li> a method implementation in the factory implementation class
* <li> a constructor implementation in the actual implementation class
* </ul>
*/
public class BIConstructor
{
BIConstructor( Element _node ) {
this.dom = _node;
StringTokenizer tokens = new StringTokenizer(
DOMUtil.getAttribute(_node,"properties"));
List<String> vec = new ArrayList<String>();
while(tokens.hasMoreTokens())
vec.add(tokens.nextToken());
properties = vec.toArray(new String[0]);
if( properties.length==0 )
throw new AssertionError("this error should be catched by the validator");
}
/** &lt;constructor> element in the source binding file. */
private final Element dom;
/** properties specified by @properties. */
private final String[] properties;
/**
* Creates a constructor declaration into the ClassItem.
*
* @param cls
* ClassItem object that corresponds to the
* element declaration that contains this declaration.
*/
public void createDeclaration( CClassInfo cls ) {
cls.addConstructor(properties);
}
/** Gets the location where this declaration is declared. */
public Locator getSourceLocation() {
return DOMLocator.getLocationInfo(dom);
}
}

View File

@@ -0,0 +1,138 @@
/*
* 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.dtd.bindinfo;
import java.util.ArrayList;
import com.sun.codemodel.internal.JClass;
import com.sun.tools.internal.xjc.Options;
import com.sun.tools.internal.xjc.generator.bean.field.FieldRenderer;
import org.w3c.dom.Element;
/**
* Particles in the &lt;content> declaration in the binding file.
*
*/
public class BIContent
{
/**
* Wraps a given particle.
*
* <p>
* This object should be created through
* the {@link #create(Element, BIElement)} method.
*/
private BIContent( Element e, BIElement _parent ) {
this.element = e;
this.parent = _parent;
this.opts = parent.parent.model.options;
}
/** The particle element which this object is wrapping. */
protected final Element element;
/** The parent object.*/
protected final BIElement parent;
private final Options opts;
/**
* Gets the realization of this particle, if any.
*
* @return
* null if the "collection" attribute was not specified.
*/
public final FieldRenderer getRealization() {
String v = DOMUtil.getAttribute(element,"collection");
if(v==null) return null;
v = v.trim();
if(v.equals("array")) return opts.getFieldRendererFactory().getArray();
if(v.equals("list"))
return opts.getFieldRendererFactory().getList(
parent.parent.codeModel.ref(ArrayList.class));
// the correctness of the attribute value must be
// checked by the validator.
throw new InternalError("unexpected collection value: "+v);
}
/**
* Gets the property name of this particle.
*
* @return
* always a non-null, valid string.
*/
public final String getPropertyName() {
String r = DOMUtil.getAttribute(element,"property");
// in case of <element-ref>, @property is optional and
// defaults to @name.
// in all other cases, @property is mandatory.
if(r!=null) return r;
return DOMUtil.getAttribute(element,"name");
}
/**
* Gets the type of this property, if any.
* <p>
* &lt;element-ref> particle doesn't have the type.
*
* @return
* null if none is specified.
*/
public final JClass getType() {
try {
String type = DOMUtil.getAttribute(element,"supertype");
if(type==null) return null;
// TODO: does this attribute defaults to the current package?
int idx = type.lastIndexOf('.');
if(idx<0) return parent.parent.codeModel.ref(type);
else return parent.parent.getTargetPackage().ref(type);
} catch( ClassNotFoundException e ) {
// TODO: better error handling
throw new NoClassDefFoundError(e.getMessage());
}
}
/**
* Creates an appropriate subclass of BIContent
* by sniffing the tag name.
* <p>
* This method should be only called by the BIElement class.
*/
static BIContent create( Element e, BIElement _parent ) {
return new BIContent(e,_parent);
}
}

View File

@@ -0,0 +1,40 @@
/*
* 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.dtd.bindinfo;
import com.sun.tools.internal.xjc.model.TypeUse;
/**
* conversion declaration (&lt;conversion> and &lt;enumeration>).
*/
public interface BIConversion
{
/** Gets the conversion name. */
String name();
/** Gets a transducer for this conversion. */
TypeUse getTransducer();
}

View File

@@ -0,0 +1,273 @@
/*
* 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.dtd.bindinfo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.namespace.QName;
import com.sun.tools.internal.xjc.model.CClassInfo;
import com.sun.xml.internal.bind.api.impl.NameConverter;
import org.w3c.dom.Element;
import org.xml.sax.Locator;
/**
* &lt;element> declaration in the binding file.
*/
public final class BIElement
{
/**
* Wraps a given &lt;element> element in the binding file.
*
* <p>
* Should be created only from {@link BindInfo}.
*/
BIElement( BindInfo bi, Element _e ) {
this.parent = bi;
this.e = _e;
{
Element c = DOMUtil.getElement(e,"content");
if(c!=null) {
if(DOMUtil.getAttribute(c,"property")!=null) {
// if @property is there, this is a general declaration
this.rest = BIContent.create(c,this);
} else {
// this must be a model-based declaration
for( Element p : DOMUtil.getChildElements(c) ) {
if(p.getLocalName().equals("rest"))
this.rest = BIContent.create(p,this);
else
this.contents.add(BIContent.create(p,this));
}
}
}
}
// parse <attribute>s
for( Element atr : DOMUtil.getChildElements(e,"attribute") ) {
BIAttribute a = new BIAttribute( this, atr );
attributes.put(a.name(),a);
}
if(isClass()) {
// if this is a class-declaration, create JClass object now
String className = DOMUtil.getAttribute(e,"class");
if(className==null)
// none was specified. infer the name.
className = NameConverter.standard.toClassName(name());
this.className = className;
} else {
// this is not an element-class declaration
className = null;
}
// process conversion declarations
for( Element conv : DOMUtil.getChildElements(e,"conversion") ) {
BIConversion c = new BIUserConversion(bi,conv);
conversions.put(c.name(),c);
}
for( Element en : DOMUtil.getChildElements(e,"enumeration") ) {
BIConversion c = BIEnumeration.create(en,this);
conversions.put(c.name(),c);
}
// parse <constructor>s
for( Element c : DOMUtil.getChildElements(e,"constructor") ) {
constructors.add( new BIConstructor(c) );
}
String name = name();
QName tagName = new QName("",name);
this.clazz = new CClassInfo(parent.model,parent.getTargetPackage(),className,getLocation(),null,tagName,null,null/*TODO*/);
}
/**
* Gets the source location where this element is declared.
*/
public Locator getLocation() {
return DOMLocator.getLocationInfo(e);
}
/** The parent {@link BindInfo} object to which this object belongs. */
final BindInfo parent;
/** &lt;element> element which this object is wrapping. */
private final Element e;
/**
* The bean representation for this element.
*/
public final CClassInfo clazz;
/**
* Content-property declarations.
* <p>
* This vector will be empty if no content-property declaration is made.
*/
private final List<BIContent> contents = new ArrayList<BIContent>();
/** Conversion declarations. */
private final Map<String,BIConversion> conversions = new HashMap<String,BIConversion>();
/**
* The "rest" content-property declaration.
* <p>
* This field is null when there was no "rest" declaration.
*/
private BIContent rest;
/** Attribute-property declarations. */
private final Map<String,BIAttribute> attributes = new HashMap<String,BIAttribute>();
/** Constructor declarations. */
private final List<BIConstructor> constructors = new ArrayList<BIConstructor>();
/**
* the class which is generated by this declaration.
* This field will be null if this declaration is an element-property
* declaration.
*/
private final String className;
/** Gets the element name. */
public String name() { return DOMUtil.getAttribute(e,"name"); }
/**
* Checks if the element type is "class".
* If false, that means this element will be a value.
*/
public boolean isClass() {
return "class".equals(e.getAttribute("type"));
}
/**
* Checks if this element is designated as a root element.
*/
public boolean isRoot() {
return "true".equals(e.getAttribute("root"));
}
/**
* Gets the JClass object that represents this declaration.
*
* <p>
* This method returns null if this declaration
* is an element-property declaration.
*/
public String getClassName() {
return className;
}
/**
* Creates constructor declarations for this element.
*
* <p>
* This method should only be called by DTDReader <b>after</b>
* the normalization has completed.
*
* @param src
* The ClassItem object that corresponds to this declaration
*/
public void declareConstructors( CClassInfo src ) {
for( BIConstructor c : constructors )
c.createDeclaration(src);
}
/**
* Gets the conversion method for this element.
*
* <p>
* This method can be called only when this element
* declaration is designated as element-value.
*
* @return
* If the convert attribute is not specified, this
* method returns null.
*/
public BIConversion getConversion() {
String cnv = DOMUtil.getAttribute(e,"convert");
if(cnv==null) return null;
return conversion(cnv);
}
/**
* Resolves the conversion name to the conversion declaration.
*
* <p>
* Element-local declarations are checked first.
*
* @return
* A non-null valid BIConversion object.
*/
public BIConversion conversion( String name ) {
BIConversion r = conversions.get(name);
if(r!=null) return r;
// check the global conversion declarations
return parent.conversion(name);
}
/**
* Iterates all content-property declarations (except 'rest').
*/
public List<BIContent> getContents() {
return contents;
}
/**
* Gets the attribute-property declaration, if any.
*
* @return
* null if attribute declaration was not given by that name.
*/
public BIAttribute attribute( String name ) {
return attributes.get(name);
}
/**
* Gets the 'rest' content-property declaration, if any.
* @return
* if there is no 'rest' declaration, return null.
*/
public BIContent getRest() { return this.rest; }
/** Gets the location where this declaration is declared. */
public Locator getSourceLocation() {
return DOMLocator.getLocationInfo(e);
}
}

View File

@@ -0,0 +1,112 @@
/*
* 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.dtd.bindinfo;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import com.sun.tools.internal.xjc.model.CBuiltinLeafInfo;
import com.sun.tools.internal.xjc.model.CClassInfoParent;
import com.sun.tools.internal.xjc.model.CEnumConstant;
import com.sun.tools.internal.xjc.model.CEnumLeafInfo;
import com.sun.tools.internal.xjc.model.Model;
import com.sun.tools.internal.xjc.model.TypeUse;
import org.w3c.dom.Element;
/**
* &lt;enumeration> declaration in the binding file.
*/
public final class BIEnumeration implements BIConversion
{
/** Creates an object from &lt;enumeration> declaration. */
private BIEnumeration( Element _e, TypeUse _xducer ) {
this.e = _e;
this.xducer = _xducer;
}
/** &lt;enumeration> element in DOM. */
private final Element e;
private final TypeUse xducer;
public String name() { return DOMUtil.getAttribute(e,"name"); }
/** Returns a transducer for this enumeration declaration. */
public TypeUse getTransducer() { return xducer; }
/** Creates a global enumeration declaration. */
static BIEnumeration create( Element dom, BindInfo parent ) {
// create a class in the target package.
return new BIEnumeration(
dom,
new CEnumLeafInfo(
parent.model,
null,
new CClassInfoParent.Package(parent.getTargetPackage()),
DOMUtil.getAttribute(dom,"name"),
CBuiltinLeafInfo.STRING,
buildMemberList(parent.model,dom),
null, null/*TODO*/,
DOMLocator.getLocationInfo(dom)));
}
/** Creates an element-local enumeration declaration. */
static BIEnumeration create( Element dom, BIElement parent ) {
// create a class as a nested class
return new BIEnumeration(
dom,
new CEnumLeafInfo(
parent.parent.model,
null,
parent.clazz,
DOMUtil.getAttribute(dom,"name"),
CBuiltinLeafInfo.STRING,
buildMemberList(parent.parent.model,dom),
null, null/*TODO*/,
DOMLocator.getLocationInfo(dom) ));
}
private static List<CEnumConstant> buildMemberList( Model model, Element dom ) {
List<CEnumConstant> r = new ArrayList<CEnumConstant>();
String members = DOMUtil.getAttribute(dom,"members");
if(members==null) members=""; // TODO: error handling
StringTokenizer tokens = new StringTokenizer(members);
while(tokens.hasMoreTokens()) {
String token = tokens.nextToken();
r.add(new CEnumConstant(model.getNameConverter().toConstantName(token),
null,token,null/*TODO*/,null,null));
}
return r;
}
}

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.dtd.bindinfo;
import java.util.StringTokenizer;
import org.w3c.dom.Element;
import org.xml.sax.Locator;
/**
* &lt;interface> declaration in the binding file.
*/
public final class BIInterface
{
BIInterface( Element e ) {
this.dom = e;
name = DOMUtil.getAttribute(e,"name");
members = parseTokens(DOMUtil.getAttribute(e,"members"));
if(DOMUtil.getAttribute(e,"properties")!=null) {
fields = parseTokens(DOMUtil.getAttribute(e,"properties"));
throw new AssertionError("//interface/@properties is not supported");
} else // no property was specified
fields = new String[0];
}
/** &lt;interface> element in the binding file. */
private final Element dom;
/** Name of the generated Java interface. */
private final String name;
/**
* Gets the name of this interface.
* This name should also used as the class name.
*/
public String name() { return name; }
private final String[] members;
/**
* Gets the names of interfaces/classes that implement
* this interface.
*/
public String[] members() { return members; }
private final String[] fields;
/** Gets the names of fields in this interface. */
public String[] fields() { return fields; }
/** Gets the location where this declaration is declared. */
public Locator getSourceLocation() {
return DOMLocator.getLocationInfo(dom);
}
/** splits a list into an array of strings. */
private static String[] parseTokens( String value ) {
StringTokenizer tokens = new StringTokenizer(value);
String[] r = new String[tokens.countTokens()];
int i=0;
while(tokens.hasMoreTokens())
r[i++] = tokens.nextToken();
return r;
}
}

View File

@@ -0,0 +1,227 @@
/*
* 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.dtd.bindinfo;
import java.io.IOException;
import java.io.StringReader;
import java.util.Map;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
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.JPrimitiveType;
import com.sun.codemodel.internal.JType;
import com.sun.codemodel.internal.JVar;
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.xml.internal.bind.v2.util.XmlFactory;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
/**
* &lt;conversion> declaration in the binding file.
* This declaration declares a conversion by user-specified methods.
*/
public class BIUserConversion implements BIConversion
{
/**
* Wraps a given &lt;conversion> element in the binding file.
*/
BIUserConversion( BindInfo bi, Element _e ) {
this.owner = bi;
this.e = _e;
}
private static void add( Map<String,BIConversion> m, BIConversion c ) {
m.put( c.name(), c );
}
/** Adds all built-in conversions into the given map. */
static void addBuiltinConversions( BindInfo bi, Map<String,BIConversion> m ) {
add( m, new BIUserConversion( bi, parse("<conversion name='boolean' type='java.lang.Boolean' parse='getBoolean' />")));
add( m, new BIUserConversion( bi, parse("<conversion name='byte' type='java.lang.Byte' parse='parseByte' />")));
add( m, new BIUserConversion( bi, parse("<conversion name='short' type='java.lang.Short' parse='parseShort' />")));
add( m, new BIUserConversion( bi, parse("<conversion name='int' type='java.lang.Integer' parse='parseInt' />")));
add( m, new BIUserConversion( bi, parse("<conversion name='long' type='java.lang.Long' parse='parseLong' />")));
add( m, new BIUserConversion( bi, parse("<conversion name='float' type='java.lang.Float' parse='parseFloat' />")));
add( m, new BIUserConversion( bi, parse("<conversion name='double' type='java.lang.Double' parse='parseDouble' />")));
}
private static Element parse(String text) {
try {
//this is parsing well known schemas, do not configure secure processing - always true
DocumentBuilderFactory dbf = XmlFactory.createDocumentBuilderFactory(false);
InputSource is = new InputSource(new StringReader(text));
return dbf.newDocumentBuilder().parse(is).getDocumentElement();
} catch (SAXException x) {
throw new Error(x);
} catch (IOException x) {
throw new Error(x);
} catch (ParserConfigurationException x) {
throw new Error(x);
}
}
/** The owner {@link BindInfo} object to which this object belongs. */
private final BindInfo owner;
/** &lt;conversion> element which this object is wrapping. */
private final Element e;
/** Gets the location where this declaration is declared. */
public Locator getSourceLocation() {
return DOMLocator.getLocationInfo(e);
}
/** Gets the conversion name. */
public String name() { return DOMUtil.getAttribute(e,"name"); }
/** Gets a transducer for this conversion. */
public TypeUse getTransducer() {
String ws = DOMUtil.getAttribute(e,"whitespace");
if(ws==null) ws = "collapse";
String type = DOMUtil.getAttribute(e,"type");
if(type==null) type=name();
JType t=null;
int idx = type.lastIndexOf('.');
if(idx<0) {
// no package name is specified.
try {
t = JPrimitiveType.parse(owner.codeModel,type);
} catch( IllegalArgumentException ex ) {
// otherwise treat it as a class name in the current package
type = owner.getTargetPackage().name()+'.'+type;
}
}
if(t==null) {
try {
// TODO: revisit this later
JDefinedClass cls = owner.codeModel._class(type);
cls.hide();
t = cls;
} catch( JClassAlreadyExistsException ex ) {
t = ex.getExistingClass();
}
}
String parse = DOMUtil.getAttribute(e,"parse");
if(parse==null) parse="new";
String print = DOMUtil.getAttribute(e,"print");
if(print==null) print="toString";
JDefinedClass adapter = generateAdapter(owner.codeModel, parse, print, t.boxify());
// XmlJavaType customization always converts between string and an user-defined type.
return TypeUseFactory.adapt(CBuiltinLeafInfo.STRING,new CAdapter(adapter));
}
// TODO: anyway to reuse this code between XML Schema compiler?
private JDefinedClass generateAdapter(JCodeModel cm, String parseMethod, String printMethod, JClass inMemoryType) {
JDefinedClass adapter = null;
int id = 1;
while(adapter==null) {
try {
JPackage pkg = owner.getTargetPackage();
adapter = pkg._class("Adapter"+id);
} catch (JClassAlreadyExistsException ex) {
// 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++;
}
}
adapter._extends(cm.ref(XmlAdapter.class).narrow(String.class).narrow(inMemoryType));
JMethod unmarshal = adapter.method(JMod.PUBLIC, inMemoryType, "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(inMemoryType).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 = inMemoryType.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(inMemoryType,"value");
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);
} else {
// RESULT: <className>.<method>(<value>)
inv = JExpr.direct(printMethod+"(value)");
}
marshal.body()._return(inv);
return adapter;
}
}

View File

@@ -0,0 +1,334 @@
/*
* 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.dtd.bindinfo;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.validation.ValidatorHandler;
import com.sun.codemodel.internal.ClassType;
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.JPackage;
import com.sun.istack.internal.SAXParseException2;
import com.sun.tools.internal.xjc.AbortException;
import com.sun.tools.internal.xjc.ErrorReceiver;
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.Const;
import com.sun.tools.internal.xjc.util.CodeModelClassFactory;
import com.sun.tools.internal.xjc.util.ErrorReceiverFilter;
import com.sun.tools.internal.xjc.util.ForkContentHandler;
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.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
/**
* Root of the binding information.
*/
public class BindInfo
{
/** Controller object that can be used to report errors. */
protected final ErrorReceiver errorReceiver;
/*package*/ final Model model;
/**
* The -p option that should control the default Java package that
* will contain the generated code. Null if unspecified. This takes
* precedence over the value specified in the binding file.
*/
private final String defaultPackage;
public BindInfo(Model model, InputSource source, ErrorReceiver _errorReceiver) throws AbortException {
this( model, parse(model,source,_errorReceiver), _errorReceiver);
}
public BindInfo(Model model, Document _dom, ErrorReceiver _errorReceiver) {
this.model = model;
this.dom = _dom.getDocumentElement();
this.codeModel = model.codeModel;
this.errorReceiver = _errorReceiver;
this.classFactory = new CodeModelClassFactory(_errorReceiver);
// TODO: decide name converter from the binding file
this.defaultPackage = model.options.defaultPackage;
// copy global customizations to the model
model.getCustomizations().addAll(getGlobalCustomizations());
// process element declarations
for( Element ele : DOMUtil.getChildElements(dom,"element")) {
BIElement e = new BIElement(this,ele);
elements.put(e.name(),e);
}
// add built-in conversions
BIUserConversion.addBuiltinConversions(this,conversions);
// process conversion declarations
for( Element cnv : DOMUtil.getChildElements(dom,"conversion")) {
BIConversion c = new BIUserConversion(this,cnv);
conversions.put(c.name(),c);
}
for( Element en : DOMUtil.getChildElements(dom,"enumeration")) {
BIConversion c = BIEnumeration.create( en, this );
conversions.put(c.name(),c);
}
// TODO: check the uniquness of conversion name
// process interface definitions
for( Element itf : DOMUtil.getChildElements(dom,"interface")) {
BIInterface c = new BIInterface(itf);
interfaces.put(c.name(),c);
}
}
/** CodeModel object that is used by this binding file. */
final JCodeModel codeModel;
/** Wrap the codeModel object and automate error reporting. */
final CodeModelClassFactory classFactory;
/** DOM tree that represents binding info. */
private final Element dom;
/** Conversion declarations. */
private final Map<String,BIConversion> conversions = new HashMap<String,BIConversion>();
/** Element declarations keyed by names. */
private final Map<String,BIElement> elements = new HashMap<String,BIElement>();
/** interface declarations keyed by names. */
private final Map<String,BIInterface> interfaces = new HashMap<String,BIInterface>();
/** XJC extension namespace. */
private static final String XJC_NS = Const.XJC_EXTENSION_URI;
//
//
// Exposed public methods
//
//
/** Gets the serialVersionUID if it's turned on. */
public Long getSerialVersionUID() {
Element serial = DOMUtil.getElement(dom,XJC_NS,"serializable");
if(serial==null) return null;
String v = DOMUtil.getAttribute(serial,"uid");
if(v==null) v="1";
return new Long(v);
}
/** Gets the xjc:superClass customization if it's turned on. */
public JClass getSuperClass() {
Element sc = DOMUtil.getElement(dom,XJC_NS,"superClass");
if (sc == null) return null;
JDefinedClass c;
try {
String v = DOMUtil.getAttribute(sc,"name");
if(v==null) return null;
c = codeModel._class(v);
c.hide();
} catch (JClassAlreadyExistsException e) {
c = e.getExistingClass();
}
return c;
}
/** Gets the xjc:superInterface customization if it's turned on. */
public JClass getSuperInterface() {
Element sc = DOMUtil.getElement(dom,XJC_NS,"superInterface");
if (sc == null) return null;
String name = DOMUtil.getAttribute(sc,"name");
if (name == null) return null;
JDefinedClass c;
try {
c = codeModel._class(name, ClassType.INTERFACE);
c.hide();
} catch (JClassAlreadyExistsException e) {
c = e.getExistingClass();
}
return c;
}
/**
* Gets the specified package name (options/@package).
*/
public JPackage getTargetPackage() {
if(model.options.defaultPackage!=null)
// "-p" takes precedence over everything else
return codeModel._package(model.options.defaultPackage);
String p;
if( defaultPackage!=null )
p = defaultPackage;
else
p = getOption("package", "");
return codeModel._package(p);
}
/**
* Gets the conversion declaration from the binding info.
*
* @return
* A non-null valid BIConversion object.
*/
public BIConversion conversion(String name) {
BIConversion r = conversions.get(name);
if (r == null)
throw new AssertionError("undefined conversion name: this should be checked by the validator before we read it");
return r;
}
/**
* Gets the element declaration from the binding info.
*
* @return
* If there is no declaration with a given name,
* this method returns null.
*/
public BIElement element( String name ) {
return elements.get(name);
}
/** Iterates all {@link BIElement}s in a read-only set. */
public Collection<BIElement> elements() {
return elements.values();
}
/** Returns all {@link BIInterface}s in a read-only set. */
public Collection<BIInterface> interfaces() {
return interfaces.values();
}
/**
* Gets the list of top-level {@link CPluginCustomization}s.
*/
private CCustomizations getGlobalCustomizations() {
CCustomizations r=null;
for( Element e : DOMUtil.getChildElements(dom) ) {
if(!model.options.pluginURIs.contains(e.getNamespaceURI()))
continue; // this isn't a plugin customization
if(r==null)
r = new CCustomizations();
r.add(new CPluginCustomization(e, DOMLocator.getLocationInfo(e)));
}
if(r==null) r = CCustomizations.EMPTY;
return new CCustomizations(r);
}
//
//
// Internal utility methods
//
//
/** Gets the value from the option element. */
private String getOption(String attName, String defaultValue) {
Element opt = DOMUtil.getElement(dom,"options");
if (opt != null) {
String s = DOMUtil.getAttribute(opt,attName);
if (s != null)
return s;
}
return defaultValue;
}
/**
* Lazily parsed schema for the binding file.
*/
private static SchemaCache bindingFileSchema = new SchemaCache(BindInfo.class.getResource("bindingfile.xsd"));
/**
* Parses an InputSource into dom4j Document.
* Returns null in case of an exception.
*/
private static Document parse( Model model, InputSource is, ErrorReceiver receiver ) throws AbortException {
try {
ValidatorHandler validator = bindingFileSchema.newValidator();
// set up the pipe line as :
// /-> extensionChecker -> validator
// parser-> -<
// \-> DOM builder
SAXParserFactory pf = XmlFactory.createParserFactory(model.options.disableXmlSecurity);
DocumentBuilderFactory domFactory = XmlFactory.createDocumentBuilderFactory(model.options.disableXmlSecurity);
DOMBuilder builder = new DOMBuilder(domFactory);
ErrorReceiverFilter controller = new ErrorReceiverFilter(receiver);
validator.setErrorHandler(controller);
XMLReader reader = pf.newSAXParser().getXMLReader();
reader.setErrorHandler(controller);
DTDExtensionBindingChecker checker = new DTDExtensionBindingChecker("", model.options, controller);
checker.setContentHandler(validator);
reader.setContentHandler(new ForkContentHandler(checker,builder));
reader.parse(is);
if(controller.hadError()) throw new AbortException();
return (Document)builder.getDOM();
} catch( IOException e ) {
receiver.error( new SAXParseException2(e.getMessage(),null,e) );
} catch( SAXException e ) {
receiver.error( new SAXParseException2(e.getMessage(),null,e) );
} catch( ParserConfigurationException e ) {
receiver.error( new SAXParseException2(e.getMessage(),null,e) );
}
throw new AbortException();
}
}

View File

@@ -0,0 +1,57 @@
/*
* 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.dtd.bindinfo;
import javax.xml.parsers.ParserConfigurationException;
import com.sun.xml.internal.bind.marshaller.SAX2DOMEx;
import javax.xml.parsers.DocumentBuilderFactory;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
/**
* @author Kohsuke Kawaguchi
*/
final class DOMBuilder extends SAX2DOMEx {
private Locator locator;
public DOMBuilder(DocumentBuilderFactory f) throws ParserConfigurationException {
super(f);
}
@Override
public void setDocumentLocator(Locator locator) {
super.setDocumentLocator(locator);
this.locator = locator;
}
@Override
public void startElement(String namespace, String localName, String qName, Attributes attrs) {
super.startElement(namespace, localName, qName, attrs);
DOMLocator.setLocationInfo(getCurrentElement(),locator);
}
}

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.dtd.bindinfo;
import org.w3c.dom.Element;
import org.xml.sax.Locator;
class DOMLocator {
private static final String locationNamespace =
"http://www.sun.com/xmlns/jaxb/dom-location";
private static final String systemId = "systemid";
private static final String column = "column";
private static final String line = "line";
/** Sets the location information to a specified element. */
public static void setLocationInfo( Element e, Locator loc ) {
e.setAttributeNS(locationNamespace,"loc:"+systemId,loc.getSystemId());
e.setAttributeNS(locationNamespace,"loc:"+column,Integer.toString(loc.getLineNumber()));
e.setAttributeNS(locationNamespace,"loc:"+line,Integer.toString(loc.getColumnNumber()));
}
/**
* Gets the location information from an element.
*
* <p>
* For this method to work, the setLocationInfo method has to be
* called before.
*/
public static Locator getLocationInfo( final Element e ) {
if(DOMUtil.getAttribute(e,locationNamespace,systemId)==null)
return null; // no location information
return new Locator(){
public int getLineNumber() {
return Integer.parseInt(DOMUtil.getAttribute(e,locationNamespace,line));
}
public int getColumnNumber() {
return Integer.parseInt(DOMUtil.getAttribute(e,locationNamespace,column));
}
public String getSystemId() {
return DOMUtil.getAttribute(e,locationNamespace,systemId);
}
// we are not interested in PUBLIC ID.
public String getPublicId() { return null; }
};
}
}

View File

@@ -0,0 +1,108 @@
/*
* 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.dtd.bindinfo;
import java.util.ArrayList;
import java.util.List;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* @author Kohsuke Kawaguchi
*/
public final class DOMUtil {
final static String getAttribute(Element e,String attName) {
if(e.getAttributeNode(attName)==null) return null;
return e.getAttribute(attName);
}
public static String getAttribute(Element e, String nsUri, String local) {
if(e.getAttributeNodeNS(nsUri,local)==null) return null;
return e.getAttributeNS(nsUri,local);
}
public static Element getElement(Element e, String nsUri, String localName) {
NodeList l = e.getChildNodes();
for(int i=0;i<l.getLength();i++) {
Node n = l.item(i);
if(n.getNodeType()==Node.ELEMENT_NODE) {
Element r = (Element)n;
if(equals(r.getLocalName(),localName) && equals(fixNull(r.getNamespaceURI()),nsUri))
return r;
}
}
return null;
}
/**
* Used for defensive string comparisons, as many DOM methods often return null
* depending on how they are created.
*/
private static boolean equals(String a,String b) {
if(a==b) return true;
if(a==null || b==null) return false;
return a.equals(b);
}
/**
* DOM API returns null for the default namespace whereas it should return "".
*/
private static String fixNull(String s) {
if(s==null) return "";
else return s;
}
public static Element getElement(Element e, String localName) {
return getElement(e,"",localName);
}
public static List<Element> getChildElements(Element e) {
List<Element> r = new ArrayList<Element>();
NodeList l = e.getChildNodes();
for(int i=0;i<l.getLength();i++) {
Node n = l.item(i);
if(n.getNodeType()==Node.ELEMENT_NODE)
r.add((Element)n);
}
return r;
}
public static List<Element> getChildElements(Element e,String localName) {
List<Element> r = new ArrayList<Element>();
NodeList l = e.getChildNodes();
for(int i=0;i<l.getLength();i++) {
Node n = l.item(i);
if(n.getNodeType()==Node.ELEMENT_NODE) {
Element c = (Element)n;
if(c.getLocalName().equals(localName))
r.add(c);
}
}
return r;
}
}

View File

@@ -0,0 +1,89 @@
/*
* 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.dtd.bindinfo;
import com.sun.tools.internal.xjc.Options;
import com.sun.tools.internal.xjc.reader.AbstractExtensionBindingChecker;
import com.sun.tools.internal.xjc.reader.Const;
import org.xml.sax.Attributes;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.XMLFilter;
/**
* {@link XMLFilter} that checks the use of extension namespace URIs
* (to see if they have corresponding plugins), and otherwise report an error.
*
* <p>
* This code also masks the recognized extensions from the validator that
* will be plugged as the next component to this.
*
* @author Kohsuke Kawaguchi
*/
final class DTDExtensionBindingChecker extends AbstractExtensionBindingChecker {
public DTDExtensionBindingChecker(String schemaLanguage, Options options, ErrorHandler handler) {
super(schemaLanguage, options, handler);
}
/**
* Returns true if the elements with the given namespace URI
* should be blocked by this filter.
*/
private boolean needsToBePruned( String uri ) {
if( uri.equals(schemaLanguage) )
return false;
if( uri.equals(Const.JAXB_NSURI) )
return false;
if( uri.equals(Const.XJC_EXTENSION_URI) )
return false;
// we don't want validator to see extensions that we understand ,
// because they will complain.
// OTOH, if this is an extension that we didn't understand,
// we want the validator to report an error
return enabledExtensions.contains(uri);
}
public void startElement(String uri, String localName, String qName, Attributes atts)
throws SAXException {
if( !isCutting() ) {
if(!uri.equals("")) {
// "" is the standard namespace
checkAndEnable(uri);
verifyTagName(uri, localName, qName);
if(needsToBePruned(uri))
startCutting();
}
}
super.startElement(uri, localName, qName, atts);
}
}

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.dtd.bindinfo;
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_UNDEFINED_FIELD = // arg:1
"BIConstructor.UndefinedField";
}