Categories & Attributes (Java)
This tutorial walks you through an example of creating and using Categories and Attributes in Content Server using the CWS API with Java and Eclipse.
Outline
- Create a New Project
- Create CWS Client Proxies
- Write Your Code
- Run the Program
- Source Code
- References
- Notes
Create a New Project
The first thing we need is a new project in Eclipse to work with.
-
Open Eclipse.
-
Open the File menu and select New → Java Project.
-
Enter a name for the project and then select Finish.
Create CWS Client Proxies
Next, we need create the client proxies for each CWS service we want to use.
-
Open a new command prompt.
-
Use the wsimport command to generate the client proxies for each service.
NOTE: wsimport used to be bundled with the JDK in the \bin directory but it has been removed as of JDK 11. It can be found in the 'JAXWS-RI' package at https://javaee.github.io/metro-jax-ws/
NOTE: The old wsimport.exe file can be found at https://jdk.java.net/archive/ for JDK 10.0.2 (in the \bin directory)
Go to the \bin directory where wsimport is and enter the following commands:Tomcat
wsimport -keep http://localhost:8080/cws/services/Authentication?wsdl
wsimport -keep http://localhost:8080/cws/services/DocumentManagement?wsdl
IIS
wsimport -keep http://localhost/cws/Authentication.svc?wsdl
wsimport -keep http://localhost/cws/DocumentManagement.svc?wsdl
-
Use the jar command to bundle the generated class files into a .jar file. Enter the following command:
jar cvfM cws.jar com/opentext*
-
Copy the cws.jar file into your eclipse project and add it to your build path by right clicking the cws.jar file in the Package Explorer and select Build Path → Add to Build Path
These are the import statements used for the program:
// cws.jar import com.opentext.ecm.api.*; import com.opentext.livelink.service.core.*; import com.opentext.livelink.service.core.Attachment; import com.opentext.livelink.service.docman.*; import com.opentext.livelink.service.docman.Node; // JRE System Library[jdk-15.0.1] import java.util.*; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.attribute.BasicFileAttributes; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.namespace.*; // cws.war > WEB-INF\lib import javax.xml.soap.*; // javax.xml.soap-api.jar import javax.xml.ws.soap.*; // jaxws-api.jar import com.sun.xml.ws.developer.*; // jaxws-rt.jar import com.sun.xml.ws.api.message.*; // jaxws-rt.jar
Write Your Code
Now that the CWS services are ready to use we can go ahead and start writing some code. The first thing to do is to authenticate a user. We will use basic Content Server authentication using the CWS Authentication service. You will need to change the USERNAME
and PASSWORD
to use valid credentials of a user on your system.
// The user's credentials final String USERNAME = "username"; final String PASSWORD = "password"; // Create the Authentication service client Authentication_Service authService = new Authentication_Service(); Authentication authClient = authService.getBasicHttpBindingAuthentication(); // Store the authentication token String authToken = null; // Call the AuthenticateUser() method to get an authentication token try { System.out.print("Authenticating User..."); authToken = authClient.authenticateUser(USERNAME, PASSWORD); System.out.println("SUCCESS!\n"); } catch (SOAPFaultException e) { System.out.println("FAILED!\n"); System.out.println(e.getFault().getFaultCode() + " : " + e.getMessage()); return; }
Next, we will create a category to store information about a movie. The category will contain the following attributes:
- Directed By (Text Field)
- Starring (Text Field)
- Release Date (Date Field)
- Running Time (Integer Field)
- Miscellaneous Info (Set)
- Genre (Set Text Field)
You can change the PARENT_ID
to create the category in a different location, if needed.
// The ID of the parent container to create the category in int PARENT_ID = 2000; // Create the DocumentManagement service client DocumentManagement_Service docManService = new DocumentManagement_Service(); DocumentManagement docManClient = docManService.getBasicHttpBindingDocumentManagement(); // Create the OTAuthentication object and set the authentication token OTAuthentication otAuth = new OTAuthentication(); otAuth.setAuthenticationToken(authToken); // We need to manually set the SOAP header to include the authentication token try { // The namespace of the OTAuthentication object final String ECM_API_NAMESPACE = "urn:api.ecm.opentext.com"; // Create a SOAP header SOAPHeader header = MessageFactory.newInstance().createMessage().getSOAPPart().getEnvelope().getHeader(); // Add the OTAuthentication SOAP header element SOAPHeaderElement otAuthElement = header.addHeaderElement(new QName(ECM_API_NAMESPACE, "OTAuthentication")); // Add the AuthenticationToken SOAP element SOAPElement authTokenElement = otAuthElement.addChildElement(new QName(ECM_API_NAMESPACE, "AuthenticationToken")); authTokenElement.addTextNode(otAuth.getAuthenticationToken()); // Set the SOAP header on the docManClient ((WSBindingProvider) docManClient).setOutboundHeaders(Headers.create(otAuthElement)); } catch (SOAPException e) { System.out.println("Failed to set authentication SOAP header!\n"); System.out.println(e.getMessage()); return; } // Directed By StringAttribute directedBy = new StringAttribute(); directedBy.setDisplayLength(64); directedBy.setDisplayName("Directed By"); directedBy.setMaxLength(64); directedBy.setMaxValues(5); directedBy.setMinValues(1); directedBy.setReadOnly(new BooleanObject()); directedBy.getReadOnly().setValue(false); directedBy.setRequired(false); directedBy.setSearchable(true); // Starring StringAttribute starring = new StringAttribute(); starring.setDisplayLength(64); starring.setDisplayName("Starring"); starring.setMaxLength(64); starring.setMaxValues(20); starring.setMinValues(1); starring.setReadOnly(new BooleanObject()); starring.getReadOnly().setValue(false); starring.setRequired(false); starring.setSearchable(true); // Release Date DateAttribute releaseDate = new DateAttribute(); releaseDate.setDisplayName("Release Date"); releaseDate.setMaxValues(1); releaseDate.setMinValues(1); releaseDate.setReadOnly(new BooleanObject()); releaseDate.getReadOnly().setValue(false); releaseDate.setRequired(false); releaseDate.setSearchable(true); releaseDate.setShowTime(false); // Running Time IntegerAttribute runningTime = new IntegerAttribute(); runningTime.setDisplayName("Running Time (minutes)"); runningTime.setMaxValues(1); runningTime.setMinValues(1); runningTime.setReadOnly(new BooleanObject()); runningTime.getReadOnly().setValue(false); runningTime.setRequired(false); runningTime.setSearchable(true); // Miscellaneous Info SetAttribute miscellaneousInfo = new SetAttribute(); miscellaneousInfo.setDisplayName("Miscellaneous Info"); miscellaneousInfo.setMaxValues(1); miscellaneousInfo.setMinValues(1); miscellaneousInfo.setReadOnly(new BooleanObject()); miscellaneousInfo.getReadOnly().setValue(false); miscellaneousInfo.setRequired(false); miscellaneousInfo.setSearchable(true); // Genre StringAttribute genre = new StringAttribute(); genre.setDisplayLength(64); genre.setDisplayName("Genre"); genre.setMaxLength(64); genre.setMaxValues(1); genre.setMinValues(1); genre.setReadOnly(new BooleanObject()); genre.getReadOnly().setValue(false); genre.setRequired(false); genre.setSearchable(true); // Add the Genre into the Miscellaneous Info set as the first set attribute miscellaneousInfo.getAttributes().add(genre); List<Attribute> attributes = new ArrayList<Attribute>(); attributes.add(directedBy); attributes.add(starring); attributes.add(releaseDate); attributes.add(runningTime); attributes.add(miscellaneousInfo); Node movieInfo = null; // Call the createCategory() method to create the category try { System.out.print("Creating Category..."); movieInfo = docManClient.createCategory(PARENT_ID, "MovieInfo", null, attributes, null); System.out.println("SUCCESS!\n"); } catch (SOAPFaultException e) { System.out.println("FAILED!\n"); System.out.println(e.getFault().getFaultCode() + " : " + e.getMessage()); return; }
Next, we will get the category template to make it easier to create objects using the category. This will save us having to create the object structure and allow us to just fill in the values for each attribute from the template.
AttributeGroup categoryTemplate = null; // Call the getCategoryTemplate() method to get the category template try { System.out.print("Getting Movie Info Category Template..."); categoryTemplate = docManClient.getCategoryTemplate(movieInfo.getID()); System.out.println("SUCCESS!\n"); } catch (SOAPFaultException e) { System.out.println("FAILED!"); System.out.println(e.getFault().getFaultCode() + " : " + e.getMessage()); return; }
Finally, we will create a document using the category we created. You will need to change the FILE_PATH
to point to a file on your local system.
File file = new File(FILE_PATH); // Get the file attributes byte[] contents = null; BasicFileAttributes fileAttributes = null; try { contents = Files.readAllBytes(file.toPath()); fileAttributes = Files.readAttributes(file.toPath(), BasicFileAttributes.class); } catch (IOException e) { System.out.println("Failed to read file attributes!\n"); System.out.println(e.getMessage()); return; } // Create the attachment Attachment attachment = new Attachment(); try { attachment.setContents(contents); attachment.setCreatedDate(DatatypeFactory.newInstance().newXMLGregorianCalendar(fileAttributes.creationTime().toString())); attachment.setFileName(file.getName()); attachment.setFileSize(file.length()); attachment.setModifiedDate(DatatypeFactory.newInstance().newXMLGregorianCalendar(fileAttributes.lastModifiedTime().toString())); } catch (DatatypeConfigurationException e) { System.out.println("Failed to set file attributes!\n"); System.out.println(e.getMessage()); return; } // Set the category values // Directed By StringValue directedByValue = (StringValue) categoryTemplate.getValues().get(0); directedByValue.getValues().clear(); directedByValue.getValues().add("Andy Wachowski"); directedByValue.getValues().add("Larry Wachowski"); // Starring StringValue starringValue = (StringValue) categoryTemplate.getValues().get(1); starringValue.getValues().clear(); starringValue.getValues().add("Keanu Reeves"); starringValue.getValues().add("Laurence Fishburne"); starringValue.getValues().add("Carrie-Anne Moss"); starringValue.getValues().add("Hugo Weaving"); starringValue.getValues().add("Joe Pantoliano"); // Release Date DateValue releaseDateValue = (DateValue) categoryTemplate.getValues().get(2); releaseDateValue.getValues().clear(); GregorianCalendar date = new GregorianCalendar(1999, 3, 31); try { releaseDateValue.getValues().add(DatatypeFactory.newInstance().newXMLGregorianCalendar(date)); } catch (DatatypeConfigurationException e) { System.out.println("Error creating new XMLGregorianCalendar!"); System.out.println(e.getMessage()); return; } // Running Time IntegerValue runningTimeValue = (IntegerValue) categoryTemplate.getValues().get(3); runningTimeValue.getValues().clear(); runningTimeValue.getValues().add((long) 136); // Miscellaneous Info : Genre List<RowValue> miscellaneousInfoSetRows = ((TableValue) categoryTemplate.getValues().get(4)).getValues(); List<?> MiscellaneousInfoSetAttributes = ((RowValue) miscellaneousInfoSetRows.get(0)).getValues(); List<String> genreValue = ((StringValue) MiscellaneousInfoSetAttributes.get(0)).getValues(); genreValue.add("Sci-Fi"); Metadata metadata = new Metadata(); metadata.getAttributeGroups().add(categoryTemplate); Node theMatrix = null; // Call the createDocument() method to create the document try { System.out.print("Creating Document With Category..."); theMatrix = docManClient.createDocument(PARENT_ID, "The Matrix", null, false, metadata, attachment); System.out.println("SUCCESS!\n"); System.out.println("Document ID = " + theMatrix.getID()); } catch (SOAPFaultException e) { System.out.println("FAILED!"); System.out.println(e.getFault().getFaultCode() + " : " + e.getMessage()); }
Run the Program
If everything is setup correctly you should be able to successfully run the program.
Source Code
References
- Eclipse - The Eclipse Foundation Open Source Community Website
- Oracle Java SE Documentation - wsimport
- Oracle Java SE Documentation - jar
- Oracle Java Tutorials - Creating a JAR File
Notes
-
How do I get Category inheritance or set no Categories when creating a node?
Category inheritance
Method 1: pass in a null for the Metadata parametertheMatrix = docManClient.createDocument(PARENT_ID, "The Matrix", null, false, null, attachment);
Method 2: create a new AttributeGroup, set the 'Type' to 'Category' and pass it in when setting Metadata's AttributeGroups list (this 'empty' Category AttributeGroup must occur only once in the list, but it doesn't have to be the only thing in there). This is useful when Metadata contains AttributeGroups that are not Categories.AttributeGroup catAttrGroup = new AttributeGroup(); catAttrGroup.setType("Category"); Metadata metadata = new Metadata(); metadata.getAttributeGroups().add(catAttrGroup); theMatrix = docManClient.createDocument(PARENT_ID, "The Matrix", null, false, metadata, attachment);
Set no Categories
Method 1: pass in an empty Metadata object for the Metadata parameterMetadata metadata = new Metadata(); theMatrix = docManClient.createDocument(PARENT_ID, "The Matrix", null, false, metadata, attachment);
Method 2: do not pass in any Category AttributeGroups. This is useful when Metadata contains AttributeGroups that are not Categories.Metadata metadata = new Metadata(); // myCustomAttributeGroup is an AttributeGroup that is not a Category AttributeGroup metadata.getAttributeGroups().add(myCustomAttributeGroup); theMatrix = docManClient.createDocument(PARENT_ID, "The Matrix", null, false, metadata, attachment);