Mercurial > hg > openmind
view src/main/java/org/mpi/openmind/repository/bo/Entity.java @ 56:467843399e70
Fixs for lost relation, when editing clone entities in parallel
author | jurzua <jjjurzua@hotmail.com> |
---|---|
date | Mon, 28 Nov 2016 14:26:10 +0100 |
parents | 5bf964077567 |
children | 83b209aa4226 |
line wrap: on
line source
package org.mpi.openmind.repository.bo; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import javax.persistence.DiscriminatorValue; import javax.persistence.Transient; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; import org.mpi.openmind.cache.WrapperService; import org.mpi.openmind.repository.utils.AttributeMap; import org.mpi.openmind.repository.utils.OMUtils; import cl.maps.duplex.DuplexKey; /** * * @author jurzua */ /** * @author casties * */ @javax.persistence.Entity @DiscriminatorValue("ENTITY") @Cache(usage=CacheConcurrencyStrategy.READ_ONLY) public class Entity extends Node implements Serializable, Cloneable, Comparable<Entity> { private static final long serialVersionUID = 3498561370603862745L; private static Logger logger = Logger.getLogger(Entity.class); public Entity() { } /** * * @param type could be either Node.TYPE_ABOX (for assertions) or Node.TYPE_TBOX (for definitions). * @param lightweight */ public Entity(String type, Boolean lightweight) { if(StringUtils.isEmpty(type) || (!Node.TYPE_ABOX.equals(type) && !Node.TYPE_TBOX.equals(type))){ try { throw new Exception("Creating a Entity. Type=" + type + " is invalid. Type could be either ABOX (for assertions) or TBOX (for definitions). " + "See org.mpi.openmind.repository.bo.Node"); } catch (Exception e) { logger.error(e.getMessage(), e); } } this.setLightweight(lightweight); this.setType(type); } /** * * @param type could be either Node.TYPE_ABOX (for assertions) or Node.TYPE_TBOX (for definitions). * @param objectClass * @param lightweight */ public Entity(String type, String objectClass, Boolean lightweight) { if(StringUtils.isEmpty(type) || (!Node.TYPE_ABOX.equals(type) && !Node.TYPE_TBOX.equals(type))){ try { throw new Exception("Creating a Entity. Type=" + type + " is invalid. Type could be either ABOX (for assertions) or TBOX (for definitions). " + "See org.mpi.openmind.repository.bo.Node"); } catch (Exception e) { logger.error(e.getMessage(), e); } } this.setLightweight(lightweight); this.setObjectClass(objectClass); this.setType(type); } @Transient private Boolean lightweight; @Transient private List<Attribute> attributes = new ArrayList<Attribute>(); @Transient private List<Relation> sourceRelations = new ArrayList<Relation>(); @Transient private List<Relation> targetRelations = new ArrayList<Relation>(); /** * <p>This method returns the relations which were loaded from the DB. </p> * <p>If the content of this entity was not loaded, it means is lightweight, the output will not be valid</p> * @param ownValue * @return */ public Relation getSourceRelationByOwnValue(String ownValue){ try { if (this.lightweight) { throw new IllegalAccessException("This Entity is lightweight, so its relations and attributes were not loaded from the DB."); } for (Relation relation : this.getSourceRelations()) { if (relation.getOwnValue().equals(ownValue)) { return relation; } } } catch (Exception e) { logger.error(e.getMessage(), e); } return null; } /** * Returns if this entity has a source relation of the given type to the given id. * * @param relationName * @param targetId * @return */ public boolean containsSourceRelation(String relationName, Long targetId) { try { if (this.lightweight) { throw new IllegalAccessException( "This Entity is lightweight, so its relations and attributes were not loaded from the DB."); } for (Relation relation : this.getSourceRelations()) { if (relation.getOwnValue().equals(relationName) && OMUtils.equals(relation.getTargetId(), targetId)) { return true; } } } catch (Exception e) { logger.error(e.getMessage(), e); } return false; } /** * Returns if this entity has a target relation of the given type from the given id. * * @param relationName * @param sourceId * @return */ public boolean containsTargetRelation(String relationName, Long sourceId) { try { if (this.lightweight) { throw new IllegalAccessException( "This Entity is lightweight, so its relations and attributes were not loaded from the DB."); } for (Relation relation : this.getTargetRelations()) { if (relation.getOwnValue().equals(relationName) && OMUtils.equals(relation.getSourceId(), sourceId)) { return true; } } } catch (Exception e) { logger.error(e.getMessage(), e); } return false; } /** * Returns if the two Longs are equal and not null. * * @param l1 * @param l2 * @return */ public boolean equals(Long l1, Long l2){ if(l1 != null && l2 != null){ return l1.equals(l2); } return false; } public List<Relation> getSourceRelations(String relationName, String tarObjClass){ List<Relation> list = new ArrayList<Relation>(); try { if (this.lightweight) { throw new IllegalAccessException("This Entity is lightweight, so its relations and attributes were not loaded from the DB."); } for (Relation relation : this.getSourceRelations()) { if (relation.getOwnValue().equals(relationName) && relation.getTargetObjectClass().equals(tarObjClass)) { list.add(relation); } } } catch (Exception e) { logger.error(e.getMessage(), e); } return list; } public List<Relation> getTargetRelations(String relationName, String srcObjClass){ List<Relation> list = new ArrayList<Relation>(); try { if (this.lightweight) { throw new IllegalAccessException("This Entity is lightweight, so its relations and attributes were not loaded from the DB."); } for (Relation relation : this.getTargetRelations()) { if (relation.getOwnValue().equals(relationName) && relation.getSourceObjectClass().equals(srcObjClass)) { list.add(relation); } } } catch (Exception e) { logger.error(e.getMessage(), e); } return list; } public Boolean isConcept() { if (this.getType().equals(Node.TYPE_TBOX)) { return true; } return false; } public Boolean isAssertion() { if (this.getType().equals(Node.TYPE_ABOX)) { return true; } return false; } public void setConcept(Entity concept) throws Exception { if (this.getType().equals(Node.TYPE_TBOX)) { throw new IllegalStateException("A concept can not belong to a concept"); } Relation toRemove = this.getSourceRelationByOwnValue(WrapperService.IS_TYPE_OF); if (toRemove != null) { this.getSourceRelations().remove(toRemove); } Relation isTypeOf = new Relation(this, concept); isTypeOf.setOwnValue(WrapperService.IS_TYPE_OF); isTypeOf.setType(this.getType()); this.setObjectClass(concept.getOwnValue()); } public void addAttribute(Attribute att) { this.testLightweightState(); if(!lightweight){ if(att != null){ att.setType(this.getType()); att.setSourceId(this.getId()); att.setSourceModif(this.getModificationTime()); att.setSourceObjectClass(this.getObjectClass()); if(Node.TYPE_TBOX.equals(this.getType())){ att.setObjectClass(Node.TYPE_TBOX); } this.attributes.add(att); } } } public void replaceTargetRelation(Entity newSrc, String srcObjClass, String relName){ this.testLightweightState(); if(!lightweight){ if(newSrc == null || !newSrc.isValid()){ this.removeAllTargetRelations(relName, srcObjClass); }else{ boolean found = false; for(Relation rel : new ArrayList<Relation>(getTargetRelations(relName, srcObjClass))){ if(rel.getSourceId().equals(newSrc.getId())){ found = true; }else{ this.targetRelations.remove(rel); } } if(!found){ this.removeAllTargetRelations(relName, srcObjClass); Relation rel = new Relation(newSrc, this); rel.setOwnValue(relName); } } } } /** * This methods should be used for relation one-to-many * like witness->is_part_of->codex. * * @param newTar * @param tarObjClass * @param relName */ public void replaceSourceRelation(Entity newNonLwTar, String tarObjClass, String relName){ testLightweightState(); if(!lightweight){ if(newNonLwTar == null || !newNonLwTar.isValid()){ this.removeAllSourceRelations(relName, tarObjClass); }else{ boolean found = false; for(Relation rel : new ArrayList<Relation>(getSourceRelations(relName, tarObjClass))){ if(rel.getTargetId().equals(newNonLwTar.getId())){ found = true; }else{ this.sourceRelations.remove(rel); } } if(!found){ this.removeAllSourceRelations(relName, tarObjClass); this.addSourceRelation(relName, newNonLwTar); //Relation rel = new Relation(this, newTar); //rel.setOwnValue(relName); } } } } /** * Add a source relation from this entity to another target entity. * * @param relName * @param tar */ public void addSourceRelation(String relName, Entity tar) { if (!containsSourceRelation(relName, tar.getId()) && !tar.containsTargetRelation(relName, this.getId())) { new Relation(this, tar, relName); } else if (!containsSourceRelation(relName, tar.getId())) { Relation rel = tar.getTargetRelation(relName, this.getId()); if (rel != null) { this.sourceRelations.add(rel); } } else if (!tar.containsTargetRelation(relName, this.getId())) { Relation rel = this.getSourceRelation(relName, tar.getId()); if (rel != null) { tar.getTargetRelations().add(rel); } } } /** * Add a target relation from another source entity to this entity. * * @param relName * @param src */ public void addTargetRelation(String relName, Entity src) { if (!containsTargetRelation(relName, src.getId()) && !src.containsSourceRelation(relName, getId())) { new Relation(src, this, relName); } else if (!containsTargetRelation(relName, src.getId())) { Relation rel = src.getSourceRelation(relName, getId()); if (rel != null) { this.targetRelations.add(rel); } } else if (!src.containsSourceRelation(relName, getId())) { Relation rel = this.getTargetRelation(relName, src.getId()); if (rel != null) { src.getSourceRelations().add(rel); } } } public Relation getTargetRelation(String relName, Long srcId){ for(Relation rel : getTargetRelations()){ if(rel.getOwnValue().equals(relName) && rel.getSourceId().equals(srcId)){ return rel; } } return null; } public Relation getSourceRelation(String relName, Long tarId){ for(Relation rel : getSourceRelations()){ if(rel.getOwnValue().equals(relName) && rel.getTargetId().equals(tarId)){ return rel; } } return null; } public void addSourceRelation(Relation srcRel) { // @TODO /* * big problem definition: example TEXT is_version_of TEXT the relation * is_version_of is saved twice in the DB */ Relation oldRel = this.containsSrcRel(srcRel); if (oldRel != null) { logger.error("This entity has already this (source) relation [\n" + toString() + "\n" + "NewRel=" + srcRel + "\n" + "OldRel=" + oldRel + "]"); // remove new relation(?) this.removeSourceRelation(srcRel.getOwnValue(), srcRel.getTargetId()); } srcRel.setType(getType()); this.sourceRelations.add(srcRel); } public void addTargetRelation(Relation tarRel) { Relation oldRel = this.containsTarRel(tarRel); if (oldRel != null) { logger.error("This entity has already this (target) relation [\n" + toString() + "\n" + "NewRel=" + tarRel + "\n" + "OldRel=" + oldRel + "]"); this.removeTargetRelation(tarRel.getOwnValue(), tarRel.getSourceId()); } tarRel.setType(this.getType()); this.targetRelations.add(tarRel); } private void testLightweightState() { // FIXME: should this just be a logger call? try { if (this.lightweight) { throw new IllegalAccessException( "This Entity is lightweight, so its relations and attributes were not loaded from the DB. " + this.toString()); } } catch (Exception e) { logger.error(e.getMessage(), e); } } public List<Relation> getSourceRelations() { this.testLightweightState(); return sourceRelations; } public void setSourceRelations(List<Relation> sourceRelations) { this.sourceRelations = sourceRelations; } public List<Relation> getTargetRelations() { testLightweightState(); return targetRelations; } public void setTargetRelations(List<Relation> targetRelations) { this.targetRelations = targetRelations; } public List<Attribute> getAttributes() { testLightweightState(); return attributes; } public void setAttributes(List<Attribute> attributes) { this.attributes = attributes; } /** * <p>This method sets the object class for the current entity and * for the entityObjectClass of its attributes.</p> * <p>The field entityObjectClass is added to the attributes * to be used to performance some specific types of searchs.</p> */ @Override public void setObjectClass(String objectClass) { super.setObjectClass(objectClass); for(Attribute att : this.attributes){ att.setSourceObjectClass(objectClass); } for(Relation rel : this.sourceRelations){ rel.setSourceObjectClass(objectClass); } for(Relation rel : this.targetRelations){ rel.setTargetObjectClass(objectClass); } if(!Node.TYPE_TBOX.equals(objectClass)){ //OJO //this.setType(TYPE_ABOX); } } @Override public void setUser(String user){ super.setUser(user); if(this.lightweight.equals(false)){ for(Attribute att : this.getAttributes()){ att.setUser(user); } for(Relation rel : this.getSourceRelations()){ rel.setUser(user); for(Attribute att : rel.getAttributes()){ att.setUser(user); } } for(Relation rel : this.getTargetRelations()){ rel.setUser(user); for(Attribute att : rel.getAttributes()){ att.setUser(user); } } } } /* * Methods needing to the integration * */ public void removeAllSourceRelationsByName(String name) { try { if (this.lightweight) { throw new IllegalAccessException("This Entity is lightweight, so its relations and attributes were not loaded from the DB."); } for (Relation rel : new ArrayList<Relation>(this.getSourceRelations())) { if (rel.getOwnValue() != null && rel.getOwnValue().equals(name)) { this.getSourceRelations().remove(rel); } } } catch (Exception e) { logger.error(e.getMessage(), e); } } /** * <p>Removes transiently all relations from this entity, which conform the given input.</p> * <p>It could be made persistent using ontology service.</p> * @param nameRelation * @param objClassSource * @return */ public void removeAllTargetRelations(String nameRelation, String objClassSource){ testLightweightState(); if(!lightweight){ for(Relation rel : new ArrayList<Relation>(getTargetRelations())){ if(rel.getOwnValue().equals(nameRelation) && rel.getSourceObjectClass().equals(objClassSource)){ this.targetRelations.remove(rel); } } } } /** * <p>Removes transiently all relations from this entity, which conform the given input.</p> * <p>It could be made persistent using ontology service.</p> * @param nameRelation * @param objClassSource * @return */ public void removeAllSourceRelations(String nameRelation, String objClassTarget){ testLightweightState(); if(!lightweight){ for(Relation rel : new ArrayList<Relation>(getSourceRelations())){ if(rel.getOwnValue().equals(nameRelation) && rel.getTargetObjectClass().equals(objClassTarget)){ this.sourceRelations.remove(rel); } } } } /** * * <p>The changes executed by this method are transiently</p> * * <p>Two source relations are not unique for the perspective of this entity, * if they have the same 'relationName' and 'target object class' (one-to-many relations).</p> * * <p>This method create a source relation, if it does not exist, * otherwise the first source relation will be updated with the new entity target.</p> * * <p>Attention: if already there is more than one relation with same 'relationName' and 'target object class', * only the first one found will be updated with the new target entity.</p> * * @param relName * @param source */ public void setAsUniqueSourceRelation(String relName, Entity target){ try { if (this.lightweight) { throw new IllegalAccessException("This Entity is lightweight, so its relations and attributes were not loaded from the DB."); } Relation srcRel = null; for(Relation rel : getSourceRelations()){ if(rel.getOwnValue().equals(relName) && rel.getSourceObjectClass().equals(target.getObjectClass())){ srcRel = rel; } } if(srcRel == null){ srcRel = new Relation(this, target, relName); }else{ srcRel.setTarget(this); } } catch (Exception e) { logger.error(e.getMessage(), e); } } /** * <p>The changes executed by this method are transiently</p> * * <p>Two target relations are not unique for the perspective of this entity, * if they have the same 'relationName' and 'source object class' (many-to-one relations).</p> * * <p>This method create a target relation, if it does not exist, * otherwise the first target relation will be updated with the new entity source.</p> * * <p>Attention: if already there is more than one relation with same 'relationName' and 'source object class', * only the first one found will be updated with the new source entity.</p> * * @param relName * @param source */ public void setAsUniqueTargetRelation(String relName, Entity source){ try { if (this.lightweight) { throw new IllegalAccessException("This Entity is lightweight, so its relations and attributes were not loaded from the DB."); } Relation tarRel = null; for(Relation rel : getTargetRelations()){ if(rel.getOwnValue().equals(relName) && rel.getSourceObjectClass().equals(source.getObjectClass())){ tarRel = rel; } } if(tarRel == null){ tarRel = new Relation(source, this, relName); }else{ tarRel.setTarget(this); } } catch (Exception e) { logger.error(e.getMessage(), e); } } /** * Removes transiently the relation from this entity. * It could be made persistent using ontology service * @param name * @param target * @return true if the relation was found and removed */ public boolean removeSourceRelation(String relName, Long tarId){ for(Relation rel : new ArrayList<Relation>(getSourceRelations())){ if(StringUtils.equals(rel.getOwnValue(), relName) && rel.getTargetId().equals(tarId)){ this.sourceRelations.remove(rel); return true; } } return false; } /** * * @return true if this entity can be made persistent, otherwise false. */ public boolean isValid(){ if(StringUtils.isNotEmpty(getType()) && (getType().equals(Node.TYPE_ABOX) || getType().equals(Node.TYPE_TBOX))){ if(StringUtils.isNotEmpty(getObjectClass())){ return true; } } return false; } /** * Removes transiently the relation from this entity. * It could be made persistent using ontology service * @param name * @param target * @return true if the relation was found and removed */ public boolean removeTargetRelation(String relName, Long srcId){ for(Relation rel : new ArrayList<Relation>(getTargetRelations())){ if(StringUtils.equals(rel.getOwnValue(), relName) && rel.getSourceId().equals(srcId)){ this.targetRelations.remove(rel); return true; } } return false; } /** * Removes transiently the first target relation found, which match the given name. * change: now delete all relation by name * @param name ownValue of the relation. */ public void removeAllTargetRelationsByName(String name){ try { if (this.lightweight) { throw new IllegalAccessException("This Entity is lightweight, so its relations and attributes were not loaded from the DB."); } List<Relation> removeList = new ArrayList<Relation>(); for (Relation rel : this.getTargetRelations()) { if (rel.getOwnValue() != null && rel.getOwnValue().equals(name)) { removeList.add(rel); } } for(Relation r : removeList){ this.getTargetRelations().remove(r); } } catch (Exception e) { logger.error(e.getMessage(), e); } } public AttributeMap getAttributeMap(){ return new AttributeMap(this); } /** * Returns the named attribute. * * Returns null if no attribute of this name exists. * * @param name * @return */ public Attribute getAttributeByName(String name) { try { if (this.lightweight) { throw new IllegalAccessException("This Entity is lightweight, so its relations and attributes were not loaded from the DB."); } for (Attribute attribute : this.getAttributes()) { if (attribute.getObjectClass().equals(name)) { return attribute; } } } catch (Exception e) { logger.error(e.getMessage(), e); } return null; } public Attribute getAttributeByOwnValue(String ow) { try { if (this.lightweight) { throw new IllegalAccessException("This Entity is lightweight, so its relations and attributes were not loaded from the DB."); } for (Attribute attribute : this.getAttributes()) { if (attribute.getOwnValue().equals(ow) /*|| attribute.getObjectClass().equals(name)*/) { return attribute; } } } catch (Exception e) { logger.error(e.getMessage(), e); } return null; } public boolean containsAttribute(String name) { try { if (this.lightweight) { throw new IllegalAccessException("This Entity is lightweight, so its relations and attributes were not loaded from the DB."); } for (Attribute attribute : this.getAttributes()) { if (attribute.getObjectClass().equals(name)) { return true; } } } catch (Exception e) { logger.error(e.getMessage(), e); return false; } return false; } @Override public void increaseVersion() { super.increaseVersion(); for (Attribute att : this.attributes) { att.increaseVersion(); } for (Relation rel : this.sourceRelations) { rel.increaseVersion(); for(Attribute att : rel.getAttributes()){ att.increaseVersion(); } } for (Relation rel : this.targetRelations) { rel.increaseVersion(); for(Attribute att : rel.getAttributes()){ att.increaseVersion(); } } for (View view : this.getViews()) { view.increaseVersion(); } } /** * deletes the value of rowId for the entity and all associated elements. * As consequence of this method, when the entity is saved, it will be saved as a new row. */ public void resetRowId() { this.setRowId(null); for (Attribute att : this.attributes) { att.setRowId(null); } for (Relation rel : this.sourceRelations) { rel.setRowId(null); for(Attribute att : rel.getAttributes()){ att.setRowId(null); } } for (Relation rel : this.targetRelations) { rel.setRowId(null); for(Attribute att : rel.getAttributes()){ att.setRowId(null); } } for (View view : this.getViews()) { view.setRowId(null); } } /** * Sets the ID of the entity and its attributes and relations to null. */ public void resetId() { this.setId(null); for (Attribute att : this.attributes) { att.setId(null); att.setSourceId(null); att.setSourceModif(null); att.setSourceObjectClass(null); } for (Relation rel : this.sourceRelations) { rel.setId(null); for(Attribute att : rel.getAttributes()){ att.setId(null); } } for (Relation rel : this.targetRelations) { rel.setId(null); for(Attribute att : rel.getAttributes()){ att.setId(null); } } for (View view : this.getViews()) { view.setId(null); } } @Override public void setType(String type) { super.setType(type); for (Attribute attribute : this.attributes) { attribute.setType(type); } for (Relation rel : this.sourceRelations) { rel.setType(type); for(Attribute att : rel.getAttributes()){ att.setType(type); } } for (Relation rel : this.targetRelations) { rel.setType(type); for(Attribute att : rel.getAttributes()){ att.setType(type); } } } @Override public void setModificationTime(Long time) { super.setModificationTime(time); for (Attribute attribute : this.getAttributes()) { attribute.setModificationTime(time); attribute.setSourceModif(time); } for (Relation rel : this.getSourceRelations()) { //rel.setModificationTime(time); rel.setSourceModif(time); rel.setModificationTime(time); for(Attribute att : rel.getAttributes()){ att.setModificationTime(time); } if(this.getId() != null && this.getId().equals(rel.getTargetId())){ rel.setTargetModif(time); } } for (Relation rel : this.getTargetRelations()) { //rel.setModificationTime(time); rel.setTargetModif(time); rel.setModificationTime(time); for(Attribute att : rel.getAttributes()){ att.setModificationTime(time); } if(this.getId() != null && this.getId().equals(rel.getSourceId())){ rel.setSourceModif(time); } } } @Override public void setIsPublic(Boolean isPublic) { super.setIsPublic(isPublic); if(!this.isLightweight()){ for (Attribute attribute : this.getAttributes()) { attribute.setIsPublic(isPublic); } for (Relation rel : this.getSourceRelations()) { rel.setIsPublic(isPublic); for(Attribute att : rel.getAttributes()){ att.setIsPublic(isPublic); } } for (Relation rel : this.getTargetRelations()) { rel.setIsPublic(isPublic); for(Attribute att : rel.getAttributes()){ att.setIsPublic(isPublic); } } } } /* (non-Javadoc) * @see org.mpi.openmind.repository.bo.Node#clone() */ @Override public Object clone() { try { // super.clone Entity clone = (Entity) super.clone(); // start with empty attributes and relations clone.setAttributes(new ArrayList<Attribute>()); clone.setSourceRelations(new ArrayList<Relation>()); clone.setTargetRelations(new ArrayList<Relation>()); if (!clone.isLightweight()) { // clone attributes and add to cloned entity for (Attribute attribute : this.attributes) { clone.addAttribute((Attribute) attribute.clone()); } // clone source relations and add to cloned entity for (Relation srcRelation : this.sourceRelations) { Relation cloneRelation = (Relation) srcRelation.clone(); cloneRelation.setAttributes(new ArrayList<Attribute>()); // clone relation attributes for (Attribute att : srcRelation.getAttributes()) { cloneRelation.getAttributes().add((Attribute) att.clone()); } clone.addSourceRelation(cloneRelation); } // clone target relations and add to cloned entity for (Relation targetRelation : this.targetRelations) { Relation cloneRelation = (Relation) targetRelation.clone(); cloneRelation.setAttributes(new ArrayList<Attribute>()); // clone relation attributes for (Attribute att : targetRelation.getAttributes()) { cloneRelation.getAttributes().add((Attribute) att.clone()); } clone.addTargetRelation((Relation) targetRelation.clone()); } } return clone; } catch (Exception e) { logger.error(e); } return null; } /** * Set the system_status of this Entity and its attributes and relations. */ @Override public void setSystemStatus(String status) { super.setSystemStatus(status); if(!lightweight){ for (Attribute attribute : this.getAttributes()) { attribute.setSystemStatus(status); } //really does matter if the system status is or no //Current for a relation for (Relation rel : this.getSourceRelations()) { rel.setSystemStatus(status); for(Attribute att : rel.getAttributes()){ att.setSystemStatus(status); } } for (Relation rel : this.getTargetRelations()) { rel.setSystemStatus(status); for(Attribute att : rel.getAttributes()){ att.setSystemStatus(status); } } } } public DuplexKey<String, Long> getKey(){ return new DuplexKey<String, Long>(this.getObjectClass(), this.getId()); } public Boolean isLightweight() { if(lightweight == null) this.lightweight = true; return lightweight; } public void setLightweight(Boolean lightweight) { this.lightweight = lightweight; } public String toSmallString() { String rowIdString = (this.getRowId() == null) ? "" : "rowId=" + this.getRowId() + ", "; String idString = (this.getId() == null) ? "" : "id=" + getId() + ", "; return "Entity[" + rowIdString + idString + "objClass=" + this.getObjectClass() + "]"; } @Override public String toString() { String rowIdString = (this.getRowId() == null) ? "" : "rowId=" + this.getRowId() + ", "; String idString = (this.getId() == null) ? "" : "id=" + getId() + ", "; return "Entity[" + rowIdString + idString + "oc=" + this.getObjectClass() + ", ov=" + this.getOwnValue() + ", user=" + getUser() + ", sysStatus=" + this.getSystemStatus() + ", type=" + this.getType() + " att.size=" + this.attributes.size() + "]"; } /** * Returns a String representation with base64-encoded own-value. * * To be used for the transaction log. * * @return */ public String toEncString() { try { String es = "ENTITY[" + "id=\"" + this.getId() + "\", " + "row-id=\"" + this.getRowId() + "\", " + "object-class=\"" + this.getObjectClass() + "\", " + "mtime=\"" + this.getModificationTime() + "\", " + "version=\"" + this.getVersion() + "\", " + "user=\"" + this.getUser() + "\", " + "public=\"" + this.getIsPublic() + "\", " + "system-status=\"" + this.getSystemStatus() + "\", " + "status=\"" + this.getStatus() + "\", " + "type=\"" + this.getType() + "\", " + "b64-value=\"" + ((this.getOwnValue() != null) ? Base64.encodeBase64String(this.getOwnValue().getBytes("UTF-8")) : "") + "\"]"; return es; } catch (UnsupportedEncodingException e) { // this shouldn't happen e.printStackTrace(); } return "!!!ENCODING-ERROR!!!"; } public String getShortString(){ return "[" + this.getId() + "] " + this.getOwnValue(); } /* (non-Javadoc) * @see java.lang.Comparable#compareTo(java.lang.Object) */ @Override public int compareTo(Entity e) { // compares by own value if(e == null) return 1; String ov = this.getOwnValue(); String eov = e.getOwnValue(); if (ov != null && eov != null) { // String <> String return ov.compareTo(eov); } else if (ov == null && eov == null){ // null == null return 0; } else if (ov == null) { // null <> String return -1; } else { // String <> null return 1; } } /** * Returns if this entity has this source relation. * * Compares the relations by content. * * @param other * @return */ public Relation containsSrcRel(Relation other) { for (Relation ownRel : getSourceRelations()) { if (ownRel.equalsContent(other)) { return ownRel; } } return null; } /** * Returns if this entity has this target relation. * * Compares the relations by content. * * @param other * @return */ public Relation containsTarRel(Relation other) { for (Relation ownRel : getTargetRelations()) { if (ownRel.equalsContent(other)) { return ownRel; } } return null; } /** * Returns if this entity has the same content as another entity. * * Compares contents of Attributes and Relations. * * @param other * @return * @throws Exception */ public boolean equalsContent(Entity other) throws Exception { if (this.isLightweight() || other.isLightweight()) { throw new Exception("It is not possible to compare the content of lightWeight entities."); } // compare number of attributes and relations if (this.getAttributes().size() != other.getAttributes().size() || this.sourceRelations.size() != other.sourceRelations.size() || this.targetRelations.size() != other.targetRelations.size()) { return false; } // compare attributes for (Attribute att : this.getAttributes()) { Attribute otherAtt = other.getAttributeByName(att.getName()); if (!att.equalsContent(otherAtt)) { return false; } } // compare source relations for (Relation rel : other.getSourceRelations()) { if (containsSrcRel(rel) == null) { return false; } } // compare target relations for (Relation rel : other.getTargetRelations()) { if (containsTarRel(rel) == null) { return false; } } return true; } /** * Returns if this entity has the same structure as another entity. * * Compares only names of Attributes and Relations. * * @param other * @return * @throws Exception */ public boolean equalsStructure(Entity other) throws Exception { if (this.isLightweight() || other.isLightweight()) { throw new Exception("It is not possible to compare the structure of lightWeight entities."); } // compare number of attributes and relations if (this.sourceRelations.size() != other.sourceRelations.size() || this.targetRelations.size() != other.targetRelations.size()) { logger.debug("entities have different number of relations"); return false; } // compare attributes if (this.attributes.size() >= other.attributes.size()) { for (Attribute att : this.getAttributes()) { Attribute otherAtt = other.getAttributeByName(att.getName()); if (otherAtt == null || StringUtils.isEmpty(otherAtt.getOwnValue())) { // other attribute is empty if (!StringUtils.isEmpty(att.getOwnValue())) { logger.debug("entities have different attributes"); return false; } } } } else { // other had more attributes - check from the other side for (Attribute att : other.getAttributes()) { Attribute thisAtt = this.getAttributeByName(att.getName()); if (thisAtt == null || StringUtils.isEmpty(thisAtt.getOwnValue())) { // this attribute is empty if (!StringUtils.isEmpty(att.getOwnValue())) { logger.debug("entities have different attributes"); return false; } } } } // compare source relations for (Relation rel : other.getSourceRelations()) { if (containsSrcRel(rel) == null) { logger.debug("entities have different source relations"); return false; } } // compare target relations for (Relation rel : other.getTargetRelations()) { if (containsTarRel(rel) == null) { logger.debug("entities have different target relations"); return false; } } return true; } public void refreshEnt(Entity other, WrapperService ws) throws Exception{ //Attributes for(Attribute otherAtt : other.getAttributes()){ Attribute rootAtt = this.getAttributeByName(otherAtt.getName()); if(rootAtt == null){ Attribute newAtt = new Attribute(otherAtt.getName(), otherAtt.getContentType(), otherAtt.getValue()); this.addAttribute(newAtt); logger.info("Adding " + newAtt); }else if(!rootAtt.equalsContent(otherAtt)){ String oldValue = rootAtt.getOwnValue(); rootAtt.setValue(otherAtt.getValue()); logger.info("Refreshing " + rootAtt + "\n" + oldValue + "\n"); } } for(Attribute rootAtt : new ArrayList<Attribute>(this.getAttributes())){ if(other.getAttributeByName(rootAtt.getName()) == null){ this.getAttributes().remove(rootAtt); } } //Source Relations for(Relation otherRel : other.getSourceRelations()){ if(this.containsSrcRel(otherRel) == null){ //create Relation rel = Relation.entRelation(otherRel, ws); this.addSourceRelation(rel); } } for(Relation rootRel : new ArrayList<Relation>(this.getSourceRelations())){ if(other.containsSrcRel(rootRel) == null){ this.getSourceRelations().remove(rootRel); } } //Target relations for(Relation otherRel : other.getTargetRelations()){ if(this.containsTarRel(otherRel) == null){ //create Relation rel = Relation.entRelation(otherRel, ws); this.addTargetRelation(rel); } } for(Relation rootRel : new ArrayList<Relation>(this.getTargetRelations())){ if(other.containsTarRel(rootRel) == null){ this.getTargetRelations().remove(rootRel); } } } @Override public String getNodeType() { return "ENTITY"; } }