View Javadoc

1   /*
2    * Copyright 2005 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at 
7    * 
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software 
11   * distributed under the License is distributed on an "AS IS" BASIS, 
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
13   * See the License for the specific language governing permissions and 
14   * limitations under the License.
15   */
16  
17  package org.apache.jdo.impl.enhancer.generator;
18  
19  import java.util.List;
20  import java.util.ArrayList;
21  import java.util.HashMap;
22  
23  
24  /***
25   *
26   */
27  final class ImplHelper
28      extends NameHelper
29  {
30      // string constants
31      static final String[] COMMENT_ENHANCER_ADDED
32      = null; //{ "added by enhancer" };
33      static final String[] COMMENT_NOT_ENHANCER_ADDED
34      = null; //{ "not added by enhancer" };
35  
36      static final String CLASSNAME_JDO_PERSISTENCE_CAPABLE
37      = "javax.jdo.spi.PersistenceCapable";
38      static final String CLASSNAME_JDO_PERSISTENCE_MANAGER
39      = "javax.jdo.PersistenceManager";
40      static final String CLASSNAME_JDO_IMPL_HELPER
41      = "javax.jdo.spi.JDOImplHelper";
42      static final String CLASSNAME_JDO_STATE_MANAGER
43      = "javax.jdo.spi.StateManager";
44      static final String CLASSNAME_JDO_PERMISSION
45      = "javax.jdo.spi.JDOPermission";
46      static final String CLASSNAME_JDO_USER_EXCEPTION
47      = "javax.jdo.JDOUserException";
48      //static final String CLASSNAME_JDO_FATAL_INTERNAL_EXCEPTION
49      //= "javax.jdo.JDOFatalInternalException";
50      static final String CLASSNAME_JDO_OBJECT_ID_FIELD_SUPPLIER
51      = CLASSNAME_JDO_PERSISTENCE_CAPABLE + "." + "ObjectIdFieldSupplier";
52      static final String CLASSNAME_JDO_OBJECT_ID_FIELD_CONSUMER
53      = CLASSNAME_JDO_PERSISTENCE_CAPABLE + "." + "ObjectIdFieldConsumer";
54  
55      static final String FIELDNAME_JDO_FLAGS
56      = "jdoFlags";
57      static final String FIELDNAME_JDO_STATE_MANAGER
58      = "jdoStateManager";
59      static final String FIELDNAME_JDO_INHERITED_FIELD_COUNT
60      = "jdoInheritedFieldCount";
61      static final String FIELDNAME_JDO_FIELD_NAMES
62      = "jdoFieldNames";
63      static final String FIELDNAME_JDO_FIELD_TYPES
64      = "jdoFieldTypes";
65      static final String FIELDNAME_JDO_FIELD_FLAGS
66      = "jdoFieldFlags";
67      static final String FIELDNAME_JDO_PC_SUPERCLASS
68      = "jdoPersistenceCapableSuperclass";
69      static final String FIELDNAME_SERIAL_VERSION_UID
70      = "serialVersionUID";
71  
72      static final String METHODNAME_WRITE_OBJECT
73      = "writeObject";
74  
75      static final String METHODNAME_JDO_GET_MANAGED_FIELD_COUNT
76      = "jdoGetManagedFieldCount";
77      static final String METHODNAME_JDO_NEW_INSTANCE
78      = "jdoNewInstance";
79      static final String METHODNAME_JDO_NEW_OID_INSTANCE
80      = "jdoNewObjectIdInstance";
81      static final String METHODNAME_JDO_REPLACE_STATE_MANAGER
82      = "jdoReplaceStateManager";
83      static final String METHODNAME_JDO_REPLACE_FLAGS
84      = "jdoReplaceFlags";
85      static final String METHODNAME_JDO_REPLACE_FIELD
86      = "jdoReplaceField";
87      static final String METHODNAME_JDO_REPLACE_FIELDS
88      = "jdoReplaceFields";
89      static final String METHODNAME_JDO_PROVIDE_FIELD
90      = "jdoProvideField";
91      static final String METHODNAME_JDO_PROVIDE_FIELDS
92      = "jdoProvideFields";
93      static final String METHODNAME_JDO_COPY_FIELDS
94      = "jdoCopyFields";
95      static final String METHODNAME_JDO_COPY_FIELD
96      = "jdoCopyField";
97      static final String METHODNAME_JDO_PRE_SERIALIZE
98      = "jdoPreSerialize";
99      static final String METHODNAME_JDO_GET_PERSISTENCE_MANAGER
100     = "jdoGetPersistenceManager";
101     static final String METHODNAME_JDO_MAKE_DIRTY
102     = "jdoMakeDirty";
103     static final String METHODNAME_JDO_GET_OBJECT_ID
104     = "jdoGetObjectId";
105     static final String METHODNAME_JDO_GET_TRANSACTIONAL_OBJECT_ID
106     = "jdoGetTransactionalObjectId";
107     static final String METHODNAME_JDO_GET_VERSION
108     = "jdoGetVersion";
109     static final String METHODNAME_JDO_IS_PERSISTENT
110     = "jdoIsPersistent";
111     static final String METHODNAME_JDO_IS_TRANSACTIONAL
112     = "jdoIsTransactional";
113     static final String METHODNAME_JDO_IS_NEW
114     = "jdoIsNew";
115     static final String METHODNAME_JDO_IS_DIRTY
116     = "jdoIsDirty";
117     static final String METHODNAME_JDO_IS_DELETED
118     = "jdoIsDeleted";
119     static final String METHODNAME_JDO_IS_DETACHED
120     = "jdoIsDetached";
121     static final String METHODNAME_JDO_COPY_KEY_FIELDS_TO_OID
122     = "jdoCopyKeyFieldsToObjectId";
123     static final String METHODNAME_JDO_COPY_KEY_FIELDS_FROM_OID
124     = "jdoCopyKeyFieldsFromObjectId";
125 
126     static private final HashMap typeNameConversion = new HashMap();
127     static
128     {
129         typeNameConversion.put(int.class.getName(), "Int");
130         typeNameConversion.put(long.class.getName(), "Long");
131         typeNameConversion.put(byte.class.getName(), "Byte");
132         typeNameConversion.put(char.class.getName(), "Char");
133         typeNameConversion.put(boolean.class.getName(), "Boolean");
134         typeNameConversion.put(short.class.getName(), "Short");
135         typeNameConversion.put(float.class.getName(), "Float");
136         typeNameConversion.put(double.class.getName(), "Double");
137         typeNameConversion.put("String", "String");
138     }
139 
140     static private String getConvertedTypeName(String fieldtype)
141     {
142         final String name = (String)typeNameConversion.get(fieldtype);
143         return (name != null ? name : "Object");
144     }
145 
146     static private String getMethodNameGetField(String fieldtype)
147     {
148         return "get" + getConvertedTypeName(fieldtype) + "Field";
149     }
150 
151     static private String getMethodNameSetField(String fieldtype)
152     {
153         return "set" + getConvertedTypeName(fieldtype) + "Field";
154     }
155 
156     static private String getMethodNameReplacingField(String fieldtype)
157     {
158         return "replacing" + getConvertedTypeName(fieldtype) + "Field";
159     }
160 
161     static private String getMethodNameProvidedField(String fieldtype)
162     {
163         return "provided" + getConvertedTypeName(fieldtype) + "Field";
164     }
165 
166     static private String getMethodNameFetchField(String fieldtype)
167     {
168         return "fetch" + getConvertedTypeName(fieldtype) + "Field";
169     }
170 
171     static private String getMethodNameStoreField(String fieldtype)
172     {
173         return "store" + getConvertedTypeName(fieldtype) + "Field";
174     }
175 
176     // ----------------------------------------------------------------------
177 
178     static String createJDOFieldAccessorName(String classname,
179                                              String fieldname)
180     {
181         return "jdoGet" + fieldname;
182     }
183     
184     static String createJDOFieldMutatorName(String classname,
185                                             String fieldname)
186     {
187         return "jdoSet" + fieldname;
188     }
189 
190     // Create initial values of fields.
191 
192     static String getJDOInheritedFieldCountInitValue(String superclassname)
193     {
194         return(superclassname == null  ?
195                "0"  :
196                (normalizeClassName(superclassname)
197                 + '.' + METHODNAME_JDO_GET_MANAGED_FIELD_COUNT + "()"));
198     }
199 
200     static String getJDOFieldNamesInitValue(String[] fieldnames)
201     {
202         String value = "new String[]{ ";
203         final int n = fieldnames.length;
204         for (int i = 0; i < n; i++) {
205             value += "\"" + fieldnames[i] + "\"";
206             if (i < n - 1) {
207                 value += ", ";
208             }
209         }
210         return value + " }";
211     }
212 
213     static String getJDOFieldTypesInitValue(String[] fieldtypes)
214     {
215         String value = "new Class[]{ ";
216         final int n = fieldtypes.length;
217         for (int i = 0; i < n; i++) {
218             value += normalizeClassName(fieldtypes[i]) + ".class";
219             if (i < n - 1) {
220                 value += ", ";
221             }
222         }
223         return value + " }";
224     }
225 
226     static String getJDOFieldFlagsInitValue(int[] fieldflags)
227     {
228         String value = "new byte[]{ ";
229         final int n = fieldflags.length;
230         for (int i = 0; i < n; i++) {
231             value += "0x" + Integer.toHexString(fieldflags[i]);
232             if (i < n - 1) {
233                 value += ", ";
234             }
235         }
236         return value + " }";
237     }
238 
239     static String getJDOPCSuperclassInitValue(String superclass)
240     {
241         return (superclass == null
242                 ? "null"
243                 : normalizeClassName(superclass) + ".class");
244     }
245 
246     static String getSerialVersionUIDInitValue(long uid)
247     {
248         return uid + "L";
249     }
250 
251     // Create bodies of methods.
252 
253     static List getJDOManagedFieldCountImpl(int fieldcount)
254     {
255         final List impl = new ArrayList(3);
256         impl.add(FIELDNAME_JDO_INHERITED_FIELD_COUNT
257                  + " + " + fieldcount + ';');
258         return impl;
259     }
260 
261     static List getStaticInitializerImpl(String classname,
262                                          String superPC,
263                                          String[] managedFieldNames,
264                                          String[] managedFieldTypes,
265                                          int[] managedFieldFlags)
266     {
267         classname = normalizeClassName(classname);
268         final List impl = new ArrayList(20);
269 
270         impl.add(ImplHelper.FIELDNAME_JDO_INHERITED_FIELD_COUNT
271                  + " = "+ getJDOInheritedFieldCountInitValue(superPC) + ";");
272         impl.add(ImplHelper.FIELDNAME_JDO_FIELD_NAMES
273                  + " = " + getJDOFieldNamesInitValue(managedFieldNames) + ";");
274         impl.add(ImplHelper.FIELDNAME_JDO_FIELD_TYPES
275                  + " = " + getJDOFieldTypesInitValue(managedFieldTypes) + ";");
276         impl.add(ImplHelper.FIELDNAME_JDO_FIELD_FLAGS
277                  + " = " + getJDOFieldFlagsInitValue(managedFieldFlags) + ";");
278         impl.add(ImplHelper.FIELDNAME_JDO_PC_SUPERCLASS
279                  + " = " + getJDOPCSuperclassInitValue(superPC) + ";");
280 
281         impl.add(CLASSNAME_JDO_IMPL_HELPER
282                  + ".registerClass(");
283         impl.add("    " + classname + ".class" + ", ");
284         impl.add("    " + FIELDNAME_JDO_FIELD_NAMES + ", ");
285         impl.add("    " + FIELDNAME_JDO_FIELD_TYPES + ", ");
286         impl.add("    " + FIELDNAME_JDO_FIELD_FLAGS + ", ");
287         impl.add("    " + FIELDNAME_JDO_PC_SUPERCLASS + ", ");
288         impl.add("    " + "new " + classname + "()");
289         impl.add(");");
290         return impl;
291     }
292 
293     static List getJDOGetManagedFieldCountImpl(boolean isRoot,
294                                                String superPC,
295                                                int fieldcount)
296     {
297         superPC = normalizeClassName(superPC);
298         final List impl = new ArrayList(5);
299         if (isRoot) {
300             impl.add("return " + fieldcount + ';');
301         }
302         else {
303             impl.add("return " + superPC + "." + 
304                      METHODNAME_JDO_GET_MANAGED_FIELD_COUNT +
305                      "() + " + fieldcount + ';');
306         }
307         return impl;
308     }
309     
310     static List getDefaultConstructorImpl()
311     {
312         final List impl = new ArrayList(5);
313         impl.add("super();");
314         return impl;
315     }
316 
317     static List getDummyConstructorImpl()
318     {
319         final List impl = new ArrayList(5);
320         impl.add("super();");
321         return impl;
322     }
323 
324     static List getOidStringArgConstructorImpl(String superoidclassname,
325                                                String str)
326     {
327         final List impl = new ArrayList(5);
328         if (superoidclassname != null) {
329             impl.add("super(" + str + ");");
330         }
331         //^olsen: todo
332         impl.add("// not implemented yet");
333         impl.add("throw new UnsupportedOperationException();");
334         return impl;
335     }
336 
337     static List getCloneImpl(String classname)
338     {
339         classname = normalizeClassName(classname);
340         final List impl = new ArrayList(5);
341         impl.add("final " + classname
342                  + " pc = ("  + classname + ")super.clone();");
343         impl.add("pc." + FIELDNAME_JDO_FLAGS + " = 0; // == READ_OK");
344         impl.add("pc." + FIELDNAME_JDO_STATE_MANAGER + " = null;");
345         impl.add("return pc;");
346         return impl;
347     }
348 
349     static List getJDONewInstanceImpl(String classname,
350                                       String statemanager) 
351     {
352         final List impl = new ArrayList(5);
353         classname = getClassName(classname);
354         impl.add("final " + classname
355                  + " pc = new " + classname + "();");        
356         impl.add("pc." + FIELDNAME_JDO_FLAGS + " = 1; // == LOAD_REQUIRED");
357         impl.add("pc." + FIELDNAME_JDO_STATE_MANAGER
358                  + " = " + statemanager + ';');
359         impl.add("return pc;");
360         return impl;
361     }
362 
363     static List getJDONewInstanceKeyImpl(String classname,
364                                          String statemanager,
365                                          String oid)
366     {
367         final List impl = new ArrayList(5);
368         classname = getClassName(classname);
369         impl.add("final " + classname
370                  + " pc = new " + classname + "();");        
371         impl.add("pc." + METHODNAME_JDO_COPY_KEY_FIELDS_FROM_OID
372                  + "(" + oid + ");");
373         impl.add("pc." + FIELDNAME_JDO_FLAGS + " = 1; // == LOAD_REQUIRED");
374         impl.add("pc." + FIELDNAME_JDO_STATE_MANAGER
375                  + " = " + statemanager + ';');
376         impl.add("return pc;");
377         return impl;
378     }
379 
380     static List getJDONewOidInstanceImpl(String oidclassname)
381     {
382         final List impl = new ArrayList(5);
383         if (oidclassname == null) {
384             impl.add("return null;");
385         } else {
386             impl.add("return new " + oidclassname + "();");
387         }
388         return impl;
389     }
390 
391     static List getJDONewOidInstanceImpl(String oidclassname,
392                                          String o)
393     {
394         final List impl = new ArrayList(5);
395         if (oidclassname == null) {
396             impl.add("return null;");
397         } else {
398             // TODO: support for single field identity
399             impl.add("return new " + oidclassname + "((String)" + o + ");");
400         }
401         return impl;
402     }
403 
404     static List getJDOCopyKeyFieldsToOid(String oidclassname,
405                                          String superoidclassname,
406                                          String oid,
407                                          String[] fieldnames)
408     {
409         final List impl = new ArrayList(5);
410         if (oidclassname == null) {
411             impl.add("return;");
412         } else {
413             impl.add("if (!(" + oid + " instanceof " + oidclassname + ")) {");
414             impl.add("    throw new IllegalArgumentException(\"arg1\");");
415             impl.add("}");
416             final String _oid = "_" + oid;
417             impl.add("final " + oidclassname
418                      + " " + _oid + " = (" + oidclassname + ")" + oid + ";");
419             if (superoidclassname != null) {
420                 impl.add("super." + METHODNAME_JDO_COPY_KEY_FIELDS_TO_OID
421                          + "(" + _oid + ");");
422             }
423             for (int i = 0; i < fieldnames.length; i++) {
424                 final String fname = fieldnames[i];
425                 impl.add(_oid + "." + fname + " = " + "this." + fname + ";");
426             }
427         }
428         return impl;
429     }
430 
431     static List getJDOCopyKeyFieldsFromOid(String oidclassname,
432                                            String superoidclassname,
433                                            String oid,
434                                            String[] fieldnames)
435     {
436         final List impl = new ArrayList(5);
437         if (oidclassname == null) {
438             impl.add("return;");
439         } else {
440             impl.add("if (!(" + oid + " instanceof " + oidclassname + ")) {");
441             impl.add("    throw new IllegalArgumentException(\"arg1\");");
442             impl.add("}");
443             final String _oid = "_" + oid;
444             impl.add("final " + oidclassname
445                      + " " + _oid + " = (" + oidclassname + ")" + oid + ";");
446             if (superoidclassname != null) {
447                 impl.add("super." + METHODNAME_JDO_COPY_KEY_FIELDS_FROM_OID
448                          + "(" + _oid + ");");
449             }
450             for (int i = 0; i < fieldnames.length; i++) {
451                 final String fname = fieldnames[i];
452                 impl.add("this." + fname + " = " + _oid + "." + fname + ";");
453             }
454         }
455         return impl;
456     }
457 
458     static List getJDOCopyKeyFieldsToOid(String oidclassname,
459                                          String superoidclassname,
460                                          String fm,
461                                          String oid,
462                                          String[] fieldnames,
463                                          String[] fieldtypes,
464                                          int[] fieldnumbers)
465     {
466         final List impl = new ArrayList(5);
467         if (oidclassname == null) {
468             impl.add("return;");
469         } else {
470             impl.add("if (" + fm + " == null) {");
471             impl.add("    throw new IllegalArgumentException(\"arg1\");");
472             impl.add("}");
473             impl.add("if (!(" + oid + " instanceof " + oidclassname + ")) {");
474             impl.add("    throw new IllegalArgumentException(\"arg2\");");
475             impl.add("}");
476             final String _oid = "_" + oid;
477             impl.add("final " + oidclassname
478                      + " " + _oid + " = (" + oidclassname + ")" + oid + ";");
479             if (superoidclassname != null) {
480                 impl.add("super." + METHODNAME_JDO_COPY_KEY_FIELDS_TO_OID
481                          + "(" + fm + ", " + _oid + ");");
482             }
483             for (int i = 0; i < fieldnames.length; i++) {
484                 impl.add(_oid + "." + fieldnames[i] + " = " + fm + "."
485                          + getMethodNameFetchField(fieldtypes[i])
486                          + "(" + FIELDNAME_JDO_INHERITED_FIELD_COUNT
487                          + " + " + fieldnumbers[i] + ");");
488             }
489         }
490         return impl;
491     }
492 
493     static List getJDOCopyKeyFieldsFromOid(String oidclassname,
494                                            String superoidclassname,
495                                            String fm,
496                                            String oid,
497                                            String[] fieldnames,
498                                            String[] fieldtypes,
499                                            int[] fieldnumbers)
500     {
501         final List impl = new ArrayList(5);
502         if (oidclassname == null) {
503             impl.add("return;");
504         } else {
505             impl.add("if (" + fm + " == null) {");
506             impl.add("    throw new IllegalArgumentException(\"arg1\");");
507             impl.add("}");
508             impl.add("if (!(" + oid + " instanceof " + oidclassname + ")) {");
509             impl.add("    throw new IllegalArgumentException(\"arg2\");");
510             impl.add("}");
511             final String _oid = "_" + oid;
512             impl.add("final " + oidclassname
513                      + " " + _oid + " = (" + oidclassname + ")" + oid + ";");
514             if (superoidclassname != null) {
515                 impl.add("super." + METHODNAME_JDO_COPY_KEY_FIELDS_FROM_OID
516                          + "(" + fm + ", " + _oid + ");");
517             }
518             for (int i = 0; i < fieldnames.length; i++) {
519                 impl.add(fm + "." + getMethodNameStoreField(fieldtypes[i])
520                          + "(" + FIELDNAME_JDO_INHERITED_FIELD_COUNT
521                          + " + " + fieldnumbers[i] + ", "
522                          + _oid + "." + fieldnames[i] + ");");
523             }
524         }
525         return impl;
526     }
527 
528     static List getJDOReplaceStateManagerImpl(String statemanager)
529     {
530         final List impl = new ArrayList(8);
531         impl.add("final " + CLASSNAME_JDO_STATE_MANAGER
532                  + " s = this." + FIELDNAME_JDO_STATE_MANAGER + ";");
533         impl.add("if (s != null) {");
534         impl.add("    this." + FIELDNAME_JDO_STATE_MANAGER
535                  + " = s.replacingStateManager(this, " + statemanager + ");");
536         impl.add("    return;");
537         impl.add("}");
538         impl.add(CLASSNAME_JDO_IMPL_HELPER 
539                  + ".checkAuthorizedStateManager(" + statemanager + ");");
540         impl.add("this." + FIELDNAME_JDO_STATE_MANAGER
541                  + " = " + statemanager + ';');
542         impl.add("this." + FIELDNAME_JDO_FLAGS
543                  + " = LOAD_REQUIRED;");
544         return impl;
545     }
546     
547     static List getJDOReplaceFlagsImpl()
548     {
549         final List impl = new ArrayList(5);
550         impl.add("final " + CLASSNAME_JDO_STATE_MANAGER
551                  + " sm = this." + FIELDNAME_JDO_STATE_MANAGER + ";");
552         impl.add("if (sm != null) {");
553         impl.add("    this." + FIELDNAME_JDO_FLAGS
554                  + " = sm.replacingFlags(this);");
555         impl.add("}");
556         return impl;
557     }
558 
559     static List getJDOFieldDirectReadImpl(String fieldname,
560                                           String fieldtype,
561                                           int    fieldnumber,
562                                           String instancename)
563     {
564         fieldtype = normalizeClassName(fieldtype);
565         final List impl = new ArrayList(20);
566         impl.add("// augmentation: grant direct read access");
567         impl.add("return " + instancename + '.' + fieldname + ';');
568         return impl;
569     }
570     
571     static private void addFieldMediateReadImpl(List impl,
572                                                 String fieldname,
573                                                 String fieldtype,
574                                                 int    fieldnumber,
575                                                 String instancename)
576     {
577         impl.add("final " + CLASSNAME_JDO_STATE_MANAGER + " sm = "
578                  + instancename + '.' + FIELDNAME_JDO_STATE_MANAGER + ";");
579         impl.add("if (sm == null) {");
580         impl.add("    return " + instancename + '.' + fieldname + ';');
581         impl.add("}");
582         impl.add("if (sm.isLoaded(" + instancename + ", "
583                  + FIELDNAME_JDO_INHERITED_FIELD_COUNT
584                  + " + " + fieldnumber + ")) {");
585         impl.add("    return " + instancename + '.' + fieldname + ';');
586         impl.add("}");
587         impl.add("return (" + fieldtype + ")"
588                  + "sm." + getMethodNameGetField(fieldtype)
589                  + "(" + instancename + ", "
590                  + FIELDNAME_JDO_INHERITED_FIELD_COUNT
591                  + " + " + fieldnumber + ", "
592                  + instancename + '.' + fieldname + ");");
593     }
594 
595     static List getJDOFieldMediateReadImpl(String fieldname,
596                                            String fieldtype,
597                                            int    fieldnumber,
598                                            String instancename)
599     {
600         fieldtype = normalizeClassName(fieldtype);
601         final List impl = new ArrayList(20);
602         impl.add("// augmentation: mediate read access");
603         addFieldMediateReadImpl(impl, fieldname, fieldtype,
604                                 fieldnumber, instancename);
605         return impl;
606     }
607 
608     static List getJDOFieldCheckReadImpl(String fieldname,
609                                          String fieldtype,
610                                          int    fieldnumber,
611                                          String instancename)
612     {
613         fieldtype = normalizeClassName(fieldtype);
614         final List impl = new ArrayList(20);
615         impl.add("// augmentation: check read access");
616         impl.add("if (" + instancename + '.' + FIELDNAME_JDO_FLAGS
617                  + " <= 0) {");
618         impl.add("    return " + instancename + '.' + fieldname + ';');
619         impl.add("}");
620         addFieldMediateReadImpl(impl, fieldname, fieldtype,
621                                 fieldnumber, instancename);
622         return impl;
623     }
624 
625     static List getJDOFieldDirectWriteImpl(String fieldname,
626                                            String fieldtype,
627                                            int    fieldnumber,
628                                            String instancename,
629                                            String newvalue)
630     {
631         fieldtype = normalizeClassName(fieldtype);
632         final List impl = new ArrayList(20);
633         impl.add("// augmentation: grant direct write access");
634         impl.add(instancename + '.' + fieldname
635                  + " = " + newvalue + ';');
636         return impl;
637     }
638 
639     static private void addFieldMediateWriteImpl(List impl,
640                                                  String fieldname,
641                                                  String fieldtype,
642                                                  int    fieldnumber,
643                                                  String instancename,
644                                                  String newvalue)
645     {
646         impl.add("final " + CLASSNAME_JDO_STATE_MANAGER + " sm = "
647                  + instancename + '.' + FIELDNAME_JDO_STATE_MANAGER + ";");
648         impl.add("if (sm == null) {");
649         impl.add("    " + instancename + '.' + fieldname
650                  + " = " + newvalue + ';');
651         impl.add("    return;");
652         impl.add("}");
653         impl.add("sm."
654                  + getMethodNameSetField(fieldtype)
655                  + "(" + instancename + ", "
656                  + FIELDNAME_JDO_INHERITED_FIELD_COUNT
657                  + " + " + fieldnumber + ", "
658                  + instancename
659                  + '.' + fieldname + ", "
660                  + newvalue + ");");
661     }
662 
663     static List getJDOFieldMediateWriteImpl(String fieldname,
664                                             String fieldtype,
665                                             int    fieldnumber,
666                                             String instancename,
667                                             String newvalue)
668     {
669         fieldtype = normalizeClassName(fieldtype);
670         final List impl = new ArrayList(20);
671         impl.add("// augmentation: mediate write access");
672         addFieldMediateWriteImpl(impl, fieldname, fieldtype,
673                                  fieldnumber, instancename, newvalue);
674         return impl;
675     }
676 
677     static List getJDOFieldCheckWriteImpl(String fieldname,
678                                           String fieldtype,
679                                           int    fieldnumber,
680                                           String instancename,
681                                           String newvalue)
682     {
683         fieldtype = normalizeClassName(fieldtype);
684         final List impl = new ArrayList(20);
685         impl.add("// augmentation: check write access");
686         impl.add("if (" + instancename
687                  + '.' + FIELDNAME_JDO_FLAGS + " == 0) {");
688         impl.add("    " + instancename + '.' + fieldname
689                  + " = " + newvalue + ';');
690         impl.add("    return;");
691         impl.add("}");
692         addFieldMediateWriteImpl(impl, fieldname, fieldtype,
693                                  fieldnumber, instancename, newvalue);
694         return impl;
695     }
696 
697     static List getJDOReplaceFieldImpl(String   fieldnumber,
698                                        boolean  isRoot,
699                                        String[] fieldnames,
700                                        String[] fieldtypes)
701     {
702         final List impl = new ArrayList(20);
703         impl.add("final " + CLASSNAME_JDO_STATE_MANAGER + " sm = this."
704                  + FIELDNAME_JDO_STATE_MANAGER + ";");
705         impl.add("switch (" + fieldnumber
706                  + " - " + FIELDNAME_JDO_INHERITED_FIELD_COUNT + ") {");
707         for (int i = 0; i < fieldnames.length; i++) {
708             String fieldtype = normalizeClassName(fieldtypes[i]);
709             impl.add("case " + i + ':');
710             impl.add("    if (sm == null) {");
711             impl.add("        throw new IllegalStateException(\"arg0."
712                      + FIELDNAME_JDO_STATE_MANAGER + "\");");
713             impl.add("    }");
714             impl.add("    this." + fieldnames[i]
715                      + " = (" + fieldtype + ")sm."
716                      + getMethodNameReplacingField(fieldtype)
717                      + "(this, " + fieldnumber + ");");
718             impl.add("    return;");
719         }
720         impl.add("default:");
721         if (isRoot) {
722             impl.add("    throw new IllegalArgumentException(\"arg1\");");
723         } else {
724             impl.add("    super." + METHODNAME_JDO_REPLACE_FIELD
725                      + "(" + fieldnumber + ");");
726         }
727         impl.add("}");
728         return impl;
729     }
730 
731     static List getJDOProvideFieldImpl(String   fieldnumber,
732                                        boolean  isRoot,
733                                        String[] fieldnames,
734                                        String[] fieldtypes)
735     {
736         final List impl = new ArrayList(20);
737         impl.add("final " + CLASSNAME_JDO_STATE_MANAGER + " sm = this."
738                  + FIELDNAME_JDO_STATE_MANAGER + ";");
739         impl.add("switch (" + fieldnumber
740                  + " - " + FIELDNAME_JDO_INHERITED_FIELD_COUNT + ") {");
741         for (int i = 0; i < fieldnames.length; i++) {
742             String fieldtype = normalizeClassName(fieldtypes[i]);
743             impl.add("case " + i + ':');
744             impl.add("    if (sm == null) {");
745             impl.add("        throw new IllegalStateException(\"arg0."
746                      + FIELDNAME_JDO_STATE_MANAGER + "\");");
747             impl.add("    }");
748             impl.add("    sm." + getMethodNameProvidedField(fieldtype)
749                      + "(this, " + fieldnumber + ", "
750                      + "this." + fieldnames[i] + ");");
751             impl.add("    return;");
752         }
753         impl.add("default:");
754         if (isRoot) {
755             impl.add("    throw new IllegalArgumentException(\"arg1\");");
756         } else {
757             impl.add("    super." + METHODNAME_JDO_PROVIDE_FIELD
758                      + "(" + fieldnumber + ");");
759         }
760         impl.add("}");
761         return impl;
762     }
763 
764     static List getJDOCopyFieldsImpl(String   classname,
765                                      String   copy,
766                                      String   fieldnumbers)
767     {
768         classname = normalizeClassName(classname);
769         final List impl = new ArrayList(50);
770         impl.add("if (this." + FIELDNAME_JDO_STATE_MANAGER + " == null) {");
771         impl.add("    throw new IllegalStateException(\"arg0."
772                  + FIELDNAME_JDO_STATE_MANAGER + "\");");
773         impl.add("}");
774         impl.add("if (!(" + copy + " instanceof " + classname + ")) {");
775         impl.add("    throw new IllegalArgumentException(\"arg1\");");
776         impl.add("}");
777         impl.add("if (" + fieldnumbers + " == null) {");
778         impl.add("    throw new IllegalArgumentException(\"arg2\");");
779         impl.add("}");
780         impl.add("final " + classname
781                  + " other = (" + classname + ")" + copy + ';');
782         impl.add("if (other." + FIELDNAME_JDO_STATE_MANAGER
783                  + " != this." + FIELDNAME_JDO_STATE_MANAGER + ") {");
784         impl.add("    throw new IllegalArgumentException(\""
785                  + "arg1." + FIELDNAME_JDO_STATE_MANAGER + "\");");
786         impl.add("}");
787         impl.add("final int n = " + fieldnumbers + ".length;");
788         impl.add("for (int i = 0; i < n; i++) {");
789         impl.add("    this." + METHODNAME_JDO_COPY_FIELD
790                  + "(other, " + fieldnumbers + "[i]);");
791         impl.add("}");
792         return impl;
793     }
794 
795     static List getJDOCopyFieldImpl(String   classname,
796                                     String   copy,
797                                     String   fieldnumber,
798                                     String[] fieldnames,
799                                     boolean  isRoot)
800     {
801         classname = normalizeClassName(classname);
802         final List impl = new ArrayList(50);
803         impl.add("switch (" + fieldnumber
804                  + " - " + FIELDNAME_JDO_INHERITED_FIELD_COUNT + ") {");
805         for (int i = 0; i < fieldnames.length; i++) {
806             impl.add("case " + i + ':');
807             impl.add("    if (" + copy + " == null) {");
808             impl.add("        throw new IllegalArgumentException(\"arg1\");");
809             impl.add("    }");
810             impl.add("    this." + fieldnames[i]
811                      + " = " + copy + "." + fieldnames[i] + ';');
812             impl.add("    return;");
813         }
814         impl.add("default:");
815         if (isRoot) {
816             impl.add("    throw new IllegalArgumentException(\"arg2\");");
817         } else {
818             impl.add("    super." + METHODNAME_JDO_COPY_FIELD
819                      + "(" + copy + ", " + fieldnumber + ");");
820         }
821         impl.add("}");
822         return impl;
823     }
824 
825     static List getWriteObjectImpl(String out)
826     {
827         final List impl = new ArrayList(5);
828         impl.add(METHODNAME_JDO_PRE_SERIALIZE + "();");
829         impl.add(out + ".defaultWriteObject();");
830 
831         return impl;
832     }
833 
834     static List getJDOStateManagerVoidDelegationImpl(String delegation)
835     {
836         final List impl = new ArrayList(5);
837         impl.add("final " + CLASSNAME_JDO_STATE_MANAGER
838                  + " sm = this." + FIELDNAME_JDO_STATE_MANAGER + ";");
839         impl.add("if (sm != null) {");
840         impl.add("    sm." + delegation + ';');
841         impl.add("}");
842         return impl;
843 
844     }
845 
846     static List getJDOStateManagerObjectDelegationImpl(String delegation)
847     {
848         final List impl = new ArrayList(5);
849         impl.add("final " + CLASSNAME_JDO_STATE_MANAGER
850                  + " sm = this." + FIELDNAME_JDO_STATE_MANAGER + ";");
851         impl.add("if (sm != null) {");
852         impl.add("    return sm." + delegation + ';');
853         impl.add("}");
854         impl.add("return null;");
855         return impl;
856     }
857 
858     static List getJDOStateManagerBooleanDelegationImpl(String delegation)
859     {
860         final List impl = new ArrayList(5);
861         impl.add("final " + CLASSNAME_JDO_STATE_MANAGER
862                  + " sm = this." + FIELDNAME_JDO_STATE_MANAGER + ";");
863         impl.add("if (sm != null) {");
864         impl.add("    return sm." + delegation + ';');
865         impl.add("}");
866         impl.add("return false;");
867         return impl;
868     }
869 
870     static List getJDOFieldIterationImpl(String fieldnumbers,
871                                          String method)
872     {
873         final List impl = new ArrayList(10);
874         impl.add("if (" + fieldnumbers + " == null) {");
875         impl.add("    throw new IllegalArgumentException(\"arg1\");");
876         impl.add("}");
877         impl.add("final int n = " + fieldnumbers + ".length;");
878         impl.add("for (int i = 0; i < n; i++) {");
879         impl.add("    this." + method + "(" + fieldnumbers + "[i]);");
880         impl.add("}");
881         return impl;
882     }
883 
884     static List getOidHashCodeImpl(String[] pknames,
885                                    String[] pktypes,
886                                    boolean  isRoot)
887     {
888         final List impl = new ArrayList(3);
889         if (isRoot) {
890             impl.add("int hash = 0;");
891         } else {
892             impl.add("int hash = super.hashCode();");
893         }
894         for (int i = 0; i < pknames.length; i++) {
895             if (isPrimitiveClass(pktypes[i])) {
896                 if (pktypes[i].equals("boolean")) {
897                     impl.add("hash += (" + pknames[i] + " ? 1 : 0);");
898                 } else {
899                     impl.add("hash += (int)" + pknames[i] + ';');
900                 }
901             } else {
902                 impl.add("hash += (this." + pknames[i]
903                          + " != null ? this." + pknames[i]
904                          + ".hashCode() : 0);");
905             }
906         }
907         impl.add("return hash;");
908         return impl;
909     }
910 
911     static List getOidEqualsImpl(String   oidclassname,
912                                  String[] pknames,
913                                  String[] pktypes,
914                                  String   pk,
915                                  boolean  isRoot)
916     {
917         final List impl = new ArrayList(3);
918         if (isRoot) {
919             impl.add("if (" + pk + " == null || !this.getClass().equals("
920                      + pk + ".getClass())) {");
921         } else {
922             impl.add("if (!super.equals(" + pk + ")) {");
923         }
924         impl.add("    return false;");
925         impl.add("}");
926         oidclassname = getClassName(oidclassname);
927         impl.add(oidclassname + " oid = (" + oidclassname + ")" + pk + ';');
928         for (int i = 0; i < pknames.length; i++) {
929             if (isPrimitiveClass(pktypes[i])) {
930                 impl.add("if (this." + pknames[i] + " != oid."
931                          + pknames[i] + ") return false;");
932             } else {
933                 impl.add("if (this." + pknames[i] + " != oid."
934                          + pknames[i] + " && (this." + pknames[i]
935                          + " == null || " + "!this." + pknames[i]
936                          + ".equals(oid." + pknames[i]
937                          + "))) return false;");
938             }
939         }
940         impl.add("return true;");
941         return impl;
942     }
943 
944     static List getNotYetImplemented(String methodName)
945     {
946         final List impl = new ArrayList(5);
947         String msg = "Method " + methodName + " not yet implemented";
948         impl.add("throw new UnsupportedOperationException(\"" + msg + "\");");
949         return impl;
950     }
951 
952     static private boolean isPrimitiveClass(String classname)
953     {
954         return (classname.equals("int")
955                 || classname.equals("long")
956                 || classname.equals("short")
957                 || classname.equals("byte")
958                 || classname.equals("boolean")
959                 || classname.equals("char")
960                 || classname.equals("double")
961                 || classname.equals("float"));
962     }
963 }