コード例 #1
0
        public void NewMaObjCreated(EventHandlerEnvironment env)

        {
            if (env.ObjVerEx.IsFirstVersion)
            {
                string mitarbeiter = $"{env.ObjVerEx.GetPropertyText("PD.Nachname")}, {env.ObjVerEx.GetPropertyText("PD.Vorname")}";
                env.ObjVerEx.SetProperty("PD.VollstName", MFDataType.MFDatatypeText, mitarbeiter);
                int maObjType = env.Vault.ObjectTypeOperations.GetObjectTypeIDByAlias("Obj.MA"); //need ObjTypeID to get ObjectType for OwnerPropertyDef

                MFPropertyValuesBuilder vmdProperties = new MFPropertyValuesBuilder(env.Vault)
                                                        .SetClass("CL.VMD")
                                                        .Add("PD.VMD-Name", MFDataType.MFDatatypeText, $"VMD-{mitarbeiter}")
                                                        .SetLookup(env.Vault.ObjectTypeOperations.GetObjectType(maObjType).OwnerPropertyDef, env.ObjVer)
                ;

                int newVMD = env.Vault.ObjectOperations.CreateNewObjectExQuick(
                    env.Vault.ObjectTypeOperations.GetObjectTypeIDByAlias("Obj.VMD"),
                    vmdProperties.Values
                    );

                env.ObjVerEx.SetProperty("PD.VertraulicheMitarbeiterdaten", MFDataType.MFDatatypeUninitialized, newVMD);
                //env.ObjVerEx.SetProperty("PD.FirstCheckin", MFDataType.MFDatatypeBoolean, false);
                env.ObjVerEx.SaveProperties();
            }



            //chown when M-Files User is created
            if (env.ObjVerEx.HasValue("PD.MFUser"))
            {
                env.ObjVerEx.SaveProperty(MFBuiltInPropertyDef.MFBuiltInPropertyDefCreatedBy, MFDataType.MFDatatypeUninitialized, env.ObjVerEx.GetProperty("PD.MFUser"));
                env.ObjVerEx.GetDirectReference("PD.VertraulicheMitarbeiterdaten").SaveProperty(MFBuiltInPropertyDef.MFBuiltInPropertyDefCreatedBy,
                                                                                                MFDataType.MFDatatypeUninitialized, env.ObjVerEx.GetProperty("PD.MFUser"));
            }
        }
        /// <summary>
        /// Executes the <see cref="ObjectSelector"/> rule against the <see cref="XNode"/>,
        /// importing matching objects.
        /// </summary>
        /// <param name="vault">The vault reference to use for processing the import.</param>
        /// <param name="node">The node to import data from.</param>
        /// <param name="objectSelector">The selector to execute.</param>
        /// <param name="xmlFile">The information about the XML file being imported.</param>
        /// <param name="parent">A parent object to create a relationship to, if appropriate.</param>
        /// <param name="xmlNamespaceManager">A namespace manager for using XML prefixes in XPath statements.</param>
        /// <returns>A list of files which were attached to the object, for deletion.</returns>
        public List <FileInfo> ImportXmlFile(
            Vault vault,
            XNode node,
            ObjectSelector objectSelector,
            FileInfo xmlFile = null,
            ObjVer parent    = null,
            XmlNamespaceManager xmlNamespaceManager = null)
        {
            // Sanity.
            if (vault == null)
            {
                throw new ArgumentNullException(nameof(vault));
            }
            if (null == node)
            {
                throw new ArgumentNullException(nameof(node));
            }
            if (null == objectSelector)
            {
                throw new ArgumentNullException(nameof(objectSelector));
            }
            if (string.IsNullOrWhiteSpace(objectSelector.XPathQuery))
            {
                throw new ArgumentException("The XPath query for the object was empty", nameof(objectSelector));
            }
            if (null == objectSelector.PropertySelectors)
            {
                throw new ArgumentException("The object selector contained no property selectors.", nameof(objectSelector));
            }
            if (false == objectSelector.ObjectType.IsResolved)
            {
                throw new InvalidOperationException("The object selector object type is not resolved");
            }
            if (false == objectSelector.Class.IsResolved)
            {
                throw new InvalidOperationException("The object selector class is not resolved");
            }

            // Create a list of attached files (which can then be deleted later).
            var attachedFilesToDelete = new List <FileInfo>();

            // Create the namespace manager.
            if (null != xmlNamespaceManager)
            {
                // Copy data from the other manager (so we don't accidentally affect other queries).
                var xmlNamespaceManager2 = new XmlNamespaceManager(new NameTable());
                foreach (string prefix in xmlNamespaceManager)
                {
                    // Don't add default.
                    if (string.IsNullOrWhiteSpace(prefix))
                    {
                        continue;
                    }
                    if (prefix == "xsi")
                    {
                        continue;
                    }
                    if (prefix == "xmlns")
                    {
                        continue;
                    }

                    // Add.
                    xmlNamespaceManager2.AddNamespace(prefix, xmlNamespaceManager.LookupNamespace(prefix));
                }
                xmlNamespaceManager = xmlNamespaceManager2;
            }
            else
            {
                xmlNamespaceManager = new XmlNamespaceManager(new NameTable());
            }

            // Populate the namespace manager.
            if (null != objectSelector.XmlNamespaces)
            {
                foreach (var ns in objectSelector.XmlNamespaces)
                {
                    // If the namespace manager already contains a prefix then remove it.
                    string existingPrefix = xmlNamespaceManager.LookupPrefix(ns.Uri);
                    if (false == string.IsNullOrEmpty(existingPrefix))
                    {
                        xmlNamespaceManager.RemoveNamespace(existingPrefix, ns.Uri);
                    }

                    xmlNamespaceManager.AddNamespace(ns.Prefix, ns.Uri);
                }
            }

            // Find matching nodes.
            foreach (var matchingElement in node.XPathSelectElements(objectSelector.XPathQuery, xmlNamespaceManager))
            {
                // Hold all the properties being read.
                var propertyValuesBuilder = new MFPropertyValuesBuilder(vault);

                // Add the class property value.
                propertyValuesBuilder.SetClass(objectSelector.Class.ID);

                // Retrieve the properties.
                foreach (var propertySelector in objectSelector.PropertySelectors)
                {
                    // Sanity.
                    if (string.IsNullOrWhiteSpace(propertySelector.XPathQuery))
                    {
                        throw new ArgumentException("The object selector contained no property selectors.", nameof(objectSelector));
                    }
                    if (false == propertySelector.PropertyDef.IsResolved)
                    {
                        throw new InvalidOperationException("The property value selector property definition is not resolved");
                    }

                    // Retrieve the element for the property value.
                    // var matchingPropertyElement = matchingElement
                    //	.XPathSelectElement(propertySelector.XPathQuery, xmlNamespaceManager);
                    //if (null == matchingPropertyElement)
                    //	continue;

                    // Find the property definition type.
                    var propertyDefType = vault
                                          .PropertyDefOperations
                                          .GetPropertyDef(propertySelector.PropertyDef.ID)
                                          .DataType;

                    // Check if it's lookup or multilookup
                    var isLookup = ((propertyDefType == MFDataType.MFDatatypeMultiSelectLookup) || (propertyDefType == MFDataType.MFDatatypeLookup));

                    #region itterate XAttributes from XPath
                    if (propertySelector.XPathQuery.Contains("@"))
                    {
                        List <int>  listLookup = new List <int>();
                        IEnumerable matchingPropertyAttributes =
                            (IEnumerable)matchingElement.XPathEvaluate(propertySelector.XPathQuery);
                        foreach (System.Xml.Linq.XAttribute matchingPropertyAttribute in matchingPropertyAttributes)
                        {
                            string szValue = matchingPropertyAttribute.Value;

                            if (propertyDefType == MFDataType.MFDatatypeBoolean)
                            {
                                propertyValuesBuilder.Add(
                                    propertySelector.PropertyDef.ID,
                                    propertyDefType,
                                    CastToBool(szValue));
                            }
                            else if (propertyDefType == MFDataType.MFDatatypeDate)
                            {
                                szValue = $"{szValue} 00:00:00";
                                propertyValuesBuilder.Add(
                                    propertySelector.PropertyDef.ID,
                                    propertyDefType,
                                    szValue);
                            }
                            else if (isLookup)
                            {
                                var iLookupDef = (propertySelector.LookupOrValuelistStrategy == LookupOrValuelistStrategy.SearchLookup ?
                                                  propertySelector.LookupObjectDef.ID :
                                                  propertySelector.LookupValueListDef.ID);

                                var iLookupItem = LookupRef(vault,
                                                            iLookupDef,
                                                            propertyDefType,
                                                            propertySelector.SearchByLookupID,
                                                            szValue,
                                                            propertySelector.LookupOrValuelistStrategy);

                                if (iLookupItem != -1)
                                {
                                    listLookup.Add(iLookupItem);
                                }
                            }
                            else
                            {
                                propertyValuesBuilder.Add(
                                    propertySelector.PropertyDef.ID,
                                    propertyDefType,
                                    szValue);
                            }
                        }

                        // Lookup or MultiSelectLookup and found something
                        if ((isLookup) && (listLookup.Count != 0))
                        {
                            int[] arrLookupIDs = listLookup.ToArray();
                            propertyValuesBuilder.Add(
                                propertySelector.PropertyDef.ID,
                                propertyDefType,
                                arrLookupIDs);
                        }
                    }
                    #endregion
                    else
                    #region itterate XElements from XPath
                    {
                        List <int> listLookup = new List <int>();
                        var        matchingPropertyElements =
                            matchingElement.XPathSelectElements(propertySelector.XPathQuery);
                        if (null == matchingPropertyElements)
                        {
                            continue;
                        }

                        // iterate found XElements
                        foreach (var matchingPropertyElement in matchingPropertyElements)
                        {
                            if (null == matchingPropertyElement)
                            {
                                continue;
                            }

                            string szValue = matchingPropertyElement.Value;

                            if (propertyDefType == MFDataType.MFDatatypeBoolean)
                            {
                                propertyValuesBuilder.Add(
                                    propertySelector.PropertyDef.ID,
                                    propertyDefType,
                                    CastToBool(szValue));
                            }
                            else if (propertyDefType == MFDataType.MFDatatypeDate)
                            {
                                szValue = $"{szValue} 00:00:00";
                                propertyValuesBuilder.Add(
                                    propertySelector.PropertyDef.ID,
                                    propertyDefType,
                                    szValue);
                            }
                            else if (isLookup)
                            {
                                var iLookupDef = (propertySelector.LookupOrValuelistStrategy == LookupOrValuelistStrategy.SearchLookup ?
                                                  propertySelector.LookupObjectDef.ID :
                                                  propertySelector.LookupValueListDef.ID);

                                var iLookupItem = LookupRef(vault,
                                                            iLookupDef,
                                                            propertyDefType,
                                                            propertySelector.SearchByLookupID,
                                                            szValue,
                                                            propertySelector.LookupOrValuelistStrategy);

                                if (iLookupItem != -1)
                                {
                                    listLookup.Add(iLookupItem);
                                }
                                propertyValuesBuilder.AddLookup(
                                    propertySelector.PropertyDef.ID,
                                    szValue);
                            }
                            else
                            {
                                propertyValuesBuilder.Add(
                                    propertySelector.PropertyDef.ID,
                                    propertyDefType,
                                    szValue);
                            }
                        }
                        // Lookup or MultiSelectLookup and found something
                        if ((isLookup) && (listLookup.Count != 0))
                        {
                            int[] arrLookupIDs = listLookup.ToArray();
                            propertyValuesBuilder.Add(
                                propertySelector.PropertyDef.ID,
                                propertyDefType,
                                arrLookupIDs);
                        }
                    }
                    #endregion

                    // Add the property to the builder.
                    //propertyValuesBuilder.Add(
                    //propertySelector.PropertyDef.ID,
                    //propertyDefType,
                    //matchingPropertyElement.Value);
                }

                // Set the static values
                foreach (var staticPropertyValue in objectSelector.StaticPropertyValues ?? new List <StaticPropertyValue>())
                {
                    // Sanity.
                    if (false == staticPropertyValue.PropertyDef.IsResolved)
                    {
                        throw new InvalidOperationException("The property value selector property definition is not resolved");
                    }

                    // Find the property definition type.
                    var propertyDefType = vault
                                          .PropertyDefOperations
                                          .GetPropertyDef(staticPropertyValue.PropertyDef.ID)
                                          .DataType;

                    // Add the property to the builder.
                    propertyValuesBuilder.Add(
                        staticPropertyValue.PropertyDef.ID,
                        propertyDefType,
                        staticPropertyValue.Value);
                }


                // Create a reference to the parent?
                if (null != parent)
                {
                    // If the property definition to use was configured then use that.
                    if (true == objectSelector.ParentRelationshipPropertyDef?.IsResolved)
                    {
                        // Check that this property is a list and is for the correct object type.
                        var parentRelationshipPropertyDef = vault
                                                            .PropertyDefOperations
                                                            .GetPropertyDef(objectSelector.ParentRelationshipPropertyDef.ID);
                        if (false == parentRelationshipPropertyDef.BasedOnValueList ||
                            parentRelationshipPropertyDef.ValueList != parent.Type)
                        {
                            throw new InvalidOperationException(
                                      $"The property def {parentRelationshipPropertyDef.Name} ({parentRelationshipPropertyDef.ID}) is not based on value list {parent.Type}.");
                        }

                        // Use the configured property definition.
                        propertyValuesBuilder.Add(
                            parentRelationshipPropertyDef.ID,
                            parentRelationshipPropertyDef.DataType,
                            parent.ID);
                    }
                    else
                    {
                        // Retrieve data about the parent object type.
                        var parentObjectType = vault
                                               .ObjectTypeOperations
                                               .GetObjectType(parent.Type);

                        // Retrieve data about the child object type.
                        var childObjectType = vault
                                              .ObjectTypeOperations
                                              .GetObjectType(objectSelector.ObjectType.ID);

                        // Is there an owner for this child type?
                        if (childObjectType.HasOwnerType)
                        {
                            // Use the "owner" property definition.
                            propertyValuesBuilder.Add(
                                parentObjectType.OwnerPropertyDef,
                                MFDataType.MFDatatypeLookup,
                                parent.ID);
                        }
                        else
                        {
                            // Use the default property definition.
                            propertyValuesBuilder.Add(
                                parentObjectType.DefaultPropertyDef,
                                MFDataType.MFDatatypeMultiSelectLookup,
                                parent.ID);
                        }
                    }
                }

                // Create a container for any attached files.
                var sourceObjectFiles = new SourceObjectFiles();

                // Should we attach the file to this object?
                if (objectSelector.AttachFileToThisObject)
                {
                    // Locate the files to retrieve.
                    sourceObjectFiles = this.FindFilesToAttach(objectSelector, xmlFile, matchingElement, xmlNamespaceManager);

                    // If we were supposed to attach a file but no files were found then throw an exception.
                    if (objectSelector.AttachedFileConfiguration?.FileNotFoundHandlingStrategy == FileNotFoundHandlingStrategy.Fail &&
                        0 == sourceObjectFiles.Count)
                    {
                        throw new InvalidOperationException("Attached file expected but not found.");
                    }

                    if (objectSelector.AttachedFileConfiguration?.AttachedFileHandlingStrategy
                        == AttachedFileHandlingStrategy.AttachToCurrentObject)
                    {
                        // Retrieve information about the object type from the vault.
                        var objectType = vault
                                         .ObjectTypeOperations
                                         .GetObjectType(objectSelector.ObjectType.ID);

                        // If the object type cannot have files but we are meant to attach a file, then fail.
                        if (false == objectType.CanHaveFiles)
                        {
                            throw new InvalidOperationException(
                                      $"The object type {objectType.NameSingular} cannot have files, but the configuration states to attach a file.");
                        }
                    }
                }

                // Which source object files should we use for the new object?
                var sourceObjectFilesForNewObject = objectSelector.AttachedFileConfiguration?.AttachedFileHandlingStrategy
                                                    == AttachedFileHandlingStrategy.AttachToCurrentObject
                                        ? sourceObjectFiles
                                        : new SourceObjectFiles();

                // Add the object to the vault.
                var createdObject = vault
                                    .ObjectOperations
                                    .CreateNewObjectEx(
                    objectSelector.ObjectType.ID,
                    propertyValuesBuilder.Values,
                    sourceObjectFilesForNewObject,
                    SFD: objectSelector.ObjectType.ID == (int)MFBuiltInObjectType.MFBuiltInObjectTypeDocument &&
                    sourceObjectFilesForNewObject.Count == 1
                    );

                // The files which need to be deleted.
                attachedFilesToDelete.AddRange(
                    sourceObjectFiles
                    .Cast <SourceObjectFile>()
                    .Select(sof => new FileInfo(sof.SourceFilePath))
                    );

                // Are there any related objects (e.g. children) to create?
                foreach (var childObjectSelector in objectSelector.ChildObjectSelectors)
                {
                    attachedFilesToDelete.AddRange(this.ImportXmlFile(vault,
                                                                      matchingElement,
                                                                      childObjectSelector,
                                                                      xmlFile: xmlFile,
                                                                      parent: createdObject.ObjVer,
                                                                      xmlNamespaceManager: xmlNamespaceManager));
                }

                // Clean up the collections we were using.
                propertyValuesBuilder = new MFPropertyValuesBuilder(vault);

                // Handle creating a new object for the file.
                if (
                    objectSelector.AttachFileToThisObject &&
                    objectSelector.AttachedFileConfiguration?.AttachedFileHandlingStrategy
                    == AttachedFileHandlingStrategy.CreateNewObject)
                {
                    // Set the static values
                    foreach (var staticPropertyValue in objectSelector.AttachedFileConfiguration?.StaticPropertyValues ?? new List <StaticPropertyValue>())
                    {
                        // Sanity.
                        if (false == staticPropertyValue.PropertyDef.IsResolved)
                        {
                            throw new InvalidOperationException("The property value selector property definition is not resolved");
                        }

                        // Find the property definition type.
                        var propertyDefType = vault
                                              .PropertyDefOperations
                                              .GetPropertyDef(staticPropertyValue.PropertyDef.ID)
                                              .DataType;

                        // Add the property to the builder.
                        propertyValuesBuilder.Add(
                            staticPropertyValue.PropertyDef.ID,
                            propertyDefType,
                            staticPropertyValue.Value);
                    }

                    // Add the class property value.
                    propertyValuesBuilder.SetClass(objectSelector.AttachedFileConfiguration.Class.ID);

                    // Add a reference from this new object to the one we created earlier.
                    {
                        // Retrieve data about the parent object type.
                        var parentObjectType = vault
                                               .ObjectTypeOperations
                                               .GetObjectType(createdObject.ObjVer.Type);

                        // Set the relationship.
                        propertyValuesBuilder.Add(
                            parentObjectType.DefaultPropertyDef,
                            MFDataType.MFDatatypeMultiSelectLookup,
                            createdObject.ObjVer.ID);
                    }

                    // Add the object to the vault.
                    var createdDocumentObject = vault
                                                .ObjectOperations
                                                .CreateNewObjectEx(
                        objectSelector.AttachedFileConfiguration.ObjectType.ID,
                        propertyValuesBuilder.Values,
                        sourceObjectFiles,
                        SFD: objectSelector.AttachedFileConfiguration.ObjectType.ID == (int)MFBuiltInObjectType.MFBuiltInObjectTypeDocument &&
                        sourceObjectFiles.Count == 1
                        );
                }
            }

            // Return the files to remove.
            return(attachedFilesToDelete);
        }
コード例 #3
0
        /// <summary>
        /// Implementation for <see cref="CreateCopy(ObjVerEx, ObjectCopyOptions" />.
        /// Interaction with the vault is via the <paramref name="objectCopyCreator"/>.
        /// </summary>
        /// <param name="source">The source object to copy.</param>
        /// <param name="objectCopyOptions">Options about how to copy the object.</param>
        /// <param name="objectCopyCreator">The instance that will actually create the copy.</param>
        /// <returns></returns>
        internal static ObjVerEx CreateCopy
        (
            this ObjVerEx source,
            ObjectCopyOptions objectCopyOptions  = null,
            IObjectCopyCreator objectCopyCreator = null
        )
        {
            // Sanity.
            if (null == source)
            {
                throw new ArgumentNullException(nameof(source));
            }
            objectCopyOptions = objectCopyOptions ?? new ObjectCopyOptions();
            objectCopyCreator = objectCopyCreator ?? new ObjectCopyCreator();

            // Create properties for the new object.
            // If we should copy the source properties then start there,
            // otherwise use an empty collection.
            var propertyValues = new MFPropertyValuesBuilder
                                 (
                source.Vault,
                objectCopyOptions.CopySourceProperties ? source.Properties.Clone() : new PropertyValues()
                                 );

            // Remove system properties if requested.
            if (objectCopyOptions.RemoveSystemProperties)
            {
                propertyValues.RemoveSystemProperties();
            }

            // Create an instruction to set SFD to false (will be applied in next section).
            // Will be set accordingly later.
            {
                var instruction = new PropertyValueInstruction()
                {
                    InstructionType = PropertyValueInstructionType.RemovePropertyValue
                };
                instruction.PropertyValue.PropertyDef =
                    (int)MFBuiltInPropertyDef.MFBuiltInPropertyDefSingleFileObject;
                objectCopyOptions.Properties.Add(instruction);
            }

            // Modify the properties as appropriate by running the instructions.
            if (null != objectCopyOptions.Properties)
            {
                foreach (var instruction in objectCopyOptions.Properties)
                {
                    if (null == instruction)
                    {
                        continue;
                    }
                    instruction.ApplyTo(propertyValues.Values);
                }
            }

            // Are there any properties that are deleted?
            foreach (PropertyValue property in propertyValues.Values.Clone())
            {
                try
                {
                    var loadedProperty = source.Vault.PropertyDefOperations.GetPropertyDef(property.PropertyDef);
                }
                catch
                {
                    // Property cannot be loaded; it has been deleted.
                    propertyValues.Values.RemoveProperty(property.PropertyDef);
                }
            }

            // Create the object, but do not check it in.
            var newObject = new ObjVerEx(source.Vault, objectCopyCreator.CreateObject
                                         (
                                             source.Vault,
                                             objectCopyOptions.TargetObjectType ?? source.ObjVer.Type,
                                             propertyValues.Values,
                                             sourceObjectFiles: null,   // We will add these later.
                                             singleFileDocument: false, // Always false here, until we know how many files we're copying.
                                             checkIn: false,            // Don't check in until the files have been added.
                                             accessControlList: objectCopyOptions.CopySourceACL ? source.ACL : null
                                         ));

            // Copy the source files to the new object.
            var fileCount = 0;

            if (objectCopyOptions.CopySourceFiles && null != source?.Info?.Files)
            {
                // Note: using .Cast() here throws out our Moq tests, so let's not use it...
                foreach (ObjectFile file in source.Info.Files)
                {
                    fileCount++;
                    using (var fileStream = file.OpenRead(source.Vault))
                    {
                        objectCopyCreator.AddFile(newObject, file.Title, file.Extension, fileStream);
                    }
                }
            }

            // Add any additional files.
            if (null != objectCopyOptions.AdditionalFiles)
            {
                foreach (SourceObjectFile sourceFile in objectCopyOptions.AdditionalFiles)
                {
                    fileCount++;
                    objectCopyCreator.AddFile
                    (
                        newObject,
                        sourceFile.Title,
                        sourceFile.Extension,
                        sourceFile.SourceFilePath
                    );
                }
            }

            // If the option is set to false then we'll get whatever the source was
            // (unless it went from a document to something else, in which case it's always false).
            if (objectCopyOptions.SetSingleFileDocumentIfAppropriate)
            {
                // True if a single file.
                objectCopyCreator.SetSingleFileDocument
                (
                    newObject,
                    newObject.Type == (int)MFBuiltInObjectType.MFBuiltInObjectTypeDocument &&
                    fileCount == 1
                );
            }

            // Check in?
            if (objectCopyOptions.CheckInObject)
            {
                objectCopyCreator.CheckIn
                (
                    newObject,
                    objectCopyOptions.CheckInComments ?? "",
                    objectCopyOptions.CreatedByUserId ?? -1
                );
            }

            // Return the shiny new object.
            return(newObject);
        }