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 }