View Javadoc

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