Пример #1
0
 public void AddField(ImportedContentTypeField field)
 {
     this.Fields[field.Name] = field;
 }
Пример #2
0
        protected void ApplyAttributes(ListItem li, XElement attributes, String objectType)
        {
            XNamespace          ns         = attributes.GetDefaultNamespace();
            ImportedContentType typeObject = this.ContentTypeImporter.ResolveLibraryContentType(objectType);

            foreach (XElement attribute in attributes.Elements(ns + "attribute"))
            {
                string fieldName           = attribute.Attribute("name").Value;
                ImportedContentTypeField f = typeObject.GetField(fieldName);
                if (f == null)
                {
                    continue;
                }
                // Ok...so...now we convert the value and slam it into the thing
                object value = null;
                if (f.Repeating)
                {
                    value = "|";
                    bool first = true;
                    foreach (XElement v in attribute.Elements(ns + "value"))
                    {
                        if (!first)
                        {
                            value += "|";
                        }
                        value += Tools.SanitizeSingleLineString((string)v);
                        first  = false;
                    }
                    value += "|";
                }
                else
                {
                    FieldType type = Tools.DecodeFieldType(attribute.Attribute("dataType").Value);
                    string    v    = Tools.SanitizeSingleLineString((string)attribute.Elements(ns + "value").FirstOrDefault());
                    if (type == FieldType.Text)
                    {
                        value = v;
                    }
                    else if (v != null && v != string.Empty)
                    {
                        switch (type)
                        {
                        case FieldType.Boolean:
                            value = XmlConvert.ToBoolean(v);
                            break;

                        case FieldType.Integer:
                            value = XmlConvert.ToInt32(v);
                            break;

                        case FieldType.Number:
                            value = XmlConvert.ToDecimal(v);
                            break;

                        case FieldType.DateTime:
                            value = Tools.ParseXmlDate(v);
                            break;

                        default:
                            value = v;
                            break;
                        }
                    }
                }
                li[f.FinalName] = value;
            }
        }
Пример #3
0
        public ContentTypeImporter(ImportContext importContext, String documentLibraryName, bool clearFirst) : base("content types", importContext)
        {
            this.Log.Info(string.Format("Mapping the object types to content types and columns to the site and the library [{0}]...", documentLibraryName));

            // TODO: Make these two configurable
            this.TypeGroup  = TYPE_GROUP;
            this.FieldGroup = FIELD_GROUP;

            using (ObjectPool <SharePointSession> .Ref sessionRef = this.ImportContext.SessionFactory.GetSession())
            {
                SharePointSession session       = sessionRef.Target;
                ClientContext     clientContext = session.ClientContext;
                List documentLibrary            = clientContext.Web.Lists.GetByTitle(documentLibraryName);
                if (clearFirst)
                {
                    try
                    {
                        Log.Warn("Cleaning out document library content types...");
                        CleanContentTypes(sessionRef.Target, documentLibrary.ContentTypes);
                        Log.Warn("Cleaning out document library fields...");
                        CleanFields(sessionRef.Target, documentLibrary.Fields);
                        Log.Warn("Cleaning out site content types...");
                        CleanContentTypes(sessionRef.Target, clientContext.Web.ContentTypes);
                        Log.Warn("Cleaning out site fields...");
                        CleanFields(sessionRef.Target, clientContext.Web.Fields);
                        Log.Warn("Fields and content types cleared!");
                    }
                    catch (Exception e)
                    {
                        Log.Warn("Tried to remove the existing content types, but failed", e);
                    }
                }

                ContentTypeCollection contentTypeCollection = clientContext.Web.ContentTypes;
                clientContext.Load(contentTypeCollection, c => c.Include(t => t.Id, t => t.Name, t => t.Group, t => t.Parent, t => t.FieldLinks));
                clientContext.Load(documentLibrary.ContentTypes, c => c.Include(t => t.Id, t => t.Name, t => t.Parent));
                clientContext.Load(clientContext.Web, w => w.Fields, w => w.AvailableFields);
                session.ExecuteQuery();

                // First we gather up whatever's already there
                Dictionary <string, ImportedContentType> siteContentTypes    = new Dictionary <string, ImportedContentType>();
                Dictionary <string, ImportedContentType> libraryContentTypes = new Dictionary <string, ImportedContentType>();
                Dictionary <string, ImportedContentType> contentTypesById    = new Dictionary <string, ImportedContentType>();
                Dictionary <string, ContentType>         allTypes            = new Dictionary <string, ContentType>();
                foreach (ContentType type in contentTypeCollection)
                {
                    ImportedContentType ct = new ImportedContentType(this, type);
                    siteContentTypes[type.Name]           = ct;
                    contentTypesById[type.Id.StringValue] = ct;
                }

                Dictionary <string, Field> existingFields = new Dictionary <string, Field>();
                foreach (Field f in clientContext.Web.Fields)
                {
                    existingFields[f.StaticName] = f;
                }

                HashSet <string> documentLibraryTypes = new HashSet <string>();
                foreach (ContentType ct in documentLibrary.ContentTypes)
                {
                    documentLibraryTypes.Add(ct.Name);
                    ImportedContentType ict = new ImportedContentType(this, ct);
                    libraryContentTypes[ct.Name]        = ict;
                    contentTypesById[ct.Id.StringValue] = ict;
                }

                // Now we go over the XML declarations
                HashSet <string> newTypes = new HashSet <string>();
                XElement         types    = XElement.Load(this.ImportContext.LoadIndex("types"));
                XNamespace       ns       = types.GetDefaultNamespace();
                foreach (XElement type in types.Elements(ns + "type"))
                {
                    string typeName = (string)type.Element(ns + "name");
                    ImportedContentType finalType = null;
                    HashSet <string>    linkNames = new HashSet <string>();
                    bool skipInherited            = true;
                    bool patchFields     = false;
                    bool versionableType = false;
                    bool containerType   = false;
                    if (siteContentTypes.ContainsKey(typeName))
                    {
                        finalType = siteContentTypes[typeName];
                        foreach (FieldLink link in finalType.Type.FieldLinks)
                        {
                            linkNames.Add(link.Name);
                        }
                        if (typeName == "dm_sysobject" || typeName == "dm_folder")
                        {
                            patchFields     = true;
                            versionableType = (typeName == "dm_sysobject");
                            containerType   = (typeName == "dm_folder");
                        }
                    }
                    else
                    {
                        // New type...create it
                        ImportedContentType superType        = null;
                        XElement            superTypeElement = type.Element(ns + "superType");
                        if ((superTypeElement != null) && (typeName != "dm_folder"))
                        {
                            string stName = (string)superTypeElement;
                            if (siteContentTypes.ContainsKey(stName))
                            {
                                superType = siteContentTypes[stName];
                            }
                        }

                        if (superType == null)
                        {
                            switch (typeName)
                            {
                            case "dm_sysobject":
                                superType = siteContentTypes["Document"];
                                // skipInherited = false;
                                patchFields     = true;
                                versionableType = true;
                                break;

                            case "dm_folder":
                                superType = siteContentTypes["Folder"];
                                // skipInherited = false;
                                patchFields   = true;
                                containerType = true;
                                break;

                            default:
                                // This isn't a type we're intereseted in, so we skip it
                                continue;
                            }
                        }

                        Log.Info(string.Format("Creating content type {0} (descended from [{1}]])", typeName, superType.Name));
                        ContentTypeCreationInformation ctInfo = new ContentTypeCreationInformation();
                        ctInfo.Description       = string.Format("Documentum Type {0}", typeName);
                        ctInfo.Name              = typeName;
                        ctInfo.ParentContentType = (superType != null ? superType.Type : null);
                        ctInfo.Group             = this.TypeGroup;

                        ContentType contentTypeObj = contentTypeCollection.Add(ctInfo);
                        clientContext.Load(contentTypeObj, t => t.Id);
                        session.ExecuteQuery();

                        finalType = new ImportedContentType(this, contentTypeObj, superType.Id);
                        siteContentTypes[typeName] = finalType;
                        contentTypesById[finalType.Id.StringValue] = finalType;
                    }

                    // Now we link the type to its fields, as needed
                    int updateCount = 0;

                    XElement attributeContainer = type.Element(ns + "attributes");
                    if (patchFields)
                    {
                        XElement versionAtt = new XElement(ns + "attribute");
                        versionAtt.SetAttributeValue("length", "32");
                        versionAtt.SetAttributeValue("repeating", "false");
                        versionAtt.SetAttributeValue("inherited", "false");
                        versionAtt.SetAttributeValue("sourceName", "version");
                        versionAtt.SetAttributeValue("name", "cmf:version");
                        versionAtt.SetAttributeValue("dataType", "STRING");
                        attributeContainer.AddFirst(versionAtt);

                        versionAtt = new XElement(ns + "attribute");
                        versionAtt.SetAttributeValue("length", "400");
                        versionAtt.SetAttributeValue("repeating", "false");
                        versionAtt.SetAttributeValue("inherited", "false");
                        versionAtt.SetAttributeValue("sourceName", "title");
                        versionAtt.SetAttributeValue("name", "cmis:description");
                        versionAtt.SetAttributeValue("dataType", "STRING");
                        attributeContainer.AddFirst(versionAtt);

                        versionAtt = new XElement(ns + "attribute");
                        versionAtt.SetAttributeValue("length", "128");
                        versionAtt.SetAttributeValue("repeating", "false");
                        versionAtt.SetAttributeValue("inherited", "false");
                        versionAtt.SetAttributeValue("sourceName", "author_name");
                        versionAtt.SetAttributeValue("name", "shpt:authorName");
                        versionAtt.SetAttributeValue("dataType", "STRING");
                        attributeContainer.AddFirst(versionAtt);

                        versionAtt = new XElement(ns + "attribute");
                        versionAtt.SetAttributeValue("length", "0");
                        versionAtt.SetAttributeValue("repeating", "false");
                        versionAtt.SetAttributeValue("inherited", "false");
                        versionAtt.SetAttributeValue("sourceName", "author");
                        versionAtt.SetAttributeValue("name", "shpt:author");
                        versionAtt.SetAttributeValue("dataType", "USER");
                        attributeContainer.AddFirst(versionAtt);

                        versionAtt = new XElement(ns + "attribute");
                        versionAtt.SetAttributeValue("length", "128");
                        versionAtt.SetAttributeValue("repeating", "false");
                        versionAtt.SetAttributeValue("inherited", "false");
                        versionAtt.SetAttributeValue("sourceName", "editor_name");
                        versionAtt.SetAttributeValue("name", "shpt:editorName");
                        versionAtt.SetAttributeValue("dataType", "STRING");
                        attributeContainer.AddFirst(versionAtt);

                        versionAtt = new XElement(ns + "attribute");
                        versionAtt.SetAttributeValue("length", "0");
                        versionAtt.SetAttributeValue("repeating", "false");
                        versionAtt.SetAttributeValue("inherited", "false");
                        versionAtt.SetAttributeValue("sourceName", "editor");
                        versionAtt.SetAttributeValue("name", "shpt:editor");
                        versionAtt.SetAttributeValue("dataType", "USER");
                        attributeContainer.AddFirst(versionAtt);

                        versionAtt = new XElement(ns + "attribute");
                        versionAtt.SetAttributeValue("length", "16");
                        versionAtt.SetAttributeValue("repeating", "false");
                        versionAtt.SetAttributeValue("inherited", "false");
                        versionAtt.SetAttributeValue("sourceName", "object_id");
                        versionAtt.SetAttributeValue("name", "cmis:objectId");
                        versionAtt.SetAttributeValue("dataType", "STRING");
                        attributeContainer.AddFirst(versionAtt);

                        versionAtt = new XElement(ns + "attribute");
                        versionAtt.SetAttributeValue("length", "256");
                        versionAtt.SetAttributeValue("repeating", "false");
                        versionAtt.SetAttributeValue("inherited", "false");
                        versionAtt.SetAttributeValue("sourceName", "location");
                        versionAtt.SetAttributeValue("name", "cmf:location");
                        versionAtt.SetAttributeValue("dataType", "STRING");
                        attributeContainer.AddFirst(versionAtt);

                        versionAtt = new XElement(ns + "attribute");
                        versionAtt.SetAttributeValue("length", "256");
                        versionAtt.SetAttributeValue("repeating", "false");
                        versionAtt.SetAttributeValue("inherited", "false");
                        versionAtt.SetAttributeValue("sourceName", "path");
                        versionAtt.SetAttributeValue("name", "cmis:path");
                        versionAtt.SetAttributeValue("dataType", "STRING");
                        attributeContainer.AddFirst(versionAtt);

                        versionAtt = new XElement(ns + "attribute");
                        versionAtt.SetAttributeValue("length", "256");
                        versionAtt.SetAttributeValue("repeating", "false");
                        versionAtt.SetAttributeValue("inherited", "false");
                        versionAtt.SetAttributeValue("sourceName", "name");
                        versionAtt.SetAttributeValue("name", "cmis:name");
                        versionAtt.SetAttributeValue("dataType", "STRING");
                        attributeContainer.AddFirst(versionAtt);

                        versionAtt = new XElement(ns + "attribute");
                        versionAtt.SetAttributeValue("length", "1024");
                        versionAtt.SetAttributeValue("repeating", "true");
                        versionAtt.SetAttributeValue("inherited", "false");
                        versionAtt.SetAttributeValue("sourceName", "keywords");
                        versionAtt.SetAttributeValue("name", "dctm:keywords");
                        versionAtt.SetAttributeValue("dataType", "STRING");
                        attributeContainer.AddFirst(versionAtt);

                        versionAtt = new XElement(ns + "attribute");
                        versionAtt.SetAttributeValue("length", "16");
                        versionAtt.SetAttributeValue("repeating", "false");
                        versionAtt.SetAttributeValue("inherited", "false");
                        versionAtt.SetAttributeValue("sourceName", "acl_id");
                        versionAtt.SetAttributeValue("name", "dctm:acl_id");
                        versionAtt.SetAttributeValue("dataType", "STRING");
                        attributeContainer.AddFirst(versionAtt);

                        if (versionableType)
                        {
                            versionAtt = new XElement(ns + "attribute");
                            versionAtt.SetAttributeValue("length", "16");
                            versionAtt.SetAttributeValue("repeating", "false");
                            versionAtt.SetAttributeValue("inherited", "false");
                            versionAtt.SetAttributeValue("sourceName", "history_id");
                            versionAtt.SetAttributeValue("name", "cmis:versionSeriesId");
                            versionAtt.SetAttributeValue("dataType", "STRING");
                            attributeContainer.AddFirst(versionAtt);

                            versionAtt = new XElement(ns + "attribute");
                            versionAtt.SetAttributeValue("length", "16");
                            versionAtt.SetAttributeValue("repeating", "false");
                            versionAtt.SetAttributeValue("inherited", "false");
                            versionAtt.SetAttributeValue("sourceName", "antecedent_id");
                            versionAtt.SetAttributeValue("name", "cmf:version_antecedent_id");
                            versionAtt.SetAttributeValue("dataType", "STRING");
                            attributeContainer.AddFirst(versionAtt);

                            versionAtt = new XElement(ns + "attribute");
                            versionAtt.SetAttributeValue("length", "0");
                            versionAtt.SetAttributeValue("repeating", "false");
                            versionAtt.SetAttributeValue("inherited", "false");
                            versionAtt.SetAttributeValue("sourceName", "current");
                            versionAtt.SetAttributeValue("name", "cmis:isLatestVersion");
                            versionAtt.SetAttributeValue("dataType", "BOOLEAN");
                            attributeContainer.AddFirst(versionAtt);
                        }
                    }

                    foreach (XElement att in attributeContainer.Elements(ns + "attribute"))
                    {
                        // The attribute is either not inherited or its inheritance is ignored, so add it to the content type's declaration
                        string attName       = att.Attribute("name").Value;
                        string attSourceName = att.Attribute("sourceName").Value;
                        string finalName     = string.Format("dctm_{0}", attSourceName);
                        // Special case for folder attributes inherited from dm_sysobject
                        bool inherited = XmlConvert.ToBoolean(att.Attribute("inherited").Value) && (typeName != "dm_folder");
                        bool repeating = XmlConvert.ToBoolean(att.Attribute("repeating").Value);

                        // If this is an inherited attribute, we won't add it because we're not interested in it
                        if (inherited && skipInherited)
                        {
                            continue;
                        }

                        ImportedContentTypeField finalField = null;
                        if (linkNames.Contains(finalName) || (inherited && skipInherited))
                        {
                            // Existing or inherited link...
                            finalField = new ImportedContentTypeField(existingFields[finalName], attName, finalName, attSourceName, repeating);
                        }
                        else
                        {
                            FieldLinkCreationInformation fieldLink = new FieldLinkCreationInformation();
                            if (existingFields.ContainsKey(finalName))
                            {
                                finalField      = new ImportedContentTypeField(existingFields[finalName], attName, finalName, attSourceName, repeating);
                                fieldLink.Field = finalField.Field;
                            }
                            else
                            {
                                Log.Info(string.Format("Creating field {0} (first declared by {1})", finalName, typeName));
                                FieldType attType = Tools.DecodeFieldType(att.Attribute("dataType").Value);
                                if (repeating)
                                {
                                    // Default repeating fields to strings, since they'll be concatenated
                                    attType = FieldType.Note;
                                }
                                int length = XmlConvert.ToInt32(att.Attribute("length").Value);
                                if (length > 255)
                                {
                                    attType = FieldType.Note;
                                }
                                Guid guid = Guid.NewGuid();


                                string fieldXml = string.Format("<Field DisplayName='{0}' Name='{1}' ID='{2}' Group='{3}' Type='{4}' />", finalName, finalName, guid.ToString(), this.FieldGroup, attType);
                                fieldLink.Field = clientContext.Web.Fields.AddFieldAsXml(fieldXml, false, AddFieldOptions.AddFieldInternalNameHint);
                                clientContext.Load(fieldLink.Field, f => f.Id, f => f.FieldTypeKind, f => f.StaticName, f => f.Group);
                                existingFields[finalName] = fieldLink.Field;
                                finalField = new ImportedContentTypeField(existingFields[finalName], attName, finalName, attSourceName, repeating);
                            }
                            finalType.Type.FieldLinks.Add(fieldLink);
                            linkNames.Add(finalName);
                            updateCount++;
                        }
                        finalType.AddField(finalField);
                    }
                    if (updateCount > 0)
                    {
                        finalType.Type.Update(true);
                        session.ExecuteQuery();
                    }
                    newTypes.Add(typeName);
                }

                // Now, make sure this type exists in the document library
                List <ContentType> newContentTypes = new List <ContentType>();
                foreach (string typeName in newTypes)
                {
                    if (!documentLibraryTypes.Contains(typeName))
                    {
                        ContentType ct = documentLibrary.ContentTypes.AddExistingContentType(siteContentTypes[typeName].Type);
                        newContentTypes.Add(ct);
                        clientContext.Load(ct);
                        clientContext.Load(ct, c => c.Parent);
                    }
                }
                if (newContentTypes.Count > 0)
                {
                    session.ExecuteQuery();
                    foreach (ContentType ct in newContentTypes)
                    {
                        ImportedContentType newCt = new ImportedContentType(this, ct);
                        contentTypesById[ct.Id.StringValue] = newCt;
                        libraryContentTypes[ct.Name]        = newCt;
                    }
                }

                this.SiteContentTypes    = siteContentTypes;
                this.LibraryContentTypes = libraryContentTypes;
                this.ContentTypesById    = contentTypesById;
            }
        }