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