Source code: org/apache/axis/wsdl/toJava/JavaClassWriter.java
1 /*
2 * Copyright 2001-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.axis.wsdl.toJava;
17
18 import org.apache.axis.Version;
19 import org.apache.axis.utils.Messages;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.io.PrintWriter;
24
25 /**
26 * Emitter knows about WSDL writers, one each for PortType, Binding, Service,
27 * Definition, Type. But for some of these WSDL types, Wsdl2java generates
28 * multiple files. Each of these files has a corresponding writer that extends
29 * JavaWriter. So the Java WSDL writers (JavaPortTypeWriter, JavaBindingWriter,
30 * etc.) each calls a file writer (JavaStubWriter, JavaSkelWriter, etc.) for
31 * each file that that WSDL generates.
32 * <p/>
33 * <p>For example, when Emitter calls JavaWriterFactory for a Binding Writer, it
34 * returns a JavaBindingWriter. JavaBindingWriter, in turn, contains a
35 * JavaStubWriter, JavaSkelWriter, and JavaImplWriter since a Binding may cause
36 * a stub, skeleton, and impl template to be generated.
37 * <p/>
38 * <p>Note that the writers that are given to Emitter by JavaWriterFactory DO NOT
39 * extend JavaWriter. They simply implement Writer and delegate the actual
40 * task of writing to extensions of JavaWriter.
41 * <p/>
42 * <p>All of Wsdl2java's Writer implementations follow a common behaviour.
43 * JavaWriter is the abstract base class that dictates this common behaviour.
44 * Many of the files generated are .java files, so this abstract class -
45 * JavaClassWriter - exists. It extends JavaWriter and adds a bit of Java-
46 * relative behaviour. This behaviour is primarily placed within the generate
47 * method. The generate method calls, in succession (note: the starred methods
48 * are the ones you are probably most interested in):
49 * <dl>
50 * <dt> getFileName
51 * <dd> This method is abstract in JavaWriter, but JavaClassWriter implements
52 * this method. Subclasses should have no need to override it. It
53 * returns the fully-qualified file name based on the fully-qualified
54 * classname + ".java".
55 * <dt> isFileGenerated(file)
56 * <dd> You should not need to override this method. It checks to see whether
57 * this file is in the List returned by emitter.getGeneratedFileNames.
58 * <dt> registerFile(file)
59 * <dd> You should not need to override this method. It registers this file by
60 * calling emitter.getGeneratedFileInfo().add(...).
61 * <dt> * verboseMessage(file)
62 * <dd> You may override this method if you want to provide more information.
63 * The generate method only calls verboseMessage if verbose is turned on.
64 * <dt> getPrintWriter(file)
65 * <dd> You should not need to override this method. Given the file name, it
66 * creates a PrintWriter for it.
67 * <dt> writeFileHeader(pw)
68 * <dd> JavaClassWriter implements this method, so you should not need to
69 * override it. This method generates a javadoc giving the filename and
70 * a comment stating that this file is generated by WSDL2Java, and it
71 * generates the class definition including the opening curly brace..
72 * <dt> * writeFileBody(pw)
73 * <dd> This is an abstract method that must be implemented by the subclass.
74 * This is where the body of a file is generated.
75 * <dt> * writeFileFooter(pw)
76 * <dd> JavaClassWriter implements this method, so you should not need to
77 * override it. It generates the closing curly brace for the class.
78 * <dt> closePrintWriter(pw)
79 * <dd> You should not need to override this method. It simply closes the
80 * PrintWriter.
81 * </dl>
82 * <p/>
83 * Additional behaviour that JavaClassWriter introduces beyond JavaWriter is
84 * related to the class header and definition:
85 * <dl>
86 * <dt> writeHeaderComments
87 * <dd> Write the header comments, such as the file name and that the file was
88 * generated by WSDL2Java. You need not override this method unless you
89 * want a tailored comment.
90 * <dt> writePackage
91 * <dd> Write the package statement, if necessary. You should not need to
92 * override this method.
93 * <dt> getClassModifiers
94 * <dd> Modifiers, such as "public", "final", "abstract" would be returned by
95 * this method. The default implementation only generates "public ", so
96 * any subclass that needs more must override this method.
97 * <dt> getClassText
98 * <dd> This simply returns "class ". If anything else is desired, for
99 * instance, JavaInterfaceWriter prefers "interface ", then this method
100 * must be overridden.
101 * <dt> getExtendsText
102 * <dd> The default implementation returns "". If a subclass desires to list
103 * a set of classes this one extends, then this method must be overridden.
104 * <dt> getImplementsText
105 * <dd> Same as getExtendsText except for the implements clause.
106 * </dl>
107 */
108 public abstract class JavaClassWriter extends JavaWriter {
109
110 /** Field namespaces */
111 protected Namespaces namespaces;
112
113 /** Field className */
114 protected String className;
115
116 /** Field packageName */
117 protected String packageName;
118
119 /**
120 * Constructor.
121 *
122 * @param emitter The emitter instance
123 * @param fullClassName The fully qualified class name of the class
124 * to be generated.
125 * @param type
126 */
127 protected JavaClassWriter(Emitter emitter, String fullClassName,
128 String type) {
129
130 super(emitter, type);
131
132 this.namespaces = emitter.getNamespaces();
133 this.packageName = Utils.getJavaPackageName(fullClassName);
134 this.className = Utils.getJavaLocalName(fullClassName);
135 } // ctor
136
137 /**
138 * Return the file name as a string of the form:
139 * "<directory-ized fully-qualified classname>.java"
140 *
141 * @return
142 */
143 protected String getFileName() {
144 return namespaces.toDir(packageName) + className + ".java";
145 } // getFileName
146
147 /**
148 * You should not need to override this method.
149 * It registers the given file by calling
150 * emitter.getGeneratedFileInfo().add(...).
151 * JavaClassWriter overrides this method from JavaWriter because
152 * it add class name to the registration information.
153 *
154 * @param file
155 */
156 protected void registerFile(String file) {
157
158 final String pkg = getPackage();
159 String fqClass;
160 if (pkg != null && pkg.length() > 0) {
161 fqClass = pkg + '.' + getClassName();
162 } else {
163 fqClass = getClassName();
164 }
165
166 emitter.getGeneratedFileInfo().add(file, fqClass, type);
167 } // registerFile
168
169 /**
170 * Write a common header, including the package name, the class
171 * declaration, and the opening curly brace.
172 *
173 * @param pw
174 * @throws IOException
175 */
176 protected void writeFileHeader(PrintWriter pw) throws IOException {
177
178 writeHeaderComments(pw);
179 writePackage(pw);
180
181 // print class declaration
182 pw.println(getClassModifiers() + getClassText() + getClassName() + ' '
183 + getExtendsText() + getImplementsText() + "{");
184 } // writeFileHeader
185
186 /**
187 * Write the header comments.
188 *
189 * @param pw
190 * @throws IOException
191 */
192 protected void writeHeaderComments(PrintWriter pw) throws IOException {
193
194 String localFile = getFileName();
195 int lastSepChar = localFile.lastIndexOf(File.separatorChar);
196
197 if (lastSepChar >= 0) {
198 localFile = localFile.substring(lastSepChar + 1);
199 }
200
201 pw.println("/**");
202 pw.println(" * " + localFile);
203 pw.println(" *");
204 pw.println(" * " + Messages.getMessage("wsdlGenLine00"));
205 pw.println(" * "
206 + Messages.getMessage("wsdlGenLine01",
207 Version.getVersionText()));
208 pw.println(" */");
209 pw.println();
210 } // writeHeaderComments
211
212 /**
213 * Write the package declaration statement.
214 *
215 * @param pw
216 * @throws IOException
217 */
218 protected void writePackage(PrintWriter pw) throws IOException {
219
220 final String pkg = getPackage();
221 if (pkg != null && pkg.length() > 0) {
222 pw.println("package " + pkg + ";");
223 pw.println();
224 }
225 } // writePackage
226
227 /**
228 * Return "public ". If more modifiers are needed, this method must be
229 * overridden.
230 *
231 * @return
232 */
233 protected String getClassModifiers() {
234 return "public ";
235 } // getClassModifiers
236
237 /**
238 * Return "class ". If "interface " is needed instead, this method must be
239 * overridden.
240 *
241 * @return
242 */
243 protected String getClassText() {
244 return "class ";
245 } // getClassString
246
247 /**
248 * Returns the appropriate extends clause. This default implementation
249 * simply returns "", but if you want "extends <class/interface list> "
250 * then you must override this method.
251 *
252 * @return ""
253 */
254 protected String getExtendsText() {
255 return "";
256 } // getExtendsText
257
258 /**
259 * Returns the appropriate implements clause. This default implementation
260 * simply returns "", but if you want "implements <interface list> " then
261 * you must override this method.
262 *
263 * @return ""
264 */
265 protected String getImplementsText() {
266 return "";
267 } // getImplementsText
268
269 /**
270 * Returns the package name.
271 *
272 * @return
273 */
274 protected String getPackage() {
275 return packageName;
276 } // getPackage
277
278 /**
279 * Returns the class name.
280 *
281 * @return
282 */
283 protected String getClassName() {
284 return className;
285 } // getClassName
286
287 /**
288 * Generate the closing curly brace.
289 *
290 * @param pw
291 * @throws IOException
292 */
293 protected void writeFileFooter(PrintWriter pw) throws IOException {
294 super.writeFileFooter(pw);
295 pw.println('}');
296 } // writeFileFooter
297 } // abstract class JavaClassWriter