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

org.enhydra.xml.xmlc.codegen.JavaClass Maven / Gradle / Ivy

The newest version!
/*
 * Enhydra Java Application Server Project
 * 
 * The contents of this file are subject to the Enhydra Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License on
 * the Enhydra web site ( http://www.enhydra.org/ ).
 * 
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 
 * the License for the specific terms governing rights and limitations
 * under the License.
 * 
 * The Initial Developer of the Enhydra Application Server is Lutris
 * Technologies, Inc. The Enhydra Application Server and portions created
 * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
 * All Rights Reserved.
 * 
 * Contributor(s):
 * 
 * $Id: JavaClass.java,v 1.2 2005/01/26 08:29:24 jkjome Exp $
 */

package org.enhydra.xml.xmlc.codegen;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import org.enhydra.xml.xmlc.misc.ReadIterator;

// FIXME: Add trackin of source files to this file.

/**
 * Object that is used to assemble the Java source for a class.  Able to
 * generate either a stand-alone class, or an interface and an implementation
 * of that interface
 */
public final class JavaClass {
    /** Attributes of the class */
    protected String fPackageName;
    protected String fName;
    protected int fModifiers;
    protected String[] fDoc;

    /**
     * Imports to use for the class but not the interface,
     */
    private TreeSet fClassImports = new TreeSet();

    /**
     * Imports to for both class and interface.
     */
    private TreeSet fImports = new TreeSet();

    /**
     * Class that this class extends, or null.
     */
    private String fExtends;

    /**
     * If the class is also going to have an associated generated
     * interface, this is its name.
     */
    private String fInterface;

    /**
     * List of interfaces that this class extends.
     */
    private TreeSet fImplements = new TreeSet();

    /**
     * Fields associated with the class.
     */
    private TreeMap fFields = new TreeMap();

    /**
     * Class initializer.
     */
    private JavaCode fClassInitializer = new JavaCode();;

    /**
     * Constructors associated with the class.
     */
    private ArrayList fConstructors = new ArrayList();

    /**
     * Methods associated with the class.
     */
    private TreeMap fMethods = new TreeMap();

    /**
     * Constructor.
     * @param packageName package for the class, or null for default package.
     * @param name class name
     * @param modifiers class modifier bit set.
     * @param doc Class documentation, each row becomes a line of
     * documentation.
     * @see JavaModifiers
     */
    public JavaClass(String packageName,
                     String name,
                     int modifiers,
                     String[] doc) {
        fPackageName = packageName;
        if (fPackageName.length() == 0) {
            fPackageName = null;  // Force default
        }
        fName = name;
        fModifiers = modifiers;
        fDoc = (String[])doc.clone();
    }

    /**
     * Set the interface name for the associated generated interface.
     */
    public void setInterface(String interfaceName) {
        fInterface = interfaceName;
    }

    /**
     * Add an class imports to the class.  These will not be in
     * any generated interface.
     * @param importSpec Name package, class, or package.* to import.
     *  Should not include import keyword.  Duplicates will be discarded.
     */
    public void addClassImport(String importSpec) {
        fClassImports.add(importSpec);
    }

    /**
     * Add a set of class imports.  These will not be in
     * any generated interface.
     * @param importSpecs Names of packages, classes, or package.* to import.
     *  Should not include import keyword.
     */
    public void addClassImports(String[] importSpecs) {
        for (int idx = 0; idx < importSpecs.length; idx++) {
            addClassImport(importSpecs[idx]);
        }
    }

    /**
     * Add an import to the class and interface.
     * @param importSpec Name package, class, or package.* to import.
     *  Should not include import keyword.  Duplicates will be discarded.
     */
    public void addImport(String importSpec) {
        fImports.add(importSpec);
    }

    /**
     * Add a set of imports.
     * @param importSpecs Names of packages, classes, or package.* to import.
     *  Should not include import keyword.  Duplicates will be discarded.
     */
    public void addImports(String[] importSpecs) {
        for (int idx = 0; idx < importSpecs.length; idx++) {
            addImport(importSpecs[idx]);
        }
    }

    /**
     * Set the class that this class extends.
     */
    public void setExtends(String extendsName) {
        fExtends = extendsName;
    }

    /**
     * Add a interface that the class will implement.
     */
    public void addImplements(String implementsName) {
        fImplements.add(implementsName);
    }

    /**
     * Add a list of interface for this class to implement.
     */
    public void addImplements(String[] implementsName) {
        for (int idx = 0; idx < implementsName.length; idx++) {
            fImplements.add(implementsName[idx]);
        }
    }

    /**
     * Add a field to the class.
     */
    public void addField(JavaField field) {
        fFields.put(field.getName(), field);
    }

    /**
     * Add a constructor.
     */
    public void addConstructor(JavaMethod method) {
        fConstructors.add(method);
    }

    /**
     * Add a method.
     */
    public void addMethod(JavaMethod method) {
        fMethods.put(method.getName(), method);
    }

    /**
     * Get the name.
     */
    public String getName() {
        return fName;
    }

    /**
     * Get the modifiers.
     */
    public int getModifiers() {
        return fModifiers;
    }

    /**
     * Get the documentation, or null if there is none.
     */
    public String[] getDoc() {
        return (fDoc == null) ? null : (String[])fDoc.clone();
    }

    /**
     * Get the fields, sorted by field name.
     */
    public Iterator getFields() {
        return new ReadIterator(fFields.values().iterator());
    }

    /**
     * Get the class initializer.
     */
    public JavaCode getClassInitializer() {
        return fClassInitializer;
    }

    /**
     * Get the constructors
     */
    public Iterator getConstructors() {
        return new ReadIterator(fConstructors.listIterator());
    }
    
    /**
     * Get the methods, sorted by method name.
     */
    public Iterator getMethods() {
        return new ReadIterator(fMethods.values().iterator());
    }

    /**
     * Output a set of imports.
     */
    private void printImports(IndentWriter out,
                              Set importSet) {
        Iterator imports = importSet.iterator();
        while (imports.hasNext()) {
            out.print("import ");
            out.print((String)imports.next());
            out.println(';');
        }
    }
    
    /**
     * Print the package, imports and comment.
     */
    private void printStart(IndentWriter out,
                            boolean forInterface) {
        // Package and imports.
        if (fPackageName != null) {
            out.print("package ");
            out.print(fPackageName);
            out.println(';');
            out.println();
        }

        printImports(out, fImports);
        if (!forInterface) {
            printImports(out, fClassImports);
        }
        out.println();

        // Print class comment
        out.println("/**");
        for (int idx = 0; idx < fDoc.length; idx++) {
            out.print(" * ");
            out.println(fDoc[idx]);
        }
        out.println(" */");
    }

    /**
     * Generate `implements' clause for classes or `extends' clause for
     * interfaces.
     */
    private void printImplExtends(IndentWriter out,
                                  String keyword,
                                  String single,
                                  Set set) {
        boolean printedKeyword = false;
        if (single != null) {
            out.print(' ');
            out.print(keyword);
            out.print(' ');
            printedKeyword = true;
            out.print(single);
        }
        Iterator items = set.iterator();
        while (items.hasNext()) {
            if (!printedKeyword) {
                out.print(' ');
                out.print(keyword);
                out.print(' ');
                printedKeyword = true;
            } else {
                out.print(", ");
            }
            out.print((String)items.next());
        }
    }
    
    /**
     * Print the class declaration.
     */
    private void printClassDecl(IndentWriter out) {
        out.print(JavaModifiers.toDecl(fModifiers));
        out.print("class ");
        out.print(fName);
        if (fExtends != null) {
            out.print(" extends ");
            out.print(fExtends);
        }

        printImplExtends(out, "implements", fInterface, fImplements);
        out.println(" {");
    }

    /**
     * Print the interface declaration.
     */
    private void printInterfaceDecl(IndentWriter out) {
        out.print(JavaModifiers.toDecl(fModifiers));
        out.print("interface ");
        out.print(fInterface);

        printImplExtends(out, "extends", null, fImplements);
        out.println(" {");
    }

    /**
     * Print the fields
     */
    private void printFields(IndentWriter out,
                             int omitFlags) {
        Iterator fields = getFields();
        while (fields.hasNext()) {
            JavaField field = (JavaField)fields.next();
            if ((field.getModifiers() & omitFlags) == 0) {
                field.print(out);
            }
        }
    }

    /**
     * Print the class initializer
     */
    private void printClassInitializer(IndentWriter out,
                                       boolean printMethodBodies) {
        if (printMethodBodies && !fClassInitializer.isEmpty()) {
            out.println("/*");
            out.println(" * Class initializer.");
            out.println(" */");
            out.println("static {");
            out.enter();
            fClassInitializer.print(out);
            out.leave();
            out.println("}");
            out.println();
        }
    }

    /**
     * Print the constructors
     */
    private void printConstructors(IndentWriter out,
                                   boolean printMethodBodies,
                                   int omitFlags) {
        Iterator constrs = getConstructors();
        while (constrs.hasNext()) {
            JavaMethod method = (JavaMethod)constrs.next();
            if ((method.getModifiers() & omitFlags) == 0) {
                method.print(out, printMethodBodies);
            }
        }
    }
  
    /**
     * Print the methods
     */
    private void printMethods(IndentWriter out,
                              boolean printMethodBodies,
                              int omitFlags) {
        Iterator methods = getMethods();
        while (methods.hasNext()) { 
            JavaMethod method = (JavaMethod)methods.next();
            if ((method.getModifiers() & omitFlags) == 0) {
                method.print(out, printMethodBodies);
            }
        }
    }
  
    /**
     * Print the body of a class, interface, or implementation.
     * @param printMethodBodies If true, print the body of methods, if false
     *  don't print the bodies.
     * @param omitFlags If any of these modifier flags are set, the
     *  method or field is omitted.
     */
    private void printBody(IndentWriter out,
                           boolean printMethodBodies,
                           int omitFlags) {
        out.enter();
        printFields(out, omitFlags);
        printClassInitializer(out, printMethodBodies);
        printConstructors(out, printMethodBodies, omitFlags);
        printMethods(out, printMethodBodies, omitFlags);
        out.leave();
        out.println('}');
    }

    /**
     * Output a generated class which doesn't have a corresponding
     * interface.
     */
    public void printClass(IndentWriter out) {
        printStart(out, false);
        printClassDecl(out);
        printBody(out, true, 0);
    }

    /**
     * Output a generated interface.
     */
    public void printInterface(IndentWriter out) {
        printStart(out, true);
        printInterfaceDecl(out);
        printBody(out, false, JavaModifiers.OMIT_INTERFACE);
    }

    /**
     * Output a generated class which has an interface.
     */
    public void printImplementation(IndentWriter out) {
        printStart(out, false);
        printClassDecl(out);
        printBody(out, true, JavaModifiers.OMIT_IMPLEMENTATION);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy