 |
Exercise 2 Solution
using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace Plato.Core { /// <summary> /// The set of entities. /// </summary> public class Brain { // The set of entities. private Dictionary<string, Entity> entities;
public Brain() { entities = new Dictionary<string, Entity>(); }
/// <summary> /// Create/add a new entity. /// </summary> /// <param name="id">The entity's internal ID.</param> /// <returns>The new entity.</returns> public IEntity CreateEntity(string id) { if (entities.ContainsKey(id)) { throw new Exception(String.Format("Entity [{0}] already exists.", id)); }
Entity newEntity = new Entity(id); entities.Add(id, newEntity);
return newEntity; }
/// <summary> /// Returns an entity given its ID. /// </summary> /// <param name="id">The entity's internal ID.</param> /// <returns>The entity.</returns> public IEntity Get(string id) { if (!entities.ContainsKey(id)) { throw new Exception(String.Format("Entity [{0}] doesn't exist.", id)); }
return entities[id]; }
/// <summary> /// Create/add a new relationship. /// </summary> /// <param name="entity1">The first entity.</param> /// <param name="entity2">The second entity.</param> /// <param name="relation">The relation that defines how the entities are related.</param> /// <param name="args">Optional argument entities.</param> /// <param name="directed">Whether or not the relationship is directed.</param> /// <returns>The new relationship.</returns> public IRelationship CreateRelationship(IEntity entity1, IEntity relation, IEntity entity2, IEntity[] args, bool directed) { Relationship newRelationship = new Relationship(entity1, relation, entity2, args, directed); entity1.AddRelationship(newRelationship); return newRelationship; }
public IRelationship CreateRelationship(IEntity entity1, IEntity relation, IEntity entity2, bool directed) { return CreateRelationship(entity1, relation, entity2, null, directed); }
public IRelationship CreateRelationship(IEntity entity1, IEntity relation, IEntity entity2) { return CreateRelationship(entity1, relation, entity2, null, true); }
public IRelationship CreateRelationship(IEntity entity1, IEntity relation, IEntity entity2, IEntity[] args) { return CreateRelationship(entity1, relation, entity2, args, true); } }
/// <summary> /// An entity. /// </summary> internal class Entity : IEntity { private string id;
// Relationships, organized by target entity. private Dictionary<string, List<IRelationship>> relationships;
// Values which have been assigned to properties private Dictionary<string, List<IEntity>> values;
public Entity(string id) { this.id = id; this.values = new Dictionary<string, List<IEntity>>(); this.relationships = new Dictionary<string, List<IRelationship>>(); }
/// <summary> /// The ID by which the entity is internally referenced. /// </summary> public string Id { get { return id; } set { id = value; } }
/// <summary> /// Add a relationship between this entity and another entity. /// </summary> /// <param name="relationship">The relationship.</param> public void AddRelationship(IRelationship relationship) { if (relationship.Entity1.Id != this.id) { throw new ArgumentException("The relationship's source entity doesn't match this entity."); }
List<IRelationship> list; string entity2 = relationship.Entity2.Id;
if (relationships.ContainsKey(entity2)) { // One or more relationships already exist with this // entity. Add the new relationship. relationships[entity2].Add(relationship); } else { // No relationships yet exist with this entity. // Add this first relationship. list = new List<IRelationship>(); list.Add(relationship); relationships[relationship.Entity2.Id] = list; } }
/// <summary> /// Assign a value to a property. /// </summary> /// <param name="property">The property.</param> /// <param name="value">The value.</param> public void Set(IEntity property, IEntity value) { // TODO: Verify 'has' relationship exists
List<IEntity> list = new List<IEntity>(); list.Add(value);
// Overwrite any existing value values[property.Id] = list; }
/// <summary> /// Get a property's value. /// </summary> /// <param name="property">The property.</param> /// <returns>The value if set, or null otherwise.</returns> public IEntity Get(IEntity property) { if (values.ContainsKey(property.Id)) { return values[property.Id][0]; } else { return null; } } }
/// <summary> /// A relationship. /// </summary> internal class Relationship : Entity, IRelationship { // The 'source' entity private IEntity entity1;
// The target entity private IEntity entity2;
private IEntity relation; private IEntity[] args; private bool directed;
public Relationship(IEntity entity1, IEntity relation, IEntity entity2, IEntity[] args) : base(null) { if (entity1 == null) { throw new ArgumentNullException("entity1"); } if (entity2 == null) { throw new ArgumentNullException("entity2"); } if (relation == null) { throw new ArgumentNullException("relation"); }
this.entity1 = entity1; this.entity2 = entity2; this.relation = relation; this.args = args; directed = true;
// Create a reference from the first entity // to this relationship. entity1.AddRelationship(this);
}
public Relationship(IEntity entity1, IEntity relation, IEntity entity2, IEntity[] args, bool directed) : this(entity1, relation, entity2, args) { this.directed = directed; }
/// <summary> /// The first entity of the relationship. /// </summary> public IEntity Entity1 { get { return entity1; } }
/// <summary> /// The second Entity of the relationship. /// </summary> public IEntity Entity2 { get { return entity2; } }
/// <summary> /// The relation defines how the two entities relate. /// </summary> public IEntity Relation { get { return relation; } }
/// <summary> /// Optional entity arguments. /// </summary> public IEntity[] Args { get { return args; } }
/// <summary> /// Is the relationship directed? /// </summary> public bool Directed { get { return directed; } } } } |
|
|
|
 |