1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jdo.impl.enhancer.generator;
18
19 import java.lang.reflect.Modifier;
20
21 import java.util.Iterator;
22 import java.util.Collection;
23 import java.util.List;
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.Properties;
27
28 import java.io.Serializable;
29 import java.io.File;
30 import java.io.Writer;
31 import java.io.PrintWriter;
32 import java.io.FileWriter;
33 import java.io.BufferedWriter;
34 import java.io.InputStream;
35 import java.io.BufferedInputStream;
36 import java.io.FileInputStream;
37 import java.io.ObjectOutputStream;
38 import java.io.IOException;
39 import java.io.FileNotFoundException;
40
41 import org.apache.jdo.impl.enhancer.meta.ExtendedMetaData;
42 import org.apache.jdo.impl.enhancer.meta.prop.EnhancerMetaDataPropertyImpl;
43 import org.apache.jdo.impl.enhancer.util.Support;
44
45
46
47
48 /***
49 *
50 */
51 public final class Main
52 extends Support
53 {
54 /***
55 * The stream to write messages to.
56 */
57 private final PrintWriter out = new PrintWriter(System.out, true);
58
59 /***
60 * The stream to write error messages to.
61 */
62 private final PrintWriter err = new PrintWriter(System.err, true);
63
64 /***
65 * The command line options.
66 */
67 private final CmdLineOptions opts = new CmdLineOptions();
68
69 /***
70 *
71 */
72 private final CodeWriter writer = new CodeWriter();
73
74 /***
75 * The MetaData for generating classes.
76 */
77 private ExtendedMetaData meta = null;
78
79 /***
80 *
81 */
82 public Main()
83 {}
84
85 /***
86 *
87 */
88 public static final void main(String[] argv)
89 {
90 final Main gen = new Main();
91 try {
92 gen.opts.processArgs(argv);
93 gen.init();
94 gen.generate();
95 } catch(Exception ex) {
96 gen.printError(null, ex);
97 }
98 }
99
100 /***
101 * A class for holding the command line options.
102 */
103 private class CmdLineOptions
104 {
105
106 String destinationDirectory = null;
107 String jdoXMLModelFileName = null;
108 String jdoPropertiesFileName = null;
109 boolean verbose = false;
110 boolean quiet = false;
111 boolean forceWrite = false;
112 boolean noWrite = false;
113
114 /***
115 * Print a usage message to System.err
116 */
117 public void usage() {
118 err.println("Usage: Main <options> <arguments>...");
119 err.println("Options:");
120 err.println(" -v, --verbose print verbose output");
121
122
123
124
125
126 err.println(" -d, --dest <dir> destination directory for output files");
127 err.println(" -p, --properties <file> use property file for meta data");
128
129
130
131 err.println();
132 err.println("Arguments:");
133 err.println();
134 err.println("Returns a non-zero value in case of errors.");
135 System.exit(1);
136 }
137
138 /***
139 * Process command line options
140 */
141 protected int processArgs(String[] argv)
142 {
143 for (int i = 0; i < argv.length; i++) {
144 final String arg = argv[i];
145 if (arg.equals("-v")
146 || arg.equals("--verbose")) {
147 verbose = true;
148 quiet = false;
149 continue;
150 }
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169 if (arg.equals("-d")
170 || arg.equals("--dest")) {
171 if (argv.length - i < 2) {
172 printError("Missing argument to the -d/-dest option", null);
173 usage();
174 }
175 destinationDirectory = argv[++i];
176 continue;
177 }
178 if (arg.equals("-p") ||
179 arg.equals("--properties")) {
180 if (argv.length - i < 2) {
181 printError("Missing argument to the -p/--properties option", null);
182 usage();
183 }
184 jdoPropertiesFileName = argv[++i];
185 continue;
186 }
187
188
189
190
191
192
193
194
195
196
197
198 if (arg.length() > 0 && arg.charAt(0) == '-') {
199 printError("Unrecognized option:" + arg, null);
200 usage();
201 }
202 if (arg.length() == 0) {
203 printMessage("Ignoring empty command line argument.");
204 continue;
205 }
206
207
208 }
209
210
211 if (jdoPropertiesFileName == null) {
212 printError("No destination directory specified", null);
213 usage();
214 }
215
216
217 if (destinationDirectory == null) {
218 printError("No destination directory specified", null);
219 usage();
220 }
221
222 return 0;
223 }
224 }
225
226 private void init()
227 throws FileNotFoundException, IOException
228 {
229
230 affirm(opts.jdoPropertiesFileName != null);
231 meta = new EnhancerMetaDataPropertyImpl(out, opts.verbose,
232 opts.jdoPropertiesFileName);
233
234
235 affirm(opts.destinationDirectory != null);
236 final File destinationDir = new File(opts.destinationDirectory);
237 boolean res = destinationDir.mkdirs();
238 if (!res) {
239 throw new IOException("unable to create destination directory: "
240 + "'" + destinationDir + "'");
241 }
242 }
243
244 private void generate()
245 {
246 final String[] classes = meta.getKnownClasses();
247 for (int i = 0; i < classes.length; i++) {
248 final String classname = classes[i];
249 try {
250 if (classname.indexOf('$') != -1) {
251 printMessage("Skipping generation of nested class " + classname + "." +
252 " Note, a nested ObjectId class is generated with its pc class.");
253 continue;
254 }
255 final Writer writer = createFileWriter(classname);
256 this.writer.setWriter(writer);
257 generateClass(classname);
258 writer.close();
259 } catch(IOException ex) {
260 printError("Error generating class '" + classname + "'.", ex);
261 }
262 }
263 }
264
265 private void generateClass(final String classname)
266 throws IOException
267 {
268 affirm(classname);
269
270 final String normClassName = NameHelper.normalizeClassName(classname);
271 printMessage("generating '" + normClassName + "'...");
272
273 final</strong> String packageName = NameHelper.getPackageName(classname);
274 writer.writePackage(
275 packageName,
276 null);
277
278 writer.writeImports(
279 null,
280 null);
281
282
283 final String oidClassName = meta.getKeyClass(classname);
284 if (oidClassName == null) {
285 writeClassHeader(classname);
286 } else {
287 final String oidPackageName
288 = NameHelper.getPackageName(oidClassName);
289 affirm(packageName.equals(oidPackageName),
290 "PC class and key class must be in same package.");
291
292 final boolean enclosedOid
293 = oidClassName.startsWith(classname + "$");
294 if (enclosedOid) {
295 writeClassHeader(classname);
296 writeOidClass(classname, oidClassName, enclosedOid);
297 } else {
298 writeOidClass(classname, oidClassName, enclosedOid);
299 writeClassHeader(classname);
300 }
301 }
302
303 writeClassMembers(classname);
304
305
306 final boolean isPC = meta.isPersistenceCapableClass(classname);
307 if (isPC) {
308 final boolean isPCRoot
309 = meta.isPersistenceCapableRootClass(classname);
310 if (isPCRoot) {
311 writePCRootMembers(classname);
312 }
313 writePCMembers(classname);
314
315 writeClassMemberAccessors(classname);
316 }
317
318 writer.writeClassEnd();
319 }
320
321 private Writer createFileWriter(String classname)
322 throws IOException
323 {
324 final File file = new File(opts.destinationDirectory,
325 classname + ".java");
326 file.getAbsoluteFile().getParentFile().mkdirs();
327 return new BufferedWriter(new FileWriter(file));
328 }
329
330 private void writeClassHeader(final String classname)
331 throws IOException
332 {
333 final boolean isPCRoot = meta.isPersistenceCapableRootClass(classname);
334 final String superclass = meta.getSuperClass(classname);
335
336 String[] interfaces = null;
337 String[] comments = null;
338 interfaces
339 = new String[]{ ImplHelper.CLASSNAME_JDO_PERSISTENCE_CAPABLE };
340 writer.writeClassHeader(meta.getClassModifiers(classname),
341 ImplHelper.getClassName(classname),
342 superclass,
343 interfaces,
344 comments);
345 }
346
347 private void writeClassMembers(final String classname)
348 throws IOException
349 {
350 writer.writeComments(1, new String[]{
351 "----------------------------------------------------------------------",
352 "Class Members:",
353 "----------------------------------------------------------------------"
354 });
355 writer.writeln();
356
357
358 writer.writeConstructor(
359 ImplHelper.getClassName(classname),
360 Modifier.PUBLIC,
361 null, null, null,
362 ImplHelper.getDefaultConstructorImpl(),
363 ImplHelper.COMMENT_NOT_ENHANCER_ADDED);
364
365
366 writer.writeConstructor(
367 ImplHelper.getClassName(classname),
368 Modifier.PUBLIC,
369 new String[]{ "str" },
370 new String[]{ "String" },
371 null,
372 ImplHelper.getDummyConstructorImpl(),
373 ImplHelper.COMMENT_NOT_ENHANCER_ADDED);
374
375 final String[] fieldnames = meta.getKnownFields(classname);
376 final int n = (fieldnames != null ? fieldnames.length : 0);
377
378
379 for (int i = 0; i < n; i++) {
380 final String fieldname = (String)fieldnames[i];
381 writeFieldMember(classname, fieldname);
382 }
383 }
384
385 private void writeFieldMember(final String classname,
386 final String fieldname)
387 throws IOException
388 {
389 final String fieldtype = meta.getFieldType(classname, fieldname);
390 final int access = meta.getFieldModifiers(classname, fieldname);
391 final String normClassName = NameHelper.normalizeClassName(classname);
392 final List impl = new ArrayList();
393
394
395 writer.writeField(
396 fieldname,
397 access,
398 fieldtype,
399 null, null);
400
401
402 if ((access & Modifier.STATIC) != 0) {
403 return;
404 }
405
406
407 impl.clear();
408 impl.add("//return this." + fieldname + ';');
409 final String accessor
410 = ImplHelper.createJDOFieldAccessorName(classname, fieldname);
411 impl.add("return " + normClassName + "." + accessor + "(this);");
412 writer.writeMethod(
413 createMethodName("get", fieldname),
414 Modifier.PUBLIC,
415 fieldtype,
416 null,
417 null,
418 null,
419 impl,
420 ImplHelper.COMMENT_NOT_ENHANCER_ADDED);
421
422
423 impl.clear();
424 impl.add("//this." + fieldname + " = " + fieldname + ';');
425 final String mutator
426 = ImplHelper.createJDOFieldMutatorName(classname, fieldname);
427 impl.add(normClassName + "." + mutator + "(this, " + fieldname + ");");
428 writer.writeMethod(
429 createMethodName("set", fieldname),
430 Modifier.PUBLIC,
431 "void",
432 new String[]{ fieldname },
433 new String[]{ fieldtype },
434 null,
435 impl,
436 ImplHelper.COMMENT_NOT_ENHANCER_ADDED);
437 }
438
439 private void writeClassMemberAccessors(final String classname)
440 throws IOException
441 {
442 writer.writeComments(1, new String[]{
443 "----------------------------------------------------------------------",
444 "Augmentation for Field Accessors and Mutators (added by enhancer):",
445 "----------------------------------------------------------------------"
446 });
447 writer.writeln();
448
449
450 final String[] fields = meta.getManagedFields(classname);
451 final int n = (fields != null ? fields.length : 0);
452 for (int i = 0; i < n; i++) {
453 final String fieldname = (String)fields[i];
454 writeFieldAccessors(classname, fieldname);
455 }
456 }
457
458 private void writeFieldAccessors(final String classname,
459 final String fieldname)
460 throws IOException
461 {
462 final String fieldtype
463 = meta.getFieldType(classname, fieldname);
464 final int fieldnumber
465 = meta.getFieldNumber(classname, fieldname);
466 final boolean dfg
467 = meta.isDefaultFetchGroupField(classname, fieldname);
468 final int access
469 = meta.getFieldModifiers(classname, fieldname);
470 final int flags
471 = meta.getFieldFlags(classname, fieldname);
472
473 final String accessor
474 = ImplHelper.createJDOFieldAccessorName(classname, fieldname);
475 final String mutator
476 = ImplHelper.createJDOFieldMutatorName(classname, fieldname);
477
478 final String instancename
479 = "instance";
480
481
482 {
483 affirm(((flags & meta.CHECK_READ) == 0)
484 | (flags & meta.MEDIATE_READ) == 0);
485 final List impl;
486 if ((flags & meta.CHECK_READ) != 0) {
487 impl = ImplHelper.getJDOFieldCheckReadImpl(fieldname,
488 fieldtype,
489 fieldnumber,
490 instancename);
491 } else if ((flags & meta.MEDIATE_READ) != 0) {
492 impl = ImplHelper.getJDOFieldMediateReadImpl(fieldname,
493 fieldtype,
494 fieldnumber,
495 instancename);
496 } else {
497 impl = ImplHelper.getJDOFieldDirectReadImpl(fieldname,
498 fieldtype,
499 fieldnumber,
500 instancename);
501 }
502 writer.writeMethod(
503 accessor,
504 access | Modifier.STATIC | Modifier.FINAL,
505 fieldtype,
506 new String[]{ instancename },
507 new String[]{ classname },
508 null,
509 impl,
510 ImplHelper.COMMENT_ENHANCER_ADDED);
511 }
512
513
514 {
515 affirm(((flags & meta.CHECK_WRITE) == 0)
516 | (flags & meta.MEDIATE_WRITE) == 0);
517 final List impl;
518 if ((flags & meta.CHECK_WRITE) != 0) {
519 impl = ImplHelper.getJDOFieldCheckWriteImpl(fieldname,
520 fieldtype,
521 fieldnumber,
522 instancename,
523 fieldname);
524 } else if ((flags & meta.MEDIATE_WRITE) != 0) {
525 impl = ImplHelper.getJDOFieldMediateWriteImpl(fieldname,
526 fieldtype,
527 fieldnumber,
528 instancename,
529 fieldname);
530 } else {
531 impl = ImplHelper.getJDOFieldDirectWriteImpl(fieldname,
532 fieldtype,
533 fieldnumber,
534 instancename,
535 fieldname);
536 }
537 writer.writeMethod(
538 mutator,
539 access | Modifier.STATIC | Modifier.FINAL,
540 "void",
541 new String[]{ instancename, fieldname },
542 new String[]{ classname, fieldtype },
543 null,
544 impl,
545 ImplHelper.COMMENT_ENHANCER_ADDED);
546 }
547 }
548
549 private void writePCRootMembers(final String classname)
550 throws IOException
551 {
552 writer.writeComments(1, new String[]{
553 "----------------------------------------------------------------------",
554 "Augmentation for Persistence-Capable Root Classes (added by enhancer):",
555 "----------------------------------------------------------------------"
556 });
557 writer.writeln();
558
559
560 writer.writeField(
561 ImplHelper.FIELDNAME_JDO_STATE_MANAGER,
562 Modifier.PROTECTED | Modifier.TRANSIENT,
563 ImplHelper.CLASSNAME_JDO_STATE_MANAGER,
564 "null",
565 ImplHelper.COMMENT_ENHANCER_ADDED);
566
567
568 writer.writeField(
569 ImplHelper.FIELDNAME_JDO_FLAGS,
570 Modifier.PROTECTED | Modifier.TRANSIENT,
571 "byte",
572 "0",
573
574 ImplHelper.COMMENT_ENHANCER_ADDED);
575
576
577 writer.writeMethod(
578 ImplHelper.METHODNAME_JDO_REPLACE_STATE_MANAGER,
579 Modifier.PUBLIC | Modifier.FINAL | Modifier.SYNCHRONIZED,
580 "void",
581 new String[]{ "sm" },
582 new String[]{ ImplHelper.CLASSNAME_JDO_STATE_MANAGER },
583 null,
584 ImplHelper.getJDOReplaceStateManagerImpl("sm"),
585 ImplHelper.COMMENT_ENHANCER_ADDED);
586
587
588 writer.writeMethod(
589 ImplHelper.METHODNAME_JDO_REPLACE_FLAGS,
590 Modifier.PUBLIC | Modifier.FINAL,
591 "void", null, null, null,
592 ImplHelper.getJDOReplaceFlagsImpl(),
593 ImplHelper.COMMENT_ENHANCER_ADDED);
594
595
596 writer.writeMethod(
597 ImplHelper.METHODNAME_JDO_GET_PERSISTENCE_MANAGER,
598 Modifier.PUBLIC | Modifier.FINAL,
599 ImplHelper.CLASSNAME_JDO_PERSISTENCE_MANAGER, null, null, null,
600 ImplHelper.getJDOStateManagerObjectDelegationImpl("getPersistenceManager(this)"),
601 ImplHelper.COMMENT_ENHANCER_ADDED);
602
603
604 writer.writeMethod(
605 ImplHelper.METHODNAME_JDO_GET_OBJECT_ID,
606 Modifier.PUBLIC | Modifier.FINAL,
607 Object.class.getName(), null, null, null,
608 ImplHelper.getJDOStateManagerObjectDelegationImpl("getObjectId(this)"),
609 ImplHelper.COMMENT_ENHANCER_ADDED);
610
611 writer.writeMethod(
612 ImplHelper.METHODNAME_JDO_GET_TRANSACTIONAL_OBJECT_ID,
613 Modifier.PUBLIC | Modifier.FINAL,
614 Object.class.getName(), null, null, null,
615 ImplHelper.getJDOStateManagerObjectDelegationImpl("getTransactionalObjectId(this)"),
616 ImplHelper.COMMENT_ENHANCER_ADDED);
617
618
619 writer.writeMethod(
620 ImplHelper.METHODNAME_JDO_GET_VERSION,
621 Modifier.PUBLIC | Modifier.FINAL,
622 Object.class.getName(), null, null, null,
623
624 ImplHelper.getNotYetImplemented(
625 ImplHelper.METHODNAME_JDO_GET_VERSION),
626 ImplHelper.COMMENT_ENHANCER_ADDED);
627
628
629 writer.writeMethod(
630 ImplHelper.METHODNAME_JDO_IS_PERSISTENT,
631 Modifier.PUBLIC | Modifier.FINAL,
632 "boolean", null, null, null,
633 ImplHelper.getJDOStateManagerBooleanDelegationImpl("isPersistent(this)"),
634 ImplHelper.COMMENT_ENHANCER_ADDED);
635
636 writer.writeMethod(
637 ImplHelper.METHODNAME_JDO_IS_TRANSACTIONAL,
638 Modifier.PUBLIC | Modifier.FINAL,
639 "boolean", null, null, null,
640 ImplHelper.getJDOStateManagerBooleanDelegationImpl("isTransactional(this)"),
641 ImplHelper.COMMENT_ENHANCER_ADDED);
642
643 writer.writeMethod(
644 ImplHelper.METHODNAME_JDO_IS_NEW,
645 Modifier.PUBLIC | Modifier.FINAL,
646 "boolean", null, null, null,
647 ImplHelper.getJDOStateManagerBooleanDelegationImpl("isNew(this)"),
648 ImplHelper.COMMENT_ENHANCER_ADDED);
649
650 writer.writeMethod(
651 ImplHelper.METHODNAME_JDO_IS_DELETED,
652 Modifier.PUBLIC | Modifier.FINAL,
653 "boolean", null, null, null,
654 ImplHelper.getJDOStateManagerBooleanDelegationImpl("isDeleted(this)"),
655 ImplHelper.COMMENT_ENHANCER_ADDED);
656
657 writer.writeMethod(
658 ImplHelper.METHODNAME_JDO_IS_DIRTY,
659 Modifier.PUBLIC | Modifier.FINAL,
660 "boolean", null, null, null,
661 ImplHelper.getJDOStateManagerBooleanDelegationImpl("isDirty(this)"),
662 ImplHelper.COMMENT_ENHANCER_ADDED);
663
664 writer.writeMethod(
665 ImplHelper.METHODNAME_JDO_IS_DETACHED,
666 Modifier.PUBLIC | Modifier.FINAL,
667 "boolean", null, null, null,
668
669 ImplHelper.getNotYetImplemented(
670 ImplHelper.METHODNAME_JDO_IS_DETACHED),
671 ImplHelper.COMMENT_ENHANCER_ADDED);
672
673
674 writer.writeMethod(
675 ImplHelper.METHODNAME_JDO_MAKE_DIRTY,
676 Modifier.PUBLIC | Modifier.FINAL,
677 "void",
678 new String[]{ "fieldname" },
679 new String[]{ String.class.getName() },
680 null,
681 ImplHelper.getJDOStateManagerVoidDelegationImpl("makeDirty(this, fieldname)"),
682 ImplHelper.COMMENT_ENHANCER_ADDED);
683
684
685 writer.writeMethod(
686 ImplHelper.METHODNAME_JDO_REPLACE_FIELDS,
687 Modifier.PUBLIC | Modifier.FINAL,
688 "void",
689 new String[]{ "fieldnumbers" },
690 new String[]{ "int[]" },
691 null,
692 ImplHelper.getJDOFieldIterationImpl("fieldnumbers",
693 ImplHelper.METHODNAME_JDO_REPLACE_FIELD),
694 ImplHelper.COMMENT_ENHANCER_ADDED);
695
696
697 writer.writeMethod(
698 ImplHelper.METHODNAME_JDO_PROVIDE_FIELDS,
699 Modifier.PUBLIC | Modifier.FINAL,
700 "void",
701 new String[]{ "fieldnumbers" },
702 new String[]{ "int[]" },
703 null,
704 ImplHelper.getJDOFieldIterationImpl("fieldnumbers",
705 ImplHelper.METHODNAME_JDO_PROVIDE_FIELD),
706 ImplHelper.COMMENT_ENHANCER_ADDED);
707
708
709 writer.writeMethod(
710 ImplHelper.METHODNAME_JDO_PRE_SERIALIZE,
711 Modifier.PROTECTED | Modifier.FINAL,
712 "void", null, null, null,
713 ImplHelper.getJDOStateManagerVoidDelegationImpl("preSerialize(this)"),
714 ImplHelper.COMMENT_ENHANCER_ADDED);
715
716
717 writer.writeMethod(
718 "clone",
719 Modifier.PUBLIC,
720 "Object",
721 null,
722 null,
723 new String[]{ "java.lang.CloneNotSupportedException" },
724 ImplHelper.getCloneImpl(classname),
725 ImplHelper.COMMENT_NOT_ENHANCER_ADDED);
726
727 }
728
729 private void writePCMembers(final String classname)
730 throws IOException
731 {
732 writer.writeComments(1, new String[]{
733 "----------------------------------------------------------------------",
734 "Augmentation for Persistence-Capable Classes (added by enhancer):",
735 "----------------------------------------------------------------------"
736 });
737 writer.writeln();
738
739 final String[] managedFieldNames
740 = meta.getManagedFields(classname);
741 final String[] managedFieldTypes
742 = meta.getFieldType(classname, managedFieldNames);
743 final boolean isPCRoot
744 = meta.isPersistenceCapableRootClass(classname);
745
746 writePCStaticMembers(classname);
747
748
749 writer.writeMethod(
750 ImplHelper.METHODNAME_JDO_NEW_INSTANCE,
751 Modifier.PUBLIC,
752 ImplHelper.CLASSNAME_JDO_PERSISTENCE_CAPABLE,
753 new String[]{ "sm" },
754 new String[]{ ImplHelper.CLASSNAME_JDO_STATE_MANAGER },
755 null,
756 ImplHelper.getJDONewInstanceImpl(classname,
757 "sm"),
758 ImplHelper.COMMENT_ENHANCER_ADDED);
759
760
761 writer.writeMethod(
762 ImplHelper.METHODNAME_JDO_NEW_INSTANCE,
763 Modifier.PUBLIC,
764 ImplHelper.CLASSNAME_JDO_PERSISTENCE_CAPABLE,
765 new String[]{ "sm", "oid" },
766 new String[]{ ImplHelper.CLASSNAME_JDO_STATE_MANAGER, "Object" },
767 null,
768 ImplHelper.getJDONewInstanceKeyImpl(classname,
769
770 "sm",
771 "oid"),
772
773 ImplHelper.COMMENT_ENHANCER_ADDED);
774
775
776 writer.writeMethod(
777 ImplHelper.METHODNAME_JDO_REPLACE_FIELD,
778 Modifier.PUBLIC,
779 "void",
780 new String[]{ "fieldnumber" },
781 new String[]{ "int" },
782 null,
783 ImplHelper.getJDOReplaceFieldImpl("fieldnumber",
784 isPCRoot,
785 managedFieldNames,
786 managedFieldTypes),
787 ImplHelper.COMMENT_ENHANCER_ADDED);
788
789
790 writer.writeMethod(
791 ImplHelper.METHODNAME_JDO_PROVIDE_FIELD,
792 Modifier.PUBLIC,
793 "void",
794 new String[]{ "fieldnumber" },
795 new String[]{ "int" },
796 null,
797 ImplHelper.getJDOProvideFieldImpl("fieldnumber",
798 isPCRoot,
799 managedFieldNames,
800 managedFieldTypes),
801 ImplHelper.COMMENT_ENHANCER_ADDED);
802
803
804 writer.writeMethod(
805 ImplHelper.METHODNAME_JDO_COPY_FIELDS,
806 Modifier.PUBLIC,
807 "void",
808 new String[]{ "pc", "fieldnumbers" },
809 new String[]{ Object.class.getName(), "int[]" },
810 null,
811 ImplHelper.getJDOCopyFieldsImpl(classname,
812 "pc",
813 "fieldnumbers"),
814 ImplHelper.COMMENT_ENHANCER_ADDED);
815
816
817 writer.writeMethod(
818 ImplHelper.METHODNAME_JDO_COPY_FIELD,
819 Modifier.PROTECTED | Modifier.FINAL,
820 "void",
821 new String[]{ "pc", "fieldnumber" },
822 new String[]{ classname, "int" },
823 null,
824 ImplHelper.getJDOCopyFieldImpl(classname,
825 "pc",
826 "fieldnumber",
827 managedFieldNames,
828 isPCRoot),
829 ImplHelper.COMMENT_ENHANCER_ADDED);
830
831 writePCKeyHandlingMembers(classname);
832
833 writePCSerializationMembers(classname);
834 }
835
836 private void writePCStaticMembers(final String classname)
837 throws IOException
838 {
839 final String[] managedFieldNames
840 = meta.getManagedFields(classname);
841 final String superPC
842 = meta.getPersistenceCapableSuperClass(classname);
843 final String[] managedFieldTypes
844 = meta.getFieldType(classname, managedFieldNames);
845 final int[] managedFieldFlags
846 = meta.getFieldFlags(classname, managedFieldNames);
847 final boolean isPCRoot
848 = meta.isPersistenceCapableRootClass(classname);
849
850
851 writer.writeField(
852 ImplHelper.FIELDNAME_JDO_INHERITED_FIELD_COUNT,
853 Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL,
854 "int",
855 null,
856 ImplHelper.COMMENT_ENHANCER_ADDED);
857
858
859 writer.writeField(
860 ImplHelper.FIELDNAME_JDO_FIELD_NAMES,
861 Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL,
862 "String[]",
863 null,
864 ImplHelper.COMMENT_ENHANCER_ADDED);
865
866
867 writer.writeField(
868 ImplHelper.FIELDNAME_JDO_FIELD_TYPES,
869 Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL,
870 "Class[]",
871 null,
872 ImplHelper.COMMENT_ENHANCER_ADDED);
873
874
875 writer.writeField(
876 ImplHelper.FIELDNAME_JDO_FIELD_FLAGS,
877 Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL,
878 "byte[]",
879 null,
880 ImplHelper.COMMENT_ENHANCER_ADDED);
881
882
883 writer.writeField(
884 ImplHelper.FIELDNAME_JDO_PC_SUPERCLASS,
885 Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL,
886 "Class",
887 null,
888 ImplHelper.COMMENT_ENHANCER_ADDED);
889
890
891 writer.writeStaticInitializer(
892 ImplHelper.getStaticInitializerImpl(classname,
893 superPC,
894 managedFieldNames,
895 managedFieldTypes,
896 managedFieldFlags),
897 ImplHelper.COMMENT_ENHANCER_ADDED);
898
899
900 writer.writeMethod(
901 ImplHelper.METHODNAME_JDO_GET_MANAGED_FIELD_COUNT,
902 Modifier.PROTECTED | Modifier.STATIC,
903 "int", null, null, null,
904 ImplHelper.getJDOGetManagedFieldCountImpl(
905 isPCRoot, superPC, managedFieldNames.length),
906 ImplHelper.COMMENT_ENHANCER_ADDED);
907 }
908
909 private void writePCKeyHandlingMembers(final String classname)
910 throws IOException
911 {
912 final boolean isPCRoot
913 = meta.isPersistenceCapableRootClass(classname);
914 final String oidClassName
915 = NameHelper.normalizeClassName(meta.getKeyClass(classname));
916
917
918
919 if (!isPCRoot && oidClassName == null) {
920 return;
921 }
922
923 final String superOidClassName
924 = NameHelper.normalizeClassName(meta.getSuperKeyClass(classname));
925 final String[] keyFieldNames
926 = meta.getKeyFields(classname);
927 final String[] keyFieldTypes
928 = meta.getFieldType(classname, keyFieldNames);
929 final int[] keyFieldNumbers
930 = meta.getFieldNumber(classname, keyFieldNames);
931
932
933 writer.writeMethod(
934 ImplHelper.METHODNAME_JDO_NEW_OID_INSTANCE,
935 Modifier.PUBLIC,
936 Object.class.getName(), null, null, null,
937 ImplHelper.getJDONewOidInstanceImpl(oidClassName),
938 ImplHelper.COMMENT_ENHANCER_ADDED);
939
940 writer.writeMethod(
941 ImplHelper.METHODNAME_JDO_NEW_OID_INSTANCE,
942 Modifier.PUBLIC,
943 Object.class.getName(),
944 new String[]{ "o" },
945 new String[]{ "Object" },
946 null,
947 ImplHelper.getJDONewOidInstanceImpl(oidClassName,
948 "o"),
949 ImplHelper.COMMENT_ENHANCER_ADDED);
950
951
952 writer.writeMethod(
953 ImplHelper.METHODNAME_JDO_COPY_KEY_FIELDS_TO_OID,
954 Modifier.PUBLIC,
955 "void",
956 new String[]{ "oid" },
957 new String[]{ "Object" },
958 null,
959 ImplHelper.getJDOCopyKeyFieldsToOid(oidClassName,
960 superOidClassName,
961 "oid",
962 keyFieldNames),
963 ImplHelper.COMMENT_ENHANCER_ADDED);
964
965 writer.writeMethod(
966 ImplHelper.METHODNAME_JDO_COPY_KEY_FIELDS_FROM_OID,
967 Modifier.PROTECTED,
968 "void",
969 new String[]{ "oid" },
970 new String[]{ "Object" },
971 null,
972 ImplHelper.getJDOCopyKeyFieldsFromOid(oidClassName,
973 superOidClassName,
974 "oid",
975 keyFieldNames),
976 ImplHelper.COMMENT_ENHANCER_ADDED);
977
978 writer.writeMethod(
979 ImplHelper.METHODNAME_JDO_COPY_KEY_FIELDS_TO_OID,
980 Modifier.PUBLIC,
981 "void",
982 new String[]{ "ofs", "oid" },
983 new String[]{ ImplHelper.CLASSNAME_JDO_OBJECT_ID_FIELD_SUPPLIER,
984 "Object" },
985 null,
986 ImplHelper.getJDOCopyKeyFieldsToOid(oidClassName,
987 superOidClassName,
988 "ofs",
989 "oid",
990 keyFieldNames,
991 keyFieldTypes,
992 keyFieldNumbers),
993 ImplHelper.COMMENT_ENHANCER_ADDED);
994
995 writer.writeMethod(
996 ImplHelper.METHODNAME_JDO_COPY_KEY_FIELDS_FROM_OID,
997 Modifier.PUBLIC,
998 "void",
999 new String[]{ "ofc", "oid" },
1000 new String[]{ ImplHelper.CLASSNAME_JDO_OBJECT_ID_FIELD_CONSUMER,
1001 "Object" },
1002 null,
1003 ImplHelper.getJDOCopyKeyFieldsFromOid(oidClassName,
1004 superOidClassName,
1005 "ofc",
1006 "oid",
1007 keyFieldNames,
1008 keyFieldTypes,
1009 keyFieldNumbers),
1010 ImplHelper.COMMENT_ENHANCER_ADDED);
1011 }
1012
1013 private void writePCSerializationMembers(final String classname)
1014 throws IOException
1015 {
1016 final long serialUID
1017 = createJDOVersionUID(classname);
1018
1019
1020 writer.writeField(
1021 ImplHelper.FIELDNAME_SERIAL_VERSION_UID,
1022 Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL,
1023 "long",
1024 ImplHelper.getSerialVersionUIDInitValue(serialUID),
1025 new String[]{ "only a dummy value yet"});
1026
1027
1028 writer.writeMethod(
1029 ImplHelper.METHODNAME_WRITE_OBJECT,
1030 Modifier.PRIVATE,
1031 "void",
1032 new String[]{ "out" },
1033 new String[]{ ObjectOutputStream.class.getName() },
1034 new String[]{ IOException.class.getName() },
1035 ImplHelper.getWriteObjectImpl("out"),
1036 ImplHelper.COMMENT_ENHANCER_ADDED);
1037 }
1038
1039 private void writeOidClass(final String classname,
1040 final String oidClassName,
1041 final boolean enclosedOid)
1042 throws IOException
1043 {
1044 final int indent = (enclosedOid ? 1 : 0);
1045 writer.writeComments(indent, new String[]{
1046 "----------------------------------------------------------------------",
1047 "Key Class:",
1048 "----------------------------------------------------------------------"
1049 });
1050 writer.writeln();
1051
1052 writer.setInitialIndents(indent);
1053
1054 final String superOidClassName
1055 = NameHelper.normalizeClassName(meta.getSuperKeyClass(classname));
1056
1057 writer.writeClassHeader(
1058 (enclosedOid ? Modifier.PUBLIC | Modifier.STATIC : 0),
1059 oidClassName,
1060 superOidClassName,
1061 new String[]{ Serializable.class.getName() },
1062 ImplHelper.COMMENT_NOT_ENHANCER_ADDED);
1063
1064 final boolean isPCRoot
1065 = meta.isPersistenceCapableRootClass(classname);
1066
1067 final String[] pknames = meta.getKeyFields(classname);
1068 final String[] pktypes = meta.getFieldType(classname, pknames);
1069
1070
1071 for (int i = 0; i < pknames.length; i++) {
1072 writer.writeField(
1073 pknames[i],
1074 Modifier.PUBLIC,
1075 pktypes[i],
1076 null,
1077 null);
1078 }
1079
1080
1081 writer.writeConstructor(
1082 NameHelper.getClassName(oidClassName),
1083 Modifier.PUBLIC,
1084 null, null, null,
1085 ImplHelper.getDefaultConstructorImpl(),
1086 ImplHelper.COMMENT_NOT_ENHANCER_ADDED);
1087
1088
1089 writer.writeConstructor(
1090 NameHelper.getClassName(oidClassName),
1091 Modifier.PUBLIC,
1092 new String[]{ "str" },
1093 new String[]{ "String" },
1094 null,
1095 ImplHelper.getOidStringArgConstructorImpl(superOidClassName,
1096 "str"),
1097 ImplHelper.COMMENT_NOT_ENHANCER_ADDED);
1098
1099
1100 writer.writeMethod(
1101 "hashCode",
1102 Modifier.PUBLIC,
1103 "int",
1104 null,
1105 null,
1106 null,
1107 ImplHelper.getOidHashCodeImpl(pknames,
1108 pktypes,
1109 isPCRoot),
1110 ImplHelper.COMMENT_NOT_ENHANCER_ADDED);
1111
1112
1113 writer.writeMethod(
1114 "equals", Modifier.PUBLIC, "boolean",
1115 new String[]{ "pk" },
1116 new String[]{ Object.class.getName() },
1117 null,
1118 ImplHelper.getOidEqualsImpl(oidClassName,
1119 pknames,
1120 pktypes,
1121 "pk",
1122 isPCRoot),
1123 ImplHelper.COMMENT_NOT_ENHANCER_ADDED);
1124
1125 writer.writeClassEnd();
1126 writer.setInitialIndents(0);
1127 }
1128
1129
1130 static private long createJDOVersionUID(final String classname)
1131 {
1132 return classname.hashCode();
1133 }
1134
1135 static private String createMethodName(final String prefix,
1136 final String fieldname)
1137 {
1138 return (prefix + Character.toUpperCase(fieldname.charAt(0))
1139 + fieldname.substring(1));
1140 }
1141
1142 private void printMessage(String msg)
1143 {
1144 out.println(msg);
1145 }
1146
1147 private void printError(String msg,
1148 Throwable ex)
1149 {
1150 if (msg != null) {
1151 err.println(msg + (ex != null ? ": " + ex.getMessage() : ""));
1152 }
1153 if (ex != null) {
1154 ex.printStackTrace(err);
1155 }
1156 }
1157 }