1 /** 2 * Redistribution and use of this software and associated documentation ("Software"), with or 3 * without modification, are permitted provided that the following conditions are met: 4 * 5 * 1. Redistributions of source code must retain copyright statements and notices. Redistributions 6 * must also contain a copy of this document. 7 * 8 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of 9 * conditions and the following disclaimer in the documentation and/or other materials provided with 10 * the distribution. 11 * 12 * 3. The name "Exolab" must not be used to endorse or promote products derived from this Software 13 * without prior written permission of Intalio, Inc. For written permission, please contact 14 * info@exolab.org. 15 * 16 * 4. Products derived from this Software may not be called "Exolab" nor may "Exolab" appear in 17 * their names without prior written permission of Intalio, Inc. Exolab is a registered trademark of 18 * Intalio, Inc. 19 * 20 * 5. Due credit should be given to the Exolab Project (http://www.exolab.org/). 21 * 22 * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 24 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTALIO, INC. OR ITS 25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 29 * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * 31 * Copyright 1999-2002 (C) Intalio, Inc. All Rights Reserved. 32 */ 33 package org.exolab.javasource; 34 35 import java.util.LinkedHashMap; 36 import java.util.Map; 37 38 import org.exolab.castor.builder.SourceGenerator; 39 40 /** 41 * Describes the definition of a annotation type class. 42 * 43 * <pre> 44 * JAnnotationType type = new JAnnotationType("RequestForEnhancement"); 45 * type.addElement(new JAnnotationTypeElement("id", JType.Int)); 46 * type.addElement(new JAnnotationTypeElement("synopsis", new JType("String"))); 47 * JAnnotationTypeElement engineer; 48 * engineer = new JAnnotationTypeElement("engineer", new JType("String")); 49 * engineer.setDefaultString("\"[unassigned]\""); 50 * type.addElement(engineer); 51 * JAnnotationTypeElement date; 52 * date = new JAnnotationTypeElement("date", new JType("String")); 53 * date.setDefaultString("\"[unimplemented]\""); 54 * type.addElement(date); 55 * </pre> 56 * 57 * outputs 58 * 59 * <pre> 60 * public @interface RequestForEnhancement { 61 * int id(); 62 * 63 * String synopsis(); 64 * 65 * String engineer() default "[unassigned]"; 66 * 67 * String date() default "[unimplemented]"; 68 * } 69 * </pre> 70 * 71 * @author <a href="mailto:andrew DOT fawcett AT coda DOT com">Andrew Fawcett</a> 72 * @version $Revision$ $Date: 2006-04-25 16:09:10 -0600 (Tue, 25 Apr 2006) $ 73 */ 74 public final class JAnnotationType extends JStructure { 75 76 /** The list of elements of this JAnnotationType. */ 77 private Map<String, JAnnotationTypeElement> _elements = 78 new LinkedHashMap<String, JAnnotationTypeElement>(); 79 80 /** 81 * Creates a JAnnotationType of the given name. 82 * 83 * @param name Annotation name. 84 */ 85 public JAnnotationType(final String name) { 86 super(name); 87 88 // -- initialize default Java doc 89 getJDocComment().appendComment("Annotation " + getLocalName() + "."); 90 } 91 92 /** 93 * {@inheritDoc} 94 */ 95 public void addImport(final String className) { 96 if (className == null || className.length() == 0) { 97 return; 98 } 99 addImportInternal(className); 100 } 101 102 /** 103 * Adds the given JMember to this JAnnotationType. 104 * 105 * @param jMember The JMember to add. 106 */ 107 public void addMember(final JMember jMember) { 108 if (!(jMember instanceof JAnnotationTypeElement)) { 109 throw new IllegalArgumentException("Must be a JAnnotationTypeElement."); 110 } 111 addElement((JAnnotationTypeElement) jMember); 112 } 113 114 /** 115 * Returns an Array containing all our JAnnotationTypeElements. 116 * 117 * @return An Array containing all our JAnnotationTypeElements. 118 */ 119 public JAnnotationTypeElement[] getElements() { 120 return _elements.values().toArray(new JAnnotationTypeElement[_elements.size()]); 121 } 122 123 /** 124 * Returns the member with the given name, or null if no member was found with the given name. 125 * 126 * @param name The name of the member to return. 127 * @return The member with the given name, or null if no member was found with the given name. 128 */ 129 public JAnnotationTypeElement getElement(final String name) { 130 return _elements.get(name); 131 } 132 133 /** 134 * Adds the given JAnnotationTypeElement to this JAnnotationType. 135 * 136 * @param jElement The element to add. 137 */ 138 public void addElement(final JAnnotationTypeElement jElement) { 139 if (jElement == null) { 140 throw new IllegalArgumentException("Class members cannot be null"); 141 } 142 143 String name = jElement.getName(); 144 if (_elements.get(name) != null) { 145 String err = "duplicate name found: " + name; 146 throw new IllegalArgumentException(err); 147 } 148 _elements.put(name, jElement); 149 150 // if member is of a type not imported by this class 151 // then add import 152 JType type = jElement.getType(); 153 while (type.isArray()) { 154 type = ((JArrayType) type).getComponentType(); 155 } 156 if (!type.isPrimitive()) { 157 addImport(type.getName()); 158 } 159 } 160 161 /** 162 * Not implemented. Always throws a RuntimeException. <br/> 163 * {@inheritDoc} 164 */ 165 public JField[] getFields() { 166 throw new RuntimeException("Not implemented."); 167 } 168 169 /** 170 * Not implemented. Always throws a RuntimeException. <br/> 171 * {@inheritDoc} 172 */ 173 public JField getField(final String name) { 174 throw new RuntimeException("Not implemented."); 175 } 176 177 /** 178 * Not implemented. Always throws a RuntimeException. <br/> 179 * {@inheritDoc} 180 */ 181 public void addField(final JField jField) { 182 throw new RuntimeException("Not implemented."); 183 } 184 185 /** 186 * {@inheritDoc} 187 * 188 * @deprecated Please use the Velocity-template based approach instead. 189 * @see SourceGenerator#setJClassPrinterType(String) 190 */ 191 public void print(final JSourceWriter jsw) { 192 if (jsw == null) { 193 throw new IllegalArgumentException("argument 'jsw' should not be null."); 194 } 195 196 StringBuilder buffer = new StringBuilder(100); 197 198 printHeader(jsw); 199 printPackageDeclaration(jsw); 200 printImportDeclarations(jsw); 201 202 // ------------/ 203 // - Java Doc -/ 204 // ------------/ 205 206 getJDocComment().print(jsw); 207 208 // -- print class information 209 // -- we need to add some JavaDoc API adding comments 210 211 buffer.setLength(0); 212 JModifiers modifiers = getModifiers(); 213 if (modifiers.isPrivate()) { 214 buffer.append("private "); 215 } else if (modifiers.isPublic()) { 216 buffer.append("public "); 217 } 218 buffer.append("@interface "); 219 buffer.append(getLocalName()); 220 buffer.append(' '); 221 buffer.append('{'); 222 jsw.writeln(buffer.toString()); 223 224 // -- declare members 225 226 buffer.setLength(0); 227 jsw.writeln(); 228 jsw.indent(); 229 for (JAnnotationTypeElement jElement : _elements.values()) { 230 jElement.print(jsw); 231 jsw.writeln(); 232 } 233 jsw.unindent(); 234 235 // -- close class 236 237 jsw.writeln('}'); 238 jsw.flush(); 239 } 240 241 }