Exemplo n.º 1
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);
        }
Exemplo n.º 2
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.º 3
0
        private void PropertyChanged(DateTime eventTime, ResourceBE prop, UserBE user, ResourceBE.ParentType parentType, XUri parentUri, params string[] path)
        {
            try {
                string parent = string.Empty;
                switch (parentType)
                {
                case ResourceBE.ParentType.PAGE:
                    parent = PAGES;
                    break;

                case ResourceBE.ParentType.FILE:
                    parent = FILES;
                    break;

                case ResourceBE.ParentType.USER:
                    parent = USERS;
                    break;

                case ResourceBE.ParentType.SITE:
                    parent = SITE;
                    break;
                }
                XUri     channel  = _channel.At(parent).At(PROPERTY).At(path);
                XUri     resource = prop.PropertyInfoUri(parentUri);
                string[] origin   = new string[] { resource.ToString() };
                XDoc     doc      = new XDoc("deki-event")
                                    .Elem("channel", channel)
                                    .Elem("name", prop.Name)
                                    .Elem("uri", resource)
                                    .Start("content")
                                    .Attr("mime-type", prop.MimeType.FullType)
                                    .Attr("size", prop.Size)
                                    .Attr("href", prop.PropertyContentUri(parentUri));
                if (prop.MimeType.MainType == MimeType.TEXT.MainType && prop.Size < 256)
                {
                    doc.Value(ResourceContentBL.Instance.Get(prop).ToText());
                }
                doc.End();
                if (parentType == ResourceBE.ParentType.PAGE)
                {
                    doc.Elem("pageid", prop.ParentPageId ?? 0);
                }
                else if (parentType == ResourceBE.ParentType.USER)
                {
                    doc.Elem("userid", prop.ParentUserId ?? 0);
                }
                else if (parentType == ResourceBE.ParentType.FILE)
                {
                    ResourceBE attachment = ResourceBL.Instance.GetResource(prop.ParentId.Value);
                    doc.Elem("fileid", attachment.MetaXml.FileId ?? 0);
                    PageDependentChanged(eventTime, PageBL.GetPageById(attachment.ParentPageId.Value), user, ArrayUtil.Concat(new string[] { FILES, PROPERTY }, path));
                }
                Queue(eventTime, channel, resource, origin, doc);
            } catch (Exception e) {
                _log.WarnExceptionMethodCall(e, "PropertyChanged", "event couldn't be created");
            }
        }
Exemplo n.º 4
0
        private void NotifyPropertyParent(DateTime eventTime, ResourceBE prop, UserBE user, ResourceBE.ParentType parentType, string action)
        {
            if (parentType == ResourceBE.ParentType.PAGE && prop.ParentPageId != null)
            {
                PageBE parentPage = PageBL.GetPageById(prop.ParentPageId.Value);
                if (parentPage != null)
                {
                    PageDependentChanged(eventTime, parentPage, user, PROPERTY, action);
                }
            }
            else if (parentType == ResourceBE.ParentType.USER)
            {
                // Owner of property may not be same as requesting user.
                // The dependentschanged event is triggered on the property owner.
                if (prop.ParentUserId != null)
                {
                    // Optimization to avoid a db call when operating on your own user property.
                    if (user.ID != prop.ParentUserId.Value)
                    {
                        user = UserBL.GetUserById(prop.ParentUserId.Value);
                        if (user == null)
                        {
                            _log.WarnFormat("Could not find owner user (id: {0}) of user property (key: {1})", prop.ParentUserId.Value, prop.Name);
                            return;
                        }
                    }
                }

                UserDependentChanged(eventTime, user, PROPERTY, action);
            }

            //TODO (maxm): trigger file property changes
        }
Exemplo n.º 5
0
 public void PropertyDelete(DateTime eventTime, ResourceBE prop, UserBE user, ResourceBE.ParentType parentType, XUri parentUri)
 {
     NotifyPropertyParent(eventTime, prop, user, parentType, DELETE);
     PropertyChanged(eventTime, prop, user, parentType, parentUri, DELETE);
 }
Exemplo n.º 6
0
 public IList <ResourceBE> GetResources(uint?parentId, ResourceBE.ParentType parentType, IList <ResourceBE.Type> resourceTypes, string[] names, DeletionFilter deletionStateFilter)
 {
     uint[] parentids = parentId == null ? new uint[] { } : new[] { parentId.Value };
     return(GetResources(parentids, parentType, resourceTypes, names, deletionStateFilter, null, null, null));
 }
Exemplo n.º 7
0
        /// <summary>
        /// Returns a hash by parentid's based on parentType of lists of child resources
        /// </summary>
        /// <param name="resources"></param>
        /// <param name="parentType"></param>
        /// <returns></returns>
        public Dictionary <ulong, IList <ResourceBE> > GroupByParentIdWithCast(IEnumerable <ResourceBE> resources, ResourceBE.ParentType parentType)
        {
            Dictionary <ulong, List <ResourceBE> >  temp = GroupByParentIdInternal(resources, parentType);
            Dictionary <ulong, IList <ResourceBE> > ret  = new Dictionary <ulong, IList <ResourceBE> >();

            //Convert lists to arrays
            foreach (KeyValuePair <ulong, List <ResourceBE> > kvp in temp)
            {
                ret[kvp.Key] = kvp.Value;
            }

            return(ret);
        }
Exemplo n.º 8
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);
 }
Exemplo n.º 9
0
 public ResourceBE DeleteProperty(ResourceBE prop, ResourceBE.ParentType parentType, XUri parentUri)
 {
     DekiContext.Current.Instance.EventSink.PropertyDelete(DekiContext.Current.Now, prop, DekiContext.Current.User, parentType, parentUri);
     return(_resourceBL.Delete(prop));
 }
Exemplo n.º 10
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());
        }