public void BE_hashes_stream()
        {
            var value = StringUtil.CreateAlphaNumericKey(20);
            var be    = new ResourceContentBE(value, MimeType.TEXT_UTF8);

            Assert.AreEqual(StringUtil.ComputeHashString(value, Encoding.UTF8), be.ComputeHashString());
        }
        public void Can_roundtrip_text_through_BE()
        {
            var text = StringUtil.CreateAlphaNumericKey(20);
            var be   = new ResourceContentBE(text, MimeType.TEXT_UTF8);

            Assert.AreEqual(text, be.ToText());
        }
Exemplo n.º 3
0
        private static ResourceBE PopulateFile(IDataRecord dr)
        {
            string   name              = GetUTF8String(dr, "img_name");
            uint     size              = DbUtils.Convert.To <uint>(dr["img_size"], 0);
            MimeType mimetype          = new MimeType(GetUTF8String(dr, "img_major_mime") + "/" + GetUTF8String(dr, "img_minor_mime"));
            string   changedescription = GetUTF8String(dr, "img_description");
            uint     userId;

            if (MediaWikiConverterContext.Current.Merge)
            {
                userId = MediaWikiConverterContext.Current.MergeUserId;
            }
            else
            {
                userId = DbUtils.Convert.To <uint>(dr["img_user"], 0);
            }

            // TODO (steveb): why is this not used?!?
            DateTime timestamp = DbUtils.ToDateTime(GetUTF8String(dr, "img_timestamp"));

            ResourceContentBE rc = new ResourceContentBE(true);

            rc.Size     = size;
            rc.MimeType = mimetype;

            ResourceBE file = ResourceBL.Instance.BuildRevForNewResource(0 /*parent page defined later*/, ResourceBE.ParentType.PAGE, name, mimetype, size, changedescription, ResourceBE.Type.FILE, userId, rc);

            file.MetaXml.Elem("physicalfilename", GetUTF8String(dr, "img_filename"));
            return(file);
        }
        public void Can_write_bytes_to_blank_BE()
        {
            var be = new ResourceContentBE(true);
            var v  = 42;

            be.SetData(BitConverter.GetBytes(v));
            Assert.AreEqual(v, BitConverter.ToInt32(be.ToBytes(), 0));
        }
        public void Can_create_BE_from_XDoc()
        {
            var doc = new XDoc("test").Elem("foo", StringUtil.CreateAlphaNumericKey(6));
            var be  = new ResourceContentBE(doc);

            var doc2 = XDocFactory.From(be.ToStream(), be.MimeType);

            Assert.AreEqual(doc, doc2);
        }
Exemplo n.º 6
0
 public ResourceBE UpdatePropertyContent(ResourceBE prop, ResourceContentBE content, string changeDescription, string eTag, AbortEnum abort, XUri parentUri, ResourceBE.ParentType parentType)
 {
     if (abort == AbortEnum.Modified)
     {
         _resourceBL.ValidateEtag(eTag, prop, true);
     }
     prop = _resourceBL.BuildRevForContentUpdate(prop, content.MimeType, content.Size, changeDescription, null, content);
     prop = _resourceBL.SaveResource(prop);
     DekiContext.Current.Instance.EventSink.PropertyUpdate(DekiContext.Current.Now, prop, DekiContext.Current.User, parentType, parentUri);
     return(prop);
 }
        public void Can_create_BE_from_Stream()
        {
            var stream = new MemoryStream();
            var bytes  = Encoding.UTF8.GetBytes("foo");

            stream.Write(bytes, 0, bytes.Length);
            stream.Position = 0;
            var be = new ResourceContentBE(stream, MimeType.TEXT_UTF8);

            Assert.AreEqual(MimeType.TEXT_UTF8, be.MimeType);
            Assert.AreEqual(stream.Length, be.Size);
            Assert.AreEqual(stream.Length, be.ToBytes().Length);
        }
Exemplo n.º 8
0
        private ResourceContentBE Resources_ContentInsert(ResourceContentBE contents)
        {
            string query = @" /* ResourceDA::ContentInsert */
insert into resourcecontents (rescontent_res_id, rescontent_res_rev, rescontent_location, rescontent_mimetype, rescontent_size, rescontent_value)
values (?RESCONTENT_RES_ID, ?RESCONTENT_RES_REV, ?RESCONTENT_LOCATION, ?RESCONTENT_MIMETYPE, ?RESCONTENT_SIZE, ?RESCONTENT_VALUE);
select last_insert_id();";

            contents.ContentId = Catalog.NewQuery(query)
                                 .With("RESCONTENT_RES_ID", contents.ResourceId)
                                 .With("RESCONTENT_RES_REV", contents.Revision)
                                 .With("RESCONTENT_LOCATION", contents.Location)
                                 .With("RESCONTENT_MIMETYPE", contents.MimeType.ToString())
                                 .With("RESCONTENT_SIZE", contents.Size)
                                 .With("RESCONTENT_VALUE", contents.IsDbBased ? contents.ToBytes() : null)
                                 .ReadAsUInt() ?? 0;

            return(contents);
        }
Exemplo n.º 9
0
        protected ResourceBE BuildRevForContentUpdate(ResourceBE currentResource, MimeType mimeType, uint size, string description, string name, ResourceContentBE newContent)
        {
            ResourceBE newRev = _resourceBL.BuildRevForContentUpdate(currentResource, mimeType, size, description, name, newContent);

            newRev.MetaXml.FileId = currentResource.MetaXml.FileId;
            return(newRev);
        }
Exemplo n.º 10
0
        public ResourceBE AddAttachment(ResourceBE existingRevision, Stream filestream, long filesize, MimeType mimeType, PageBE targetPage, string userDescription, string fileName, bool isMsWebDav)
        {
            if (_dekiContext.Instance.MaxFileSize < filesize)
            {
                throw new AttachmentMaxFileSizeAllowedInvalidArgumentException(_dekiContext.Instance.MaxFileSize);
            }
            var saveFileName = ValidateFileName(fileName);

            if (existingRevision != null)
            {
                if (!saveFileName.EqualsInvariant(existingRevision.Name))
                {
                    // An existing file is getting renamed. Make sure no file exists with the new name
                    var existingAttachment = GetPageAttachment(targetPage.ID, saveFileName);
                    if (existingAttachment != null)
                    {
                        throw new AttachmentExistsOnPageConflictException(saveFileName, targetPage.Title.AsUserFriendlyName());
                    }
                }
            }

            // If file is found but has been deleted, create a new file.
            if (existingRevision != null && existingRevision.ResourceIsDeleted)
            {
                existingRevision = null;
            }
            if (isMsWebDav)
            {
                _log.DebugFormat("Upload client is MD WebDAV, provided mimetype is: {0}", mimeType);
                var extensionFileType = MimeType.FromFileExtension(Path.GetExtension(saveFileName));
                if (!extensionFileType.Match(mimeType) || extensionFileType == MimeType.DefaultMimeType)
                {
                    mimeType = existingRevision == null ? extensionFileType : existingRevision.MimeType;
                    _log.DebugFormat("using mimetype '{0}' instead", mimeType);
                }
            }
            ResourceBE attachment;
            var        resourceContents = new ResourceContentBE((uint)filesize, mimeType);
            var        isUpdate         = false;

            if (existingRevision == null)
            {
                attachment = _resourceBL.BuildRevForNewResource((uint)targetPage.ID, ResourceBE.ParentType.PAGE, saveFileName, mimeType, (uint)filesize, null, ResourceBE.Type.FILE, _dekiContext.User.ID, resourceContents);
            }
            else
            {
                isUpdate   = true;
                attachment = BuildRevForContentUpdate(existingRevision, mimeType, (uint)filesize, null, saveFileName, resourceContents);
            }

            // rewrite mimetype to text/plain for certain extensions
            string extension = attachment.FilenameExtension;

            if (_dekiContext.Instance.FileExtensionForceAsTextList.Any(forcedExtensions => extension == forcedExtensions))
            {
                attachment.MimeType = MimeType.TEXT;
            }

            // Insert the attachment into the DB
            attachment = SaveResource(attachment);
            try {
                // Save file to storage provider
                _dekiContext.Instance.Storage.PutFile(attachment, SizeType.ORIGINAL, new StreamInfo(filestream, filesize, mimeType));
            } catch (Exception x) {
                _dekiContext.Instance.Log.WarnExceptionFormat(x, "Failed to save attachment to storage provider");

                // Upon save failure, delete the record from the db.
                _session.Resources_DeleteRevision(attachment.ResourceId, attachment.Revision);
                throw;
            }

            // Set description property
            if (!string.IsNullOrEmpty(userDescription))
            {
                attachment = SetDescription(attachment, userDescription);
            }

            // For images resolve width/height (if not in imagemagick's blacklist)
            attachment = IdentifyUnknownImage(attachment);

            // Pre render thumbnails of images
            AttachmentPreviewBL.PreSaveAllPreviews(attachment);
            PageBL.Touch(targetPage, DateTime.UtcNow);

            //TODO MaxM: Connect with transaction
            RecentChangeBL.AddFileRecentChange(targetPage.Touched, targetPage, _dekiContext.User, DekiResources.FILE_ADDED(attachment.Name), 0);
            if (isUpdate)
            {
                _dekiContext.Instance.EventSink.AttachmentUpdate(_dekiContext.Now, attachment, _dekiContext.User);
            }
            else
            {
                _dekiContext.Instance.EventSink.AttachmentCreate(_dekiContext.Now, attachment, _dekiContext.User);
            }
            return(attachment);
        }
Exemplo n.º 11
0
        private ResourceContentBE Resources_ContentInsert(ResourceContentBE contents) {

            string query = @" /* ResourceDA::ContentInsert */
insert into resourcecontents (rescontent_res_id, rescontent_res_rev, rescontent_location, rescontent_mimetype, rescontent_size, rescontent_value)
values (?RESCONTENT_RES_ID, ?RESCONTENT_RES_REV, ?RESCONTENT_LOCATION, ?RESCONTENT_MIMETYPE, ?RESCONTENT_SIZE, ?RESCONTENT_VALUE);
select last_insert_id();";

            contents.ContentId = Catalog.NewQuery(query)
            .With("RESCONTENT_RES_ID", contents.ResourceId)
            .With("RESCONTENT_RES_REV", contents.Revision)
            .With("RESCONTENT_LOCATION", contents.Location)
            .With("RESCONTENT_MIMETYPE", contents.MimeType.ToString())
            .With("RESCONTENT_SIZE", contents.Size)
            .With("RESCONTENT_VALUE", contents.IsDbBased ? contents.ToBytes() : null)
            .ReadAsUInt() ?? 0;

            return contents;
        }
Exemplo n.º 12
0
        public ResourceBE Resources_SaveRevision(ResourceBE resource)
        {
            string query          = string.Empty;
            bool   contentUpdated = false;

            if (resource.Content != null && resource.Content.IsNewContent())
            {
                contentUpdated = true;
                ResourceContentBE content = Resources_ContentInsert(resource.Content);
                resource.Content   = content;
                resource.ContentId = content.ContentId;
            }

            if (resource.IsNewResource())
            {
                query = @" /* Resources_SaveRevision (new resource) */
set @resourceid = 0;

insert into resources set
res_headrev =               ?RES_HEADREV, 
res_type =                  ?RES_TYPE, 
res_deleted =               ?RES_DELETED, 
res_create_timestamp =      ?RES_CREATE_TIMESTAMP, 
res_update_timestamp =      ?RES_UPDATE_TIMESTAMP, 
res_create_user_id =        ?RES_CREATE_USER_ID, 
res_update_user_id =        ?RES_UPDATE_USER_ID, 
resrev_rev =                ?RESREV_REV, 
resrev_user_id =            ?RESREV_USER_ID, 
resrev_parent_id =          ?RESREV_PARENT_ID, 
resrev_parent_page_id =     ?RESREV_PARENT_PAGE_ID, 
resrev_parent_user_id =     ?RESREV_PARENT_USER_ID, 
resrev_change_mask =        ?RESREV_CHANGE_MASK, 
resrev_name =               ?RESREV_NAME, 
resrev_change_description = ?RESREV_CHANGE_DESCRIPTION, 
resrev_timestamp =          ?RESREV_TIMESTAMP, 
resrev_content_id =         ?RESREV_CONTENT_ID, 
resrev_deleted =            ?RESREV_DELETED, 
resrev_changeset_id =       ?RESREV_CHANGESET_ID, 
resrev_size =               ?RESREV_SIZE, 
resrev_mimetype =           ?RESREV_MIMETYPE, 
resrev_language =           ?RESREV_LANGUAGE,
resrev_is_hidden =          ?RESREV_IS_HIDDEN, 
resrev_meta =               ?RESREV_META;

select last_insert_id() into @resourceid;

insert into resourcerevs set 
resrev_res_id =             @resourceid,
resrev_rev =                ?RESREV_REV,
resrev_user_id =            ?RESREV_USER_ID,
resrev_parent_id =          ?RESREV_PARENT_ID,
resrev_parent_page_id =     ?RESREV_PARENT_PAGE_ID,
resrev_parent_user_id =     ?RESREV_PARENT_USER_ID,
resrev_change_mask =        ?RESREV_CHANGE_MASK,
resrev_name =               ?RESREV_NAME,
resrev_change_description = ?RESREV_CHANGE_DESCRIPTION,
resrev_timestamp =          ?RESREV_TIMESTAMP,
resrev_content_id =         ?RESREV_CONTENT_ID,
resrev_deleted =            ?RESREV_DELETED,
resrev_changeset_id =       ?RESREV_CHANGESET_ID,
resrev_size =               ?RESREV_SIZE,
resrev_mimetype =           ?RESREV_MIMETYPE,
resrev_language =           ?RESREV_LANGUAGE,
resrev_is_hidden =          ?RESREV_IS_HIDDEN,
resrev_meta =               ?RESREV_META;

update resourcecontents set 
rescontent_res_id =     @resourceid,
rescontent_res_rev =    ?RESREV_REV
where rescontent_id =   ?RESREV_CONTENT_ID;

select *
from resources
left join resourcecontents
    on resources.resrev_content_id = resourcecontents.rescontent_id
where res_id = @resourceid;

/* End of ResourceDA::InsertResourceRevision (new resource) */
";
            }
            else
            {
                resource.Revision = ++resource.ResourceHeadRevision;
                if (contentUpdated)
                {
                    resource.Content.Revision = (uint)resource.Revision;
                }

                query = @" /* Resources_SaveRevision + concurrency check (new revision) */
update resources set 
res_headrev =               ?RES_HEADREV,
res_type =                  ?RES_TYPE,
res_deleted =               ?RES_DELETED,
res_update_timestamp =      ?RESREV_TIMESTAMP,
res_update_user_id =        ?RES_UPDATE_USER_ID,
resrev_rev =                ?RESREV_REV,
resrev_user_id =            ?RESREV_USER_ID,
resrev_parent_id =          ?RESREV_PARENT_ID,
resrev_parent_page_id =     ?RESREV_PARENT_PAGE_ID,
resrev_parent_user_id =     ?RESREV_PARENT_USER_ID,
resrev_change_mask =        ?RESREV_CHANGE_MASK,
resrev_name =               ?RESREV_NAME,
resrev_change_description = ?RESREV_CHANGE_DESCRIPTION,
resrev_timestamp =          ?RESREV_TIMESTAMP,
resrev_content_id =         ?RESREV_CONTENT_ID,
resrev_deleted =            ?RESREV_DELETED,
resrev_changeset_id =       ?RESREV_CHANGESET_ID,
resrev_size =               ?RESREV_SIZE,
resrev_mimetype =           ?RESREV_MIMETYPE,
resrev_language =           ?RESREV_LANGUAGE,
resrev_is_hidden =          ?RESREV_IS_HIDDEN,
resrev_meta =               ?RESREV_META
WHERE res_id =              ?RES_ID
AND res_headrev =           ?RES_HEADREV - 1
AND res_update_timestamp =  ?RES_UPDATE_TIMESTAMP;

select ROW_COUNT() into @affectedRows;

select *
from resources
where @affectedrows > 0
and res_id = ?RES_ID;
";
                if (ArrayUtil.IsNullOrEmpty(Resources_ExecuteInsertUpdateQuery(resource, query)))
                {
                    //Cleanup content row if resource could not be updated
                    Resources_ContentDelete(resource.ContentId);
                    throw new ResourceConcurrencyException(resource.ResourceId);
                }
                query = @" /* Resources_SaveRevision (new revision) */
replace into resourcerevs set 
resrev_res_id =             ?RES_ID,
resrev_rev =                ?RESREV_REV,
resrev_user_id =            ?RESREV_USER_ID, 
resrev_parent_id =          ?RESREV_PARENT_ID,
resrev_parent_page_id =     ?RESREV_PARENT_PAGE_ID,
resrev_parent_user_id =     ?RESREV_PARENT_USER_ID,
resrev_change_mask =        ?RESREV_CHANGE_MASK,
resrev_name =               ?RESREV_NAME,
resrev_change_description = ?RESREV_CHANGE_DESCRIPTION,
resrev_timestamp =          ?RESREV_TIMESTAMP,
resrev_content_id =         ?RESREV_CONTENT_ID,
resrev_deleted =            ?RESREV_DELETED,
resrev_changeset_id =       ?RESREV_CHANGESET_ID,
resrev_size =               ?RESREV_SIZE,
resrev_mimetype =           ?RESREV_MIMETYPE,
resrev_language =           ?RESREV_LANGUAGE,
resrev_is_hidden =          ?RESREV_IS_HIDDEN,
resrev_meta =               ?RESREV_META;

update resourcecontents set 
rescontent_res_id =     ?RES_ID,
rescontent_res_rev =    ?RESCONTENT_RES_REV
where rescontent_id =   ?RESREV_CONTENT_ID;

select *
from resources
left join resourcecontents
    on resources.resrev_content_id = resourcecontents.rescontent_id
where res_id = ?RES_ID;
";
            }

            ResourceBE[] ret = Resources_ExecuteInsertUpdateQuery(resource, query);
            return((ArrayUtil.IsNullOrEmpty(ret)) ? null : ret[0]);
        }
Exemplo n.º 13
0
        public virtual ResourceBE BuildRevForContentUpdate(ResourceBE currentResource, MimeType mimeType, uint size, string description, string name, ResourceContentBE newContent)
        {
            ResourceBE newRev = BuildRevForExistingResource(currentResource, mimeType, size, description);

            newRev.Content     = newContent;
            newRev.ContentId   = 0;
            newRev.ChangeMask |= ResourceBE.ChangeOperations.CONTENT;
            if (name != null && !StringUtil.EqualsInvariant(name, newRev.Name))
            {
                newRev.ChangeMask |= ResourceBE.ChangeOperations.NAME;
                newRev.Name        = name;
            }
            return(newRev);
        }
Exemplo n.º 14
0
        private ResourceBE BuildRevForNewResource(string resourcename, MimeType mimeType, uint size, string description, ResourceBE.Type resourceType, uint userId, ResourceContentBE content)
        {
            ResourceBE newResource = new ResourceBE(resourceType);

            newResource.Name                 = resourcename;
            newResource.ChangeMask           = newResource.ChangeMask | ResourceBE.ChangeOperations.NAME;
            newResource.Size                 = size;
            newResource.MimeType             = mimeType;
            newResource.ChangeDescription    = description;
            newResource.ResourceCreateUserId = newResource.ResourceUpdateUserId = newResource.UserId = userId;
            newResource.ChangeSetId          = 0;
            newResource.Timestamp            = newResource.ResourceCreateTimestamp = newResource.ResourceUpdateTimestamp = DateTime.UtcNow;
            newResource.Content              = content;
            newResource.ChangeMask           = newResource.ChangeMask | ResourceBE.ChangeOperations.CONTENT;
            newResource.ResourceHeadRevision = ResourceBE.TAILREVISION;
            newResource.Revision             = ResourceBE.TAILREVISION;
            newResource.IsHidden             = false;
            return(newResource);
        }
Exemplo n.º 15
0
        public virtual ResourceBE BuildRevForNewResource(uint?parentId, ResourceBE.ParentType parentType, string resourcename, MimeType mimeType, uint size, string description, ResourceBE.Type resourceType, uint userId, ResourceContentBE content)
        {
            ResourceBE newResource = BuildRevForNewResource(resourcename, mimeType, size, description, resourceType, userId, content);

            switch (parentType)
            {
            case ResourceBE.ParentType.PAGE:
                newResource.ParentPageId = parentId;
                break;

            case ResourceBE.ParentType.USER:
                newResource.ParentUserId = parentId;
                break;

            default:
                newResource.ParentId = parentId;
                break;
            }
            newResource.ChangeMask = newResource.ChangeMask | ResourceBE.ChangeOperations.PARENT;
            return(newResource);
        }
Exemplo n.º 16
0
        public ResourceBE[] SaveBatchProperties(uint?parentId, XUri parentUri, ResourceBE.ParentType parentType, XDoc doc, out string[] failedNames, out Dictionary <string, Exception> saveStatusByName)
        {
            //This is a specialized method that saves a batch of property updates in one request and connects them with a transaction.
            //Successful updates are returned
            //Status/description of each property update is returned as well as a hash of dreammessages by name

            saveStatusByName = new Dictionary <string, Exception>();
            List <string> failedNamesList = new List <string>();
            Dictionary <string, ResourceBE> resourcesByName = new Dictionary <string, ResourceBE>();
            List <ResourceBE> ret = new List <ResourceBE>();

            //Get list of names and perform dupe check
            foreach (XDoc propDoc in doc["/properties/property"])
            {
                string name = propDoc["@name"].AsText ?? string.Empty;
                if (resourcesByName.ContainsKey(name))
                {
                    throw new PropertyDuplicateInvalidOperationException(name);
                }

                resourcesByName[name] = null;
            }

            //Retrieve current properties with given name
            resourcesByName = _resourceBL.GetResources(parentId, parentType, ResourceBL.PROPERTIES, new List <string>(resourcesByName.Keys).ToArray(), DeletionFilter.ACTIVEONLY).AsHash(e => e.Name);

            //extract property info, build resource revisions, save resource, and maintain statuses for each save
            foreach (XDoc propDoc in doc["/properties/property"])
            {
                ResourceBE res = null;
                string     content;
                uint       contentLength = 0;
                string     description   = string.Empty;
                string     etag          = null;
                MimeType   mimeType;
                string     name = string.Empty;

                try {
                    name = propDoc["@name"].AsText ?? string.Empty;
                    resourcesByName.TryGetValue(name, out res);
                    if (propDoc["contents"].IsEmpty)
                    {
                        if (res == null)
                        {
                            throw new PropertyDeleteDoesNotExistInvalidArgumentException(name);
                        }
                        else
                        {
                            res = DeleteProperty(res, parentType, parentUri);
                        }
                    }
                    else
                    {
                        //parse content from xml
                        etag          = propDoc["@etag"].AsText;
                        description   = propDoc["description"].AsText;
                        content       = propDoc["contents"].Contents;
                        contentLength = (uint)(content ?? string.Empty).Length;
                        string mimeTypeStr = propDoc["contents/@type"].AsText;
                        if (string.IsNullOrEmpty(mimeTypeStr) || !MimeType.TryParse(mimeTypeStr, out mimeType))
                        {
                            throw new PropertyMimtypeInvalidArgumentException(name, mimeTypeStr);
                        }
                        ResourceContentBE resourceContent = new ResourceContentBE(content, mimeType);

                        if (res == null)
                        {
                            //new property
                            res = CreateProperty(parentId, parentUri, parentType, name, resourceContent, description, etag, AbortEnum.Exists);
                        }
                        else
                        {
                            //new revision
                            res = UpdatePropertyContent(res, resourceContent, description, etag, AbortEnum.Modified, parentUri, parentType);
                        }
                    }

                    ret.Add(res);
                    saveStatusByName[name] = null;
                } catch (ResourcedMindTouchException x) {
                    //Unexpected errors fall through while business logic errors while saving a property continues processing
                    saveStatusByName[name] = x;
                    failedNamesList.Add(name);
                } catch (DreamAbortException x) {
                    // TODO (arnec): remove this once all usage of DreamExceptions is purged from Deki logic

                    //Unexpected errors fall through while business logic errors while saving a property continues processing
                    saveStatusByName[name] = x;
                    failedNamesList.Add(name);
                }
            }

            failedNames = failedNamesList.ToArray();
            return(ret.ToArray());
        }
Exemplo n.º 17
0
        public ResourceBE CreateProperty(uint?parentId, XUri parentUri, ResourceBE.ParentType parentType, string name, ResourceContentBE content, string description, string etag, AbortEnum abort)
        {
            //TODO: The parent resource isn't verified when the resource name and the parent info is given
            ResourceBE prop = _resourceBL.GetResource(parentId, parentType, ResourceBE.Type.PROPERTY, name, DeletionFilter.ACTIVEONLY);

            if (prop != null)
            {
                switch (abort)
                {
                case AbortEnum.Exists:
                    throw new PropertyExistsConflictException(name);

                case AbortEnum.Modified:
                    _resourceBL.ValidateEtag(etag, prop, true);
                    break;
                }
                prop = _resourceBL.BuildRevForContentUpdate(prop, content.MimeType, content.Size, description, null, content);
                prop = _resourceBL.SaveResource(prop);
                DekiContext.Current.Instance.EventSink.PropertyUpdate(DekiContext.Current.Now, prop, DekiContext.Current.User, parentType, parentUri);
            }
            else
            {
                if ((abort == AbortEnum.Modified) && !string.IsNullOrEmpty(etag))
                {
                    throw new PropertyUnexpectedEtagConflictException();
                }
                prop = _resourceBL.BuildRevForNewResource(parentId, parentType, name, content.MimeType, content.Size, description, ResourceBE.Type.PROPERTY, DekiContext.Current.User.ID, content);
                prop = _resourceBL.SaveResource(prop);
                DekiContext.Current.Instance.EventSink.PropertyCreate(DekiContext.Current.Now, prop, DekiContext.Current.User, parentType, parentUri);
            }
            return(prop);
        }