Wiki source code of EOF-Using EOF-EOGenerator

Last modified by Pascal Robert on 2012/01/21 22:03

Hide last authors
Pascal Robert 30.1 1 {{warning}}
2 This is deprecated information!
3 {{/warning}}
Quinton Dolan 14.1 4
Pascal Robert 31.1 5 |=(((
6 Contents
7 )))
8 |(((
Pascal Robert 32.1 9 {{toc minLevel="2" style="disc"/}}
Pascal Robert 31.1 10 )))
Quinton Dolan 14.1 11
Pascal Robert 30.1 12 == Overview ==
David Avendasora 10.1 13
Pascal Robert 31.1 14 If you've ever used EOModeler's Java source code generator, you know how much of a pain it can be when you make changes to your model objects and have to merge changes in later. One solution for this is to use [[EOGenerator>>url:http://www.rubicode.com/Software/EOGenerator/||shape="rect"]], an application developed by Rubicode Software, which uses the Generation Gap pattern to create your Java files from your EOModels. EOGenerator produces TWO java files for each Entity rather than one. Take the example of a Person entity. The first java file is _Person.java, which contains all of the autogenerated methods. The second java file is Person.java, and Person extends _Person. The second file is where you place all of your customizations. Any time your model changes, only your _Xxx.java files are updated, and your customizations are left untouched. Additionally, EOGenerator allows for the creation of extensive custom templates for your files, which provides the ability to place convenience methods in your _Xxx.java files.
David LeBer 18.1 15
Pascal Robert 30.1 16 {{warning}}
Pascal Robert 31.1 17 EOGenerator doesn't work on Mac OS X 10.5. You have to use [[JavaEOGenerator>>url:http://developer.apple.com/samplecode/JavaEOGenerator/||shape="rect"]] or [[Velocity EOGenerator>>doc:WOL.Velocity EOGenerator (Veogen)]].
Pascal Robert 30.1 18 {{/warning}}
19
20 == Advantages ==
21
David Avendasora 10.1 22 There are several advantages to using EOGenerator over EOModeler's default Java file generation and merging with FileMerge.
23
Pascal Robert 31.1 24 * EOGenerator uses the Generation Gap pattern, which provides a much cleaner separation of autogenerated vs customized code with no need to deal with merging at all. There are border cases with FileMerge that can cause you to deal with annoying conflicts.
25 * EOGenerator uses the MiscMerge language for its templates. This allows you to extend the core templates with extensive customizations (see the EOGenerator Mods section below), better supporting your own custom development process and workflow.
David Avendasora 10.1 26 * As David LaBer put it, "all the cool kids use it - and we all know looking cool is the **most** important criteria".
27
Pascal Robert 30.1 28 == How To Use It ==
David Avendasora 10.1 29
Pascal Robert 31.1 30 Kieran Kelleher has writtten an [[Introduction to EOGenerator>>url:http://homepage.mac.com/kelleherk/iblog/C1837526061/E1908382110/index.html||shape="rect"]] on his blog.
David Avendasora 10.1 31
Pascal Robert 31.1 32 It's actually very simple to use. The quick start is:
David Avendasora 10.1 33
34 * Download and untar EOGenerator from the Rubicode site
35 * Run the following command:
36
37 {{panel}}
Pascal Robert 31.1 38 eogenerator -model /path/to/model/YourModel.eomodeld -destination /path/to/source/folder
39 -subclassDestination /path/to/source/folder -templatedir /path/to/EOGenerator/templates -java -packagedirs
David Avendasora 10.1 40 {{/panel}}
41
Pascal Robert 31.1 42 Voila. EOGenerator will spit out your Java files for you. Let's break down the commands you can pass in:
David Avendasora 10.1 43
Pascal Robert 31.1 44 * -define-EOGenericRecord <class>, allows you to specify the _Person class's superclass. For instance, if you use Project Wonder, you would specify -define-EOGenericRecord er.extensions.ERXGenericRecord
45 * -destination <path>, the folder that _Person.java-style java files will be produced in (the non-editable files)
46 * -java, produce java files
47 * -javaTemplate <filename>, the name of the Java template to use inside of the template dir (_Person)
48 * -model <path>, Passes in the path of a .eomodeld you would like to generate Java files for. You can actually include multiple -model commands on the commandline
49 * -packagedirs, produce package directory for any package statements defined in your Java files (not necessary if you don't specify package names on your entities. By the way, you should specify packages on your entities )
50 * -refmodel <path>, Passes in the path of an .eomodeld that is required for generating Java files, but that won't actually have Java files generated for it. For instance, you should -refmodel any prototypes, or any models in other frameworks that you depend on
51 * -subclassDestination <path>, the folder that Person.java-style java files will be produced in (the editable files)
52 * -subclassJavaTemplate <filename>, the name of the Java subclass template to use inside of the template dir (Person)
53 * -templatedir <path>, the path to the folder that contains EOGenerator templates
54 * -verbose, turn on verbose output
David Avendasora 10.1 55
Pascal Robert 30.1 56 == Custom EOGenerator Mods ==
David Avendasora 10.1 57
Pascal Robert 30.1 58 === Zak Burke ===
David Avendasora 10.1 59
Pascal Robert 31.1 60 Allow setting nulls on a to-one relationship (and turn it into a remove). Note, this is also included in Jonathan Rentzsch's templates.
David Avendasora 10.1 61
Quinton Dolan 14.1 62 {{code}}
David Avendasora 10.1 63
Pascal Robert 30.1 64 public void save<$ToOneRelationship.name.initialCapitalString$>(<$ToOneRelationship.destinationEntity.referenceJavaClassName$> value)
David Avendasora 10.1 65 {
66 if (value == null)
67 {
68 <$ToOneRelationship.destinationEntity.referenceJavaClassName$> object = <$ToOneRelationship.name$>();
69 if (object != null)
70 removeObjectFromBothSidesOfRelationshipWithKey(object, "<$ToOneRelationship.name$>");
71 }
72 else
73 {
74 addObjectToBothSidesOfRelationshipWithKey(value, "<$ToOneRelationship.name$>");
75 }
76 }
77
Quinton Dolan 14.1 78 {{/code}}
David Avendasora 10.1 79
Pascal Robert 30.1 80 === Chuck Hill ===
David Avendasora 10.1 81
82 Return the list of changes between the current EO and the last committed version of the EO:
83
Quinton Dolan 14.1 84 {{code}}
David Avendasora 10.1 85
Pascal Robert 30.1 86 public NSDictionary changedProperties() {
David Avendasora 10.1 87 NSDictionary commitedValues = editingContext().committedSnapshotForObject(this);
88 return changesFromSnapshot(commitedValues);
89 }
90
Quinton Dolan 14.1 91 {{/code}}
David Avendasora 10.1 92
Pascal Robert 30.1 93 === Jonathan Rentzsch ===
David Avendasora 10.1 94
95 Jonathan Rentzsch has provided his base EOGenerator templates, which are a must-have:
96
Pascal Robert 31.1 97 [[http:~~/~~/rentzsch.com/share/eogenerator52templates.zip>>url:http://rentzsch.com/share/eogenerator52templates.zip||shape="rect"]]
David Avendasora 10.1 98
Pascal Robert 30.1 99 === Markus Ruggiero ===
David Avendasora 10.1 100
101 Constants for all attributes and relationships. This allows compile time error checking in situations like
Pascal Robert 31.1 102 addObjecttoBothSidesOfRelationshipWithKey(myObject, Person.TO_MANY_Children)
David Avendasora 10.1 103
Quinton Dolan 14.1 104 {{code}}
David Avendasora 10.1 105
Pascal Robert 30.1 106 <$foreach attribute classAttributes.@reversedArray do$>
David Avendasora 10.1 107 public static final String ATTRIBUTE_<$attribute.name$> = "<$attribute.name$>";<$endforeach do$>
108
109 <$foreach ToOneRelationship classToOneRelationships.@reversedArray do$>
110 public static final String TO_ONE_<$ToOneRelationship.name$> = "<$ToOneRelationship.name$>";<$endforeach do$>
111
112 <$foreach ToManyRelationship classToManyRelationships.@reversedArray do$>
113 public static final String TO_MANY_<$ToManyRelationship.name$> = "<$ToManyRelationship.name$>";<$endforeach do$>
114
Quinton Dolan 14.1 115 {{/code}}
David Avendasora 10.1 116
117 We also make heavy use of the user info dictionary on entity and attribute level. Allows to generate customized methods and what not. One example is booleans that are stored in the DB as strings with values "true" and "false".
118
Quinton Dolan 14.1 119 {{code}}
David Avendasora 10.1 120
Pascal Robert 30.1 121 <$if attribute.userInfo.usage h1. booleanFlag $> // boolean accessors
David Avendasora 10.1 122 public void <$attribute.userInfo.setterName$>(boolean newBoolean) {
123 set<$attribute.name.initialCapitalString$>(newBoolean ? "true" : "false");
124 }
Pascal Robert 30.1 125
David Avendasora 10.1 126 public boolean <$attribute.userInfo.getterName$>() {
127 return "true".equals(<$attribute.name$>()) ? true : false;
128 }
Pascal Robert 30.1 129
David Avendasora 10.1 130 // validation
131 public String validate<$attribute.name.initialCapitalString$>(String newValue) {
132 if ( newValue null ) {
133 return "false";
134 } else if ( !newValue.equals("true") && !newValue.equals("false") ) {
135 String errorMessage = MessageHandler.format("INVALID_BOOLEAN_FLAG <$classNameWithoutPackage$>.<$attribute.name$>", null);
136 throw new NSValidation.ValidationException(errorMessage);
137 }
138 return newValue;
139 }
140 <$endif$>
141
Quinton Dolan 14.1 142 {{/code}}
David Avendasora 10.1 143
Pascal Robert 30.1 144 === Mike Schrag ===
David Avendasora 10.1 145
Pascal Robert 31.1 146 Add a constant that represents the name of the entity so that you can refer to Person.ENTITY_NAME in fetches rather than the String (allows refactoring support in Eclipse):
David Avendasora 10.1 147
Quinton Dolan 14.1 148 {{code}}
David Avendasora 10.1 149
Pascal Robert 30.1 150 public static final String ENTITY_NAME = "<$name$>";
David Avendasora 10.1 151
Quinton Dolan 14.1 152 {{/code}}
David Avendasora 10.1 153
154 Add a static factory method to your EO's ( Person createPerson(...) ) that shows you what required attributes and relationships are configured for you entity (attempts to provide a replacement "constructor" since EO constructors are empty):
155
Pascal Robert 30.1 156 {{code}}
David Avendasora 10.1 157
Quinton Dolan 28.1 158 public static <$classNameWithoutPackage$> create<$classNameWithoutPackage$>(EOEditingContext _editingContext<$foreach Attribute classAttributes.@sortedNameArray do$><$if !Attribute.allowsNull$>, <$Attribute.javaValueClassName$> _<$Attribute.name$><$endif$><$endforeach do$><$foreach ToOneRelationship classToOneRelationships.@sortedNameArray do$><$if ToOneRelationship.isMandatory$>, <$ToOneRelationship.destinationEntity.referenceJavaClassName$> _<$ToOneRelationship.name$><$endif$><$endforeach do$>) {
159 <$classNameWithoutPackage$> eoObject = (<$classNameWithoutPackage$>)EOUtilities.createAndInsertInstance(_editingContext, <$GEN_PREFIX$><$classNameWithoutPackage$>.ENTITY_NAME);<$foreach Attribute classAttributes.@sortedNameArray do$><$if !Attribute.allowsNull$>
160 eoObject.set<$Attribute.name.initialCapitalString$>(_<$Attribute.name$>);<$endif$><$endforeach do$><$foreach ToOneRelationship classToOneRelationships.@sortedNameArray do$><$if ToOneRelationship.isMandatory$>
161 eoObject.set<$ToOneRelationship.name.initialCapitalString$>Relationship(_<$ToOneRelationship.name$>);<$endif$><$endforeach do$>
162 return eoObject;
163 }
David Avendasora 10.1 164
Quinton Dolan 14.1 165 {{/code}}
David Avendasora 10.1 166
Pascal Robert 31.1 167 Here's a little bitty fancier (read: nastier) version that also handles superclass mandatory attributes and fields (one level). It skips any attribute that is referenced in the restricting qualifier of your subclass (since you are probably going to set that in your awakeFromInsertion):
David Avendasora 10.1 168
Pascal Robert 30.1 169 {{code}}
David Avendasora 10.1 170
Quinton Dolan 28.1 171 public static <$classNameWithoutPackage$> create<$classNameWithoutPackage$>(EOEditingContext editingContext<$foreach Attribute classAttributes.@sortedNameArray do$><$if !Attribute.allowsNull$>, <$Attribute.javaValueClassName$> <$Attribute.name$><$endif$><$endforeach do$><$foreach Attribute parentEntity.classAttributes.@sortedNameArray do$><$if !Attribute.allowsNull$><$set RestrictingQualifierKey = false$><$foreach QualifierKey restrictingQualifier.allQualifierKeys do$><$if Attribute.name = QualifierKey$><$set RestrictingQualifierKey = true$><$endif$><$endforeach do$><$if RestrictingQualifierKey = false$>, <$Attribute.javaValueClassName$> <$Attribute.name$><$endif$><$endif$><$endforeach do$><$foreach ToOneRelationship classToOneRelationships.@sortedNameArray do$><$if ToOneRelationship.isMandatory$>, <$ToOneRelationship.destinationEntity.referenceJavaClassName$> <$ToOneRelationship.name$><$endif$><$endforeach do$><$foreach ToOneRelationship parentEntity.classToOneRelationships.@sortedNameArray do$><$if ToOneRelationship.isMandatory$>, <$ToOneRelationship.destinationEntity.referenceJavaClassName$> <$ToOneRelationship.name$><$endif$><$endforeach do$>) {
172 <$classNameWithoutPackage$> eoObject = (<$classNameWithoutPackage$>)EOUtilities.createAndInsertInstance(editingContext, <$GEN_PREFIX$><$classNameWithoutPackage$>.ENTITY_NAME);<$foreach Attribute classAttributes.@sortedNameArray do$><$if !Attribute.allowsNull$>
173 eoObject.set<$Attribute.name.initialCapitalString$>(<$Attribute.name$>);<$endif$><$endforeach do$><$foreach ToOneRelationship classToOneRelationships.@sortedNameArray do$><$if ToOneRelationship.isMandatory$>
174 eoObject.set<$ToOneRelationship.name.initialCapitalString$>Relationship(<$ToOneRelationship.name$>);<$endif$><$endforeach do$><$foreach Attribute parentEntity.classAttributes.@sortedNameArray do$><$if !Attribute.allowsNull$><$set RestrictingQualifierKey = false$><$foreach QualifierKey restrictingQualifier.allQualifierKeys do$><$if Attribute.name = QualifierKey$><$set RestrictingQualifierKey = true$><$endif$><$endforeach do$><$if RestrictingQualifierKey = false$>
175 eoObject.set<$Attribute.name.initialCapitalString$>(<$Attribute.name$>);<$endif$><$endif$><$endforeach do$><$foreach ToOneRelationship parentEntity.classToOneRelationships.@sortedNameArray do$><$if ToOneRelationship.isMandatory$>
176 eoObject.set<$ToOneRelationship.name.initialCapitalString$>Relationship(<$ToOneRelationship.name$>);<$endif$><$endforeach do$>
Quinton Dolan 14.1 177 return eoObject;
178 }
David Avendasora 10.1 179
Quinton Dolan 14.1 180 {{/code}}
David Avendasora 10.1 181
Pascal Robert 31.1 182 Add a bunch of convience fetch methods (fetchAllPersons, fetchRequiredPerson, and other variants). It's not smart about pluralization, so it's just going to put an "s" on the end of the entity name:
David Avendasora 10.1 183
Quinton Dolan 14.1 184 {{code}}
Pascal Robert 30.1 185 public static NSArray fetchAll<$classNameWithoutPackage$>s(EOEditingContext _editingContext) {
David Avendasora 10.1 186 return <$GEN_PREFIX$><$classNameWithoutPackage$>.fetchAll<$classNameWithoutPackage$>s(_editingContext, null);
187 }
Pascal Robert 31.1 188 {{/code}}
David Avendasora 10.1 189
Pascal Robert 30.1 190 {{code}}
191 public static NSArray fetchAll<$classNameWithoutPackage$>s(EOEditingContext _editingContext, NSArray _sortOrderings) {
David Avendasora 10.1 192 return <$GEN_PREFIX$><$classNameWithoutPackage$>.fetch<$classNameWithoutPackage$>s(_editingContext, null, _sortOrderings);
193 }
Pascal Robert 31.1 194 {{/code}}
David Avendasora 10.1 195
Pascal Robert 30.1 196 {{code}}
197 public static NSArray fetch<$classNameWithoutPackage$>s(EOEditingContext _editingContext, EOQualifier _qualifier, NSArray _sortOrderings) {
David Avendasora 10.1 198 EOFetchSpecification fetchSpec = new EOFetchSpecification(<$GEN_PREFIX$><$classNameWithoutPackage$>.ENTITY_NAME, _qualifier, _sortOrderings);
199 fetchSpec.setIsDeep(true);
200 NSArray eoObjects = _editingContext.objectsWithFetchSpecification(fetchSpec);
201 return eoObjects;
202 }
Pascal Robert 31.1 203 {{/code}}
David Avendasora 10.1 204
Pascal Robert 30.1 205 {{code}}
206 public static <$classNameWithoutPackage$> fetch<$classNameWithoutPackage$>(EOEditingContext _editingContext, String _keyName, Object _value) {
David Avendasora 10.1 207 return <$GEN_PREFIX$><$classNameWithoutPackage$>.fetch<$classNameWithoutPackage$>(_editingContext, new EOKeyValueQualifier(_keyName, EOQualifier.QualifierOperatorEqual, _value));
208 }
Pascal Robert 31.1 209 {{/code}}
David Avendasora 10.1 210
Pascal Robert 30.1 211 {{code}}
212 public static <$classNameWithoutPackage$> fetch<$classNameWithoutPackage$>(EOEditingContext _editingContext, EOQualifier _qualifier) {
David Avendasora 10.1 213 NSArray eoObjects = <$GEN_PREFIX$><$classNameWithoutPackage$>.fetch<$classNameWithoutPackage$>s(_editingContext, _qualifier, null);
214 <$classNameWithoutPackage$> eoObject;
215 int count = eoObjects.count();
216 if (count == 0) {
217 eoObject = null;
218 }
219 else if (count == 1) {
220 eoObject = (<$classNameWithoutPackage$>)eoObjects.objectAtIndex(0);
221 }
222 else {
223 throw new IllegalStateException("There was more than one <$classNameWithoutPackage$> that matched the qualifier '" + _qualifier + "'.");
224 }
225 return eoObject;
226 }
Pascal Robert 31.1 227 {{/code}}
Pascal Robert 30.1 228
229 {{code}}
230 public static <$classNameWithoutPackage$> fetchRequired<$classNameWithoutPackage$>(EOEditingContext _editingContext, String _keyName, Object _value) {
David Avendasora 10.1 231 return <$GEN_PREFIX$><$classNameWithoutPackage$>.fetchRequired<$classNameWithoutPackage$>(_editingContext, new EOKeyValueQualifier(_keyName, EOQualifier.QualifierOperatorEqual, _value));
232 }
Pascal Robert 31.1 233 {{/code}}
David Avendasora 10.1 234
Pascal Robert 30.1 235 {{code}}
236
237 public static <$classNameWithoutPackage$> fetchRequired<$classNameWithoutPackage$>(EOEditingContext _editingContext, EOQualifier _qualifier) {
David Avendasora 10.1 238 <$classNameWithoutPackage$> eoObject = <$GEN_PREFIX$><$classNameWithoutPackage$>.fetch<$classNameWithoutPackage$>(_editingContext, _qualifier);
Pascal Robert 30.1 239 if (eoObject == null) {
David Avendasora 10.1 240 throw new NoSuchElementException("There was no <$classNameWithoutPackage$> that matched the qualifier '" + _qualifier + "'.");
241 }
242 return eoObject;
243 }
244
Quinton Dolan 14.1 245 {{/code}}
David Avendasora 10.1 246
Pascal Robert 31.1 247 Add methods for getting local instances of EO's. The static one is handy if you have a reference to an EO that might be null (it does a null check first):
David Avendasora 10.1 248
Quinton Dolan 14.1 249 {{code}}
Pascal Robert 30.1 250 public <$classNameWithoutPackage$> localInstanceOf<$classNameWithoutPackage$>(EOEditingContext _editingContext) {
David Avendasora 10.1 251 return (<$classNameWithoutPackage$>)EOUtilities.localInstanceOfObject(_editingContext, this);
252 }
Pascal Robert 31.1 253 {{/code}}
David Avendasora 10.1 254
Pascal Robert 30.1 255 {{code}}
256
257 public static <$classNameWithoutPackage$> localInstanceOf<$classNameWithoutPackage$>(EOEditingContext _editingContext, <$classNameWithoutPackage$> _eo) {
258 return (_eo == null) ? null : (<$classNameWithoutPackage$>)EOUtilities.localInstanceOfObject(_editingContext, _eo);
David Avendasora 10.1 259 }
260
Quinton Dolan 14.1 261 {{/code}}
David Avendasora 10.1 262
263 If you've ever wanted to be able to qualify a toMany relationship on your EO's, but sometimes you want to fetch them w/ a fetch spec, and sometimes you want to filter in-memory, you can use the following:
264
Quinton Dolan 14.1 265 {{code}}
David Avendasora 10.1 266
Pascal Robert 30.1 267 <$if !ToManyRelationship.inverseRelationship$>
David Avendasora 10.1 268 public NSArray <$ToManyRelationship.name$>(EOQualifier qualifier) {
269 return <$ToManyRelationship.name$>(qualifier, null);
270 }
271 <$endif$>
272 <$if ToManyRelationship.inverseRelationship$>
273 public NSArray <$ToManyRelationship.name$>(EOQualifier qualifier) {
274 return <$ToManyRelationship.name$>(qualifier, null, false);
275 }
Pascal Robert 30.1 276
277 public NSArray <$ToManyRelationship.name$>(EOQualifier qualifier, boolean fetch) {
David Avendasora 10.1 278 return <$ToManyRelationship.name$>(qualifier, null, fetch);
279 }
280 <$endif$>
Pascal Robert 30.1 281
David Avendasora 10.1 282 public NSArray <$ToManyRelationship.name$>(EOQualifier qualifier, NSArray sortOrderings<$if ToManyRelationship.inverseRelationship$>, boolean fetch<$endif$>) {
283 NSArray results;
284 <$if ToManyRelationship.inverseRelationship$>
285 if (fetch) {
286 EOQualifier fullQualifier;
Quinton Dolan 14.1 287 EOQualifier inverseQualifier = new EOKeyValueQualifier(<$ToManyRelationship.destination.className$>.
288 <$ToManyRelationship.inverseRelationship.name.uppercaseUnderbarString$>_KEY, EOQualifier.QualifierOperatorEqual, this);
David Avendasora 10.1 289 if (qualifier == null) {
290 fullQualifier = inverseQualifier;
291 }
292 else {
293 NSMutableArray qualifiers = new NSMutableArray();
294 qualifiers.addObject(qualifier);
295 qualifiers.addObject(inverseQualifier);
296 fullQualifier = new EOAndQualifier(qualifiers);
297 }
298 results = <$ToManyRelationship.destination.className$>.fetch<$ToManyRelationship.destination.name$>s(editingContext(), fullQualifier, sortOrderings);
299 }
300 else {
301 <$endif$>
302 results = <$ToManyRelationship.name$>();
303 if (qualifier != null) {
304 results = EOQualifier.filteredArrayWithQualifier(results, qualifier);
305 }
306 if (sortOrderings != null) {
307 results = EOSortOrdering.sortedArrayUsingKeyOrderArray(results, sortOrderings);
308 }
309 <$if ToManyRelationship.inverseRelationship$>
310 }
311 <$endif$>
312 return results;
313 }
314
Quinton Dolan 14.1 315 {{/code}}
David Avendasora 10.1 316
Pascal Robert 30.1 317 === John Huss ===
David Avendasora 10.1 318
Pascal Robert 31.1 319 I wanted to share a wonderful bit of knowledge I learned today. If you're using Java 1.5 you can add @SuppressWarnings("all") to the template for your _EO base classes and eliminate annoying compiler messages (usually uneeded import statements).
David Avendasora 10.1 320
Quinton Dolan 14.1 321 {{code}}
David Avendasora 10.1 322
Pascal Robert 30.1 323 @SuppressWarnings("all")
David Avendasora 10.1 324 public class _Invoice extends ERXGenericRecord {
325 }
326
Quinton Dolan 14.1 327 {{/code}}
David Avendasora 10.1 328
Pascal Robert 30.1 329 === Guido Neitzer ===
David Avendasora 10.1 330
331 Create awakeFromInsertion() and awakeFromFetch() in your EOGenerator template as a method stub that only calls super() and has a comment for "initialize your object here ...". You only have to put in the code at that place and can't possibly forget to call super(). Here is an example:
332
Quinton Dolan 14.1 333 {{code}}
David Avendasora 10.1 334
Pascal Robert 30.1 335 /**
Quinton Dolan 14.1 336 * Initialization of the instance while inserting it into an editing context
337 */
338 public void awakeFromInsertion (EOEditingContext editingContext) {
339 super.awakeFromInsertion (editingContext);
340 // initialize your object here
341 }
David Avendasora 10.1 342
Quinton Dolan 14.1 343 {{/code}}
David Avendasora 10.1 344
345 This is from my JavaSubclassSourceTemplate.eotemplate