private static void Merge(IDictionary<ObjectClass, ObjectClassInfo> target, IDictionary<ObjectClass, ObjectClassInfo> source) { foreach (ObjectClass oc in source.Keys) { ObjectClassInfo sourceOCI = source[oc]; if (!target.ContainsKey(oc)) { ObjectClassInfoBuilder builder = new ObjectClassInfoBuilder(); builder.ObjectType = sourceOCI.ObjectType; builder.IsContainer = sourceOCI.IsContainer; builder.AddAllAttributeInfo(sourceOCI.ConnectorAttributeInfos); ObjectClassInfo targetOCI = builder.Build(); LOGGER.TraceEvent(TraceEventType.Information, CAT_DEFAULT, "Adding object class info {0}", targetOCI.ObjectType); target.Add(oc, targetOCI); } else { ObjectClassInfo targetOCI = target[oc]; if (!targetOCI.ObjectType.Equals(sourceOCI.ObjectType)) { throw new ArgumentException("Incompatible ObjectType for object class " + oc); } if (targetOCI.IsContainer != sourceOCI.IsContainer) { throw new ArgumentException("Incompatible Container flag for object class " + oc); } ObjectClassInfoBuilder builder = new ObjectClassInfoBuilder(); builder.ObjectType = targetOCI.ObjectType; builder.IsContainer = targetOCI.IsContainer; builder.AddAllAttributeInfo(targetOCI.ConnectorAttributeInfos); foreach (ConnectorAttributeInfo info in sourceOCI.ConnectorAttributeInfos) { if (info.Is(Name.NAME)) { // The __NAME__ attribute is a special one and has to be provided on each object class. // So, even if we just want to extend an object class with a few attributes, we have to provide // artificial __NAME__ attribute there. When merging, we simply skip it. continue; } foreach (ConnectorAttributeInfo existingInfo in targetOCI.ConnectorAttributeInfos) { if (existingInfo.Is(info.Name)) { throw new ArgumentException("Attempted to redefine attribute " + info.Name); } } LOGGER.TraceEvent(TraceEventType.Verbose, CAT_DEFAULT, "Adding connector attribute info {0}:{1}", info.Name, info.ValueType); builder.AddAttributeInfo(info); } ObjectClassInfo targetRebuilt = builder.Build(); LOGGER.TraceEvent(TraceEventType.Information, CAT_DEFAULT, "Replacing object class info {0}", targetOCI.ObjectType); target.Remove(oc); target.Add(oc, targetRebuilt); } } }
/// <summary> /// Adds another ObjectClassInfo to the schema. /// </summary> /// <remarks> /// Also, adds this /// to the set of supported classes for every operation defined by /// the Connector. /// </remarks> /// <exception cref="IllegalStateException">If already defined</exception> public void DefineObjectClass(String type, ICollection<ConnectorAttributeInfo> attrInfo) { ObjectClassInfoBuilder bld = new ObjectClassInfoBuilder(); bld.ObjectType = type; bld.AddAllAttributeInfo(attrInfo); ObjectClassInfo obj = bld.Build(); DefineObjectClass(obj); }