All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.tools.xjc.reader.xmlschema.bindinfo.BIGlobalBinding Maven / Gradle / Ivy

There is a newer version: 4.0.5
Show newest version
/*
 * Copyright (c) 1997, 2022 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package com.sun.tools.xjc.reader.xmlschema.bindinfo;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import jakarta.xml.bind.annotation.XmlAttribute;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlEnumValue;
import jakarta.xml.bind.annotation.XmlRootElement;
import jakarta.xml.bind.annotation.XmlTransient;

import javax.xml.XMLConstants;
import javax.xml.namespace.QName;

import com.sun.codemodel.ClassType;
import com.sun.codemodel.JClassAlreadyExistsException;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JDefinedClass;
import com.sun.tools.xjc.ErrorReceiver;
import com.sun.tools.xjc.generator.bean.ImplStructureStrategy;
import static com.sun.tools.xjc.generator.bean.ImplStructureStrategy.BEAN_ONLY;
import com.sun.tools.xjc.model.Model;
import com.sun.tools.xjc.reader.Const;
import com.sun.tools.xjc.reader.Ring;
import com.sun.tools.xjc.reader.xmlschema.SimpleTypeBuilder;
import com.sun.tools.xjc.util.ReadOnlyAdapter;
import org.glassfish.jaxb.core.api.impl.NameConverter;
import com.sun.xml.xsom.XSDeclaration;
import com.sun.xml.xsom.XSSchemaSet;
import com.sun.xml.xsom.XSSimpleType;

/**
 * Global binding customization. The code is highly temporary.
 * 
 * 

* One of the information contained in a global customization * is the default binding for properties. This object contains a * BIProperty object to keep this information. * * @author * Kohsuke Kawaguchi ([email protected]) */ @XmlRootElement(name="globalBindings") public final class BIGlobalBinding extends AbstractDeclarationImpl { /** * Gets the name converter that will govern the {@code XML -> Java} * name conversion process for this compilation. * *

* The "underscoreBinding" customization will determine * the exact object returned from this method. The rest of XJC * should just use the NameConverter interface. * *

* Always non-null. */ @XmlTransient public NameConverter nameConverter = NameConverter.standard; // JAXB will use this property to set nameConverter @XmlAttribute void setUnderscoreBinding( UnderscoreBinding ub ) { nameConverter = ub.nc; } UnderscoreBinding getUnderscoreBinding() { throw new IllegalStateException(); // no need for this } public JDefinedClass getSuperClass() { if(superClass==null) return null; return superClass.getClazz(ClassType.CLASS); } public JDefinedClass getSuperInterface() { if(superInterface==null) return null; return superInterface.getClazz(ClassType.INTERFACE); } public BIProperty getDefaultProperty() { return defaultProperty; } public boolean isJavaNamingConventionEnabled() { return isJavaNamingConventionEnabled; } public BISerializable getSerializable() { return serializable; } public boolean isGenerateElementClass() { return generateElementClass; } public boolean isGenerateMixedExtensions() { return generateMixedExtensions; } public boolean isChoiceContentPropertyEnabled() { return choiceContentProperty; } public int getDefaultEnumMemberSizeCap() { return defaultEnumMemberSizeCap; } public boolean isSimpleMode() { return simpleMode!=null; } public boolean isRestrictionFreshType() { return treatRestrictionLikeNewType !=null; } public EnumMemberMode getEnumMemberMode() { return generateEnumMemberName; } public boolean isSimpleTypeSubstitution() { return simpleTypeSubstitution; } public ImplStructureStrategy getCodeGenerationStrategy() { return codeGenerationStrategy; } public LocalScoping getFlattenClasses() { return flattenClasses; } /** * Performs error check */ public void errorCheck() { ErrorReceiver er = Ring.get(ErrorReceiver.class); for (QName n : enumBaseTypes) { XSSchemaSet xs = Ring.get(XSSchemaSet.class); XSSimpleType st = xs.getSimpleType(n.getNamespaceURI(), n.getLocalPart()); if(st==null) { er.error(loc,Messages.ERR_UNDEFINED_SIMPLE_TYPE.format(n)); continue; } if(!SimpleTypeBuilder.canBeMappedToTypeSafeEnum(st)) { er.error(loc,Messages.ERR_CANNOT_BE_BOUND_TO_SIMPLETYPE.format(n)); continue; } } } private enum UnderscoreBinding { @XmlEnumValue("asWordSeparator") WORD_SEPARATOR(NameConverter.standard), @XmlEnumValue("asCharInWord") CHAR_IN_WORD(NameConverter.jaxrpcCompatible); final NameConverter nc; UnderscoreBinding(NameConverter nc) { this.nc = nc; } } /** * Returns true if the "isJavaNamingConventionEnabled" option is turned on. * * In this mode, the compiler is expected to apply XML-to-Java name * conversion algorithm even to names given by customizations. * * This method is intended to be called by other BIXXX classes. * The effect of this switch should be hidden inside this package. * IOW, the reader.xmlschema package shouldn't be aware of this switch. */ @XmlAttribute(name="enableJavaNamingConventions") /*package*/ boolean isJavaNamingConventionEnabled = true; /** * True to generate classes for every simple type. */ @XmlAttribute(name="mapSimpleTypeDef") boolean simpleTypeSubstitution = false; /** * Gets the default defaultProperty customization. */ @XmlTransient private BIProperty defaultProperty; /* Three properties used to construct a default property */ @XmlAttribute private boolean fixedAttributeAsConstantProperty = false; @XmlAttribute private CollectionTypeAttribute collectionType = new CollectionTypeAttribute(); @XmlAttribute void setGenerateIsSetMethod(boolean b) { optionalProperty = b ? OptionalPropertyMode.ISSET : OptionalPropertyMode.WRAPPER; } /** * Returns true if the compiler needs to generate type-safe enum * member names when enumeration values cannot be used as constant names. */ @XmlAttribute(name="typesafeEnumMemberName") EnumMemberMode generateEnumMemberName = EnumMemberMode.SKIP; /** * The code generation strategy. */ @XmlAttribute(name="generateValueClass") ImplStructureStrategy codeGenerationStrategy = BEAN_ONLY; /** * Set of datatype names. For a type-safe enum class * to be generated, the underlying XML datatype must be derived from * one of the types in this set. */ // default value is set in the post-init action @XmlAttribute(name="typesafeEnumBase") private Set enumBaseTypes; /** * Returns {@link BISerializable} if the extension is specified, * or null otherwise. */ @XmlElement private BISerializable serializable = null; /** * If {@code } extension is specified, * returns the specified root class. Otherwise null. */ @XmlElement(namespace=Const.XJC_EXTENSION_URI) ClassNameBean superClass = null; /** * If {@code } extension is specified, * returns the specified root class. Otherwise null. */ @XmlElement(namespace=Const.XJC_EXTENSION_URI) ClassNameBean superInterface = null; /** * Generate the simpler optimized code, but not necessarily * conforming to the spec. */ @XmlElement(name="simple",namespace=Const.XJC_EXTENSION_URI) String simpleMode = null; /** * Handles complex type restriction as if it were a new type. */ @XmlElement(name="treatRestrictionLikeNewType",namespace=Const.XJC_EXTENSION_URI) String treatRestrictionLikeNewType = null; /** * True to generate a class for elements by default. */ @XmlAttribute boolean generateElementClass = false; @XmlAttribute boolean generateMixedExtensions = false; @XmlElement(namespace=Const.XJC_EXTENSION_URI) Boolean generateElementProperty = null; @XmlAttribute(name="generateElementProperty") // for JAXB unmarshaller private void setGenerateElementPropertyStd(boolean value) { generateElementProperty = value; } @XmlAttribute boolean choiceContentProperty = false; @XmlAttribute OptionalPropertyMode optionalProperty = OptionalPropertyMode.WRAPPER; /** * Default cap to the number of constants in the enum. * We won't attempt to produce a type-safe enum by default * if there are more enumeration facets than specified in this field. */ @XmlAttribute(name="typesafeEnumMaxMembers") int defaultEnumMemberSizeCap = 256; /** * If true, interfaces/classes that are normally generated as a nested interface/class * will be generated into the package, allowing the generated classes to be flat. * * See Bug 4969415 for the motivation. */ @XmlAttribute(name="localScoping") LocalScoping flattenClasses = LocalScoping.NESTED; /** * Globally-defined conversion customizations. * * @see #setGlobalConversions */ @XmlTransient private final Map globalConversions = new HashMap<>(); // method for JAXB unmarshaller @XmlElement(name="javaType") private void setGlobalConversions(GlobalStandardConversion[] convs) { for (GlobalStandardConversion u : convs) { globalConversions.put(u.xmlType,u); } } @XmlElement(name="javaType",namespace=Const.XJC_EXTENSION_URI) private void setGlobalConversions2(GlobalVendorConversion[] convs) { for (GlobalVendorConversion u : convs) { globalConversions.put(u.xmlType,u); } } // // these customizations were valid in 1.0, but in 2.0 we don't // use them. OTOH, we don't want to issue an error for them, // so we just define a mapping and ignore the value. // @XmlElement(namespace=Const.XJC_EXTENSION_URI) String noMarshaller = null; @XmlElement(namespace=Const.XJC_EXTENSION_URI) String noUnmarshaller = null; @XmlElement(namespace=Const.XJC_EXTENSION_URI) String noValidator = null; @XmlElement(namespace=Const.XJC_EXTENSION_URI) String noValidatingUnmarshaller = null; @XmlElement(namespace=Const.XJC_EXTENSION_URI) TypeSubstitutionElement typeSubstitution = null; /** * Another 1.0 compatibility customization (but we accept it * and treat it as {@link #serializable}) */ @XmlElement(name="serializable",namespace=Const.XJC_EXTENSION_URI) void setXjcSerializable(BISerializable s) { this.serializable = s; } private static final class TypeSubstitutionElement { @XmlAttribute String type; } @Override public void onSetOwner() { super.onSetOwner(); // if one is given by options, use that NameConverter nc = Ring.get(Model.class).options.getNameConverter(); if(nc!=null) nameConverter = nc; } /** * Creates a bind info object with the default values */ public BIGlobalBinding() { } @Override public void setParent(BindInfo parent) { super.setParent(parent); // fill in the remaining default values if(enumBaseTypes==null) enumBaseTypes = Collections.singleton(new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI,"string")); this.defaultProperty = new BIProperty(getLocation(),null,null,null, collectionType, fixedAttributeAsConstantProperty, optionalProperty, generateElementProperty ); defaultProperty.setParent(parent); // don't forget to initialize the defaultProperty } /** * Moves global BIConversion to the right object. */ public void dispatchGlobalConversions( XSSchemaSet schema ) { // also set parent to the global conversions for( Map.Entry e : globalConversions.entrySet() ) { QName name = e.getKey(); BIConversion conv = e.getValue(); XSSimpleType st = schema.getSimpleType(name.getNamespaceURI(),name.getLocalPart()); if(st==null) { Ring.get(ErrorReceiver.class).error( getLocation(), Messages.ERR_UNDEFINED_SIMPLE_TYPE.format(name) ); continue; // abort } getBuilder().getOrCreateBindInfo(st).addDecl(conv); } } /** * Checks if the given XML Schema built-in type can be mapped to * a type-safe enum class. * */ public boolean canBeMappedToTypeSafeEnum( QName typeName ) { return enumBaseTypes.contains(typeName); } public boolean canBeMappedToTypeSafeEnum( String nsUri, String localName ) { return canBeMappedToTypeSafeEnum(new QName(nsUri,localName)); } public boolean canBeMappedToTypeSafeEnum( XSDeclaration decl ) { return canBeMappedToTypeSafeEnum( decl.getTargetNamespace(), decl.getName() ); } @Override public QName getName() { return NAME; } public static final QName NAME = new QName( Const.JAXB_NSURI, "globalBindings" ); /** * Used to unmarshal *

{@code
     * <[element] name="className" />
     * }
*/ static final class ClassNameBean { @XmlAttribute(required=true) String name; /** * Computed from {@link #name} on demand. */ @XmlTransient JDefinedClass clazz; JDefinedClass getClazz(ClassType t) { if (clazz != null) return clazz; try { JCodeModel codeModel = Ring.get(JCodeModel.class); clazz = codeModel._class(name, t); clazz.hide(); return clazz; } catch (JClassAlreadyExistsException e) { return e.getExistingClass(); } } } static final class ClassNameAdapter extends ReadOnlyAdapter { @Override public String unmarshal(ClassNameBean bean) throws Exception { return bean.name; } } /** * Global {@code }. */ static final class GlobalStandardConversion extends BIConversion.User { @XmlAttribute QName xmlType; @Override public boolean equals(Object obj) { if(obj instanceof GlobalStandardConversion) { return ((GlobalStandardConversion)obj).xmlType.equals(xmlType); } return false; } @Override public int hashCode() { int hash = 7; hash = 73 * hash + (this.xmlType != null ? this.xmlType.hashCode() : 0); return hash; } } /** * Global {@code }. */ static final class GlobalVendorConversion extends BIConversion.UserAdapter { @XmlAttribute QName xmlType; @Override public boolean equals(Object obj) { if(obj instanceof GlobalVendorConversion) { return ((GlobalVendorConversion)obj).xmlType.equals(xmlType); } return false; } @Override public int hashCode() { int hash = 7; hash = 73 * hash + (this.xmlType != null ? this.xmlType.hashCode() : 0); return hash; } } /* don't want to override equals to avoid overriding hashcode for this complex object, too */ public boolean isEqual(BIGlobalBinding b) { boolean equal = this.isJavaNamingConventionEnabled == b.isJavaNamingConventionEnabled && this.simpleTypeSubstitution == b.simpleTypeSubstitution && this.fixedAttributeAsConstantProperty == b.fixedAttributeAsConstantProperty && this.generateEnumMemberName == b.generateEnumMemberName && this.codeGenerationStrategy == b.codeGenerationStrategy && this.superClass == b.superClass && this.superInterface == b.superInterface && this.generateElementClass == b.generateElementClass && this.generateMixedExtensions == b.generateMixedExtensions && this.generateElementProperty == b.generateElementProperty && this.choiceContentProperty == b.choiceContentProperty && this.optionalProperty == b.optionalProperty && this.defaultEnumMemberSizeCap == b.defaultEnumMemberSizeCap && this.flattenClasses == b.flattenClasses; if (!equal) return false; return isEqual(this.nameConverter, b.nameConverter) && isEqual(this.noMarshaller, b.noMarshaller) && isEqual(this.noUnmarshaller, b.noUnmarshaller) && isEqual(this.noValidator, b.noValidator) && isEqual(this.noValidatingUnmarshaller, b.noValidatingUnmarshaller) && isEqual(this.serializable, b.serializable) && isEqual(this.typeSubstitution, b.typeSubstitution) && isEqual(this.simpleMode, b.simpleMode) && isEqual(this.enumBaseTypes, b.enumBaseTypes) && isEqual(this.treatRestrictionLikeNewType, b.treatRestrictionLikeNewType) && isEqual(this.globalConversions, b.globalConversions); } private boolean isEqual(Object a, Object b) { if (a != null) { return a.equals(b); } return (b == null); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy