All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.axis.wsdl.toJava.JavaWriter Maven / Gradle / Ivy

/*
 * Copyright 2001-2004 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.axis.wsdl.toJava;

import org.apache.axis.utils.Messages;
import org.apache.axis.wsdl.gen.Generator;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import java.io.*;
import java.util.StringTokenizer;

/**
 * Emitter knows about WSDL writers, one each for PortType, Binding, Service,
 * Definition, Type.  But for some of these WSDL types, Wsdl2java generates
 * multiple files.  Each of these files has a corresponding writer that extends
 * JavaWriter.  So the Java WSDL writers (JavaPortTypeWriter, JavaBindingWriter,
 * etc.) each calls a file writer (JavaStubWriter, JavaSkelWriter, etc.) for
 * each file that that WSDL generates.
 * 

*

For example, when Emitter calls JavaWriterFactory for a Binding Writer, it * returns a JavaBindingWriter. JavaBindingWriter, in turn, contains a * JavaStubWriter, JavaSkelWriter, and JavaImplWriter since a Binding may cause * a stub, skeleton, and impl template to be generated. *

*

Note that the writers that are given to Emitter by JavaWriterFactory DO NOT * extend JavaWriter. They simply implement Writer and delegate the actual * task of writing to extensions of JavaWriter. *

*

All of Wsdl2java's Writer implementations follow a common behaviour. * JavaWriter is the abstract base class that dictates this common behaviour. * This behaviour is primarily placed within the generate method. The generate * method calls, in succession (note: the starred methods are the ones you are * probably most interested in): *

*
* getFileName *
This is an abstract method that must be implemented by the subclass. * It returns the fully-qualified file name. *
isFileGenerated(file) *
You should not need to override this method. It checks to see whether * this file is in the List returned by emitter.getGeneratedFileNames. *
registerFile(file) *
You should not need to override this method. It registers this file by * calling emitter.getGeneratedFileInfo().add(...). *
* verboseMessage(file) *
You may override this method if you want to provide more information. * The generate method only calls verboseMessage if verbose is turned on. *
getPrintWriter(file) *
You should not need to override this method. Given the file name, it * creates a PrintWriter for it. *
* writeFileHeader(pw) *
You may want to override this method. The default implementation * generates nothing. *
* writeFileBody(pw) *
This is an abstract method that must be implemented by the subclass. * This is where the body of a file is generated. *
* writeFileFooter(pw) *
You may want to override this method. The default implementation * generates nothing. *
closePrintWriter(pw) *
You should not need to override this method. It simply closes the * PrintWriter. *
*/ public abstract class JavaWriter implements Generator { /** This controls how many characters per line for javadoc comments */ protected final static int LINE_LENGTH = 65; /** Field emitter */ protected Emitter emitter; /** Field type */ protected String type; /** * Constructor. * * @param emitter * @param type */ protected JavaWriter(Emitter emitter, String type) { this.emitter = emitter; this.type = type; } // ctor /** * Generate a file. * * @throws IOException */ public void generate() throws IOException { String file = getFileName(); if (isFileGenerated(file)) { throw new DuplicateFileException( Messages.getMessage("duplicateFile00", file), file); } registerFile(file); if (emitter.isVerbose()) { String msg = verboseMessage(file); if (msg != null) { System.out.println(msg); } } PrintWriter pw = getPrintWriter(file); writeFileHeader(pw); writeFileBody(pw); writeFileFooter(pw); closePrintWriter(pw); } // generate /** * This method must be implemented by a subclass. It * returns the fully-qualified name of the file to be * generated. * * @return */ protected abstract String getFileName(); /** * You should not need to override this method. It checks * to see whether the given file is in the List returned * by emitter.getGeneratedFileNames. * * @param file * @return */ protected boolean isFileGenerated(String file) { return emitter.getGeneratedFileNames().contains(file); } // isFileGenerated /** * You should not need to override this method. * It registers the given file by calling * emitter.getGeneratedFileInfo().add(...). * * @param file */ protected void registerFile(String file) { emitter.getGeneratedFileInfo().add(file, null, type); } // registerFile /** * Return the string: "Generating ". Override this * method if you want to provide more information. * * @param file * @return */ protected String verboseMessage(String file) { return Messages.getMessage("generating", file); } // verboseMessage /** * You should not need to override this method. * Given the file name, it creates a PrintWriter for it. * * @param filename * @return * @throws IOException */ protected PrintWriter getPrintWriter(String filename) throws IOException { File file = new File(filename); File parent = new File(file.getParent()); parent.mkdirs(); FileOutputStream out = new FileOutputStream(file); OutputStreamWriter writer = new OutputStreamWriter(out, "UTF-8"); return new PrintWriter(writer); } // getPrintWriter /** * This method is intended to be overridden as necessary * to generate file header information. This default * implementation does nothing. * * @param pw * @throws IOException */ protected void writeFileHeader(PrintWriter pw) throws IOException { } // writeFileHeader /** * This method must be implemented by a subclass. This * is where the body of a file is generated. * * @param pw * @throws IOException */ protected abstract void writeFileBody(PrintWriter pw) throws IOException; /** * You may want to override this method. This default * implementation generates nothing. * * @param pw * @throws IOException */ protected void writeFileFooter(PrintWriter pw) throws IOException { } // writeFileFooter /** * Close the print writer. * * @param pw */ protected void closePrintWriter(PrintWriter pw) { pw.close(); } // closePrintWriter /** * Takes out new lines and wraps at Javadoc tags * @param documentation the raw comments from schema * @param addTab if true adds a tab character when wrapping (methods) */ protected String getJavadocDescriptionPart(String documentation, boolean addTab) { if (documentation == null) { return ""; } String doc = documentation.trim(); if (documentation.trim().length() == 0) { //nothing to do return doc; } // make @ tags start a new line (for javadoc tags mostly) StringTokenizer st = new StringTokenizer(doc, "@"); StringBuffer newComments; if (st.hasMoreTokens()) { String token = st.nextToken(); boolean startLine = Character.isWhitespace(token.charAt(token.length() - 1)) && (token.charAt(token.length() - 1) != '\n'); newComments = new StringBuffer(token); while (st.hasMoreTokens()) { token = st.nextToken(); // don't span links across lines if (startLine) { newComments.append('\n'); } newComments.append('@'); startLine = Character.isWhitespace(token.charAt(token.length() - 1)) & (token.charAt(token.length() - 1) != '\n'); newComments.append(token); } } else { newComments = new StringBuffer(doc); } newComments.insert(0, addTab ? " * " : " * "); // tweak comment ending tags by insterting a // space between the star and the slash, BUG13407 int pos = newComments.toString().indexOf("*/"); while (pos >= 0) { newComments.insert(pos + 1, ' '); pos = newComments.toString().indexOf("*/"); } // now pretty it up based on column length int lineStart = 0; int newlinePos = 0; while (lineStart < newComments.length()) { newlinePos = newComments.toString().indexOf("\n", lineStart); if (newlinePos == -1) { newlinePos = newComments.length(); } if ((newlinePos - lineStart) > LINE_LENGTH) { // find first whitespace after length lineStart += LINE_LENGTH; while ((lineStart < newComments.length()) && !Character.isWhitespace(newComments.charAt(lineStart))) { lineStart++; } if (lineStart < newComments.length()) { // don't insert if line wold break at EOF char next = newComments.charAt(lineStart); // insert new line header if ((next == '\r') || (next == '\n')) { //newline exists at the break point, don't put in another one newComments.insert(lineStart + 1, addTab ? " * " : " * "); lineStart += addTab ? 8 : 4; } else { newComments.insert(lineStart, addTab ? "\n * " : "\n * "); lineStart += addTab ? 8 : 4; } } // chew up witespace after newline while ((lineStart < newComments.length()) && (newComments.charAt(lineStart) == ' ')) { // only chew up simple spaces newComments.delete(lineStart, lineStart + 1); } } else { if (++newlinePos < newComments.length()) { newComments.insert(newlinePos, addTab ? " * " : " * "); } lineStart = newlinePos; lineStart += addTab ? 7 : 3; } } return newComments.toString(); } /** * Output a documentation element as a Java comment. * * @param pw * @param element */ protected void writeComment(PrintWriter pw, Element element) { writeComment(pw, element, true); } /** * Output a documentation element as a Java comment. * * @param pw * @param element * @param addTab */ protected void writeComment(PrintWriter pw, Element element, boolean addTab) { if (element == null) { return; } Node child = element.getFirstChild(); if (child == null) { return; } String comment = child.getNodeValue(); if (comment != null) { int start = 0; pw.println(); // blank line pw.println(addTab ? " /**" : "/**"); pw.println(getJavadocDescriptionPart(comment, addTab)); pw.println(addTab ? " */" : " */"); } } // writeComment } // abstract class JavaWriter




© 2015 - 2025 Weber Informatics LLC | Privacy Policy