|
What this is
This file is included in the DevDaily.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn
Java by Example" TM.
Other links
The source code
/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is NetBeans. The Initial Developer of the Original
* Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun
* Microsystems, Inc. All Rights Reserved.
*/
package org.netbeans.lib.jmi.mapping;
import org.netbeans.api.mdr.JMIStreamFactory;
import org.netbeans.lib.jmi.util.ContainsIterator;
import org.netbeans.lib.jmi.util.Logger;
import javax.jmi.model.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintStream;
import java.io.StringReader;
import java.text.MessageFormat;
import java.util.*;
/**
* Generates java interfaces for specified meta objects or whole meta model.
*
* @author Martin Matula, Dusan Balek
* @version 0.1
*/
public class JavaMapper extends GenericMapper {
// Java doc constants .......................................................
// attribute template
// getter (single-value)
private static final String DOC_ATTR_GETTER = "Returns the value of attribute {0}."; //NOI18N
private static final String DOC_ATTR_GETTER_RETURN = "Value of attribute {0}."; //NOI18N
// setter
private static final String DOC_ATTR_SETTER = "Sets the value of {0} attribute. See '{'@link #{1}'}' for description on the attribute."; //NOI18N
private static final String DOC_ATTR_SETTER_PARAM = "New value to be set."; //NOI18N
// getter (multi-value)
private static final String DOC_ATTR_GETTER_RETURN_ORDERED = "Value of {0} attribute."; //NOI18N
private static final String DOC_ATTR_GETTER_RETURN_MULTI = "Value of {0} attribute."; //NOI18N
// association template
private static final String DOC_ASSOC_PROXY = "{0} association proxy interface."; //NOI18N
// exists method
private static final String DOC_ASSOC_EXISTS = "Queries whether a link currently exists between a given pair of instance objects in the association's link set."; //NOI18N
private static final String DOC_ASSOC_EXISTS_PARAM1 = "Value of the first association end."; //NOI18N
private static final String DOC_ASSOC_EXISTS_PARAM2 = "Value of the second association end."; //NOI18N
private static final String DOC_ASSOC_EXISTS_RETURN = "Returns true if the queried link exists."; //NOI18N
// add method
private static final String DOC_ASSOC_ADD = "Creates a link between the pair of instance objects in the association's link set."; //NOI18N
// remove method
private static final String DOC_ASSOC_REMOVE = "Removes a link between a pair of instance objects in the current association's link set."; //NOI18N
// get end_1 method
private static final String DOC_ASSOC_GET_END1_SINGLE = "Queries the instance object that is related to a particular instance object by a link in the current association's link set."; //NOI18N
private static final String DOC_ASSOC_GET_END1_MULTI = "Queries the instance objects that are related to a particular instance object by a link in the current association's link set."; //NOI18N
private static final String DOC_ASSOC_GET_END1_ORDERED = "Queries the instance objects that are related to a particular instance object by a link in the current association's link set."; //NOI18N
private static final String DOC_ASSOC_GET_END1_PARAM = "Required value of the first association end."; //NOI18N
private static final String DOC_ASSOC_GET_END1_RETURN_SINGLE = "Related object or null if none exists."; //NOI18N
private static final String DOC_ASSOC_GET_END1_RETURN_MULTI = "Collection of related objects."; //NOI18N
private static final String DOC_ASSOC_GET_END1_RETURN_ORDERED = "List of related objects."; //NOI18N
// get end_2 method
private static final String DOC_ASSOC_GET_END2_PARAM = "Required value of the second association end."; //NOI18N
// class instance template
private static final String DOC_INSTANCE = "{0} object instance interface."; //NOI18N
// reference template
// getter (single-value)
private static final String DOC_REFERENCE_GETTER = "Returns the value of reference {0}."; //NOI18N
private static final String DOC_REFERENCE_GETTER_RETURN = "Value of reference {0}."; //NOI18N
// setter
private static final String DOC_REFERENCE_SETTER = "Sets the value of reference {0}. See '{'@link #{1}'}' for description on the reference."; //NOI18N
private static final String DOC_REFERENCE_SETTER_PARAM = "New value to be set."; //NOI18N
// getter (multi-value)
private static final String DOC_REFERENCE_GETTER_RETURN_ORDERED = "Value of reference {0}."; //NOI18N
private static final String DOC_REFERENCE_GETTER_RETURN_MULTI = "Value of reference {0}."; //NOI18N
// class proxy template
private static final String DOC_CLASS_PROXY = "{0} class proxy interface."; //NOI18N
// create method (with no args)
private static final String DOC_CLASS_PROXY_CREATE = "The default factory operation used to create an instance object."; //NOI18N
private static final String DOC_CLASS_PROXY_CREATE_RETURN = "The created instance object."; //NOI18N
// create method (with args)
private static final String DOC_CLASS_PROXY_CREATE2 = "Creates an instance object having attributes initialized by the passed values."; //NOI18N
// package template
private static final String DOC_PACKAGE = "{0} package interface."; //NOI18N
// get
private static final String DOC_PACKAGE_GET_IMPORT = "Returns clustered package {1}."; //NOI18N
private static final String DOC_PACKAGE_GET_IMPORT_RETURN = "Proxy object related to clustered package {1}."; //NOI18N
// get
private static final String DOC_PACKAGE_GET_NESTED = "Returns nested package {1}."; //NOI18N
private static final String DOC_PACKAGE_GET_NESTED_RETURN = "Proxy object related to nested package {1}."; //NOI18N
// get
private static final String DOC_PACKAGE_GET_CLASS = "Returns {1} class proxy object."; //NOI18N
private static final String DOC_PACKAGE_GET_CLASS_RETURN = "{1} class proxy object."; //NOI18N
// get
private static final String DOC_PACKAGE_GET_ASSOC = "Returns {1} association proxy object."; //NOI18N
private static final String DOC_PACKAGE_GET_ASSOC_RETURN = "{1} association proxy object."; //NOI18N
// exception template
private static final String DOC_EXCEPTION = "{0} exception implementation class."; //NOI18N
// constructor
private static final String DOC_EXCEPTION_CONSTRUCTOR = "The public constructor."; //NOI18N
// getter
private static final String DOC_EXCEPTION_GETTER = "Returns value of parameter {1}."; //NOI18N
private static final String DOC_EXCEPTION_GETTER_RETURN = "Value of parameter {1}."; //NOI18N
// enumeration interface
private static final String DOC_ENUM_INTERFACE = "{0} enumeration interface."; //NOI18N
// enumeration class
private static final String DOC_ENUM_CLASS = "{0} enumeration class implementation."; //NOI18N
// literal field
private static final String DOC_ENUM_LITERAL = "Enumeration constant corresponding to literal {1}."; //NOI18N
// refTypeName
private static final String DOC_ENUM_REFTYPENAME = "Returns fully qualified name of the enumeration type."; //NOI18N
private static final String DOC_ENUM_REFTYPENAME_RETURN = "List containing all parts of the fully qualified name."; //NOI18N
// toString
private static final String DOC_ENUM_TOSTRING = "Returns a string representation of the enumeration value."; //NOI18N
private static final String DOC_ENUM_TOSTRING_RETURN = "A string representation of the enumeration value."; //NOI18N
// hashCode
private static final String DOC_ENUM_HASHCODE = "Returns a hash code for this the enumeration value."; //NOI18N
private static final String DOC_ENUM_HASHCODE_RETURN = "A hash code for this enumeration value."; //NOI18N
// equals
private static final String DOC_ENUM_EQUALS = "Indicates whether some other object is equal to this enumeration value."; //NOI18N
private static final String DOC_ENUM_EQUALS_RETURN = "true if the other object is the enumeration of the same type and of the same value."; //NOI18N
private static final String DOC_ENUM_EQUALS_PARAM = "The reference object with which to compare."; //NOI18N
// forName
private static final String DOC_ENUM_FORNAME = "Translates literal name to correspondent enumeration value."; //NOI18N
private static final String DOC_ENUM_FORNAME_RETURN = "Enumeration value corresponding to the passed literal."; //NOI18N
private static final String DOC_ENUM_FORNAME_PARAM = "Enumeration literal."; //NOI18N
// readResolve
private static final String DOC_ENUM_READRESOLVE = "Resolves serialized instance of enumeration value."; //NOI18N
private static final String DOC_ENUM_READRESOLVE_RETURN = "Resolved enumeration value."; //NOI18N
// structure template
private static final String DOC_STRUCT = "{0} structure interface."; //NOI18N
// create
private static final String DOC_STRUCT_CREATE = "Creates an instance of {0} structure type."; //NOI18N
private static final String DOC_STRUCT_CREATE_RETURN = "Value of {0}."; //NOI18N
// getter
private static final String DOC_STRUCT_GETTER = "Returns value of {1} field."; //NOI18N
private static final String DOC_STRUCT_GETTER_RETURN = "Value of {1} field."; //NOI18N
// warning - for every file
private static final String DOC_WARNING = "Note: This type should not be subclassed or implemented by clients. It is generated from a MOF metamodel and automatically implemented by MDR (see mdr.netbeans.org)"; // NOI18N
// ..........................................................................
// indentation level of generated text
private int indentation = 0;
// generator class used to generate source code
private final JMIStreamFactory generator;
// tab
private static final String TAB = " "; //NOI18N
// stream
private PrintStream stream = null;
// header
private String header = null;
// method used to write a line of text
private void generate(String text) throws IOException {
// indent the line
generateTabs();
// write the text
stream.println(text);
checkStreamForErrors(stream);
}
private void generateTabs() throws IOException {
// indent the line
for (int i = 0; i < indentation; i++) {
stream.print(TAB);
}
checkStreamForErrors(stream);
}
// method used to write a new line
private void newLine() throws IOException {
stream.println();
checkStreamForErrors(stream);
}
// method for indenting generated text
private void indent() {
indentation++;
}
// method for indenting generated text the specified number of tabs (absolutely)
private void indent(int count) {
indentation = count;
}
// method for unindenting generated text
private void unindent() {
indentation--;
}
protected boolean createStream(List pkg, String name) throws IOException {
if (stream != null) {
closeStream();
throw new IllegalStateException("Attempting to create stream before previous stream was closed.");
}
java.io.OutputStream os = generator.createStream(pkg, name);
if (os != null) {
stream = new PrintStream(os);
}
return stream != null;
}
protected void closeStream() throws IOException {
if (stream == null)
throw new IllegalStateException("Attempting to close the stream without opening it first.");
PrintStream ps = stream;
stream = null;
ps.close();
checkStreamForErrors(ps);
}
private static void checkStreamForErrors(PrintStream ps) throws IOException {
if (ps.checkError())
throw new IOException("Error writing to print stream during JMI Source generator.");
}
/**
* Method used to generate interface header.
* @param pkg Name of package for the interface.
* @param name Name for the interface.
* @param ancestors Array of interface ancestors' names.
*/
private void interfaceHeader(String pkg, String name, Object[] ancestors, ModelElement elem, String comment) throws IOException {
classHeader(pkg, name, ancestors, null, true, elem, comment);
}
/**
* Method used to generate class or interface header.
* @param pkg Name of package for the class.
* @param name Name for the class.
* @param ancestors Array of classes ancestors' names.
* @param interfaces Array of implemented interfaces.
* @param isInterface If true, method will generate an interface header. In this case the implements argument is ignored.
*/
private void classHeader(String pkg, String name, Object[] ancestors, Object[] interfaces, boolean isInterface, ModelElement elem, String comment) throws IOException {
classHeader(pkg, name, ancestors, interfaces, isInterface, false, elem, comment);
}
/**
* Method used to generate class or interface header.
* @param pkg Name of package for the class.
* @param name Name for the class.
* @param ancestors Array of classes ancestors' names.
* @param interfaces Array of implemented interfaces.
* @param isInterface If true, method will generate an interface header. In this case the implements argument is ignored.
*/
private void classHeader(String pkg, String name, Object[] ancestors, Object[] interfaces, boolean isInterface, boolean isFinal, ModelElement elem, String comment) throws IOException {
// reset the indentation
indent(0);
StringBuffer sbAnc = new StringBuffer();
StringBuffer sbIfc = new StringBuffer();
String type;
// --- here starts the generation of header
// generate header comment
if (header != null) {
generate(header);
newLine();
}
// generate package information
generate("package " + pkg + ";"); //NOI18N
newLine();
// generate class Java doc
classJavaDoc (elem, comment);
// generate class definition header
if (ancestors != null) {
for (int i = 0; i < ancestors.length; sbAnc.append((String) ancestors[i++])) {
if (sbAnc.length() > 0) sbAnc.append(", "); //NOI18N
else sbAnc.append(" extends "); //NOI18N
}
}
if (isInterface) {
type = "interface"; //NOI18N
} else {
if (isFinal) type = "final class"; //NOI18N
else type = "class"; //NOI18N
if (interfaces != null) {
for (int i = 0; i < interfaces.length; sbIfc.append((String) interfaces[i++])) {
if (sbIfc.length() > 0) sbIfc.append(", "); //NOI18N
else sbIfc.append(" implements "); //NOI18N
}
}
}
generate("public " + type + " " + name + sbAnc.toString() + sbIfc.toString() + " {"); //NOI18N
// indent the following text
indent();
}
// method used to generate interface footer
private void interfaceFooter(String name) throws IOException {
classFooter(name, true);
}
private void classFooter(String name, boolean isInterface) throws IOException {
// unindent the following text
unindent();
// generate class ending
generate("}"); //NOI18N
}
// generates a method of a given interface
private void interfaceMethod(String returnType, String name, Object[] parameters, Object[] exceptions) throws IOException {
StringBuffer sb = new StringBuffer();
StringBuffer sb2 = new StringBuffer();
if (parameters != null)
for (int i = 0; i < parameters.length; sb.append((String) parameters[i++] + " " + (String) parameters[i++])) { //NOI18N
if (sb.length() > 0) sb.append(", "); //NOI18N
}
if (exceptions != null)
for (int i = 0; i < exceptions.length; sb2.append((String) exceptions[i++])) {
if (sb2.length() > 0) sb2.append(", "); //NOI18N
else sb2.append(" throws "); //NOI18N
}
generate("public " + returnType + " " + name + "(" + sb + ")" + sb2 + ";"); //NOI18N
}
// generates an interface field
private void interfaceField(String fieldType, String name, String value) throws IOException {
generate("public final " + fieldType + " " + name + " = " + value + ";"); //NOI18N
}
// generates an interface constant
// generates interface methods for a given attribute
private void attributeTemplate(Object objAttribute) throws IOException {
Attribute attr = (Attribute) objAttribute;
String attrName = firstUpper(tagProvider.getSubstName(attr));
Classifier attrType = getAttrType(attr);
String attrTypeName = getTypeName(attrType);
if (attr.getMultiplicity().getUpper() == 1) {
// getter
String name;
String setterName;
if (attrType instanceof PrimitiveType && attrType.getName().equals("Boolean")) { //NOI18N
if (attrName.substring(0, 2).equals("Is")) name = firstLower(attrName); //NOI18N
else name = "is" + attrName; //NOI18N
setterName = "set" + name.substring(2); //NOI18N
} else {
name = "get" + attrName; //NOI18N
setterName = "set" + attrName; //NOI18N
}
// if multiplicity = [1..1] map to primitive type
String getterType = attrTypeName;
if (attr.getMultiplicity().getLower() == 1) {
getterType = getPrimitiveName(getterType);
}
methodJavaDoc(attr, true, DOC_ATTR_GETTER, DOC_ATTR_GETTER_RETURN, null, null, null);
interfaceMethod(getterType, name, null, null);
// setter
if (attr.isChangeable()) {
methodJavaDoc(
attr, false, DOC_ATTR_SETTER, null, new String [] {"newValue"}, //NOI18N
new Object [] {DOC_ATTR_SETTER_PARAM}, new String [] {name}
);
interfaceMethod("void", setterName, new String[] {getterType, "newValue"}, null); //NOI18N
}
} else if (attr.getMultiplicity().getUpper() != 0) {
// getter
boolean ordered = attr.getMultiplicity().isOrdered();
methodJavaDoc(attr, true, DOC_ATTR_GETTER,
(ordered ? DOC_ATTR_GETTER_RETURN_ORDERED : DOC_ATTR_GETTER_RETURN_MULTI), null, null, null
);
interfaceMethod((ordered ? DT_ORDERED : DT_MULTIVALUED), "get" + attrName, null, null); //NOI18N
}
}
// generates interface methods for a given operation
private void operationTemplate(Object objOperation) throws IOException {
Operation oper = (Operation) objOperation;
Collection exceptions = new ArrayList();
Collection parameters = new ArrayList();
ArrayList parametersList = new ArrayList();
ArrayList parametersNames = new ArrayList();
String operType = "void"; //NOI18N
Parameter param, returnParam = null;
ModelElement element;
for (Iterator it = oper.getContents().iterator(); it.hasNext();) {
element = (ModelElement) it.next();
if (element instanceof Parameter) {
param = (Parameter) element;
if (param.getDirection().equals(DirectionKindEnum.RETURN_DIR)) {
operType = getTypeName(param);
returnParam = param;
} else {
parameters.add(getTypeName(param));
String name = tagProvider.getSubstName(param) + (param.getDirection().equals(DirectionKindEnum.IN_DIR) ? "" : "[]"); //NOI18N
parameters.add(name);
parametersList.add (param);
parametersNames.add (name);
}
}
}
for (Iterator it = oper.getExceptions().iterator(); it.hasNext();) {
element = (ModelElement) it.next();
exceptions.add(tagProvider.getTypeFullName(element));
}
int size = parametersList.size ();
Object [] paramsArray = new Object [size];
paramsArray = parametersList.toArray (paramsArray);
String [] namesArray = new String [size];
namesArray = (String[]) parametersNames.toArray (namesArray);
methodJavaDoc(oper, true, null, returnParam, namesArray, paramsArray, null);
interfaceMethod(operType, tagProvider.getSubstName(oper), parameters.toArray(), exceptions.toArray());
}
// generates interface methods for a given constant
private void constantTemplate(Object objConstant) throws IOException {
Constant constant = (Constant) objConstant;
DataType type = (DataType) getAttrType(constant);
String value = constant.getValue();
if (type.getName ().equals ("String")) { //NOI18N
value = "\"" + value.replace('\n', ' ') + "\""; //NOI18N
}
fieldJavaDoc (constant);
interfaceField(getTypeName2(constant), tagProvider.getSubstName(constant), value);
}
// generates interface methods for a given reference
private void referenceTemplate(Object objReference) throws IOException {
Reference ref = (Reference) objReference;
String refName = firstUpper(tagProvider.getSubstName(ref));
String refType = getTypeName(getAttrType(ref));
if (ref.getMultiplicity().getUpper() == 1) {
// getter
methodJavaDoc (
ref, true, DOC_REFERENCE_GETTER, DOC_REFERENCE_GETTER_RETURN,
null, null, null
);
interfaceMethod(refType, "get" + refName, null, null); //NOI18N
// setter
if (ref.isChangeable()) {
methodJavaDoc (
ref, false, DOC_REFERENCE_SETTER, null, new String [] {"newValue"}, //NOI18N
new Object [] {DOC_REFERENCE_SETTER_PARAM}, new String [] {"get" + refName} //NOI18N
);
interfaceMethod("void", "set" + refName, new String[] {refType, "newValue"}, null); //NOI18N
}
} else if (ref.getMultiplicity().getUpper() != 0) {
// getter
boolean isOrdered = ref.getMultiplicity().isOrdered();
methodJavaDoc (
ref, true, DOC_REFERENCE_GETTER,
isOrdered ? DOC_REFERENCE_GETTER_RETURN_ORDERED : DOC_REFERENCE_GETTER_RETURN_MULTI,
null, null, null
);
interfaceMethod((isOrdered ? DT_ORDERED : DT_MULTIVALUED), "get" + refName, null, null); //NOI18N
}
}
// generates interfaces for a given class (class interface and class proxy interface)
protected void classProxyTemplate(javax.jmi.model.MofClass objClass) throws IOException {
final ClassContents contents = getClassContents(objClass);
interfaceHeader(tagProvider.getTypePrefix(objClass), tagProvider.getSubstName(objClass) + CLASS_POSTFIX, new String[] {"javax.jmi.reflect.RefClass"}, objClass, DOC_CLASS_PROXY); //NOI18N
if (!objClass.isAbstract()) {
// create (default)
methodJavaDoc (
objClass, false, DOC_CLASS_PROXY_CREATE,
DOC_CLASS_PROXY_CREATE_RETURN, null, null, null
);
interfaceMethod(tagProvider.getSubstName(objClass), "create" + tagProvider.getSubstName(objClass), null, null); //NOI18N
// create
if (contents.allAttributes.size() > 0) {
Object [] params = contents.allAttributes.toArray();
Object [] paramsObjects = contents.allAttributesObjects.toArray();
String [] paramsNames = new String [paramsObjects.length];
for (int x = 0; x < paramsNames.length; x++) {
paramsNames [x] = ((ModelElement) paramsObjects [x]).getName ();
}
String name = tagProvider.getSubstName(objClass);
methodJavaDoc (
objClass, false, DOC_CLASS_PROXY_CREATE2, DOC_CLASS_PROXY_CREATE_RETURN,
paramsNames, paramsObjects, null
);
interfaceMethod(tagProvider.getSubstName(objClass), "create" + name, params, null); //NOI18N
}
}
// generate operations
for (Iterator it = contents.clsOperations.iterator(); it.hasNext();)
operationTemplate(it.next());
// generate attributes
for (Iterator it = contents.clsAttributes.iterator(); it.hasNext();)
attributeTemplate(it.next());
// generate structure factory methods
for (Iterator it = contents.structures.iterator(); it.hasNext();) {
structTemplate(it.next());
}
interfaceFooter(tagProvider.getSubstName(objClass) + CLASS_POSTFIX);
}
protected void classInstanceTemplate(MofClass objClass) throws IOException {
final ClassContents contents = getClassContents(objClass);
// *** Instance interface generation ***************************************************************************************
final Collection ancestors = new ArrayList();
final Collection supertypes = objClass.getSupertypes();
for (Iterator it = supertypes.iterator(); it.hasNext();) {
ancestors.add(tagProvider.getTypeFullName((ModelElement) it.next()));
}
if (ancestors.size() == 0) ancestors.add("javax.jmi.reflect.RefObject"); //NOI18N
interfaceHeader(tagProvider.getTypePrefix(objClass), tagProvider.getSubstName(objClass), ancestors.toArray(), objClass, DOC_INSTANCE);
// generate constants
for (Iterator it = contents.constants.iterator(); it.hasNext();)
constantTemplate(it.next());
// generate operations
for (Iterator it = contents.instOperations.iterator(); it.hasNext();)
operationTemplate(it.next());
// generate attributes
for (Iterator it = contents.instAttributes.iterator(); it.hasNext();)
attributeTemplate(it.next());
// generate references
for (Iterator it = contents.instReferences.iterator(); it.hasNext();)
referenceTemplate(it.next());
interfaceFooter(tagProvider.getSubstName(objClass));
}
// GenericMapper will nicely generate the class proxy interface right
// before/after the class instance interface, so we "remember" the last
// class accessed as an optimization. But, even if GenericMapper didn't
// do call classInstanceTemplate() and classProxyTemplate() successively,
// this will still do the right thing.
private ClassContents getClassContents(MofClass cls) {
if (cachedClassContents == null || cachedClassContents.objClass != cls)
cachedClassContents = new ClassContents(cls);
return cachedClassContents;
}
private ClassContents cachedClassContents;
private final class ClassContents {
final Collection instAttributes = new ArrayList();
final Collection instOperations = new ArrayList();
final Collection instReferences = new ArrayList();
final Collection clsAttributes = new ArrayList();
final Collection clsOperations = new ArrayList();
final Collection allAttributes = new ArrayList();
final Collection allAttributesObjects = new ArrayList ();
final Collection constants = new ArrayList();
final Collection enumerations = new ArrayList();
final Collection structures = new ArrayList();
final MofClass objClass;
private ClassContents(MofClass objClass) {
this.objClass = objClass;
final Collection elements = objClass.getContents();
ModelElement element;
Feature feature;
for (Iterator it = elements.iterator(); it.hasNext();) {
element = (ModelElement) it.next();
if (element instanceof Constant) {
constants.add(element);
} else if (element instanceof Feature) {
feature = (Feature) element;
if (feature.getVisibility().equals(VisibilityKindEnum.PUBLIC_VIS)) {
if (feature instanceof Attribute) {
if (feature.getScope().equals(ScopeKindEnum.INSTANCE_LEVEL))
instAttributes.add(feature);
} else if (feature instanceof Operation) {
if (feature.getScope().equals(ScopeKindEnum.INSTANCE_LEVEL))
instOperations.add(feature);
} else if (feature instanceof Reference) {
instReferences.add(feature);
}
}
} else if (element instanceof EnumerationType) {
enumerations.add(element);
} else if (element instanceof StructureType) {
structures.add(element);
}
}
for (Iterator it = new ContainsIterator(objClass); it.hasNext();) {
if ((element = (ModelElement) it.next()) instanceof Attribute) {
feature = (Attribute) element;
if (feature.getScope().equals(ScopeKindEnum.CLASSIFIER_LEVEL)) {
clsAttributes.add(feature);
} else {
if (!((Attribute) feature).isDerived()) {
allAttributes.add(getTypeName((Attribute) feature));
allAttributes.add(tagProvider.getSubstName(feature));
allAttributesObjects.add(feature);
}
}
} else if (element instanceof Operation) {
feature = (Operation) element;
if (feature.getScope().equals(ScopeKindEnum.CLASSIFIER_LEVEL)) {
clsOperations.add(feature);
}
}
}
}
}
// generates interface for a given association
protected void associationTemplate(Association objAssociation) throws IOException {
Collection contents = objAssociation.getContents();
AssociationEnd[] ends = new AssociationEnd[2];
Object element;
int i = 0;
boolean single, ordered;
for (Iterator it = contents.iterator(); it.hasNext() && i < 2;) {
element = it.next();
if (element instanceof AssociationEnd)
ends[i++] = (AssociationEnd) element;
}
String end1Name = tagProvider.getSubstName(ends[0]);
String end1Class = getTypeName(getAttrType(ends[0]));
String end2Name = tagProvider.getSubstName(ends[1]);
String end2Class = getTypeName(getAttrType(ends[1]));
interfaceHeader(tagProvider.getTypePrefix(objAssociation), tagProvider.getSubstName(objAssociation), new String[] {"javax.jmi.reflect.RefAssociation"}, objAssociation, DOC_ASSOC_PROXY); //NOI18N
// exists(, )
methodJavaDoc (
objAssociation, false, DOC_ASSOC_EXISTS, DOC_ASSOC_EXISTS_RETURN,
new String [] {end1Name, end2Name}, new Object [] {DOC_ASSOC_EXISTS_PARAM1, DOC_ASSOC_EXISTS_PARAM2}, null
);
interfaceMethod("boolean", "exists", new String[] {end1Class, end1Name, end2Class, end2Name}, null); //NOI18N
// ()
if (ends[0].isNavigable()) {
single = ends[0].getMultiplicity().getUpper() == 1;
ordered = ends[0].getMultiplicity().isOrdered();
methodJavaDoc (
objAssociation, false,
single ? DOC_ASSOC_GET_END1_SINGLE : (ordered ? DOC_ASSOC_GET_END1_ORDERED : DOC_ASSOC_GET_END1_MULTI),
single ? DOC_ASSOC_GET_END1_RETURN_SINGLE : (ordered ? DOC_ASSOC_GET_END1_RETURN_ORDERED : DOC_ASSOC_GET_END1_RETURN_MULTI),
new String [] {end2Name}, new Object [] {DOC_ASSOC_GET_END2_PARAM}, null
);
interfaceMethod(single ? end1Class : (ordered ? DT_ORDERED : DT_MULTIVALUED),
"get" + firstUpper(end1Name), new String[] {end2Class, end2Name}, null); //NOI18N
}
// ()
if (ends[1].isNavigable()) {
single = ends[1].getMultiplicity().getUpper() == 1;
ordered = ends[1].getMultiplicity().isOrdered();
methodJavaDoc (
objAssociation, false,
single ? DOC_ASSOC_GET_END1_SINGLE : (ordered ? DOC_ASSOC_GET_END1_ORDERED : DOC_ASSOC_GET_END1_MULTI),
single ? DOC_ASSOC_GET_END1_RETURN_SINGLE : (ordered ? DOC_ASSOC_GET_END1_RETURN_ORDERED : DOC_ASSOC_GET_END1_RETURN_MULTI),
new String [] {end1Name}, new Object [] {DOC_ASSOC_GET_END1_PARAM}, null
);
interfaceMethod(single ? end2Class : (ordered ? DT_ORDERED : DT_MULTIVALUED),
"get" + firstUpper(end2Name), new String[] {end1Class, end1Name}, null); //NOI18N
}
if (ends[0].isChangeable() && ends[1].isChangeable()) {
String [] names = new String [] {end1Name, end2Name};
Object [] params = new Object [] {DOC_ASSOC_EXISTS_PARAM1, DOC_ASSOC_EXISTS_PARAM2};
// add(, )
methodJavaDoc (
objAssociation, false, DOC_ASSOC_ADD, null,
names, params, null
);
interfaceMethod("boolean", "add", new String[] {end1Class, end1Name, end2Class, end2Name}, null); //NOI18N
// remove(, )
methodJavaDoc (
objAssociation, false, DOC_ASSOC_REMOVE, null,
names, params, null
);
interfaceMethod("boolean", "remove", new String[] {end1Class, end1Name, end2Class, end2Name}, null); //NOI18N
}
interfaceFooter(tagProvider.getSubstName(objAssociation));
}
// generates interface for a given package
protected void packageTemplate(MofPackage objPackage) throws IOException {
Collection elements;
ModelElement element;
Collection ancestors = new ArrayList();
Collection supertypes = objPackage.getSupertypes();
for (Iterator it = supertypes.iterator(); it.hasNext();) {
ancestors.add(tagProvider.getTypeFullName((ModelElement) it.next()) + PACKAGE_POSTFIX);
}
if (ancestors.size() == 0) ancestors.add("javax.jmi.reflect.RefPackage"); //NOI18N
interfaceHeader(tagProvider.getTypePrefix(objPackage), tagProvider.getSubstName(objPackage) + PACKAGE_POSTFIX, ancestors.toArray(), objPackage, DOC_PACKAGE);
ArrayList nestedPackages = new ArrayList();
ArrayList classes = new ArrayList();
ArrayList associations = new ArrayList();
ArrayList structureTypes = new ArrayList();
elements = objPackage.getContents();
for (Iterator it = elements.iterator(); it.hasNext();) {
element = (ModelElement) it.next();
if (element instanceof Association) {
associations.add(element);
} else if (element instanceof javax.jmi.model.MofClass) {
classes.add(element);
} else if (element instanceof MofPackage) {
nestedPackages.add(element);
} else if (element instanceof StructureType) {
structureTypes.add(element);
} else if (element instanceof Import) {
// addProxyGetter cannot handle Imports, and Imports come first
// in the mapping, so go ahead and just generate the necessary
// method now.
Import imp = (Import) element;
if (imp.isClustered() && VisibilityKindEnum.PUBLIC_VIS.equals(imp.getVisibility())) {
Namespace ns = imp.getImportedNamespace();
if (ns instanceof MofPackage &&
VisibilityKindEnum.PUBLIC_VIS.equals(((MofPackage) ns).getVisibility())) {
String typeName = tagProvider.getTypeFullName(ns) + PACKAGE_POSTFIX;
String elementName = tagProvider.getSubstName(element);
interfaceMethod(typeName, "get" + elementName, null, null); //NOI18N
}
} else {
Logger.getDefault().log("import: " + imp.getName() + " mofid: " + imp.refMofId() + " clustered: " + imp.isClustered() + " visibility: " + imp.getVisibility()); //NOI18N
}
}
}
addProxyGetter(objPackage, nestedPackages, PACKAGE_POSTFIX);
addProxyGetter(objPackage, classes, CLASS_POSTFIX);
addProxyGetter(objPackage, associations, ""); //NOI18N
for (Iterator i = structureTypes.iterator(); i.hasNext(); ) {
structTemplate(i.next());
}
interfaceFooter(tagProvider.getSubstName(objPackage) + PACKAGE_POSTFIX);
}
void addProxyGetter(MofPackage objPackage, ArrayList list, String suffix) throws IOException {
for (Iterator i = list.iterator(); i.hasNext(); ) {
GeneralizableElement element = (GeneralizableElement) i.next();
if (VisibilityKindEnum.PUBLIC_VIS.equals(element.getVisibility())) {
String methodComment = null, returnComment = null;
if (element instanceof Import) {
methodComment = DOC_PACKAGE_GET_IMPORT;
returnComment = DOC_PACKAGE_GET_IMPORT_RETURN;
} else if (element instanceof MofPackage) {
methodComment = DOC_PACKAGE_GET_NESTED;
returnComment = DOC_PACKAGE_GET_NESTED_RETURN;
} else if (element instanceof MofClass) {
methodComment = DOC_PACKAGE_GET_CLASS;
returnComment = DOC_PACKAGE_GET_CLASS_RETURN;
} else if (element instanceof Association) {
methodComment = DOC_PACKAGE_GET_ASSOC;
returnComment = DOC_PACKAGE_GET_ASSOC_RETURN;
}
String typeName = tagProvider.getTypeFullName(element);
String elementName = tagProvider.getSubstName(element);
if (methodComment != null)
methodJavaDoc(objPackage, false, methodComment, returnComment, null, null, new String [] {elementName});
interfaceMethod(typeName + suffix, "get" + elementName, null, null); //NOI18N
}
}
}
// generates class for an exception
protected void exceptionTemplate(MofException objException) throws IOException {
Collection contents = objException.getContents();
ArrayList params = new ArrayList();
ArrayList paramsObjects = new ArrayList();
ArrayList paramsNames = new ArrayList();
ArrayList codeConstr = new ArrayList();
StringBuffer paramsConstr = new StringBuffer(100);
StringBuffer codeMsg = new StringBuffer(100);
Object element;
Parameter param;
String typeName;
String paramName;
String getterName;
for (Iterator it = contents.iterator(); it.hasNext();) {
element = it.next();
if (element instanceof Parameter) {
param = (Parameter) element;
paramsObjects.add (param);
params.add(getTypeName(param));
paramName = firstLower(tagProvider.getSubstName(param));
paramsNames.add (paramName);
params.add(removeUnderscores(paramName));
getterName = paramName;
if (param.getType() instanceof PrimitiveType && param.getType().getName().equals("Boolean")) { //NOI18N
if (getterName.indexOf("is") != 0) { //NOI18N
getterName = "is_" + getterName; //NOI18N
}
} else {
getterName = "get_" + getterName; //NOI18N
}
params.add(removeUnderscores(getterName));
}
}
String exceptionName = tagProvider.getSubstName(objException);
classHeader(tagProvider.getTypePrefix(objException), exceptionName, new Object[] {DT_EXCEPTION}, null, false, objException, DOC_EXCEPTION);
for (Iterator it = params.iterator(); it.hasNext(); it.next()) {
typeName = (String) it.next();
paramName = (String) it.next();
generate("private final " + typeName + " " + paramName + ";"); //NOI18N
codeConstr.add("this." + paramName + " = " + paramName + ";"); //NOI18N
paramsConstr.append(", " + typeName + " " + paramName); //NOI18N
getterName = paramName + ": \" + " + paramName; //NOI18N
if (codeMsg.length() == 0) {
codeMsg.append("\"" + getterName); //NOI18N
} else {
codeMsg.append(" + \", " + getterName); //NOI18N
}
}
// constructor
methodJavaDoc (
objException, false, DOC_EXCEPTION_CONSTRUCTOR, null,
(String []) paramsNames.toArray (new String [] {}), paramsObjects.toArray (), null
);
generate("public " + exceptionName + "(" + (paramsConstr.length() == 0 ? "" : paramsConstr.toString().substring(2)) + ") {"); //NOI18N
indent();
generate("super(" + codeMsg.toString() + ");"); //NOI18N
for (Iterator it = codeConstr.iterator(); it.hasNext();) {
generate((String) it.next());
}
unindent();
generate("}"); //NOI18N
// getters for exception parameters
for (Iterator it = params.iterator(); it.hasNext();) {
typeName = (String) it.next();
paramName = (String) it.next();
getterName = (String) it.next();
methodJavaDoc (
objException, false, DOC_EXCEPTION_GETTER, DOC_EXCEPTION_GETTER_RETURN,
null, null, new String [] {paramName}
);
generate("public " + typeName + " " + getterName + "() {"); //NOI18N
indent();
generate("return " + paramName + ";"); //NOI18N
unindent();
generate("}"); //NOI18N
}
classFooter(exceptionName, false);
}
protected void enumerationInterfaceTemplate(EnumerationType objEnumeration) throws IOException {
// generate interface for EnumerationType
String packageName = tagProvider.getTypePrefix(objEnumeration);
String ifcName = tagProvider.getSubstName(objEnumeration);
interfaceHeader(packageName, ifcName, new Object[] {"javax.jmi.reflect.RefEnum"}, objEnumeration, DOC_ENUM_INTERFACE); //NOI18N
interfaceFooter(tagProvider.getSubstName(objEnumeration));
}
protected void enumerationClassTemplate(EnumerationType objEnumeration) throws IOException {
String packageName = tagProvider.getTypePrefix(objEnumeration);
String ifcName = tagProvider.getSubstName(objEnumeration);
String clsName = ifcName + ENUM_POSTFIX;
List literals = objEnumeration.getLabels();
String literal;
classHeader(packageName, clsName, new Object[0], new Object[] {ifcName}, false, true, objEnumeration, DOC_ENUM_CLASS);
// public fields (literals)
for (Iterator it = literals.iterator(); it.hasNext();) {
literal = (String) it.next();
methodJavaDoc (objEnumeration, false, DOC_ENUM_LITERAL, null, null, null, new String [] {literal});
generate("public static final " + clsName + " " + tagProvider.mapEnumLiteral(literal) + " = new " + clsName + "(\"" + literal + "\");"); //NOI18N
}
newLine();
// private fields
generate("private static final java.util.List typeName;"); //NOI18N
generate("private final java.lang.String literalName;"); //NOI18N
newLine();
// static initializer
generate("static {"); //NOI18N
indent();
generate("java.util.ArrayList temp = new java.util.ArrayList();"); //NOI18N
String enumFQN = ""; //NOI18N
for (Iterator it = objEnumeration.getQualifiedName().iterator(); it.hasNext();) {
String fqnElement = (String) it.next();
generate("temp.add(\"" + fqnElement + "\");"); //NOI18N
enumFQN += fqnElement + (it.hasNext() ? "." : ""); //NOI18N
}
generate("typeName = java.util.Collections.unmodifiableList(temp);"); //NOI18N
unindent();
generate("}"); //NOI18N
newLine();
// constructor
generate("private " + clsName + "(java.lang.String literalName) {"); //NOI18N
indent();
generate("this.literalName = literalName;"); //NOI18N
unindent();
generate("}"); //NOI18N
newLine();
// refTypeName
methodJavaDoc (
objEnumeration, false, DOC_ENUM_REFTYPENAME, DOC_ENUM_REFTYPENAME_RETURN,
null, null, null
);
generate("public java.util.List refTypeName() {"); //NOI18N
indent();
generate("return typeName;"); //NOI18N
unindent();
generate("}"); //NOI18N
newLine();
// toString
methodJavaDoc (
objEnumeration, false, DOC_ENUM_TOSTRING, DOC_ENUM_TOSTRING_RETURN,
null, null, null
);
generate("public java.lang.String toString() {"); //NOI18N
indent();
generate("return literalName;"); //NOI18N
unindent();
generate("}"); //NOI18N
newLine();
// hashCode
methodJavaDoc (
objEnumeration, false, DOC_ENUM_HASHCODE, DOC_ENUM_HASHCODE_RETURN,
null, null, null
);
generate("public int hashCode() {"); //NOI18N
indent();
generate("return literalName.hashCode();"); //NOI18N
unindent();
generate("}"); //NOI18N
newLine();
// equals
methodJavaDoc (
objEnumeration, false, DOC_ENUM_EQUALS, DOC_ENUM_EQUALS_RETURN,
new String [] {"o"}, new Object [] {DOC_ENUM_EQUALS_PARAM}, null //NOI18N
);
generate("public boolean equals(java.lang.Object o) {"); //NOI18N
indent();
generate("if (o instanceof " + clsName + ") return (o == this);"); //NOI18N
generate("else if (o instanceof " + ifcName + ") return (o.toString().equals(literalName));"); //NOI18N
generate("else return ((o instanceof javax.jmi.reflect.RefEnum) && ((javax.jmi.reflect.RefEnum) o).refTypeName().equals(typeName) && o.toString().equals(literalName));"); //NOI18N
unindent();
generate("}"); //NOI18N
newLine();
// forName
methodJavaDoc (
objEnumeration, false, DOC_ENUM_FORNAME, DOC_ENUM_FORNAME_RETURN,
new String [] {"name"}, new Object [] {DOC_ENUM_FORNAME_PARAM}, null //NOI18N
);
generate("public static " + ifcName + " forName(java.lang.String name) {"); //NOI18N
indent();
for (Iterator it = literals.iterator(); it.hasNext();) {
literal = (String) it.next();
generate("if (name.equals(\"" + literal + "\")) return " + tagProvider.mapEnumLiteral(literal) + ";"); //NOI18N
}
generate("throw new java.lang.IllegalArgumentException(\"Unknown literal name '\" + name + \"' for enumeration '" + enumFQN + "'\");"); //NOI18N
unindent();
generate("}"); //NOI18N
// readResolve
methodJavaDoc (
objEnumeration, false, DOC_ENUM_READRESOLVE, DOC_ENUM_READRESOLVE_RETURN,
null, null, null
);
generate("protected java.lang.Object readResolve() throws java.io.ObjectStreamException {"); //NOI18N
indent();
generate("try {"); //NOI18N
indent();
generate("return forName(literalName);"); //NOI18N
unindent();
generate("} catch (java.lang.IllegalArgumentException e) {"); //NOI18N
indent();
generate("throw new java.io.InvalidObjectException(e.getMessage());"); //NOI18N
unindent();
generate("}"); //NOI18N
unindent();
generate("}"); //NOI18N
classFooter(ifcName, false);
}
protected void structureTemplate(StructureType objStructure) throws IOException {
String memberName, fieldName;
// generate interface for StructuredType
interfaceHeader(tagProvider.getTypePrefix(objStructure), tagProvider.getSubstName(objStructure), new Object[] {"javax.jmi.reflect.RefStruct"}, objStructure, DOC_STRUCT); //NOI18N
List fields = objStructure.getContents();
ModelElement field;
Classifier fieldType;
// generate getters for structure fields
for (Iterator it = fields.iterator(); it.hasNext();) {
field = (ModelElement) it.next();
if (field instanceof StructureField) {
fieldType = ((StructureField) field).getType();
memberName = firstUpper (tagProvider.getSubstName(field));
fieldName = memberName;
if (fieldType instanceof PrimitiveType && fieldType.getName().equals("Boolean")) { //NOI18N
if (memberName.indexOf("Is") != 0) { //NOI18N
memberName = "is" + memberName; //NOI18N
} else {
memberName = firstLower(memberName);
}
} else {
memberName = "get" + memberName; //NOI18N
}
methodJavaDoc (
objStructure, false, DOC_STRUCT_GETTER, DOC_STRUCT_GETTER_RETURN,
null, null, new String [] {fieldName}
);
interfaceMethod(getPrimitiveName(getTypeName(fieldType)), memberName, null, null);
}
}
interfaceFooter(tagProvider.getSubstName(objStructure));
}
// generates factory methods for structured datatype
void structTemplate(Object objStructure) throws IOException {
DataType dataType = (DataType) objStructure;
ArrayList parameters = new ArrayList();
ArrayList structureFields = new ArrayList ();
ArrayList paramNames = new ArrayList ();
List fields = dataType.getContents();
ModelElement field;
// generate getters for structure fields
for (Iterator it = fields.iterator(); it.hasNext();) {
field = (ModelElement) it.next();
if (field instanceof StructureField) {
parameters.add(getTypeName2((StructureField) field));
String name = tagProvider.getSubstName(field);
parameters.add(name);
paramNames.add(name);
structureFields.add(field);
}
}
String params[] = new String [parameters.size ()];
params = (String []) parameters.toArray(params);
int size = structureFields.size();
Object [] structFields = new Object[size];
String [] parNames = new String[size];
structFields = structureFields.toArray(structFields);
parNames = (String []) paramNames.toArray(parNames);
// generate factory method
methodJavaDoc(
dataType, false, DOC_STRUCT_CREATE, DOC_STRUCT_CREATE_RETURN,
parNames, structFields, null
);
interfaceMethod(tagProvider.getTypeFullName(dataType), "create" + firstUpper(tagProvider.getSubstName(dataType)), params, null); //NOI18N
}
// Java doc generation ------------------------------------------------------
private void classJavaDoc (ModelElement elem, String genericComment) throws IOException {
generate ("/**"); //NOI18N
if (genericComment != null) {
javaDoc (MessageFormat.format (genericComment, new String [] {elem.getName ()}));
}
javaDoc (elem.getAnnotation ());
javaDoc (" "); //NOI18N
javaDoc (DOC_WARNING);
generate (" */"); //NOI18N
}
private void fieldJavaDoc (ModelElement elem) throws IOException {
generate ("/**"); //NOI18N
javaDoc (elem.getAnnotation ());
generate (" */"); //NOI18N
}
private void methodJavaDoc (ModelElement elem, boolean annotate, String genericComment,
Object retValDescriptor, String [] args, Object [] argDescriptors, String [] variables)
throws IOException {
String text;
String [] vars = (variables == null) ? new String [1] : new String [variables.length + 1];
vars [0] = elem.getName ();
if (variables != null) {
for (int x = 0; x < variables.length; x++)
vars [x + 1] = variables [x];
}
generate ("/**"); //NOI18N
// generic comment
if (genericComment != null) {
javaDoc (MessageFormat.format (genericComment, vars));
}
// annotation based comment
if (annotate) {
javaDoc (elem.getAnnotation ());
}
// javadoc for arguments
if (args != null) {
for (int x = 0; x < args.length; x++) {
if (argDescriptors [x] instanceof ModelElement) {
text = ((ModelElement) argDescriptors [x]).getAnnotation ();
} else {
text = (String) argDescriptors [x];
if (text != null) {
text = MessageFormat.format (text, vars);
}
}
if (text != null) {
javaDoc ("@param " + args [x] + " " + text); //NOI18N
}
} // for
} // if
// javadoc for return value
if (retValDescriptor instanceof ModelElement) {
text = elem.getAnnotation ();
} else {
text = (String) retValDescriptor;
if (text != null)
text = MessageFormat.format (text, vars);
}
if (text != null) {
javaDoc ("@return " + text); //NOI18N
}
// javadoc for exceptions
generate (" */"); //NOI18N
}
private void javaDoc (String text) throws IOException {
if (text == null)
return;
final int MAX_LINE_LENGTH = 70;
BufferedReader reader = new BufferedReader (new StringReader (text));
String line = reader.readLine ();
while (line != null) {
int length = line.length ();
int pos = 0, pos2;
String s;
while (pos < length) {
if (length - pos <= MAX_LINE_LENGTH) {
s = line.substring (pos);
pos = length;
} else {
pos2 = pos + MAX_LINE_LENGTH;
// find end of a word
while ((pos2 < length) && (!Character.isWhitespace (text.charAt (pos2)))) {
pos2++;
} // while
// find start of next word
while ((pos2 < length) && (Character.isWhitespace (text.charAt (pos2)))) {
pos2++;
} // while
s = line.substring (pos, pos2);
pos = pos2;
}
generate (" * " + s); //NOI18N
} // while
line = reader.readLine ();
} // while
}
// public ---------------------------------------------------------------------------------------------------------------
/**
* Creates new JavaMapper. Each created mapping interface will be written into
* separate file to the specified Filesystem into the specified path.
*
* @param sf StreamFactory used to generate files/streams.
*/
public JavaMapper(JMIStreamFactory sf, String header) {
super();
generator = sf;
if ((header != null) && (header.trim().length() > 0)) {
this.header = "/*\n"; //NOI18N
StringTokenizer tokenizer = new StringTokenizer (header, "\n"); //NOI18N
while (tokenizer.hasMoreTokens ())
this.header += " * " + tokenizer.nextToken () + "\n"; //NOI18N
this.header += " */"; //NOI18N
}
}
}
|