use of com.sun.tools.xjc.reader.xmlschema.bindinfo.BIConversion in project jaxb-ri by eclipse-ee4j.
the class SimpleTypeBuilder method bindToTypeSafeEnum.
/**
* 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 (// use the location of the simple type as the default
loc == null)
loc = type.getLocator();
if (className == null) {
// 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<pre>\n" + out.getBuffer() + "</pre>";
}
// build base type
refererStack.push(type.getSimpleBaseType());
TypeUse use = build(type.getSimpleBaseType());
refererStack.pop();
if (use.isCollection())
// can't bind a list to enum constant
return null;
// for now just ignore that case
CNonElement baseDt = use.getInfo();
if (baseDt instanceof CClassInfo)
// can't bind to an enum if the base is a class, since we don't have the value constrctor
return null;
// 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);
}
// recover from error
return null;
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);
}
use of com.sun.tools.xjc.reader.xmlschema.bindinfo.BIConversion in project jaxb-ri by eclipse-ee4j.
the class SimpleTypeBuilder method detectJavaTypeCustomization.
/**
* 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);
}
}
use of com.sun.tools.xjc.reader.xmlschema.bindinfo.BIConversion in project jaxb-ri by eclipse-ee4j.
the class SimpleTypeBuilder method checkRefererCustomization.
/**
* 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;
}
use of com.sun.tools.xjc.reader.xmlschema.bindinfo.BIConversion in project jaxb-ri by eclipse-ee4j.
the class SimpleTypeBuilder method find.
/**
* 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 {
// 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());
}
// 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 (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(type.getTargetNamespace())) {
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);
}
// 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.emptyMap(), getEnumMemberMode(), null);
if (r != null)
return r;
}
}
return (CNonElement) getClassSelector()._bindToClass(type, null, false);
}
Aggregations