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

com.sun.tools.xjc.generator.bean.BeanGenerator Maven / Gradle / Ivy

Go to download

Old JAXB Binding Compiler. Contains source code needed for binding customization files into java sources. In other words: the *tool* to generate java classes for the given xml representation.

There is a newer version: 4.0.5
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 * 
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License. You can obtain
 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
 * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
 * Sun designates this particular file as subject to the "Classpath" exception
 * as provided by Sun in the GPL Version 2 section of the License file that
 * accompanied this code.  If applicable, add the following below the License
 * Header, with the fields enclosed by brackets [] replaced by your own
 * identifying information: "Portions Copyrighted [year]
 * [name of copyright owner]"
 * 
 * Contributor(s):
 * 
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package com.sun.tools.xjc.generator.bean;

import static com.sun.tools.xjc.outline.Aspect.EXPOSED;

import java.io.Serializable;
import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.XmlAttachmentRef;
import javax.xml.bind.annotation.XmlID;
import javax.xml.bind.annotation.XmlIDREF;
import javax.xml.bind.annotation.XmlMimeType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.namespace.QName;

import com.sun.codemodel.ClassType;
import com.sun.codemodel.JAnnotatable;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JClassAlreadyExistsException;
import com.sun.codemodel.JClassContainer;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JEnumConstant;
import com.sun.codemodel.JExpr;
import com.sun.codemodel.JExpression;
import com.sun.codemodel.JFieldVar;
import com.sun.codemodel.JForEach;
import com.sun.codemodel.JInvocation;
import com.sun.codemodel.JJavaName;
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JMod;
import com.sun.codemodel.JPackage;
import com.sun.codemodel.JType;
import com.sun.codemodel.JVar;
import com.sun.codemodel.fmt.JStaticJavaFile;
import com.sun.tools.xjc.AbortException;
import com.sun.tools.xjc.ErrorReceiver;
import com.sun.tools.xjc.api.SpecVersion;
import com.sun.tools.xjc.generator.annotation.spec.XmlAnyAttributeWriter;
import com.sun.tools.xjc.generator.annotation.spec.XmlEnumValueWriter;
import com.sun.tools.xjc.generator.annotation.spec.XmlEnumWriter;
import com.sun.tools.xjc.generator.annotation.spec.XmlJavaTypeAdapterWriter;
import com.sun.tools.xjc.generator.annotation.spec.XmlMimeTypeWriter;
import com.sun.tools.xjc.generator.annotation.spec.XmlRootElementWriter;
import com.sun.tools.xjc.generator.annotation.spec.XmlSeeAlsoWriter;
import com.sun.tools.xjc.generator.annotation.spec.XmlTypeWriter;
import com.sun.tools.xjc.generator.bean.field.FieldRenderer;
import com.sun.tools.xjc.model.CAdapter;
import com.sun.tools.xjc.model.CAttributePropertyInfo;
import com.sun.tools.xjc.model.CClassInfo;
import com.sun.tools.xjc.model.CClassInfoParent;
import com.sun.tools.xjc.model.CElementInfo;
import com.sun.tools.xjc.model.CEnumConstant;
import com.sun.tools.xjc.model.CEnumLeafInfo;
import com.sun.tools.xjc.model.CPropertyInfo;
import com.sun.tools.xjc.model.CTypeRef;
import com.sun.tools.xjc.model.Model;
import com.sun.tools.xjc.model.CClassRef;
import com.sun.tools.xjc.outline.Aspect;
import com.sun.tools.xjc.outline.ClassOutline;
import com.sun.tools.xjc.outline.EnumConstantOutline;
import com.sun.tools.xjc.outline.EnumOutline;
import com.sun.tools.xjc.outline.FieldOutline;
import com.sun.tools.xjc.outline.Outline;
import com.sun.tools.xjc.outline.PackageOutline;
import com.sun.tools.xjc.util.CodeModelClassFactory;
import com.sun.xml.bind.v2.model.core.PropertyInfo;
import com.sun.xml.bind.v2.runtime.SwaRefAdapter;
import com.sun.xml.xsom.XmlString;
import com.sun.istack.NotNull;
import com.sun.tools.xjc.model.CReferencePropertyInfo;

/**
 * Generates fields and accessors.
 */
public final class BeanGenerator implements Outline
{
    /** Simplifies class/interface creation and collision detection. */
    private final CodeModelClassFactory codeModelClassFactory;
    
    private final ErrorReceiver errorReceiver;

    /** all {@link PackageOutline}s keyed by their {@link PackageOutline#_package}. */
    private final Map packageContexts = new HashMap();
    
    /** all {@link ClassOutline}s keyed by their {@link ClassOutline#target}. */
    private final Map classes = new HashMap();

    /** all {@link EnumOutline}s keyed by their {@link EnumOutline#target}. */
    private final Map enums = new HashMap();

    /**
     * Generated runtime classes.
     */
    private final Map generatedRuntime = new HashMap();

    /** the model object which we are processing. */
    private final Model model;
    
    private final JCodeModel codeModel;

    /**
     * for each property, the information about the generated field.
     */
    private final Map fields = new HashMap();

    /**
     * elements that generate classes to the generated classes.
     */
    /*package*/ final Map elements = new HashMap();



    /**
     * Generates beans into code model according to the BGM,
     * and produces the reflection model.
     * 
     * @param _errorReceiver
     *      This object will receive all the errors discovered
     *      during the back-end stage.
     *
     * @return
     *      returns a {@link Outline} which will in turn
     *      be used to further generate marshaller/unmarshaller,
     *      or null if the processing fails (errors should have been
     *      reported to the error recevier.)
     */
    public static Outline generate(Model model, ErrorReceiver _errorReceiver) {
        
        try {
            return new BeanGenerator(model, _errorReceiver);
        } catch( AbortException e ) {
            return null;
        }
    }
    
    
    private BeanGenerator(Model _model, ErrorReceiver _errorReceiver) {

        this.model = _model;
        this.codeModel = model.codeModel;
        this.errorReceiver = _errorReceiver;
        this.codeModelClassFactory = new CodeModelClassFactory(errorReceiver);

        // build enum classes
        for( CEnumLeafInfo p : model.enums().values() )
            enums.put( p, generateEnumDef(p) );

        JPackage[] packages = getUsedPackages(EXPOSED);

        // generates per-package code and remember the results as contexts.
        for( JPackage pkg : packages )
            getPackageContext(pkg);

        // create the class definitions for all the beans first.
        // this should also fill in PackageContext#getClasses
        for( CClassInfo bean : model.beans().values() )
            getClazz(bean);

        // compute the package-level setting
        for (PackageOutlineImpl p : packageContexts.values())
            p.calcDefaultValues();

        JClass OBJECT = codeModel.ref(Object.class);

        // inheritance relationship needs to be set before we generate fields, or otherwise
        // we'll fail to compute the correct type signature (namely the common base type computation)
        for( ClassOutlineImpl cc : getClasses() ) {

            // setup inheritance between implementation hierarchy.
            CClassInfo superClass = cc.target.getBaseClass();
            if(superClass!=null) {
                // use the specified super class
                model.strategy._extends(cc,getClazz(superClass));
            } else {
                CClassRef refSuperClass = cc.target.getRefBaseClass();
                if(refSuperClass!=null) {
                    cc.implClass._extends(refSuperClass.toType(this,EXPOSED));
                } else {
                    // use the default one, if any
                    if( model.rootClass!=null && cc.implClass._extends().equals(OBJECT) )
                        cc.implClass._extends(model.rootClass);
                    if( model.rootInterface!=null)
                        cc.ref._implements(model.rootInterface);
                }
            }
        }

        // fill in implementation classes
        for( ClassOutlineImpl co : getClasses() )
            generateClassBody(co);

        for( EnumOutline eo : enums.values() )
            generateEnumBody(eo);

        // create factories for the impl-less elements
        for( CElementInfo ei : model.getAllElements())
            getPackageContext(ei._package()).objectFactoryGenerator().populate(ei);

        if(model.options.debugMode)
            generateClassList();
    }

    /**
     * Generates a class that knows how to create an instance of JAXBContext
     *
     * 

* This is used in the debug mode so that a new properly configured * {@link JAXBContext} object can be used. */ private void generateClassList() { try { JDefinedClass jc = codeModel.rootPackage()._class("JAXBDebug"); JMethod m = jc.method(JMod.PUBLIC|JMod.STATIC,JAXBContext.class,"createContext"); JVar $classLoader = m.param(ClassLoader.class,"classLoader"); m._throws(JAXBException.class); JInvocation inv = codeModel.ref(JAXBContext.class).staticInvoke("newInstance"); m.body()._return(inv); switch(model.strategy) { case INTF_AND_IMPL: { StringBuilder buf = new StringBuilder(); for( PackageOutlineImpl po : packageContexts.values() ) { if(buf.length()>0) buf.append(':'); buf.append(po._package().name()); } inv.arg(buf.toString()).arg($classLoader); break; } case BEAN_ONLY: for( ClassOutlineImpl cc : getClasses() ) inv.arg(cc.implRef.dotclass()); for( PackageOutlineImpl po : packageContexts.values() ) inv.arg(po.objectFactory().dotclass()); break; default: throw new IllegalStateException(); } } catch (JClassAlreadyExistsException e) { e.printStackTrace(); // after all, we are in the debug mode. a little sloppiness is OK. // this error is not fatal. just continue. } } public Model getModel() { return model; } public JCodeModel getCodeModel() { return codeModel; } public JClassContainer getContainer(CClassInfoParent parent, Aspect aspect) { CClassInfoParent.Visitor v; switch(aspect) { case EXPOSED: v = exposedContainerBuilder; break; case IMPLEMENTATION: v = implContainerBuilder; break; default: assert false; throw new IllegalStateException(); } return parent.accept(v); } public final JType resolve(CTypeRef ref,Aspect a) { return ref.getTarget().getType().toType(this,a); } private final CClassInfoParent.Visitor exposedContainerBuilder = new CClassInfoParent.Visitor() { public JClassContainer onBean(CClassInfo bean) { return getClazz(bean).ref; } public JClassContainer onElement(CElementInfo element) { // hmm... return getElement(element).implClass; } public JClassContainer onPackage(JPackage pkg) { return model.strategy.getPackage(pkg, EXPOSED); } }; private final CClassInfoParent.Visitor implContainerBuilder = new CClassInfoParent.Visitor() { public JClassContainer onBean(CClassInfo bean) { return getClazz(bean).implClass; } public JClassContainer onElement(CElementInfo element) { return getElement(element).implClass; } public JClassContainer onPackage(JPackage pkg) { return model.strategy.getPackage(pkg,Aspect.IMPLEMENTATION); } }; /** * Returns all used JPackages. * * A JPackage is considered as "used" if a ClassItem or * a InterfaceItem resides in that package. * * This value is dynamically calculated every time because * one can freely remove ClassItem/InterfaceItem. * * @return * Given the same input, the order of packages in the array * is always the same regardless of the environment. */ public final JPackage[] getUsedPackages( Aspect aspect ) { Set s = new TreeSet(); for( CClassInfo bean : model.beans().values() ) { JClassContainer cont = getContainer(bean.parent(),aspect); if(cont.isPackage()) s.add( (JPackage)cont ); } for( CElementInfo e : model.getElementMappings(null).values() ) { // at the first glance you might think we should be iterating all elements, // not just global ones, but if you think about it, local ones live inside // another class, so those packages are already enumerated when we were // walking over CClassInfos. s.add( e._package() ); } return s.toArray(new JPackage[s.size()]); } public ErrorReceiver getErrorReceiver() { return errorReceiver; } public CodeModelClassFactory getClassFactory() { return codeModelClassFactory; } public PackageOutlineImpl getPackageContext( JPackage p ) { PackageOutlineImpl r = packageContexts.get(p); if(r==null) { r=new PackageOutlineImpl(this,model,p); packageContexts.put(p,r); } return r; } /** * Generates the minimum {@link JDefinedClass} skeleton * without filling in its body. */ private ClassOutlineImpl generateClassDef(CClassInfo bean) { ImplStructureStrategy.Result r = model.strategy.createClasses(this,bean); JClass implRef; if( bean.getUserSpecifiedImplClass()!=null ) { // create a place holder for a user-specified class. JDefinedClass usr; try { usr = codeModel._class(bean.getUserSpecifiedImplClass()); // but hide that file so that it won't be generated. usr.hide(); } catch( JClassAlreadyExistsException e ) { // it's OK for this to collide. usr = e.getExistingClass(); } usr._extends(r.implementation); implRef = usr; } else implRef = r.implementation; return new ClassOutlineImpl(this,bean,r.exposed,r.implementation,implRef); } public Collection getClasses() { // make sure that classes are fully populated assert model.beans().size()==classes.size(); return classes.values(); } public ClassOutlineImpl getClazz( CClassInfo bean ) { ClassOutlineImpl r = classes.get(bean); if(r==null) classes.put( bean, r=generateClassDef(bean) ); return r; } public ElementOutlineImpl getElement(CElementInfo ei) { ElementOutlineImpl def = elements.get(ei); if(def==null && ei.hasClass()) { // create one. in the constructor it adds itself to the elements. def = new ElementOutlineImpl(this,ei); } return def; } public EnumOutline getEnum(CEnumLeafInfo eli) { return enums.get(eli); } public Collection getEnums() { return enums.values(); } public Iterable getAllPackageContexts() { return packageContexts.values(); } public FieldOutline getField( CPropertyInfo prop ) { return fields.get(prop); } /** * Generates the body of a class. * */ private void generateClassBody( ClassOutlineImpl cc ) { CClassInfo target = cc.target; // if serialization support is turned on, generate // [RESULT] // class ... implements Serializable { // private static final long serialVersionUID = ; // .... // } if( model.serializable ) { cc.implClass._implements(Serializable.class); if( model.serialVersionUID!=null ) { cc.implClass.field( JMod.PRIVATE|JMod.STATIC|JMod.FINAL, codeModel.LONG, "serialVersionUID", JExpr.lit(model.serialVersionUID)); } } // used to simplify the generated annotations String mostUsedNamespaceURI = cc._package().getMostUsedNamespaceURI(); // [RESULT] // @XmlType(name="foo", targetNamespace="bar://baz") XmlTypeWriter xtw = cc.implClass.annotate2(XmlTypeWriter.class); writeTypeName(cc.target.getTypeName(), xtw, mostUsedNamespaceURI); if(model.options.target.isLaterThan(SpecVersion.V2_1)) { // @XmlSeeAlso Iterator subclasses = cc.target.listSubclasses(); if(subclasses.hasNext()) { XmlSeeAlsoWriter saw = cc.implClass.annotate2(XmlSeeAlsoWriter.class); while (subclasses.hasNext()) { CClassInfo s = subclasses.next(); saw.value(getClazz(s).implRef); } } } if(target.isElement()) { String namespaceURI = target.getElementName().getNamespaceURI(); String localPart = target.getElementName().getLocalPart(); // [RESULT] // @XmlRootElement(name="foo", targetNamespace="bar://baz") XmlRootElementWriter xrew = cc.implClass.annotate2(XmlRootElementWriter.class); xrew.name(localPart); if(!namespaceURI.equals(mostUsedNamespaceURI)) // only generate if necessary xrew.namespace(namespaceURI); } if(target.isOrdered()) { for(CPropertyInfo p : target.getProperties() ) { if( ! (p instanceof CAttributePropertyInfo )) { if (!( (p instanceof CReferencePropertyInfo) && ((CReferencePropertyInfo)p).isDummy())) { xtw.propOrder(p.getName(false)); } } } } else { // produce empty array xtw.getAnnotationUse().paramArray("propOrder"); } for( CPropertyInfo prop : target.getProperties() ) { generateFieldDecl(cc,prop); } if( target.declaresAttributeWildcard() ) { generateAttributeWildcard(cc); } // generate some class level javadoc cc.ref.javadoc().append(target.javadoc); cc._package().objectFactoryGenerator().populate(cc); } private void writeTypeName(QName typeName, XmlTypeWriter xtw, String mostUsedNamespaceURI) { if(typeName ==null) { xtw.name(""); } else { xtw.name(typeName.getLocalPart()); final String typeNameURI = typeName.getNamespaceURI(); if(!typeNameURI.equals(mostUsedNamespaceURI)) // only generate if necessary xtw.namespace(typeNameURI); } } /** * Generates an attribute wildcard property on a class. */ private void generateAttributeWildcard( ClassOutlineImpl cc ) { String FIELD_NAME = "otherAttributes"; String METHOD_SEED = model.getNameConverter().toClassName(FIELD_NAME); JClass mapType = codeModel.ref(Map.class).narrow(QName.class,String.class); JClass mapImpl = codeModel.ref(HashMap.class).narrow(QName.class,String.class); // [RESULT] // Map m = new HashMap(); JFieldVar $ref = cc.implClass.field(JMod.PRIVATE, mapType, FIELD_NAME, JExpr._new(mapImpl) ); $ref.annotate2(XmlAnyAttributeWriter.class); MethodWriter writer = cc.createMethodWriter(); JMethod $get = writer.declareMethod( mapType, "get"+METHOD_SEED ); $get.javadoc().append( "Gets a map that contains attributes that aren't bound to any typed property on this class.\n\n" + "

\n" + "the map is keyed by the name of the attribute and \n" + "the value is the string value of the attribute.\n" + "\n" + "the map returned by this method is live, and you can add new attribute\n" + "by updating the map directly. Because of this design, there's no setter.\n"); $get.javadoc().addReturn().append("always non-null"); $get.body()._return($ref); } /** * Generates the minimum {@link JDefinedClass} skeleton * without filling in its body. */ private EnumOutline generateEnumDef(CEnumLeafInfo e) { JDefinedClass type; type = getClassFactory().createClass( getContainer(e.parent, EXPOSED),e.shortName,e.getLocator(), ClassType.ENUM); type.javadoc().append(e.javadoc); return new EnumOutline(e, type) { @Override public @NotNull Outline parent() { return BeanGenerator.this; } }; } private void generateEnumBody(EnumOutline eo) { JDefinedClass type = eo.clazz; CEnumLeafInfo e = eo.target; XmlTypeWriter xtw = type.annotate2(XmlTypeWriter.class); writeTypeName(e.getTypeName(), xtw, eo._package().getMostUsedNamespaceURI()); JCodeModel codeModel = model.codeModel; // since constant values are never null, no point in using the boxed types. JType baseExposedType = e.base.toType(this, EXPOSED).unboxify(); JType baseImplType = e.base.toType(this,Aspect.IMPLEMENTATION).unboxify(); XmlEnumWriter xew = type.annotate2(XmlEnumWriter.class); xew.value(baseExposedType); boolean needsValue = e.needsValueField(); // for each member , // [RESULT] // (()); Set enumFieldNames = new HashSet(); // record generated field names to detect collision for( CEnumConstant mem : e.members ) { String constName = mem.getName(); if(!JJavaName.isJavaIdentifier(constName)) { // didn't produce a name. getErrorReceiver().error( e.getLocator(), Messages.ERR_UNUSABLE_NAME.format(mem.getLexicalValue(), constName ) ); } if( !enumFieldNames.add(constName) ) getErrorReceiver().error( e.getLocator(), Messages.ERR_NAME_COLLISION.format(constName)); // [RESULT] // (...) // ASSUMPTION: datatype is outline-independent JEnumConstant constRef = type.enumConstant(constName); if(needsValue) constRef.arg(e.base.createConstant(this, new XmlString(mem.getLexicalValue()))); if(!mem.getLexicalValue().equals(constName)) constRef.annotate2(XmlEnumValueWriter.class).value(mem.getLexicalValue()); // set javadoc if( mem.javadoc!=null ) constRef.javadoc().append(mem.javadoc); eo.constants.add(new EnumConstantOutline(mem,constRef){}); } if(needsValue) { // [RESULT] // final value; JFieldVar $value = type.field( JMod.PRIVATE|JMod.FINAL, baseExposedType, "value" ); // [RESULT] // public value() { return value; } type.method(JMod.PUBLIC, baseExposedType, "value" ).body()._return($value); // [RESULT] // ( v) { // this.value=v; // } { JMethod m = type.constructor(0); m.body().assign( $value, m.param( baseImplType, "v" ) ); } // [RESULT] // public static fromValue( v) { // for( c : .values() ) { // if(c.value == v) // or equals // return c; // } // throw new IllegalArgumentException(...); // } { JMethod m = type.method(JMod.PUBLIC|JMod.STATIC , type, "fromValue" ); JVar $v = m.param(baseExposedType,"v"); JForEach fe = m.body().forEach(type,"c", type.staticInvoke("values") ); JExpression eq; if(baseExposedType.isPrimitive()) eq = fe.var().ref($value).eq($v); else eq = fe.var().ref($value).invoke("equals").arg($v); fe.body()._if(eq)._then()._return(fe.var()); JInvocation ex = JExpr._new(codeModel.ref(IllegalArgumentException.class)); JExpression strForm; if(baseExposedType.isPrimitive()) { strForm = codeModel.ref(String.class).staticInvoke("valueOf").arg($v); } else if(baseExposedType==codeModel.ref(String.class)){ strForm = $v; } else { strForm = $v.invoke("toString"); } m.body()._throw(ex.arg(strForm)); } } else { // [RESULT] // public String value() { return name(); } type.method(JMod.PUBLIC, String.class, "value" ).body()._return(JExpr.invoke("name")); // [RESULT] // public fromValue(String v) { return valueOf(v); } JMethod m = type.method(JMod.PUBLIC|JMod.STATIC, type, "fromValue" ); m.body()._return( JExpr.invoke("valueOf").arg(m.param(String.class,"v"))); } } /** * Determines the FieldRenderer used for the given FieldUse, * then generates the field declaration and accessor methods. * * The fields map will be updated with the newly * created FieldRenderer. */ private FieldOutline generateFieldDecl( ClassOutlineImpl cc, CPropertyInfo prop ) { FieldRenderer fr = prop.realization; if(fr==null) // none is specified. use the default factory fr = model.options.getFieldRendererFactory().getDefault(); FieldOutline field = fr.generate(cc, prop); fields.put(prop,field); return field; } /** * Generates {@link XmlJavaTypeAdapter} from {@link PropertyInfo} if necessary. * Also generates other per-property annotations * (such as {@link XmlID}, {@link XmlIDREF}, and {@link XmlMimeType} if necessary. */ public final void generateAdapterIfNecessary(CPropertyInfo prop, JAnnotatable field) { CAdapter adapter = prop.getAdapter(); if (adapter != null ) { if(adapter.getAdapterIfKnown()==SwaRefAdapter.class) { field.annotate(XmlAttachmentRef.class); } else { // [RESULT] // @XmlJavaTypeAdapter( Foo.class ) XmlJavaTypeAdapterWriter xjtw = field.annotate2(XmlJavaTypeAdapterWriter.class); xjtw.value(adapter.adapterType.toType(this, EXPOSED)); } } switch(prop.id()) { case ID: field.annotate(XmlID.class); break; case IDREF: field.annotate(XmlIDREF.class); break; } if(prop.getExpectedMimeType()!=null) field.annotate2(XmlMimeTypeWriter.class).value(prop.getExpectedMimeType().toString()); } public final JClass addRuntime(Class clazz) { JClass g = generatedRuntime.get(clazz); if(g==null) { // put code into a separate package to avoid name conflicts. JPackage implPkg = getUsedPackages(Aspect.IMPLEMENTATION)[0].subPackage("runtime"); g = generateStaticClass(clazz,implPkg); generatedRuntime.put(clazz,g); } return g; } public JClass generateStaticClass(Class src, JPackage out) { String shortName = getShortName(src.getName()); // some people didn't like our jars to contain files with .java extension, // so when we build jars, we'' use ".java_". But when we run from the workspace, // we want the original source code to be used, so we check both here. // see bug 6211503. URL res = src.getResource(shortName+".java"); if(res==null) res = src.getResource(shortName+".java_"); if(res==null) throw new InternalError("Unable to load source code of "+src.getName()+" as a resource"); JStaticJavaFile sjf = new JStaticJavaFile(out,shortName, res, null ); out.addResourceFile(sjf); return sjf.getJClass(); } private String getShortName( String name ) { return name.substring(name.lastIndexOf('.')+1); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy