Java tutorial
/* * Modelibra * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package org.modelibra; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Observable; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.modelibra.action.EntityAction; import org.modelibra.config.CombinationConfig; import org.modelibra.config.ConceptConfig; import org.modelibra.config.ModelConfig; import org.modelibra.config.NeighborConfig; import org.modelibra.config.NeighborsConfig; import org.modelibra.config.PropertyConfig; import org.modelibra.exception.ActionRuntimeException; import org.modelibra.exception.ConfigRuntimeException; import org.modelibra.exception.ModelibraRuntimeException; /** * <p> * Entity abstract class to implement common characteristics of all concepts. * </p> * * <p> * Each entity has oid and code properties. The oid property is generated by * Modelibra. The oid property cannot be configured. If you do not want to use * the code property, do not configure it. * </p> * * <p> * An entity may have a user defined id (unique combination) that can be simple * or composite. It may contain propertie and/or neighbors. The id is configured * by marking properties and/or neighbors with the unique configuration element * set to true. * </p> * * @author Dzenan Ridjanovic * @author Vedad Kirlic * @version 2009-02-22 */ @SuppressWarnings("serial") public abstract class Entity<T extends IEntity<T>> extends Observable implements IEntity<T> { private static Log log = LogFactory.getLog(Entity.class); private IDomainModel model; private ConceptConfig conceptConfig; private Oid oid; private String code; private UniqueCombination uniqueCombination; private IndexCombination indexCombination; /** * Constructs an entity without the domain model and concept configuration. * Used only in configuration classes. */ public Entity() { } /** * Constructs an entity within the given domain model. * * @param model * domain model */ public Entity(IDomainModel model) { this.model = model; if (model == null) { String msg = "Entity.constructor -- model is null."; throw new ModelibraRuntimeException(msg); } ModelConfig modelConfig = model.getModelConfig(); String conceptCode = getClass().getSimpleName(); conceptConfig = model.getModelConfig().getConceptConfig(conceptCode); if (conceptConfig == null) { String msg = "Entity.constructor -- concept code is not valid: " + modelConfig.getDomainConfig().getCode() + "." + modelConfig.getCode() + "." + conceptCode; throw new ConfigRuntimeException(msg); } setOid(new Oid()); } /** * Sets the entity domain model. * * @param model * domain model */ public void setModel(IDomainModel model) { String conceptCode = getClass().getSimpleName(); ConceptConfig conceptConfig = model.getModelConfig().getConceptConfig(conceptCode); if (conceptConfig != null) { this.model = model; this.conceptConfig = conceptConfig; List<String> internalChildNeighborCodes = getConceptConfig().getInternalChildNeighborCodes(); for (String code : internalChildNeighborCodes) { Entities<?> internalChildNeghbor = (Entities<?>) getChildNeighbor(code); internalChildNeghbor.setModel(model); } } else { String msg = "Entity.setModel -- concept code is not valid: " + model.getModelConfig().getDomainConfig().getCode() + "." + model.getModelConfig().getCode() + "." + conceptCode; throw new ConfigRuntimeException(msg); } } /** * Gets the model. * * @return model */ public IDomainModel getModel() { return model; } /** * Gets the concept configuration. * * @return concept configuration */ public ConceptConfig getConceptConfig() { return conceptConfig; } /** * Sets the oid. * * @param oid * oid */ public void setOid(Oid oid) { this.oid = oid; } /** * Gets the oid. * * @return the oid */ public Oid getOid() { return oid; } /** * Sets the code. * * @param code * code */ public void setCode(String code) { this.code = code; } /** * Gets the code. * * @return code */ public String getCode() { return code; } /** * Derives the entity unique combination (id) using the concept's unique * configuration. * * @return unique combination */ public UniqueCombination getUniqueCombination() { uniqueCombination = new UniqueCombination(); ConceptConfig conceptConfig = getConceptConfig(); CombinationConfig idConfig = conceptConfig.getUniqueConfig(); if (idConfig.isNotEmpty()) { if (!idConfig.isPropertyEmpty()) { for (String propertyCode : idConfig.getPropertyCodeList()) { Object property = getProperty(propertyCode); if (property != null) { uniqueCombination.addProperty(propertyCode, property); } } } if (!idConfig.isNeighborEmpty()) { for (String neighborCode : idConfig.getNeighborCodeList()) { IEntity<?> neighbor = (IEntity<?>) getParentNeighbor(neighborCode); if (neighbor != null) { uniqueCombination.addNeighbor(neighborCode, neighbor); } } } if (uniqueCombination.isEmpty()) { String msg = "Entity.getUniqueCombination -- concept has an empty unique combination: " + model.getModelConfig().getDomainConfig().getCode() + "." + model.getModelConfig().getCode() + "." + conceptConfig.getCode(); throw new ConfigRuntimeException(msg); } } return uniqueCombination; } /** * Derives the entity index combination using the concept index * configuration. * * @return entity index combination */ public IndexCombination getIndexCombination() { indexCombination = new IndexCombination(); ConceptConfig conceptConfig = getConceptConfig(); CombinationConfig ixConfig = conceptConfig.getIndexConfig(); if (ixConfig.isNotEmpty()) { if (!ixConfig.isPropertyEmpty()) { for (String propertyCode : ixConfig.getPropertyCodeList()) { Object property = getProperty(propertyCode); if (property != null) { indexCombination.addProperty(propertyCode, property); } } } if (!ixConfig.isNeighborEmpty()) { for (String neighborCode : ixConfig.getNeighborCodeList()) { IEntity<?> neighbor = (IEntity<?>) getParentNeighbor(neighborCode); if (neighbor != null) { indexCombination.addNeighbor(neighborCode, neighbor); } } } if (indexCombination.isEmpty()) { String msg = "Entity.getIndexCombination -- concept has an empty index combination: " + model.getModelConfig().getDomainConfig().getCode() + "." + model.getModelConfig().getCode() + "." + conceptConfig.getCode(); throw new ConfigRuntimeException(msg); } } return indexCombination; } /** * Sets the entity property given a property code. Meta handling is used. * * @param propertyCode * property code * @param propertyValue * property value */ public void setProperty(String propertyCode, Object propertyValue) { if (propertyCode.equals("oid")) { Oid oid = (Oid) propertyValue; setOid(oid); } else if (propertyCode.equals("code")) { String code = (String) propertyValue; setCode(code); } else { DomainModel model = (DomainModel) getModel(); if (model != null) { ModelMeta modelMeta = model.getModelMeta(); modelMeta.setProperty(this, propertyCode, propertyValue); } } } /** * Gets the entity property given a property code. Meta handling is used. * * @param propertyCode * property code * @return property */ public Object getProperty(String propertyCode) { Object property = null; if (propertyCode.equals("oid")) { property = this.getOid(); } else if (propertyCode.equals("code")) { property = this.getCode(); } else { DomainModel model = (DomainModel) getModel(); if (model != null) { ModelMeta modelMeta = model.getModelMeta(); property = modelMeta.getProperty(this, propertyCode); } } return property; } /** * Sets the entity neighbor object given a neighbor code. Meta handling is * used. * * @param neighborCode * neighbor code * @param neighbor * neighbor object */ public void setNeighbor(String neighborCode, Object neighbor) { DomainModel model = (DomainModel) getModel(); if (model != null) { ModelMeta modelMeta = model.getModelMeta(); modelMeta.setNeighbor(this, neighborCode, neighbor); } } /** * Gets the entity neighbor object given a neighbor code. Meta handling is * used. * * @param neighborCode * neighbor code * @return neighbor object */ public Object getNeighbor(String neighborCode) { Object neighbor = null; DomainModel model = (DomainModel) getModel(); if (model != null) { ModelMeta modelMeta = model.getModelMeta(); neighbor = modelMeta.getNeighbor(this, neighborCode); } return neighbor; } /** * Sets the parent entity neighbor given a neighbor code. Meta handling is * used. * * @param neighborCode * neighbor code * @param neighborEntity * neighbor entity */ public void setParentNeighbor(String neighborCode, IEntity<? extends IEntity<?>> neighborEntity) { DomainModel model = (DomainModel) getModel(); if (model != null) { ModelMeta modelMeta = model.getModelMeta(); modelMeta.setParentNeighbor(this, neighborCode, neighborEntity); } } /** * Gets the parent neighbor given a neighbor code. Meta handling is used. * * @param neighborCode * neighbor code * @return neighbor entity */ public IEntity<?> getParentNeighbor(String neighborCode) { IEntity<?> neighborEntity = null; DomainModel model = (DomainModel) getModel(); if (model != null) { ModelMeta modelMeta = model.getModelMeta(); neighborEntity = modelMeta.getParentNeighbor(this, neighborCode); } return neighborEntity; } /** * Sets the child entity neighbor given a neighbor code. Meta handling is * used. * * @param neighborCode * neighbor code * @param neighborEntities * neighbor entities */ public void setChildNeighbor(String neighborCode, IEntities<?> neighborEntities) { DomainModel model = (DomainModel) getModel(); if (model != null) { ModelMeta modelMeta = model.getModelMeta(); modelMeta.setChildNeighbor(this, neighborCode, neighborEntities); } } /** * Gets the child entity neighbor given a neighbor code. Meta handling is * used. * * @param neighborCode * neighbor code * @return neighbor entities */ public IEntities<?> getChildNeighbor(String neighborCode) { IEntities<?> neighborEntities = null; DomainModel model = (DomainModel) getModel(); if (model != null) { ModelMeta modelMeta = model.getModelMeta(); neighborEntities = modelMeta.getChildNeighbor(this, neighborCode); } return neighborEntities; } /** * Updates the entity with the given entity. * * @param entity * entity * @return <code>true</code> if the entity is updated with the given entity */ public boolean update(T entity) { return update(entity, true); } /** * Updates the entity with a given entity. Meta handling is used. Action * notification is not used. Instead, the update action on entities is used * to undo the action. * * @param entity * entity * @param updateSensitive * <code>true</code> if the sensitive information will be updated * @return <code>true</code> if the entity is updated with a given entity */ public boolean update(T entity, boolean updateSensitive) { boolean updated = false; EntityAction entityAction = new EntityAction(); entityAction.setEntity(this); entityAction.setParameter(entity); if (this == entity) { String msg = "Entity.update -- before update entity and after update entity cannot be the same object."; log.info(msg); ((Entity<?>) entity).output("Update"); throw new ActionRuntimeException(msg); } DomainModel model = (DomainModel) getModel(); if (model != null) { ModelMeta modelMeta = model.getModelMeta(); updated = modelMeta.update(this, entity, updateSensitive); } else { } return updated; } /** * Updates only the properties of the entity with a given entity. * * @param entity * entity * @return <code>true</code> if the entity is updated with a given entity */ public boolean updateProperties(T entity) { return updateProperties(entity, true); } /** * Updates only the properties of the entity with a given entity. Meta * handling is used. Action notification is not used. Instead, the update * action on entities is used to undo the action. * * @param entity * entity * @param updateSensitive * <code>true</code> if the sensitive properties will be updated * @return <code>true</code> if the entity is updated with a given entity */ public boolean updateProperties(T entity, boolean updateSensitive) { boolean updated = false; EntityAction entityAction = new EntityAction(); entityAction.setEntity(this); entityAction.setParameter(entity); if (this == entity) { String msg = "Entity.updateProperties -- before update entity and after update entity cannot be the same object."; log.info(msg); ((Entity<?>) entity).output("Update properties"); throw new ActionRuntimeException(msg); } DomainModel model = (DomainModel) getModel(); if (model != null) { ModelMeta modelMeta = model.getModelMeta(); updated = modelMeta.updateProperties(this, entity, updateSensitive); } else { } return updated; } /** * Checks if the entity satisfies the selector. * * @param selector * selector * @return <code>true</code> if the entity satisfies the selector */ public boolean isSelected(ISelector selector) { boolean selected = false; if (selector instanceof PropertySelector) { PropertySelector propertySelector = (PropertySelector) selector; return isSelected(propertySelector); } else if (selector instanceof ParentNeighborSelector) { ParentNeighborSelector parentNeighborSelector = (ParentNeighborSelector) selector; return isSelected(parentNeighborSelector); } else if (selector instanceof CompositeSelector) { CompositeSelector compositeSelector = (CompositeSelector) selector; return isSelected(compositeSelector); } return selected; } /** * Checks if the entity satisfies the property selector. * * @param propertySelector * property selector * @return <code>true</code> if the entity satisfies the property selector */ private boolean isSelected(PropertySelector propertySelector) { boolean selected = false; String relationalOperator = propertySelector.getRelationalOperator(); String propertyCode = propertySelector.getPropertyCode(); Object value = propertySelector.getValue(); if (relationalOperator.equals(PropertySelector.ALL)) { selected = true; } else { Object property = getProperty(propertyCode); if (property == null) { if (relationalOperator.equals(PropertySelector.NULL)) { selected = true; } } else { Object[] values = propertySelector.getValues(); if ((property instanceof String) && (value instanceof String) && !propertySelector.isCaseSensitive()) { property = ((String) property).toLowerCase(); value = new String(((String) value).toLowerCase()); String[] lowerCaseValues = new String[values.length]; for (int i = 0; i < values.length; i++) { lowerCaseValues[i] = new String(((String) values[i]).toLowerCase()); } values = lowerCaseValues; } if (relationalOperator.equals(PropertySelector.EQUAL)) { if (property.equals(value)) { selected = true; } } else if (relationalOperator.equals(PropertySelector.CONTAIN)) { if ((property instanceof String) && (value instanceof String)) { String p = (String) property; String s = (String) value; if (p.contains(s)) { selected = true; } } else if (property instanceof Collection) { Collection<?> p = (Collection<?>) property; if (p.contains(value)) { selected = true; } } } else if (relationalOperator.equals(PropertySelector.CONTAIN_SOME)) { // Object[] values = propertySelector.getValues(); if ((property instanceof String) && (values instanceof String[])) { String p = (String) property; String[] ps = (String[]) values; boolean isSome = false; for (String criteriaValue : ps) { if (p.contains(criteriaValue)) { isSome = true; break; } } if (isSome) { selected = true; } } else if (property instanceof Collection) { Collection<?> p = (Collection<?>) property; boolean isSome = false; for (Object criteriaValue : values) { if (p.contains(criteriaValue)) { isSome = true; break; } } if (isSome) { selected = true; } } } else if (relationalOperator.equals(PropertySelector.CONTAIN_ALL)) { // Object[] values = propertySelector.getValues(); if ((property instanceof String) && (values instanceof String[])) { String p = (String) property; String[] ps = (String[]) values; boolean isAll = true; for (String criteriaValue : ps) { if (!p.contains(criteriaValue)) { isAll = false; break; } } if (isAll) { selected = true; } } else if (property instanceof Collection) { Collection<?> p = (Collection<?>) property; boolean isAll = true; for (Object criteriaValue : values) { if (!p.contains(criteriaValue)) { isAll = false; break; } } if (isAll) { selected = true; } } } else if (relationalOperator.equals(PropertySelector.BEGIN)) { if ((property instanceof String) && (value instanceof String)) { String p = (String) property; String s = (String) value; if (p.startsWith(s)) { selected = true; } } } else if (relationalOperator.equals(PropertySelector.END)) { if ((property instanceof String) && (value instanceof String)) { String p = (String) property; String s = (String) value; if (p.endsWith(s)) { selected = true; } } } else if (relationalOperator.equals(PropertySelector.MATCH)) { if ((property instanceof String) && (value instanceof String)) { String p = (String) property; String s = (String) value; if (p.matches(s)) { selected = true; } } } else if (relationalOperator.equals(PropertySelector.IN)) { // Object[] values = propertySelector.getValues(); boolean isIn = false; for (Object criteriaValue : values) { if (property.equals(criteriaValue)) { isIn = true; break; } } if (isIn) { selected = true; } } else if (relationalOperator.equals(PropertySelector.LESS_THAN)) { if (property instanceof Comparable) { Comparable p = (Comparable) property; if (p.compareTo(value) < 0) { selected = true; } } } else if (relationalOperator.equals(PropertySelector.LESS_EQUAL)) { if (property instanceof Comparable) { Comparable p = (Comparable) property; if (p.compareTo(value) <= 0) { selected = true; } } } else if (relationalOperator.equals(PropertySelector.GREATER_THAN)) { if (property instanceof Comparable) { Comparable p = (Comparable) property; if (p.compareTo(value) > 0) { selected = true; } } } else if (relationalOperator.equals(PropertySelector.GREATER_EQUAL)) { if (property instanceof Comparable) { Comparable p = (Comparable) property; if (p.compareTo(value) >= 0) { selected = true; } } } else if (relationalOperator.equals(PropertySelector.BETWEEN)) { Object[] borders = propertySelector.getValues(); Object min = borders[0]; Object max = borders[1]; if (property instanceof Comparable) { Comparable p = (Comparable) property; if ((p.compareTo(min) >= 0) && (p.compareTo(max) <= 0)) { selected = true; } } } } // property != null } // selection criteria different form NONE and ALL return selected; } /** * Checks if the entity satisfies the parent neighbor selector. * * @param parentNeighborSelector * parent neighbor selector * @return <code>true</code> if the entity satisfies the parent neighbor * selector */ private boolean isSelected(ParentNeighborSelector parentNeighborSelector) { String parentNeighborCode = parentNeighborSelector.getParentNeighborCode(); IEntity<?> parentNeighbor = getParentNeighbor(parentNeighborCode); PropertySelector parentNeighborPropertySelector = parentNeighborSelector .getParentNeighborPropertySelector(); return parentNeighbor.isSelected(parentNeighborPropertySelector); } /** * Checks if the entity satisfies the composite selector. * * @param compositeSelector * composite selector * @return <code>true</code> if the entity satisfies the composite selector */ private boolean isSelected(CompositeSelector compositeSelector) { String logicalOperator = compositeSelector.getLogicalOperator(); ISelector leftSelector = compositeSelector.getLeftSelector(); ISelector rightSelector = compositeSelector.getRightSelector(); if (logicalOperator.equals(ISelector.NOT)) { return !isSelected(leftSelector); } else if (logicalOperator.equals(ISelector.AND)) { return isSelected(leftSelector) && isSelected(rightSelector); } else if (logicalOperator.equals(ISelector.OR)) { return isSelected(leftSelector) || isSelected(rightSelector); } return false; } /** * Copies the entity (properties and parent neighbors). * * @return copied entity */ public T copy() { return copy(true); } /** * Copies the entity. Meta handling is used. * * @param copySensitive * <code>true</code> if the sensitive information will be copied * @return copied entity */ public T copy(boolean copySensitive) { T copiedEntity = null; DomainModel model = (DomainModel) getModel(); if (model != null && getConceptConfig() != null) { ModelMeta modelMeta = model.getModelMeta(); copiedEntity = modelMeta.createEntity(this); if (copiedEntity != null) { copiedEntity.setOid(getOid()); ((Entity<T>) copiedEntity).update((T) this, copySensitive); } } return copiedEntity; } /** * Copies the entity by copying the whole internal tree with the entity as * the root. The copied entity may be a part of another model. * * @param model * another model * @return deep copied entity */ public T deepCopy(IDomainModel model) { return deepCopy(model, true); } /** * Copies the entity by copying the whole internal tree with the entity as * the root. The copied entity may be a part of another model. Meta handling * is used. * * @param model * another model * @param copySensitive * <code>true</code> if the sensitive information will be copied * @return deep copied entity */ public T deepCopy(IDomainModel model, boolean copySensitive) { T copiedEntity = null; if (getConceptConfig() != null) { if (model != null) { DomainModel anotherModel = (DomainModel) model; ModelMeta modelMeta = anotherModel.getModelMeta(); copiedEntity = modelMeta.createEntity(this); if (copiedEntity != null) { copiedEntity.setOid(getOid()); ((Entity<T>) copiedEntity).updateProperties((T) this, copySensitive); // reference properties (parentOid) ARE properties // modelMeta.setExternalParentsByOids(copiedEntity, // this); NeighborsConfig neighborsConfig = getConceptConfig().getNeighborsConfig(); for (NeighborConfig neighborConfig : neighborsConfig) { if (neighborConfig.isInternal() && neighborConfig.isChild()) { String neighborCode = neighborConfig.getCode(); Entities baseEntityNeighborEntities = (Entities) getChildNeighbor(neighborCode); IEntities copiedNeighborEntities = baseEntityNeighborEntities.deepCopy(model, copySensitive); copiedEntity.setChildNeighbor(neighborCode, copiedNeighborEntities); } } } } } return copiedEntity; } /** * Copies only the properties of the entity. * * @return copied entity */ public T copyProperties() { return copyProperties(true); } /** * Copies only the properties of the entity. Meta handling is used. * * @param copySensitive * <code>true</code> if the sensitive properties will be copied * @return copied entity */ public T copyProperties(boolean copySensitive) { T copiedEntity = null; if (getConceptConfig() != null) { DomainModel model = (DomainModel) getModel(); if (model != null) { ModelMeta modelMeta = model.getModelMeta(); copiedEntity = modelMeta.createEntity(this); if (copiedEntity != null) { copiedEntity.setOid(getOid()); Entity<T> entity = (Entity<T>) copiedEntity; entity.updateProperties((T) this, copySensitive); } } } return copiedEntity; } /** * Synchronizes the returned entitiy with the base entity. The returned * entity is a new version of the taken entity. * * @param takenEntity * taken entity * @param returnedEntity * returned entity * @param synchronizeSensitive * <code>true</code> if the sensitive information will be * synchronized */ public void synchronize(T takenEntity, T returnedEntity, boolean synchronizeSensitive) { // To be synchronized property by property and neighbor by neighbor // (parent by parent?). // If there is a difference between the base entity and the takenEntity, // the base entity wins. String msg = "Entity.synchronize -- not yet developed."; throw new ModelibraRuntimeException(msg); } /** * Checks if the entity has the same content (properties and neighbors) as * the given entity. * * @param entity * entity * @return <code>true</code> if the entity has the same content as the given * entity */ public boolean equalContent(T entity) { boolean equal = equalProperties(entity); if (equal) { equal = equalNeighbors(entity); } return equal; } /** * Checks if the entity has the same properties as the given entity. Meta * handling is used. * * @param entity * entity * @return <code>true</code> if the entity has the same properties as the * given entity */ public boolean equalProperties(T entity) { boolean equal = false; DomainModel model = (DomainModel) getModel(); if (model != null) { ModelMeta modelMeta = model.getModelMeta(); equal = modelMeta.equalProperties(this, entity); } return equal; } /** * Checks if the entity has the same neighbors as the given entity. * * @param entity * entity * @return <code>true</code> if the entity has the same neighbors as the * given entity */ public boolean equalNeighbors(T entity) { boolean equal = equalParentNeighbors(entity); if (equal) { equal = equalChildNeighbors(entity); } return equal; } /** * Checks if the entity has the same parent neighbors as the given entity. * Meta handling is used. * * @param entity * entity * @return <code>true</code> if the entity has the same parent neighbors as * the given entity */ public boolean equalParentNeighbors(T entity) { boolean equal = false; DomainModel model = (DomainModel) getModel(); if (model != null) { ModelMeta modelMeta = model.getModelMeta(); equal = modelMeta.equalParentNeighbors(this, entity); } return equal; } /** * Checks if the entity has the same child neighbors as the given entity. * Meta handling is used. * * @param entity * entity * @return <code>true</code> if the entity has the same child neighbors as * the given entity */ public boolean equalChildNeighbors(T entity) { boolean equal = false; DomainModel model = (DomainModel) getModel(); if (model != null) { ModelMeta modelMeta = model.getModelMeta(); equal = modelMeta.equalChildNeighbors(this, entity); } return equal; } /** * Checks if the entity has the same oid as the given entity. Used in the * overriden implementation of the equals method. * * @param entity * entity * @return <code>true</code> if the entity has the same oid as the given * entity */ public boolean equalOid(T entity) { boolean equal = false; if (entity == null) { equal = false; } else if (entity == this) { equal = true; } else if (getOid() != null && getOid().equals(entity.getOid())) { equal = true; } else { equal = false; } return equal; } /** * Checks if the entity has the same unique combination (id) as the given * entity. * * @param entity * entity * @return <code>true</code> if the entity has the same unique combination * (id) as the given entity */ public boolean equalUnique(T entity) { boolean equal = true; if (entity == null) { equal = false; } else if (entity == this) { equal = true; } else { UniqueCombination idLeft = getUniqueCombination(); UniqueCombination idRight = entity.getUniqueCombination(); if (idLeft != null && idRight != null) { if (idLeft.size() == idRight.size()) { for (String propertyCode : idLeft.getPropertyCodeList()) { Object propertyLeft = idLeft.getProperty(propertyCode); Object propertyRight = idRight.getProperty(propertyCode); if (!propertyLeft.equals(propertyRight)) { equal = false; break; } } for (String neighborCode : idLeft.getNeighborCodeList()) { IEntity<?> neighborLeft = idLeft.getNeighbor(neighborCode); IEntity<?> neighborRight = idRight.getNeighbor(neighborCode); if (neighborLeft != null && neighborRight != null && !neighborLeft.equals(neighborRight)) { equal = false; break; } } } else { equal = false; } } else { equal = false; } } return equal; } /** * Checks if the entity is equal to the given object. If the given object is * not of the IEntity type, two objects cannot be equal. Two entities are * equal if they have the same oid. * * @param object * object * @return <code>true</code> if the entity is equal to the given object. */ @Override public boolean equals(Object object) { boolean equal = false; if (object == null) { equal = false; } else if (object == this) { equal = true; } else if (object instanceof IEntity) { IEntity<?> entity = (IEntity<?>) object; equal = equalOid((T) entity); } else { equal = false; } return equal; } /** * Two entity objects that have the same oids will have the same hash code. */ @Override public int hashCode() { return oid.hashCode(); } /** * Outputs entity. Used in testing. Meta handling is used. * * @param title * title */ public void output(String title) { DomainModel model = (DomainModel) getModel(); if (model != null) { ModelMeta modelMeta = model.getModelMeta(); modelMeta.output(this, title); } } /** * Returns a string that represents this entity by using properties and/or * neighbors from unique combination (id). If there is no id set, entity oid * is returned. * * @return entity as a string */ @Override public String toString() { StringBuffer v = new StringBuffer(); CombinationConfig uniqueConfig = getConceptConfig().getUniqueConfig(); Iterator<String> neighborCodeListIterator = uniqueConfig.getNeighborCodeList().iterator(); while (neighborCodeListIterator.hasNext()) { v.append(getNeighbor(neighborCodeListIterator.next())); if (neighborCodeListIterator.hasNext()) { v.append(", "); } } Iterator<String> propertyCodeListIterator = uniqueConfig.getPropertyCodeList().iterator(); if (v.length() > 0 && propertyCodeListIterator.hasNext()) { v.append(" - "); } while (propertyCodeListIterator.hasNext()) { v.append(getProperty(propertyCodeListIterator.next())); if (propertyCodeListIterator.hasNext()) { v.append(", "); } } return v.length() == 0 ? oid.toString() : v.toString(); } /** * Returns a string that represents this entity by using strings of * essential properties. If there are no essential properties toString() * invoked. * * @return entity as a string of essential property string values */ public String toEssentialPropertiesString() { String essentialPropertiesString = ""; List<PropertyConfig> essentialPropertyConfigList = getConceptConfig().getPropertiesConfig() .getEssentialPropertyConfigList(); if (essentialPropertyConfigList.isEmpty()) { essentialPropertiesString = toString(); } else { for (PropertyConfig essentialPropertyConfig : essentialPropertyConfigList) { Object parentProperty = getProperty(essentialPropertyConfig.getCode()); if (parentProperty != null) { essentialPropertiesString = essentialPropertiesString + parentProperty.toString() + " "; } else { essentialPropertiesString = toString(); } } } return essentialPropertiesString; } /** * Compares two entities based on oids. If the result is less than 0 then * the first entity is less than the second, if it is equal to 0 they are * equal and if the result is greater than 0 then the first is greater than * the second. * * @return compare integer */ public int compareTo(T entity) { int result = oid.compareTo(entity.getOid()); return result; } /** * Notifies observes. * * @param arg * arg */ @Override public void notifyObservers(Object arg) { this.setChanged(); super.notifyObservers(arg); } }