org.netbeans.modules.schema2beansdev.BeanBuilder Maven / Gradle / Ivy
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* Oracle and Java are registered trademarks of Oracle and/or its affiliates.
* Other names may be trademarks of their respective owners.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common
* Development and Distribution License("CDDL") (collectively, the
* "License"). You may not use this file except in compliance with the
* License. You can obtain a copy of the License at
* http://www.netbeans.org/cddl-gplv2.html
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
* specific language governing permissions and limitations under the
* License. When distributing the software, include this License Header
* Notice in each file and include the License file at
* nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the
* License Header, with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Contributor(s):
*
* The Original Software is NetBeans. The Initial Developer of the Original
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
* Microsystems, Inc. All Rights Reserved.
*
* If you wish your version of this file to be governed by only the CDDL
* or only the GPL Version 2, indicate your decision by adding
* "[Contributor] elects to include this software in this distribution
* under the [CDDL or GPL Version 2] license." If you do not indicate a
* single choice of license, a recipient has the option to distribute
* your version of this file under either the CDDL, the GPL Version 2 or
* to extend the choice of license to its licensees as provided above.
* However, if you add GPL Version 2 code and therefore, elected the GPL
* Version 2 license, then the option applies only if the new code is
* made subject to such option by the copyright holder.
*/
package org.netbeans.modules.schema2beansdev;
import java.util.*;
import java.io.*;
import org.netbeans.modules.schema2beans.*;
import org.netbeans.modules.schema2beansdev.metadd.*;
import org.netbeans.modules.schema2beansdev.beangraph.*;
import org.netbeans.modules.schema2beansdev.gen.*;
/**
* This class implements the Document Definition handler in order to build
* the internal tree representation of the DD DTD.
*/
public class BeanBuilder {
private static final String UNIQUE_PREFIX = "My";
protected GenBeans.Config config;
protected CodeGeneratorFactory codeGenFactory;
protected BeanElement rootElement;
protected String genDir;
protected String packagePath;
protected String packageName = null;
protected TreeParser parser;
protected Map constNameMap = null; // LinkedHashMap
protected Map illegalClassNames = new HashMap();
class BeanElement {
GraphNode node;
String beanName;
int type;
String classType;
private boolean typeSetExternally = false;
boolean isRoot;
boolean isAbstract;
boolean isExtended;
private boolean canBeEmpty = false;
private Map usedTypes;
private int nonAttributePropertyCount = 0;
BeanElement(GraphNode node) {
this.node = node;
}
void initialize(boolean isRoot) {
// Make up a bean name: xxx-yyy has to be XxxYyy
this.beanName = Common.convertName(this.node.getName());
//
// As each node ends up as a property, we have to find out the
// type of the property. The default value is Common.TYPE_BEAN.
//
this.type = Common.TYPE_BEAN;
this.isRoot = isRoot;
calculateType();
}
public GraphNode getGraphNode() {
return this.node;
}
/**
* Call this to change whether or not we will actually generate
* this as a bean. Should we create it or not?
* Users need to call this method instead of node.setCreated directly,
* because some of this object's state depends on that value.
*/
public void setNodeCreated(boolean value) {
node.setCreated(value);
calculateType();
}
protected void calculateType() {
// If we arn't going to create it, then it must not be a bean.
if (!node.isCreated())
this.type = Common.TYPE_STRING;
GraphNode[] nodes = node.getNodes();
// If it is the root, then it must be a bean.
if (nodes.length == 1 && !isRoot) {
if (Common.DTD_STRING.equals(nodes[0].getName()))
this.type = Common.TYPE_STRING;
else {
if (Common.DTD_EMPTY.equals(nodes[0].getName())) {
this.type = Common.TYPE_BOOLEAN;
this.canBeEmpty = true;
}
}
}
}
void setCanBeEmpty(boolean value) {
canBeEmpty = value;
if (canBeEmpty) {
//type = Common.TYPE_BOOLEAN;
}
}
/**
* setName allows you to change the name of the generated class.
*/
public void setName(String name) {
this.beanName = name;
}
public String getName() {
return this.beanName;
}
public String getDTDName() {
return this.node.getName();
}
public void setDTDName(String dtdName) {
node.setName(dtdName);
}
public String getNamespace() {
return node.getNamespace();
}
public boolean isBean() {
return Common.isBean(this.type);
}
public boolean isBoolean() {
return Common.isBoolean(this.type);
}
public boolean isRoot() {
return this.isRoot;
}
public String typeToString() {
switch(this.type) {
case Common.TYPE_STRING:
return Common.CLASS_STRING;
case Common.TYPE_BOOLEAN:
return Common.CLASS_BOOLEAN;
default:
return this.beanName;
}
}
public String getClassType() {
if (classType == null)
return typeToString();
return classType;
}
public String getFullClassType() {
String result = getClassType();
if (packageName == null)
return result;
if (isBean() && node.isCreated())
return packageName+"."+result;
return result;
}
public void setClassType(String ct) {
classType = ct;
}
public boolean isTypeSetExternally() {
return typeSetExternally;
}
public void setTypeSetExternally(boolean value) {
typeSetExternally = value;
}
public boolean isExtended() {
return isExtended;
}
public void setExtended(boolean isExtended) {
this.isExtended = isExtended;
}
public String toString() {
return this.beanName +
((this.type ==
Common.TYPE_STRING)?" \t(String)":"\t(Bean)"); // NOI18N
}
public void setUsedTypes(Map usedTypes) {
this.usedTypes = usedTypes;
}
public boolean isUsedType(String type) {
return usedTypes.containsKey(type);
}
public boolean getCanBeEmpty() {
return canBeEmpty;
}
public String getOutputFileName() {
if (isBean())
return getClassType();
else
return getName();
}
public BeanElement getExtension() {
if (node.getExtension() == null || !node.getExtension().isCreated())
return null;
return (BeanElement) node.getExtension().getObject();
}
public void setNonAttributePropertyCount(int value) {
nonAttributePropertyCount = value;
}
public int getNonAttributePropertyCount() {
return nonAttributePropertyCount;
}
}
static class Finder {
private String findExpr, byExpr;
private boolean listFindExpr;
public Finder(String findExpr, String byExpr, boolean listFindExpr) {
this.findExpr = findExpr;
this.byExpr = byExpr;
this.listFindExpr = listFindExpr;
}
public String getFindExpr() {
return findExpr;
}
public String getByExpr() {
return byExpr;
}
public boolean isListFindExpr() {
return listFindExpr;
}
public String toString() {
if (listFindExpr)
return "Finder list "+findExpr+" by "+byExpr;
else
return "Finder "+findExpr+" by "+byExpr;
}
}
BeanBuilder(TreeParser parser, GenBeans.Config config, CodeGeneratorFactory cgf) {
this.parser = parser;
this.config = config;
this.codeGenFactory = cgf;
// Since java.lang is implicitly imported, we have to make sure to
// not generate a class with that collides with java.lang.
illegalClassNames.put("Object", null);
illegalClassNames.put("Thread", null);
illegalClassNames.put("Compiler", null);
illegalClassNames.put("Class", null);
illegalClassNames.put("ClassLoader", null);
//illegalClassNames.put("Process", null);
illegalClassNames.put("Package", null);
illegalClassNames.put("String", null);
illegalClassNames.put("Boolean", null);
illegalClassNames.put("Integer", null);
illegalClassNames.put("Long", null);
illegalClassNames.put("Short", null);
illegalClassNames.put("Double", null);
illegalClassNames.put("Float", null);
illegalClassNames.put("Byte", null);
illegalClassNames.put("Character", null);
illegalClassNames.put("int", null);
illegalClassNames.put("char", null);
illegalClassNames.put("byte", null);
illegalClassNames.put("short", null);
illegalClassNames.put("long", null);
illegalClassNames.put("double", null);
illegalClassNames.put("float", null);
illegalClassNames.put("boolean", null);
illegalClassNames.put("void", null);
}
/**
* Parse the attributes of the bean
*
* usedNames helps us to not generate multiple properties with the
* same name. The key is the name of the property and the entry
* is a BeanElement (name = BeanElement.getName()). Currently,
* the storage of the BeanElement is not used, and null should be
* valid for properties that are defined without a BeanElement.
*/
private void buildProperties(GraphLink l, CodeGeneratorClass bc,
int nestedLevel, int groupInstance,
boolean ored,
MetaElement e, MetaDD mdd, Map usedNames) {
while (l != null) {
if (config.isTraceGen())
config.messageOut.println("buildProperties: l="+l+" l.name="+l.name+" l.element="+l.element+" l.getSibling()="+l.getSibling()+" groupInstance="+groupInstance);
if (l.element != null) {
BeanElement be = (BeanElement)l.element.getObject();
if (be == null) {
// This can happen if there are no properties associated
// with this bean (like if the root element has no
// children elements).
config.messageOut.println("Warning: be was null");
continue;
}
//
// The group prop was set on the parent of the children.
// Set it on each property directly for building the class.
//
if (l.getParent() != null)
ored = ored || l.getParent().isSequenceOr();
//System.out.println("ored="+ored);
String name;
String dtdName;
String namespace;
String constName;
if (l.name != null) {
name = Common.convertName(l.name);
dtdName = l.getSchemaName();
namespace = l.getNamespace();
} else {
name = be.getName();
dtdName = be.getDTDName();
namespace = be.getNamespace();
}
MetaElement propertyME = getMetaElement(mdd, dtdName);
if (propertyME != null && propertyME.getBeanName() != null) {
name = propertyME.getBeanName();
if (config.isTraceGen())
config.messageOut.println("buildProperties: property in "+e.getBeanName()+" has been renamed to "+name);
}
constName = Common.constName(dtdName);
if ("#PCDATA".equals(dtdName)) {
// text node
//config.messageOut.println("Hit #PCDATA");
name = "pcdata";
constName = "PCDATA";
}
if (usedNames.containsKey(name)) {
int uniqNum = 2;
String baseName = name;
while (usedNames.containsKey(name = baseName + uniqNum))
uniqNum++;
constName = constName + uniqNum;
if (l.name != null) {
//l.name = l.name + uniqNum;
} else {
be.setName(name);
MetaElement origE = getMetaElement(mdd, dtdName);
if (origE != null) {
MetaElement newE = new MetaElement(origE);
mdd.addMetaElement(newE);
}
}
config.messageOut.println(Common.getMessage("RenamedProperty_msg", baseName, name, e.getBeanName()));
}
usedNames.put(name, be);
if (config.isTraceGen())
config.messageOut.println("buildProperties: name="+name+" constName="+constName+" dtdName="+dtdName+" graphlink.name="+l.name+" be.getClassType="+be.getClassType());
AttrProp[] attrs = be.node.getAttributes();
List extraData = new ArrayList(l.extraData);
if (!be.node.getExtraData().isEmpty()) {
extraData.addAll(be.node.getExtraData());
//System.out.println("**** be.node="+be.node+" extraData="+extraData);
}
//System.out.println("extraData="+extraData);
if (propertyME != null && propertyME.sizeKnownValue() > 0) {
for (int valNum = 0, size = propertyME.sizeKnownValue(); valNum < size; ++valNum) {
String knownValue = propertyME.getKnownValue(valNum);
extraData.add(new KnownValueEnumeration(knownValue));
}
}
constNameMap.put(constName, dtdName);
int type = be.type;
String classType = be.getClassType();
//
// Look to see if we need to make a primitive type into an
// Object type, but don't do it, if the user has set the
// type (like from mdd file).
//
if (!be.isTypeSetExternally() &&
(ored || l.isNillable())) {
if (JavaUtil.isPrimitiveType(classType)) {
classType = JavaUtil.toObjectType(classType);
type = Common.wrapperToType(classType);
if (type == Common.NONE)
type = Common.TYPE_STRING;
if (config.isTraceGen())
config.messageOut.println("Promoting primitive type to object type for "+name+" classType="+classType+" type="+type);
}
}
AbstractCodeGeneratorClass.Property prop =
bc.addProperty(name, dtdName, namespace, l.element, l,
classType, nestedLevel,
l.getElementInstance(),
groupInstance, type, ored,
attrs, constName,
l.getDefaultValue(), true, extraData, l.isUnion());
prop.setCanBeEmpty(be.getCanBeEmpty());
prop.setNillable(l.isNillable());
prop.setBeanElement(be);
l.setObject(prop);
if (e != null) {
// Need to check that name is not already in there.
MetaProperty[] metaProperties = e.getMetaProperty();
boolean found = false;
for (int i = 0; i < metaProperties.length; ++i) {
if (name.equals(metaProperties[i].getBeanName())) {
found = true;
break;
}
}
if (!found) {
MetaProperty mp = new MetaProperty();
mp.setBeanName(name);
e.addMetaProperty(mp);
}
}
//
// Take care of the case where a subnode is a leaf node
// and it has attributes too. In which case, that subnode's
// attributes, become our own.
//
if (!Common.isBean(be.type) &&
config.isAttributesAsProperties()) {
addAttrProps(bc, attrs, name, usedNames,
l.getElementInstance(), false);
}
}
//
// As we go one level deeper, the current link has
// the instance property of the group of children.
//
int childGroupInstance = Common.widestInstance(groupInstance,
l.getGroupInstance());
buildProperties(l.getFirstChild(), bc, nestedLevel+1,
childGroupInstance, ored, e, mdd, usedNames);
l = l.getSibling();
}
}
protected void addAttrProps(CodeGeneratorClass bc, AttrProp[] attrs,
String propertyName, Map usedNames,
int groupInstance,
boolean directChild) {
if (attrs != null) {
for (int i = 0; i < attrs.length; ++i) {
addAttrProp(bc, attrs[i], propertyName, usedNames,
groupInstance, directChild);
}
}
}
protected void addAttrProp(CodeGeneratorClass bc, AttrProp attr,
String propertyName, Map usedNames,
int groupInstance,
boolean directChild) {
String name;
if (directChild)
name = Common.convertName(attr.getName());
else
name = Common.convertName(propertyName+"_"+attr.getName());
if (usedNames.containsKey(name)) {
int uniqNum = 2;
String baseName = name;
while (usedNames.containsKey(name = baseName + uniqNum))
uniqNum++;
attr.setName(name);
config.messageOut.println(Common.getMessage("RenamedProperty_msg", baseName, name, propertyName));
}
usedNames.put(name, attr);
String javaType = attr.getJavaType();
int type;
if (javaType == null) {
type = Common.TYPE_STRING;
javaType = "java.lang.String"; // NOI18N
} else {
type = Common.wrapperToType(javaType);
if (type == Common.NONE)
type = Common.TYPE_STRING;
}
//System.out.println("addAttrProp: attr="+attr+" attr.javaType="+javaType);
List extraData = attr.getExtraData();
String namespace = attr.getNamespace();
bc.addProperty(name, attr.getDtdName(), namespace, null, null,
javaType, 0,
attr.getInstance(),
groupInstance,
type,
false,
null,
Common.constName(name),
attr.getDefaultValue(), directChild,
extraData, false)
.setAttrProp(attr);
}
protected void addCommentsProcessing(CodeGeneratorClass bc) {
bc.addProperty("Comments", "comment", null, null, null,
"java.lang.String", 0,
Common.TYPE_0_N, 0, Common.TYPE_COMMENT,
false, null, "COMMENTS", null, true,
Collections.EMPTY_LIST, false);
}
protected static class KnownValueEnumeration implements DataEnumRestriction {
private String knownValue;
protected KnownValueEnumeration(String value) {
knownValue = value;
}
public void genRestriction(Writer out, String type) throws IOException {
out.write(JavaUtil.instanceFrom(type, knownValue));
}
}
// Called by GenBeans
void process() throws IOException {
Map generators = new LinkedHashMap(); // Map
prepareBeans(generators);
doGeneration(generators);
}
void prepareBeans(Map generators) throws IOException {
GraphNode root = parser.getRoot();
GraphNode[] list = parser.getNodes();
String rootDir;
BeanElement be;
MetaDD mdd = config.getMetaDD();
if (root == null)
throw new IllegalStateException(Common.getMessage("DTDObjectGraphIsNull_msg"));
constNameMap = new LinkedHashMap();
for (int i=0; i>
// And generate the files
for (Iterator it = generators.keySet().iterator(); it.hasNext(); ) {
be = (BeanElement) it.next();
CodeGeneratorClass bc = (CodeGeneratorClass) generators.get(be);
String outputFileName = be.getOutputFileName();
MetaElement metaElement = getMetaElement(mdd, be.getDTDName(), be.node.getNamespace());
if (metaElement.isSkipGeneration()) {
config.messageOut.println("Skipping generation of class " + be.beanName
+ " (as specified in the mdd file)"); // NOI18N
continue;
}
//
// The bean class has now everything it needs to
// generate its content (name, package, attributes, ...)
//
try {
OutputStream out;
out = config.getOutputStreamProvider().getStream(genDir,
outputFileName, "java"); // NOI18N
bc.generate(out, mdd);
close(out);
out = null; // Try to encourage the GC
Collection beansMethods = bc.getGeneratedMethods();
generatedMethods.add(beansMethods);
if (config.isGenerateDelegator()) {
GraphNode graphNode = be.getGraphNode();
MetaElement e = getMetaElement(mdd, be.getDTDName(),
graphNode.getNamespace());
String delegatorClassName;
if (e != null && e.getDelegatorName() != null)
delegatorClassName = e.getDelegatorName();
else {
delegatorClassName = outputFileName+"Delegator";
if (e != null)
e.setDelegatorName(delegatorClassName);
}
String delegatorPackageName = packageName;
String dir = genDir;
if (config.getDelegateDir() != null) {
dir = config.getDelegateDir().getAbsolutePath();
if (config.getDelegatePackage() == null) {
if (packagePath != null && !packagePath.equals(""))
dir = dir + "/" + packagePath; // NOI18N
} else {
delegatorPackageName = config.getDelegatePackage();
dir = dir + "/" + delegatorPackageName.replace('.', '/'); // NOI18N
}
}
out = config.getOutputStreamProvider().getStream(dir,
delegatorClassName, "java"); // NOI18N
bc.generateDelegator(out, mdd, delegatorClassName, delegatorPackageName);
close(out);
out = null; // Try to encourage the GC
}
if (config.isGenerateInterfaces()) {
List beanInfoMethods = new ArrayList(beansMethods.size()); // List
for (Iterator mit = beansMethods.iterator(); mit.hasNext(); ) {
JavaWriter.Method method = (JavaWriter.Method) mit.next();
if (method.isStatic() || method.isConstructor() ||
!method.isPublic())
continue;
if (!method.isBeanInfo())
continue;
//System.out.println("\tFound bean info: "+method.getNameParameters());
beanInfoMethods.add(method);
}
String interfaceName = outputFileName+"Interface"; // NOI18N
GraphNode graphNode = be.getGraphNode();
MetaElement me = getMetaElement(mdd, be.getDTDName(),
graphNode.getNamespace());
generateInterface(genDir, packageName,
interfaceName,
beanInfoMethods,
"This interface has all of the bean info accessor methods.",
me.getBeanInterfaceExtends());
}
} catch(IOException ioe) {
config.messageOut.println("Failed to generate bean class: "+outputFileName); // NOI18N
TraceLogger.error(ioe);
throw ioe;
} catch(IllegalStateException ise) {
config.messageOut.println("Failed to generate bean class "+outputFileName); // NOI18N
TraceLogger.error(ise);
throw ise;
}
}
if (config.getGenerateCommonInterface() != null
&& generatedMethods.size() > 0) {
Map commonGeneratedMethods = new HashMap(); // Map
Iterator it = generatedMethods.iterator();
Collection methods = (Collection) it.next();
// Put all of the methods into our map
for (Iterator mit = methods.iterator(); mit.hasNext(); ) {
JavaWriter.Method method = (JavaWriter.Method) mit.next();
if (method.isStatic() || method.isConstructor() ||
!method.isPublic() || method.isUnsupported())
continue;
commonGeneratedMethods.put(method.getNameParameters(), method);
}
// Now go thru the other classes, and remove any methods that we do
// not find.
while (it.hasNext()) {
//System.out.println("---- Next bean");
methods = (Collection) it.next();
Map toKeep = new HashMap(); // Map
for (Iterator mit = methods.iterator(); mit.hasNext(); ) {
JavaWriter.Method method = (JavaWriter.Method) mit.next();
String nameParameters = method.getNameParameters();
if (commonGeneratedMethods.containsKey(nameParameters)) {
//System.out.println("Keeping "+nameParameters);
toKeep.put(nameParameters, commonGeneratedMethods.get(nameParameters));
}
}
commonGeneratedMethods = toKeep;
}
//System.out.println("Common Methods:");
List sortedMethodNames = new ArrayList(commonGeneratedMethods.keySet());
Collections.sort(sortedMethodNames);
List sortedMethods = new ArrayList(sortedMethodNames.size());
for (Iterator sortedMethodNamesIterator = sortedMethodNames.iterator();
sortedMethodNamesIterator.hasNext(); ) {
sortedMethods.add(commonGeneratedMethods.get(sortedMethodNamesIterator.next()));
}
generateInterface(genDir, packageName,
config.getGenerateCommonInterface(),
sortedMethods,
"This interface is the intersection of all generated methods.",
null);
}
if (config.getDumpBeanTree() != null) {
Writer out = new FileWriter(config.getDumpBeanTree());
try {
CodeGeneratorClass bc = (CodeGeneratorClass) generators.get(rootElement);
bc.dumpBeanTree(out, "", config.getIndent());
} finally {
close(out);
}
}
if (config.isGenerateTagsFile()) {
String tagsClassName = "Tags";
while (illegalClassNames.containsKey(tagsClassName)) {
tagsClassName = UNIQUE_PREFIX + tagsClassName;
}
OutputStream out = config.getOutputStreamProvider().getStream(genDir,
tagsClassName, "java"); // NOI18N
generateTagsFile(out, packageName, tagsClassName);
close(out);
}
}
if (config.getGenerateDotGraph() != null) {
Writer out = new FileWriter(config.getGenerateDotGraph());
try {
generateDotGraph(out, rootElement.getGraphNode());
} finally {
close(out);
}
}
if (!config.isQuiet())
config.messageOut.println(Common.getMessage("MSG_GenerationSummary",
rootElement.getDTDName(),
rootElement.getClassType()));
}
protected void processFinders(GraphNode rootGraphNode) {
for (int i = 0, size = config.sizeFinder(); i < size; ++i) {
String finderExpr = config.getFinder(i);
processFinder(rootGraphNode, finderExpr);
}
MetaDD mdd = config.getMetaDD();
for (Iterator it = mdd.fetchFinderList().iterator();
it.hasNext(); ) {
String finderExpr = (String) it.next();
processFinder(rootGraphNode, finderExpr);
}
}
protected void processFinder(GraphNode rootGraphNode, String finderExpr) {
String rootName = rootGraphNode.getName();
//System.out.println("finderExpr="+finderExpr);
//
// Parse finder expression: on _ find _ by _"
//
String onExpr = null;
String findExpr = null;
boolean isListFindExpr = false;
String byExpr = null;
StringTokenizer st = new StringTokenizer(finderExpr);
while (st.hasMoreTokens()) {
String token = st.nextToken().intern();
if (token == "on")
onExpr = st.nextToken();
else if (token == "find") {
findExpr = st.nextToken();
isListFindExpr = false;
} else if (token == "findall") {
findExpr = st.nextToken();
isListFindExpr = true;
} else if (token == "by")
byExpr = st.nextToken();
else
throw new IllegalArgumentException(Common.getMessage("MSG_BadTokenInFinder", token));
}
if (onExpr == null)
throw new IllegalArgumentException(Common.getMessage("MSG_MissingOnExpression", finderExpr));
if (onExpr.startsWith("/"+rootName)) {
onExpr = onExpr.substring(rootName.length()+1, onExpr.length());
if (onExpr.startsWith("/"))
onExpr = onExpr.substring(1, onExpr.length());
}
//System.out.println("onExpr="+onExpr);
GraphNode onNode = null;
if (onExpr.equals("")) {
// It's on the root
onNode = rootGraphNode;
} else {
GraphLink gl = null;
for (Iterator it = rootGraphNode.getGraphLink().xPathIterator(onExpr);
it.hasNext(); ) {
gl = (GraphLink) it.next();
if (gl == null)
break;
}
if (gl == null)
throw new IllegalArgumentException(Common.getMessage("MSG_UnableToFindExpressionFromFinder", finderExpr));
onNode = gl.element;
}
//System.out.println("onNode="+onNode);
onNode.addExtraDataIncludeAlias(new Finder(findExpr, byExpr,
isListFindExpr));
}
protected void setSchemaType(GraphNode[] list) {
Map nodeMap = new HashMap(list.length*4);
for (int i = 0; i < list.length; ++i) {
nodeMap.put(list[i].getNameWithNamespace(), list[i]);
}
GraphNode emptyGraphNode = null;
for (Iterator it = config.readBeanGraphs(); it.hasNext(); ) {
org.netbeans.modules.schema2beansdev.beangraph.BeanGraph bg = (org.netbeans.modules.schema2beansdev.beangraph.BeanGraph) it.next();
for (int i = 0; i < bg.sizeSchemaTypeMapping(); ++i) {
org.netbeans.modules.schema2beansdev.beangraph.SchemaTypeMappingType stm = bg.getSchemaTypeMapping(i);
String key;
if (stm.getSchemaTypeNamespace() == null)
key = stm.getSchemaTypeName();
else
key = "{"+stm.getSchemaTypeNamespace()+"}"+stm.getSchemaTypeName();
if (nodeMap.containsKey(key)) {
GraphNode node = (GraphNode) nodeMap.get(key);
//System.out.println("Found match from beangraph: node="+node);
node.setJavaType(stm.getJavaType());
node.setCreated(false);
if (stm.isCanBeEmpty()) {
node.setExtendedProperty("can-be-empty", Boolean.TRUE);
}
}
}
}
}
protected void generateInterface(String genDir, String packageName,
String name, List methods,
String comments,
String extendsStatement) throws IOException {
JavaWriter jw = new JavaWriter();
jw.bigComment(comments+"\n\n@"+Common.GENERATED_TAG);
jw.cr();
if (!(packageName == null || "".equals(packageName))) {
jw.writePackage(packageName);
jw.cr();
}
jw.writeAccess(jw.PUBLIC);
jw.write(" interface ");
jw.write(name);
jw.write(" ");
if (extendsStatement != null)
jw.write("extends ", extendsStatement, " ");
jw.begin();
for (Iterator methodsIterator = methods.iterator(); methodsIterator.hasNext(); ) {
JavaWriter.Method method = (JavaWriter.Method) methodsIterator.next();
method.writeMethod(jw);
jw.eol();
jw.cr();
}
jw.end();
try {
OutputStream out;
out = config.getOutputStreamProvider().getStream(genDir,
name, "java"); // NOI18N
jw.writeTo(out);
close(out);
} catch(IOException ioe) {
config.messageOut.println("Failed to generate interface: "+name); // NOI18N
TraceLogger.error(ioe);
throw ioe;
}
}
protected BeanGraph generateBeanGraph(GraphNode[] list) {
BeanGraph bg = new BeanGraph();
for (int i = 0; i < list.length; ++i) {
GraphNode node = list[i];
BeanElement be = (BeanElement)node.getObject();
SchemaTypeMappingType stm =
new SchemaTypeMappingType(node.getName(),
be.getFullClassType());
stm.setRoot(be.isRoot());
stm.setBean(be.isBean());
stm.setCanBeEmpty(be.getCanBeEmpty());
stm.setSchemaTypeNamespace(node.getNamespace());
bg.addSchemaTypeMapping(stm);
}
return bg;
}
/**
* Generate a .dot file for the dot or dotty program to run with.
* This is primarily useful for debugging the graph that the schema parser
* created for us. See http://www.graphviz.org
*/
protected void generateDotGraph(Writer out, GraphNode node) throws IOException {
out.write("digraph \""+node.getName()+"\" {\n");
out.write("\t\""+node.getName()+"\" [shape=box]\n");
out.write("\t\""+node.getName()+"\" -> \""+node.getGraphLink()+"\";\n");
generateDotGraph(out, node.getGraphLink(), new HashMap());
out.write("}\n");
}
protected void generateDotGraph(Writer out, List children, Map doneLinks) throws IOException {
for (Iterator it = children.iterator(); it.hasNext(); ) {
GraphLink l = (GraphLink) it.next();
generateDotGraph(out, l, doneLinks);
}
}
protected void generateDotGraph(Writer out, GraphLink l, Map doneLinks) throws IOException {
if (l == null)
return;
doneLinks.put(l, null);
out.write("\t\""+l+"\" [label=\""+dotGraphLabel(l)+"\"];\n");
GraphNode node = l.element;
if (node != null) {
BeanBuilder.BeanElement be =
(BeanBuilder.BeanElement)node.getObject();
if (be == null)
return;
String type = be.getClassType();
out.write("\t\""+node+"\" [label=\""+dotGraphLabel(node)+"\", shape=box];\n");
out.write("\t\""+l+"\" -> \""+node+"\" [label=\"type of property\", color=darkgreen];\n");
if ("#PCDATA".equals(l.name) && "String".equals(type)) {
return;
}
AttrProp[] attrs = node.getAttributes();
for (int i = 0; i < attrs.length; ++i) {
String attrName = node.getName()+" attribute "+attrs[i].getName();
out.write("\t\""+attrName+"\" [label=\""+dotGraphLabel(attrs[i])+"\", shape=egg];\n");
out.write("\t\""+node+"\" -> \""+attrName+"\" [label=\"attribute\", color=magenta];\n");
}
GraphLink hasAttr = node.getGraphLink();
if (hasAttr != null) {
if (node.getMarked() == false ) {
if ((config.isTraceDot() || hasData(hasAttr)) && !doneLinks.containsKey(hasAttr)) {
out.write("\t\""+node+"\" -> \""+hasAttr+"\" [label=\"has attr\", color=purple];\n");
node.setMarked(true);
generateDotGraph(out, hasAttr, doneLinks);
node.setMarked(false);
}
}
}
}
List children = l.getChildren();
for (Iterator childIt = children.iterator(); childIt.hasNext(); ) {
GraphLink child = (GraphLink) childIt.next();
out.write("\t\""+l+"\" -> \""+child+"\" [label=child, color=blue];\n");
}
generateDotGraph(out, children, doneLinks);
/*
GraphLink sibling = l.getSibling();
if (sibling != null) {
while (!config.isTraceDot() && sibling.name == null &&
sibling.getFirstChild() == null &&
sibling.getSibling() != null)
sibling = sibling.getSibling();
out.write("\t\""+l+"\" -> \""+sibling+"\" [label=sibling, color=red];\n");
}
*/
}
private String dotGraphLabel(GraphLink l) {
if (config.isTraceDot()) {
String elementInstance = TreeBuilder.instanceToString(l.getElementInstance(), true);
String groupInstance = TreeBuilder.instanceToString(l.getGroupInstance(), true);
String result = "GraphLink@"+Integer.toHexString(l.hashCode());
if (l.name == null)
result += " (grouping)";
else
result += ":"+l.name;
result += "\\n";
if (!"".equals(elementInstance))
result += " element: "+elementInstance;
if (!"".equals(groupInstance))
result += " group: "+groupInstance;
if (l.isSequenceAnd())
result += " ,";
if (l.isSequenceOr())
result += " |";
return result;
} else if (l.name == null)
return "GraphLink";
else
return "property: "+l.name;
}
private String dotGraphLabel(GraphNode node) {
String result;
if (config.isTraceDot())
result = "GraphNode@"+Integer.toHexString(node.hashCode())+":"+node.toString();
else
result = node.getName();
if (node.getJavaType() != null)
result += ":" + node.getJavaType();
return result;
}
private String dotGraphLabel(AttrProp attr) {
return attr.toString();
}
private boolean hasData(GraphLink l) {
for (; l != null; l = l.getSibling()) {
if (l.name != null)
return true;
if (l.element != null) {
return true;
}
if (l.getFirstChild() != null)
if (hasData(l.getFirstChild()))
return true;
}
return false;
}
protected void generateTagsFile(OutputStream out,
String packageName, String className) throws IOException {
JavaWriter jw = new JavaWriter();
try {
jw.bigComment("This class has all element and attribute names as constants.\n\n@"+Common.GENERATED_TAG);
jw.cr();
jw.writePackage(packageName);
jw.cr();
jw.writeClassDecl(className, null, null, jw.PUBLIC);
jw.select(jw.DECL_SECTION);
for (Iterator it = constNameMap.keySet().iterator(); it.hasNext(); ) {
String constName = (String) it.next();
String dtdName = (String) constNameMap.get(constName);
jw.write("public final static String ", constName, " = ");
jw.writeEol("\"", dtdName, "\"");
}
jw.cr();
jw.select(jw.CONSTRUCTOR_SECTION);
jw.comment("This class is not to be instantiated.");
jw.beginConstructor(className, "", null, jw.PRIVATE);
jw.end();
jw.writeTo(out);
} finally {
jw.close();
}
}
/**
* Search in the MetaDD @mdd for @dtdName
*/
private MetaElement getMetaElement(MetaDD mdd, String dtdName) {
return getMetaElement(mdd, dtdName, null);
}
private MetaElement getMetaElement(MetaDD mdd, String dtdName, String namespace) {
if (mdd == null)
return null;
int size = mdd.sizeMetaElement();
for (int i=0; i= 0) {
String impl = implList.substring(0, pos);
impl = impl.trim();
if (impl.equals(interfce))
return;
implList = implList.substring(pos+1, implList.length());
implList = implList.trim();
pos = implList.indexOf(',');
}
if (implList.equals(interfce))
return;
//
// It's a new interface, add it on in.
//
e.setImplements(e.getImplements()+", "+interfce);
}
private void addToBeanInterfaceExtends(MetaElement e, String interfce) {
String implList = e.getBeanInterfaceExtends();
if (implList == null) {
e.setBeanInterfaceExtends(interfce);
return;
}
//
// Check to see if we already have this one.
//
implList = implList.trim();
int pos = implList.indexOf(',');
while (pos >= 0) {
String impl = implList.substring(0, pos);
impl = impl.trim();
if (impl.equals(interfce))
return;
implList = implList.substring(pos+1, implList.length());
implList = implList.trim();
pos = implList.indexOf(',');
}
if (implList.equals(interfce))
return;
//
// It's a new interface, add it on in.
//
e.setBeanInterfaceExtends(e.getBeanInterfaceExtends()+", "+interfce);
}
protected void close(OutputStream out) throws java.io.IOException {
out.close();
if (!config.isQuiet() && config.isTraceGen() &&
out instanceof org.netbeans.modules.schema2beansdev.gen.WriteIfDifferentOutputStream) {
org.netbeans.modules.schema2beansdev.gen.WriteIfDifferentOutputStream widos = (org.netbeans.modules.schema2beansdev.gen.WriteIfDifferentOutputStream) out;
if (!widos.isChanged())
config.messageOut.println(Common.getMessage("MSG_DidNotChangeFile"));
}
}
protected void close(Writer out) throws java.io.IOException {
out.close();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy