Subversion Repository Public Repository

litesoft

Diff Revisions 949 vs 950 for /trunk/Java/KeyHole/src/org/litesoft/aokeyhole/objects/ObjectMetaData.java

Diff revisions: vs.
  @@ -1,607 +1,607 @@
1 - // This Source Code is in the Public Domain per: http://unlicense.org
2 - package org.litesoft.aokeyhole.objects;
3 -
4 - import org.litesoft.aokeyhole.objects.attributes.*;
5 - import org.litesoft.aokeyhole.objects.factories.*;
6 - import org.litesoft.aokeyhole.objects.support.*;
7 - import org.litesoft.aokeyhole.persist.*;
8 - import org.litesoft.aokeyhole.toolkit.*;
9 - import org.litesoft.core.simpletypes.nonpublic.*;
10 -
11 - import java.util.*;
12 -
13 - public class ObjectMetaData extends AbstractNamedOwningMetaData<SubSystemMetaData, ObjectMetaData, AttributeMetaData> implements ViewSupportable,
14 - Comparable<ObjectMetaData> {
15 - protected static final String CIRCULAR_ERROR = "Can NOT specify the current Object as it's own ";
16 -
17 - public static final ObjectMetaData[] EMPTY_ARRAY = new ObjectMetaData[0];
18 -
19 - private MetaDataOwnerManager<ObjectMetaData, AttributeMetaData> mOwnerManager = new MetaDataOwnerManager<ObjectMetaData, AttributeMetaData>( this );
20 -
21 - private ObjectSet mObjectSet;
22 -
23 - private AttributeFactory mAttributeFactory;
24 - private String mNotes = null;
25 - private PropertyManager mPropertyManager;
26 -
27 - private ObjectProxy mParent;
28 - private ObjectMetaData[] mGeneratedRelationsByParent = EMPTY_ARRAY;
29 -
30 - public ObjectMetaData( Mode pMode, boolean pEditable, ObjectSet pObjectSet, IdentifierValidator pNameValidator, String pName,
31 - AttributeFactory pAttributeFactory ) {
32 - super( pObjectSet.getType(), pMode, pEditable, pNameValidator, pName );
33 -
34 - mObjectSet = pObjectSet;
35 - mAttributeFactory = pAttributeFactory;
36 - mPropertyManager = new PropertyManager( this, isEditable(), pObjectSet.getPMDs() );
37 -
38 - mParent = new ObjectProxy( this, "Parent" );
39 - }
40 -
41 - @Override
42 - public MetaDataOwnerManager<ObjectMetaData, AttributeMetaData> getOwnerManager() {
43 - return mOwnerManager;
44 - }
45 -
46 - public String[] getPotentialRelateToObjectNamesFor( AttributeSet pAttributeSet, boolean pVirtual ) {
47 - ObjectMetaData[] zSortedObjectMetaDatas = getSystemMetaData().getSortedObjectMetaDatas();
48 - List<String> rv = new ArrayList<String>( zSortedObjectMetaDatas.length );
49 - for ( ObjectMetaData zMD : zSortedObjectMetaDatas ) {
50 - if ( pAttributeSet.isAcceptableAsRelatedTo( zMD, pVirtual ) ) {
51 - rv.add( zMD.getName() );
52 - }
53 - }
54 - return rv.toArray( new String[rv.size()] );
55 - }
56 -
57 - @Override
58 - public int compareTo( ObjectMetaData them ) {
59 - int zDiff = this.getObjectSet().getSortIndex() - them.getObjectSet().getSortIndex();
60 - if ( zDiff != 0 ) {
61 - return zDiff;
62 - }
63 - return CompareSupport.compare( this.getName(), them.getName() );
64 - }
65 -
66 - @SuppressWarnings({"EqualsWhichDoesntCheckParameterClass"})
67 - @Override
68 - public final boolean equals( Object obj ) {
69 - return this == obj;
70 - }
71 -
72 - @Override
73 - public final int hashCode() {
74 - return System.identityHashCode( this );
75 - }
76 -
77 - @Override
78 - public String toString() {
79 - String zChanged = isChanged() ? " * " : " ";
80 - return zChanged + getName() + zChanged;
81 - }
82 -
83 - @SuppressWarnings({"UnusedDeclaration"})
84 - public String toStringForError() {
85 - return getSubSystemMetaData().getName() + "." + getName();
86 - }
87 -
88 - public AttributeMetaData unpersistAttributeID( String pName ) {
89 - return add( mAttributeFactory.createAttributeMetaDataID( getObjectSet(), Mode.Rehydrating, isEditable(), pName ) );
90 - }
91 -
92 - public AttributeMetaData unpersistAttributeValidOptions( AttributeType pType, String pName, String[] pOptions, boolean pVirtual ) {
93 - return add( mAttributeFactory.createAttributeMetaDataValidOptions( getObjectSet(), Mode.Rehydrating, isEditable(), pType, pVirtual, pName, pOptions ) );
94 - }
95 -
96 - public AttributeMetaData unpersistAttributeSimple( AttributeType pType, String pName, boolean pVirtual ) {
97 - return add( mAttributeFactory.createAttributeMetaDataSimple( getObjectSet(), Mode.Rehydrating, isEditable(), pType, pVirtual, pName ) );
98 - }
99 -
100 - public AttributeMetaData unpersistAttributeRelatedVirtual( AttributeType pType, String pName, String pRelatedToName ) {
101 - AttributeMetaDataRelatedVirtual md =
102 - mAttributeFactory.createAttributeMetaDataRelatedVirtual( getObjectSet(), Mode.Rehydrating, isEditable(), pType, pName );
103 - add( md );
104 - md.unpersistRelatedTo( pRelatedToName );
105 - return md;
106 - }
107 -
108 - public AttributeMetaData unpersistAttributeRelatedPersisted( AttributeType pType, String pName, String pRelatedToName, String pBackAttrib ) {
109 - AttributeMetaDataRelatedPersisted md =
110 - mAttributeFactory.createAttributeMetaDataRelatedPersisted( getObjectSet(), Mode.Rehydrating, isEditable(), pType, pName );
111 - add( md );
112 - md.unpersistRelatedTo( pRelatedToName );
113 - md.unpersistBackAttrib( pBackAttrib );
114 - return md;
115 - }
116 -
117 - public ObjectSet getObjectSet() {
118 - return mObjectSet;
119 - }
120 -
121 - public void createAttributeMetaDataID() {
122 - verifyEditability();
123 -
124 - add( mAttributeFactory.createAttributeMetaDataID( getObjectSet(), Mode.New, isEditable(), null ) );
125 - }
126 -
127 - public void createAttributeMetaDataCommonPairedToOne() {
128 - verifyEditability();
129 -
130 - add( mAttributeFactory.createAttributeMetaDataRelatedPersisted( getObjectSet(), Mode.New, isEditable(), A_CommonPairedToOne.TYPE, "Varies" ) );
131 - }
132 -
133 - public void createAttributeMetaDataPairedToOne() {
134 - verifyEditability();
135 -
136 - add( mAttributeFactory.createAttributeMetaDataRelatedPersisted( getObjectSet(), Mode.New, isEditable(), A_PairedToOne.TYPE, "PairTo" ) );
137 - }
138 -
139 - public void createAttributeMetaDataVariableBridgeToOneLeft() {
140 - verifyEditability();
141 -
142 - add( mAttributeFactory.createAttributeMetaDataRelatedPersisted( getObjectSet(), Mode.New, isEditable(), A_VariableBridgeToOneLeft.TYPE, "Left" ) );
143 - }
144 -
145 - public void createAttributeMetaDataBridgeToOneLeft() {
146 - verifyEditability();
147 -
148 - add( mAttributeFactory.createAttributeMetaDataRelatedPersisted( getObjectSet(), Mode.New, isEditable(), A_BridgeToOneLeft.TYPE, "Left" ) );
149 - }
150 -
151 - public void createAttributeMetaDataBridgeToOneRight() {
152 - verifyEditability();
153 -
154 - add( mAttributeFactory.createAttributeMetaDataRelatedPersisted( getObjectSet(), Mode.New, isEditable(), A_BridgeToOneRight.TYPE, "Right" ) );
155 - }
156 -
157 - public AttributeMetaData createAttributeMetaData( AttributeType pType, boolean pVirtual ) {
158 - verifyEditability();
159 -
160 - if ( pType.getFAT().isRelated() ) {
161 - return add( createRelatedAttributeMetaData( pType, pVirtual ) );
162 - }
163 - if ( pType instanceof AbstractValidOptionsAttributeTypeSimple ) {
164 - return add( mAttributeFactory.createAttributeMetaDataValidOptions( getObjectSet(), Mode.New, isEditable(), pType, pVirtual, null ) );
165 - }
166 - // Simple
167 - return add( mAttributeFactory.createAttributeMetaDataSimple( getObjectSet(), Mode.New, isEditable(), pType, pVirtual, null ) );
168 - }
169 -
170 - private AttributeMetaData createRelatedAttributeMetaData( AttributeType pType, boolean pVirtual ) {
171 - if ( pVirtual ) {
172 - return mAttributeFactory.createAttributeMetaDataRelatedVirtual( getObjectSet(), Mode.New, isEditable(), pType, null );
173 - }
174 - return mAttributeFactory.createAttributeMetaDataRelatedPersisted( getObjectSet(), Mode.New, isEditable(), pType, null );
175 - }
176 -
177 - public void remove( AttributeMetaData pAMD ) {
178 - getOwnerManager().remove( pAMD );
179 - }
180 -
181 - private AttributeMetaData add( AttributeMetaData pAMD ) {
182 - getOwnerManager().add( pAMD );
183 - return pAMD;
184 - }
185 -
186 - public String getNotes() {
187 - return mNotes;
188 - }
189 -
190 - public void unpersistNotes( String pNotes ) {
191 - mNotes = pNotes;
192 - }
193 -
194 - public void setNotes( String pNotes ) {
195 - verifyEditability();
196 - if ( !areEqual( mNotes, pNotes ) ) {
197 - mNotes = pNotes;
198 - changed();
199 - }
200 - }
201 -
202 - public boolean shouldShowParent() {
203 - return getSystemMetaData().shouldShowParent( getSubSystemMetaData(), mObjectSet );
204 - }
205 -
206 - public String getParentLabel() {
207 - return mObjectSet.getParentLabel( getSubSystemMetaData().getName() );
208 - }
209 -
210 - public String getParentName() {
211 - return mParent.getObjectName();
212 - }
213 -
214 - public void unpersistParentName( String pParentName ) {
215 - chkUnhappyCase( updateParentName( pParentName ) );
216 - }
217 -
218 - /**
219 - * @return null or Error
220 - */
221 - public String setParentName( String pParentName ) {
222 - verifyEditability();
223 - return updateParentName( pParentName );
224 - }
225 -
226 - /**
227 - * @return null or Error
228 - */
229 - protected String updateParentName( String pParentName ) {
230 - ObjectMetaData curParent = mParent.getObjectMetaData();
231 - try {
232 - if ( !mParent.setObjectName( pParentName, this, CIRCULAR_ERROR + getParentLabel() ) ) {
233 - return null;
234 - }
235 - }
236 - catch ( IllegalArgumentException e ) {
237 - return e.getMessage();
238 - }
239 - if ( curParent != null ) {
240 - curParent.removeGeneratedRelation( this );
241 - }
242 - wireGeneratedRelation();
243 - changed();
244 - return null;
245 - }
246 -
247 - private void wireGeneratedRelation() // Parent or Paired
248 - {
249 - ObjectMetaData newParent = mParent.getObjectMetaData();
250 - if ( newParent != null ) {
251 - newParent.addGeneratedRelation( this );
252 - }
253 - }
254 -
255 - @SuppressWarnings({"UnusedDeclaration"})
256 - public PropertyManager getPropertyManager() {
257 - return mPropertyManager;
258 - }
259 -
260 - @SuppressWarnings({"UnusedDeclaration"})
261 - public Property[] getProperties() {
262 - return mPropertyManager.getProperties();
263 - }
264 -
265 - public void unpersistProperty( String pName, String pValueAsString ) {
266 - mPropertyManager.unpersistProperty( pName, pValueAsString );
267 - }
268 -
269 - /**
270 - * @return null or Error
271 - */
272 - @SuppressWarnings({"UnusedDeclaration"})
273 - public String setPropertyValue( String pName, Object pValue ) {
274 - return mPropertyManager.updatePropertyValue( pName, pValue );
275 - }
276 -
277 - @Override
278 - public void setRehydrated() {
279 - if ( getOwnerManager().available( AttributeMetaData.ID_NAME ) && mObjectSet.requireID() ) {
280 - add( mAttributeFactory.createAttributeMetaDataID( getObjectSet(), Mode.Rehydrating, isEditable(), null ) );
281 - }
282 - mPropertyManager.setRehydrated();
283 - mParent.unpersistFini( getSystemMetaData(), getNameValidator(), this, CIRCULAR_ERROR + getParentLabel() );
284 - wireGeneratedRelation();
285 - super.setRehydrated();
286 - }
287 -
288 - @Override
289 - public String validatePersistable() {
290 - String error = super.validatePersistable();
291 - return (error != null) ? error : mPropertyManager.validatePersistable();
292 - }
293 -
294 - public String[] getSortedChildNames() {
295 - if ( mGeneratedRelationsByParent.length == 0 ) {
296 - return EMPTY_STRINGS;
297 - }
298 - String[] names = new String[mGeneratedRelationsByParent.length];
299 - for ( int i = 0; i < mGeneratedRelationsByParent.length; i++ ) {
300 - names[i] = mGeneratedRelationsByParent[i].getName();
301 - }
302 - Arrays.sort( names );
303 - return names;
304 - }
305 -
306 - public void addGeneratedRelation( ObjectMetaData pGeneratedRelation ) // Parent or Paired
307 - {
308 - mGeneratedRelationsByParent = add( mGeneratedRelationsByParent, pGeneratedRelation );
309 - }
310 -
311 - public void removeGeneratedRelation( ObjectMetaData pGeneratedRelation ) {
312 - mGeneratedRelationsByParent = remove( mGeneratedRelationsByParent, pGeneratedRelation );
313 - }
314 -
315 - public String[] getSortedRelatedPersistedAttributeNamesTo( boolean pToManys, ObjectMetaData pToObject ) {
316 - ArrayList<String> names = new ArrayList<String>();
317 - for ( AttributeMetaData zAMD : getOwnerManager().getEntries() ) {
318 - if ( zAMD.isRelated() && !zAMD.isVirtual() ) {
319 - AttributeMetaDataRelatedPersisted rpmd = (AttributeMetaDataRelatedPersisted) zAMD;
320 - if ( (pToManys == rpmd.isToMany()) && (rpmd.isRelatedTo( pToObject ) || rpmd.isVariableToOne()) ) {
321 - names.add( zAMD.getName() );
322 - }
323 - }
324 - }
325 - Collections.sort( names );
326 - return names.toArray( new String[names.size()] );
327 - }
328 -
329 - public AttributeMetaData getAttribute( String pName ) {
330 - return getOwnerManager().getEntry( pName );
331 - }
332 -
333 - public List<AttributeMetaData> getSortedAttributes() {
334 - List<AttributeMetaData> rv = new ArrayList<AttributeMetaData>( getOwnerManager().getEntries() );
335 - Collections.sort( rv );
336 - return rv;
337 - }
338 -
339 - protected ObjectMetaData[] add( ObjectMetaData[] pOrig, ObjectMetaData pNew ) {
340 - int oldLength = pOrig.length;
341 - if ( oldLength == 0 ) {
342 - return new ObjectMetaData[]{pNew};
343 - }
344 - ObjectMetaData[] joined = new ObjectMetaData[oldLength + 1];
345 - joined[0] = pNew;
346 - System.arraycopy( pOrig, 0, joined, 1, oldLength );
347 - return joined;
348 - }
349 -
350 - protected ObjectMetaData[] remove( ObjectMetaData[] pOrig, ObjectMetaData pToRemove ) {
351 - for ( int i = 0; i < pOrig.length; i++ ) {
352 - if ( pToRemove == pOrig[i] ) {
353 - if ( i == 0 ) {
354 - return removeFirst( pOrig );
355 - }
356 - if ( i == (pOrig.length - 1) ) {
357 - return removeLast( pOrig );
358 - }
359 - return removeMiddle( pOrig, i );
360 - }
361 - }
362 - return pOrig;
363 - }
364 -
365 - private ObjectMetaData[] removeFirst( ObjectMetaData[] pOrig ) {
366 - if ( pOrig.length == 1 ) {
367 - return EMPTY_ARRAY;
368 - }
369 - int newLength = pOrig.length - 1;
370 - ObjectMetaData[] shrunk = new ObjectMetaData[newLength];
371 - System.arraycopy( pOrig, 1, shrunk, 0, newLength );
372 - return shrunk;
373 - }
374 -
375 - private ObjectMetaData[] removeLast( ObjectMetaData[] pOrig ) {
376 - int newLength = pOrig.length - 1;
377 - ObjectMetaData[] shrunk = new ObjectMetaData[newLength];
378 - System.arraycopy( pOrig, 0, shrunk, 0, newLength );
379 - return shrunk;
380 - }
381 -
382 - private ObjectMetaData[] removeMiddle( ObjectMetaData[] pOrig, int pIndex ) {
383 - int newLength = pOrig.length - 1;
384 - ObjectMetaData[] shrunk = new ObjectMetaData[newLength];
385 - System.arraycopy( pOrig, 0, shrunk, 0, pIndex );
386 - System.arraycopy( pOrig, pIndex + 1, shrunk, pIndex, newLength - pIndex );
387 - return shrunk;
388 - }
389 -
390 - public void addTo( SubSystemBuilder pBuilder ) {
391 - ObjectBuilder zBuilder =
392 - pBuilder.createObjectBuilder( getMetaDataType(), getName(), getParentName(), SingleLineNotes.convertStringToLines( getNotes() ) );
393 - mPropertyManager.addTo( zBuilder );
394 - for ( AttributeMetaData zAttribute : getSortedAttributes() ) {
395 - zAttribute.addTo( zBuilder );
396 - }
397 - zBuilder.done();
398 - }
399 -
400 - public void populateFrom( ObjectReader pReader ) {
401 - unpersistNotes( SingleLineNotes.convertLinesToString( pReader.getNotes() ) );
402 - for ( PropertyReader zReader; null != (zReader = pReader.nextProperty()); ) {
403 - String zWhat = zReader.getWhat();
404 - String zData = zReader.getData();
405 - mPropertyManager.unpersistProperty( zWhat, zData );
406 - }
407 - for ( AttributeReader zReader; null != (zReader = pReader.nextAttribute()); ) {
408 - String zType = zReader.getType();
409 -
410 - boolean zVirtual = zReader.isVirtual();
411 - AttributeSet zSet = determineAttributeSet( zType, zVirtual );
412 - if ( zSet == null ) {
413 - throw zReader.unrecognizedType(
414 - "Unrecognized Attribute-type '" + (zVirtual ? "Virtual-" : "") + zType + "', not" + mAttributeFactory.getTypesForError() );
415 - }
416 -
417 - createAttributeMetaData( zSet, zVirtual, zReader ).populateFrom( zReader );
418 - }
419 - }
420 -
421 - private AttributeMetaData createAttributeMetaData( AttributeSet pSet, boolean pVirtual, AttributeReader pReader ) {
422 - AttributeType zType = pSet.getType();
423 - FundamentalAttributeType zFAT = zType.getFAT();
424 - if ( zFAT.isRelated() ) {
425 - String[] parts;
426 - if ( pVirtual ) {
427 - parts = pReader.getAdditionalValues( 1 ); // assert there are not more than 1
428 - return unpersistAttributeRelatedVirtual( zType, pReader.getName(), parts[0] ); // RelatedToName
429 - }
430 - parts = pReader.getAdditionalValues( 2 ); // assert there are not more than 2
431 - return unpersistAttributeRelatedPersisted( zType, pReader.getName(), parts[0], parts[1] ); // RelatedToName, BackAttrib
432 - }
433 - if ( zType instanceof AbstractValidOptionsAttributeTypeSimple ) {
434 - return unpersistAttributeValidOptions( zType, pReader.getName(), pReader.getAdditionalValues( null ), pVirtual );
435 - }
436 - pReader.getAdditionalValues( 0 ); // assert there are none!
437 - if ( zType instanceof A_ID ) {
438 - return unpersistAttributeID( pReader.getName() );
439 - }
440 - return unpersistAttributeSimple( zType, pReader.getName(), pVirtual );
441 - }
442 -
443 - private AttributeSet determineAttributeSet( String pWhat, boolean pVirtual ) {
444 - for ( AttributeSet zSet : mAttributeFactory.getAttributeSets() ) {
445 - if ( pWhat.equals( zSet.getType().toString() ) ) {
446 - if ( pVirtual ) {
447 - return (zSet.getVirtual() != null) ? zSet : null;
448 - }
449 - return (zSet.getPersisted() != null) ? zSet : null;
450 - }
451 - }
452 - return null;
453 - }
454 -
455 - public SubSystemMetaData getSubSystemMetaData() {
456 - return getOwner();
457 - }
458 -
459 - @Override
460 - public void setUpView( NameValuesComponent pNameValuesComponent ) {
461 - pNameValuesComponent.setValue( ObjectNames.NAME, getName() );
462 - pNameValuesComponent.setValue( ObjectNames.NOTES, getNotes() );
463 - if ( shouldShowParent() ) {
464 - pNameValuesComponent.setValue( ObjectNames.PARENT, getParentName() );
465 - }
466 - mPropertyManager.setUpView( pNameValuesComponent );
467 - }
468 -
469 - protected void saveFromViewCollectChanges( ChangeHandler pChanges, NameValuesComponent pNameValuesComponent ) {
470 - pChanges.add( checkNameChange( pNameValuesComponent.getValue( AttribNames.NAME ) ) );
471 - pChanges.add( checkNotesChange( pNameValuesComponent.getValue( ObjectNames.NOTES ) ) );
472 - if ( shouldShowParent() ) {
473 - pChanges.add( checkParentChange( getParentName(), pNameValuesComponent.getValue( ObjectNames.PARENT ) ) );
474 - }
475 - mPropertyManager.saveFromView( pChanges, pNameValuesComponent );
476 - }
477 -
478 - /**
479 - * @return null or Error
480 - */
481 - @Override
482 - public String saveFromView( NameValuesComponent pNameValuesComponent ) {
483 - ChangeHandler zChanges = new ChangeHandler();
484 - try {
485 - saveFromViewCollectChanges( zChanges, pNameValuesComponent );
486 - }
487 - catch ( RuntimeException e ) {
488 - return e.getMessage();
489 - }
490 -
491 - zChanges.commitChanges();
492 - return null;
493 - }
494 -
495 - /**
496 - * @return null or Error
497 - */
498 - public String deleteExisting() {
499 - ChangeHandler zChanges = new ChangeHandler();
500 - try {
501 - deleteExisting( zChanges );
502 - }
503 - catch ( RuntimeException e ) {
504 - return e.getMessage();
505 - }
506 -
507 - zChanges.commitChanges();
508 - return null;
509 - }
510 -
511 - private void deleteExisting( ChangeHandler pChanges ) {
512 - Collection<AttributeMetaData> zChildren = getOwnerManager().getEntries();
513 - for ( AttributeMetaData zAMD : new ArrayList<AttributeMetaData>( zChildren ) ) {
514 - zAMD.deleteExistingCollectChanges( pChanges );
515 - }
516 - getSubSystemMetaData().remove( this, pChanges );
517 - }
518 -
519 - public void clearAllAttributeRelatedToIf( ObjectMetaData pObjectMetaData, ChangeHandler pChanges ) {
520 - Collection<AttributeMetaData> zChildren = getOwnerManager().getEntries();
521 - for ( AttributeMetaData zAMD : new ArrayList<AttributeMetaData>( zChildren ) ) {
522 - zAMD.clearRelatedToIf( pObjectMetaData, pChanges );
523 - }
524 - }
525 -
526 - protected abstract static class AbstractChangeFragment implements ChangeFragment {
527 - protected ObjectMetaData mCaller;
528 -
529 - protected AbstractChangeFragment( ObjectMetaData pCaller ) {
530 - mCaller = pCaller;
531 - }
532 - }
533 -
534 - protected ChangeFragment checkNameChange( String pNewName ) {
535 - String zError = getNameValidator().validateIdentifier( pNewName, "Attribute Name" );
536 - if ( zError != null ) {
537 - throw new RuntimeException( zError );
538 - }
539 - String zCurName = getName();
540 - if ( !areEqual( zCurName, pNewName ) ) {
541 - SubSystemMetaData zOwner = getSubSystemMetaData();
542 - if ( zOwner.isUsedOwnedName( pNewName ) ) {
543 - throw new RuntimeException( "Duplicate Name" );
544 - }
545 - return createChangeNameFragment( pNewName );
546 - }
547 - return null;
548 - }
549 -
550 - protected ChangeFragment createChangeNameFragment( String pNewName ) {
551 - return new ChangeName( this, pNewName );
552 - }
553 -
554 - protected static class ChangeName extends AbstractChangeFragment {
555 - private String mNewName;
556 -
557 - public ChangeName( ObjectMetaData pCaller, String pNewName ) {
558 - super( pCaller );
559 - mNewName = pNewName;
560 - }
561 -
562 - @Override
563 - public void commitChange() {
564 - mCaller.setName( mNewName );
565 - }
566 - }
567 -
568 - protected ChangeFragment checkNotesChange( String pNewNotes ) {
569 - String zCurNotes = getNotes();
570 - return !areEqual( zCurNotes, pNewNotes ) ? createChangeNotesFragment( pNewNotes ) : null;
571 - }
572 -
573 - protected ChangeFragment createChangeNotesFragment( String pNewNotes ) {
574 - return new ChangeNotes( this, pNewNotes );
575 - }
576 -
577 - protected static class ChangeNotes extends AbstractChangeFragment {
578 - private String mNewNotes;
579 -
580 - public ChangeNotes( ObjectMetaData pCaller, String pNewNotes ) {
581 - super( pCaller );
582 - mNewNotes = pNewNotes;
583 - }
584 -
585 - @Override
586 - public void commitChange() {
587 - mCaller.setNotes( mNewNotes );
588 - }
589 - }
590 -
591 - protected ChangeFragment checkParentChange( String pCurParent, String pNewParent ) {
592 - return !areEqual( pCurParent, pNewParent ) ? new ChangeParent( pNewParent ) : null;
593 - }
594 -
595 - protected class ChangeParent implements ChangeFragment {
596 - private String mNewParent;
597 -
598 - public ChangeParent( String pNewParent ) {
599 - mNewParent = pNewParent;
600 - }
601 -
602 - @Override
603 - public void commitChange() {
604 - setParentName( mNewParent );
605 - }
606 - }
607 - }
1 + // This Source Code is in the Public Domain per: http://unlicense.org
2 + package org.litesoft.aokeyhole.objects;
3 +
4 + import org.litesoft.aokeyhole.objects.attributes.*;
5 + import org.litesoft.aokeyhole.objects.factories.*;
6 + import org.litesoft.aokeyhole.objects.support.*;
7 + import org.litesoft.aokeyhole.persist.*;
8 + import org.litesoft.aokeyhole.toolkit.*;
9 + import org.litesoft.core.simpletypes.nonpublic.*;
10 +
11 + import java.util.*;
12 +
13 + public class ObjectMetaData extends AbstractNamedOwningMetaData<SubSystemMetaData, ObjectMetaData, AttributeMetaData> implements ViewSupportable,
14 + Comparable<ObjectMetaData> {
15 + protected static final String CIRCULAR_ERROR = "Can NOT specify the current Object as it's own ";
16 +
17 + public static final ObjectMetaData[] EMPTY_ARRAY = new ObjectMetaData[0];
18 +
19 + private MetaDataOwnerManager<ObjectMetaData, AttributeMetaData> mOwnerManager = new MetaDataOwnerManager<ObjectMetaData, AttributeMetaData>( this );
20 +
21 + private ObjectSet mObjectSet;
22 +
23 + private AttributeFactory mAttributeFactory;
24 + private String mNotes = null;
25 + private PropertyManager mPropertyManager;
26 +
27 + private ObjectProxy mParent;
28 + private ObjectMetaData[] mGeneratedRelationsByParent = EMPTY_ARRAY;
29 +
30 + public ObjectMetaData( Mode pMode, boolean pEditable, ObjectSet pObjectSet, IdentifierValidator pNameValidator, String pName,
31 + AttributeFactory pAttributeFactory ) {
32 + super( pObjectSet.getType(), pMode, pEditable, pNameValidator, pName );
33 +
34 + mObjectSet = pObjectSet;
35 + mAttributeFactory = pAttributeFactory;
36 + mPropertyManager = new PropertyManager( this, isEditable(), pObjectSet.getPMDs() );
37 +
38 + mParent = new ObjectProxy( this, "Parent" );
39 + }
40 +
41 + @Override
42 + public MetaDataOwnerManager<ObjectMetaData, AttributeMetaData> getOwnerManager() {
43 + return mOwnerManager;
44 + }
45 +
46 + public String[] getPotentialRelateToObjectNamesFor( AttributeSet pAttributeSet, boolean pVirtual ) {
47 + ObjectMetaData[] zSortedObjectMetaDatas = getSystemMetaData().getSortedObjectMetaDatas();
48 + List<String> rv = new ArrayList<String>( zSortedObjectMetaDatas.length );
49 + for ( ObjectMetaData zMD : zSortedObjectMetaDatas ) {
50 + if ( pAttributeSet.isAcceptableAsRelatedTo( zMD, pVirtual ) ) {
51 + rv.add( zMD.getName() );
52 + }
53 + }
54 + return rv.toArray( new String[rv.size()] );
55 + }
56 +
57 + @Override
58 + public int compareTo( ObjectMetaData them ) {
59 + int zDiff = this.getObjectSet().getSortIndex() - them.getObjectSet().getSortIndex();
60 + if ( zDiff != 0 ) {
61 + return zDiff;
62 + }
63 + return CompareSupport.compare( this.getName(), them.getName() );
64 + }
65 +
66 + @SuppressWarnings({"EqualsWhichDoesntCheckParameterClass"})
67 + @Override
68 + public final boolean equals( Object obj ) {
69 + return this == obj;
70 + }
71 +
72 + @Override
73 + public final int hashCode() {
74 + return System.identityHashCode( this );
75 + }
76 +
77 + @Override
78 + public String toString() {
79 + String zChanged = isChanged() ? " * " : " ";
80 + return zChanged + getName() + zChanged;
81 + }
82 +
83 + @SuppressWarnings({"UnusedDeclaration"})
84 + public String toStringForError() {
85 + return getSubSystemMetaData().getName() + "." + getName();
86 + }
87 +
88 + public AttributeMetaData unpersistAttributeID( String pName ) {
89 + return add( mAttributeFactory.createAttributeMetaDataID( getObjectSet(), Mode.Rehydrating, isEditable(), pName ) );
90 + }
91 +
92 + public AttributeMetaData unpersistAttributeValidOptions( AttributeType pType, String pName, String[] pOptions, boolean pVirtual ) {
93 + return add( mAttributeFactory.createAttributeMetaDataValidOptions( getObjectSet(), Mode.Rehydrating, isEditable(), pType, pVirtual, pName, pOptions ) );
94 + }
95 +
96 + public AttributeMetaData unpersistAttributeSimple( AttributeType pType, String pName, boolean pVirtual ) {
97 + return add( mAttributeFactory.createAttributeMetaDataSimple( getObjectSet(), Mode.Rehydrating, isEditable(), pType, pVirtual, pName ) );
98 + }
99 +
100 + public AttributeMetaData unpersistAttributeRelatedVirtual( AttributeType pType, String pName, String pRelatedToName ) {
101 + AttributeMetaDataRelatedVirtual md =
102 + mAttributeFactory.createAttributeMetaDataRelatedVirtual( getObjectSet(), Mode.Rehydrating, isEditable(), pType, pName );
103 + add( md );
104 + md.unpersistRelatedTo( pRelatedToName );
105 + return md;
106 + }
107 +
108 + public AttributeMetaData unpersistAttributeRelatedPersisted( AttributeType pType, String pName, String pRelatedToName, String pBackAttrib ) {
109 + AttributeMetaDataRelatedPersisted md =
110 + mAttributeFactory.createAttributeMetaDataRelatedPersisted( getObjectSet(), Mode.Rehydrating, isEditable(), pType, pName );
111 + add( md );
112 + md.unpersistRelatedTo( pRelatedToName );
113 + md.unpersistBackAttrib( pBackAttrib );
114 + return md;
115 + }
116 +
117 + public ObjectSet getObjectSet() {
118 + return mObjectSet;
119 + }
120 +
121 + public void createAttributeMetaDataID() {
122 + verifyEditability();
123 +
124 + add( mAttributeFactory.createAttributeMetaDataID( getObjectSet(), Mode.New, isEditable(), null ) );
125 + }
126 +
127 + public void createAttributeMetaDataCommonPairedToOne() {
128 + verifyEditability();
129 +
130 + add( mAttributeFactory.createAttributeMetaDataRelatedPersisted( getObjectSet(), Mode.New, isEditable(), A_CommonPairedToOne.TYPE, "Varies" ) );
131 + }
132 +
133 + public void createAttributeMetaDataPairedToOne() {
134 + verifyEditability();
135 +
136 + add( mAttributeFactory.createAttributeMetaDataRelatedPersisted( getObjectSet(), Mode.New, isEditable(), A_PairedToOne.TYPE, "PairTo" ) );
137 + }
138 +
139 + public void createAttributeMetaDataVariableBridgeToOneLeft() {
140 + verifyEditability();
141 +
142 + add( mAttributeFactory.createAttributeMetaDataRelatedPersisted( getObjectSet(), Mode.New, isEditable(), A_VariableBridgeToOneLeft.TYPE, "Left" ) );
143 + }
144 +
145 + public void createAttributeMetaDataBridgeToOneLeft() {
146 + verifyEditability();
147 +
148 + add( mAttributeFactory.createAttributeMetaDataRelatedPersisted( getObjectSet(), Mode.New, isEditable(), A_BridgeToOneLeft.TYPE, "Left" ) );
149 + }
150 +
151 + public void createAttributeMetaDataBridgeToOneRight() {
152 + verifyEditability();
153 +
154 + add( mAttributeFactory.createAttributeMetaDataRelatedPersisted( getObjectSet(), Mode.New, isEditable(), A_BridgeToOneRight.TYPE, "Right" ) );
155 + }
156 +
157 + public AttributeMetaData createAttributeMetaData( AttributeType pType, boolean pVirtual ) {
158 + verifyEditability();
159 +
160 + if ( pType.getFAT().isRelated() ) {
161 + return add( createRelatedAttributeMetaData( pType, pVirtual ) );
162 + }
163 + if ( pType instanceof AbstractValidOptionsAttributeTypeSimple ) {
164 + return add( mAttributeFactory.createAttributeMetaDataValidOptions( getObjectSet(), Mode.New, isEditable(), pType, pVirtual, null ) );
165 + }
166 + // Simple
167 + return add( mAttributeFactory.createAttributeMetaDataSimple( getObjectSet(), Mode.New, isEditable(), pType, pVirtual, null ) );
168 + }
169 +
170 + private AttributeMetaData createRelatedAttributeMetaData( AttributeType pType, boolean pVirtual ) {
171 + if ( pVirtual ) {
172 + return mAttributeFactory.createAttributeMetaDataRelatedVirtual( getObjectSet(), Mode.New, isEditable(), pType, null );
173 + }
174 + return mAttributeFactory.createAttributeMetaDataRelatedPersisted( getObjectSet(), Mode.New, isEditable(), pType, null );
175 + }
176 +
177 + public void remove( AttributeMetaData pAMD ) {
178 + getOwnerManager().remove( pAMD );
179 + }
180 +
181 + private AttributeMetaData add( AttributeMetaData pAMD ) {
182 + getOwnerManager().add( pAMD );
183 + return pAMD;
184 + }
185 +
186 + public String getNotes() {
187 + return mNotes;
188 + }
189 +
190 + public void unpersistNotes( String pNotes ) {
191 + mNotes = pNotes;
192 + }
193 +
194 + public void setNotes( String pNotes ) {
195 + verifyEditability();
196 + if ( !areEqual( mNotes, pNotes ) ) {
197 + mNotes = pNotes;
198 + changed();
199 + }
200 + }
201 +
202 + public boolean shouldShowParent() {
203 + return getSystemMetaData().shouldShowParent( getSubSystemMetaData(), mObjectSet );
204 + }
205 +
206 + public String getParentLabel() {
207 + return mObjectSet.getParentLabel( getSubSystemMetaData().getName() );
208 + }
209 +
210 + public String getParentName() {
211 + return mParent.getObjectName();
212 + }
213 +
214 + public void unpersistParentName( String pParentName ) {
215 + chkUnhappyCase( updateParentName( pParentName ) );
216 + }
217 +
218 + /**
219 + * @return null or Error
220 + */
221 + public String setParentName( String pParentName ) {
222 + verifyEditability();
223 + return updateParentName( pParentName );
224 + }
225 +
226 + /**
227 + * @return null or Error
228 + */
229 + protected String updateParentName( String pParentName ) {
230 + ObjectMetaData curParent = mParent.getObjectMetaData();
231 + try {
232 + if ( !mParent.setObjectName( pParentName, this, CIRCULAR_ERROR + getParentLabel() ) ) {
233 + return null;
234 + }
235 + }
236 + catch ( IllegalArgumentException e ) {
237 + return e.getMessage();
238 + }
239 + if ( curParent != null ) {
240 + curParent.removeGeneratedRelation( this );
241 + }
242 + wireGeneratedRelation();
243 + changed();
244 + return null;
245 + }
246 +
247 + private void wireGeneratedRelation() // Parent or Paired
248 + {
249 + ObjectMetaData newParent = mParent.getObjectMetaData();
250 + if ( newParent != null ) {
251 + newParent.addGeneratedRelation( this );
252 + }
253 + }
254 +
255 + @SuppressWarnings({"UnusedDeclaration"})
256 + public PropertyManager getPropertyManager() {
257 + return mPropertyManager;
258 + }
259 +
260 + @SuppressWarnings({"UnusedDeclaration"})
261 + public Property[] getProperties() {
262 + return mPropertyManager.getProperties();
263 + }
264 +
265 + public void unpersistProperty( String pName, String pValueAsString ) {
266 + mPropertyManager.unpersistProperty( pName, pValueAsString );
267 + }
268 +
269 + /**
270 + * @return null or Error
271 + */
272 + @SuppressWarnings({"UnusedDeclaration"})
273 + public String setPropertyValue( String pName, Object pValue ) {
274 + return mPropertyManager.updatePropertyValue( pName, pValue );
275 + }
276 +
277 + @Override
278 + public void setRehydrated() {
279 + if ( getOwnerManager().available( AttributeMetaData.ID_NAME ) && mObjectSet.requireID() ) {
280 + add( mAttributeFactory.createAttributeMetaDataID( getObjectSet(), Mode.Rehydrating, isEditable(), null ) );
281 + }
282 + mPropertyManager.setRehydrated();
283 + mParent.unpersistFini( getSystemMetaData(), getNameValidator(), this, CIRCULAR_ERROR + getParentLabel() );
284 + wireGeneratedRelation();
285 + super.setRehydrated();
286 + }
287 +
288 + @Override
289 + public String validatePersistable() {
290 + String error = super.validatePersistable();
291 + return (error != null) ? error : mPropertyManager.validatePersistable();
292 + }
293 +
294 + public String[] getSortedChildNames() {
295 + if ( mGeneratedRelationsByParent.length == 0 ) {
296 + return EMPTY_STRINGS;
297 + }
298 + String[] names = new String[mGeneratedRelationsByParent.length];
299 + for ( int i = 0; i < mGeneratedRelationsByParent.length; i++ ) {
300 + names[i] = mGeneratedRelationsByParent[i].getName();
301 + }
302 + Arrays.sort( names );
303 + return names;
304 + }
305 +
306 + public void addGeneratedRelation( ObjectMetaData pGeneratedRelation ) // Parent or Paired
307 + {
308 + mGeneratedRelationsByParent = add( mGeneratedRelationsByParent, pGeneratedRelation );
309 + }
310 +
311 + public void removeGeneratedRelation( ObjectMetaData pGeneratedRelation ) {
312 + mGeneratedRelationsByParent = remove( mGeneratedRelationsByParent, pGeneratedRelation );
313 + }
314 +
315 + public String[] getSortedRelatedPersistedAttributeNamesTo( boolean pToManys, ObjectMetaData pToObject ) {
316 + ArrayList<String> names = new ArrayList<String>();
317 + for ( AttributeMetaData zAMD : getOwnerManager().getEntries() ) {
318 + if ( zAMD.isRelated() && !zAMD.isVirtual() ) {
319 + AttributeMetaDataRelatedPersisted rpmd = (AttributeMetaDataRelatedPersisted) zAMD;
320 + if ( (pToManys == rpmd.isToMany()) && (rpmd.isRelatedTo( pToObject ) || rpmd.isVariableToOne()) ) {
321 + names.add( zAMD.getName() );
322 + }
323 + }
324 + }
325 + Collections.sort( names );
326 + return names.toArray( new String[names.size()] );
327 + }
328 +
329 + public AttributeMetaData getAttribute( String pName ) {
330 + return getOwnerManager().getEntry( pName );
331 + }
332 +
333 + public List<AttributeMetaData> getSortedAttributes() {
334 + List<AttributeMetaData> rv = new ArrayList<AttributeMetaData>( getOwnerManager().getEntries() );
335 + Collections.sort( rv );
336 + return rv;
337 + }
338 +
339 + protected ObjectMetaData[] add( ObjectMetaData[] pOrig, ObjectMetaData pNew ) {
340 + int oldLength = pOrig.length;
341 + if ( oldLength == 0 ) {
342 + return new ObjectMetaData[]{pNew};
343 + }
344 + ObjectMetaData[] joined = new ObjectMetaData[oldLength + 1];
345 + joined[0] = pNew;
346 + System.arraycopy( pOrig, 0, joined, 1, oldLength );
347 + return joined;
348 + }
349 +
350 + protected ObjectMetaData[] remove( ObjectMetaData[] pOrig, ObjectMetaData pToRemove ) {
351 + for ( int i = 0; i < pOrig.length; i++ ) {
352 + if ( pToRemove == pOrig[i] ) {
353 + if ( i == 0 ) {
354 + return removeFirst( pOrig );
355 + }
356 + if ( i == (pOrig.length - 1) ) {
357 + return removeLast( pOrig );
358 + }
359 + return removeMiddle( pOrig, i );
360 + }
361 + }
362 + return pOrig;
363 + }
364 +
365 + private ObjectMetaData[] removeFirst( ObjectMetaData[] pOrig ) {
366 + if ( pOrig.length == 1 ) {
367 + return EMPTY_ARRAY;
368 + }
369 + int newLength = pOrig.length - 1;
370 + ObjectMetaData[] shrunk = new ObjectMetaData[newLength];
371 + System.arraycopy( pOrig, 1, shrunk, 0, newLength );
372 + return shrunk;
373 + }
374 +
375 + private ObjectMetaData[] removeLast( ObjectMetaData[] pOrig ) {
376 + int newLength = pOrig.length - 1;
377 + ObjectMetaData[] shrunk = new ObjectMetaData[newLength];
378 + System.arraycopy( pOrig, 0, shrunk, 0, newLength );
379 + return shrunk;
380 + }
381 +
382 + private ObjectMetaData[] removeMiddle( ObjectMetaData[] pOrig, int pIndex ) {
383 + int newLength = pOrig.length - 1;
384 + ObjectMetaData[] shrunk = new ObjectMetaData[newLength];
385 + System.arraycopy( pOrig, 0, shrunk, 0, pIndex );
386 + System.arraycopy( pOrig, pIndex + 1, shrunk, pIndex, newLength - pIndex );
387 + return shrunk;
388 + }
389 +
390 + public void addTo( SubSystemBuilder pBuilder ) {
391 + ObjectBuilder zBuilder =
392 + pBuilder.createObjectBuilder( getMetaDataType(), getName(), getParentName(), SingleLineNotes.convertStringToLines( getNotes() ) );
393 + mPropertyManager.addTo( zBuilder );
394 + for ( AttributeMetaData zAttribute : getSortedAttributes() ) {
395 + zAttribute.addTo( zBuilder );
396 + }
397 + zBuilder.done();
398 + }
399 +
400 + public void populateFrom( ObjectReader pReader ) {
401 + unpersistNotes( SingleLineNotes.convertLinesToString( pReader.getNotes() ) );
402 + for ( PropertyReader zReader; null != (zReader = pReader.nextProperty()); ) {
403 + String zWhat = zReader.getWhat();
404 + String zData = zReader.getData();
405 + mPropertyManager.unpersistProperty( zWhat, zData );
406 + }
407 + for ( AttributeReader zReader; null != (zReader = pReader.nextAttribute()); ) {
408 + String zType = zReader.getType();
409 +
410 + boolean zVirtual = zReader.isVirtual();
411 + AttributeSet zSet = determineAttributeSet( zType, zVirtual );
412 + if ( zSet == null ) {
413 + throw zReader.unrecognizedType(
414 + "Unrecognized Attribute-type '" + (zVirtual ? "Virtual-" : "") + zType + "', not" + mAttributeFactory.getTypesForError() );
415 + }
416 +
417 + createAttributeMetaData( zSet, zVirtual, zReader ).populateFrom( zReader );
418 + }
419 + }
420 +
421 + private AttributeMetaData createAttributeMetaData( AttributeSet pSet, boolean pVirtual, AttributeReader pReader ) {
422 + AttributeType zType = pSet.getType();
423 + FundamentalAttributeType zFAT = zType.getFAT();
424 + if ( zFAT.isRelated() ) {
425 + String[] parts;
426 + if ( pVirtual ) {
427 + parts = pReader.getAdditionalValues( 1 ); // assert there are not more than 1
428 + return unpersistAttributeRelatedVirtual( zType, pReader.getName(), parts[0] ); // RelatedToName
429 + }
430 + parts = pReader.getAdditionalValues( 2 ); // assert there are not more than 2
431 + return unpersistAttributeRelatedPersisted( zType, pReader.getName(), parts[0], parts[1] ); // RelatedToName, BackAttrib
432 + }
433 + if ( zType instanceof AbstractValidOptionsAttributeTypeSimple ) {
434 + return unpersistAttributeValidOptions( zType, pReader.getName(), pReader.getAdditionalValues( null ), pVirtual );
435 + }
436 + pReader.getAdditionalValues( 0 ); // assert there are none!
437 + if ( zType instanceof A_ID ) {
438 + return unpersistAttributeID( pReader.getName() );
439 + }
440 + return unpersistAttributeSimple( zType, pReader.getName(), pVirtual );
441 + }
442 +
443 + private AttributeSet determineAttributeSet( String pWhat, boolean pVirtual ) {
444 + for ( AttributeSet zSet : mAttributeFactory.getAttributeSets() ) {
445 + if ( pWhat.equals( zSet.getType().toString() ) ) {
446 + if ( pVirtual ) {
447 + return (zSet.getVirtual() != null) ? zSet : null;
448 + }
449 + return (zSet.getPersisted() != null) ? zSet : null;
450 + }
451 + }
452 + return null;
453 + }
454 +
455 + public SubSystemMetaData getSubSystemMetaData() {
456 + return getOwner();
457 + }
458 +
459 + @Override
460 + public void setUpView( NameValuesComponent pNameValuesComponent ) {
461 + pNameValuesComponent.setValue( ObjectNames.NAME, getName() );
462 + pNameValuesComponent.setValue( ObjectNames.NOTES, getNotes() );
463 + if ( shouldShowParent() ) {
464 + pNameValuesComponent.setValue( ObjectNames.PARENT, getParentName() );
465 + }
466 + mPropertyManager.setUpView( pNameValuesComponent );
467 + }
468 +
469 + protected void saveFromViewCollectChanges( ChangeHandler pChanges, NameValuesComponent pNameValuesComponent ) {
470 + pChanges.add( checkNameChange( pNameValuesComponent.getValue( AttribNames.NAME ) ) );
471 + pChanges.add( checkNotesChange( pNameValuesComponent.getValue( ObjectNames.NOTES ) ) );
472 + if ( shouldShowParent() ) {
473 + pChanges.add( checkParentChange( getParentName(), pNameValuesComponent.getValue( ObjectNames.PARENT ) ) );
474 + }
475 + mPropertyManager.saveFromView( pChanges, pNameValuesComponent );
476 + }
477 +
478 + /**
479 + * @return null or Error
480 + */
481 + @Override
482 + public String saveFromView( NameValuesComponent pNameValuesComponent ) {
483 + ChangeHandler zChanges = new ChangeHandler();
484 + try {
485 + saveFromViewCollectChanges( zChanges, pNameValuesComponent );
486 + }
487 + catch ( RuntimeException e ) {
488 + return e.getMessage();
489 + }
490 +
491 + zChanges.commitChanges();
492 + return null;
493 + }
494 +
495 + /**
496 + * @return null or Error
497 + */
498 + public String deleteExisting() {
499 + ChangeHandler zChanges = new ChangeHandler();
500 + try {
501 + deleteExisting( zChanges );
502 + }
503 + catch ( RuntimeException e ) {
504 + return e.getMessage();
505 + }
506 +
507 + zChanges.commitChanges();
508 + return null;
509 + }
510 +
511 + private void deleteExisting( ChangeHandler pChanges ) {
512 + Collection<AttributeMetaData> zChildren = getOwnerManager().getEntries();
513 + for ( AttributeMetaData zAMD : new ArrayList<AttributeMetaData>( zChildren ) ) {
514 + zAMD.deleteExistingCollectChanges( pChanges );
515 + }
516 + getSubSystemMetaData().remove( this, pChanges );
517 + }
518 +
519 + public void clearAllAttributeRelatedToIf( ObjectMetaData pObjectMetaData, ChangeHandler pChanges ) {
520 + Collection<AttributeMetaData> zChildren = getOwnerManager().getEntries();
521 + for ( AttributeMetaData zAMD : new ArrayList<AttributeMetaData>( zChildren ) ) {
522 + zAMD.clearRelatedToIf( pObjectMetaData, pChanges );
523 + }
524 + }
525 +
526 + protected abstract static class AbstractChangeFragment implements ChangeFragment {
527 + protected ObjectMetaData mCaller;
528 +
529 + protected AbstractChangeFragment( ObjectMetaData pCaller ) {
530 + mCaller = pCaller;
531 + }
532 + }
533 +
534 + protected ChangeFragment checkNameChange( String pNewName ) {
535 + String zError = getNameValidator().validateIdentifier( pNewName, "Attribute Name" );
536 + if ( zError != null ) {
537 + throw new RuntimeException( zError );
538 + }
539 + String zCurName = getName();
540 + if ( !areEqual( zCurName, pNewName ) ) {
541 + SubSystemMetaData zOwner = getSubSystemMetaData();
542 + if ( zOwner.isUsedOwnedName( pNewName ) ) {
543 + throw new RuntimeException( "Duplicate Name" );
544 + }
545 + return createChangeNameFragment( pNewName );
546 + }
547 + return null;
548 + }
549 +
550 + protected ChangeFragment createChangeNameFragment( String pNewName ) {
551 + return new ChangeName( this, pNewName );
552 + }
553 +
554 + protected static class ChangeName extends AbstractChangeFragment {
555 + private String mNewName;
556 +
557 + public ChangeName( ObjectMetaData pCaller, String pNewName ) {
558 + super( pCaller );
559 + mNewName = pNewName;
560 + }
561 +
562 + @Override
563 + public void commitChange() {
564 + mCaller.setName( mNewName );
565 + }
566 + }
567 +
568 + protected ChangeFragment checkNotesChange( String pNewNotes ) {
569 + String zCurNotes = getNotes();
570 + return !areEqual( zCurNotes, pNewNotes ) ? createChangeNotesFragment( pNewNotes ) : null;
571 + }
572 +
573 + protected ChangeFragment createChangeNotesFragment( String pNewNotes ) {
574 + return new ChangeNotes( this, pNewNotes );
575 + }
576 +
577 + protected static class ChangeNotes extends AbstractChangeFragment {
578 + private String mNewNotes;
579 +
580 + public ChangeNotes( ObjectMetaData pCaller, String pNewNotes ) {
581 + super( pCaller );
582 + mNewNotes = pNewNotes;
583 + }
584 +
585 + @Override
586 + public void commitChange() {
587 + mCaller.setNotes( mNewNotes );
588 + }
589 + }
590 +
591 + protected ChangeFragment checkParentChange( String pCurParent, String pNewParent ) {
592 + return !areEqual( pCurParent, pNewParent ) ? new ChangeParent( pNewParent ) : null;
593 + }
594 +
595 + protected class ChangeParent implements ChangeFragment {
596 + private String mNewParent;
597 +
598 + public ChangeParent( String pNewParent ) {
599 + mNewParent = pNewParent;
600 + }
601 +
602 + @Override
603 + public void commitChange() {
604 + setParentName( mNewParent );
605 + }
606 + }
607 + }