001: // THIS SOFTWARE IS PROVIDED BY SOFTARIS PTY.LTD. AND OTHER METABOSS
002: // CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
003: // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
004: // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTARIS PTY.LTD.
005: // OR OTHER METABOSS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
006: // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
007: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
008: // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
009: // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
010: // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
011: // EVEN IF SOFTARIS PTY.LTD. OR OTHER METABOSS CONTRIBUTORS ARE ADVISED OF THE
012: // POSSIBILITY OF SUCH DAMAGE.
013: //
014: // Copyright 2000-2005 © Softaris Pty.Ltd. All Rights Reserved.
015: package com.metaboss.sdlctools.models.modelassistant.metabossmodel.implicittypes;
016:
017: import java.util.Arrays;
018: import java.util.Collection;
019: import java.util.Comparator;
020: import java.util.HashSet;
021: import java.util.Iterator;
022: import java.util.List;
023: import java.util.Set;
024: import java.util.TreeSet;
025:
026: import javax.jmi.reflect.ConstraintViolationException;
027:
028: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.DataType;
029: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.Namespace;
030: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.Property;
031: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.PropertyDescriptor;
032: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.TypeTemplate;
033: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Attribute;
034: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Entity;
035:
036: /** This class holds details about OrderingInstructions DataType
037: * being processed. Used internally in the Assistant impl */
038: class EntityOrderingInstructionsDataTypeHelper {
039: // Utility comparator, which is used to sort properties in order of deletion
040: // The problem is that when parent property is deleted - the child property is deleted too, so
041: // when we iterate through unused properties and issue refDelete() - we may hit already deleted property.
042: // This comparator sorts the properties in the reverse string sort order of the keys,
043: // which ensures that properties are sorted in the right order for deletion (child properties before parent ones)
044: private static Comparator sPropertiesToDeleteComparator = new Comparator() {
045: public int compare(Object o1, Object o2) {
046: return ((Property) o2).getKey().compareTo(
047: ((Property) o1).getKey());
048: }
049: };
050:
051: private ModelAssistantImpl mModelAssistantImpl;
052: private Set mUnusedProperties = new TreeSet(
053: sPropertiesToDeleteComparator);
054:
055: private DataType mOrderingInstructionsDataType = null;
056: private TypeTemplate mEnumerableValueTypeTemplate = null;
057: private PropertyDescriptor mComparablePropertyDescriptor = null;
058: private PropertyDescriptor mCategoryPropertyDescriptor = null;
059: private PropertyDescriptor mCategoryNamePropertyDescriptor = null;
060: private PropertyDescriptor mCategoryDescriptionPropertyDescriptor = null;
061: private PropertyDescriptor mCategoryValueNamePropertyDescriptor = null;
062: private PropertyDescriptor mValuePropertyDescriptor = null;
063: private PropertyDescriptor mValueNamePropertyDescriptor = null;
064: private PropertyDescriptor mValueDescriptionPropertyDescriptor = null;
065:
066: // This helper is looking at the conditions and ensuring the inegrity of the data type
067: // it will create the missing data type and delete exta one if necessary
068: static void verifyEntityOrderingInstructionDataTypeIntegrity(
069: Collection pViolations,
070: ModelAssistantImpl pModelAssistantImpl, Entity pEntity,
071: List pUnprocessedDataTypes, HelperContext pHelperContext) {
072: Namespace lDomainNamespace = pHelperContext
073: .getDomainNamespace();
074: if (lDomainNamespace == null)
075: return;
076: TypeTemplate lDesiredTypeTemplate = pHelperContext
077: .getEnumerableValueFieldTypeTemplate();
078:
079: Collection lAttributesToBeUsedInOrdering = pEntity
080: .getCombinedAttributesUsedForOrdering();
081: if (lAttributesToBeUsedInOrdering.isEmpty() == false) {
082: String lExpectedDataTypeName = StylesheetImpl
083: .getOrderingInstructionDataTypeName(pEntity
084: .getName());
085: DataType lDataTypeInNamespace = lDomainNamespace
086: .findDataType(lExpectedDataTypeName);
087: if (lDataTypeInNamespace != null) {
088: // Remove this data type from the list of unprocessed ones
089: if (pUnprocessedDataTypes != null)
090: pUnprocessedDataTypes.remove(lDataTypeInNamespace);
091: // Verify that the entity is actually pointing to this data type
092: DataType lDataTypeInEntity = pEntity
093: .getOrderingInstructionDataType();
094: if (lDataTypeInEntity != null
095: && lDataTypeInEntity
096: .equals(lDataTypeInNamespace) == false)
097: pViolations
098: .add(new ConstraintViolationException(
099: pEntity,
100: pEntity.refMetaObject(),
101: "Orderable Entity must always be associated with the Entity Ordering Instruction data type residing in System namespace."));
102:
103: // Verify that this data type is based on prescribed template
104: TypeTemplate lActualTypeTemplate = lDataTypeInNamespace
105: .getTypetemplate();
106: if (lActualTypeTemplate == null
107: || lActualTypeTemplate
108: .equals(lDesiredTypeTemplate) == false)
109: pViolations
110: .add(new ConstraintViolationException(
111: lDataTypeInNamespace,
112: lDataTypeInNamespace
113: .refMetaObject(),
114: "The Entity Ordering Instruction data type must be based on a '"
115: + lDesiredTypeTemplate
116: .getName()
117: + "' typetemplate. The '"
118: + lExpectedDataTypeName
119: + "' data type is not based on this template."));
120: } else
121: pViolations
122: .add(new ConstraintViolationException(
123: lDomainNamespace,
124: lDomainNamespace.refMetaObject(),
125: "System namespace for Domain must contain an Entity Ordering Instruction data type for every orderable entity in the domain. Entity '"
126: + pEntity.getName()
127: + "' does not have corresponding '"
128: + lExpectedDataTypeName
129: + "' data type."));
130: }
131: }
132:
133: // This helper is looking at the conditions and ensuring the inegrity of the data type
134: // it will create the missing data type and delete exta one if necessary
135: static void ensureEntityOrderingInstructionDataTypeIntegrity(
136: ModelAssistantImpl pModelAssistantImpl, Entity pEntity,
137: List pUnprocessedDataTypes, HelperContext pHelperContext) {
138: // See if we need to support ordering in this entity. If we do - we need to
139: // generate special enumerated type with all possible ordering options
140: String lOrderingInstructionDataTypeName = StylesheetImpl
141: .getOrderingInstructionDataTypeName(pEntity.getName());
142: Collection lOrderByAttributes = pEntity
143: .getCombinedAttributesUsedForOrdering();
144: if (!lOrderByAttributes.isEmpty()) {
145: // Ensure that data type exists
146: ensureEntityOrderingInstructionDataTypeExists(
147: pModelAssistantImpl, pEntity,
148: pUnprocessedDataTypes, pHelperContext);
149: // Now work on all properties
150: EntityOrderingInstructionsDataTypeHelper lDataTypeHelper = new EntityOrderingInstructionsDataTypeHelper(
151: pModelAssistantImpl, pEntity
152: .getOrderingInstructionDataType());
153: // Work on properties
154: lDataTypeHelper.markPropertiesAsUnused();
155: // Work on attributes
156: for (Iterator lOrderByAttributesIterator = lOrderByAttributes
157: .iterator(); lOrderByAttributesIterator.hasNext();) {
158: Attribute lAttribute = (Attribute) lOrderByAttributesIterator
159: .next();
160: lDataTypeHelper
161: .ensureAttributeOrderingInstructionExists(lAttribute
162: .getName());
163: }
164: // Delete all still unused properties
165: lDataTypeHelper.deleteUnusedProperties();
166: } else
167: ensureEntityOrderingInstructionDataTypeAbsent(pEntity,
168: pUnprocessedDataTypes, pHelperContext);
169: }
170:
171: // This helper is looking after creation of absent ordering instruction data type
172: // It returns the newly created or found Data Type
173: // The namespaces are optional parameters - if they are null - they will be discovered inside this method
174: // and if they are unobtainable - this method will fail to work and return null. This is provided to save some time
175: // during batch operations
176: static DataType ensureEntityOrderingInstructionDataTypeExists(
177: ModelAssistantImpl pModelAssistantImpl, Entity pEntity,
178: List pUnprocessedDataTypes, HelperContext pHelperContext) {
179: Namespace lDomainNamespace = pHelperContext
180: .getDomainNamespace();
181: if (lDomainNamespace == null)
182: return null;
183: // Work on ordering instruction data type
184: // See if we need to support ordering in this entity. If we do - we need to
185: // generate special enumerated type with all possible ordering options
186: String lOrderingInstructionDataTypeName = StylesheetImpl
187: .getOrderingInstructionDataTypeName(pEntity.getName());
188: DataType lOrderingInstructionDataType = lDomainNamespace
189: .findDataType(lOrderingInstructionDataTypeName);
190: TypeTemplate lEnumerableValueTypeTemplate = pHelperContext
191: .getEnumerableValueFieldTypeTemplate();
192: if (lOrderingInstructionDataType == null) {
193:
194: lOrderingInstructionDataType = pModelAssistantImpl.mDataTypeClass
195: .createDataType();
196: lOrderingInstructionDataType
197: .setName(lOrderingInstructionDataTypeName);
198: lDomainNamespace.getDataTypes().add(
199: lOrderingInstructionDataType);
200: } else {
201: if (pUnprocessedDataTypes != null)
202: pUnprocessedDataTypes
203: .remove(lOrderingInstructionDataType);
204: }
205: // Because the data type is located by name - it is possible that in fact it does not have
206: // features set up as we would like them to be. We need just to override them
207: lOrderingInstructionDataType.setDescription(StylesheetImpl
208: .getOrderingInstructionDataTypeDescription(pEntity
209: .getName()));
210: lOrderingInstructionDataType
211: .setTypetemplate(lEnumerableValueTypeTemplate);
212: pEntity
213: .setOrderingInstructionDataType(lOrderingInstructionDataType);
214: // Ensure that mandatory properties are present
215: EntityOrderingInstructionsDataTypeHelper lDataTypeHelper = new EntityOrderingInstructionsDataTypeHelper(
216: pModelAssistantImpl, lOrderingInstructionDataType);
217: // Work on mandatory comparable property
218: lDataTypeHelper.ensureComparableExists();
219: // Work on mandatory ascending and descending categories
220: lDataTypeHelper
221: .ensureCategoryExists("Ascending",
222: "All ordering instructions which force the ascending order.");
223: lDataTypeHelper
224: .ensureCategoryExists("Descending",
225: "All ordering instructions which force the descending order.");
226: return lOrderingInstructionDataType;
227: }
228:
229: // This helper is looking after creation of absent ordering instruction data type
230: // The namespace is optional parameters - if it is null it will be discovered inside this method
231: // and if it is unobtainable - this method will fail to work and return false. This is provided to save some time
232: // during batch operations
233: static boolean ensureEntityOrderingInstructionDataTypeAbsent(
234: Entity pEntity, List pUnprocessedDataTypes,
235: HelperContext pHelperContext) {
236: Namespace lDomainNamespace = pHelperContext
237: .getDomainNamespace();
238: if (lDomainNamespace == null)
239: return false;
240: String lOrderingInstructionDataTypeName = StylesheetImpl
241: .getOrderingInstructionDataTypeName(pEntity.getName());
242: DataType lOrderingInstructionDataType = lDomainNamespace
243: .findDataType(lOrderingInstructionDataTypeName);
244: if (lOrderingInstructionDataType != null) {
245: if (pUnprocessedDataTypes != null)
246: pUnprocessedDataTypes
247: .remove(lOrderingInstructionDataType);
248: lOrderingInstructionDataType.refDelete();
249: }
250: // Just in case - set the datatype to null
251: pEntity.setOrderingInstructionDataType(null);
252: return true; // Done
253: }
254:
255: public EntityOrderingInstructionsDataTypeHelper(
256: ModelAssistantImpl pModelAssistantImpl,
257: DataType pOrderingInstructionsDataType) {
258: mModelAssistantImpl = pModelAssistantImpl;
259: mOrderingInstructionsDataType = pOrderingInstructionsDataType;
260: mEnumerableValueTypeTemplate = mOrderingInstructionsDataType
261: .getTypetemplate();
262: mComparablePropertyDescriptor = mEnumerableValueTypeTemplate
263: .getPropertyDescriptor("Comparable");
264: mCategoryPropertyDescriptor = mEnumerableValueTypeTemplate
265: .getPropertyDescriptor("Category");
266: mCategoryNamePropertyDescriptor = mCategoryPropertyDescriptor
267: .getPropertyDescriptor("Name");
268: mCategoryDescriptionPropertyDescriptor = mCategoryPropertyDescriptor
269: .getPropertyDescriptor("Description");
270: mCategoryValueNamePropertyDescriptor = mCategoryPropertyDescriptor
271: .getPropertyDescriptor("ValueName");
272: mValuePropertyDescriptor = mEnumerableValueTypeTemplate
273: .getPropertyDescriptor("Value");
274: mValueNamePropertyDescriptor = mValuePropertyDescriptor
275: .getPropertyDescriptor("Name");
276: mValueDescriptionPropertyDescriptor = mValuePropertyDescriptor
277: .getPropertyDescriptor("Description");
278: }
279:
280: // Marks all optional properties as unused.
281: // Every subsequent property action will remove from this list a property, which is not unused one
282: void markPropertiesAsUnused() {
283: // Put all properties to unused apart from mandatory ones
284: for (Iterator lPropertiesIterator = mOrderingInstructionsDataType
285: .getCombinedTypetemplateProperties().iterator(); lPropertiesIterator
286: .hasNext();) {
287: Property lProperty = (Property) lPropertiesIterator.next();
288: PropertyDescriptor lPropertyDescriptor = lProperty
289: .getDescriptor();
290: if (lPropertyDescriptor
291: .equals(mComparablePropertyDescriptor))
292: continue; // Always there
293: else if (lPropertyDescriptor
294: .equals(mCategoryPropertyDescriptor)) {
295: Collection lNamePropertyCollection = lProperty
296: .getPropertiesByDescriptor(mCategoryNamePropertyDescriptor);
297: if (lNamePropertyCollection.size() == 1) {
298: Property lNameProperty = (Property) lNamePropertyCollection
299: .toArray()[0];
300: String lNamePropertyValue = lNameProperty
301: .getValue();
302: if ((lNamePropertyValue != null)
303: && (lNamePropertyValue.equals("Ascending") || lNamePropertyValue
304: .equals("Descending")))
305: continue; // These categories always there
306: }
307: } else if (lPropertyDescriptor
308: .equals(mCategoryNamePropertyDescriptor)) {
309: String lNamePropertyValue = lProperty.getValue();
310: if ((lNamePropertyValue != null)
311: && (lNamePropertyValue.equals("Ascending") || lNamePropertyValue
312: .equals("Descending")))
313: continue; // These categories always there - leave name alone
314: } else if (lPropertyDescriptor
315: .equals(mCategoryDescriptionPropertyDescriptor)) {
316: Property lCategoryProperty = lProperty
317: .getParentProperty();
318: Collection lNamePropertyCollection = lCategoryProperty
319: .getPropertiesByDescriptor(mCategoryNamePropertyDescriptor);
320: if (lNamePropertyCollection.size() == 1) {
321: Property lNameProperty = (Property) lNamePropertyCollection
322: .toArray()[0];
323: String lNamePropertyValue = lNameProperty
324: .getValue();
325: if ((lNamePropertyValue != null)
326: && (lNamePropertyValue.equals("Ascending") || lNamePropertyValue
327: .equals("Descending")))
328: continue; // These categories always there - leave description alone
329: }
330: }
331: // Every property, which has fallen up to here has a potential to be unused
332: mUnusedProperties.add(lProperty);
333: }
334: }
335:
336: // Deletes all properties in unused set at the moment. Normally
337: // we start with marking all properties as unused, than going though all property manipulations
338: // and than calling this method to delete all whjat is left
339: void deleteUnusedProperties() {
340: for (Iterator lUnprocessedPropertiesIterator = mUnusedProperties
341: .iterator(); lUnprocessedPropertiesIterator.hasNext();) {
342: Property lProperty = (Property) lUnprocessedPropertiesIterator
343: .next();
344: lProperty.refDelete();
345: }
346: }
347:
348: public void ensureComparableExists() {
349: Property lComparableProperty = mOrderingInstructionsDataType
350: .findTypetemplatePropertyByKey("Comparable");
351: if (lComparableProperty == null) {
352: lComparableProperty = mComparablePropertyDescriptor
353: .createProperty("false", null);
354: mOrderingInstructionsDataType.getTypetemplateProperties()
355: .add(lComparableProperty);
356: } else {
357: // Update value just in case
358: lComparableProperty.setValue("false");
359: }
360: }
361:
362: public void ensureCategoryExists(String pCategoryName,
363: String pCategoryDescription) {
364: // Work on ascending and descending categories
365: Property lCategoryProperty = null;
366: Property lCategoryNameProperty = null;
367: Property lCategoryDescriptionProperty = null;
368: Collection lAllCategoryNames = mOrderingInstructionsDataType
369: .getTypetemplatePropertiesByDescriptor(mCategoryNamePropertyDescriptor);
370: for (Iterator lPropertiesIterator = lAllCategoryNames
371: .iterator(); lPropertiesIterator.hasNext();) {
372: Property lProperty = (Property) lPropertiesIterator.next();
373: if (lProperty.getValue().equals(pCategoryName)) {
374: // If name found - it means category is already declared.
375: // If name is not found - we have to create a category
376: lCategoryNameProperty = lProperty;
377: lCategoryProperty = lCategoryNameProperty
378: .getParentProperty();
379: // Find description property
380: for (Iterator lSubPropertiesIterator = lCategoryProperty
381: .getSubProperties().iterator(); lCategoryDescriptionProperty == null
382: && lSubPropertiesIterator.hasNext();) {
383: Property lSubProperty = (Property) lSubPropertiesIterator
384: .next();
385: if (lSubProperty.getDescriptor().equals(
386: mCategoryDescriptionPropertyDescriptor))
387: lCategoryDescriptionProperty = lSubProperty;
388: }
389: break;
390: }
391: }
392: if (lCategoryProperty == null) {
393: lCategoryProperty = mCategoryPropertyDescriptor
394: .createProperty(
395: null,
396: new Integer(
397: mOrderingInstructionsDataType
398: .getTypetemplatePropertiesByDescriptor(
399: mCategoryPropertyDescriptor)
400: .size() + 1));
401: mOrderingInstructionsDataType.getTypetemplateProperties()
402: .add(lCategoryProperty);
403: } else {
404: mUnusedProperties.remove(lCategoryProperty);
405: }
406:
407: if (lCategoryNameProperty == null) {
408: lCategoryNameProperty = mCategoryNamePropertyDescriptor
409: .createProperty(pCategoryName, null);
410: lCategoryProperty.getSubProperties().add(
411: lCategoryNameProperty);
412: } else {
413: // No point updating the name it must be the same because we have found the whole thing by name
414: mUnusedProperties.remove(lCategoryNameProperty);
415: }
416:
417: if (lCategoryDescriptionProperty == null) {
418: lCategoryDescriptionProperty = mCategoryDescriptionPropertyDescriptor
419: .createProperty(pCategoryDescription, null);
420: lCategoryProperty.getSubProperties().add(
421: lCategoryDescriptionProperty);
422: } else {
423: // Update description
424: lCategoryDescriptionProperty.setValue(pCategoryDescription);
425: mUnusedProperties.remove(lCategoryDescriptionProperty);
426: }
427: }
428:
429: public void ensureCategoryAbsent(String pCategoryName) {
430: // Work on ascending and descending categories
431: Property lCategoryProperty = null;
432: Collection lAllCategoryNames = mOrderingInstructionsDataType
433: .getTypetemplatePropertiesByDescriptor(mCategoryNamePropertyDescriptor);
434: for (Iterator lPropertiesIterator = lAllCategoryNames
435: .iterator(); lPropertiesIterator.hasNext();) {
436: Property lProperty = (Property) lPropertiesIterator.next();
437: if (lProperty.getValue().equals(pCategoryName)) {
438: // If name found - it means category is declared.
439: lCategoryProperty = lProperty.getParentProperty();
440: break;
441: }
442: }
443: if (lCategoryProperty != null) {
444: mUnusedProperties.remove(lCategoryProperty);
445: mUnusedProperties.removeAll(lCategoryProperty
446: .getCombinedProperties());
447: lCategoryProperty.refDelete();
448: }
449: }
450:
451: public void ensureAttributeOrderingInstructionExists(
452: String pAttributeName) {
453: // First ensure that attribute category exists
454: String lAttributeCategoryName = StylesheetImpl
455: .getOrderByAttributeCategoryName(pAttributeName);
456: String lAttributeCategoryDescription = StylesheetImpl
457: .getOrderByAttributeCategoryDescription(pAttributeName);
458: ensureCategoryExists(lAttributeCategoryName,
459: lAttributeCategoryDescription);
460: // Now work on ascending ordering value
461: String lAscendingOrderByInstructionValueName = StylesheetImpl
462: .getAscendingOrderByAttributeValueName(pAttributeName);
463: String lAscendingOrderByInstructionValueDescription = StylesheetImpl
464: .getAscendingOrderByAttributeValueDescription(pAttributeName);
465: ensureValueExists(lAscendingOrderByInstructionValueName,
466: lAscendingOrderByInstructionValueDescription);
467: ensureValueExistsInCategories(
468: lAscendingOrderByInstructionValueName, new String[] {
469: "Ascending", lAttributeCategoryName });
470:
471: // Now work on descending ordering value
472: String lDescendingOrderByInstructionValueName = StylesheetImpl
473: .getDescendingOrderByAttributeValueName(pAttributeName);
474: String lDescendingOrderByInstructionValueDescription = StylesheetImpl
475: .getDescendingOrderByAttributeValueDescription(pAttributeName);
476: ensureValueExists(lDescendingOrderByInstructionValueName,
477: lDescendingOrderByInstructionValueDescription);
478: ensureValueExistsInCategories(
479: lDescendingOrderByInstructionValueName, new String[] {
480: "Descending", lAttributeCategoryName });
481: }
482:
483: public void ensureAttributeOrderingInstructionAbsent(
484: String pAttributeName) {
485: // First ensure that attribute category exists
486: String lAttributeCategoryName = StylesheetImpl
487: .getOrderByAttributeCategoryName(pAttributeName);
488: ensureCategoryAbsent(lAttributeCategoryName);
489: // Now work on ascending ordering value
490: String lAscendingOrderByInstructionValueName = StylesheetImpl
491: .getAscendingOrderByAttributeValueName(pAttributeName);
492: ensureValueAbsent(lAscendingOrderByInstructionValueName);
493: ensureValueAbsentInCategories(
494: lAscendingOrderByInstructionValueName,
495: new String[] { "Ascending" });
496: // Now work on descending ordering value
497: String lDescendingOrderByInstructionValueName = StylesheetImpl
498: .getDescendingOrderByAttributeValueName(pAttributeName);
499: ensureValueAbsent(lDescendingOrderByInstructionValueName);
500: ensureValueAbsentInCategories(
501: lDescendingOrderByInstructionValueName,
502: new String[] { "Descending", });
503: }
504:
505: public void ensureValueExists(String pValueName,
506: String pValueDescription) {
507: // Work on values
508: Property lValueProperty = null;
509: Property lValueNameProperty = null;
510: Property lValueDescriptionProperty = null;
511: Collection lAllValueNames = mOrderingInstructionsDataType
512: .getTypetemplatePropertiesByDescriptor(mValueNamePropertyDescriptor);
513: for (Iterator lPropertiesIterator = lAllValueNames.iterator(); lPropertiesIterator
514: .hasNext();) {
515: Property lProperty = (Property) lPropertiesIterator.next();
516: if (lProperty.getValue().equals(pValueName)) {
517: // If name found - it means category is already declared.
518: // If name is not found - we have to create a category
519: lValueNameProperty = lProperty;
520: lValueProperty = lValueNameProperty.getParentProperty();
521: // Find description property
522: for (Iterator lSubPropertiesIterator = lValueProperty
523: .getSubProperties().iterator(); lSubPropertiesIterator
524: .hasNext();) {
525: Property lSubProperty = (Property) lSubPropertiesIterator
526: .next();
527: if (lSubProperty.getDescriptor().equals(
528: mValueDescriptionPropertyDescriptor)) {
529: lValueDescriptionProperty = lSubProperty;
530: break;
531: }
532: }
533: break;
534: }
535: }
536: if (lValueProperty == null) {
537: int lNextAvailableArrayIndex = mOrderingInstructionsDataType
538: .getTypetemplatePropertiesByDescriptor(
539: mValuePropertyDescriptor).size() + 1;
540: lValueProperty = mValuePropertyDescriptor.createProperty(
541: null, new Integer(lNextAvailableArrayIndex));
542: mOrderingInstructionsDataType.getTypetemplateProperties()
543: .add(lValueProperty);
544: } else {
545: mUnusedProperties.remove(lValueProperty);
546: }
547:
548: if (lValueNameProperty == null) {
549: lValueNameProperty = mValueNamePropertyDescriptor
550: .createProperty(pValueName, null);
551: lValueProperty.getSubProperties().add(lValueNameProperty);
552: } else {
553: // No point updating the name it must be the same because we have found the whole thing by name
554: mUnusedProperties.remove(lValueNameProperty);
555: }
556:
557: if (lValueDescriptionProperty == null) {
558: lValueDescriptionProperty = mValueDescriptionPropertyDescriptor
559: .createProperty(pValueDescription, null);
560: lValueProperty.getSubProperties().add(
561: lValueDescriptionProperty);
562: } else {
563: // Update description
564: lValueDescriptionProperty.setValue(pValueDescription);
565: mUnusedProperties.remove(lValueDescriptionProperty);
566: }
567: }
568:
569: public void ensureValueAbsent(String pValueName) {
570: // Work on values
571: Property lValueProperty = null;
572: Collection lAllValueNames = mOrderingInstructionsDataType
573: .getTypetemplatePropertiesByDescriptor(mValueNamePropertyDescriptor);
574: for (Iterator lPropertiesIterator = lAllValueNames.iterator(); lPropertiesIterator
575: .hasNext();) {
576: Property lProperty = (Property) lPropertiesIterator.next();
577: if (lProperty.getValue().equals(pValueName)) {
578: // If name found - it means value is declared.
579: // If name is not found - we have to create a category
580: lValueProperty = lProperty.getParentProperty();
581: break;
582: }
583: }
584: if (lValueProperty != null) {
585: mUnusedProperties.remove(lValueProperty);
586: mUnusedProperties.removeAll(lValueProperty
587: .getCombinedProperties());
588: lValueProperty.refDelete();
589: }
590: }
591:
592: public void ensureValueExistsInCategories(String pValueName,
593: String[] pCategoryNames) {
594: Set lDesiredCategoryNames = new HashSet();
595: lDesiredCategoryNames.addAll(Arrays.asList(pCategoryNames));
596: Collection lAllCategoryNames = mOrderingInstructionsDataType
597: .getTypetemplatePropertiesByDescriptor(mCategoryNamePropertyDescriptor);
598: for (Iterator lPropertiesIterator = lAllCategoryNames
599: .iterator(); lPropertiesIterator.hasNext();) {
600: Property lProperty = (Property) lPropertiesIterator.next();
601: if (lDesiredCategoryNames.contains(lProperty.getValue())) {
602: // Ensure that this category has this value
603: Property lCategoryProperty = lProperty
604: .getParentProperty();
605: Collection lAllCategoryValueNames = lCategoryProperty
606: .getPropertiesByDescriptor(mCategoryValueNamePropertyDescriptor);
607: Property lDesiredValueNameProperty = null;
608: for (Iterator lCategoryValueNamePropertiesIterator = lAllCategoryValueNames
609: .iterator(); lCategoryValueNamePropertiesIterator
610: .hasNext();) {
611: Property lCategoryValueNameProperty = (Property) lCategoryValueNamePropertiesIterator
612: .next();
613: if (pValueName.equals(lCategoryValueNameProperty
614: .getValue())) {
615: lDesiredValueNameProperty = lCategoryValueNameProperty;
616: break;
617: }
618: }
619: if (lDesiredValueNameProperty == null) {
620: lDesiredValueNameProperty = mCategoryValueNamePropertyDescriptor
621: .createProperty(pValueName, new Integer(
622: lAllCategoryValueNames.size() + 1));
623: lCategoryProperty.getSubProperties().add(
624: lDesiredValueNameProperty);
625: } else {
626: // No need to update because we have found it by this name
627: mUnusedProperties.remove(lDesiredValueNameProperty);
628: }
629: }
630: }
631: }
632:
633: public void ensureValueAbsentInCategories(String pValueName,
634: String[] pCategoryNames) {
635: Set lDesiredCategoryNames = new HashSet();
636: lDesiredCategoryNames.addAll(Arrays.asList(pCategoryNames));
637: Collection lAllCategoryNames = mOrderingInstructionsDataType
638: .getTypetemplatePropertiesByDescriptor(mCategoryNamePropertyDescriptor);
639: for (Iterator lCategoryNamePropertiesIterator = lAllCategoryNames
640: .iterator(); lCategoryNamePropertiesIterator.hasNext();) {
641: Property lProperty = (Property) lCategoryNamePropertiesIterator
642: .next();
643: if (lDesiredCategoryNames.contains(lProperty.getValue())) {
644: // Ensure that this category has this value
645: Property lCategoryProperty = lProperty
646: .getParentProperty();
647: Collection lAllCategoryValueNames = lCategoryProperty
648: .getPropertiesByDescriptor(mCategoryValueNamePropertyDescriptor);
649: Property lValueNameProperty = null;
650: for (Iterator lCategoryValueNamePropertiesIterator = lAllCategoryValueNames
651: .iterator(); lCategoryValueNamePropertiesIterator
652: .hasNext();) {
653: Property lCategoryValueNameProperty = (Property) lCategoryValueNamePropertiesIterator
654: .next();
655: if (pValueName.equals(lCategoryValueNameProperty
656: .getValue())) {
657: lValueNameProperty = lCategoryValueNameProperty;
658: break;
659: }
660: }
661: if (lValueNameProperty != null) {
662: mUnusedProperties.remove(lValueNameProperty);
663: mUnusedProperties.removeAll(lValueNameProperty
664: .getCombinedProperties());
665: lValueNameProperty.refDelete();
666: }
667: }
668: }
669: }
670: }
|