@Override public int hashCode() { int result = superClassGroup != null ? superClassGroup.hashCode() : 0; for (String attribute : getItems().keySet()) { // avoid processing values in getItems map to avoid infinite recursion // as ATTRIBUTE_ITEM.hashCode() calls group.hashCode() result = 31 * result + attribute.hashCode(); } return 31 * result; }
/** * INTERNAL: This method will insert the group into the entity hierarchy just below this * AttributeGroup. * * @param group */ public void insertSubClass(CoreAttributeGroup group) { if (this == group) { return; } group.superClassGroup = this; if (subClasses != null) { for (Iterator<CoreAttributeGroup> subClasses = this.subClasses.iterator(); subClasses.hasNext(); ) { CoreAttributeGroup subClass = subClasses.next(); if (group != subClass && group.getType().isAssignableFrom(subClass.getType())) { group.subClasses.add(subClass); subClass.superClassGroup = group; subClasses.remove(); } } } else { this.subClasses = new HashSet<CoreAttributeGroup>(); } this.subClasses.add(group); }
@Override public boolean equals(Object obj) { if (this != obj) { if (obj == null) { return false; } CoreAttributeGroup anotherGroup = null; try { anotherGroup = (CoreAttributeGroup) obj; } catch (ClassCastException cce) { return false; } if (hasItems()) { if (anotherGroup.hasItems()) { if (!getItems().equals(anotherGroup.getItems())) { return false; } } else { return false; } } else { if (anotherGroup.hasItems()) { return false; } } if (this.superClassGroup != null) { if (anotherGroup.superClassGroup != null) { return this.superClassGroup.equals(anotherGroup.superClassGroup); } else { return false; } } else { if (anotherGroup.superClassGroup != null) { return false; } return true; } } else { return true; } }
/** * INTERNAL: Convert all the class-name-based settings in this Descriptor to actual class-based * settings. This method is used when converting a project that has been built with class names to * a project with classes. * * @param classLoader */ public void convertClassNamesToClasses(ClassLoader classLoader) { if (this.type == null) { try { if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) { try { this.type = AccessController.doPrivileged( new PrivilegedClassForName(this.typeName, true, classLoader)); } catch (PrivilegedActionException exception) { throw ValidationException.classNotFoundWhileConvertingClassNames( this.typeName, exception.getException()); } } else { this.type = org.eclipse.persistence.internal.security.PrivilegedAccessHelper.getClassForName( this.typeName, true, classLoader); } } catch (ClassNotFoundException exc) { throw ValidationException.classNotFoundWhileConvertingClassNames(this.typeName, exc); } if (this.items != null) { for (ATTRIBUTE_ITEM item : this.items.values()) { item.convertClassNamesToClasses(classLoader); } } if (this.allsubclasses != null) { Map<Object, CoreAttributeGroup> allGroups = new HashMap<Object, CoreAttributeGroup>(); this.subClasses = new HashSet<CoreAttributeGroup>(); for (CoreAttributeGroup subClass : allsubclasses.values()) { subClass.convertClassNamesToClasses(classLoader); allGroups.put(subClass.getType(), subClass); } this.allsubclasses = allGroups; for (CoreAttributeGroup subClass : allsubclasses.values()) { if (CoreAttributeItem.orderInheritance(subClass, allGroups)) { this.insertSubClass(subClass); } } } } }
/** * Locate the AttributeGroup where the leaf attribute in the path should be applied to. * * @param create indicates if intermediate AttributeGroup required within the specified path * should be created as needed. When checking the state of the map callers should set this to * false to avoid changing the state unexpectedly */ protected ATTRIBUTE_ITEM getItem(String[] attributePath, boolean create) { ATTRIBUTE_ITEM item = null; CoreAttributeGroup<ATTRIBUTE_ITEM, DESCRIPTOR> currentGroup = this; for (int index = 0; index < attributePath.length; index++) { String attrName = attributePath[index]; item = currentGroup.getItems().get(attrName); // Add missing AttributeGroup if (item == null) { // If not creating missing AttributeGroups then return null if (!create) { if (this.superClassGroup != null) { return (ATTRIBUTE_ITEM) this.superClassGroup.getItem(attributePath, create); } return null; } item = (ATTRIBUTE_ITEM) newItem(currentGroup, attrName); currentGroup.getItems().put(attrName, item); } // Add a AttributeGroup if not at the end of the attributes path if (item.getGroup() == null && index < (attributePath.length - 1)) { if (!create) { return null; } // XXX-dclarke: Converting the attribute[] into a string and then re-parsing it seems odd CoreAttributeGroup newGroup = newGroup(attrName, currentGroup); item.setRootGroup(newGroup); } currentGroup = item.getGroup(); } return item; }
/** Return true if this AttributeGroup is a super-set of the passed in AttributeGroup. */ public boolean isSupersetOf(CoreAttributeGroup<ATTRIBUTE_ITEM, DESCRIPTOR> anotherGroup) { // TODO: should handle the case when the current group has all // attributes - then its equivalent to null if (anotherGroup == null) { return false; } if (anotherGroup != this) { if (hasItems()) { if (anotherGroup.hasItems()) { Iterator<Map.Entry<String, ATTRIBUTE_ITEM>> otherItemEntries = anotherGroup.getItems().entrySet().iterator(); while (otherItemEntries.hasNext()) { Map.Entry<String, ATTRIBUTE_ITEM> otherItemEntry = otherItemEntries.next(); String otherAttributeName = otherItemEntry.getKey(); CoreAttributeItem item = this.items.get(otherAttributeName); if (item == null) { return false; } CoreAttributeGroup<ATTRIBUTE_ITEM, DESCRIPTOR> group = item.getGroup(); CoreAttributeGroup<ATTRIBUTE_ITEM, DESCRIPTOR> otherGroup = otherItemEntry.getValue().getGroup(); if (group != null) { if (!group.isSupersetOf(otherGroup)) { return false; } } else { if (otherGroup != null) { return true; } } group = item.getKeyGroup(); otherGroup = otherItemEntry.getValue().getKeyGroup(); if (group != null) { if (!group.isSupersetOf(otherGroup)) { return false; } } else { if (otherGroup != null) { return true; } } if (item.getGroups() != null) { if (otherItemEntry.getValue().getGroups() == null) { return true; } for (Object next : item.getGroups().values()) { CoreAttributeGroup<ATTRIBUTE_ITEM, DESCRIPTOR> element = (CoreAttributeGroup<ATTRIBUTE_ITEM, DESCRIPTOR>) next; CoreAttributeGroup<ATTRIBUTE_ITEM, DESCRIPTOR> otherElement = (CoreAttributeGroup<ATTRIBUTE_ITEM, DESCRIPTOR>) otherItemEntry.getValue().getGroups().get(element.getType()); if (!element.isSupersetOf(otherElement)) { return false; } } } if (item.getKeyGroups() != null) { if (otherItemEntry.getValue().getKeyGroups() == null) { return true; } for (Object next : item.getKeyGroups().values()) { CoreAttributeGroup element = (CoreAttributeGroup) next; CoreAttributeGroup otherElement = (CoreAttributeGroup) otherItemEntry.getValue().getKeyGroups().get(element.getType()); if (!element.isSupersetOf(otherElement)) { return false; } } } } return true; } else { return true; } } else { if (anotherGroup.hasItems()) { return false; } else { return true; } } } else { return true; } }
/** * INTERNAL: This method is used internally in the clone processing. * * @param cloneMap * @return */ public CoreAttributeGroup clone( Map< CoreAttributeGroup<ATTRIBUTE_ITEM, DESCRIPTOR>, CoreAttributeGroup<ATTRIBUTE_ITEM, DESCRIPTOR>> cloneMap) { CoreAttributeGroup clone = cloneMap.get(this); if (clone != null) { return clone; } try { clone = (CoreAttributeGroup) super.clone(); } catch (CloneNotSupportedException e) { throw new AssertionError(e); } clone.name = this.name; clone.type = this.type; clone.typeName = this.typeName; clone.isValidated = this.isValidated; cloneMap.put(this, clone); if (this.allsubclasses != null) { for (CoreAttributeGroup group : this.allsubclasses.values()) { clone.getSubClassGroups().put(group.getType(), group.clone(cloneMap)); } } if (this.superClassGroup != null) { clone.superClassGroup = this.superClassGroup.clone(cloneMap); } if (this.subClasses != null) { clone.subClasses = new HashSet<CoreAttributeGroup>(); for (CoreAttributeGroup group : this.subClasses) { clone.subClasses.add(group.clone(cloneMap)); } } // all attributes and nested groups should be cloned, too clone.items = null; if (hasItems()) { clone.items = new HashMap<String, ATTRIBUTE_ITEM>(); for (ATTRIBUTE_ITEM item : this.items.values()) { clone.items.put(item.getAttributeName(), item.clone(cloneMap, clone)); } } return clone; }