[Mmil-commits] r16 - trunk/src/fr/loria/led/mmil

alexandredenis at users.gforge.inria.fr alexandredenis at users.gforge.inria.fr
Mar 3 Oct 10:51:21 CEST 2006


Author: alexandredenis
Date: 2006-10-03 08:51:21 +0000 (Tue, 03 Oct 2006)
New Revision: 16

Modified:
   trunk/src/fr/loria/led/mmil/MMILComponent.java
   trunk/src/fr/loria/led/mmil/MMILEntity.java
Log:


Modified: trunk/src/fr/loria/led/mmil/MMILComponent.java
===================================================================
--- trunk/src/fr/loria/led/mmil/MMILComponent.java	2006-08-31 09:35:37 UTC (rev 15)
+++ trunk/src/fr/loria/led/mmil/MMILComponent.java	2006-10-03 08:51:21 UTC (rev 16)
@@ -379,6 +379,119 @@
 		relations = new ArrayList<MMILRelation>();
 	}
 
+
+    /**
+        Return a component where all the similar entities are fusionned.
+        The similar entities are given by a relationship between these entities whose type is "similar".
+        It indicates that these entities are in fact the same one. This method removes the sources of these relations
+        and keeps updated targets. It joins the two entities by replacing the features of the target 
+        by the features of the source, and by redirecting all the relations on the source to the target.
+        @return an updated mmil component with no more "similar" relationships.
+    */
+    public MMILComponent reduceSimilarity()
+    {
+        MMILComponent reduced = new MMILComponent(this);
+
+        for(MMILRelation similar : reduced.getRelations("similar"))
+        {
+            MMILEntity source = similar.getSource();
+            MMILEntity target = similar.getTarget();
+
+            target.fusion(source);
+            
+            for(MMILRelation rel : reduced.getRelationsByEntitySource(source))
+                if (!rel.equals(similar))
+                {
+                    if (reduced.hasRelationBetween(target, rel.getTarget(), rel.getName()))
+                        reduced.remove(rel);
+                    else rel.setSource(target);
+                }
+                
+            for(MMILRelation rel : reduced.getRelationsByEntityTarget(source))
+                if (!rel.equals(similar))
+                {
+                    if (reduced.hasRelationBetween(rel.getSource(), target, rel.getName()))
+                        reduced.remove(rel);
+                    else rel.setTarget(target);
+                }
+
+            reduced.remove(source);
+            reduced.remove(similar);
+        }
+
+        return reduced;
+    }
+    
+
+    /**
+        Join this component to the given component.
+        It adds all the entities and the relations of the given component in this component, and renames the ids.
+        @param mmil - the mmil component to join this component with
+    */
+    public void join(MMILComponent mmil)
+    {
+        for(MMILEntity entity : mmil.getEntities())
+        {
+            entity.setId(createId());
+            add(entity);
+        }
+      
+        for(MMILRelation rel : mmil.getRelations())
+            add(rel);
+        
+        this.segment += "."+mmil.getSegment();
+    }
+
+
+   /**
+        Get an iterator on this component in a postfix way.
+    */
+    public MMILIterator getIterator()
+    {
+        return new MMILIterator(this);
+    }
+
+
+    /**
+        Return true if this component is equal to the given component.
+    */
+    public boolean equals(Object obj)
+    {
+        if (!(obj instanceof MMILComponent))
+            return false;
+    
+        MMILComponent mmil = (MMILComponent) obj;
+    
+        if (!this.segment.equals(mmil.getSegment()) ||
+            this.shift != mmil.getShift())
+            return false;
+
+        boolean sameEntities = Utils.equalsIgnoreOrder(entities, mmil.getEntities());
+        boolean sameRelations = Utils.equalsIgnoreOrder(relations, mmil.getRelations());
+   
+        return sameEntities && sameRelations;
+    }
+
+
+    /**
+        Split the component into several components, each containing one entity.
+        @return a list of components, each one containing a single entity of this component and no relations.
+    */
+    public List<MMILComponent> splitComponent()
+    {
+        List<MMILComponent> ret = new ArrayList<MMILComponent>();
+
+        for(MMILEntity entity : entities)
+        {
+            MMILComponent mmil = new MMILComponent();
+            mmil.add(entity);
+            ret.add(mmil);
+        }
+
+        return ret;
+    }
+
+
  
 
 /////////////////////
@@ -920,120 +1033,7 @@
 		return features;
 	}
 
-
-    /**
-        Return a component where all the similar entities are fusionned.
-        The similar entities are given by a relationship between these entities whose type is "similar".
-        It indicates that these entities are in fact the same one. This method removes the sources of these relations
-        and keeps updated targets. It joins the two entities by replacing the features of the target 
-        by the features of the source, and by redirecting all the relations on the source to the target.
-        @return an updated mmil component with no more "similar" relationships.
-    */
-    public MMILComponent reduceSimilarity()
-    {
-        MMILComponent reduced = new MMILComponent(this);
-
-        for(MMILRelation similar : reduced.getRelations("similar"))
-        {
-            MMILEntity source = similar.getSource();
-            MMILEntity target = similar.getTarget();
-
-            target.fusion(source);
-            
-            for(MMILRelation rel : reduced.getRelationsByEntitySource(source))
-                if (!rel.equals(similar))
-                {
-                    if (reduced.hasRelationBetween(target, rel.getTarget(), rel.getName()))
-                        reduced.remove(rel);
-                    else rel.setSource(target);
-                }
-                
-            for(MMILRelation rel : reduced.getRelationsByEntityTarget(source))
-                if (!rel.equals(similar))
-                {
-                    if (reduced.hasRelationBetween(rel.getSource(), target, rel.getName()))
-                        reduced.remove(rel);
-                    else rel.setTarget(target);
-                }
-
-            reduced.remove(source);
-            reduced.remove(similar);
-        }
-
-        return reduced;
-    }
     
-
-    /**
-        Join this component to the given component.
-        It adds all the entities and the relations of the given component in this component, and renames the ids.
-        @param mmil - the mmil component to join this component with
-    */
-    public void join(MMILComponent mmil)
-    {
-        for(MMILEntity entity : mmil.getEntities())
-        {
-            entity.setId(createId());
-            add(entity);
-        }
-      
-        for(MMILRelation rel : mmil.getRelations())
-            add(rel);
-        
-        this.segment += "."+mmil.getSegment();
-    }
-
-
-   /**
-        Get an iterator on this component in a postfix way.
-    */
-    public MMILIterator getIterator()
-    {
-        return new MMILIterator(this);
-    }
-
-
-    /**
-        Return true if this component is equal to the given component.
-    */
-    public boolean equals(Object obj)
-    {
-        if (!(obj instanceof MMILComponent))
-            return false;
-    
-        MMILComponent mmil = (MMILComponent) obj;
-    
-        if (!this.segment.equals(mmil.getSegment()) ||
-            this.shift != mmil.getShift())
-            return false;
-
-        boolean sameEntities = Utils.equalsIgnoreOrder(entities, mmil.getEntities());
-        boolean sameRelations = Utils.equalsIgnoreOrder(relations, mmil.getRelations());
-   
-        return sameEntities && sameRelations;
-    }
-
-
-    /**
-        Split the component into several components, each containing one entity.
-        @return a list of components, each one containing a single entity of this component and no relations.
-    */
-    public List<MMILComponent> splitComponent()
-    {
-        List<MMILComponent> ret = new ArrayList<MMILComponent>();
-
-        for(MMILEntity entity : entities)
-        {
-            MMILComponent mmil = new MMILComponent();
-            mmil.add(entity);
-            ret.add(mmil);
-        }
-
-        return ret;
-    }
-
-
-    
 	/**
 		Retrieve a formatted list of the namespaces used in this component.
         @return a String representing a list of xml namespaces definitions.

Modified: trunk/src/fr/loria/led/mmil/MMILEntity.java
===================================================================
--- trunk/src/fr/loria/led/mmil/MMILEntity.java	2006-08-31 09:35:37 UTC (rev 15)
+++ trunk/src/fr/loria/led/mmil/MMILEntity.java	2006-10-03 08:51:21 UTC (rev 16)
@@ -24,7 +24,9 @@
 	private List<MMILFeature> features    = new ArrayList<MMILFeature>();
     private List<MMILEntity>  subEntities = new ArrayList<MMILEntity>(); 
     private MMILComponent fatherComponent = null;
-    
+
+///// CONSTRUCTORS
+
     /**
         Create an empty entity with no features.
     */
@@ -209,175 +211,74 @@
     }
 
 
-   	/**
-		Returns the MMIL type of the entity (event or participant).
-        Don't be confused between the MMIL type (event or participant) and the type (value of objType for
-        participants or evtType for events).
-        @return the String "event" if the entity is a MMILEvent, 
-        the String "participant" is the entity is a MMILParticipant. 
-	*/
-	public abstract String getMMILType(); 
 
 
-	/**
-		Returns the type of the entity (value of evtType or objType).
-	*/
-	public abstract String getType();
+ 
 
-
-	/**
-		Set the type of the entity (value of evtType or objType).
-	*/
-	public abstract void setType(String type);
-
-
     /**
-        Test if this entity is underspecified.
-        @return true if the type of the entity is not defined.
-    */
-	public boolean isUnderspecified()
-	{
-		return getType().equals("");
-	}
-
-
-    /**
-        Add a sub-entity to this entity.
-        @deprecated Use add(MMILEntity) instead.
-    */
-    public void addSubEntity(MMILEntity entity)
-	{
-	    subEntities.add(entity);
-	}
-
-
-    /**
-        Add a sub-entity to this entity.
+        Add all the features of the given entity to this entity and replace their value if they already exist.
         @param entity - any entity
     */
-	public void add(MMILEntity entity)
-	{
-		addSubEntity(entity);
-	}
+    public void fusion(MMILEntity entity)
+    {
+        for(MMILFeature feat : entity.getFeatures())
+            replace(feat);
+    }
 
 
     /**
-        Add a feature to this entity.
-        @param feature - any feature
-    */
-	public void add(MMILFeature feature)
+		Returns the negative distance between the index of this entity and the given entity.
+        @return the distance between the entities.
+	*/
+	public int compareTo(Object entity)
 	{
-		features.add(feature);
-	}
+		MMILEntity e = (MMILEntity) entity;
 
-
-    /**
-        Add a feature to this entity.
-        @param name - the name of the feature
-        @param value - the value of the feature
-    */
-    public void addFeature(String name, String value)
-	{
-		add(new MMILFeature(name, value));
+		return getIndex()-e.getIndex();
 	}
 
-    /**
-        Add a feature in a namespace to this entity.
-        @param namespace - the namespace of the feature
-        @param name - the name of the feature
-        @param value - the value of the feature
-    */
-    public void addFeature(String namespace, String name, String value)
-	{
-		add(new MMILFeature(namespace, name, value));
-	}
 
 
-    /**
-        Add a feature to this entity and replaces its value if it already exists.
-        @param name - the name of the feature
-        @param value - the value of the feature
-    */
-    public void replaceFeature(String name, String value)
-    {
-        replace(new MMILFeature(name, value));
-    }
-
-
 	/**
-        Add a feature to this entity and replaces its value if it already exists.
-        This method does not consider the namespace of the feature.
-        @param feature - any feature already existing or not
+		Sort the features by their index.
 	*/
-	public void replace(MMILFeature feature)
+	public void sortFeatures()
 	{
-		for(MMILFeature feat : features)
-			if (feat.getName().equalsIgnoreCase(feature.getName()))
-			{
-				feat.setValue(feature.getValue());
-				return;
-			}
-
-		add(feature);
+		Collections.sort(features);	
 	}
 
 
-
-
     /**
-        Remove a feature of this entity.
-        @param feature - any existing feature of this entity
+        Unify this entity to the given entity.
+        Two entities 
+        @return null if no unification was possible.
     */
-	public void remove(MMILFeature feature)
-	{
-		features.remove(feature);
-	}
+    public MMILEntity unify(MMILEntity entity)
+    {
+        MMILEntity ret = entity instanceof MMILParticipant ? new MMILParticipant() : new MMILEvent();
+        for(MMILFeature feat : features)
+        {
+            List<String> values = entity.getValuesOf(feat.getName());
+            if ((values.isEmpty() || values.contains(feat.getValue())) &&
+                !ret.hasFeature(feat.getNamespace(), feat.getName(), feat.getValue()))
+                ret.add(feat);
+            else return null;
+        }
+        for(MMILFeature feat : entity.getFeatures())
+        {
+            List<String> values = getValuesOf(feat.getName());
+            if ((values.isEmpty() || values.contains(feat.getValue())) && 
+                !ret.hasFeature(feat.getNamespace(), feat.getName(), feat.getValue()))
+                ret.add(feat);
+            else return null;
+        }
+        return ret;         
+    }
 
 
-    /**
-        Remove all the features which have the given name.
-        @param name - a name of a feature
-    */
-	public void remove(String name)
-	{
-		for(MMILFeature feat : features)
-			if (feat.getName().equals(name))
-			{
-				features.remove(feat);
-				return;
-			}
-	}
 
-    /**
-		Returns all the values of a given feature's name.
-        @param name - the name of a feature
-        @return all the values of any feature which have the given name, or empty list.
-	*/
-	public List<String> getValuesOf(String name)
-	{
-		List<String> values = new ArrayList<String>();
-	
-		for(MMILFeature feat : features)
-			if (feat.getName().equalsIgnoreCase(name))
-				values.add(feat.getValue());
-	
-		return values;
-	}
+//////// TESTS 
 
-
-	/**
-		Returns the first found value of a given feature's name.
-        @param name - the name of a feature
-		@return an empty string if if it is not found.
-	*/
-	public String getValueOf(String name)
-	{
-		for(MMILFeature feat : features)
-			if (feat.getName().equalsIgnoreCase(name))
-				return feat.getValue();
-		return "";
-	}
-
     /**
         Test if this entity has the same values for the given feature's name than the given entity.
         @param entity - any entity
@@ -388,12 +289,36 @@
     {
         List<String> values1 = getValuesOf(name);
         List<String> values2 = entity.getValuesOf(name);
-
         return values1.containsAll(values2) && values2.containsAll(values1);
     }
 
 
-	/**
+    /**
+        Test if this entity equals the given entity.
+        Two entities are equal if they have the same ids (case insensitive), left and right borns, 
+        the same features (without ordering) and the same sub-entities (without ordering).
+        @return true if these conditions are satisfied
+    */
+    public boolean equals(Object obj)
+    {
+        if (!(obj instanceof MMILEntity))
+            return false;
+   
+        MMILEntity entity = (MMILEntity) obj;
+   
+        if (!entity.getId().equalsIgnoreCase(this.id) ||
+             entity.getLeftIndex()!=this.left ||
+             entity.getRightIndex()!=this.right)
+             return false;
+        
+        boolean sameFeatures = Utils.equalsIgnoreOrder(features,entity.getFeatures());
+        boolean sameSubEntities = Utils.equalsIgnoreOrder(subEntities,entity.getSubEntities());        
+       
+        return sameFeatures && sameSubEntities;
+    }
+
+
+    /**
 		Test if this entity has no features.
         @return true if it does not have any features.
 	*/
@@ -403,132 +328,64 @@
 	}
 
 
+//////// SETTERS AND GETTERS
+
     /**
-        Get the first found feature which has the given value.
-        @param value - a value of a feature
-        @return the feature found, or null if none is found.
+        Return the id of this entity.
     */
-    public MMILFeature getFeatureByValue(String value)
-    {
-    	for(MMILFeature feat : features)
-			if (feat.getValue().equalsIgnoreCase(value))
-				return feat;
-		return null;
+	public String getId() 
+    { 
+        return id; 
     }
 
 
     /**
-        Get the first found feature which has the given name.
-        @param name - the name of a feature
-        @return null if the feature doesnt exist in this entity.
+        Set the id of this entity.
     */
-    public MMILFeature getFeature(String name)
-    {
-    	for(MMILFeature feat : features)
-			if (feat.getName().equalsIgnoreCase(name))
-				return feat;
-		return null;
-    }
+	public void setId(String id) 
+    {   
+        this.id = id; 
+    } 
 
+    // deprecated
+    public int getIndex() { return left; }
 
+
     /**
-        Get all the features which have the given name.
-        @param name - the name of a feature
-        @return the list of features with the given name
+        Get the left born of this entity.
     */
-	public List<MMILFeature> getFeaturesByName(String name)
-    {
-		List<MMILFeature> result = new ArrayList<MMILFeature>();
-		for(MMILFeature feat : features)
-			if (feat.getName().equalsIgnoreCase(name))
-				result.add(feat);
-		return result;
+	public int getLeftIndex() 
+    { 
+        return left; 
     }
-		
-		
-	/**
-		Test if this entity has a feature with given name.
-        @return true if such feature is found.
-	*/
-	public boolean hasFeature(String name)
-	{
-        return getFeature(name)!=null;
-	}
+	
 
-
     /**
-		Test if this entity has a feature with given name and value.
-        @return true if such feature is found.
-	*/
-	public boolean hasFeature(String name, String value)
-	{
-        return getValueOf(name).equals(value);
-	}
-
-
-	/**
-		Test if this entity contains exactly the given feature.
-        @return true if a feature with the same name, value, namespace and borns is found.
-	*/
-	public boolean hasFeature(MMILFeature feature)
-	{
-		for(MMILFeature feat : features)
-			if (feat.equals(feature))
-				return true;
-		return false;
-	}
-
-
-    /**
-		Retrieve the sub-entities contained in this entity.
-        @return the list of the sub-entities of this entity.
-	*/
-	public List<MMILEntity> getSubEntities()
-	{
-		return subEntities; 
-	}
-
-
-  	/**
-		Retrieve all the features of this entity.
-        @return the list of the features of this entity.
-	*/
-	public List<MMILFeature> getFeatures()
-	{
-		return features; 
-	}
-
-
-    /**
-        Remove all the features of this entity.
+        Set the left born of this entity.
     */
-	public void removeAllFeatures()
-	{
-		features = new ArrayList();
-	}
+    public void setLeftIndex(int left) 
+    { 
+        this.left = left; 
+    } 
+	
 
-
-    /**
-        Add all the features of the given entity to this entity and replace their value if they already exist.
-        @param entity - any entity
+    /** 
+        Get the right born of this entity.
     */
-    public void fusion(MMILEntity entity)
-    {
-        for(MMILFeature feat : entity.getFeatures())
-            replace(feat);
+    public int getRightIndex() 
+    { 
+        return right; 
     }
+	
 
-
     /**
-		Returns the negative distance between the index of this entity and the given entity.
-        @return the distance between the entities.
-	*/
-	public int compareTo(Object entity)
-	{
-		MMILEntity e = (MMILEntity) entity;
+        Set the right born of this entity.
+    */
+    public void setRightIndex(int right) 
+    { 
+        this.right = right; 
 
-		return getIndex()-e.getIndex();
-	}
+    }
 
 
     /**
@@ -555,7 +412,7 @@
         throw new NotFoundMMILException("Feature "+name+" not found in entity "+this);
     }
  
-     /**
+    /**
         Returns the first found value of a given feature casted as a double.
         @param name - the name of a feature
         @return the found value
@@ -670,20 +527,345 @@
     }
     
 
+    /**
+        Get the first found feature which has the given value.
+        @param value - a value of a feature
+        @return the feature found, or null if none is found.
+    */
+    public MMILFeature getFeatureByValue(String value)
+    {
+    	for(MMILFeature feat : features)
+			if (feat.getValue().equalsIgnoreCase(value))
+				return feat;
+		return null;
+    }
+
+
+    /**
+        Get the first found feature which has the given name.
+        @param name - the name of a feature
+        @return null if the feature doesnt exist in this entity.
+    */
+    public MMILFeature getFeature(String name)
+    {
+    	for(MMILFeature feat : features)
+			if (feat.getName().equalsIgnoreCase(name))
+				return feat;
+		return null;
+    }
+
+
+    /**
+        Get all the features which have the given name.
+        @param name - the name of a feature
+        @return the list of features with the given name
+    */
+	public List<MMILFeature> getFeaturesByName(String name)
+    {
+		List<MMILFeature> result = new ArrayList<MMILFeature>();
+		for(MMILFeature feat : features)
+			if (feat.getName().equalsIgnoreCase(name))
+				result.add(feat);
+		return result;
+    }
+		
+		
 	/**
-		Sort the features by their index.
+		Test if this entity has a feature with given name.
+        @return true if such feature is found.
 	*/
-	public void sortFeatures()
+	public boolean hasFeature(String name)
 	{
-		Collections.sort(features);	
+        return getFeature(name)!=null;
 	}
 
 
+    /**
+		Test if this entity has a feature with given name and value.
+        @return true if such feature is found.
+	*/
+	public boolean hasFeature(String name, String value)
+	{
+        for(String val : getValuesOf(name))
+            if (val.equalsIgnoreCase(value))
+                return true;
+        return false;
+	}
 
 
-// XML
+    /**
+		Test if this entity has a feature with given namespace, name and value.
+        @return true if such feature is found.
+	*/
+	public boolean hasFeature(String namespace, String name, String value)
+	{
+        for(MMILFeature feat : features)
+            if (feat.getNamespace().equalsIgnoreCase(namespace) &&
+                feat.getName().equalsIgnoreCase(name) &&
+                feat.getValue().equalsIgnoreCase(value))
+            return true;
+        return false;
+	}
 
+
+	/**
+		Test if this entity contains exactly the given feature.
+        @return true if a feature with the same name, value, namespace and borns is found.
+	*/
+	public boolean hasFeature(MMILFeature feature)
+	{
+		for(MMILFeature feat : features)
+			if (feat.equals(feature))
+				return true;
+		return false;
+	}
+
+
     /**
+		Retrieve the sub-entities contained in this entity.
+        @return the list of the sub-entities of this entity.
+	*/
+	public List<MMILEntity> getSubEntities()
+	{
+		return subEntities; 
+	}
+
+
+  	/**
+		Retrieve all the features of this entity.
+        @return the list of the features of this entity.
+	*/
+	public List<MMILFeature> getFeatures()
+	{
+		return features; 
+	}
+
+
+    /**
+		Retrieve all the names of the features of this entity.
+        No doubles are allowed.
+        @return the list of the feature's names used in this entity.
+	*/
+	public List<String> getFeaturesName()
+	{
+        List<String> ret = new ArrayList<String>();
+		for(MMILFeature feat : features)
+            if (!ret.contains(feat.getName()))
+                ret.add(feat.getName());
+        return ret;
+	}
+
+
+    /**
+        Remove all the features of this entity.
+    */
+	public void removeAllFeatures()
+	{
+		features = new ArrayList();
+	}
+
+
+    /**
+		Returns the MMIL type of the entity (event or participant).
+        Don't be confused between the MMIL type (event or participant) and the type (value of objType for
+        participants or evtType for events).
+        @return the String "event" if the entity is a MMILEvent, 
+        the String "participant" is the entity is a MMILParticipant. 
+	*/
+	public abstract String getMMILType(); 
+
+
+	/**
+		Returns the type of the entity (value of evtType or objType).
+	*/
+	public abstract String getType();
+
+
+	/**
+		Set the type of the entity (value of evtType or objType).
+	*/
+	public abstract void setType(String type);
+
+
+    /**
+        Test if this entity is underspecified.
+        @return true if the type of the entity is not defined.
+    */
+	public boolean isUnderspecified()
+	{
+		return getType().equals("");
+	}
+
+
+    /**
+        Add a sub-entity to this entity.
+        @deprecated Use add(MMILEntity) instead.
+    */
+    public void addSubEntity(MMILEntity entity)
+	{
+	    subEntities.add(entity);
+	}
+
+
+    /**
+        Add a sub-entity to this entity.
+        @param entity - any entity
+    */
+	public void add(MMILEntity entity)
+	{
+		addSubEntity(entity);
+	}
+
+
+    /**
+        Add a feature to this entity.
+        @param feature - any feature
+    */
+	public void add(MMILFeature feature)
+	{
+		features.add(feature);
+	}
+
+
+    /**
+        Add a feature to this entity.
+        @param name - the name of the feature
+        @param value - the value of the feature
+    */
+    public void addFeature(String name, String value)
+	{
+		add(new MMILFeature(name, value));
+	}
+
+
+    /**
+        Add a feature in a namespace to this entity.
+        @param namespace - the namespace of the feature
+        @param name - the name of the feature
+        @param value - the value of the feature
+    */
+    public void addFeature(String namespace, String name, String value)
+	{
+		add(new MMILFeature(namespace, name, value));
+	}
+
+
+    /**
+        Add a feature to this entity and replaces its value if it already exists.
+        @param name - the name of the feature
+        @param value - the value of the feature
+    */
+    public void replaceFeature(String name, String value)
+    {
+        replace(new MMILFeature(name, value));
+    }
+
+
+	/**
+        Add a feature to this entity and replaces its value if it already exists.
+        This method does not consider the namespace of the feature.
+        @param feature - any feature already existing or not
+	*/
+	public void replace(MMILFeature feature)
+	{
+		for(MMILFeature feat : features)
+			if (feat.getName().equalsIgnoreCase(feature.getName()))
+			{
+				feat.setValue(feature.getValue());
+				return;
+			}
+
+		add(feature);
+	}
+
+
+    /**
+        Remove a feature of this entity.
+        @param feature - any existing feature of this entity
+    */
+	public void remove(MMILFeature feature)
+	{
+		features.remove(feature);
+	}
+
+
+    /**
+        Remove all the features which have the given name.
+        @param name - a name of a feature
+    */
+	public void remove(String name)
+	{
+		for(MMILFeature feat : features)
+			if (feat.getName().equals(name))
+			{
+				features.remove(feat);
+				return;
+			}
+	}
+
+
+    /**
+		Returns all the values of a given feature's name.
+        @param name - the name of a feature
+        @return all the values of any feature which have the given name, or empty list.
+	*/
+	public List<String> getValuesOf(String name)
+	{
+		List<String> values = new ArrayList<String>();
+	
+		for(MMILFeature feat : features)
+			if (feat.getName().equalsIgnoreCase(name))
+				values.add(feat.getValue());
+	
+		return values;
+	}
+
+
+	/**
+		Returns the first found value of a given feature's name.
+        @param name - the name of a feature
+		@return an empty string if if it is not found.
+	*/
+	public String getValueOf(String name)
+	{
+		for(MMILFeature feat : features)
+			if (feat.getName().equalsIgnoreCase(name))
+				return feat.getValue();
+		return "";
+	}
+
+
+
+
+
+//////// ATTACHMENT TO FATHER COMPONENT
+
+    /**
+     * @return the fatherComponent
+     */
+    public MMILComponent getFatherComponent() {
+        return fatherComponent;
+    }
+
+
+    /**
+     * @param fatherComponent the fatherComponent to set
+     */
+    public void setFatherComponent(MMILComponent fatherComponent) {
+        if (fatherComponent.contains(this))
+            this.fatherComponent = fatherComponent;
+    } 
+    
+    /**
+     * @return true if the MMILEntity is attached to its MMILComponent 
+     */
+    public boolean isAttached() {
+        return (this.fatherComponent != null);
+    }
+
+////// STRING OUTPUT
+
+    /**
         Return the list of the exernal namespaces.
         @return the list of the namespaces of the features which are external to mmil.
     */
@@ -850,102 +1032,4 @@
 		return xml;
 	}
 
-
-    /**
-        Test if this entity equals the given entity.
-        Two entities are equal if they have the same ids (case insensitive), left and right borns, 
-        the same features (without ordering) and the same sub-entities (without ordering).
-        @return true if these conditions are satisfied
-    */
-    public boolean equals(Object obj)
-    {
-        if (!(obj instanceof MMILEntity))
-            return false;
-   
-        MMILEntity entity = (MMILEntity) obj;
-   
-        if (!entity.getId().equalsIgnoreCase(this.id) ||
-             entity.getLeftIndex()!=this.left ||
-             entity.getRightIndex()!=this.right)
-             return false;
-        
-        boolean sameFeatures = Utils.equalsIgnoreOrder(features,entity.getFeatures());
-        boolean sameSubEntities = Utils.equalsIgnoreOrder(subEntities,entity.getSubEntities());        
-       
-        return sameFeatures && sameSubEntities;
-    }
-    /**





Plus d'informations sur la liste de diffusion Mmil-commits