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> /// Gets the object class info for specified object class, used for schema building /// </summary> /// <param name="oc">ObjectClass to get info for</param> /// <returns>ObjectClass' ObjectClassInfo</returns> protected override ObjectClassInfo GetObjectClassInfo(ObjectClass oc) { // get the object class from base ObjectClassInfo oinfo = base.GetObjectClassInfo(oc); // add additional attributes for ACCOUNT if (oc.Is(ObjectClass.ACCOUNT_NAME)) { var classInfoBuilder = new ObjectClassInfoBuilder { IsContainer = oinfo.IsContainer, ObjectType = oinfo.ObjectType }; classInfoBuilder.AddAllAttributeInfo(oinfo.ConnectorAttributeInfos); classInfoBuilder.AddAttributeInfo(AttInfoDatabase); classInfoBuilder.AddAttributeInfo(AttInfoRecipientType); classInfoBuilder.AddAttributeInfo(AttInfoExternalMail); oinfo = classInfoBuilder.Build(); } // return return(oinfo); }