示例#1
0
        void UpdateCachedDropBox()
        {
            StringBuilder errors = new StringBuilder();

            dropBoxManager = new DropBoxManager(properties);
            foreach (DropBoxUpdate update in cachedDropBoxUpdates)
            {
                try
                {
                    UpdateDropBoxPermissionsNow(update.State, update.User);
                }
                catch (Exception e)
                {
                    properties.Store.LogException(e);
                    errors.AppendFormat(SlkCulture.GetResources().ErrorSavingDropBoxPermissions, update.State, update.User.LoginName);
                }
            }

            if (errors.Length > 0)
            {
                throw new SafeToDisplayException(errors.ToString());
            }

            dropBoxManager = null;
        }
示例#2
0
 void CheckUserIsLearner()
 {
     if (Assignment.Store.CurrentUserId != LearnerId)
     {
         throw new SafeToDisplayException(SlkCulture.GetResources().SubmitAssignmentNotLearner);
     }
 }
        /// <summary>Saves the assignment.</summary>
        /// <remarks>
        /// <para>
        /// When creating a self-assigned assignment, take care to ensure that
        /// <r>AssignmentProperties.AutoReturn</r> is <n>true</n>, otherwise the learner assignments
        /// will never reach
        /// <a href="Microsoft.SharePointLearningKit.LearnerAssignmentState.Enumeration.htm">LearnerAssignmentState.Final</a>
        /// state.
        /// </para>
        /// <para>
        /// <b>Security:</b>&#160; If <pr>slkRole</pr> is
        /// <a href="Microsoft.SharePointLearningKit.SlkRole.Enumeration.htm">SlkRole.Instructor</a>,
        /// this operation fails if the <a href="SlkApi.htm#AccessingSlkStore">current user</a> doesn't
        /// have SLK
        /// <a href="Microsoft.SharePointLearningKit.SlkSPSiteMapping.InstructorPermission.Property.htm">instructor</a>
        /// permissions on <pr>destinationSPWeb</pr>.  Also fails if the current user doesn't have access to the
        /// package/file.
        /// </para>
        /// </remarks>
        /// <param name="web">The <c>SPWeb</c> to create the assignment in.</param>
        /// <param name="slkRole">The <c>SlkRole</c> to use when creating the assignment.  Use
        ///     <c>SlkRole.Learner</c> to create a self-assigned assignment, i.e. an assignment with
        ///     no instructors for which the current learner is the only learner.  Otherwise, use
        ///     <c>SlkRole.Instructor</c>.</param>
        public void Save(SPWeb web, SlkRole slkRole)
        {
            // Verify that the web is in the site
            if (web.Site.ID != Store.SPSiteGuid)
            {
                throw new InvalidOperationException(SlkCulture.GetResources().SPWebDoesNotMatchSlkSPSite);
            }

            if (Id == null)
            {
                SaveNewAssignment(web, slkRole);
            }
            else
            {
                UpdateAssignment(web);
            }

            if (customPropertiesItem != null)
            {
                customPropertiesItem["Title"] = Id.GetKey().ToString();

                foreach (AssignmentProperty property in Properties)
                {
                    customPropertiesItem[property.Name] = property.Value;
                }

                customPropertiesItem.ParentList.ParentWeb.AllowUnsafeUpdates = true;
                customPropertiesItem.Update();
            }
        }
        static void CreateDatabase(SlkSPSiteMapping mapping, string databaseName, string appPoolAccountName, string databaseSchema)
        {
            // restrict the characters in <databaseName>
            if (!Regex.Match(databaseName, @"^\w+$").Success)
            {
                throw new SafeToDisplayException(SlkCulture.GetResources().InvalidDatabaseName, databaseName);
            }

            // if <appPoolAccountName> is null, set it to the name of the application pool account
            // (e.g. "NT AUTHORITY\NETWORK SERVICE"); set <appPoolSid> to its SID
            byte[] appPoolSid = null;
            if (appPoolAccountName == null)
            {
                using (SPSite site = new SPSite(mapping.SPSiteGuid))
                {
                    appPoolAccountName = site.WebApplication.ApplicationPool.Username;
                }
            }

            NTAccount          appPoolAccount = new NTAccount(appPoolAccountName);
            SecurityIdentifier securityId     =
                (SecurityIdentifier)appPoolAccount.Translate(typeof(SecurityIdentifier));

            appPoolSid = new byte[securityId.BinaryLength];
            securityId.GetBinaryForm(appPoolSid, 0);

            SlkUtilities.ImpersonateAppPool(delegate()
            {
                CreateDatabase(mapping.DatabaseServerConnectionString, databaseName,
                               mapping.DatabaseConnectionString, appPoolAccountName,
                               appPoolSid, databaseSchema);
            });
        }
        /// <summary>
        /// Returns an <c>AssignmentProperties</c> object populated with default information for
        /// a new assignment based on a given e-learning package or non-e-learning document.
        /// This method doesn't actually create the assignment -- it just returns information that
        /// can be used as defaults for a form that a user would fill in to create a new assignment.
        /// </summary>
        /// <remarks>
        /// <para>
        /// If <paramref name="slkRole"/> is <c>SlkRole.Learner</c>, default properties for a
        /// self-assigned assignment are returned.  In this case, the returned
        /// <c>AssignmentProperties</c> will contain no users in
        /// <c>AssignmentProperties.Instructors</c>, and <c>AssignmentProperties.Learners</c> will
        /// contain only the current user.
        /// </para>
        /// <para>
        /// <b>Security:</b>&#160; If <pr>slkRole</pr> is
        /// <a href="Microsoft.SharePointLearningKit.SlkRole.Enumeration.htm">SlkRole.Instructor</a>,
        /// this operation fails if the <a href="SlkApi.htm#AccessingSlkStore">current user</a> doesn't
        /// have SLK
        /// <a href="Microsoft.SharePointLearningKit.SlkSPSiteMapping.InstructorPermission.Property.htm">instructor</a>
        /// permissions on <pr>destinationSPWeb</pr>.  Also fails if the current user doesn't have access to the
        /// package/file.
        /// </para>
        /// </remarks>
        /// <param name="store"></param>
        /// <param name="destinationSPWeb">The <c>SPWeb</c> that the assignment would be assigned in.</param>
        /// <param name="slkRole">The <c>SlkRole</c> for which information is to be retrieved.
        ///     Use <c>SlkRole.Learner</c> to get default information for a self-assigned assignment,
        ///     i.e. an assignment with no instructors for which the current learner is the only
        ///     learner.  Otherwise, use <c>SlkRole.Instructor</c>.</param>
        /// <returns></returns>
        public static AssignmentProperties CreateNewAssignmentObject(ISlkStore store, SPWeb destinationSPWeb, SlkRole slkRole)
        {
            // Security checks: Fails if the user isn't an instructor on the web if SlkRole=Instructor
            // (verified by EnsureInstructor).  Fails if the user doesn't have access to the
            // package (verified by calling RegisterPackage or by accessing
            // the properties of the non-elearning file).

            // Check parameters
            if (destinationSPWeb == null)
            {
                throw new ArgumentNullException("destinationSPWeb");
            }

            // Verify that the web is in the site
            if (destinationSPWeb.Site.ID != store.SPSiteGuid)
            {
                throw new InvalidOperationException(SlkCulture.GetResources().SPWebDoesNotMatchSlkSPSite);
            }

            UserItemIdentifier   currentUserId = store.CurrentUserId;
            AssignmentProperties assignment    = new AssignmentProperties(null, store);

            assignment.StartDate    = DateTime.Today; // midnight today
            assignment.DueDate      = null;
            assignment.EmailChanges = store.Settings.EmailSettings.DefaultEmailingOn;
            assignment.CreatedById  = currentUserId;
            store.AddCustomProperties(assignment, destinationSPWeb);

            // Role checking and determine if self assigned
            bool isSelfAssigned;

            if (slkRole == SlkRole.Instructor)
            {
                store.EnsureInstructor(destinationSPWeb);
                isSelfAssigned = false;
            }
            else if (slkRole == SlkRole.Learner)
            {
                isSelfAssigned = true;
            }
            else
            {
                throw new ArgumentException(SlkCulture.GetResources().InvalidSlkRole, "slkRole");
            }

            assignment.ShowAnswersToLearners = isSelfAssigned;
            assignment.AutoReturn            = isSelfAssigned;
            if (isSelfAssigned)
            {
                assignment.Learners.Add(new SlkUser(currentUserId, destinationSPWeb.CurrentUser));
            }
            else
            {
                assignment.Instructors.Add(new SlkUser(currentUserId, destinationSPWeb.CurrentUser));
            }

            return(assignment);
        }
        /// <summary>Loads SLK configuration information from WSS and LearningStore, in a form that's
        /// suitable for copying to Configure.aspx form fields. </summary>
        ///
        /// <param name="spSiteGuid">The GUID of the SPSite to retrieve configuration information
        ///     from.</param>
        ///
        /// <returns>An AdministrationConfiguration.</returns>
        ///
        /// <remarks>
        /// This method is static so it can used outside the context of IIS.  Only SharePoint
        /// administrators can perform this function.
        /// </remarks>
        ///
        /// <exception cref="SafeToDisplayException">
        /// An error occurred that can be displayed to a browser user.
        /// </exception>
        ///
        public static AdministrationConfiguration LoadConfiguration(Guid spSiteGuid)
        {
            AdministrationConfiguration configuration = new AdministrationConfiguration(spSiteGuid);

            // only SharePoint administrators can perform this action
            CheckPermissions();

            // set <mapping> to the mapping between <spSiteGuid> and the LearningStore connection
            // information for that SPSite
            SlkSPSiteMapping mapping = SlkSPSiteMapping.GetMapping(spSiteGuid);

            // set "out" parameters based on <mappingExists> and <mapping>
            if (mapping != null)
            {
                // the mapping exists -- set "out" parameters based on <mapping>
                configuration.DatabaseServer       = mapping.DatabaseServer;
                configuration.DatabaseName         = mapping.DatabaseName;
                configuration.InstructorPermission = mapping.InstructorPermission;
                configuration.LearnerPermission    = mapping.LearnerPermission;

                // The below given condition will be true only during the migration of SLK from
                // 'SLK without Observer role' to 'SLK with Observer role' implementation
                if (mapping.ObserverPermission == null)
                {
                    mapping.ObserverPermission = LoadCulture(spSiteGuid).Resources.DefaultSlkObserverPermissionName;
                }
                configuration.ObserverPermission = mapping.ObserverPermission;
            }
            else
            {
                SlkCulture        siteCulture    = LoadCulture(spSiteGuid);
                AppResourcesLocal adminResources = SlkCulture.GetResources();

                configuration.IsNewConfiguration = true;
                mapping = SlkSPSiteMapping.CreateMapping(spSiteGuid);
                // the mapping doesn't exist -- set "out" parameters to default values
                SPWebService adminWebService = SlkAdministration.GetAdminWebService();
                configuration.DatabaseServer       = adminWebService.DefaultDatabaseInstance.Server.Address;
                configuration.DatabaseName         = adminResources.DefaultSlkDatabaseName;
                mapping.DatabaseServer             = configuration.DatabaseServer;
                mapping.DatabaseName               = configuration.DatabaseName;
                configuration.InstructorPermission = siteCulture.Resources.DefaultSlkInstructorPermissionName;
                configuration.LearnerPermission    = siteCulture.Resources.DefaultSlkLearnerPermissionName;
                configuration.ObserverPermission   = siteCulture.Resources.DefaultSlkObserverPermissionName;
            }

            // set "out" parameters that need to be computed
            bool createDatabaseResult = false;

            SlkUtilities.ImpersonateAppPool(delegate()
            {
                createDatabaseResult = !DatabaseExists(mapping.DatabaseServerConnectionString, mapping.DatabaseName);
            });
            configuration.CreateDatabase = createDatabaseResult;

            return(configuration);
        }
        /// <summary>Throws an exception if this computer isn't part of a SharePoint farm, or the caller doesn't
        /// have the necessary permissions to access instances of this class.</summary>
        static internal void CheckPermissions()
        {
            SPFarm farm = SPFarm.Local;

            if (farm == null)
            {
                throw new InvalidOperationException(SlkCulture.GetResources().SharePointFarmNotFound);
            }
            else if (!farm.CurrentUserIsAdministrator())
            {
                throw new SafeToDisplayException(SlkCulture.GetResources().NotSharePointAdmin);
            }
        }
示例#8
0
        void CheckUserIsInstructor()
        {
            UserItemIdentifier current = Assignment.Store.CurrentUserId;

            foreach (SlkUser instructor in Assignment.Instructors)
            {
                if (instructor.UserId == current)
                {
                    return;
                }
            }

            throw new SafeToDisplayException(SlkCulture.GetResources().ChangeLearnerAssignmentNotInstructor);
        }
        /// <summary>
        /// Returns the SPSite-to-LearningStore mapping represented by a given SPSite GUID.  If no
        /// such mapping exists, an exception is thrown.
        /// </summary>
        ///
        /// <param name="site">The SPSite to retrieve a mapping for.</param>
        ///
        /// <exception cref="SlkNotConfiguredException">
        /// SLK is not configured for SharePoint site collection.
        /// (This configuration is performed in SharePoint Central Administration.)
        /// </exception>
        ///
        public static SlkSPSiteMapping GetRequiredMapping(SPSite site)
        {
            SlkSPSiteMapping mapping = GetMapping(site.ID);

            if (mapping == null)
            {
                mapping = GetMapping(site.WebApplication.Id);
            }

            if (mapping == null)
            {
                throw new SlkNotConfiguredException(SlkCulture.GetResources().SlkNotEnabled);
            }
            else
            {
                return(mapping);
            }
        }
        void VerifyIsValidSelfAssigned()
        {
            // set <currentUserId> to the UserItemIdentifier of the current user; note that this
            // requires a round trip to the database
            UserItemIdentifier currentUserId = Store.CurrentUserId;

            // verify that <properties> specify no instructors and that the current user is the
            // only learner
            if (Instructors.Count != 0)
            {
                throw new UnauthorizedAccessException(SlkCulture.GetResources().InvalidSelfAssignment);
            }

            if ((Learners.Count != 1) || (Learners[0].UserId != currentUserId))
            {
                throw new UnauthorizedAccessException(SlkCulture.GetResources().InvalidSelfAssignment);
            }
        }
        void SaveNewAssignment(SPWeb web, SlkRole slkRole)
        {
            // Security checks: If assigning as an instructor, fails if user isn't an instructor on
            // the web (implemented by calling EnsureInstructor).  Fails if the user doesn't have access to the package/file
            if (web == null)
            {
                throw new ArgumentNullException("web");
            }

            if (PackageFormat == null && Location == null)
            {
                throw new InvalidOperationException(SlkCulture.GetResources().InvalidNewAssignment);
            }

            SPSiteGuid = web.Site.ID;
            SPWebGuid  = web.ID;

            VerifyRole(web, slkRole);
            Id = Store.CreateAssignment(this);

            if (isSelfAssigned == false)
            {
                //Update the MRU list
                Store.AddToUserWebList(web);
            }

            if (IsNonELearning)
            {
                DropBoxManager dropBoxMgr = new DropBoxManager(this);
                Microsoft.SharePoint.Utilities.SPUtility.ValidateFormDigest();
                dropBoxMgr.CreateAssignmentFolder();
            }

            if (EmailChanges)
            {
                using (AssignmentEmailer emailer = new AssignmentEmailer(this, Store.Settings.EmailSettings, web))
                {
                    emailer.SendNewEmail(Learners);
                }
            }
        }
        /// <summary>Makes the assignment be a no package assignemnt.</summary>
        public void MakeNoPackageAssignment(string title)
        {
            Location = Package.NoPackageLocation.ToString();
            if (String.IsNullOrEmpty(Title))
            {
                if (string.IsNullOrEmpty(title))
                {
                    Title = SlkCulture.GetResources().NoPackageTitle;
                }
                else
                {
                    Title = title;
                }
            }

            if (Description == null)
            {
                Description = String.Empty;
            }
            return;
        }
        private static SlkSettings LoadSettings(SlkSPSiteMapping mapping, SPSite site, XmlSchema xmlSchema)
        {
            // create a LearningStore. Read is in privileged scope so irrelevant what key is.
            // Cannot use current user as may be be called in a page PreInit event when it's not necessarily valid
            string        learningStoreKey = "SHAREPOINT\\System";
            LearningStore learningStore    = new LearningStore(mapping.DatabaseConnectionString, learningStoreKey, ImpersonationBehavior.UseOriginalIdentity);

            // read the SLK Settings file from the database into <settings>
            SlkSettings settings;

            using (LearningStorePrivilegedScope privilegedScope = new LearningStorePrivilegedScope())
            {
                LearningStoreJob   job   = learningStore.CreateJob();
                LearningStoreQuery query = learningStore.CreateQuery(Schema.SiteSettingsItem.ItemTypeName);
                query.AddColumn(Schema.SiteSettingsItem.SettingsXml);
                query.AddColumn(Schema.SiteSettingsItem.SettingsXmlLastModified);
                query.AddCondition(Schema.SiteSettingsItem.SiteGuid, LearningStoreConditionOperator.Equal, mapping.SPSiteGuid);
                job.PerformQuery(query);
                DataRowCollection dataRows = job.Execute <DataTable>().Rows;
                if (dataRows.Count != 1)
                {
                    throw new SafeToDisplayException(SlkCulture.GetResources().SlkSettingsNotFound, site.Url);
                }
                DataRow  dataRow                 = dataRows[0];
                string   settingsXml             = (string)dataRow[0];
                DateTime settingsXmlLastModified = ((DateTime)dataRow[1]);
                using (StringReader stringReader = new StringReader(settingsXml))
                {
                    XmlReaderSettings xmlSettings = new XmlReaderSettings();
                    xmlSettings.Schemas.Add(xmlSchema);
                    xmlSettings.ValidationType = ValidationType.Schema;
                    using (XmlReader xmlReader = XmlReader.Create(stringReader, xmlSettings))
                    {
                        settings = new SlkSettings(xmlReader, settingsXmlLastModified);
                    }
                }
            }

            return(settings);
        }
示例#14
0
        //////////////////////////////////////////////////////////////////////////////////////////////
        // Internal Methods
        //

        /// <summary>
        /// Initializes an instance of this class.
        /// </summary>
        ///
        /// <param name="viewColumnName">The value to use for the <c>ViewColumnName</c> property.
        ///     </param>
        ///
        /// <param name="oper">The value to use for the <c>Operator</c> property.  Note that
        ///     if this value is "IsNull" or "IsNotNull" then
        ///     <c>LearningStoreConditionOperator.Equal</c> or
        ///     <c>LearningStoreConditionOperator.NotEqual</c>, respectively, is used for the
        ///     <c>Operator</c> property; in this case <c>null</c> should be used for
        ///     <paramref name="value"/>.</param>
        ///
        /// <param name="value">The value to use for the <c>Value</c> property.</param>
        ///
        /// <param name="macroName">The value to use for the <c>MacroName</c> property.</param>
        ///
        /// <param name="noConditionOnNull">The value to use for the <c>NoConditionOnNull</c> property.
        ///     </param>
        ///
        /// <param name="lineNumber">The line number of the "&lt;Condition&gt;" element with the
        ///     XML file.</param>
        ///
        /// <remarks>
        /// Note that one of <paramref name="value"/> and <paramref name="macroName"/> must be
        /// non-null unless <paramref name="oper"/> equals "IsNull" or "IsNotNull".
        /// </remarks>
        ///
        internal ConditionDefinition(string viewColumnName, string oper, string value, string macroName, bool noConditionOnNull, int lineNumber)
        {
            // store state
            m_viewColumnName = viewColumnName;
            switch (oper)
            {
            case "Equal":
                m_operator = LearningStoreConditionOperator.Equal;
                break;

            case "GreaterThan":
                m_operator = LearningStoreConditionOperator.GreaterThan;
                break;

            case "GreaterThanEqual":
                m_operator = LearningStoreConditionOperator.GreaterThanEqual;
                break;

            case "LessThan":
                m_operator = LearningStoreConditionOperator.LessThan;
                break;

            case "LessThanEqual":
                m_operator = LearningStoreConditionOperator.LessThanEqual;
                break;

            case "NotEqual":
                m_operator = LearningStoreConditionOperator.NotEqual;
                break;

            case "IsNull":
                m_operator = LearningStoreConditionOperator.Equal;
                if ((value != null) || (macroName != null))
                {
                    throw new ArgumentException(SlkCulture.GetResources().SlkUtilitiesValueNullifIsNull, "operator");
                }
                break;

            case "IsNotNull":
                m_operator = LearningStoreConditionOperator.NotEqual;
                if ((value != null) || (macroName != null))
                {
                    throw new ArgumentException(SlkCulture.GetResources().SlkUtilitiesValueNullifIsNotNull, "operator");
                }
                break;
            }

            m_value = value;

            if (string.IsNullOrEmpty(macroName) == false)
            {
                MacroResolver.ValidateMacro(macroName);
            }

            m_macroName         = macroName;
            m_noConditionOnNull = noConditionOnNull;
            m_lineNumber        = lineNumber;

            // only one of <value> and <macroName> may be provided
            if ((value != null) && (macroName != null))
            {
                throw new ArgumentException(SlkCulture.GetResources().SlkUtilitiesOneValueNonNull, "value");
            }

            // if <noConditionOnNull> is true, <macroName> must be provided
            if (noConditionOnNull && (macroName == null))
            {
                throw new ArgumentException(SlkCulture.GetResources().SlkUtilitiesMacroNameNotProvided, "noConditionOnNull");
            }
        }
示例#15
0
 /// <summary>
 /// Initializes an instance of this class.
 /// </summary>
 ///
 /// <param name="internalErrorCode">An internal error code, e.g. "APP1001".</param>
 ///
 internal InternalErrorException(string internalErrorCode) : base(String.Format(SlkCulture.GetCulture(), SlkCulture.GetResources().InternalError, internalErrorCode))
 {
 }
示例#16
0
 /// <summary>
 /// Initializes an instance of this class, by formatting an error message and prepending
 /// the line number within the XML file.
 /// </summary>
 ///
 /// <param name="lineNumber">The line number (within the XML file) to include in the
 ///     exception message.</param>
 ///
 /// <param name="format">A <c>String.Format</c>-style format string.</param>
 ///
 /// <param name="args">Formatting arguments.</param>
 ///
 internal SlkSettingsException(int lineNumber, string format, params object[] args) :
     base(String.Format(SlkCulture.GetCulture(), SlkCulture.GetResources().SlkUtilitiesSettingsException, lineNumber,
                        String.Format(SlkCulture.GetCulture(), format, args)))
 {
 }
示例#17
0
 /// <summary>
 /// Initializes an instance of this class, by formatting an error message and prepending
 /// the line number within the XML file.
 /// </summary>
 ///
 /// <param name="xmlReader">The line number of the exception message will include the
 ///     current line number of this <c>XmlReader</c>.</param>
 ///
 /// <param name="format">A <c>String.Format</c>-style format string.</param>
 ///
 /// <param name="args">Formatting arguments.</param>
 ///
 internal SlkSettingsException(XmlReader xmlReader, string format, params object[] args) :
     base(String.Format(SlkCulture.GetCulture(), SlkCulture.GetResources().SlkUtilitiesSettingsException, ((IXmlLineInfo)xmlReader).LineNumber,
                        String.Format(SlkCulture.GetCulture(), format, args)))
 {
 }
        /// <summary>Sets the location of the package.</summary>
        /// <remarks>Security checks:Fails if the user doesn't have access to the package/file</remarks>
        /// <param name="location">The MLC SharePoint location string that refers to the e-learning
        ///     package or non-e-learning document to assign.  Use
        ///     <c>SharePointPackageStore.GetLocation</c> to construct this string.</param>
        /// <param name="organizationIndex">The zero-based index of the organization within the
        ///     e-learning content to assign; this is the value that's used as an index to
        ///     <c>ManifestReader.Organizations</c>.  If the content being assigned is a non-e-learning
        ///     document, use <c>null</c> for <paramref name="organizationIndex"/>.</param>
        /// <param name="title">Any title that has been passed in.</param>
        public void SetLocation(SharePointFileLocation location, Nullable <int> organizationIndex, string title)
        {
            if (location == null)
            {
                throw new ArgumentNullException("location");
            }

            if (location.ToString() == Package.NoPackageLocation.ToString())
            {
                MakeNoPackageAssignment(title);
                return;
            }

            // Access the properties of the file to verify that the user has access to the file
            SPFile file = location.LoadFile();

            System.Collections.Hashtable fileProperties = file.Properties;

            // set <rootActivityId> to the ID of the organization, or null if a non-e-learning document is being assigned
            if (organizationIndex != null)
            {
                using (Package package = new Package(Store, file, location))
                {
                    package.Register();

                    RootActivityId = package.FindRootActivity(organizationIndex.Value);

                    bool existingTitle = (string.IsNullOrEmpty(Title) == false);

                    if (existingTitle == false)
                    {
                        Title = package.Title;
                    }

                    if (string.IsNullOrEmpty(Description))
                    {
                        Description = package.Description;
                    }

                    // validate <organizationIndex>
                    if ((organizationIndex.Value < 0) || (organizationIndex.Value >= package.Organizations.Count))
                    {
                        throw new SafeToDisplayException(SlkCulture.GetResources().InvalidOrganizationIndex);
                    }

                    PackageFormat = package.PackageFormat;

                    // set <organizationNodeReader> to refer to the organization
                    OrganizationNodeReader organizationNodeReader = package.Organizations[organizationIndex.Value];

                    // if there is more than one organization, append the organization title, if any
                    if (existingTitle == false && package.Organizations.Count > 1)
                    {
                        if (!String.IsNullOrEmpty(organizationNodeReader.Title))
                        {
                            SlkCulture culture = new SlkCulture();
                            Title = culture.Format(culture.Resources.SlkPackageAndOrganizationTitle, Title, organizationNodeReader.Title);
                        }
                    }

                    // set <pointsPossible> to the points-possible value stored in the manifest, or null if none
                    switch (PackageFormat)
                    {
                    case Microsoft.LearningComponents.PackageFormat.Lrm:
                        PointsPossible = organizationNodeReader.PointsPossible;
                        break;

                    case Microsoft.LearningComponents.PackageFormat.V1p3:
                        PointsPossible = 100;
                        break;

                    default:
                        PointsPossible = null;
                        break;
                    }
                }
            }
            else  // Non-elearning content
            {
                RootActivityId = null;
                Location       = location.ToString();
                if (string.IsNullOrEmpty(Title))
                {
                    Title = file.Title;
                    if (String.IsNullOrEmpty(Title))
                    {
                        Title = System.IO.Path.GetFileNameWithoutExtension(file.Name);
                    }
                }

                if (string.IsNullOrEmpty(Description))
                {
                    Description = string.Empty;
                }

                if (PointsPossible == null)
                {
                    PointsPossible  = null;     // "Points Possible" defaults to null for non-e-learning content
                    PackageWarnings = null;     // no package warnings
                    PackageFormat   = null;     // non-e-learning package
                }
            }
        }