KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ws > jaxme > js > JavaSource


1 /*
2  * Copyright 2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.ws.jaxme.js;
17
18 import java.io.IOException JavaDoc;
19 import java.io.Serializable JavaDoc;
20 import java.io.StringWriter JavaDoc;
21 import java.io.Writer JavaDoc;
22 import java.lang.reflect.Method JavaDoc;
23 import java.lang.reflect.Modifier JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Arrays JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.NoSuchElementException JavaDoc;
29 import java.util.StringTokenizer JavaDoc;
30
31
32 /** A class representing a Java source file.
33  */

34 public class JavaSource extends IndentationEngineImpl {
35     /** Specifies the type of a java class (interface, or class).
36      */

37     public static class Type implements Serializable JavaDoc {
38         private String JavaDoc name;
39         Type(String JavaDoc pName) {
40             name = pName;
41         }
42         public String JavaDoc toString() { return name; }
43         /** Converts the given string into a java class type.
44          */

45         public static Type valueOf(String JavaDoc pType) {
46             if ("class".equals(pType)) {
47                 return CLASS;
48             } else if ("interface".equals(pType)) {
49                 return INTERFACE;
50             } else {
51                 throw new IllegalArgumentException JavaDoc("Type must be either 'class' or 'interface'.");
52             }
53         }
54     }
55
56     /** Specifies a java objects protection (default, public,
57      * protected, or private).
58      */

59     public static class Protection implements Serializable JavaDoc {
60         private String JavaDoc name;
61         Protection(String JavaDoc pName) {
62             name = pName;
63         }
64         public String JavaDoc toString() { return name; }
65         /** Converts the given string into a protection type.
66          */

67         public static Protection valueOf(String JavaDoc pProtection) {
68             if ("public".equals(pProtection)) {
69                 return PUBLIC;
70             } else if ("protected".equals(pProtection)) {
71                 return PROTECTED;
72             } else if ("private".equals(pProtection)) {
73                 return PRIVATE;
74             } else if (pProtection == null || "".equals(pProtection)) {
75                 return DEFAULT_PROTECTION;
76             } else {
77                 throw new IllegalArgumentException JavaDoc("Protection must be either 'public', 'protected', 'private', null or '' (default protection).");
78             }
79         }
80         /** Returns an instance of Protection by using the methods
81          * {@link Modifier#isPublic(int)}, {@link Modifier#isProtected(int)} and
82          * {@link Modifier#isPrivate(int)} on the argument <code>pModifiers</code>.
83          * If neither returns true, assumes {@link JavaSource#DEFAULT_PROTECTION}.
84          */

85         public static Protection valueOf(int pModifiers) {
86             if (Modifier.isPublic(pModifiers)) {
87                 return PUBLIC;
88             } else if (Modifier.isProtected(pModifiers)) {
89                 return PROTECTED;
90             } else if (Modifier.isPrivate(pModifiers)) {
91                 return PRIVATE;
92             } else {
93                 return DEFAULT_PROTECTION;
94             }
95         }
96     }
97
98     /** Type of a JavaSource class.
99      * @see #INTERFACE
100      * @see #getType
101      * @see #setType
102      */

103     public static final Type CLASS = new Type("class");
104     
105     /** Type of a JavaSource interface.
106      * @see #CLASS
107      * @see #getType
108      * @see #setType
109      */

110     public static final Type INTERFACE = new Type("interface");
111     
112     /** Protection of a class, field or method: public
113      */

114     public static final Protection PUBLIC = new Protection("public");
115     
116     /** Protection of a class, field or method: protected
117      */

118     public static final Protection PROTECTED = new Protection("protected");
119     
120     /** Protection of a class, field or method: private
121      */

122     public static final Protection PRIVATE = new Protection("private");
123     
124     /** Default protection of a class, field or method
125      */

126     public static final Protection DEFAULT_PROTECTION = new Protection("");
127     
128     /** Creates a new instance of JavaSource with the given protection.
129      * @param pFactory The {@link JavaSourceFactory factory} creating this
130      * instance of JavaSource.
131      * @param pName The class or interface name
132      * @param pProtection null, "public", "protected" or "private"
133      */

134     JavaSource(JavaSourceFactory pFactory, JavaQName pName, Protection pProtection) {
135         factory = pFactory;
136         setQName(pName);
137         setProtection(pProtection);
138     }
139     
140     List JavaDoc myObjects = new ArrayList JavaDoc();
141     
142     /** Returns the static class initializers.
143      */

144     public JavaClassInitializer[] getClassInitializers() {
145         List JavaDoc result = new ArrayList JavaDoc(myObjects);
146         for (Iterator JavaDoc iter = myObjects.iterator(); iter.hasNext(); ) {
147             ConditionalIndentationJavaSourceObject object =
148                 (ConditionalIndentationJavaSourceObject) iter.next();
149             if (object instanceof JavaClassInitializer) {
150                 result.add(object);
151             }
152         }
153         return (JavaClassInitializer[]) result.toArray(new JavaClassInitializer[result.size()]);
154     }
155     
156     private JavaSourceFactory factory;
157
158     /** Returns the {@link JavaSourceFactory} that created this instance of
159      * JavaSource.
160      */

161     public JavaSourceFactory getFactory() {
162         return factory;
163     }
164     
165     private JavaQName myQName;
166     /** Returns the JavaSource's JavaQName.
167      */

168     public JavaQName getQName() {
169         return myQName;
170     }
171     /** Sets the JavaSource's JavaQName.
172      */

173     public void setQName(JavaQName pQName) {
174         myQName = pQName;
175     }
176     /** Returns the class or interface name.
177      * @see #setQName
178      */

179     public String JavaDoc getClassName() { return myQName.getClassName(); }
180     /** Returns the package name. The empty String represents the
181      * root package.
182      */

183     public String JavaDoc getPackageName() { return myQName.getPackageName(); }
184     
185     private Protection myProtection;
186     /** Returns the protection.
187      * @see #setProtection
188      */

189     public Protection getProtection() { return myProtection; }
190     /** Sets the protection; use null for default protection.
191      * @see #getProtection
192      */

193     public void setProtection(Protection protection) {
194         myProtection = (protection == null) ? DEFAULT_PROTECTION : protection;
195     }
196     
197     private Type type = CLASS;
198     /** Returns the JavaSource type.
199      * @return "class" or "interface"
200      * @see #setType
201      */

202     public Type getType() { return type; }
203     /** Sets the JavaSource type.
204      * @param pType "class" or "interface"
205      * @see #getType
206      */

207     public void setType(Type pType) {
208         this.type = (pType == null) ? CLASS : pType;
209     }
210     
211     private JavaComment comment;
212     /** Returns the comment describing this class or interface.
213      * @see #newComment
214      */

215     public JavaComment getComment() { return comment; }
216     /** Creates a new Javadoc comment describing this class or interface.
217      * @see #getComment
218      */

219     public JavaComment newComment() {
220         if (comment == null) {
221             comment = new JavaComment();
222             return comment;
223         } else {
224             throw new IllegalStateException JavaDoc("A Javadoc comment has already been created for this object.");
225         }
226     }
227     
228     private List JavaDoc extendedClasses;
229     /** Clears the list of extended classes or interfaces.
230      */

231     public void clearExtends() {
232         extendedClasses = null;
233     }
234     /** Returns the class or interface extended by this class or interface.
235      * @see #addExtends(JavaQName)
236      */

237     public JavaQName[] getExtends() {
238         if (extendedClasses == null) {
239             return new JavaQName[0];
240         } else {
241             return (JavaQName[]) extendedClasses.toArray(new JavaQName[extendedClasses.size()]);
242         }
243     }
244     /** Sets the class or interface extended by this class or interface.
245      * Null or the empty string disable the "extends" clause.
246      * @see #getExtends
247      */

248     public void addExtends(JavaQName pExtends) {
249         if (extendedClasses == null) {
250             extendedClasses = new ArrayList JavaDoc();
251         } else if ("class".equals(getType())) {
252             throw new IllegalStateException JavaDoc("Only interfaces may extend multiple classes.");
253         }
254         extendedClasses.add(pExtends);
255     }
256     /** Sets the class or interface extended by this class or interface.
257      * Null or the empty string disable the "extends" clause.
258      * @see #getExtends
259      */

260     public void addExtends(Class JavaDoc pExtends) {
261         addExtends(JavaQNameImpl.getInstance(pExtends));
262     }
263     
264     /** Returns whether the class is extending the given super class or interface.
265      */

266     public boolean isExtending(JavaQName pClass) {
267         for (Iterator JavaDoc iter = extendedClasses.iterator(); iter.hasNext(); ) {
268             if (iter.next().equals(pClass)) {
269                 return true;
270             }
271         }
272         return false;
273     }
274     
275     /** Returns whether the class is extending the given super class or interface.
276      */

277     public boolean isExtending(Class JavaDoc pClass) {
278         return isExtending(JavaQNameImpl.getInstance(pClass));
279     }
280     
281     private ArrayList JavaDoc imports = new ArrayList JavaDoc();
282     /** Returns the list of packages and classes being imported.
283      * @see #addImport(JavaQName)
284      */

285     public JavaQName[] getImports() {
286         return (JavaQName[]) imports.toArray(new JavaQName[imports.size()]);
287     }
288     
289     /** Adds a package or class to the list of packages and classes being imported.
290      * @see #getImports()
291      */

292     public void addImport(JavaQName s) {
293         if (s.isArray()) {
294             throw new IllegalArgumentException JavaDoc("Arrays cannot be imported");
295         }
296         imports.add(s);
297     }
298     
299     /** Adds a package or class to the list of packages and classes being imported.
300      * @see #addImport(JavaQName)
301      */

302     public void addImport(Class JavaDoc s) { imports.add(JavaQNameImpl.getInstance(s)); }
303     
304     /** Clears the list of imports.
305      */

306     public void clearImports() { imports.clear(); }
307     
308     private ArrayList JavaDoc myImplements = new ArrayList JavaDoc();
309     /** Returns the list of interfaces being implented by this class or
310      * interface.
311      * @see #addImplements(JavaQName)
312      */

313     public JavaQName[] getImplements() {
314         return (JavaQName[]) myImplements.toArray(new JavaQName[myImplements.size()]);
315     }
316     
317     /** Adds an interface to the list of interfaces being implemented by
318      * this class or interface.
319      * @see #getImplements()
320      */

321     public void addImplements(JavaQName s) { myImplements.add(s); }
322     
323     /** Adds an interface to the list of interfaces being implemented by
324      * this class or interface.
325      * @see #getImplements()
326      */

327     public void addImplements(Class JavaDoc s) { myImplements.add(JavaQNameImpl.getInstance(s)); }
328     
329     /** Clears the list of implemented interfaces.
330      */

331     public void clearImplements() { myImplements.clear(); }
332     
333     /** Returns whether the class is implementing the given interface.
334      */

335     public boolean isImplementing(JavaQName pClass) {
336         for (Iterator JavaDoc iter = myImplements.iterator(); iter.hasNext(); ) {
337             if (iter.next().equals(pClass)) {
338                 return true;
339             }
340         }
341         return false;
342     }
343     
344     /** Returns whether the class is implementing the given interface.
345      */

346     public boolean isImplementing(Class JavaDoc pClass) {
347         return isImplementing(JavaQNameImpl.getInstance(pClass));
348     }
349     
350     private ArrayList JavaDoc myFields = new ArrayList JavaDoc();
351     /** Returns the field with the given name or null, if no such field exists.
352      */

353     public JavaField getField(String JavaDoc pName) {
354         if (pName == null) {
355             throw new NullPointerException JavaDoc("A field name must not be null.");
356         }
357         JavaField[] fields = getFields();
358         for (int i = 0; i < fields.length; i++) {
359             if (pName.equals(fields[i].getName())) {
360                 return fields[i];
361             }
362         }
363         return null;
364     }
365     /** Returns the list of fields that this class has.
366      * @see #newJavaField(String, JavaQName, Protection)
367      */

368     public JavaField[] getFields() {
369         return (JavaField[]) myFields.toArray(new JavaField[myFields.size()]);
370     }
371     /** Adds a field to this classes list of fields.
372      * @see #getFields
373      */

374     void addField(JavaField f) {
375         String JavaDoc s = f.getName();
376         for (int i = 0; i < myFields.size(); i++) {
377             if (s.equals(((JavaField) myFields.get(i)).getName())) {
378                 throw new IllegalStateException JavaDoc("The class " + getQName() + " already has a field " + s + ".");
379             }
380         }
381         myFields.add(f);
382     }
383     
384     /** Returns the list of constructors that this class has.
385      * @see #newJavaConstructor(JavaConstructor, boolean)
386      */

387     public JavaConstructor[] getConstructors() {
388         List JavaDoc result = new ArrayList JavaDoc();
389         for (Iterator JavaDoc iter = myObjects.iterator(); iter.hasNext(); ) {
390             ConditionalIndentationJavaSourceObject object =
391                 (ConditionalIndentationJavaSourceObject) iter.next();
392             if (object instanceof JavaConstructor) {
393                 result.add(object);
394             }
395         }
396         return (JavaConstructor[]) result.toArray(new JavaConstructor[result.size()]);
397     }
398     /** Adds a constructor to this classes list of constructors.
399      * @see #getConstructors()
400      */

401     void addConstructor(JavaConstructor c) { myObjects.add(c); }
402     /** Returns an iterator the the classes constructors. This
403      * iterator allows to remove constructors.
404      */

405     public Iterator JavaDoc getConstructorIterator() {
406         return new MyObjectIterator(JavaConstructor.class);
407     }
408     
409     /** Returns the list of methods that this class has.
410      * @see #newJavaMethod(String, JavaQName, Protection)
411      */

412     public JavaMethod[] getMethods() {
413         List JavaDoc result = new ArrayList JavaDoc();
414         for (Iterator JavaDoc iter = myObjects.iterator(); iter.hasNext(); ) {
415             ConditionalIndentationJavaSourceObject object = (ConditionalIndentationJavaSourceObject) iter.next();
416             if (object instanceof JavaMethod) {
417                 result.add(object);
418             }
419         }
420         return (JavaMethod[]) result.toArray(new JavaMethod[result.size()]);
421     }
422     
423     /** Returns the method with the given signature or null, if there
424      * is no such method.
425      */

426     public JavaMethod getMethod(String JavaDoc pMethodName, JavaQName[] pParams) {
427         for (Iterator JavaDoc iter = myObjects.iterator(); iter.hasNext(); ) {
428             ConditionalIndentationJavaSourceObject object = (ConditionalIndentationJavaSourceObject) iter.next();
429             if (object instanceof JavaMethod) {
430                 JavaMethod jm = (JavaMethod) object;
431                 if (jm.getName().equals(pMethodName)) {
432                     Parameter[] parameters = jm.getParams();
433                     if (parameters.length == pParams.length) {
434                         boolean equals = true;
435                         for (int i = 0; i < parameters.length; i++) {
436                             if (!parameters[i].getType().equals(pParams[i])) {
437                                 equals = false;
438                                 break;
439                             }
440                         }
441                         if (equals) {
442                             return jm;
443                         }
444                     }
445                 }
446             }
447         }
448         return null;
449     }
450     
451     private class MyObjectIterator implements Iterator JavaDoc {
452         private final Class JavaDoc instanceClass;
453         MyObjectIterator(Class JavaDoc pInstanceClass) {
454             instanceClass = pInstanceClass;
455         }
456         
457         private Object JavaDoc result = null;
458         private boolean mayRemove;
459         private Iterator JavaDoc inner = myObjects.iterator();
460         public void remove() {
461             if (!mayRemove) {
462                 throw new IllegalStateException JavaDoc("remove() is only allowed immediately after next()");
463             }
464             inner.remove();
465             mayRemove = false;
466         }
467         public boolean hasNext() {
468             mayRemove = false;
469             if (result != null) {
470                 return true;
471             }
472             while (inner.hasNext()) {
473                 Object JavaDoc o = inner.next();
474                 if (instanceClass.isAssignableFrom(o.getClass())) {
475                     result = o;
476                     return true;
477                 }
478             }
479             result = null;
480             return false;
481         }
482         public Object JavaDoc next() {
483             if (!hasNext()) {
484                 throw new NoSuchElementException JavaDoc();
485             }
486             Object JavaDoc myResult = result;
487             result = null;
488             mayRemove = true;
489             return myResult;
490         }
491     }
492     
493     /** Returns an iterator to the classes methods. This iterator
494      * allows to remove certain methods.
495      */

496     public Iterator JavaDoc getMethodIterator() {
497         return new MyObjectIterator(JavaMethod.class);
498     }
499     
500     
501     /** Adds a method to this classes list of methods.
502      * @see #getMethods()
503      */

504     void addMethod(JavaMethod m) { myObjects.add(m); }
505     
506     
507     public void write(IndentationTarget pTarget) throws IOException JavaDoc {
508         if (!isInnerClass()) {
509             String JavaDoc packageName = getPackageName();
510             if (packageName.length() > 0) {
511                 pTarget.indent(0);
512                 pTarget.write("package ");
513                 pTarget.write(packageName);
514                 pTarget.write(";");
515                 pTarget.write();
516                 pTarget.indent(0);
517                 pTarget.write();
518             }
519         }
520         
521         JavaQName[] myExtendedClasses = getExtends();
522         JavaQName[] implementedInterfaces = getImplements();
523         JavaInnerClass[] myInnerClasses = getInnerClasses();
524         JavaField[] fields = getFields();
525         getConstructors();
526         getMethods();
527         
528         JavaQName[] myImports = getImports();
529         Arrays.sort(myImports);
530         if (myImports.length > 0) {
531             for (int i = 0; i < myImports.length; i++) {
532                 pTarget.indent(0);
533                 pTarget.write("import ");
534                 pTarget.write(myImports[i].toString());
535                 pTarget.write(";");
536                 pTarget.write();
537             }
538             pTarget.indent(0);
539             pTarget.write();
540             pTarget.indent(0);
541             pTarget.write();
542         }
543         if (comment != null) {
544             comment.write(pTarget);
545             pTarget.indent(0);
546             pTarget.write();
547         }
548         
549         pTarget.indent(0);
550         if (myProtection != null && !myProtection.equals(DEFAULT_PROTECTION)) {
551             pTarget.write(myProtection.toString());
552             pTarget.write(" ");
553         }
554         if (isStatic) {
555             pTarget.write("static ");
556         }
557         if (isAbstract()) {
558             pTarget.write("abstract ");
559         }
560         pTarget.write(getType().toString());
561         pTarget.write(" ");
562         String JavaDoc s = getClassName();
563         int offset = s.lastIndexOf('.');
564         if (offset > -1) {
565             s = s.substring(offset+1);
566         }
567         offset = s.lastIndexOf('$');
568         if (offset > -1) {
569             s = s.substring(offset+1);
570         }
571         pTarget.write(s);
572         pTarget.write(" ");
573         for (int i = 0; i < myExtendedClasses.length; i++) {
574             if (i > 0) {
575                 pTarget.write(", ");
576             } else {
577                 pTarget.write("extends ");
578             }
579             pTarget.write(pTarget.asString(myExtendedClasses[i]));
580             pTarget.write(" ");
581         }
582         if (implementedInterfaces.length > 0) {
583             for (int i = 0; i < implementedInterfaces.length; i++) {
584                 if (i == 0) {
585                     pTarget.write("implements ");
586                 } else {
587                     pTarget.write(", ");
588                 }
589                 pTarget.write(pTarget.asString(implementedInterfaces[i]));
590                 pTarget.write(" ");
591             }
592         }
593         pTarget.write("{");
594         pTarget.write();
595         
596         IncreasingTarget increasingTarget = new IncreasingTarget(pTarget);
597         for (int i = 0; i < myInnerClasses.length; i++) {
598             increasingTarget.setInterface(myInnerClasses[i].isInterface() ?
599                     Boolean.TRUE : Boolean.FALSE);
600             myInnerClasses[i].write(increasingTarget);
601             increasingTarget.setInterface(null);
602             pTarget.indent(0);
603             pTarget.write();
604         }
605         
606         if (fields != null && fields.length > 0) {
607             for (int i = 0; i < fields.length; i++) {
608                 fields[i].write(increasingTarget);
609                 pTarget.indent(0);
610                 pTarget.write();
611             }
612             pTarget.indent(0);
613             pTarget.write();
614         }
615         
616         for (Iterator JavaDoc iter = myObjects.iterator(); iter.hasNext(); ) {
617             ConditionalIndentationJavaSourceObject object =
618                 (ConditionalIndentationJavaSourceObject) iter.next();
619             object.write(increasingTarget);
620             pTarget.indent(0);
621             pTarget.write();
622         }
623         
624         String JavaDoc[] myRawJavaSources = getRawJavaSources();
625         
626         for (int i = 0; i < myRawJavaSources.length; i++) {
627             for (StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(myRawJavaSources[i], "\r\n");
628             st.hasMoreTokens(); ) {
629                 pTarget.indent(0);
630                 String JavaDoc tok = st.nextToken();
631                 if (tok.length() > 0) {
632                     pTarget.write(tok);
633                 }
634                 pTarget.write();
635             }
636             pTarget.indent(0);
637             pTarget.write();
638         }
639         pTarget.indent(0);
640         pTarget.write("}");
641         pTarget.write();
642     }
643     
644     /** Returns a quoted string constant suitable for embedding
645      * into Java source, but without quotes.
646      */

647     public static String JavaDoc getQuotedNoQuotes(String JavaDoc s) {
648         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
649         for (int i = 0; i < s.length(); i++) {
650             char c = s.charAt(i);
651             if (c == '\n') {
652                 sb.append("\\n");
653             } else if (c == '\\') {
654                 sb.append("\\\\");
655             } else if (c == '\t') {
656                 sb.append("\\t");
657             } else if (c == '\r') {
658                 sb.append("\\r");
659             } else if (c == '\f') {
660                 sb.append("\\f");
661             } else if (c == '\"') {
662                 sb.append("\\\"");
663             } else {
664                 sb.append(c);
665             }
666         }
667         return sb.toString();
668     }
669     
670     /** Returns a quoted string constant suitable for embedding
671      * into Java source.
672      */

673     public static String JavaDoc getQuoted(String JavaDoc s) {
674         return "\"" + getQuotedNoQuotes(s) + "\"";
675     }
676     
677     private java.util.List JavaDoc innerClasses;
678     /** Adds an inner class.
679      */

680     public void addInnerClass(JavaInnerClass pClass) {
681         if (innerClasses == null) {
682             innerClasses = new java.util.ArrayList JavaDoc();
683         }
684         innerClasses.add(pClass);
685     }
686     /** Clears the list of inner classes.
687      */

688     public void clearInnerClasses() {
689         innerClasses = null;
690     }
691     /** Returns the array of inner classes.
692      */

693     public JavaInnerClass[] getInnerClasses() {
694         if (innerClasses == null) {
695             return new JavaInnerClass[0];
696         }
697         return (JavaInnerClass[])
698         innerClasses.toArray(new JavaInnerClass[innerClasses.size()]);
699     }
700     /** Returns the inner class named <code>pName</code>, or
701      * null, if no such class exists.
702      */

703     public JavaInnerClass getInnerClass(String JavaDoc pName) {
704         if (innerClasses == null) {
705             return null;
706         }
707         for (int i = 0; i < innerClasses.size(); i++) {
708             JavaInnerClass jic = (JavaInnerClass) innerClasses.get(i);
709             if (jic.getQName().getInnerClassName().equals(pName)) {
710                 return jic;
711             }
712         }
713         return null;
714     }
715     
716     private boolean isStatic;
717     /** Returns whether this JavaSource is static (for inner classes).
718      */

719     protected boolean getStatic() {
720         return isStatic;
721     }
722     
723     /** Sets whether this JavaSource is static (for inner classes).
724      */

725     public void setStatic(boolean pStatic) {
726         isStatic = pStatic;
727     }
728     
729     private java.util.List JavaDoc rawJavaSources;
730     /** Adds a piece of raw Java source to the class.
731      */

732     public void addRawJavaSource(String JavaDoc pSource) {
733         if (pSource != null && pSource.length() > 0) {
734             if (rawJavaSources == null) {
735                 rawJavaSources = new java.util.ArrayList JavaDoc();
736             }
737             rawJavaSources.add(pSource);
738         }
739     }
740     
741     /** Clears the list of raw Java sources.
742      */

743     public void clearRawJavaSources() {
744         rawJavaSources = null;
745     }
746     
747     /** Returns an array with the pieces of raw Java sources.
748      */

749     public String JavaDoc[] getRawJavaSources() {
750         if (rawJavaSources == null) {
751             return new String JavaDoc[0];
752         }
753         return (String JavaDoc[]) rawJavaSources.toArray(new String JavaDoc[rawJavaSources.size()]);
754     }
755     
756     private boolean bAbstract;
757     /** Returns whether class is abstract.
758      */

759     public boolean isAbstract() {
760         return bAbstract;
761     }
762     /** Sets whether this class is abstract.
763      */

764     public void setAbstract(boolean isAbstract) {
765         this.bAbstract = isAbstract;
766     }
767     
768     /** Returns whether this is an interface or not.
769      */

770     public boolean isInterface() {
771         return INTERFACE.equals(getType());
772     }
773     
774     /** Returns whether the given JavaQName is a local class.
775      * In other words, whether the package name can be omitted
776      * when referencing the class.
777      */

778     public String JavaDoc asString(JavaQName pQName, boolean pAddIfPossible) {
779         return _asString(pQName, pAddIfPossible).replace('$', '.');
780     }
781     
782     private String JavaDoc _asString(JavaQName pQName, boolean pAddIfPossible) {
783         if (isForcingFullyQualifiedName()) {
784             return pQName.toString();
785         }
786         if (pQName.isArray()) {
787             return asString(pQName.getInstanceClass(), pAddIfPossible) + "[]";
788         }
789         if (!pQName.isImportable()) {
790             return pQName.toString();
791         }
792         if ("".equals(pQName.getPackageName())) {
793             return pQName.getClassName();
794         }
795         
796         JavaQName outerQName = pQName;
797         int offset = outerQName.getClassName().indexOf('$');
798         if (offset >= 0) {
799             String JavaDoc className = outerQName.getClassName().substring(0, offset);
800             outerQName = JavaQNameImpl.getInstance(outerQName.getPackageName(), className);
801         }
802         
803         offset = outerQName.getClassName().indexOf('.');
804         if (offset >= 0) {
805             String JavaDoc className = pQName.getClassName().substring(0, offset);
806             outerQName = JavaQNameImpl.getInstance(outerQName.getPackageName(), className);
807         }
808         
809         if (getQName().equals(outerQName)) {
810             return pQName.getClassName();
811         } else if (getQName().getClassName().equals(outerQName.getClassName())) {
812             return pQName.toString();
813         }
814         
815         boolean done = false;
816         boolean imported = false;
817         
818         for (Iterator JavaDoc iter = imports.iterator(); !done && iter.hasNext(); ) {
819             JavaQName jqName = (JavaQName) iter.next();
820             if (jqName.equals(outerQName)) {
821                 done = true;
822                 imported = true;
823             } else if (outerQName.getClassName().equals(jqName.getClassName())) {
824                 done = true;
825                 imported = false;
826             }
827         }
828         
829         if (!done) {
830             String JavaDoc packageName = pQName.getPackageName();
831             if (packageName.equals(getPackageName()) ||
832                     packageName.equals("java.lang")) {
833                 imported = true;
834                 done = true;
835             }
836             if (!done) {
837                 if (pAddIfPossible) {
838                     addImport(outerQName);
839                     done = true;
840                     imported = true;
841                 } else {
842                     done = true;
843                     imported = false;
844                 }
845             }
846         }
847         
848         if (imported) {
849             return pQName.getClassName();
850         } else {
851             return pQName.toString();
852         }
853     }
854     
855     private boolean forcingFullyQualifiedName = false;
856     /** Returns, whether class references are always using the
857      * fully qualified class name.
858      */

859     public boolean isForcingFullyQualifiedName() {
860         return forcingFullyQualifiedName;
861     }
862     /** Sets, whether class references are always using the
863      * fully qualified class name.
864      */

865     public void setForcingFullyQualifiedName(boolean pForcingFullyQualifiedName) {
866         forcingFullyQualifiedName = pForcingFullyQualifiedName;
867     }
868
869     private boolean hasDynamicImports = true;
870     /** Returns, whether the class is automatically adding imports.
871      */

872     public boolean hasDynamicImports() {
873         return hasDynamicImports;
874     }
875     /** Sets, whether the class is automatically adding imports.
876      */

877     public void setDynamicImports(boolean pDynamicImports) {
878         hasDynamicImports = pDynamicImports;
879     }
880     
881     /** Writes the JavaSource contents into the given Writer.
882      */

883     public void write(Writer JavaDoc pTarget) throws IOException JavaDoc {
884         if (hasDynamicImports()) {
885             IndentationTarget devNullTarget = new IndentationTarget(){
886                 public boolean isInterface() { return JavaSource.this.isInterface(); }
887                 public String JavaDoc asString(JavaQName pQName) {
888                     return JavaSource.this.asString(pQName, true);
889                 }
890                 public void write(String JavaDoc pValue) {}
891                 public void write() {}
892                 public void indent(int i) {}
893             };
894             write(devNullTarget);
895         }
896         WriterTarget wt = new WriterTarget(){
897             public boolean isInterface() { return JavaSource.this.isInterface(); }
898             public String JavaDoc asString(JavaQName pQName) {
899                 return JavaSource.this.asString(pQName, false);
900             }
901         };
902         wt.setTarget(pTarget);
903         write(wt);
904     }
905     
906     /** Returns a string representation of this JavaSource file.
907      */

908     public String JavaDoc toString() {
909         StringWriter JavaDoc sw = new StringWriter JavaDoc();
910         try {
911             write(sw);
912             return sw.toString();
913         } catch (IOException JavaDoc e) {
914             throw new IllegalStateException JavaDoc("Unexcpected IOException while writing into a StringWriter: " + e.getMessage());
915         }
916     }
917     
918     /** Creates a new instance of JavaClassInitializer.
919      */

920     public JavaClassInitializer newJavaClassInitializer() {
921         JavaClassInitializer result = new JavaClassInitializer();
922         result.setJavaSource(this);
923         myObjects.add(result);
924         return result;
925     }
926     
927     /** Creates a new JavaConstructor with default protection.
928      */

929     public JavaConstructor newJavaConstructor() {
930         return newJavaConstructor(DEFAULT_PROTECTION);
931     }
932     
933     /** Creates a new JavaConstructor with the given protection.
934      */

935     public JavaConstructor newJavaConstructor(JavaSource.Protection pProtection) {
936         JavaConstructor result = new JavaConstructor(getClassName(), pProtection);
937         result.setJavaSource(this);
938         this.addConstructor(result);
939         return result;
940     }
941     
942     /** Creates a new JavaConstructor with the given protection.
943      * Equivalent to <code>newJavaConstructor(Protection.valueOf(pProtection))</code>.
944      */

945     public JavaConstructor newJavaConstructor(String JavaDoc pProtection) {
946         return newJavaConstructor(Protection.valueOf(pProtection));
947     }
948     
949     /** Creates a new JavaConstructor with the same parameters,
950      * protection and exceptions than the given. Equivalent to
951      * <code>newJavaConstructor(pConstructor, false)</code>.
952      */

953     public JavaConstructor newJavaConstructor(JavaConstructor pConstructor) {
954         return newJavaConstructor(pConstructor, false);
955     }
956     
957     /** Creates a new JavaConstructor with the same signature
958      * than the given constructors. Equivalent to
959      * <code>newJavaConstructor(pConstructor, false)</code>.
960      * If the <code>pSuper</code> argument is true, adds an
961      * invocation of the super classes constructor with the
962      * same arguments.
963      */

964     public JavaConstructor newJavaConstructor(JavaConstructor pConstructor, boolean pSuper) {
965         JavaConstructor result = newJavaConstructor(pConstructor.getProtection());
966         List JavaDoc superParams = pSuper ? new ArrayList JavaDoc() : null;
967         Parameter[] params = pConstructor.getParams();
968         for (int i = 0; i < params.length; i++) {
969             DirectAccessible p = result.addParam(params[i]);
970             if (pSuper) {
971                 if (!superParams.isEmpty()) {
972                     superParams.add(", ");
973                 }
974                 superParams.add(p);
975             }
976         }
977         JavaQName[] exceptions = pConstructor.getExceptions();
978         for (int i = 0; i < exceptions.length; i++) {
979             result.addThrows(exceptions[i]);
980         }
981         if (pSuper) {
982             result.addLine("super(", superParams, ");");
983         }
984         return result;
985     }
986     
987     /** Creates a new JavaMethod with the given name, return
988      * type and default protection.
989      */

990     public JavaMethod newJavaMethod(String JavaDoc pName, String JavaDoc pType) {
991         return newJavaMethod(pName, JavaQNameImpl.getInstance(pType, true), (Protection) null);
992     }
993     
994     /** Creates a new JavaMethod with the given name, return
995      * type and protection.
996      */

997     public JavaMethod newJavaMethod(String JavaDoc pName, String JavaDoc pType, Protection pProtection) {
998         return newJavaMethod(pName, JavaQNameImpl.getInstance(pType, true), pProtection);
999     }
1000    
1001    /** Creates a new JavaMethod with the given name, return
1002     * type and protection.
1003     */

1004    public JavaMethod newJavaMethod(String JavaDoc pName, String JavaDoc pType, String JavaDoc pProtection) {
1005        return newJavaMethod(pName, JavaQNameImpl.getInstance(pType, true),
1006                Protection.valueOf(pProtection));
1007    }
1008    
1009    /** Creates a new JavaMethod with the given name, return
1010     * type and default protection.
1011     */

1012    public JavaMethod newJavaMethod(String JavaDoc pName, JavaQName pType) {
1013        return newJavaMethod(pName, pType, DEFAULT_PROTECTION);
1014    }
1015    
1016    /** Creates a new JavaMethod with the given name, return
1017     * type and protection.
1018     */

1019    public JavaMethod newJavaMethod(String JavaDoc pName, JavaQName pType, Protection pProtection) {
1020        JavaMethod result = new JavaMethod(pName, pType, pProtection);
1021        result.setJavaSource(this);
1022        addMethod(result);
1023        return result;
1024    }
1025    
1026    /** Creates a new JavaMethod with the given name, return
1027     * type and protection.
1028     */

1029    public JavaMethod newJavaMethod(String JavaDoc pName, JavaQName pType, String JavaDoc pProtection) {
1030        JavaMethod result = new JavaMethod(pName, pType, Protection.valueOf(pProtection));
1031        result.setJavaSource(this);
1032        addMethod(result);
1033        return result;
1034    }
1035    
1036    /** Creates a new JavaMethod with the given name, return
1037     * type and default protection.
1038     */

1039    public JavaMethod newJavaMethod(String JavaDoc pName, Class JavaDoc pType) {
1040        return newJavaMethod(pName, JavaQNameImpl.getInstance(pType), DEFAULT_PROTECTION);
1041    }
1042    
1043    /** Creates a new JavaMethod with the given name, return
1044     * type and protection.
1045     */

1046    public JavaMethod newJavaMethod(String JavaDoc pName, Class JavaDoc pType, Protection pProtection) {
1047        return newJavaMethod(pName, JavaQNameImpl.getInstance(pType), pProtection);
1048    }
1049    
1050    /** Creates a new JavaMethod with the given name, return
1051     * type and protection.
1052     */

1053    public JavaMethod newJavaMethod(String JavaDoc pName, Class JavaDoc pType, String JavaDoc pProtection) {
1054        return newJavaMethod(pName, JavaQNameImpl.getInstance(pType),
1055                Protection.valueOf(pProtection));
1056    }
1057    
1058    /** Creates a new JavaMethod with the signature of the given method
1059     * <code>pMethod</code>.
1060     * More precise:
1061     * <ol>
1062     * <li>The name of the created method is <code>pMethod.getName()</code>.</li>
1063     * <li>The return type is set to <code>pMethod.getReturnType()</code>.</li>
1064     * <li>The protection is set to <code>pMethod.
1065     * <li>For any class in <code>pMethod.getParameterTypes()</code>, calls
1066     * {@link JavaMethod#addParam(Class,String)} with the parameter names "p0", "p1", ...</li>
1067     * <li>For any exception in <code>pMethod.getExceptionTypes()</code>, calls
1068     * {@link JavaMethod#addThrows(Class)}.</li>
1069     * </ol>
1070     */

1071    public JavaMethod newJavaMethod(Method JavaDoc pMethod) {
1072        JavaMethod result = newJavaMethod(pMethod.getName(),
1073                JavaQNameImpl.getInstance(pMethod.getReturnType()),
1074                JavaSource.Protection.valueOf(pMethod.getModifiers()));
1075        Class JavaDoc[] parameters = pMethod.getParameterTypes();
1076        if (parameters != null) {
1077            for (int i = 0; i < parameters.length; i++) {
1078                String JavaDoc parameterName = "p" + i;
1079                result.addParam(parameters[i], parameterName);
1080            }
1081        }
1082        Class JavaDoc[] exceptions = pMethod.getExceptionTypes();
1083        if (exceptions != null) {
1084            for (int i = 0; i < exceptions.length; i++) {
1085                result.addThrows(exceptions[i]);
1086            }
1087        }
1088        return result;
1089    }
1090    
1091    /** Creates a new JavaMethod with the given methods name and signature.
1092     * This is useful, for example, if you have an interface and derive an
1093     * implementation. The following values are not cloned:
1094     * {@link JavaMethod#isAbstract()}, {@link JavaMethod#isStatic()},
1095     * {@link JavaMethod#isFinal()}, and {@link JavaMethod#isSynchronized()}.
1096     */

1097    public JavaMethod newJavaMethod(JavaMethod pMethod) {
1098        JavaMethod jm = newJavaMethod(pMethod.getName(), pMethod.getType(), pMethod.getProtection());
1099        Parameter[] params = pMethod.getParams();
1100        for (int i = 0; i < params.length; i++) {
1101            jm.addParam(params[i].getType(), params[i].getName());
1102        }
1103        JavaQName[] exceptions = pMethod.getExceptions();
1104        for (int i = 0; i < exceptions.length; i++) {
1105            jm.addThrows(exceptions[i]);
1106        }
1107        return jm;
1108    }
1109    
1110    /** Creates a new JavaField with the given name, type and
1111     * protection.
1112     */

1113    public JavaField newJavaField(String JavaDoc pName, JavaQName pType, Protection pProtection) {
1114        JavaField result = new JavaField(pName, pType, pProtection);
1115        result.setJavaSource(this);
1116        addField(result);
1117        return result;
1118    }
1119    
1120    /** Creates a new JavaField with the given name, type and
1121     * protection.
1122     */

1123    public JavaField newJavaField(String JavaDoc pName, JavaQName pType, String JavaDoc pProtection) {
1124        JavaField result = new JavaField(pName, pType, Protection.valueOf(pProtection));
1125        result.setJavaSource(this);
1126        addField(result);
1127        return result;
1128    }
1129    
1130    /** Creates a new JavaField with the given name, type and
1131     * default protection.
1132     */

1133    public JavaField newJavaField(String JavaDoc pName, JavaQName pType) {
1134        return newJavaField(pName, pType, DEFAULT_PROTECTION);
1135    }
1136    
1137    /** Creates a new JavaField with the given name, type and
1138     * protection.
1139     */

1140    public JavaField newJavaField(String JavaDoc pName, String JavaDoc pType, Protection pProtection) {
1141        return newJavaField(pName, JavaQNameImpl.getInstance(pType, true), pProtection);
1142    }
1143    
1144    /** Creates a new JavaField with the given name, type and
1145     * protection.
1146     */

1147    public JavaField newJavaField(String JavaDoc pName, String JavaDoc pType, String JavaDoc pProtection) {
1148        return newJavaField(pName, JavaQNameImpl.getInstance(pType, true),
1149                Protection.valueOf(pProtection));
1150    }
1151    
1152    /** Creates a new JavaField with the given name, type and
1153     * default protection.
1154     */

1155    public JavaField newJavaField(String JavaDoc pName, String JavaDoc pType) {
1156        return newJavaField(pName, JavaQNameImpl.getInstance(pType, true), (Protection) null);
1157    }
1158    
1159    /** Creates a new JavaField with the given name, type and
1160     * protection.
1161     */

1162    public JavaField newJavaField(String JavaDoc pName, Class JavaDoc pType, JavaSource.Protection pProtection) {
1163        return newJavaField(pName, JavaQNameImpl.getInstance(pType), pProtection);
1164    }
1165    
1166    /** Creates a new JavaField with the given name, type and
1167     * protection. Equivalent to <code>newJavaField(pName, pType,
1168     * Protection.valueOf(pProtecttion)</code>.
1169     */

1170    public JavaField newJavaField(String JavaDoc pName, Class JavaDoc pType, String JavaDoc pProtection) {
1171        return newJavaField(pName, JavaQNameImpl.getInstance(pType),
1172                Protection.valueOf(pProtection));
1173    }
1174    
1175    /** Creates a new JavaField with the given name, type and
1176     * default protection.
1177     */

1178    public JavaField newJavaField(String JavaDoc pName, Class JavaDoc pType) {
1179        return newJavaField(pName, JavaQNameImpl.getInstance(pType));
1180    }
1181    
1182    /** Creates a new JavaInnerClass with the given name and
1183     * default protection.
1184     */

1185    public JavaInnerClass newJavaInnerClass(String JavaDoc pName) {
1186        return newJavaInnerClass(pName, DEFAULT_PROTECTION);
1187    }
1188    
1189    /** Creates a new JavaInnerClass with the given name and
1190     * protection.
1191     */

1192    public JavaInnerClass newJavaInnerClass(String JavaDoc pName, Protection pProtection) {
1193        JavaQName innerClassName = JavaQNameImpl.getInnerInstance(getQName(), pName);
1194        JavaInnerClass result = new JavaInnerClass(this, innerClassName, pProtection);
1195        addInnerClass(result);
1196        return result;
1197    }
1198    
1199    /** Creates a new JavaInnerClass with the given name and
1200     * protection.
1201     */

1202    public JavaInnerClass newJavaInnerClass(String JavaDoc pName, String JavaDoc pProtection) {
1203        return newJavaInnerClass(pName, Protection.valueOf(pProtection));
1204    }
1205    
1206    /** Returns, whether this is an inner class.
1207     */

1208    public boolean isInnerClass() {
1209        return false;
1210    }
1211    /** Creates a new Java property with the given type and name.
1212     * Shortcut for
1213     * <pre>
1214     * String upperCaseName = Character.toUpperCase(pName.charAt(0)) +
1215     * pName.substring(1);
1216     * if (JavaQNameImpl.VOID.equals(pType)) {
1217     * newBeanProperty(pType, pName, "is" + upperCaseName, "set" + upperCaseName);
1218     * } else {
1219     * newBeanProperty(pType, pName, "get" + upperCaseName, "set" + upperCaseName);
1220     * }
1221     * </pre>
1222     */

1223    public void newBeanProperty(JavaQName pType, String JavaDoc pName) {
1224        String JavaDoc upperCaseName = Character.toUpperCase(pName.charAt(0)) + pName.substring(1);
1225        if (JavaQNameImpl.VOID.equals(pType)) {
1226            newBeanProperty(pType, pName, "is" + upperCaseName, "set" + upperCaseName);
1227        } else {
1228            newBeanProperty(pType, pName, "get" + upperCaseName, "set" + upperCaseName);
1229        }
1230    }
1231    
1232    /** Shortcut for <code>newBeanProperty(JavaQNameImpl.getInstance(pClass), pName)</code>.
1233     * @see #newBeanProperty(JavaQName, String)
1234     */

1235    public void newBeanProperty(Class JavaDoc pClass, String JavaDoc pName) {
1236        newBeanProperty(JavaQNameImpl.getInstance(pClass), pName);
1237    }
1238    
1239    /** Shortcut for
1240     * <pre>
1241     * newJavaField(pFieldName, pType, JavaSource.PRIVATE);
1242     * JavaMethod getMethod = newJavaMethod(pGetMethodName, pType, JavaSource.PUBLIC);
1243     * getMethod.addLine("return this.", pFieldName, ";");
1244     * JavaMethod setMethod = newJavaMethod(pSetMethodName, JavaQNameImpl.VOID, JavaSource.PUBLIC);
1245     * setMethod.addParam(pType, pFieldName);
1246     * setMethod.addLine("this.", pFieldName, " = ", pFieldName, ";");
1247     * </pre>
1248     * @param pType The property type
1249     * @param pFieldName The name of the generated field. The generated field has private
1250     * access.
1251     * @param pGetMethodName The name of the generated get method or null, if no such
1252     * method is being created.
1253     * @param pSetMethodName The name of the generated set method or null, if no such
1254     * method is being created.
1255     */

1256    public void newBeanProperty(JavaQName pType, String JavaDoc pFieldName,
1257            String JavaDoc pGetMethodName, String JavaDoc pSetMethodName) {
1258        newJavaField(pFieldName, pType, JavaSource.PRIVATE);
1259        if (pGetMethodName != null) {
1260            JavaMethod getMethod = newJavaMethod(pGetMethodName, pType, JavaSource.PUBLIC);
1261            getMethod.addLine("return this.", pFieldName, ";");
1262        }
1263        if (pSetMethodName != null) {
1264            JavaMethod setMethod = newJavaMethod(pSetMethodName, JavaQNameImpl.VOID, JavaSource.PUBLIC);
1265            setMethod.addParam(pType, pFieldName);
1266            setMethod.addLine("this.", pFieldName, " = ", pFieldName, ";");
1267        }
1268    }
1269    
1270    /** Shortcut for <code>newBeanProperty(JavaQNameImpl.getInstance(pClass),
1271     * pFieldName, pGetMethodName, pSetMethodName)</code>.
1272     * @see #newBeanProperty(JavaQName, String, String, String)
1273     */

1274    public void newBeanProperty(Class JavaDoc pClass, String JavaDoc pFieldName,
1275            String JavaDoc pGetMethodName, String JavaDoc pSetMethodName) {
1276        newBeanProperty(JavaQNameImpl.getInstance(pClass), pFieldName, pGetMethodName,
1277                pSetMethodName);
1278    }
1279}
1280
Popular Tags