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