1 package org.codehaus.modello.plugin.java;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import java.io.File;
26 import java.io.IOException;
27 import java.text.DateFormat;
28 import java.text.ParseException;
29 import java.text.SimpleDateFormat;
30 import java.util.ArrayList;
31 import java.util.Date;
32 import java.util.List;
33 import java.util.Locale;
34 import java.util.Optional;
35 import java.util.Properties;
36
37 import org.codehaus.modello.ModelloException;
38 import org.codehaus.modello.ModelloParameterConstants;
39 import org.codehaus.modello.model.BaseElement;
40 import org.codehaus.modello.model.Model;
41 import org.codehaus.modello.model.ModelAssociation;
42 import org.codehaus.modello.model.ModelClass;
43 import org.codehaus.modello.model.ModelDefault;
44 import org.codehaus.modello.model.ModelField;
45 import org.codehaus.modello.model.ModelInterface;
46 import org.codehaus.modello.model.ModelType;
47 import org.codehaus.modello.plugin.AbstractModelloGenerator;
48 import org.codehaus.modello.plugin.java.javasource.JClass;
49 import org.codehaus.modello.plugin.java.javasource.JComment;
50 import org.codehaus.modello.plugin.java.javasource.JInterface;
51 import org.codehaus.modello.plugin.java.javasource.JSourceWriter;
52 import org.codehaus.modello.plugin.java.javasource.JStructure;
53 import org.codehaus.modello.plugin.java.metadata.JavaClassMetadata;
54 import org.codehaus.modello.plugin.java.metadata.JavaFieldMetadata;
55 import org.codehaus.modello.plugin.java.metadata.JavaModelMetadata;
56 import org.codehaus.modello.plugin.model.ModelClassMetadata;
57 import org.codehaus.plexus.util.StringUtils;
58
59
60
61
62
63
64
65 public abstract class AbstractJavaModelloGenerator extends AbstractModelloGenerator {
66 private Optional<Integer> javaSource;
67
68 protected boolean domAsXpp3 = true;
69
70 protected void initialize(Model model, Properties parameters) throws ModelloException {
71 super.initialize(model, parameters);
72
73 javaSource = Optional.ofNullable(getParameter(parameters, ModelloParameterConstants.OUTPUT_JAVA_SOURCE, null))
74 .map(Integer::valueOf);
75
76 domAsXpp3 = !"false".equals(parameters.getProperty(ModelloParameterConstants.DOM_AS_XPP3));
77 }
78
79
80
81
82
83
84
85
86
87 protected JSourceWriter newJSourceWriter(String packageName, String className) throws IOException {
88 String directory = packageName.replace('.', File.separatorChar);
89
90 File f = new File(new File(getOutputDirectory(), directory), className + ".java");
91
92 if (!f.getParentFile().exists()) {
93 f.getParentFile().mkdirs();
94 }
95
96 return new JSourceWriter(newWriter(f.toPath()));
97 }
98
99 private JComment getHeaderComment() {
100 JComment comment = new JComment();
101 comment.setComment(getHeader());
102 return comment;
103 }
104
105 protected void initHeader(JClass clazz) {
106 clazz.setHeader(getHeaderComment());
107 }
108
109 protected void initHeader(JInterface interfaze) {
110 interfaze.setHeader(getHeaderComment());
111 }
112
113 protected final boolean hasJavaSourceSupport(int source) {
114 return javaSource.map(i -> i >= source).orElse(false);
115 }
116
117 protected void suppressAllWarnings(Model objectModel, JStructure structure) {
118 JavaModelMetadata javaModelMetadata = (JavaModelMetadata) objectModel.getMetadata(JavaModelMetadata.ID);
119
120 if (hasJavaSourceSupport(5) && javaModelMetadata.isSuppressAllWarnings()) {
121 structure.appendAnnotation("@SuppressWarnings( \"all\" )");
122 }
123 }
124
125 protected void addModelImports(JClass jClass, BaseElement baseElem) throws ModelloException {
126 String basePackageName = null;
127 if (baseElem instanceof ModelType) {
128 basePackageName = ((ModelType) baseElem).getPackageName(isPackageWithVersion(), getGeneratedVersion());
129 }
130
131
132 for (ModelInterface modelInterface : getModel().getInterfaces(getGeneratedVersion())) {
133 addModelImport(jClass, modelInterface, basePackageName);
134 }
135
136
137 for (ModelClass modelClass : getClasses(getModel())) {
138 addModelImport(jClass, modelClass, basePackageName);
139 }
140 }
141
142 protected void addModelImport(JClass jClass, ModelType modelType, String basePackageName) {
143 String packageName = modelType.getPackageName(isPackageWithVersion(), getGeneratedVersion());
144
145 if (!packageName.equals(basePackageName)) {
146 jClass.addImport(packageName + '.' + modelType.getName());
147 }
148 }
149
150 protected String getPrefix(JavaFieldMetadata javaFieldMetadata) {
151 return javaFieldMetadata.isBooleanGetter() ? "is" : "get";
152 }
153
154 protected String getDefaultValue(ModelAssociation association) {
155 String value = association.getDefaultValue();
156
157 if (hasJavaSourceSupport(5)) {
158 value = StringUtils.replaceOnce(StringUtils.replaceOnce(value, "/*", ""), "*/", "");
159 }
160
161 return value;
162 }
163
164 protected static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS";
165
166 protected String getJavaDefaultValue(ModelField modelField) throws ModelloException {
167 String type = modelField.getType();
168 String value = modelField.getDefaultValue();
169
170 if ("String".equals(type)) {
171 return '"' + escapeStringLiteral(value) + '"';
172 } else if ("char".equals(type)) {
173 return '\'' + escapeStringLiteral(value) + '\'';
174 } else if ("long".equals(type)) {
175 return value + 'L';
176 } else if ("float".equals(type)) {
177 return value + 'f';
178 } else if ("Date".equals(type)) {
179 DateFormat format = new SimpleDateFormat(DEFAULT_DATE_FORMAT, Locale.US);
180 try {
181 Date date = format.parse(value);
182 return "new java.util.Date( " + date.getTime() + "L )";
183 } catch (ParseException pe) {
184 throw new ModelloException("Unparseable default date: " + value, pe);
185 }
186 } else if (value != null && value.length() > 0) {
187 boolean useJava5 = hasJavaSourceSupport(5);
188 if ("Character".equals(type) && !value.contains(type)) {
189 return newPrimitiveWrapper(type, "'" + escapeStringLiteral(value) + "'", useJava5);
190 } else if ("Boolean".equals(type) && !value.contains(type)) {
191 return newPrimitiveWrapper(type, value, true);
192 } else if ("Byte".equals(type) && !value.contains(type)) {
193 return newPrimitiveWrapper(type, "(byte) " + value, useJava5);
194 } else if ("Short".equals(type) && !value.contains(type)) {
195 return newPrimitiveWrapper(type, "(short) " + value, useJava5);
196 } else if ("Integer".equals(type) && !value.contains(type)) {
197 return newPrimitiveWrapper(type, value, useJava5);
198 } else if ("Long".equals(type) && !value.contains(type)) {
199 return newPrimitiveWrapper(type, value + 'L', useJava5);
200 } else if ("Float".equals(type) && !value.contains(type)) {
201 return newPrimitiveWrapper(type, value + 'f', useJava5);
202 } else if ("Double".equals(type) && !value.contains(type)) {
203 return newPrimitiveWrapper(type, value, useJava5);
204 }
205 }
206
207 return value;
208 }
209
210 private String newPrimitiveWrapper(String type, String value, boolean useJava5) {
211 if (useJava5) {
212 return type + ".valueOf( " + value + " )";
213 } else {
214 return "new " + type + "( " + value + " )";
215 }
216 }
217
218 private String escapeStringLiteral(String str) {
219 StringBuilder buffer = new StringBuilder(str.length() + 32);
220
221 for (int i = 0, n = str.length(); i < n; i++) {
222 char c = str.charAt(i);
223 switch (c) {
224 case '\0':
225 buffer.append("\\0");
226 break;
227 case '\t':
228 buffer.append("\\t");
229 break;
230 case '\r':
231 buffer.append("\\r");
232 break;
233 case '\n':
234 buffer.append("\\n");
235 break;
236 case '\\':
237 buffer.append("\\\\");
238 break;
239 default:
240 buffer.append(c);
241 }
242 }
243
244 return buffer.toString();
245 }
246
247 protected String getValueChecker(String type, String value, ModelField field) throws ModelloException {
248 String retVal;
249 if ("boolean".equals(type)
250 || "double".equals(type)
251 || "float".equals(type)
252 || "int".equals(type)
253 || "long".equals(type)
254 || "short".equals(type)
255 || "byte".equals(type)
256 || "char".equals(type)) {
257 retVal = "if ( " + value + " != " + getJavaDefaultValue(field) + " )";
258 } else if (ModelDefault.LIST.equals(type)
259 || ModelDefault.SET.equals(type)
260 || ModelDefault.MAP.equals(type)
261 || ModelDefault.PROPERTIES.equals(type)) {
262 retVal = "if ( ( " + value + " != null ) && ( " + value + ".size() > 0 ) )";
263 } else if ("String".equals(type) && field.getDefaultValue() != null) {
264 retVal = "if ( ( " + value + " != null ) && !" + value + ".equals( \"" + field.getDefaultValue() + "\" ) )";
265 } else if ("Date".equals(type) && field.getDefaultValue() != null) {
266 retVal = "if ( ( " + value + " != null ) && !" + value + ".equals( " + getJavaDefaultValue(field) + " ) )";
267 } else {
268 retVal = "if ( " + value + " != null )";
269 }
270 return retVal;
271 }
272
273 protected List<ModelClass> getClasses(Model model) {
274 List<ModelClass> modelClasses = new ArrayList<ModelClass>();
275
276 for (ModelClass modelClass : model.getClasses(getGeneratedVersion())) {
277 if (isRelevant(modelClass)) {
278 modelClasses.add(modelClass);
279 }
280 }
281
282 return modelClasses;
283 }
284
285 protected boolean isRelevant(ModelClass modelClass) {
286 return isJavaEnabled(modelClass) && !isTrackingSupport(modelClass);
287 }
288
289 protected boolean isJavaEnabled(ModelClass modelClass) {
290 JavaClassMetadata javaClassMetadata = (JavaClassMetadata) modelClass.getMetadata(JavaClassMetadata.ID);
291 return javaClassMetadata.isEnabled();
292 }
293
294 protected boolean isTrackingSupport(ModelClass modelClass) {
295 ModelClassMetadata modelClassMetadata = (ModelClassMetadata) modelClass.getMetadata(ModelClassMetadata.ID);
296 if (StringUtils.isNotEmpty(modelClassMetadata.getLocationTracker())) {
297 return true;
298 }
299 if (StringUtils.isNotEmpty(modelClassMetadata.getSourceTracker())) {
300 return true;
301 }
302 return false;
303 }
304 }