001: /*
002: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: /*
027: * Use is subject to the license terms.
028: */
029: package com.sun.tools.internal.xjc.generator.bean;
030:
031: import javax.xml.bind.annotation.XmlAccessType;
032: import javax.xml.bind.annotation.XmlEnum;
033: import javax.xml.bind.annotation.XmlEnumValue;
034:
035: import com.sun.codemodel.internal.JClassContainer;
036: import com.sun.codemodel.internal.JDefinedClass;
037: import com.sun.codemodel.internal.JDocComment;
038: import com.sun.codemodel.internal.JMethod;
039: import com.sun.codemodel.internal.JMod;
040: import com.sun.codemodel.internal.JPackage;
041: import com.sun.codemodel.internal.JType;
042: import com.sun.codemodel.internal.JVar;
043: import com.sun.tools.internal.xjc.generator.annotation.spec.XmlAccessorTypeWriter;
044: import com.sun.tools.internal.xjc.model.CClassInfo;
045: import com.sun.tools.internal.xjc.outline.Aspect;
046: import com.sun.tools.internal.xjc.outline.Outline;
047:
048: /**
049: * Decides how a bean token is mapped to the generated classes.
050: *
051: * <p>
052: * The actual implementations of this interface is tightly coupled with
053: * the backend, but the front-end gets to choose which strategy to be used.
054: *
055: * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
056: */
057: @XmlEnum(Boolean.class)
058: public enum ImplStructureStrategy {
059: /**
060: * Generates beans only. The simplest code generation.
061: */
062: @XmlEnumValue("true")
063: BEAN_ONLY() {
064: protected Result createClasses(Outline outline, CClassInfo bean) {
065: JClassContainer parent = outline.getContainer(
066: bean.parent(), Aspect.EXPOSED);
067:
068: JDefinedClass impl = outline.getClassFactory().createClass(
069: parent,
070: JMod.PUBLIC
071: | (parent.isPackage() ? 0 : JMod.STATIC)
072: | (bean.isAbstract() ? JMod.ABSTRACT : 0),
073: bean.shortName, bean.getLocator());
074: impl.annotate2(XmlAccessorTypeWriter.class).value(
075: XmlAccessType.FIELD);
076:
077: return new Result(impl, impl);
078: }
079:
080: protected JPackage getPackage(JPackage pkg, Aspect a) {
081: return pkg;
082: }
083:
084: protected MethodWriter createMethodWriter(
085: final ClassOutlineImpl target) {
086: assert target.ref == target.implClass;
087:
088: return new MethodWriter(target) {
089: private final JDefinedClass impl = target.implClass;
090:
091: private JMethod implMethod;
092:
093: public JVar addParameter(JType type, String name) {
094: return implMethod.param(type, name);
095: }
096:
097: public JMethod declareMethod(JType returnType,
098: String methodName) {
099: implMethod = impl.method(JMod.PUBLIC, returnType,
100: methodName);
101: return implMethod;
102: }
103:
104: public JDocComment javadoc() {
105: return implMethod.javadoc();
106: }
107: };
108: }
109:
110: protected void _extends(ClassOutlineImpl derived,
111: ClassOutlineImpl base) {
112: derived.implClass._extends(base.implRef);
113: }
114: },
115:
116: /**
117: * Generates the interfaces to describe beans (content interfaces)
118: * and then the beans themselves in a hidden impl package.
119: *
120: * Similar to JAXB 1.0.
121: */
122: @XmlEnumValue("false")
123: INTF_AND_IMPL() {
124: protected Result createClasses(Outline outline, CClassInfo bean) {
125: JClassContainer parent = outline.getContainer(
126: bean.parent(), Aspect.EXPOSED);
127:
128: JDefinedClass intf = outline.getClassFactory()
129: .createInterface(parent, bean.shortName,
130: bean.getLocator());
131:
132: parent = outline.getContainer(bean.parent(),
133: Aspect.IMPLEMENTATION);
134: JDefinedClass impl = outline.getClassFactory().createClass(
135: parent,
136: JMod.PUBLIC
137: | (parent.isPackage() ? 0 : JMod.STATIC)
138: | (bean.isAbstract() ? JMod.ABSTRACT : 0),
139: bean.shortName + "Impl", bean.getLocator());
140: impl.annotate2(XmlAccessorTypeWriter.class).value(
141: XmlAccessType.FIELD);
142:
143: impl._implements (intf);
144:
145: return new Result(intf, impl);
146: }
147:
148: protected JPackage getPackage(JPackage pkg, Aspect a) {
149: switch (a) {
150: case EXPOSED:
151: return pkg;
152: case IMPLEMENTATION:
153: return pkg.subPackage("impl");
154: default:
155: assert false;
156: throw new IllegalStateException();
157: }
158: }
159:
160: protected MethodWriter createMethodWriter(
161: final ClassOutlineImpl target) {
162: return new MethodWriter(target) {
163: private final JDefinedClass intf = target.ref;
164: private final JDefinedClass impl = target.implClass;
165:
166: private JMethod intfMethod;
167: private JMethod implMethod;
168:
169: public JVar addParameter(JType type, String name) {
170: // TODO: do we still need to deal with the case where intf is null?
171: if (intf != null)
172: intfMethod.param(type, name);
173: return implMethod.param(type, name);
174: }
175:
176: public JMethod declareMethod(JType returnType,
177: String methodName) {
178: if (intf != null)
179: intfMethod = intf.method(0, returnType,
180: methodName);
181: implMethod = impl.method(JMod.PUBLIC, returnType,
182: methodName);
183: return implMethod;
184: }
185:
186: public JDocComment javadoc() {
187: if (intf != null)
188: return intfMethod.javadoc();
189: else
190: return implMethod.javadoc();
191: }
192: };
193: }
194:
195: protected void _extends(ClassOutlineImpl derived,
196: ClassOutlineImpl base) {
197: derived.implClass._extends(base.implRef);
198: derived.ref._implements (base.ref);
199: }
200: };
201:
202: /**
203: * Creates class(es) for the given bean.
204: */
205: protected abstract Result createClasses(Outline outline,
206: CClassInfo bean);
207:
208: /**
209: * Gets the specified aspect of the given package.
210: */
211: protected abstract JPackage getPackage(JPackage pkg, Aspect a);
212:
213: protected abstract MethodWriter createMethodWriter(
214: ClassOutlineImpl target);
215:
216: /**
217: * Sets up an inheritance relationship.
218: */
219: protected abstract void _extends(ClassOutlineImpl derived,
220: ClassOutlineImpl base);
221:
222: public static final class Result {
223: /**
224: * Corresponds to {@link Aspect#EXPOSED}
225: */
226: public final JDefinedClass exposed;
227: /**
228: * Corresponds to {@link Aspect#IMPLEMENTATION}
229: */
230: public final JDefinedClass implementation;
231:
232: public Result(JDefinedClass exposed,
233: JDefinedClass implementation) {
234: this.exposed = exposed;
235: this.implementation = implementation;
236: }
237: }
238: }
|