1 package org.exolab.castor.builder.factory;
2
3 import org.apache.commons.lang3.StringUtils;
4 import org.castor.xml.JavaNaming;
5 import org.exolab.castor.builder.AnnotationBuilder;
6 import org.exolab.castor.builder.info.FieldInfo;
7 import org.exolab.castor.builder.info.nature.SolrjFieldInfoNature;
8 import org.exolab.castor.builder.info.nature.XMLInfoNature;
9 import org.exolab.castor.builder.types.XSType;
10 import org.exolab.javasource.JAnnotation;
11 import org.exolab.javasource.JAnnotationType;
12 import org.exolab.javasource.JClass;
13 import org.exolab.javasource.JDocComment;
14 import org.exolab.javasource.JDocDescriptor;
15 import org.exolab.javasource.JField;
16 import org.exolab.javasource.JMethod;
17 import org.exolab.javasource.JModifiers;
18 import org.exolab.javasource.JParameter;
19 import org.exolab.javasource.JPrimitiveType;
20 import org.exolab.javasource.JSourceCode;
21 import org.exolab.javasource.JType;
22
23
24
25
26
27 public class FieldMemberAndAccessorFactory {
28
29
30
31
32 private JavaNaming javaNaming;
33
34
35
36
37
38 private boolean useOldFieldNaming;
39
40
41
42
43
44
45
46 public FieldMemberAndAccessorFactory(final JavaNaming javaNaming) {
47 this(javaNaming, false);
48 }
49
50
51
52
53
54
55 public FieldMemberAndAccessorFactory(final JavaNaming javaNaming, boolean useOldFieldNaming) {
56 this.javaNaming = javaNaming;
57 this.useOldFieldNaming = useOldFieldNaming;
58 }
59
60
61
62
63
64
65
66 public void generateInitializerCode(final FieldInfo fieldInfo, final JSourceCode jsc) {
67
68 XMLInfoNature xmlNature = new XMLInfoNature(fieldInfo);
69
70 if (!xmlNature.getSchemaType().isPrimitive()) {
71 String value = fieldInfo.getDefaultValue();
72 boolean dateTime = xmlNature.getSchemaType().isDateTime();
73 if (value == null) {
74 value = fieldInfo.getFixedValue();
75 }
76 if (value != null) {
77 StringBuilder buffer = new StringBuilder(50);
78
79
80
81 if (dateTime) {
82 jsc.add("try {");
83 jsc.indent();
84 }
85
86
87
88
89
90
91 buffer.append(fieldInfo.getWriteMethodName())
92
93
94 .append('(').append(value).append(");");
95 jsc.add(buffer.toString());
96 if (dateTime) {
97 jsc.unindent();
98 jsc.add("} catch (java.text.ParseException pe) {");
99 jsc.indent();
100 jsc.add("throw new IllegalStateException(pe.getMessage());");
101 jsc.unindent();
102 jsc.add("}");
103 }
104 }
105 }
106 }
107
108
109
110
111
112
113
114 public final void createJavaField(final FieldInfo fieldInfo, final JClass jClass) {
115 XMLInfoNature xmlNature = new XMLInfoNature(fieldInfo);
116 XSType type = xmlNature.getSchemaType();
117 JType jType = type.getJType();
118
119 JField field = null;
120 if (useOldFieldNaming()) {
121 field = new JField(type.getJType(), fieldInfo.getName());
122 } else {
123 field = new JField(type.getJType(), fieldInfo.getName(), null);
124 }
125
126 if (xmlNature.getSchemaType().isDateTime()) {
127 field.setDateTime(true);
128 }
129
130 if (fieldInfo.isStatic() || fieldInfo.isFinal()) {
131 JModifiers modifiers = field.getModifiers();
132 modifiers.setFinal(fieldInfo.isFinal());
133 modifiers.setStatic(fieldInfo.isStatic());
134 }
135
136 if (!(fieldInfo.getVisibility().equals("private"))) {
137 JModifiers modifiers = field.getModifiers();
138 if (fieldInfo.getVisibility().equals("protected")) {
139 modifiers.makeProtected();
140 } else if (fieldInfo.getVisibility().equals("public")) {
141 modifiers.makePublic();
142 }
143 }
144
145
146 if (fieldInfo.getDefaultValue() != null) {
147 if (!xmlNature.isMultivalued()) {
148 field.setInitString(fieldInfo.getDefaultValue());
149 }
150 }
151
152 if (fieldInfo.getFixedValue() != null && !xmlNature.getSchemaType().isDateTime()) {
153 field.setInitString(fieldInfo.getFixedValue());
154 }
155
156
157 if (fieldInfo.getComment() != null) {
158 field.setComment(fieldInfo.getComment());
159 }
160
161
162 if (fieldInfo.hasNature(SolrjFieldInfoNature.class.getName())) {
163 SolrjFieldInfoNature solrjNature = new SolrjFieldInfoNature(fieldInfo);
164
165 JAnnotationType annotationType = null;
166 if (solrjNature.isIdDefinition()) {
167 annotationType = new JAnnotationType("org.apache.solr.client.solrj.beans.Id");
168 jClass.addImport("org.apache.solr.client.solrj.beans.Id");
169 } else {
170 annotationType = new JAnnotationType("org.apache.solr.client.solrj.beans.Field");
171 jClass.addImport("org.apache.solr.client.solrj.beans.Field");
172 }
173 JAnnotation annotation = new JAnnotation(annotationType);
174 field.addAnnotation(annotation);
175 String fieldName = solrjNature.getFieldName();
176 if (StringUtils.isNotBlank(fieldName)) {
177 annotation.setValue("\"" + fieldName + "\"");
178 }
179 }
180
181 jClass.addField(field);
182
183
184
185
186 if ((!type.isEnumerated()) && (jType.isPrimitive())) {
187 if (useOldFieldNaming()) {
188 field = new JField(JType.BOOLEAN, "_has" + fieldInfo.getName());
189 } else {
190 field = new JField(JType.BOOLEAN, "has" + fieldInfo.getName());
191 }
192 field.setComment("Keeps track of whether primitive field " + fieldInfo.getName()
193 + " has been set already.");
194 jClass.addField(field);
195 }
196
197
198
199
200
201
202
203
204
205
206
207
208 }
209
210
211
212
213
214
215
216
217 public void createAccessMethods(final FieldInfo fieldInfo, final JClass jClass,
218 final boolean useJava50, final AnnotationBuilder[] annotationBuilders) {
219 if ((fieldInfo.getMethods() & FieldInfo.READ_METHOD) > 0) {
220 createGetterMethod(fieldInfo, jClass, useJava50, annotationBuilders);
221 }
222 if ((fieldInfo.getMethods() & FieldInfo.WRITE_METHOD) > 0) {
223 createSetterMethod(fieldInfo, jClass, useJava50);
224 }
225 if (fieldInfo.requiresHasAndDeleteMethods()) {
226 createHasAndDeleteMethods(fieldInfo, jClass);
227 }
228 }
229
230
231
232
233
234
235
236 private void createGetterComment(final FieldInfo fieldInfo, final JDocComment jDocComment) {
237 String fieldName = fieldInfo.getName();
238
239 if (fieldName.indexOf('_') == 0) {
240 fieldName = fieldName.substring(1);
241 }
242
243 String mComment = "Returns the value of field '" + fieldName + "'.";
244 if ((fieldInfo.getComment() != null) && (fieldInfo.getComment().length() > 0)) {
245 mComment += " The field '" + fieldName + "' has the following description: ";
246
247
248 if (fieldInfo.getComment().startsWith("@")) {
249 mComment += "\n\n";
250 }
251
252 mComment += fieldInfo.getComment();
253 }
254 jDocComment.setComment(mComment);
255 }
256
257
258
259
260
261
262
263
264 private void createGetterMethod(final FieldInfo fieldInfo, final JClass jClass,
265 final boolean useJava50, AnnotationBuilder[] annotationBuilders) {
266 JMethod method = null;
267 JSourceCode jsc = null;
268
269 String mname = fieldInfo.getMethodSuffix();
270
271 XSType xsType = new XMLInfoNature(fieldInfo).getSchemaType();
272 JType jType = xsType.getJType();
273
274
275 method =
276 new JMethod(fieldInfo.getReadMethodName(), jType, "the value of field '" + mname + "'.");
277
278
279
280
281 for (AnnotationBuilder annotationBuilder : annotationBuilders) {
282 annotationBuilder.addFieldGetterAnnotations(fieldInfo, method);
283 }
284
285 jClass.addMethod(method);
286 createGetterComment(fieldInfo, method.getJDocComment());
287 jsc = method.getSourceCode();
288 jsc.add("return this.");
289 jsc.append(fieldInfo.getName());
290 jsc.append(";");
291
292 if (xsType.getType() == XSType.BOOLEAN_TYPE) {
293
294
295 method =
296 new JMethod(fieldInfo.getIsMethodName(), jType, "the value of field '" + mname + "'.");
297
298
299
300 jClass.addMethod(method);
301 createGetterComment(fieldInfo, method.getJDocComment());
302 jsc = method.getSourceCode();
303 jsc.add("return this.");
304 jsc.append(fieldInfo.getName());
305 jsc.append(";");
306
307 }
308
309 }
310
311
312
313
314
315
316
317
318 private void createHasAndDeleteMethods(final FieldInfo fieldInfo, final JClass jClass) {
319 JMethod method = null;
320 JSourceCode jsc = null;
321
322 String mname = fieldInfo.getMethodSuffix();
323
324 XSType xsType = new XMLInfoNature(fieldInfo).getSchemaType();
325 xsType.getJType();
326
327
328 method = new JMethod(fieldInfo.getHasMethodName(), JType.BOOLEAN,
329 "true if at least one " + mname + " has been added");
330 jClass.addMethod(method);
331 jsc = method.getSourceCode();
332 jsc.add("return this.");
333 if (useOldFieldNaming()) {
334 jsc.append("_");
335 }
336 jsc.append("has");
337 String fieldName = fieldInfo.getName();
338 jsc.append(fieldName);
339 jsc.append(";");
340
341
342 method = new JMethod(fieldInfo.getDeleteMethodName());
343 jClass.addMethod(method);
344 jsc = method.getSourceCode();
345 jsc.add("this.");
346 if (useOldFieldNaming()) {
347 jsc.append("_");
348 }
349 jsc.append("has");
350 jsc.append(fieldName);
351 jsc.append("= false;");
352
353 if (fieldInfo.isBound()) {
354
355 jsc.add("notifyPropertyChangeListeners(\"");
356 if (fieldName.startsWith("_")) {
357 jsc.append(fieldName.substring(1));
358 } else {
359 jsc.append(fieldName);
360 }
361 jsc.append("\", ");
362
363 jsc.append(xsType.createToJavaObjectCode("this." + fieldName));
364 jsc.append(", null");
365 jsc.append(");");
366 }
367 }
368
369
370
371
372
373
374
375 private void createSetterComment(final FieldInfo fieldInfo, final JDocComment jDocComment) {
376 String fieldName = fieldInfo.getName();
377
378 if (fieldName.indexOf('_') == 0) {
379 fieldName = fieldName.substring(1);
380 }
381
382 String atParam = "the value of field '" + fieldName + "'.";
383
384 String mComment = "Sets " + atParam;
385 if ((fieldInfo.getComment() != null) && (fieldInfo.getComment().length() > 0)) {
386 mComment += " The field '" + fieldName + "' has the following description: ";
387
388
389 if (fieldInfo.getComment().startsWith("@")) {
390 mComment += "\n\n";
391 }
392
393 mComment += fieldInfo.getComment();
394 }
395
396 jDocComment.setComment(mComment);
397
398 JDocDescriptor paramDesc = jDocComment.getParamDescriptor(fieldName);
399 if (paramDesc == null) {
400 paramDesc = JDocDescriptor.createParamDesc(fieldName, null);
401 jDocComment.addDescriptor(paramDesc);
402 }
403 paramDesc.setDescription(atParam);
404 }
405
406
407
408
409
410
411
412
413 private void createSetterMethod(final FieldInfo fieldInfo, final JClass jClass,
414 final boolean useJava50) {
415 JMethod method = null;
416 JSourceCode jsc = null;
417
418 XMLInfoNature xmlNature = new XMLInfoNature(fieldInfo);
419
420 String mname = fieldInfo.getMethodSuffix();
421 XSType xsType = xmlNature.getSchemaType();
422 JType jType = xsType.getJType();
423
424
425
426
427
428
429
430
431 method = new JMethod(fieldInfo.getWriteMethodName());
432 jClass.addMethod(method);
433
434 String paramName = fieldInfo.getName();
435
436
437
438 if (paramName.indexOf('_') == 0) {
439 String tempName = paramName.substring(1);
440 if (javaNaming.isValidJavaIdentifier(tempName)) {
441 paramName = tempName;
442 }
443 }
444
445 method.addParameter(new JParameter(jType, paramName));
446
447
448
449 createSetterComment(fieldInfo, method.getJDocComment());
450 jsc = method.getSourceCode();
451
452 String fieldName = fieldInfo.getName();
453
454 if (fieldInfo.isBound()) {
455
456 jsc.add("java.lang.Object old");
457 jsc.append(mname);
458 jsc.append(" = ");
459
460 jsc.append(xsType.createToJavaObjectCode("this." + fieldName));
461 jsc.append(";");
462 }
463
464
465 jsc.add("this.");
466 jsc.append(fieldName);
467 jsc.append(" = ");
468 jsc.append(paramName);
469 jsc.append(";");
470
471 if (fieldInfo.getFieldInfoReference() != null) {
472 jsc.add("this.");
473 jsc.append(fieldInfo.getFieldInfoReference().getName());
474 jsc.append(" = ");
475
476 JType referencedJType =
477 new XMLInfoNature(fieldInfo.getFieldInfoReference()).getSchemaType().getJType();
478 if (referencedJType.isPrimitive()) {
479 jsc.append(paramName);
480 } else if (jType.isPrimitive()) {
481 JPrimitiveType primitive = (JPrimitiveType) jType;
482 jsc.append("new ");
483 jsc.append(primitive.getWrapperName());
484 jsc.append("(");
485 jsc.append(paramName);
486 jsc.append(")");
487 } else {
488 jsc.append(paramName);
489 }
490
491 jsc.append(";");
492 }
493
494
495 if (fieldInfo.requiresHasAndDeleteMethods()) {
496 jsc.add("this.");
497 if (useOldFieldNaming()) {
498 jsc.append("_");
499 }
500 jsc.append("has");
501 jsc.append(fieldName);
502 jsc.append(" = true;");
503 }
504
505
506 if (fieldInfo.isBound()) {
507
508 jsc.add("notifyPropertyChangeListeners(\"");
509 if (fieldName.startsWith("_")) {
510 jsc.append(fieldName.substring(1));
511 } else {
512 jsc.append(fieldName);
513 }
514 jsc.append("\", old");
515 jsc.append(mname);
516 jsc.append(", ");
517
518 jsc.append(xsType.createToJavaObjectCode("this." + fieldName));
519 jsc.append(");");
520 }
521 }
522
523
524
525
526
527
528 public JavaNaming getJavaNaming() {
529 return javaNaming;
530 }
531
532 public void setUseOldFieldNaming(boolean useOldFieldNaming) {
533 this.useOldFieldNaming = useOldFieldNaming;
534 }
535
536 private boolean useOldFieldNaming() {
537 return this.useOldFieldNaming;
538 }
539 }