View Javadoc

1   /*
2    * Copyright (C) 2003-2012 David E. Berry
3    *
4    * This library is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Lesser General Public
6    * License as published by the Free Software Foundation; either
7    * version 2.1 of the License, or (at your option) any later version.
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   * Lesser General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this library; if not, write to the Free Software
16   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17   *
18   * A copy of the GNU Lesser General Public License may also be found at
19   * http://www.gnu.org/licenses/lgpl.txt
20   */
21  package org.synchronoss.cpo.exporter;
22  
23  import org.synchronoss.cpo.CpoException;
24  import org.synchronoss.cpo.MetaVisitor;
25  import org.synchronoss.cpo.meta.CpoMetaDescriptor;
26  import org.synchronoss.cpo.meta.domain.*;
27  
28  /**
29   * The CpoClassSourceGenerator generates java source code to define the cpo classes.
30   *
31   * @author Michael Bellomo
32   * @since 4/17/12
33   */
34  public class CpoClassSourceGenerator implements MetaVisitor {
35  
36    private static final String ATTR_PREFIX = "ATTR_";
37    private static final String FG_PREFIX = "FG_";
38    private static final String VAR_PREFIX = "_";
39  
40    protected CpoMetaDescriptor metaDescriptor;
41    protected String className = null;
42    protected StringBuilder header = new StringBuilder();
43    protected StringBuilder attributeStatics = new StringBuilder();
44    protected StringBuilder functionGroupStatics = new StringBuilder();
45    protected StringBuilder properties = new StringBuilder();
46    protected StringBuilder constructor = new StringBuilder();
47    protected StringBuilder gettersSetters = new StringBuilder();
48    protected StringBuilder equals = new StringBuilder();
49    protected StringBuilder hashCode = new StringBuilder();
50    protected StringBuilder toString = new StringBuilder();
51    protected StringBuilder footer = new StringBuilder();
52  
53    public CpoClassSourceGenerator(CpoMetaDescriptor metaDescriptor) {
54      this.metaDescriptor = metaDescriptor;
55    }
56  
57    /**
58     * Resets all of the buffers.
59     *
60     * This is needed if you intend to reuse the visitor. This is always called by visit(CpoClass)
61     */
62    private void reset() {
63      attributeStatics = new StringBuilder();
64      functionGroupStatics = new StringBuilder();
65      properties = new StringBuilder();
66      constructor = new StringBuilder();
67      gettersSetters = new StringBuilder();
68      equals = new StringBuilder();
69      hashCode = new StringBuilder();
70      toString = new StringBuilder();
71      footer = new StringBuilder();
72    }
73  
74    public String getSourceCode() {
75      StringBuilder source = new StringBuilder();
76  
77      source.append("/* \n");
78      source.append(" *  This class auto-generated by " + this.getClass().getName() + "\n");
79      source.append(" */\n");
80      source.append(header);
81      source.append("\n");
82      source.append("  /* Attribute name statics */\n");
83      source.append(attributeStatics);
84      source.append("\n");
85      source.append("  /* Function group statics */\n");
86      source.append(functionGroupStatics);
87      source.append("\n");
88      source.append("  /* Properties */\n");
89      source.append(properties);
90      source.append("\n");
91      source.append("  /* Constructor */\n");
92      source.append(constructor);
93      source.append("\n");
94      source.append("  /* Getters and Setters */\n");
95      source.append(gettersSetters);
96  
97      // generate equals()
98      source.append("  public boolean equals(Object o) {\n");
99      source.append("    if (this == o)\n");
100     source.append("      return true;\n");
101     source.append("    if (o == null || getClass() != o.getClass())\n");
102     source.append("      return false;\n");
103     source.append("\n");
104     source.append("    " + className + " that = (" + className + ")o;\n");
105     source.append("\n");
106     source.append(equals);
107     source.append("\n");
108     source.append("    return true;\n");
109     source.append("  }\n\n");
110 
111     // generate hashCode()
112     source.append("  public int hashCode() {\n");
113     source.append("    int result = 0;\n");
114     source.append("    result = 31 * result + getClass().getName().hashCode();\n");
115     source.append(hashCode);
116     source.append("    return result;\n");
117     source.append("  }\n\n");
118 
119     // generate toString()
120     source.append("  public String toString() {\n");
121     source.append("    StringBuilder str = new StringBuilder();\n");
122     source.append(toString);
123     source.append("    return str.toString();\n");
124     source.append("  }\n");
125 
126     source.append(footer);
127     source.append("\n");
128 
129     return source.toString();
130   }
131 
132   @Override
133   public void visit(CpoClass cpoClass) {
134 
135     // reset all the buffers
136     reset();
137 
138     className = cpoClass.getName();
139 
140     // generate class header
141     if (className.lastIndexOf(".") != -1) {
142       String packageName = className.substring(0, className.lastIndexOf("."));
143       className = className.substring(className.lastIndexOf(".") + 1);
144       header.append("package " + packageName + ";\n\n");
145     }
146 
147     // generate class declaration
148     header.append("public class " + className + " implements java.io.Serializable {\n");
149 
150     // footer
151     footer.append("}\n");
152 
153     // generate constructor
154     constructor.append("  public " + className + "() {\n");
155     constructor.append("  }\n");
156   }
157 
158   @Override
159   public void visit(CpoAttribute cpoAttribute) {
160 
161     String attName = cpoAttribute.getJavaName();
162     
163     if (cpoAttribute.getTransformClassName()!=null && cpoAttribute.getTransformInMethod()==null) {
164       try {
165         cpoAttribute.loadRunTimeInfo(metaDescriptor, null);
166       } catch (Exception e) {
167         
168       }
169     }
170 
171     // the getter name is get concatenated with the camel case of the attribute name
172     String getterName;
173     String setterName;
174     if (attName.length() > 1) {
175       getterName = ("get" + attName.substring(0, 1).toUpperCase() + attName.substring(1) + "()");
176       setterName = ("set" + attName.substring(0, 1).toUpperCase() + attName.substring(1));
177     } else {
178       getterName = ("get" + attName.toUpperCase() + "()");
179       setterName = ("set" + attName.toUpperCase());
180     }
181 
182     try {
183       Class<?> attClass = metaDescriptor.getJavaTypeClass(cpoAttribute);
184       String attClassName = metaDescriptor.getJavaTypeName(cpoAttribute);
185 
186       // generate attribute statics
187       String staticName = ATTR_PREFIX + attName.toUpperCase();
188       attributeStatics.append("  public final static String " + staticName + " = \"" + attName + "\";\n");
189 
190       // generate property declarations
191       properties.append("  private " + attClassName + " " + VAR_PREFIX + attName + ";\n");
192 
193       // generate getter
194       gettersSetters.append("  public " + attClassName + " " + getterName + " {\n");
195       gettersSetters.append("    return " + VAR_PREFIX + attName + ";\n");
196       gettersSetters.append("  }\n\n");
197 
198       // generate setter
199       gettersSetters.append("  public void " + setterName + "(" + attClassName + " " + attName + ") {\n");
200       gettersSetters.append("    " + VAR_PREFIX + attName + " = " + attName + ";\n");
201       gettersSetters.append("  }\n\n");
202 
203       // equals()
204       if (attClass.isPrimitive()) {
205         // primitive type, use ==
206         equals.append("    if (" + getterName + " != that." + getterName + ")\n");
207       } else if (attClass.isArray()) {
208         // array type, use Array.equals()
209         equals.append("    if (!java.util.Arrays.equals(" + getterName + ", that." + getterName + "))\n");
210       } else {
211         // object, use .equals
212         equals.append("    if (" + getterName + " != null ? !" + getterName + ".equals(that." + getterName + ") : that." + getterName + " != null)\n");
213       }
214       equals.append("      return false;\n");
215 
216       // hashCode()
217       if (attClass.isPrimitive()) {
218         // primitive type, need some magic
219         hashCode.append("    result = 31 * result + (String.valueOf(" + getterName + ").hashCode());\n");
220       } else if (attClass.isArray()) {
221         // array type, use Array.hashCode()
222         hashCode.append("    result = 31 * result + (" + getterName + "!= null ? java.util.Arrays.hashCode(" + getterName + ") : 0);\n");
223       } else {
224         hashCode.append("    result = 31 * result + (" + getterName + " != null ? " + getterName + ".hashCode() : 0);\n");
225       }
226 
227       // toString()
228       toString.append("    str.append(\"" + attName + " = \" + " + getterName + " + \"\\n\");\n");
229     } catch(CpoException ce) {
230       
231     }
232   }
233 
234   @Override
235   public void visit(CpoFunctionGroup cpoFunctionGroup) {
236 
237     // generate statics for function group
238     String fgName = cpoFunctionGroup.getName();
239     if (fgName == null) {
240       fgName = "NULL";
241     }
242 
243     String staticName = FG_PREFIX + cpoFunctionGroup.getType() + "_" + fgName.toUpperCase();
244 
245     if (cpoFunctionGroup.getName() == null) {
246       functionGroupStatics.append("  public final static String " + staticName + " = null;\n");
247     } else {
248       functionGroupStatics.append("  public final static String " + staticName + " = \"" + fgName + "\";\n");
249     }
250   }
251 
252   @Override
253   public void visit(CpoFunction cpoFunction) {
254     // nothing to do
255   }
256 
257   @Override
258   public void visit(CpoArgument cpoArgument) {
259     // nothing to do
260   }
261 }