예제 #1
0
        private void AddBibTexLinks()
        {
            using (ResourceDataAccess resourceDAL = new ResourceDataAccess(this.CreateContext()))
            {
                if (!IsSecurityAwareControl || (UserPermissions != null && UserPermissions.Contains(UserResourcePermissions.Read)))
                {
                    ScholarlyWork scholarlyWorkObj = (ScholarlyWork)resourceDAL.GetScholarlyWorkWithCitedScholarlyWorks(SubjectResource.Id);

                    if (scholarlyWorkObj != null && scholarlyWorkObj.Cites.Count > 0)
                    {
                        BibTexExportLink.Visible = true;
                    }
                    else
                    {
                        BibTexExportLink.Visible = false;
                    }
                }

                if (!IsSecurityAwareControl || (UserPermissions != null && UserPermissions.Contains(UserResourcePermissions.Update)))
                {
                    BibTexImportLink.Visible = true;
                }
                else
                {
                    BibTexImportLink.Visible = false;
                }

                SeperatorLabel.Visible = (BibTexExportLink.Visible == false || BibTexImportLink.Visible == false) ? false : true;
            }

            this.Controls.Add(BibTexPanel);
        }
        /// <summary>
        /// Gets the resource property.
        /// </summary>
        /// <param name="resource">The resource.</param>
        /// <param name="propertyName">Name of the property.</param>
        /// <returns>A <see cref="ResourceProperty"/>.</returns>
        internal static ResourceProperty GetResourceProperty(ScholarlyWork resource, string propertyName)
        {
            if (!resource.ResourceProperties.IsLoaded)
            {
                try
                {
                    resource.ResourceProperties.Load();

                    foreach (ResourceProperty resourceProperties in resource.ResourceProperties)
                    {
                        if (!resourceProperties.PropertyReference.IsLoaded)
                        {
                            resourceProperties.PropertyReference.Load();
                        }
                    }
                }
                catch (InvalidOperationException)
                {
                    // Do nothing if resource is not attached to the context.
                }
            }
            string propertyUri = AtomPubHelper.GetPropertyUri(propertyName);

            return(resource.ResourceProperties
                   .Where(tuple => tuple.Property.Uri == propertyUri)
                   .FirstOrDefault());
        }
예제 #3
0
        /// <summary>
        /// Updates the metadata for the specified resource.
        /// </summary>
        /// <param name="collectionName">Name of the target collection.</param>
        /// <param name="memberResourceId">The Id of the member resource.</param>
        /// <param name="atomEntry">Describes the resource to be modified.</param>
        /// <returns>A SyndicationItem that describes the updated resource.</returns>
        /// <exception cref="ArgumentNullException">Throws exception if collectionName is null/empty
        /// or atomEntry is null.</exception>
        /// <exception cref="ArgumentException">Throws exception if requested memberResourceId is not a unique identifier.</exception>
        SyndicationItem IAtomPubStoreWriter.UpdateMemberInfo(string collectionName, string memberResourceId, AtomEntryDocument atomEntry)
        {
            if (string.IsNullOrEmpty(collectionName))
            {
                throw new ArgumentNullException("collectionName");
            }

            if (string.IsNullOrEmpty(memberResourceId))
            {
                throw new ArgumentNullException("memberResourceId");
            }

            if (null == atomEntry)
            {
                throw new ArgumentNullException("atomEntry");
            }

            using (ZentityContext context = CoreHelper.CreateZentityContext())
            {
                ScholarlyWork resource = (ScholarlyWork)AtomPubHelper.GetMember(context, collectionName, memberResourceId, "Update");
                resource.Files.Load();

                // Bug Fix : 177689 - AtomPub (M2): Author node is appending after every PUT request instead of overwriting it.
                resource.Authors.Load();
                resource.Contributors.Load();

                UpdateResourceProperty(context, resource, atomEntry);
                context.SaveChanges();

                return(ZentityAtomPubStoreReader.GenerateSyndicationItem(this.BaseUri, resource));
            }
        }
예제 #4
0
        /// <summary>
        /// Creates a new resource of type collectionName in the repository.
        /// </summary>
        /// <param name="collectionName">The resource type.</param>
        /// <param name="atomEntry">Information about the resource.</param>
        /// <returns>A SyndicationItem that describes the newly created resource.</returns>
        /// <exception cref="ArgumentNullException">Throws exception if collectionName is null/empty
        /// or atomEntry is null/empty .</exception>
        SyndicationItem IAtomPubStoreWriter.CreateMember(string collectionName, AtomEntryDocument atomEntry)
        {
            if (string.IsNullOrEmpty(collectionName))
            {
                throw new ArgumentNullException("collectionName");
            }

            if (null == atomEntry)
            {
                throw new ArgumentNullException("atomEntry");
            }

            AuthenticatedToken authenticatedToken = CoreHelper.GetAuthenticationToken();

            using (ZentityContext context = CoreHelper.CreateZentityContext())
            {
                if (!authenticatedToken.HasCreatePermission(context))
                {
                    throw new UnauthorizedException(Resources.ATOMPUB_UNAUTHORIZED);
                }

                ScholarlyWork resource = CreateScholarlyWork(collectionName);
                context.AddToResources(resource);
                ZentityAtomPubStoreWriter.UpdateResourceProperty(context, resource, atomEntry);

                resource.GrantDefaultPermissions(context, authenticatedToken);

                context.SaveChanges();

                return(ZentityAtomPubStoreReader.GenerateSyndicationItem(this.BaseUri, resource));
            }
        }
예제 #5
0
 /// <summary>
 /// Adds the file resource.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="resource">The resource.</param>
 /// <returns>The added <see cref="Core.File"/> type.</returns>
 private static Core.File AddFileResource(ZentityContext context, ScholarlyWork resource)
 {
     Core.File mediaResource = new Core.File();
     context.AddToResources(mediaResource);
     context.SaveChanges();
     resource.Files.Add(mediaResource);
     return(mediaResource);
 }
예제 #6
0
        /// <summary>
        /// Creates an instance of specified resource type.
        /// </summary>
        /// <param name="resourceType">The name of the collection in which the member resource should be created.</param>
        /// <returns>An instance of ScholarlyWork resource.</returns>
        protected internal static ScholarlyWork CreateScholarlyWork(string resourceType)
        {
            // Get the resource type to create new instance.
            Type          collectionType = CoreHelper.GetSystemResourceType(resourceType);
            ScholarlyWork resource       = Activator.CreateInstance(collectionType, false) as ScholarlyWork;

            return(resource);
        }
 /// <summary>
 /// Gets the specified resource.
 /// </summary>
 /// <param name="collectionName">The name of the resource type.</param>
 /// <param name="memberResourceId">The Guid of the resource to return.</param>
 /// <returns>A SyndicationItem for the specified resource.</returns>
 /// <exception cref="ArgumentNullException">Throws exception if collectionName is null/empty.</exception>
 SyndicationItem IAtomPubStoreReader.GetMember(string collectionName, string memberResourceId)
 {
     using (ZentityContext context = CoreHelper.CreateZentityContext())
     {
         ScholarlyWork resource = (ScholarlyWork)AtomPubHelper.GetMember(context, collectionName, memberResourceId, "Read");
         return(ZentityAtomPubStoreReader.GenerateSyndicationItem(this.BaseUri, resource));
     }
 }
예제 #8
0
        /// <summary>
        /// Updates the Resource.File of the specified resource.
        /// </summary>
        /// <param name="collectionName">The type of the resource.</param>
        /// <param name="memberResourceId">The resource whose File needs to be updated.</param>
        /// <param name="mimeType">The MIME type of media.</param>
        /// <param name="media">The new File contents.</param>
        /// <returns>A SyndicationItem that describes the updated resource.</returns>
        /// <exception cref="ArgumentNullException">Throws exception if collectionName is null/empty
        /// or media is null.</exception>
        /// <exception cref="ArgumentException">Throws exception if requested memberResourceId is not a unique identifier.</exception>
        SyndicationItem IAtomPubStoreWriter.UpdateMedia(string collectionName, string memberResourceId, string mimeType, byte[] media)
        {
            if (string.IsNullOrEmpty(collectionName))
            {
                throw new ArgumentNullException("collectionName");
            }

            if (null == media)
            {
                throw new ArgumentNullException("media");
            }

            if (string.IsNullOrEmpty(memberResourceId))
            {
                throw new ArgumentNullException("memberResourceId");
            }

            if (!AtomPubHelper.IsValidGuid(memberResourceId))
            {
                throw new ArgumentException(Resources.ATOMPUB_INVALID_RESOURCE_ID, "memberResourceId");
            }

            using (ZentityContext context = CoreHelper.CreateZentityContext())
            {
                Type collectionType = CoreHelper.GetSystemResourceType(collectionName);
                // Prepare a query to get a resource with specified Id and specified type.
                string commandText = string.Format(CultureInfo.InvariantCulture, AtomPubConstants.EsqlToGetFileContents,
                                                   collectionType.FullName);

                ObjectQuery <Core.File> query = new ObjectQuery <Core.File>(commandText, context);
                query.Parameters.Add(new ObjectParameter("Id", new Guid(memberResourceId)));
                Core.File mediaResource = query.FirstOrDefault();

                if (null == mediaResource)
                {
                    throw new ResourceNotFoundException(Resources.ATOMPUB_RESOURCE_NOT_FOUND);
                }

                if (!mediaResource.Authorize("Update", context, CoreHelper.GetAuthenticationToken()))
                {
                    throw new UnauthorizedException(Resources.ATOMPUB_UNAUTHORIZED);
                }

                mediaResource.Resources.Load();
                ScholarlyWork resource = (ScholarlyWork)mediaResource.Resources.First();
                resource.DateModified       = DateTime.Now;
                mediaResource.MimeType      = mimeType;
                mediaResource.FileExtension = AtomPubHelper.GetFileExtension(mimeType);

                MemoryStream mediaStream = ZentityAtomPubStoreWriter.GetMediaStream(media);
                context.UploadFileContent(mediaResource, mediaStream);

                // Bug Fix : 180811 - Save Changes once mime type and contents are set.
                context.SaveChanges();

                return(ZentityAtomPubStoreReader.GenerateSyndicationItem(this.BaseUri, resource));
            }
        }
예제 #9
0
        /// <summary>
        /// Adds the child resources.
        /// </summary>
        /// <param name="extractionPath">The extraction path.</param>
        /// <param name="document">The document.</param>
        /// <param name="resource">The resource.</param>
        /// <param name="zentityContext">The zentity context.</param>
        private static void AddChildResources(
            string extractionPath,
            MetsDocument document,
            ScholarlyWork resource,
            ZentityContext zentityContext)
        {
            resource.Container = new ScholarlyWorkContainer();
            ScholarlyWorkContainer childContainer = null;

            string[] fileNames = Directory.GetFiles(extractionPath)
                                 .Select(path => GetFileName(path))
                                 .Where(name => SwordConstants.MetsDocumentName != name)
                                 .ToArray();

            if (0 < fileNames.Length)
            {
                childContainer = new ScholarlyWorkContainer();
                resource.Container.ContainedWorks.Add(childContainer);
            }

            // Loop though all files which are extracted.
            foreach (string fileName in fileNames)
            {
                // Get the extension
                int    dotIndex      = fileName.LastIndexOf('.');
                string fileExtension = (0 < dotIndex) ? fileName.Substring(dotIndex + 1) : string.Empty;

                #region Upload Zip File Contents

                // Get Metadata for the specified fileName
                MetadataSection dataSection = document.Files[fileName];

                // Create resource against each type as specified in the METS document.
                ScholarlyWork individualResource = CreateResouceUsingMetsMetadata(dataSection);

                UpdateResourceProeprties(zentityContext, individualResource, dataSection);

                // Create Media and Upload file contents.
                Core.File individualMediaResource = AddFileResource(zentityContext,
                                                                    individualResource,
                                                                    extractionPath + "\\" + fileName);
                individualMediaResource.MimeType      = AtomPubHelper.GetMimeTypeFromFileExtension(fileExtension);
                individualMediaResource.FileExtension = fileExtension;

                // Save file name in notes for future references.
                individualMediaResource.Description = fileName;

                // Associate with the main resource.
                childContainer.ContainedWorks.Add(individualResource);

                #endregion

                AuthenticatedToken authenticatedToken = CoreHelper.GetAuthenticationToken();

                individualResource.GrantDefaultPermissions(zentityContext, authenticatedToken);
                individualMediaResource.GrantDefaultPermissions(zentityContext, authenticatedToken);
            }
        }
예제 #10
0
 /// <summary>
 /// Adds the file resource.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="resource">The resource.</param>
 /// <param name="mediaFilePath">The media file path.</param>
 /// <returns>The added <see cref="Core.File"/> type.</returns>
 private static Core.File AddFileResource(
     ZentityContext context,
     ScholarlyWork resource,
     string mediaFilePath)
 {
     Core.File mediaResource = AddFileResource(context, resource);
     context.UploadFileContent(mediaResource, mediaFilePath);
     return(mediaResource);
 }
예제 #11
0
 /// <summary>
 /// Adds the file resource.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="resource">The resource.</param>
 /// <param name="mediaStream">The media stream.</param>
 /// <returns>The added <see cref="Core.File"/> type.</returns>
 private static Core.File AddFileResource(
     ZentityContext context,
     ScholarlyWork resource,
     Stream mediaStream)
 {
     Core.File mediaResource = AddFileResource(context, resource);
     mediaStream.Position = 0;
     context.UploadFileContent(mediaResource, mediaStream);
     return(mediaResource);
 }
예제 #12
0
        /// <summary>
        /// Creates a new Resource.File for a specified resource of type collectionName in the repository.
        /// </summary>
        /// <param name="collectionName">The resource type.</param>
        /// <param name="mimeType">The MIME type of media.</param>
        /// <param name="media">The new File contents.</param>
        /// <param name="fileExtension">The media file extension.</param>
        /// <returns>A SyndicationItem that describes the newly created resource.</returns>
        /// <exception cref="ArgumentNullException">Throws exception if collectionName is null/empty
        /// or mimeType is null/empty or media is null.</exception>
        protected SyndicationItem CreateMedia(string collectionName, string mimeType, byte[] media,
                                              string fileExtension)
        {
            if (string.IsNullOrEmpty(collectionName))
            {
                throw new ArgumentNullException("collectionName");
            }

            if (string.IsNullOrEmpty(mimeType))
            {
                throw new ArgumentNullException("mimeType");
            }

            if (null == media)
            {
                throw new ArgumentNullException("media");
            }

            AuthenticatedToken authenticatedToken = CoreHelper.GetAuthenticationToken();

            using (ZentityContext context = CoreHelper.CreateZentityContext())
            {
                if (!authenticatedToken.HasCreatePermission(context))
                {
                    throw new UnauthorizedException(Resources.ATOMPUB_UNAUTHORIZED);
                }

                ScholarlyWork resource = CreateScholarlyWork(collectionName);
                resource.DateModified = DateTime.Now;

                Core.File mediaResource = new Core.File();
                mediaResource.MimeType      = mimeType;
                mediaResource.FileExtension = string.IsNullOrEmpty(fileExtension) ?
                                              AtomPubHelper.GetFileExtension(mimeType) : fileExtension;
                context.AddToResources(mediaResource);
                context.SaveChanges();
                resource.Files.Add(mediaResource);

                MemoryStream mediaStream = ZentityAtomPubStoreWriter.GetMediaStream(media);
                context.UploadFileContent(mediaResource, mediaStream);
                mediaStream.Close();

                resource.GrantDefaultPermissions(context, authenticatedToken);
                mediaResource.GrantDefaultPermissions(context, authenticatedToken);

                context.SaveChanges();

                return(ZentityAtomPubStoreReader.GenerateSyndicationItem(this.BaseUri, resource));
            }
        }
예제 #13
0
 /// <summary>
 /// Sets the type of the content.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="resource">The resource.</param>
 /// <param name="contentType">Type of the content.</param>
 /// <param name="propertyName">Name of the property.</param>
 private static void SetContentType(
     ZentityContext context,
     ScholarlyWork resource,
     string contentType,
     string propertyName)
 {
     if (contentType.ToUpperInvariant() == "TEXT")
     {
         return;
     }
     else
     {
         SetExtensionProperty(context, resource, propertyName, contentType);
     }
 }
예제 #14
0
        /// <summary>
        /// Get user permissions for the specified list of resources and their related resources.
        /// </summary>
        /// <param name="token">Authentication token.</param>
        /// <param name="resources">List or resources.</param>
        /// <returns>Mapping resource id and user permissions on the resource.</returns>
        private Dictionary <Guid, IEnumerable <string> > GetPermissions(AuthenticatedToken token, IList <Resource> resources)
        {
            Dictionary <Guid, IEnumerable <string> > userPermissions = null;

            if (resources != null && token != null && resources.Count > 0)
            {
                IList <Resource> srcResources = resources.ToList();
                foreach (Resource res in resources)
                {
                    //add file resources to source list
                    if (res.Files != null && res.Files.Count > 0)
                    {
                        srcResources = srcResources.Union(res.Files.Select(tuple => tuple as Resource).ToList()).ToList();
                    }

                    //add author resources to source list
                    ScholarlyWork scholWork = res as ScholarlyWork;
                    if (scholWork != null && scholWork.Authors != null && scholWork.Authors.Count > 0)
                    {
                        srcResources = srcResources.Union(scholWork.Authors.Select(tuple => tuple as Resource).ToList()).ToList();
                    }
                }

                using (ResourceDataAccess dataAccess = new ResourceDataAccess(this.CreateContext()))
                {
                    //Get user permission for all resources in the source list.
                    var permissons = dataAccess.GetResourcePermissions(token, srcResources);

                    if (permissons != null)
                    {
                        userPermissions = permissons.ToDictionary(tuple => tuple.Resource.Id, tuple => tuple.Permissions);
                    }
                }
            }

            //This is a default case which indicates that user is not having any permission.
            if (userPermissions == null)
            {
                userPermissions = new Dictionary <Guid, IEnumerable <string> >();
            }
            ;

            return(userPermissions);
        }
예제 #15
0
        void BibTexExportLink_Click(object sender, EventArgs e)
        {
            if (SubjectResource == null)
            {
                return;
            }

            ScholarlyWork scholarlyWorkObj = null;

            using (ResourceDataAccess resourceDAL = new ResourceDataAccess(this.CreateContext()))
            {
                scholarlyWorkObj = (ScholarlyWork)resourceDAL.GetScholarlyWorkWithCitedScholarlyWorks(SubjectResource.Id);

                if (scholarlyWorkObj != null)
                {
                    ICollection <ScholarlyWork> citationsList = scholarlyWorkObj.Cites;
                    List <ScholarlyWork>        citations     = resourceDAL.GetAuthorizedResources <ScholarlyWork>
                                                                    (AuthenticatedToken, UserResourcePermissions.Read, citationsList).ToList();
                    if (citations.Count > 0)
                    {
                        String fileNameToSend = scholarlyWorkObj.Id.ToString() + _bibExtention;
                        String value          = _attachment + fileNameToSend;
                        this.Page.Response.ContentType = _contentTypeOctetStream;
                        this.Page.Response.AddHeader(_responseHeader, value);
                        this.Page.Response.Clear();
                        BibTeXConverter bibConverter = new BibTeXConverter(BibTeXParserBehavior.IgnoreParseErrors);

                        foreach (ScholarlyWork swork in citations)
                        {
                            swork.Authors.Load();
                            swork.Editors.Load();
                        }
                        bibConverter.Export(citations, this.Page.Response.OutputStream);
                        this.Page.Response.Flush();
                        this.Page.Response.End();
                    }
                    else
                    {
                        BibTexExportLink.Visible = false;
                        SeperatorLabel.Visible   = false;
                    }
                }
            }
        }
예제 #16
0
        /// <summary>
        /// Gets the resource properties.
        /// </summary>
        /// <param name="resource">The resource.</param>
        /// <param name="propertyName">Name of the property.</param>
        /// <returns>List of <see cref="ResourceProperty"/>.</returns>
        internal static List <ResourceProperty> GetResourceProperties(ScholarlyWork resource, string propertyName)
        {
            if (!resource.ResourceProperties.IsLoaded)
            {
                try
                {
                    resource.ResourceProperties.Load();
                }
                catch (InvalidOperationException)
                {
                    // Do nothing if resource is not attached to the context.
                }
            }
            string propertyUri = AtomPubHelper.GetPropertyUri(propertyName);

            return(resource.ResourceProperties
                   .Where(tuple => tuple.Property.Uri == propertyUri)
                   .ToList());
        }
예제 #17
0
        /// <summary>
        /// Update the properties of the resource.
        /// </summary>
        /// <param name="zentityContext">The ZentityContext to which the resource is attached.</param>
        /// <param name="resource">Resource to be update scalar properties.</param>
        /// <param name="dataSection"><typeref name="MetadataSection"/> Metadata which contains property values.</param>
        private static void UpdateResourceProeprties(ZentityContext zentityContext, ScholarlyWork resource,
                                                     MetadataSection dataSection)
        {
            if (null == resource)
            {
                throw new ArgumentNullException("resource");
            }

            if (null == dataSection)
            {
                throw new ArgumentNullException("dataSection");
            }

            resource.DateModified = DateTime.Now;

            PropertyInfo[] properties = resource.GetType().GetProperties()
                                        .Where(property => PropertyMapper.ResourceProperties.ContainsKey(property.Name))
                                        .ToArray();

            // Loop for each property of the resource.
            foreach (PropertyInfo property in properties)
            {
                ReadOnlyCollection <string> values = GetPropertyValues(property.Name, dataSection);

                // If no values are present for current property, do not process.
                if (null == values || 0 >= values.Count)
                {
                    continue;
                }

                // Check if the property is scalar property or Navigation Property.
                object[] navigationAttr = property.GetCustomAttributes(typeof(EdmRelationshipNavigationPropertyAttribute), true);

                if (0 < navigationAttr.Length)
                {
                    UpdateNavigationproperties(zentityContext, resource, property, values);
                }
                else
                {
                    UpdateScalarProperties(resource, property, values);
                }
            }
        }
예제 #18
0
        /// <summary>
        /// Sets the extension property.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="resource">The resource.</param>
        /// <param name="propertyName">Name of the property.</param>
        /// <param name="propertyValue">The property value.</param>
        private static void SetExtensionProperty(
            ZentityContext context,
            ScholarlyWork resource,
            string propertyName,
            string propertyValue)
        {
            ResourceProperty resourceProperty = ZentityAtomPubStoreReader.GetResourceProperty(resource, propertyName);

            if (null == resourceProperty)
            {
                Property extensionProperty = GetProperty(context, propertyName);
                resourceProperty = new ResourceProperty
                {
                    Property = extensionProperty,
                    Resource = resource,
                };
            }

            resourceProperty.Value = propertyValue;
        }
예제 #19
0
        /// <summary>
        /// Updates the scalar properties.
        /// </summary>
        /// <param name="resource">The resource.</param>
        /// <param name="property">The property.</param>
        /// <param name="values">The values.</param>
        private static void UpdateScalarProperties(ScholarlyWork resource, PropertyInfo property, ReadOnlyCollection <string> values)
        {
            Type   propType    = property.PropertyType;
            object scalarValue = null;

            // Change the property value type from string to proper resource type.
            if (propType.ToString() == SwordConstants.TypeNullableDateTime)
            {
                scalarValue = Convert.ChangeType(values[0],
                                                 typeof(DateTime),
                                                 CultureInfo.InvariantCulture);
            }
            else
            {
                scalarValue = Convert.ChangeType(values[0],
                                                 property.PropertyType,
                                                 CultureInfo.InvariantCulture);
            }

            // Update the property value.
            property.SetValue(resource, scalarValue, null);
        }
예제 #20
0
        /// <summary>
        /// Create resource using metadata.
        /// </summary>
        /// <param name="dataSection">Metadata Section containing metadata of the resource.</param>
        /// <returns>A resource of type ScholarlyWork or its derived type.</returns>
        private static ScholarlyWork CreateResouceUsingMetsMetadata(MetadataSection dataSection)
        {
            if (null == dataSection)
            {
                throw new ArgumentNullException("dataSection");
            }

            ScholarlyWork resource     = null;
            Type          resourceType = null;

            // Get the resource type specified in METS document.
            if (null != dataSection.DescriptiveMetadata && null != dataSection.DescriptiveMetadata.ResourceType &&
                0 < dataSection.DescriptiveMetadata.ResourceType.Count)
            {
                string resourceTypeName = dataSection.DescriptiveMetadata.ResourceType[0];

                // Check if the resource type is derived from ScholarlyWork,
                // as Sword & AtomPub supports only ScholarlyWork and its derivatives.
                if (AtomPubHelper.IsValidCollectionType(resourceTypeName))
                {
                    resourceType = CoreHelper.GetSystemResourceType(resourceTypeName);
                }
            }

            // Take ScholarlyWork as default resource type.
            if (null == resourceType)
            {
                resourceType = typeof(ScholarlyWork);
            }

            // Create resource of type ScholarlyWork or its derived types.
            resource = Activator.CreateInstance(resourceType, false) as ScholarlyWork;
            if (null == resource)
            {
                throw new SwordException(Properties.Resources.UNSUPPORTED_RESOURCE_TYPE);
            }

            return(resource);
        }
예제 #21
0
        /// <summary>
        /// Deletes the specified resource.
        /// </summary>
        /// <param name="collectionName">The type of the resource.</param>
        /// <param name="memberResourceId">The Guid of the resource.</param>
        /// <returns>True if the operation succeeds, False otherwise.</returns>
        /// <exception cref="ArgumentNullException">Throws exception if collectionName is null/empty.</exception>
        /// <exception cref="ArgumentException">Throws exception if requested memberResourceId is not a unique identifier.</exception>
        bool IAtomPubStoreWriter.DeleteMember(string collectionName, string memberResourceId)
        {
            using (ZentityContext context = CoreHelper.CreateZentityContext())
            {
                ScholarlyWork resource = (ScholarlyWork)AtomPubHelper.GetMember(context, collectionName, memberResourceId, "Delete");

                // Load to delete all Core.File resource associated to requested scholarlywork.
                if (!resource.Files.IsLoaded)
                {
                    resource.Files.Load();
                }

                Zentity.Core.File[] resourceFiles = resource.Files.ToArray();

                for (int i = 0; i < resourceFiles.Length; i++)
                {
                    DeleteRelationships(context, resourceFiles[i]);
                    context.DeleteObject(resourceFiles[i]);
                }

                DeleteRelationships(context, resource);

                // Delete associated Resource propertes
                resource.ResourceProperties.Load();
                List <ResourceProperty> resProperties = resource.ResourceProperties.ToList();
                foreach (ResourceProperty property in resProperties)
                {
                    resource.ResourceProperties.Remove(property);
                    context.DeleteObject(property);
                }

                context.DeleteObject(resource);
                context.SaveChanges();
                return(true);
            }
        }
예제 #22
0
        /// <summary>
        /// Generates the Syndication Item from the specified resource.
        /// </summary>
        /// <param name="baseUri">Base Uri to generate links Url and content Url in SyndicationItem.</param>
        /// <param name="resource">An instance of resource from which SyndicationItem is to be generated.</param>
        /// <returns>A <see cref="SyndicationItem"/>.</returns>
        internal static SyndicationItem GenerateSyndicationItem(Uri baseUri, ScholarlyWork resource)
        {
            #region Load Navigation properties
            // Load navigation properties explicitly.

            try
            {
                if (!resource.Files.IsLoaded)
                {
                    resource.Files.Load();
                }

                if (!resource.Authors.IsLoaded)
                {
                    resource.Authors.Load();
                }

                if (!resource.Contributors.IsLoaded)
                {
                    resource.Contributors.Load();
                }

                if (!resource.ResourceProperties.IsLoaded)
                {
                    resource.ResourceProperties.Load();
                }

                if (null != resource.ResourceProperties)
                {
                    foreach (ResourceProperty resourceProperty in resource.ResourceProperties)
                    {
                        if (!resourceProperty.PropertyReference.IsLoaded)
                        {
                            resourceProperty.PropertyReference.Load();
                        }
                    }
                }

                // Load parent container of resource.
                if (!resource.ContainerReference.IsLoaded)
                {
                    resource.ContainerReference.Load();
                }

                if (null != resource.Container)
                {
                    // Load child container of resource.
                    if (!resource.Container.ContainedWorks.IsLoaded)
                    {
                        resource.Container.ContainedWorks.Load();
                    }

                    foreach (ScholarlyWorkContainer childContainer in resource.Container.ContainedWorks.OfType <ScholarlyWorkContainer>())
                    {
                        // Load child resources of parent resource.
                        if (!childContainer.ContainedWorks.IsLoaded)
                        {
                            childContainer.ContainedWorks.Load();
                        }
                    }
                }
            }
            catch (InvalidOperationException)
            {
                // DO nothing if resource not attached to the context.
            }

            #endregion

            SyndicationItem item = new SyndicationItem();
            item.Id = AtomPubConstants.IdPrefix + resource.Id.ToString();
            item.LastUpdatedTime = (null != resource.DateModified) ? resource.DateModified.Value : DateTimeOffset.MinValue;
            item.Title           = GetContent <TextSyndicationContent>(resource.Title, resource.ResourceProperties, AtomPubConstants.TitleTypeProperty, true);
            item.Copyright       = GetContent <TextSyndicationContent>(resource.Copyright, resource.ResourceProperties, AtomPubConstants.CopyrightTypeProperty, false);

            Publication publication = resource as Publication;

            if (null != publication && null != publication.DatePublished)
            {
                item.PublishDate = publication.DatePublished.Value;
            }

            #region Add Authors and Contributors

            AddSyndicationPerson(resource.Authors, item.Authors);

            if (item.Authors.Count == 0)
            {
                item.Authors.Add(new SyndicationPerson(null, string.Empty, null));
            }

            AddSyndicationPerson(resource.Contributors, item.Contributors);

            #endregion

            #region Edit and Edit-Media links for main resource

            AddLinksAndSource(baseUri, resource, ref item);

            #endregion

            ResourceProperty summary = GetResourceProperty(resource, AtomPubConstants.SummaryProperty);

            if (null != summary)
            {
                item.Summary = GetContent <TextSyndicationContent>(summary.Value, resource.ResourceProperties, AtomPubConstants.SummaryTypeProperty, false);
            }

            if (!(item.Content is TextSyndicationContent))
            {
                item.Summary = new TextSyndicationContent(string.Empty);
            }

            return(item);
        }
예제 #23
0
        /// <summary>
        /// Adds the links and source.
        /// </summary>
        /// <param name="baseUri">The base URI.</param>
        /// <param name="resource">The resource.</param>
        /// <param name="item">The syndication item.</param>
        private static void AddLinksAndSource(Uri baseUri, ScholarlyWork resource, ref SyndicationItem item)
        {
            // NameValue pair for creating Uri from UriTemplate.
            NameValueCollection parameters = new NameValueCollection();

            parameters.Add(AtomPubParameterType.CollectionName.ToString(), resource.GetType().Name);
            parameters.Add(AtomPubParameterType.Id.ToString(), resource.Id.ToString());

            Core.File mediaFile = resource.Files.FirstOrDefault();

            if (null != mediaFile)
            {
                Uri mediaUri = AtomPubHelper.AtomPubTemplates[AtomPubRequestType.EditMedia]
                               .BindByName(baseUri, parameters);

                // Add content linnk and edit-media link
                if (string.IsNullOrEmpty(mediaFile.MimeType))
                {
                    mediaFile.MimeType = AtomPubConstants.DefaultMimeType;
                }

                SyndicationLink resourceMediaLink = new SyndicationLink(mediaUri);
                resourceMediaLink.RelationshipType = AtomPubConstants.EditMedia;
                item.Links.Add(resourceMediaLink);

                item.Content = new UrlSyndicationContent(mediaUri, mediaFile.MimeType);
            }
            else
            {
                ResourceProperty urlContent = GetResourceProperty(resource, AtomPubConstants.ContentUrlProperty);

                if (null != urlContent && !string.IsNullOrEmpty(urlContent.Value))
                {
                    item.Content = GetContent <UrlSyndicationContent>(urlContent.Value, resource.ResourceProperties, AtomPubConstants.DescriptionTypeProperty, false);
                }
                else
                {
                    item.Content = GetContent <SyndicationContent>(resource.Description, resource.ResourceProperties, AtomPubConstants.DescriptionTypeProperty, true);
                }
            }

            // Add resource Edit link
            Uri             resourceUri      = AtomPubHelper.AtomPubTemplates[AtomPubRequestType.EditMember].BindByName(baseUri, parameters);
            SyndicationLink resourceEditLink = new SyndicationLink(resourceUri);

            resourceEditLink.RelationshipType = AtomPubConstants.Edit;
            item.Links.Add(resourceEditLink);

            if (null != resource.Container)
            {
                var relatedItems = resource.Container.ContainedWorks.OfType <ScholarlyWorkContainer>()
                                   .SelectMany(tuple => tuple.ContainedWorks)
                                   .Where(tuple => !(tuple is ScholarlyWorkContainer));

                foreach (ScholarlyWork containedItem in relatedItems)
                {
                    parameters.Set(AtomPubParameterType.CollectionName.ToString(), containedItem.GetType().Name);
                    parameters.Set(AtomPubParameterType.Id.ToString(), containedItem.Id.ToString());
                    resourceUri = AtomPubHelper.AtomPubTemplates[AtomPubRequestType.EditMember].BindByName(baseUri, parameters);
                    SyndicationLink containsEditLink = new SyndicationLink(resourceUri);
                    containsEditLink.RelationshipType = AtomPubConstants.Related;
                    item.Links.Add(containsEditLink);
                }
            }

            AtomEntryDocument entry = new AtomEntryDocument(item);

            IEnumerable <ResourceProperty> links = ZentityAtomPubStoreReader.GetResourceProperties(resource, AtomPubConstants.LinksProperty);

            if (null != links)
            {
                foreach (ResourceProperty link in links)
                {
                    entry.XmlLinks.Add(link.Value);
                }
            }

            ResourceProperty source = GetResourceProperty(resource, AtomPubConstants.SourceProperty);

            if (null != source)
            {
                entry.Source = source.Value;
            }

            using (XmlReader reader = new XmlTextReader(entry.AtomEntry, XmlNodeType.Document, null))
            {
                item = SyndicationItem.Load(reader);
            }
        }
예제 #24
0
        /// <summary>
        /// Updates the resource property.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="resource">The resource.</param>
        /// <param name="atomEntry">The atom entry.</param>
        private static void UpdateResourceProperty(
            ZentityContext context,
            ScholarlyWork resource,
            AtomEntryDocument atomEntry)
        {
            resource.Title = atomEntry.Title.Text;
            SetContentType(context, resource, atomEntry.Title.Type, AtomPubConstants.TitleTypeProperty);
            resource.DateModified = DateTime.Now;
            Publication publication = resource as Publication;

            if (null != publication && atomEntry.PublishDate != DateTimeOffset.MinValue)
            {
                publication.DatePublished = atomEntry.PublishDate.DateTime;
            }

            if (null != atomEntry.Copyright)
            {
                resource.Copyright = atomEntry.Copyright.Text;
                SetContentType(context, resource, atomEntry.Copyright.Type, AtomPubConstants.CopyrightTypeProperty);
            }

            if (null != atomEntry.Summary && !string.IsNullOrEmpty(atomEntry.Summary.Text))
            {
                SetExtensionProperty(context, resource, AtomPubConstants.SummaryProperty, atomEntry.Summary.Text);
                SetContentType(context, resource, atomEntry.Summary.Type, AtomPubConstants.SummaryTypeProperty);
            }

            if (null != atomEntry.Content)
            {
                UrlSyndicationContent urlContent = atomEntry.Content as UrlSyndicationContent;

                if (null != urlContent)
                {
                    resource.Description = null;
                    SetExtensionProperty(context, resource, AtomPubConstants.ContentUrlProperty, urlContent.Url.AbsoluteUri);
                }
                else
                {
                    ResourceProperty urlContentProperty = ZentityAtomPubStoreReader.GetResourceProperty(resource, AtomPubConstants.ContentUrlProperty);

                    if (null != urlContentProperty)
                    {
                        resource.ResourceProperties.Remove(urlContentProperty);
                    }

                    TextSyndicationContent textDescription = atomEntry.Content as TextSyndicationContent;

                    if (null != textDescription)
                    {
                        resource.Description = textDescription.Text;
                    }
                    else
                    {
                        XmlSyndicationContent content = atomEntry.Content as XmlSyndicationContent;

                        if (null != content)
                        {
                            XmlDictionaryReader contentReader = content.GetReaderAtContent();
                            StringBuilder       contentValue  = new StringBuilder(151);

                            try
                            {
                                while (contentReader.Read())
                                {
                                    contentValue.Append(contentReader.Value);
                                }
                            }
                            finally
                            {
                                contentReader.Close();
                            }

                            resource.Description = contentValue.ToString();
                        }
                    }
                }

                SetContentType(context, resource, atomEntry.Content.Type, AtomPubConstants.DescriptionTypeProperty);
            }

            if (null != atomEntry.Source)
            {
                ResourceProperty source = ZentityAtomPubStoreReader.GetResourceProperty(resource, AtomPubConstants.SourceProperty);

                if (null == source)
                {
                    Property sourceProperty = GetProperty(context, AtomPubConstants.SourceProperty);
                    source = new ResourceProperty
                    {
                        Property = sourceProperty,
                        Resource = resource,
                    };
                }

                source.Value = atomEntry.Source;
            }

            #region Add Links

            List <ResourceProperty> links = ZentityAtomPubStoreReader.GetResourceProperties(resource, AtomPubConstants.LinksProperty);

            if (0 == atomEntry.XmlLinks.Count && null != links)
            {
                foreach (var item in links)
                {
                    resource.ResourceProperties.Remove(item);
                }
            }

            Property linkProperty = GetProperty(context, AtomPubConstants.LinksProperty);

            foreach (string xmlLink in atomEntry.XmlLinks)
            {
                resource.ResourceProperties.Add(new ResourceProperty
                {
                    Resource = resource,
                    Property = linkProperty,
                    Value    = xmlLink
                });
            }

            #endregion


            var authors = atomEntry.Authors.Select(author => new Person
            {
                Title = author.Name,
                Email = author.Email,
                Uri   = author.Uri
            });
            // Bug Fix : 177689 - AtomPub (M2): Author node is appending after every PUT request instead
            //                    of overwriting it.
            // Remove previous authors.
            resource.Authors.Clear();
            AddPersons(context, resource.Authors, authors);

            resource.Contributors.Clear();
            var contributors = atomEntry.Contributors.Select(author => new Person
            {
                Title = author.Name,
                Email = author.Email,
                Uri   = author.Uri
            });
            AddPersons(context, resource.Contributors, contributors);
        }
예제 #25
0
        /// <summary>
        /// Updates the navigation properties.
        /// </summary>
        /// <param name="zentityContext">The zentity context.</param>
        /// <param name="resource">The resource.</param>
        /// <param name="property">The property.</param>
        /// <param name="values">The values.</param>
        private static void UpdateNavigationproperties(ZentityContext zentityContext, ScholarlyWork resource, PropertyInfo property, ReadOnlyCollection <string> values)
        {
            EntityCollection <Contact> contactRelation = property.GetValue(resource, null) as EntityCollection <Contact>;

            if (null != contactRelation)
            {
                contactRelation.Clear();
                var authors = values.Distinct().Where(name => name.Length > 0)
                              .Select(name => new Person
                {
                    Title = name
                });
                ZentityAtomPubStoreWriter.AddPersons(zentityContext, contactRelation, authors);
            }
        }
예제 #26
0
        /// <summary>
        /// Updates the status of controls base on DataSource.
        /// </summary>
        public override void DataBind()
        {
            base.DataBind();

            if (DataSource != null)
            {
                this.TitleHeader.Text = GlobalResource.TitleText + _colan;
                //Set title with link
                this.ResourceTitle.Text = HttpUtility.HtmlEncode(CoreHelper.FitString(CoreHelper.UpdateEmptyTitle(
                                                                                          CoreHelper.GetTitleByResourceType(DataSource)), _maxTitleCharWidth)) + " (" + DataSource.GetType().Name + ")";

                if (!string.IsNullOrEmpty(TitleLink) &&
                    (UserPermissions == null ||
                     (UserPermissions.Keys.Contains(DataSource.Id) && UserPermissions[DataSource.Id].Contains(UserResourcePermissions.Read))))
                {
                    this.ResourceTitle.NavigateUrl = string.Format(CultureInfo.CurrentCulture, TitleLink, DataSource.Id);
                }
                else
                {
                    this.ResourceTitle.NavigateUrl = string.Empty;
                }

                //Set date based on ShowDate value.
                if (ShowDate == DateType.DateAdded)
                {
                    this.DateAddedHeader.Text = GlobalResource.DateAddedText + _colan;
                    this.DateAdded.Text       = DataSource.DateAdded != null?DataSource.DateAdded.Value.ToString() : string.Empty;
                }
                else
                {
                    this.DateAddedHeader.Text = GlobalResource.DateModifiedText + _colan;
                    this.DateAdded.Text       = DataSource.DateModified != null?DataSource.DateModified.Value.ToString() : string.Empty;
                }
                //Set Description.
                this.Description.Text = HttpUtility.HtmlEncode(CoreHelper.FitString(DataSource.Description, _maxDescriptionCharWidth));
                //Set files.
                BindRelatedFiles();

                //set authors.
                ScholarlyWork resource = DataSource as ScholarlyWork;
                if (resource != null && resource.Authors != null && resource.Authors.Count > 0)
                {
                    int index = 0;
                    foreach (Contact author in resource.Authors)
                    {
                        if (UserPermissions == null ||
                            (UserPermissions.Keys.Contains(author.Id) && UserPermissions[author.Id].Contains(UserResourcePermissions.Read)))
                        {
                            HyperLink link = new HyperLink();
                            link.Text = HttpUtility.HtmlEncode(CoreHelper.FitString(CoreHelper.UpdateEmptyTitle(CoreHelper.GetTitleByResourceType(author)), _maxTitleCharWidth));

                            if (!string.IsNullOrEmpty(AuthorsLink))
                            {
                                link.NavigateUrl = string.Format(CultureInfo.CurrentCulture, AuthorsLink, author.Id);
                            }

                            this.Authors.Controls.Add(link);

                            if (index < (resource.Authors.Count - 1))
                            {
                                Label commalbl = new Label();
                                commalbl.Text = _comma;
                                this.Authors.Controls.Add(commalbl);
                            }
                        }


                        if (index >= _maxAuthorsCount - 1)
                        {
                            if (index < (resource.Authors.Count - 1))
                            {
                                Label etcLbl = new Label();
                                etcLbl.Text = _etc;
                                this.Authors.Controls.Add(etcLbl);
                            }
                            break;
                        }

                        index++;
                    }
                }
            }
        }
예제 #27
0
        /// <summary>
        /// Creates a new Resource.File for a specified resource of type collectionName in the repository.
        /// </summary>
        /// <param name="collectionName">The resource type.</param>
        /// <param name="mimeType">The MIME type of media.</param>
        /// <param name="media">The new File contents.</param>
        /// <param name="fileExtension">The media file extension.</param>
        /// <returns>A SyndicationItem that describes the newly created resource.</returns>
        SyndicationItem IAtomPubStoreWriter.CreateMedia(string collectionName, string mimeType,
                                                        byte[] media, string fileExtension)
        {
            if (string.IsNullOrEmpty(collectionName))
            {
                throw new ArgumentNullException("collectionName");
            }

            if (string.IsNullOrEmpty(mimeType))
            {
                throw new ArgumentNullException("mimeType");
            }

            if (null == media)
            {
                throw new ArgumentNullException("media");
            }

            if (SwordConstants.ZipContentType != mimeType)
            {
                return(base.CreateMedia(collectionName, mimeType, media, fileExtension));
            }

            // Convert byte array to stream.
            MemoryStream mediaStream    = ZentityAtomPubStoreWriter.GetMediaStream(media);
            string       extractionPath = ExtractZipContent(mediaStream);

            HttpContext.Current.Items[SwordConstants.ZipExtractedPath] = extractionPath;

            // Get the path of METS xml file.
            string metsFilePath = extractionPath + "\\" + SwordConstants.MetsDocumentName;

            if (!System.IO.File.Exists(metsFilePath))
            {
                //string errorMessage = string.Format(CultureInfo.CurrentCulture,
                //                                    Properties.Resources.SWORD_MISSING_METS_DOCUMENT,
                //                                    SwordConstants.MetsDocumentName);
                //throw new MetsException(errorMessage);
                return(base.CreateMedia(collectionName, mimeType, media, fileExtension));
            }

            AuthenticatedToken authenticatedToken = CoreHelper.GetAuthenticationToken();

            using (ZentityContext zentityContext = CoreHelper.CreateZentityContext())
            {
                if (!authenticatedToken.HasCreatePermission(zentityContext))
                {
                    throw new UnauthorizedException(Resources.ATOMPUB_UNAUTHORIZED);
                }

                // Generate METS document from given METS xml file.
                MetsDocument document = new MetsDocument(metsFilePath);

                // Create resource of specified collection type.
                ScholarlyWork resource = CreateScholarlyWork(collectionName);
                resource.DateModified = DateTime.Now;

                // Upload the zip file contents as media for main resource.
                // This will be required in AtomPub get requests and further use.
                Core.File mediaResource = AddFileResource(zentityContext, resource, mediaStream);
                mediaResource.MimeType      = mimeType;
                mediaResource.FileExtension = AtomPubHelper.GetFileExtension(mimeType);
                // close the stream
                mediaStream.Close();

                AddChildResources(extractionPath, document, resource, zentityContext);

                resource.GrantDefaultPermissions(zentityContext, authenticatedToken);
                mediaResource.GrantDefaultPermissions(zentityContext, authenticatedToken);

                // Save all changes at the end
                zentityContext.SaveChanges();

                return(ZentityAtomPubStoreReader.GenerateSyndicationItem(base.BaseUri, resource));
            }
        }
예제 #28
0
    protected void Page_Load(object sender, EventArgs e)
    {
        Control startNavigationTemplate = Wizard1.FindControl(_templateContainerID) as Control;

        if (startNavigationTemplate != null)
        {
            Button stepNextButton = startNavigationTemplate.FindControl(_stepNextButtonId) as Button;
            if (stepNextButton != null)
            {
                stepNextButton.Text = Resources.Resources.BibTexImportStep1NextButtonText;
            }
        }

        // This is required to avoid "PageRequestManagerParserErrorException" exception with update panel
        // because there is rendering problem with update panel.
        Control stepNavigationTemplate = Wizard1.FindControl(_stepNavTemplateContainerID) as Control;

        if (stepNavigationTemplate != null)
        {
            Button step2ImportButton = stepNavigationTemplate.FindControl(_step2ImportButton) as Button;
            if (step2ImportButton != null)
            {
                step2ImportButton.Text = Resources.Resources.BibTexImportStep2ButtonText;
            }
        }

        Guid guid = Guid.Empty;

        this.HideError();

        if (!this.IsPostBack)
        {
            LocalizePage();
        }

        bool isValidGuid = true;

        if (Request.QueryString[_queryStringKey] != null)
        {
            try
            {
                guid = new Guid(Request.QueryString[_queryStringKey]);
            }
            catch (FormatException)
            {
                this.DisplayError(Resources.Resources.InvalidResource);
                isValidGuid = false;
            }
            catch (OverflowException)
            {
                this.DisplayError(Resources.Resources.InvalidResource);
                isValidGuid = false;
            }
        }
        else if (guid == Guid.Empty)
        {
            this.DisplayError(Resources.Resources.BibtexImportMissinfId);
            isValidGuid = false;
        }

        if (isValidGuid)
        {
            using (ResourceDataAccess resourceDAL = new ResourceDataAccess())
            {
                _scholarlyWorkObj = (ScholarlyWork)resourceDAL.GetResource(guid);
                AuthenticatedToken token = Session[Constants.AuthenticationTokenKey] as AuthenticatedToken;

                //if user is not having update permission on the subject resource then throw exception.
                if (!resourceDAL.AuthorizeUser(token, UserResourcePermissions.Update, _scholarlyWorkObj.Id))
                {
                    throw new UnauthorizedAccessException(string.Format(CultureInfo.InstalledUICulture,
                                                                        Resources.Resources.MsgUnAuthorizeAccess, UserResourcePermissions.Update));
                }

                if (_scholarlyWorkObj != null)
                {
                    _scholarlyWorkObj.Cites.Load();
                }
                else
                {
                    // Handle scenario which is "a resource deleted by one user and another user operating on the resource".
                    this.DisplayError(Resources.Resources.ResourceNotFound);
                    this._isResExist = false;
                }
            }
            if (!IsPostBack && this.Wizard1.ActiveStepIndex == 0)
            {
                if (_scholarlyWorkObj == null)
                {
                    this.DisplayError(Resources.Resources.ResourceNotFound);
                }
                else
                {
                    ResourceTitleLabel.InnerText         = Resources.Resources.ResourceLabelTitleText;
                    LabelImportResourceTitle.Text        = FitString(_scholarlyWorkObj.Title, 40);
                    LabelImportResourceTitle.NavigateUrl = _resourceDetailUrl + _scholarlyWorkObj.Id;
                }
            }
        }
    }