View Javadoc
1   /*
2    * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  /*
27   * Use is subject to the license terms.
28   */
29  package com.sun.tools.internal.xjc.generator.bean;
30  
31  import javax.xml.bind.annotation.XmlAccessType;
32  import javax.xml.bind.annotation.XmlEnum;
33  import javax.xml.bind.annotation.XmlEnumValue;
34  
35  import com.sun.codemodel.internal.JClassContainer;
36  import com.sun.codemodel.internal.JDefinedClass;
37  import com.sun.codemodel.internal.JDocComment;
38  import com.sun.codemodel.internal.JMethod;
39  import com.sun.codemodel.internal.JMod;
40  import com.sun.codemodel.internal.JPackage;
41  import com.sun.codemodel.internal.JType;
42  import com.sun.codemodel.internal.JVar;
43  import com.sun.tools.internal.xjc.generator.annotation.spec.XmlAccessorTypeWriter;
44  import com.sun.tools.internal.xjc.model.CClassInfo;
45  import com.sun.tools.internal.xjc.outline.Aspect;
46  import com.sun.tools.internal.xjc.outline.Outline;
47  
48  /**
49   * Decides how a bean token is mapped to the generated classes.
50   *
51   * <p>
52   * The actual implementations of this interface is tightly coupled with
53   * the backend, but the front-end gets to choose which strategy to be used.
54   *
55   * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
56   */
57  @XmlEnum(Boolean.class)
58  public enum ImplStructureStrategy {
59      /**
60       * Generates beans only. The simplest code generation.
61       */
62      @XmlEnumValue("true")
63      BEAN_ONLY() {
64          protected Result createClasses(Outline outline, CClassInfo bean) {
65              JClassContainer parent = outline.getContainer( bean.parent(), Aspect.EXPOSED );
66  
67              JDefinedClass impl = outline.getClassFactory().createClass(
68                  parent,
69                  JMod.PUBLIC|(parent.isPackage()?0:JMod.STATIC)|(bean.isAbstract()?JMod.ABSTRACT:0),
70                  bean.shortName, bean.getLocator() );
71              impl.annotate2(XmlAccessorTypeWriter.class).value(XmlAccessType.FIELD);
72  
73              return new Result(impl,impl);
74          }
75  
76          protected JPackage getPackage(JPackage pkg, Aspect a) {
77              return pkg;
78          }
79  
80          protected MethodWriter createMethodWriter(final ClassOutlineImpl target) {
81              assert target.ref==target.implClass;
82  
83              return new MethodWriter(target) {
84                  private final JDefinedClass impl = target.implClass;
85  
86                  private JMethod implMethod;
87  
88                  public JVar addParameter(JType type, String name) {
89                      return implMethod.param(type,name);
90                  }
91  
92                  public JMethod declareMethod(JType returnType, String methodName) {
93                      implMethod = impl.method( JMod.PUBLIC, returnType, methodName );
94                      return implMethod;
95                  }
96  
97                  public JDocComment javadoc() {
98                      return implMethod.javadoc();
99                  }
100             };
101         }
102 
103         protected void _extends(ClassOutlineImpl derived, ClassOutlineImpl base) {
104             derived.implClass._extends(base.implRef);
105         }
106     },
107 
108     /**
109      * Generates the interfaces to describe beans (content interfaces)
110      * and then the beans themselves in a hidden impl package.
111      *
112      * Similar to JAXB 1.0.
113      */
114     @XmlEnumValue("false")
115     INTF_AND_IMPL() {
116         protected Result createClasses( Outline outline, CClassInfo bean ) {
117             JClassContainer parent = outline.getContainer( bean.parent(), Aspect.EXPOSED );
118 
119             JDefinedClass intf = outline.getClassFactory().createInterface(
120                 parent, bean.shortName, bean.getLocator() );
121 
122             parent = outline.getContainer(bean.parent(), Aspect.IMPLEMENTATION);
123             JDefinedClass impl = outline.getClassFactory().createClass(
124                 parent,
125                 JMod.PUBLIC|(parent.isPackage()?0:JMod.STATIC)|(bean.isAbstract()?JMod.ABSTRACT:0),
126                 bean.shortName+"Impl", bean.getLocator() );
127             impl.annotate2(XmlAccessorTypeWriter.class).value(XmlAccessType.FIELD);
128 
129             impl._implements(intf);
130 
131             return new Result(intf,impl);
132         }
133 
134         protected JPackage getPackage(JPackage pkg, Aspect a) {
135             switch(a) {
136             case EXPOSED:
137                 return pkg;
138             case IMPLEMENTATION:
139                 return pkg.subPackage("impl");
140             default:
141                 assert false;
142                 throw new IllegalStateException();
143             }
144         }
145 
146         protected MethodWriter createMethodWriter(final ClassOutlineImpl target) {
147             return new MethodWriter(target) {
148                 private final JDefinedClass intf = target.ref;
149                 private final JDefinedClass impl = target.implClass;
150 
151                 private JMethod intfMethod;
152                 private JMethod implMethod;
153 
154                 public JVar addParameter(JType type, String name) {
155                     // TODO: do we still need to deal with the case where intf is null?
156                     if(intf!=null)
157                         intfMethod.param(type,name);
158                     return implMethod.param(type,name);
159                 }
160 
161                 public JMethod declareMethod(JType returnType, String methodName) {
162                     if(intf!=null)
163                         intfMethod = intf.method( 0, returnType, methodName );
164                     implMethod = impl.method( JMod.PUBLIC, returnType, methodName );
165                     return implMethod;
166                 }
167 
168                 public JDocComment javadoc() {
169                     if(intf!=null)
170                         return intfMethod.javadoc();
171                     else
172                         return implMethod.javadoc();
173                 }
174             };
175         }
176 
177         protected void _extends(ClassOutlineImpl derived, ClassOutlineImpl base) {
178             derived.implClass._extends(base.implRef);
179             derived.ref._implements(base.ref);
180         }
181     };
182 
183 
184     /**
185      * Creates class(es) for the given bean.
186      */
187     protected abstract Result createClasses( Outline outline, CClassInfo bean );
188 
189     /**
190      * Gets the specified aspect of the given package.
191      */
192     protected abstract JPackage getPackage( JPackage pkg, Aspect a );
193 
194     protected abstract MethodWriter createMethodWriter( ClassOutlineImpl target );
195 
196     /**
197      * Sets up an inheritance relationship.
198      */
199     protected abstract void _extends( ClassOutlineImpl derived, ClassOutlineImpl base );
200 
201     public static final class Result {
202         /**
203          * Corresponds to {@link Aspect#EXPOSED}
204          */
205         public final JDefinedClass exposed;
206         /**
207          * Corresponds to {@link Aspect#IMPLEMENTATION}
208          */
209         public final JDefinedClass implementation;
210 
211         public Result(JDefinedClass exposed, JDefinedClass implementation) {
212             this.exposed = exposed;
213             this.implementation = implementation;
214         }
215     }
216 }