/// <summary> /// Converts a value returned from a LearningStore query to a <c>PackageItemIdentifier</c>, /// or <c>null</c> if the value is <c>DBNull</c>. /// </summary> /// /// <param name="value">A value from a <c>DataRow</c> within a <c>DataTable</c> /// returned from a LearningStore query.</param> /// /// <param name="result">Where to store the result.</param> /// public static void Cast(object value, out PackageItemIdentifier result) { LearningStoreItemIdentifier id; Cast(value, out id); result = (id == null) ? null : new PackageItemIdentifier(id); }
/// <summary> /// Converts a value returned from a LearningStore query to a /// <c>PackageItemIdentifier</c>. Throws an exception if the value is <c>DBNull</c>. /// </summary> /// /// <param name="value">A value from a <c>DataRow</c> within a <c>DataTable</c> /// returned from a LearningStore query.</param> /// /// <param name="result">Where to store the result.</param> /// public static void CastNonNull(object value, out PackageItemIdentifier result) { LearningStoreItemIdentifier id; CastNonNull(value, out id); result = new PackageItemIdentifier(id); }
/// <summary> /// Create an AddPackageResult object to encapsulate the results of adding a package. /// </summary> /// <param name="packageId">The packageId of the package that was added to the store. /// This value is not validated to ensure that it represents /// a package in LearningStore.</param> /// <param name="log">The log of errors and warnings that occurred during the course of adding the package to the store. /// This may not be null.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="packageId"/> or <paramref name="log"/> /// are not provided.</exception> public AddPackageResult(PackageItemIdentifier packageId, ValidationResults log) { Utilities.ValidateParameterNonNull("packageId", packageId); Utilities.ValidateParameterNonNull("log", log); m_packageId = packageId; m_log = log; }
FileSystemPackageReader m_fsPackageReader; // the PackageReader to read resource files /// <summary> /// Constructor. /// </summary> /// <param name="packageBasePath">The absolute path to the location where the packages /// are located in the filesystem.</param> /// <param name="packageStore">The PackageStore that contains information about the package.</param> /// <param name="packageId">The package id of the package to load.</param> /// <param name="packageLocation">The location of the package, as defined in /// LearningStore PackageItem.Location column. This cannot be null.</param> /// <param name="impersonationBehavior">The user who has access to the file system related to the store.</param> /// <remarks></remarks> internal FileSystemPackageStoreReader(string packageBasePath, FileSystemPackageStore packageStore, PackageItemIdentifier packageId, string packageLocation, ImpersonationBehavior impersonationBehavior) { m_store = packageStore; m_packageId = packageId; m_impersonationBehavior = impersonationBehavior; m_packageBasePath = PackageReader.SafePathCombine(packageBasePath, packageLocation); // This does not verify that m_packageBasePath actually exists m_fsPackageReader = new FileSystemPackageReader(m_packageBasePath, m_impersonationBehavior); }
/// <summary> /// Deletes pacakge and related attempts from database. /// </summary> /// <param name="packId">Long integer value represents package identifier.</param> protected void DeletePackage(long packId) { // set <packageId> to the ID of this package PackageItemIdentifier packageId = new PackageItemIdentifier(packId); // before we delete the package, we need to delete all attempts on the package -- // the following query looks for those attempts LearningStoreJob job = LStore.CreateJob(); LearningStoreQuery query = LStore.CreateQuery( Schema.MyAttempts.ViewName); query.AddCondition(Schema.MyAttempts.PackageId, LearningStoreConditionOperator.Equal, packageId); query.AddCondition(Schema.MyAttempts.AttemptId, LearningStoreConditionOperator.NotEqual, null); query.AddColumn(Schema.MyAttempts.AttemptId); query.AddSort(Schema.MyAttempts.AttemptId, LearningStoreSortDirection.Ascending); job.PerformQuery(query); DataTable dataTable = job.Execute <DataTable>(); AttemptItemIdentifier previousAttemptId = null; // loop once for each attempt on this package foreach (DataRow dataRow in dataTable.Rows) { // set <attemptId> to the ID of this attempt AttemptItemIdentifier attemptId; LStoreHelper.CastNonNull(dataRow["AttemptId"], out attemptId); // if <attemptId> is a duplicate attempt ID, skip it; note that the query // results are sorted by attempt ID (see above) if ((previousAttemptId != null) && (previousAttemptId.GetKey() == attemptId.GetKey())) { continue; } // delete this attempt StoredLearningSession.DeleteAttempt(LStore, attemptId); // continue to the next attempt previousAttemptId = attemptId; } // delete the package PStore.DeletePackage(packageId); }
/// <summary> /// Constructor. Accesses all SharePoint files with elevated privilege. /// </summary> /// <param name="packageStore">The PackageStore that contains information about the package.</param> /// <param name="packageId">The package id of the package to load.</param> /// <param name="packageLocation">The location of the package, as defined in /// LearningStore PackageItem.Location column. This cannot be null.</param> /// <remarks></remarks> internal SharePointPackageStoreReader(SharePointPackageStore packageStore, PackageItemIdentifier packageId, string packageLocation) { Resources.Culture = Thread.CurrentThread.CurrentCulture; Utilities.ValidateParameterNotEmpty("packageLocation", packageLocation); m_store = packageStore; m_packageId = packageId; SharePointFileLocation location; if (!SharePointFileLocation.TryParse(packageLocation, out location)) { throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Resources.SPFormatInvalid, packageLocation)); } CreatePackageReader(location); }
/// <summary> /// Gets a package reader to read the package from the store. /// </summary> /// <param name="packageId">The unique identifier of the package to read.</param> /// <returns>A package reader to read the requested package</returns> /// <exception cref="LearningStoreItemNotFoundException">Thrown if <paramref name="packageId"/> /// does not represent a package in the store.</exception> public override PackageReader GetPackageReader(PackageItemIdentifier packageId) { Utilities.ValidateParameterNonNull("packageId", packageId); string packageLocation; // Getting the location will fail if the current user does not have access to the package. packageLocation = GetPackageLocationFromLS(packageId); if (String.IsNullOrEmpty(packageLocation)) { throw new LearningStoreItemNotFoundException(String.Format(CultureInfo.CurrentCulture, PackageResources.FSPS_InvalidPackageId, packageId.GetKey().ToString(CultureInfo.CurrentCulture))); } return(GetPackageReader(packageId, packageLocation)); }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] // see comment in catch block public void UnregisterPackage(PackageItemIdentifier packageId) { Utilities.ValidateParameterNonNull("packageId", packageId); string packageLocation = RemovePackageReference(packageId); try { RemoveCache(packageLocation); } catch { // It does not matter why this fails, ignore it. At this point, the package reference is gone from // LearningStore. So, even if we can't remove the files now they will eventually time out and be // deleted from the cache because they have not been used. } }
/// <summary> /// Requests that the list of training for the current user be retrieved from the LearningStore /// database. Adds the request to a given <c>LearningStoreJob</c> for later execution. /// </summary> /// <param name="job">A <c>LearningStoreJob</c> to add the new query to.</param> /// <param name="packageId">To request information related to a single pass the /// <c>PackageItemIdentifier</c> of the package as this parameter. Otherwise, leave this /// parameter <c>null</c>.</param> protected void RequestMyTraining(LearningStoreJob job, PackageItemIdentifier packageId) { LearningStoreQuery query = LStore.CreateQuery(Schema.MyAttempts.ViewName); query.AddColumn(Schema.MyAttempts.PackageId); query.AddColumn(Schema.MyAttempts.OrganizationId); query.AddColumn(Schema.MyAttempts.AttemptId); query.AddColumn(Schema.MyAttempts.AttemptStatus); query.AddColumn(Schema.MyAttempts.TotalPoints); if (packageId != null) { query.AddCondition(Schema.MyAttempts.PackageId, LearningStoreConditionOperator.Equal, packageId); } job.PerformQuery(query); }
/// <summary> /// Adds package to the database. /// </summary> /// <param name="package">Package value represents package object with necessary information.</param> protected PackageItemIdentifier AddPackage(Package package) { PackageItemIdentifier packageId = null; ValidationResults importLog; using (PackageReader packageReader = package.GetPackageReader()) { AddPackageResult result = PStore.AddPackage(packageReader, new PackageEnforcement(false, false, false)); packageId = result.PackageId; importLog = result.Log; } LearningStoreJob job = LStore.CreateJob(); Dictionary <string, object> dic = new Dictionary <string, object>(); dic.Add(Schema.PackageItem.IudicoCourseRef, package.CourseID); job.UpdateItem(packageId, dic); job.Execute(); return(packageId); }
/// <summary> /// Retrieves package id by specified IUDICO course. /// </summary> /// <param name="course">Course object represents iudico course entity.</param> /// <returns>PackageItemIdentifier value representing corresponding MLC Package ID.</returns> protected PackageItemIdentifier GetPackageIdentifier(int courseId) { PackageItemIdentifier result = null; LearningStoreJob job = LStore.CreateJob(); LearningStoreQuery query = LStore.CreateQuery(Schema.PackageIdByCourse.ViewName); query.AddColumn(Schema.PackageIdByCourse.PackageId); query.SetParameter(Schema.PackageIdByCourse.IudicoCourseRef, courseId); job.PerformQuery(query); ReadOnlyCollection <object> resultList = job.Execute(); DataTable dataTable = (DataTable)resultList[0]; if (dataTable.Rows.Count > 0) { LStoreHelper.Cast(dataTable.Rows[0][Schema.PackageIdByCourse.PackageId], out result); } return(result); }
/// <summary> /// Requests that the list of training for the current user be retrieved from the LearningStore /// database. Adds the request to a given <c>LearningStoreJob</c> for later execution. /// </summary> /// /// <param name="job">A <c>LearningStoreJob</c> to add the new query to.</param> /// /// <param name="packageId">To request information related to a single pass the /// <c>PackageItemIdentifier</c> of the package as this parameter. Otherwise, leave this /// parameter <c>null</c>.</param> /// /// <remarks> /// After executing this method, and later calling <c>Job.Execute</c>, call /// <c>GetMyTrainingResultsToHtml</c> to convert the <c>DataTable</c> returned by /// <c>Job.Execute</c> into HTML. /// </remarks> /// protected void RequestMyTraining(LearningStoreJob job, PackageItemIdentifier packageId) { LearningStoreQuery query = LStore.CreateQuery(Schema.MyAttemptsAndPackages.ViewName); query.AddColumn(Schema.MyAttemptsAndPackages.PackageId); query.AddColumn(Schema.MyAttemptsAndPackages.PackageFileName); query.AddColumn(Schema.MyAttemptsAndPackages.OrganizationId); query.AddColumn(Schema.MyAttemptsAndPackages.OrganizationTitle); query.AddColumn(Schema.MyAttemptsAndPackages.AttemptId); query.AddColumn(Schema.MyAttemptsAndPackages.UploadDateTime); query.AddColumn(Schema.MyAttemptsAndPackages.AttemptStatus); query.AddColumn(Schema.MyAttemptsAndPackages.TotalPoints); query.AddSort(Schema.MyAttemptsAndPackages.UploadDateTime, LearningStoreSortDirection.Ascending); query.AddSort(Schema.MyAttemptsAndPackages.OrganizationId, LearningStoreSortDirection.Ascending); if (packageId != null) { query.AddCondition(Schema.MyAttemptsAndPackages.PackageId, LearningStoreConditionOperator.Equal, packageId); } job.PerformQuery(query); }
/// <summary> /// Retrieves Organization Id by specified package oidentifier. /// </summary> /// <param name="packageId"><c>PackageItemIdentifier</c> value representing package id, organization is being searched by.</param> /// <returns><c>ActivityPackageItemIdentifier</c> value, which represents organization identifier of specified package.</returns> protected ActivityPackageItemIdentifier GetOrganizationIdentifier(PackageItemIdentifier packageId) { ActivityPackageItemIdentifier result = null; LearningStoreJob job = LStore.CreateJob(); LearningStoreQuery query = LStore.CreateQuery(Schema.RootActivityByPackage.ViewName); query.AddColumn(Schema.RootActivityByPackage.RootActivity); query.SetParameter(Schema.RootActivityByPackage.PackageId, packageId); job.PerformQuery(query); var resultList = job.Execute(); DataTable dataTable = (DataTable)resultList[0]; if (dataTable.Rows.Count > 0) { LStoreHelper.Cast(dataTable.Rows[0][Schema.RootActivityByPackage.RootActivity], out result); } return(result); }
/// <summary>Gets a <see cref="PackageReader"/> for an item.</summary> /// <param name="packageId">the id of the package.</param> /// <param name="packageLocation">The locatoin of the package.</param> /// <returns>A <see cref="PackageReader"/>.</returns> protected internal override PackageReader GetPackageReader(PackageItemIdentifier packageId, string packageLocation) { return(new SharePointLibraryPackageReader(CacheSettings, new SharePointFileLocation(packageLocation), null)); }
/// <summary> /// Deletes pacakge and related attempts from database. /// </summary> /// <param name="packId">Long integer value represents package identifier.</param> protected void DeletePackage(long packId) { // set <packageId> to the ID of this package PackageItemIdentifier packageId = new PackageItemIdentifier(packId); // before we delete the package, we need to delete all attempts on the package -- // the following query looks for those attempts LearningStoreJob job = LStore.CreateJob(); LearningStoreQuery query = LStore.CreateQuery( Schema.MyAttempts.ViewName); query.AddCondition(Schema.MyAttempts.PackageId, LearningStoreConditionOperator.Equal, packageId); query.AddCondition(Schema.MyAttempts.AttemptId, LearningStoreConditionOperator.NotEqual, null); query.AddColumn(Schema.MyAttempts.AttemptId); query.AddSort(Schema.MyAttempts.AttemptId, LearningStoreSortDirection.Ascending); job.PerformQuery(query); DataTable dataTable = job.Execute<DataTable>(); AttemptItemIdentifier previousAttemptId = null; // loop once for each attempt on this package foreach (DataRow dataRow in dataTable.Rows) { // set <attemptId> to the ID of this attempt AttemptItemIdentifier attemptId; LStoreHelper.CastNonNull(dataRow["AttemptId"], out attemptId); // if <attemptId> is a duplicate attempt ID, skip it; note that the query // results are sorted by attempt ID (see above) if ((previousAttemptId != null) && (previousAttemptId.GetKey() == attemptId.GetKey())) continue; // delete this attempt StoredLearningSession.DeleteAttempt(LStore, attemptId); // continue to the next attempt previousAttemptId = attemptId; } // delete the package PStore.DeletePackage(packageId); }
/// <summary> /// Retrieves Organization Id by specified package oidentifier. /// </summary> /// <param name="packageId"><c>PackageItemIdentifier</c> value representing package id, organization is being searched by.</param> /// <returns><c>ActivityPackageItemIdentifier</c> value, which represents organization identifier of specified package.</returns> protected ActivityPackageItemIdentifier GetOrganizationIdentifier(PackageItemIdentifier packageId) { ActivityPackageItemIdentifier result = null; LearningStoreJob job = LStore.CreateJob(); LearningStoreQuery query = LStore.CreateQuery(Schema.RootActivityByPackage.ViewName); query.AddColumn(Schema.RootActivityByPackage.RootActivity); query.SetParameter(Schema.RootActivityByPackage.PackageId, packageId); job.PerformQuery(query); var resultList = job.Execute(); DataTable dataTable = (DataTable)resultList[0]; if (dataTable.Rows.Count > 0) LStoreHelper.Cast(dataTable.Rows[0][Schema.RootActivityByPackage.RootActivity], out result); return result; }
protected void DeletePackagesButton_Click(object sender, EventArgs e) { // the user clicked "Upload"... // hide the confirmation panel ConfirmMessage.Visible = false; // the PackagesToDelete hidden form element contains a comma-delimited list of IDs of // packages to delete (copied from <dialogArguments> on the client) -- attempt to delete // those packages, and set <deleted> to the IDs of packages successfully deleted List <string> deleted = new List <string>(); try { // loop once for each package to delete foreach (string id in PackagesToDelete.Value.Split(',')) { // set <packageId> to the ID of this package PackageItemIdentifier packageId = new PackageItemIdentifier( Convert.ToInt64(id, CultureInfo.InvariantCulture)); // before we delete the package, we need to delete all attempts on the package -- // the following query looks for those attempts LearningStoreJob job = LStore.CreateJob(); LearningStoreQuery query = LStore.CreateQuery( Schema.MyAttemptsAndPackages.ViewName); query.AddCondition(Schema.MyAttemptsAndPackages.PackageId, LearningStoreConditionOperator.Equal, packageId); query.AddCondition(Schema.MyAttemptsAndPackages.AttemptId, LearningStoreConditionOperator.NotEqual, null); query.AddColumn(Schema.MyAttemptsAndPackages.AttemptId); query.AddSort(Schema.MyAttemptsAndPackages.AttemptId, LearningStoreSortDirection.Ascending); job.PerformQuery(query); DataTable dataTable = job.Execute <DataTable>(); AttemptItemIdentifier previousAttemptId = null; // loop once for each attempt on this package foreach (DataRow dataRow in dataTable.Rows) { // set <attemptId> to the ID of this attempt AttemptItemIdentifier attemptId; LStoreHelper.CastNonNull(dataRow["AttemptId"], out attemptId); // if <attemptId> is a duplicate attempt ID, skip it; note that the query // results are sorted by attempt ID (see above) if ((previousAttemptId != null) && (previousAttemptId.GetKey() == attemptId.GetKey())) { continue; } // delete this attempt StoredLearningSession.DeleteAttempt(LStore, attemptId); // continue to the next attempt previousAttemptId = attemptId; } // delete the package PStore.DeletePackage(packageId); // add the package ID to the list of deleted packages deleted.Add(id); } // the operation was successful, and there are no messages to // display to the user, so close the dialog CloseDialogScript.Visible = true; } catch (Exception ex) { // an unexpected error occurred -- display a generic message that // doesn't include the exception message (since that message may // include sensitive information), and write the exception message // to the event log ErrorIntro.Visible = true; ErrorMessage.Visible = true; ErrorMessage.Controls.Add(new System.Web.UI.LiteralControl( Server.HtmlEncode("A serious error occurred. Please contact your system administrator. More information has been written to the server event log."))); LogEvent(System.Diagnostics.EventLogEntryType.Error, "An exception occurred while deleting a package:\n\n{0}\n\n", ex.ToString()); } // update the buttons DeletePackagesButton.Visible = false; CloseButton.Text = "OK"; // set the hidden form element PackagesSuccessfullyDeleted to a // comma-separated list of IDs of packages that were successfully // deleted, and enable the client-side script that communicates this // information to the parent page PackagesSuccessfullyDeleted.Value = String.Join(",", deleted.ToArray()); UpdateParentPageScript.Visible = true; }
/// <summary> /// Create an AddPackageResult from the results of adding a reference to a package in PackageStore. /// </summary> /// <param name="addReferenceResult">The results of adding a package reference to PackageStore.</param> internal AddPackageResult(AddPackageReferenceResult addReferenceResult) { m_log = addReferenceResult.Log; m_packageId = addReferenceResult.PackageId; }
/// <summary> /// Return a PackageReader that can read files from a package that /// is stored in LearningStore. /// </summary> /// <param name="packageId">The identifier of the package to be read.</param> /// <param name="packageLocation">The location information which defines /// the location of the package. This is the value in the PackageItem.Location column in /// LearningStore. It cannot be String.Empty.</param> /// <returns>A package reader for a package referenced in LearningStore.</returns> /// <remarks> /// </remarks> protected internal override PackageReader GetPackageReader(PackageItemIdentifier packageId, string packageLocation) { return(new FileSystemPackageStoreReader(m_basePath, this, packageId, packageLocation, m_impersonationBehavior)); }
/// <summary> /// Reads a <c>DataTable</c>, returned by <c>Job.Execute</c>, containing the results requested /// by a previous call to <c>RequestMyTraining</c>. Converts the results to HTML rows, added /// to a given HTML table. /// </summary> /// /// <param name="dataTable">A <c>DataTable</c> returned from <c>Job.Execute</c>.</param> /// /// <param name="htmlTable">The HTML table to write to.</param> /// protected void GetMyTrainingResultsToHtml(DataTable dataTable, Table htmlTable) { // loop once for each organization of each package PackageItemIdentifier previousPackageId = null; foreach (DataRow dataRow in dataTable.Rows) { // extract information from <dataRow> into local variables PackageItemIdentifier packageId; LStoreHelper.CastNonNull(dataRow[Schema.MyAttemptsAndPackages.PackageId], out packageId); string packageFileName; LStoreHelper.CastNonNull(dataRow[Schema.MyAttemptsAndPackages.PackageFileName], out packageFileName); ActivityPackageItemIdentifier organizationId; LStoreHelper.CastNonNull(dataRow[Schema.MyAttemptsAndPackages.OrganizationId], out organizationId); string organizationTitle; LStoreHelper.CastNonNull(dataRow[Schema.MyAttemptsAndPackages.OrganizationTitle], out organizationTitle); AttemptItemIdentifier attemptId; LStoreHelper.Cast(dataRow[Schema.MyAttemptsAndPackages.AttemptId], out attemptId); DateTime?uploadDateTime; LStoreHelper.Cast(dataRow[Schema.MyAttemptsAndPackages.UploadDateTime], out uploadDateTime); AttemptStatus?attemptStatus; LStoreHelper.Cast(dataRow[Schema.MyAttemptsAndPackages.AttemptStatus], out attemptStatus); float?score; LStoreHelper.Cast(dataRow[Schema.MyAttemptsAndPackages.TotalPoints], out score); // if this <dataRow> is another organization (basically another "table of contents") // within the same package as the previous <dataRow>, set <samePackage> to true bool samePackage = ((previousPackageId != null) && (packageId.GetKey() == previousPackageId.GetKey())); // begin the HTML table row TableRow htmlRow = new TableRow(); htmlRow.ID = "Package" + packageId.GetKey().ToString(); // set <trainingName> to a name to use for this row (i.e. one // organization of one package) string trainingName; if (organizationTitle.Length == 0) { trainingName = packageFileName; } else { trainingName = String.Format("{0} - {1}", packageFileName, organizationTitle); } // add the "Select" HTML cell, unless this row is for the same // package as the previous row TableCell htmlCell = new TableCell(); if (samePackage) { htmlCell.CssClass = "Select_ SamePackage_"; } else { htmlCell.CssClass = "Select_ NewPackage_"; CheckBox checkBox = new CheckBox(); checkBox.ID = "Select" + packageId.GetKey().ToString(); checkBox.Attributes.Add("onclick", "OnSelectionChanged()"); checkBox.ToolTip = "Select"; htmlCell.Controls.Add(checkBox); } htmlRow.Cells.Add(htmlCell); // add the "Name" HTML cell htmlCell = new TableCell(); htmlCell.CssClass = "Name_"; HtmlAnchor anchor = new HtmlAnchor(); if (attemptId == null) { // attempt has not yet been created for this training -- create an URL that begins // with "Org:", indicating that the ID is an OrganizationId which identifies // which organization of which package to launch anchor.HRef = String.Format("javascript:OpenTraining('Org:{0}')", organizationId.GetKey()); // give this anchor an ID that allows client-side script to update its URL once // training has been launched anchor.ID = String.Format("Org_{0}", organizationId.GetKey()); // provide a tooltip anchor.Attributes.Add("title", "Begin training"); } else { // attempt was already created -- include its ID in the URL anchor.HRef = String.Format("javascript:OpenTraining('Att:{0}')", attemptId.GetKey()); // provide a tooltip anchor.Attributes.Add("title", "Continue training"); } anchor.InnerText = trainingName; htmlCell.Controls.Add(anchor); htmlRow.Cells.Add(htmlCell); // add the "Uploaded" HTML cell htmlCell = new TableCell(); htmlCell.CssClass = "Uploaded_"; htmlCell.Wrap = false; htmlCell.Text = NoBr(Server.HtmlEncode( String.Format("{0:d} {0:t}", uploadDateTime))); htmlRow.Cells.Add(htmlCell); // add the "Status" HTML cell string attemptStatusString; if (attemptStatus == null) { attemptStatusString = "Not Started"; } else { attemptStatusString = attemptStatus.ToString(); } htmlCell = new TableCell(); htmlCell.CssClass = "Status_"; htmlCell.Wrap = false; if (attemptId != null) { anchor = new HtmlAnchor(); anchor.HRef = String.Format("javascript:ShowLog({0})", attemptId.GetKey()); anchor.InnerHtml = NoBr(Server.HtmlEncode(attemptStatusString)); anchor.Attributes.Add("title", "Show Log"); htmlCell.Controls.Add(anchor); } else { htmlCell.Text = NoBr(Server.HtmlEncode(attemptStatusString)); } htmlRow.Cells.Add(htmlCell); // add the "Score" HTML cell string scoreString; if (score == null) { scoreString = ""; } else { scoreString = String.Format("{0:0}%", Math.Round(score.Value)); } htmlCell = new TableCell(); htmlCell.CssClass = "Score_"; htmlCell.Wrap = false; htmlCell.Text = NoBr(Server.HtmlEncode(scoreString)); htmlRow.Cells.Add(htmlCell); // end the table HTML row; add it to the HTML table htmlTable.Rows.Add(htmlRow); previousPackageId = packageId; } }
/// <summary> /// Delete a package that was previously added to the store. Deleted information cannot be recovered. /// </summary> /// <param name="packageId">The package to remove.</param> /// <remarks> /// <p/>If a file in the package cannot be deleted, the FileDeletionFailed event will be raised. /// </remarks> /// <exception cref="LearningStoreItemNotFoundException">Thrown if the <P>packageId</P> does not /// represent a package in the store.</exception> /// <exception cref="LearningStoreConstraintViolationException">Thrown if the package cannot be deleted /// from LearningStore because there are other items in the store that depend upon it. For instance, /// a package for which there are attempts in LearningStore, cannot be deleted.</exception> public void DeletePackage(PackageItemIdentifier packageId) { string packageLocation = RemovePackageReference(packageId); DeleteFiles(packageLocation); }
/// <summary> /// Read the files from a package and import the package information into LearningStore. Only packages /// which may be executed can be imported into LearningStore. /// See the class overview information for details. /// </summary> /// <param name="packageReader">A reader to read the files in the package to be imported.</param> /// <param name="packageId">The identifier of the package whose files are being imported.</param> /// <returns>Returns the location of the package that was added.</returns> /// <remarks> /// <p/>This method copies all package files that are referenced in the manifest into a unique /// subdirectory in the basePath directory. /// /// <p/>This method will validate that the package does not have any errors when it is /// processed by the <c>PackageValidator</c> class. Warnings that occur during validaton /// will have no effect on adding the package. /// /// <p/>Only packages which can be excuted may be imported into LearningStore. A package may be /// executed if there is at least one <Organization> nodes within it. /// /// <p/>This method creates a transaction, regardless of whether or not it is called within /// a transaction. /// /// <p/>The identity passed to the constructor will be used to write the files to the file system. This /// account must have appropriate permissions to write to the basePath directory for the package store. /// /// <p/>The exceptions thrown by Directory.CreateDirectory() may also be thrown by this method. /// </remarks> /// <exception cref="PackageImportException">Thrown if the package to be added is not a /// <c>PackageType.ContentAggregation</c> or does not contain /// at least one <item> node.</exception> /// <exception cref="UnauthorizedAccessException">Thrown if the identity used to create this object /// does not have sufficient permissions in the file system directory.</exception> private string ImportFiles(PackageItemIdentifier packageId, PackageReader packageReader) { string relativePackageLocation; // package location unique to this pacakge // The outer try/catch block is there for security reasons. Search MSDN for // "WrapVulnerableFinallyClausesInOuterTry" to see details. try { string absPackageLocation = null; // Create directories using the identity account that was passed to the store. using (ImpersonateIdentity id = new ImpersonateIdentity(m_impersonationBehavior)) { // Create the directory, relative to m_basePath relativePackageLocation = CreatePackageDirectory(packageId.GetKey(), 100); // Get the absolution package location of the new package directory absPackageLocation = PackageReader.SafePathCombine(m_basePath, relativePackageLocation); } if (packageReader.GetType().Equals(typeof(ZipPackageReader))) { // Let the zip reader do its own copy, as it's more efficient. Do not impersonate, as the package reader // needs to use its own identity (not the the store's identity) to access the files // ZipPackageReader doesn't want the directory to exist. (We had to create it above to verify it was // possible). using (ImpersonateIdentity id = new ImpersonateIdentity(m_impersonationBehavior)) { Directory.Delete(absPackageLocation); } ZipPackageReader zipReader = packageReader as ZipPackageReader; zipReader.CopyTo(absPackageLocation); } else { foreach (string filePath in packageReader.GetFilePaths()) { using (Disposer disposer = new Disposer()) { string absFilePath; // absolute location of the file to write string absDirPath; // absolute location of the drectory to write to FileStream outputStream; // stream to write to // Get stream for file from package Stream pkgStream = packageReader.GetFileStream(filePath); disposer.Push(pkgStream); // Create subdirectory, if it's required using (ImpersonateIdentity id = new ImpersonateIdentity(m_impersonationBehavior)) { absFilePath = PackageReader.SafePathCombine(absPackageLocation, filePath); absDirPath = Path.GetDirectoryName(absFilePath); if (!File.Exists(absDirPath) && !Directory.Exists(absDirPath)) { // Create it Directory.CreateDirectory(absDirPath); } // Create file location to write outputStream = new FileStream(absFilePath, FileMode.Create); disposer.Push(outputStream); } // Copy from the pkgStream to the outputStream, using the correct identities Utilities.CopyStream(pkgStream, ImpersonationBehavior.UseImpersonatedIdentity, outputStream, m_impersonationBehavior); } } } using (ImpersonateIdentity id = new ImpersonateIdentity(m_impersonationBehavior)) { // Remove imsmanifest.xml from the target directory. It'll be stored in LearningStore and providing two // copies may cause confusion or sync issues. string manifestFilePath = PackageReader.SafePathCombine(absPackageLocation, "imsmanifest.xml"); File.Delete(manifestFilePath); } } catch { throw; } // Return the new package return(relativePackageLocation); }
/// <summary> /// Gets a PackageReader that can read files from the specified package. /// </summary> /// <param name="packageId">The identifier of a package that exists in the store.</param> /// <returns>A PackageReader for the requested <paramref name="packageId"/>.</returns> public override PackageReader GetPackageReader(PackageItemIdentifier packageId) { string packageLocation = GetPackageLocationFromLS(packageId); return(GetPackageReader(packageId, packageLocation)); }
/// <summary>Gets a <see cref="PackageReader"/> for an item.</summary> /// <param name="packageId">the id of the package.</param> /// <param name="packageLocation">The locatoin of the package.</param> /// <returns>A <see cref="PackageReader"/>.</returns> protected internal override PackageReader GetPackageReader(PackageItemIdentifier packageId, string packageLocation) { return(new SharePointPackageStoreReader(this, packageId, packageLocation)); }