public PushResponse Build() { var pushResponse = new PushResponse(); Dictionary <string, IObject> objectByNewId = null; if (this.pushRequest.NewObjects != null && this.pushRequest.NewObjects.Length > 0) { objectByNewId = this.pushRequest.NewObjects.ToDictionary( x => x.NI, x => { var cls = this.session.Database.MetaPopulation.FindClassByName(x.T); return((IObject)Allors.ObjectBuilder.Build(this.session, cls)); }); } if (this.pushRequest.Objects != null && this.pushRequest.Objects.Length > 0) { // bulk load all objects var objectIds = this.pushRequest.Objects.Select(v => v.I).ToArray(); var objects = this.session.Instantiate(objectIds); if (objectIds.Length != objects.Length) { var existingIds = objects.Select(v => v.Id.ToString()); var missingIds = objectIds.Where(v => !existingIds.Contains(v)); foreach (var missingId in missingIds) { pushResponse.AddMissingError(missingId); } } if (!pushResponse.HasErrors) { foreach (var pushRequestObject in this.pushRequest.Objects) { var obj = this.session.Instantiate(pushRequestObject.I); if (!pushRequestObject.V.Equals(obj.Strategy.ObjectVersion.ToString())) { pushResponse.AddVersionError(obj); } else { var pushRequestRoles = pushRequestObject.Roles; this.PushRequestRoles(pushRequestRoles, obj, pushResponse, objectByNewId); } } } } if (objectByNewId != null && !pushResponse.HasErrors) { var countOutstandingRoles = 0; int previousCountOutstandingRoles; do { previousCountOutstandingRoles = countOutstandingRoles; countOutstandingRoles = 0; foreach (var pushRequestNewObject in this.pushRequest.NewObjects) { var obj = objectByNewId[pushRequestNewObject.NI]; var pushRequestRoles = pushRequestNewObject.Roles; if (pushRequestRoles != null) { countOutstandingRoles += this.PushRequestRoles(pushRequestRoles, obj, pushResponse, objectByNewId, true); } } }while (countOutstandingRoles != previousCountOutstandingRoles); if (countOutstandingRoles > 0) { foreach (var pushRequestNewObject in this.pushRequest.NewObjects) { var obj = objectByNewId[pushRequestNewObject.NI]; var pushRequestRoles = pushRequestNewObject.Roles; if (pushRequestRoles != null) { this.PushRequestRoles(pushRequestRoles, obj, pushResponse, objectByNewId); } } } foreach (var newObject in objectByNewId.Values) { ((Allors.Domain.Object)newObject).OnBuild(); } foreach (var newObject in objectByNewId.Values) { ((Allors.Domain.Object)newObject).OnPostBuild(); } } var validation = this.session.Derive(false); if (validation.HasErrors) { pushResponse.AddDerivationErrors(validation); } if (!pushResponse.HasErrors) { if (objectByNewId != null) { pushResponse.NewObjects = objectByNewId.Select(dictionaryEntry => new PushResponseNewObject { I = dictionaryEntry.Value.Id.ToString(), NI = dictionaryEntry.Key }).ToArray(); } this.session.Commit(); } return(pushResponse); }
private static void AddMissingRoles(IObject[] actualRoles, string[] requestedRoleIds, PushResponse pushResponse) { var actualRoleIds = actualRoles.Select(x => x.Id.ToString()); var missingRoleIds = requestedRoleIds.Except(actualRoleIds); foreach (var missingRoleId in missingRoleIds) { pushResponse.AddMissingError(missingRoleId); } }
private int PushRequestRoles(IList <PushRequestRole> pushRequestRoles, IObject obj, PushResponse pushResponse, Dictionary <string, IObject> objectByNewId, bool ignore = false) { var countOutstandingRoles = 0; foreach (var pushRequestRole in pushRequestRoles) { var composite = (Composite)obj.Strategy.Class; var roleTypes = composite.WorkspaceRoleTypes; var acl = new AccessControlList(obj, this.user); var roleTypeName = pushRequestRole.T; var roleType = roleTypes.FirstOrDefault(v => v.PropertyName.Equals(roleTypeName)); if (roleType != null) { if (acl.CanWrite(roleType)) { if (roleType.ObjectType.IsUnit) { var unitType = (IUnit)roleType.ObjectType; var role = pushRequestRole.S; if (role is string) { role = Serialization.ReadString((string)role, unitType.UnitTag); } // Json.net deserializes number to long or double, instead of int. if (unitType.IsInteger && role != null && !(role is int)) { role = Convert.ToInt32(role); } obj.Strategy.SetUnitRole(roleType.RelationType, role); } else { if (roleType.IsOne) { var roleId = (string)pushRequestRole.S; if (string.IsNullOrEmpty(roleId)) { obj.Strategy.RemoveCompositeRole(roleType.RelationType); } else { var role = this.GetRole(roleId, objectByNewId); if (role == null) { pushResponse.AddMissingError(roleId); } else { obj.Strategy.SetCompositeRole(roleType.RelationType, role); } } } else { // Add if (pushRequestRole.A != null) { var roleIds = pushRequestRole.A; if (roleIds.Length != 0) { var roles = this.GetRoles(roleIds, objectByNewId); if (roles.Length != roleIds.Length) { AddMissingRoles(roles, roleIds, pushResponse); } else { foreach (var role in roles) { obj.Strategy.AddCompositeRole(roleType.RelationType, role); } } } } // Remove if (pushRequestRole.R != null) { var roleIds = pushRequestRole.R; if (roleIds.Length != 0) { var roles = this.GetRoles(roleIds, objectByNewId); if (roles.Length != roleIds.Length) { AddMissingRoles(roles, roleIds, pushResponse); } else { foreach (var role in roles) { obj.Strategy.RemoveCompositeRole(roleType.RelationType, role); } } } } } } } else { if (!ignore) { pushResponse.AddAccessError(obj); } else { countOutstandingRoles++; } } } } return(countOutstandingRoles); }
private int PushRequestRoles(IList<PushRequestRole> pushRequestRoles, IObject obj, PushResponse pushResponse, Dictionary<string, IObject> objectByNewId, bool ignore = false) { var countOutstandingRoles = 0; foreach (var pushRequestRole in pushRequestRoles) { var composite = (Composite)obj.Strategy.Class; var roleTypes = composite.WorkspaceRoleTypes; var acl = this.acls[obj]; var roleType = (IRoleType)this.metaPopulation.Find(Guid.Parse(pushRequestRole.T)); if (roleType != null) { if (acl.CanWrite(roleType)) { if (roleType.ObjectType.IsUnit) { var unitType = (IUnit)roleType.ObjectType; var role = UnitConvert.Parse(unitType.Id, pushRequestRole.S); obj.Strategy.SetUnitRole(roleType.RelationType, role); } else { if (roleType.IsOne) { var roleId = (string)pushRequestRole.S; if (string.IsNullOrEmpty(roleId)) { obj.Strategy.RemoveCompositeRole(roleType.RelationType); } else { var role = this.GetRole(roleId, objectByNewId); if (role == null) { pushResponse.AddMissingError(roleId); } else { obj.Strategy.SetCompositeRole(roleType.RelationType, role); } } } else { // Add if (pushRequestRole.A != null) { var roleIds = pushRequestRole.A; if (roleIds.Length != 0) { var roles = this.GetRoles(roleIds, objectByNewId); if (roles.Length != roleIds.Length) { AddMissingRoles(roles, roleIds, pushResponse); } else { foreach (var role in roles) { obj.Strategy.AddCompositeRole(roleType.RelationType, role); } } } } // Remove if (pushRequestRole.R != null) { var roleIds = pushRequestRole.R; if (roleIds.Length != 0) { var roles = this.GetRoles(roleIds, objectByNewId); if (roles.Length != roleIds.Length) { AddMissingRoles(roles, roleIds, pushResponse); } else { foreach (var role in roles) { obj.Strategy.RemoveCompositeRole(roleType.RelationType, role); } } } } } } } else { if (!ignore) { pushResponse.AddAccessError(obj); } else { countOutstandingRoles++; } } } } return countOutstandingRoles; }