using System; using System.IO; using System.Drawing; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using Plumtree.Remote.Portlet; using Plumtree.Remote.PRC; using Plumtree.Remote.PRC.Content; using Plumtree.Remote.PRC.Content.DataEntryTemplate; using Plumtree.Remote.PRC.Content.Folder; using Plumtree.Remote.PRC.Content.Property; using Plumtree.Remote.PRC.Content.SelectionList; using Plumtree.Remote.PRC.Content.Item; namespace DataEntryTemplateSample { public class DETSample : System.Web.UI.Page { protected System.Web.UI.WebControls.Label lblDETName; protected System.Web.UI.WebControls.Panel pnlMain; protected System.Web.UI.WebControls.Label lblMessage; protected System.Web.UI.WebControls.Button btnCreateItem; protected IRemoteSession remoteSession; protected IPortletContext portletContext; protected IDataEntryTemplate dataEntryTemplate; private void Page_Load(object sender, System.EventArgs e) { try { portletContext = PortletContextFactory.CreatePortletContext(Request, Response); remoteSession = portletContext.GetRemotePortalSession(); //Get the content factory. IContentFactory contentFactory = remoteSession.GetContentFactory(); //Get the folder containing the data entry template. IFolder folder = RetrieveContentFolder(contentFactory); //Get the data entry template dataEntryTemplate = RetrieveDET(contentFactory, folder); //Put the name of the data entry template at the top of the form. lblDETName.Text = dataEntryTemplate.Name; //Create input controls for data entry template. RenderDataEntryTemplate(dataEntryTemplate); } catch(Exception ex) { DisplayMessage("Exception: " + ex.Message); } } /// /// Gets the Content Server folder used to store all Content /// Server objects for our application. ///

/// In this sample, we will create a new folder. In your /// real application you would likely have created the folder * already and will need to query for it here. ///

private static IFolder RetrieveContentFolder(IContentFactory factory) { // Get a folder manager for working with Content Server folders. IFolderManager folderManager = factory.GetFolderManager(); //Check to see if the folder has already been created IFolder subFolder = folderManager.GetFolderByPath("/C# Web Example - DET"); if(subFolder == null) { //If the folder is not there we will create our own folder for the sample //Get a reference to the root folder. It always exists. IFolder rootFolder = folderManager.GetRootFolder(); // Create a new folder. subFolder = folderManager.CreateFolder(rootFolder, "C# Web Example - DET"); subFolder.Store(); } return subFolder; } /// /// Gets the DET that defines what fields are present in each /// customer support incident. ///

/// In this sample, we will create a new DET. In your real /// application, this method would probably query for an existing DET. * existing DET. ///

private static IDataEntryTemplate RetrieveDET(IContentFactory factory, IFolder folder) { // // A Data Entry Template object is a collection of // property objects. Each property object represents // a field in the records associated with the DET. // // This sample uses all of the classes of properties // available in Content Server. Each customer support // incidents will have: // (integer) Incident ID // (boolean) If the incident has been resolved // (float) Incident severity rating // (date) Date the incident was opened // (text line) Customer name // (item reference) Link to other content item representing the customer // (selection list) The product the incident was reported in // (text block) Reported problem // (file) Logs of problem // (image) Screen shot of problem // // Get manager objects needed for creating a DET. IDataEntryTemplateManager detManager = factory.GetDataEntryTemplateManager(); // Check to see if the data entry template already exists IDataEntryTemplate det = detManager.GetDataEntryTemplate(folder, "Support Incident Data Entry Template"); if(det != null) { return det; } IPropertyManager propertyManager = factory.GetPropertyManager(); ISelectionListManager slManager = factory.GetSelectionListManager(); // Create a DET object. det = detManager.CreateDataEntryTemplate(folder, "Support Incident Data Entry Template"); // Add an integer property. IIntegerProperty incident = propertyManager.CreateIntegerProperty("Incident ID", "The ticket number for this incident."); det.AddProperty(incident); // Add a boolean property IBooleanProperty resolved = propertyManager.CreateBooleanProperty("Resolved", "True if the incident has been closed; false if it is still open."); det.AddProperty(resolved); // Add a double property. IDoubleProperty severity = propertyManager.CreateDoubleProperty("Severity", "Percentage stating how severe the incident is."); det.AddProperty(severity); // Add a date property. IDateProperty opened = propertyManager.CreateDateProperty("Date Opened", "The date and time the incident was reported."); det.AddProperty(opened); // Add a text line property. // Text lines are brief strings without newline characters. // Use the text block property for storing longer strings. ITextLineProperty customerName = propertyManager.CreateTextLineProperty("Customer Name", "The name of the customer."); det.AddProperty(customerName); // Add an item reference property. // An item reference links to another content item. The // content item does not have to be associated with the // same DET. For example, we will link to a fictional // content item representing the customer that is having // the support problem; which would be associated with // a DET representing customers. // // Not shown is the item collection property. It is // similar to the item reference property, but links to // multiple content items. IItemReferenceProperty customerData = propertyManager.CreateItemReferenceProperty("Customer Information", "Links to information about the customer such as the contact and their phone number."); det.AddProperty(customerData); // Add a selection list property. // A selection list is a defined set of choices of which // one may be selected. This can be visualized as a // drop down box. //Check to see if the selection list already exists ISelectionList selectionList = null; ISelectionList[] selectionLists = slManager.GetSelectionLists(folder); foreach(ISelectionList sl in selectionLists) { if(sl.Name.Equals("Products Selection List")) { selectionList = sl; break; } } if(selectionList == null) { string[] listValues = {"Portal", "Search Server", "Collaboration Server", "Content Server", "Analytics"}; selectionList = slManager.CreateSelectionList(folder, "Products Selection List", listValues); selectionList.Store(); } ISelectionListProperty products = propertyManager.CreateSelectionListProperty("Product", "The product which the support incident is opened against", selectionList); det.AddProperty(products); // Add a text block property. // Text block properties are used to store long strings // that can span many lines. For short strings contained // on only one line, use the text line property instead. ITextBlockProperty description = propertyManager.CreateTextBlockProperty("Incident Description", "A writeup summarizing the problem the customer is experiencing."); det.AddProperty(description); // Add a file property. IFileProperty log = propertyManager.CreateFileProperty("Log File", "A log file taken while the problem occurred."); det.AddProperty(log); // Add an image property. IImageProperty screenShot = propertyManager.CreateImageProperty("Screen Shot", "A screen shot of the problem."); det.AddProperty(screenShot); // Actually store the DET and all the properties associated with it. det.Store(); return det; } /// /// Create all the controls for a given Data Entry Template. The type of /// control depends on the type of property. /// /// private void RenderDataEntryTemplate(IDataEntryTemplate dataEntryTemplate) { Table table = new Table(); table.ID = "Main DET Table"; //Add TextBox to enter Content Item Name TextBox textBox = new TextBox(); textBox.ID = "Content Item Name"; AddTableRow(table, "Content Item Name", textBox, ""); //Loop through all the properties and add them to the table based on property type IBaseProperty[] allProperties = dataEntryTemplate.GetAllProperties(); foreach(IBaseProperty property in allProperties) { //Check for different types of properties IBooleanProperty boolProp = property as Plumtree.Remote.PRC.Content.Property.IBooleanProperty; if(boolProp != null) { CheckBox checkBox = new CheckBox(); checkBox.ID = property.Name; AddTableRow(table, property.DisplayName, checkBox, property.Description); } IDateProperty dateProp = property as Plumtree.Remote.PRC.Content.Property.IDateProperty; if(dateProp != null) { textBox = new TextBox(); textBox.ID = property.Name; AddTableRow(table, property.DisplayName, textBox, property.Description); } IDoubleProperty doubleProp = property as Plumtree.Remote.PRC.Content.Property.IDoubleProperty; if(doubleProp != null) { textBox = new TextBox(); textBox.ID = property.Name; AddTableRow(table, property.DisplayName, textBox, property.Description); } IFileProperty fileProp = property as Plumtree.Remote.PRC.Content.Property.IFileProperty; if(fileProp != null) { //The HtmlInputFile control requires the 2.2 .NET WebControls to work properly //Also make sure the Html Form has the attribute enctype=multipart/form-data HtmlInputFile inputFile = new HtmlInputFile(); inputFile.ID = property.Name; //Using an HtmlInputFile control will take us out of the portal when there //is a postback. We could use something like portletContext.GetResponse().ReturnToPortal(); //to get back to the portal after the postback. For now we'll omit the control for simplicity. //AddTableRow(table, property.DisplayName, inputFile, property.Description); AddTableRow(table, property.DisplayName, new LiteralControl(""), property.Description); } IImageProperty imageProp = property as Plumtree.Remote.PRC.Content.Property.IImageProperty; if(imageProp != null) { //The HtmlInputFile control requires the 2.2 .NET WebControls to work properly //Also make sure the Html Form has the attribute enctype=multipart/form-data HtmlInputFile inputFile = new HtmlInputFile(); inputFile.ID = property.Name; //Using an HtmlInputFile control will take us out of the portal when there //is a postback. We could use something like portletContext.GetResponse().ReturnToPortal(); //to get back to the portal after the postback. For now we'll omit the control for simplicity. //AddTableRow(table, property.DisplayName, inputFile, property.Description); AddTableRow(table, property.DisplayName, new LiteralControl(""), property.Description); } IIntegerProperty integerProp = property as Plumtree.Remote.PRC.Content.Property.IIntegerProperty; if(integerProp != null) { textBox = new TextBox(); textBox.ID = property.Name; AddTableRow(table, property.DisplayName, textBox, property.Description); } IItemReferenceProperty itemRefProp = property as Plumtree.Remote.PRC.Content.Property.IItemReferenceProperty; if(itemRefProp != null) { //We could query for valid content items and display them in a control //or display content items based on some other business logic. //For the sample we'll leave this blank. AddTableRow(table, property.DisplayName, new LiteralControl(""), property.Description); } ISelectionListProperty selectionListProp = property as Plumtree.Remote.PRC.Content.Property.ISelectionListProperty; if(selectionListProp != null) { DropDownList dropDown = new DropDownList(); dropDown.ID = property.Name; ISelectionList selectionList = selectionListProp.GetSelectionList(); String[] values = selectionList.GetValues(); foreach(String val in values) { dropDown.Items.Add(val); } AddTableRow(table, property.DisplayName, dropDown, property.Description); } ITextBlockProperty textBlockProp = property as Plumtree.Remote.PRC.Content.Property.ITextBlockProperty; if(textBlockProp != null) { HtmlTextArea textArea = new HtmlTextArea(); textArea.ID = property.Name; AddTableRow(table, property.DisplayName, textArea, property.Description); } ITextLineProperty textLineProp = property as Plumtree.Remote.PRC.Content.Property.ITextLineProperty; if(textLineProp != null) { textBox = new TextBox(); textBox.ID = property.Name; AddTableRow(table, property.DisplayName, textBox, property.Description); } } //Add the table to the main panel pnlMain.Controls.Add(table); } /// /// Create button click event handler /// private void btnCreateItem_Click(object sender, System.EventArgs e) { try { //Get the Content Item Manager IContentFactory contentFactory = remoteSession.GetContentFactory(); IContentItemManager contentItemManager = contentFactory.GetContentItemManager(); // Create a new Content Item. String contentItemName = ((TextBox)pnlMain.FindControl("Content Item Name")).Text; IContentItem contentItem = contentItemManager.CreateContentItem( dataEntryTemplate.GetContainingFolder(), contentItemName, dataEntryTemplate); // Assign the fields of the content item. // Each field is defined by the DET corresponding to the content item. IBaseProperty[] props = dataEntryTemplate.GetAllProperties(); Table table = (Table)pnlMain.FindControl("Main DET Table"); foreach(TableRow row in table.Rows) { foreach(Control control in row.Cells[1].Controls) { //NOTE: Even though RenderDataEntryTemplate dynamically creates //controls for any data entry template, this method has been hard-coded //for the data entry template we've created in RetrieveDET for clarity. switch(control.ID) { case "Incident ID": contentItem.SetIntegerPropertyValue(props[0], Convert.ToInt32(((TextBox)control).Text)); break; case "Resolved": contentItem.SetBooleanPropertyValue(props[1], ((CheckBox)control).Checked); break; case "Severity": contentItem.SetDoublePropertyValue(props[2], Convert.ToDouble(((TextBox)control).Text)); break; case "Date Opened": contentItem.SetDatePropertyValue(props[3], DateTime.Parse(((TextBox)control).Text)); break; case "Customer Name": contentItem.SetTextLinePropertyValue(props[4], ((TextBox)control).Text); break; case "Customer Information": //IContentItem customer = contentItemManager.GetContentItem(dataEntryTemplate.GetContainingFolder(), "Customer X"); //contentItem.SetItemReferencePropertyValue(props[5], customer); break; case "Product": contentItem.SetSelectionListPropertyValue(props[6], ((DropDownList)control).SelectedValue); break; case "Incident Description": contentItem.SetTextBlockPropertyValue(props[7], ((HtmlTextArea)control).Value); break; case "Log File": //The HtmlInputFile control requires the 2.2 .NET WebControls to work properly //Also make sure the Html Form has the attribute enctype=multipart/form-data HttpPostedFile postedLogFile = ((HtmlInputFile)control).PostedFile; if(postedLogFile != null) { String fileName = Path.GetFileName(postedLogFile.FileName); if(fileName != "") { contentItem.SetFilePropertyValue(props[8], fileName, postedLogFile.InputStream); } } break; case "Screen Shot": //The HtmlInputFile control requires the 2.2 .NET WebControls to work properly //Also make sure the Html Form has the attribute enctype=multipart/form-data HttpPostedFile postedScreenFile = ((HtmlInputFile)control).PostedFile; if(postedScreenFile != null) { String fileName = Path.GetFileName(postedScreenFile.FileName); if(fileName != "") { contentItem.SetImagePropertyValue(props[9], fileName, postedScreenFile.InputStream); } } break; default: //do nothing break; } } } //Store the content Item contentItemManager.CheckInItem(contentItem, "Created by DET Sample Portlet"); //Display a message about the new content item DisplayMessage("Content Item " + contentItemName + " Created"); } catch(Exception ex) { DisplayMessage("Exception: " + ex.Message); } } /// /// Add a content property row to an HTML table /// /// Table to add row to /// Name of property being added /// Input control for this property /// Description of property private static void AddTableRow(Table table, String name, Control control, String description) { TableRow row = new TableRow(); TableCell cell = new TableCell(); //Add Name to first column of first row cell.Text = name; cell.Font.Bold = true; row.Cells.Add(cell); //Add Control to second column of first row cell = new TableCell(); cell.Controls.Add(control); row.Cells.Add(cell); //Add first row to table table.Rows.Add(row); //add description to second column of second row so //it is under the control row = new TableRow(); cell = new TableCell(); row.Cells.Add(cell); cell = new TableCell(); cell.Text = description; row.Cells.Add(cell); table.Rows.Add(row); } /// /// Displays an error message in red /// /// message to display private void DisplayMessage(string message) { lblMessage.Text = message; lblMessage.ForeColor = Color.Red; } #region Web Form Designer generated code override protected void OnInit(EventArgs e) { // // CODEGEN: This call is required by the ASP.NET Web Form Designer. // InitializeComponent(); base.OnInit(e); } /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.btnCreateItem.Click += new System.EventHandler(this.btnCreateItem_Click); this.Load += new System.EventHandler(this.Page_Load); } #endregion } }