import java.net.URL; import java.util.Date; import com.plumtree.remote.prc.IRemoteSession; import com.plumtree.remote.prc.RemoteSessionFactory; import com.plumtree.remote.prc.content.IContentFactory; import com.plumtree.remote.prc.content.dataentrytemplate.IDataEntryTemplate; import com.plumtree.remote.prc.content.dataentrytemplate.IDataEntryTemplateManager; import com.plumtree.remote.prc.content.folder.IFolder; import com.plumtree.remote.prc.content.folder.IFolderManager; import com.plumtree.remote.prc.content.item.IContentItem; import com.plumtree.remote.prc.content.item.IContentItemManager; import com.plumtree.remote.prc.content.presentationtemplate.IPresentationTemplate; import com.plumtree.remote.prc.content.presentationtemplate.IPresentationTemplateManager; import com.plumtree.remote.prc.content.property.IBaseProperty; import com.plumtree.remote.prc.content.property.IBooleanProperty; import com.plumtree.remote.prc.content.property.IDateProperty; import com.plumtree.remote.prc.content.property.IDoubleProperty; import com.plumtree.remote.prc.content.property.IFileProperty; import com.plumtree.remote.prc.content.property.IImageProperty; import com.plumtree.remote.prc.content.property.IIntegerProperty; import com.plumtree.remote.prc.content.property.IItemReferenceProperty; import com.plumtree.remote.prc.content.property.IPropertyManager; import com.plumtree.remote.prc.content.property.ISelectionListProperty; import com.plumtree.remote.prc.content.property.ITextBlockProperty; import com.plumtree.remote.prc.content.property.ITextLineProperty; import com.plumtree.remote.prc.content.security.IFolderACL; import com.plumtree.remote.prc.content.security.IFolderACLEntry; import com.plumtree.remote.prc.content.security.RoleType; import com.plumtree.remote.prc.content.selectionlist.ISelectionList; import com.plumtree.remote.prc.content.selectionlist.ISelectionListManager; /** * This sample demonstrates all of the basic Content Server API * objects. It can be run from the command line, creates all of * its data, and cleans up after itself when it is done. *

* This is an example of a programatically creating content items * (records in the Content Server). The use case is a business * process where something triggers a customer support incident. * This creates a content item for the incident that can be viewed * from the portal in a support incident portlet. * * Before running this sample * 1) Verify the endpointURL and username and password are correct in establishSession() * 2) Set any break points to observe the sample as it runs * 3) Comment out the folderManager.removeFolder(folder); if you want to keep the created items after the sample has run */ public class ContentItemCommandLineExample { /** * Runs through the high-level logic of importing records * into Content Server. */ public static void main(String[] args) throws Exception { System.out.println("Started sample application"); // Step 1: Get an EDK session and Content Server factory. IRemoteSession session = establishSession(); IContentFactory contentFactory = session.getContentFactory(); System.out.println("Step 1 - Session Established and Content Factory Created"); // Step 2: Get a Content Server folder. // All Content Server objects are stored in folders. Since // they are necessary for creating or querying objects, the // first real step is to get your application's folder(s). IFolder folder = retrieveContentFolder(contentFactory); System.out.println("Step 2 - Folder retrieved with name: " + folder.getName()); // Step 3: Set security on the Content Server folder // All Content Server folders have access control lists // or ACLs associated with them. This step adds a user // and a group to this folder's ACL. folder = updateContentFolderSecurity(folder); System.out.println("Step 3 - Folder security updated with name: " + folder.getName()); // Step 4: Get the Data Entry Template (DET). // A DET is used when creating any collection of records. // It defines the fields within each record and logically // groups them together. A DET is analogous to creating // a new database table. In this example the DET represents // the fields in each customer support incident. IDataEntryTemplate det = retrieveDET(contentFactory, folder); System.out.println("Step 4 - Data Entry Template retrieved with name: " + det.getName()); // Step 5: Get the Presentation Template (PT). // The PT describes how each record within a collection is // displayed. For each collection of records, there is // exactly one DET and PT. Both are needed to publish // individual records (content items). IPresentationTemplate pt = retrievePT(contentFactory, det); System.out.println("Step 5 - Presentation Template retrieved with name: " + pt.getName()); // Step 6: Create content item. // Each support incident is a new content item. Content items // are records and analogous to rows in a database table. // // In a real application, we would actually want receive events // for when new support incidents are registered from some // other system such as Siebel. This would probably be done // as a loop, but for this example we will create a single // record. IContentItem ci = createSupportIncident(contentFactory, det, pt); System.out.println("Step 6 - Content Item created with name: " + ci.getName()); System.out.println("\nThe Content Item has been created. \nYou may go to the Content Server Manager to observe the objects that have been created"); System.out.println("When you are done, press any key to remove the created items and finish the sample"); System.in.read(); // Step 7: Cleanup. // Normally an application would not erase all of its data, // but since this is a sample it should clean up after itself. // Comment out these lines if you want to see all of the // content that is created without setting break points. IFolderManager folderManager = contentFactory.getFolderManager(); folderManager.removeFolder(folder); System.out.println("Step 7 - Folder deleted"); System.out.println("Finished sample application"); } /** * Creates an EDK session. Change this to reference your SOAP endpoint. */ private static IRemoteSession establishSession() throws Exception { // Change the values below to match your configuration. URL endpointURL = new URL("http://localhost/ptapi/services/QueryInterfaceAPI"); String username = "Administrator"; String password = ""; // Create a remote API session. IRemoteSession remoteSession = RemoteSessionFactory.getExplicitLoginContext(endpointURL, username, password); return remoteSession; } /** * Gets the Content Server ACL for the folder used to store the Content * Server objects for our application. *

* In this sample, we will display the current ACL on the folder and will add * a new user and group entry for this folder. */ private static IFolder updateContentFolderSecurity(IFolder folder) throws Exception { //get the existing ACL associated with this folder IFolderACL folderACL = folder.getFolderACL(); // get the entries off of this ACL IFolderACLEntry [] entries = folderACL.getEntries(); // loop through the entries and print out the values of each entry System.out.println("Printing ACL for folder " + folder.getName()); System.out.println(entries.length + " entries found in this ACL"); for (int i = 0; i < entries.length; i++) { // get the individual entry IFolderACLEntry aclEntry = entries[i]; // print out its details System.out.println("---------------------------------------------------------"); System.out.print("ObjectID for this FolderACLEntry " + aclEntry.getObjectID()); System.out.print("MemberType for this FolderACLEntry " + aclEntry.getMemberType()); System.out.println("RoleType for this FolderACLEntry " + aclEntry.getRoleType()); } // now add a new entry to this acl for the portal Guest user // the guest user's object id is 2. folderACL.addUserEntry(2, RoleType.EDITOR); // now add a new entry to this acl for the portal Administrator's group // the portal Administrator's group's object id is 1. folderACL.addGroupEntry(1, RoleType.ADMINISTRATOR); // store this acl to persist the changes back to the server folderACL.store(); // loop through the entries and print out the values of each entry System.out.println("Printing ACL for folder " + folder.getName()); System.out.println(entries.length + " entries found in this ACL"); for (int i = 0; i < entries.length; i++) { // get the individual entry IFolderACLEntry aclEntry = entries[i]; // print out its details System.out.println("---------------------------------------------------------"); System.out.print("ObjectID for this FolderACLEntry " + aclEntry.getObjectID()); System.out.print("MemberType for this FolderACLEntry " + aclEntry.getMemberType()); System.out.println("RoleType for this FolderACLEntry " + aclEntry.getRoleType()); } return folder; } /** * Gets the Content Server folder used to store the 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) throws Exception { // Get a folder manager for working with Content Server folders. IFolderManager folderManager = factory.getFolderManager(); //If we were looking for an existing folder by path we could //use the following method //IFolder subFolder = folderManager.getFolderByPath("/folder1/folder2"); //Instead, 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 IFolder subFolder = folderManager.createFolder(rootFolder, "Java Example - Support Incidents"); 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 an already * existing DET. */ private static IDataEntryTemplate retrieveDET(IContentFactory factory, IFolder folder) throws Exception { // // 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(); IPropertyManager propertyManager = factory.getPropertyManager(); ISelectionListManager slManager = factory.getSelectionListManager(); // Create a DET object. IDataEntryTemplate 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 float 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. String[] listValues = {"Portal", "Search Server", "Collaboration Server", "Content Server", "Analytics"}; ISelectionList 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; } /** * Gets the PT that defines how to display customer support * incident records. *

* In this sample, we will create a new PT. In your real * application, this method would probably query an already * existing PT. */ private static IPresentationTemplate retrievePT(IContentFactory factory, IDataEntryTemplate det) throws Exception { // // A Presentation Template object defines how content // items associated with a Data Entry Template should // be displayed. For content items to be displayed, // the must have a DET and PT associated with them // and be published. // // Get a PT manager object. IPresentationTemplateManager ptManager = factory.getPresentationTemplateManager(); // The template text determines how a content item is displayed. // In this sample we create a template that displays all the information in a table StringBuffer templateBuffer = new StringBuffer(""); templateBuffer.append("\n") .append("\n") .append("\n") .append("\n") .append("\n") .append("\n") .append("\n") .append("\n") .append("\n") .append("\n") .append("\n") .append("\n") .append("
Incident ID
Created By on
Resolved
Severity
Date Opened
Customer Name
Customer Information
Product
Incident Description
Log File
Screen Shot
\n"); // Create the presentation template with the template IPresentationTemplate pt = ptManager.createPresentationTemplate(det.getContainingFolder(), "Customer Support Incident Presentation Template", templateBuffer.toString()); // Store the PT. pt.store(); // Validate the template text before using it to publish items String[] errorsInText = ptManager.validateTemplateText(pt, pt.getTemplateText()); if(errorsInText.length != 0) { System.out.println("Validate Template Text returned the following errors"); for(int i = 0; i < errorsInText.length; i++) { System.out.println("error[" + i + "]: " + errorsInText[i]); } } // Associate the PT with a DET. // There is a one-to-one correspondance between Data Entry // Templates and Presentation Templates. A PT must be attached // to a DET in order for content items to be published (i.e. // viewable). det.attachPresentationTemplate(pt); det.store(); return pt; } /** * Creates a content item representing a single support * incident. */ private static IContentItem createSupportIncident(IContentFactory factory, IDataEntryTemplate det, IPresentationTemplate pt) throws Exception { // // Content items (CI) are associated with a single DET/PT // combination. There can be zero or more content // items associated with that pair. The DET defines // the fields in the content items while the PT // defines how to display them. // // Get a CI manager object. IContentItemManager ciManager = factory.getContentItemManager(); // Create a new CI. IContentItem incident = ciManager.createContentItem(det.getContainingFolder(), "Incident Name", det); // Assign the fields of the CI. // Each field is defined by the DET corresponding to the CI. IBaseProperty[] props = det.getAllProperties(); // Incident ID. incident.setIntegerPropertyValue(props[0], 123); // Resolved? incident.setBooleanPropertyValue(props[1], false); // Severity. incident.setDoublePropertyValue(props[2], 0.90 ); // Date incident opened. incident.setDatePropertyValue(props[3], new Date()); // Customer's name incident.setTextLinePropertyValue(props[4], "Customer X"); // Link to another content item (CI) representing the customer's data. // Assumes there was another content item in the same folder named // with the customer's name. In reality this will return null since // we never created it. //IContentItem customer = ciManager.getContentItem(det.getContainingFolder(), "Customer X"); //incident.setItemReferencePropertyValue(props[5], customer); // Product name containing problem. // When setting a selection list value, the passed in string should exactly // match one of the values in the selection list. incident.setSelectionListPropertyValue(props[6], "Portal"); // Incident description. incident.setTextBlockPropertyValue(props[7], "The widget is broken.\nThe widget is fixed in the latest version and the fix must be back ported."); // Log file. //Commented out because we don't automatically have a WidgetBroken.log to upload. //To test this property, change the file name to a valid file on your system and uncomment //FileInputStream log = new FileInputStream("C:\\WidgetBroken.log"); //incident.setFilePropertyValue(props[8], "WidgetBroken.log", log); // Screen shot. //Commented out because we don't automatically have a WidgetBroken.gif to upload. //To test this property, change the file name to a valid file on your system and uncomment //FileInputStream screenShot = new FileInputStream("C:\\WidgetBroken.gif"); //incident.setImagePropertyValue(props[9], "WidgetBroken.gif", screenShot); // Actually store the CI. ciManager.checkInItem(incident, "Automatically created support incident."); // Publish the CI. // This will make it visible to end users. Simply checking in a content // item is not enough to make it visible. ciManager.publishContentItem(incident); return incident; } }