Creating an IBM Lotus Web Content Management site structure with one click

Read about a simple solution that enables you to define site structures in IBM® Lotus® Web Content Management in an automated fashion. This solution allows you to save time on an otherwise time-consuming and monotonous task.

Share:

Hebba Soliman (hsoliman@eg.ibm.com), Senior Software Engineer, IBM

Hebba Soliman is a senior software engineer at IBM Cairo Global Delivery Center (C-GDC). She has extensive experience in developing and designing Web applications using IBM Workplace Web Content Management and personalization.



Ahmed Khairy (KHAIRY@eg.ibm.com), IT Specialist, IBM

Ahmed Khairy is an IT specialist at IBM Cairo Technology Development Center, Egypt. He has worked with various IBM software products across IBM's different software brands. He is currently pursuing a Master's degree in Computer Science from the American University in Cairo.



08 December 2009 (First published 24 November 2009)

Also available in Chinese Russian Portuguese Spanish

Editor's note: Know a lot about this topic? Want to share your expertise? Participate in the IBM Lotus software wiki program today.

Introduction

If you work with IBM Lotus Web Content Management, one of your recurring tasks is defining site structure. This task by its nature is time-consuming and repetitive; you are required to take more than 10 distinct steps to create a single site or site area. Moreover, site structures are not portable by design; you cannot export your site structure from one library on one server to a different library on a different server. Instead, you need to recreate the entire site structure manually.

Because the number of sites and site areas that make up a single site structure can reach the thousands, you need a method to automate the process of defining the site structure and to make it easier to move, export, and import. In this article, you can learn a simple way to define your site structure as an XML file and deploy it accordingly.


Prerequisites

You should be familiar with these technologies:

  • IBM WebSphere® Portal V6.0 and later, its administration, and its components
  • IBM Lotus Web Content Management
  • XML

To demonstrate how you can create a site structure in Lotus Web Content Management without manually creating all the sites and site areas, this article uses Lotus Web Content Management APIs and an XML file that contains the site structure. You can create the XML file containing the structure by validating it against the XML schema provided in the Downloads section of this article. The XML schema validates the structure and mandatory fields to prevent runtime errors.

You can define many sites, site areas, and default contents to create the site structure in the XML document that contains the complete site structure. First, create these prerequisites:

  • Lotus Web Content Management library
  • Authoring templates to be used in the site structure
  • Presentation templates to be used in the site structure
  • Users to be used in the security settings section
  • Workflows, workflow actions, and workflow stages to be used in the authoring templates

You then define the site structure in the form of an XML file, specifying the library, sites, site areas, and so on. To ensure that the provided information is sufficient to create a site in Lotus Web Content Management , the XML file is based on the schema defined in the XSD file provided in the Downloads section of this article. The XSD file contains all the validations required to create a complete site structure, with default contents containing some fields.

You then create a JSP component to parse the XML file and create the site areas defined in it.


Implementation

In this section, we describe the steps that you take to implement the solution. We start by discussing the creation of the XML file and the XSD file, and then we move on to the JSP component that parses this file.

XML creation

The XML file contains all the information needed to create the site structure. It contains the library name, the site structure, the site area structure, and the default contents. An XML file needs to be defined in a structure that corresponds to your requirements. See the XML example in listing 1, which corresponds to the site structure shown in figure 1.

Figure 1. Site structure
Site structure

The site is made up of a single site area; that single site area, in turn, is made up of another site area.

Listing 1. XML example used in the creation of the site structure
<Library Name="Library" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:noNamespaceSchemaLocation="SiteCreation.xsd">
  <Site Name="SITE" DisplayName="SITE">
  <SiteArea Name="News" DisplayName="News">
      <Settings>
        <TemplateMapping>
          <AuthoringTemp>auth_news</AuthoringTemp>
          <PresentationTemp>pt_newsDetail</PresentationTemp>
		</TemplateMapping>
		<SecuritySettings>
		  <AccessRight Type="addReadAccessMembers">
		    <Access>[all authenticated portal users]</Access>
		    <Access>anonymous portal user</Access>
		  </AccessRight>
		</SecuritySettings>
	  </Settings>
	  <DefaultContent>
		<Name>Default_News</Name>
		<DisplayName>Default_News</DisplayName>
		<AuthoringTemp>auth_news</AuthoringTemp>
		<TextComponent>	
		  <FieldName>txt_headline</FieldName>
		  <Value>Headline for default Content</Value>
		</TextComponent>
		<RichTextComponent>	
		  <FieldName>rtf_body</FieldName>
		  <Value>Body for the default Content</Value>
		</RichTextComponent>
	  </DefaultContent>	
	  <SiteArea Name="2009News" DisplayName="2009 News">
		<DefaultContent>
		  <Name>Default_News</Name>
		  <DisplayName>Default_News</DisplayName>
		  <AuthoringTemp>auth_news</AuthoringTemp>
		  <TextComponent>	
		    <FieldName>txt_headline</FieldName>
		    <Value>Headline for default Content</Value>
		  </TextComponent>
		  <RichTextComponent>	
		    <FieldName>rtf_body</FieldName>
		    <Value>Body for the default Content</Value>
		  </RichTextComponent>
	  </DefaultContent>			
	</SiteArea>		
	<SiteArea Name="2008News" DisplayName="2008 News">
	  <DefaultContent>
	    <Name>Default_News</Name>
	  </DefaultContent>			
	</SiteArea>		
  </SiteArea>
  <Settings><!—Site Settings -
      <TemplateMapping>
	    <AuthoringTemp>auth_news</AuthoringTemp>
	    <PresentationTemp>pt_newsDetail</PresentationTemp>
	  </TemplateMapping>
	  <SecuritySettings>
	    <AccessRight Type="addReadAccessMembers">
	      <Access>[all authenticated portal users]</Access>
	      <Access>anonymous portal user</Access>
		</AccessRight>
	  </SecuritySettings>
	</Settings>
  </Site>
</Library>

Figure 2 shows a sample mapping between the XML elements and the output created after you implement the solution.

Figure 2. Mapping between the XML and Lotus Web Content Management objects and sections
Mapping between the XML and Lotus Web Content Management objects and sections

As you can see, the mapping from the actual site structure to the XML file is straightforward with a root element representing the library. This root element then contains another element that corresponds to the site, defining its name and display name. Site areas are defined in a nesting fashion in the XML file to obtain the required site structure.

Every site and site area contains a settings section that holds the security settings and template mapping sections. The following are restrictions that need to considered: Security settings and template mapping can be created for each site or site area in its respective element or in the highest site or site area in the tree, with its child elements inheriting them.

Content security settings and workflows are added in the authoring template component, not in the default content section in the XML file.

Authoring templates and presentation templates used in the template mapping and in the creation of the default content have to be created previously.

Default content can be reused in multiple site areas by defining its name. After you define a complete default content element in the XML file, you can then use it by defining a default content tag with only the name element. This feature of reusing the default content in different and multiple places can also be used if the default content already exists for that library.


XML schema validations

As previously stated, to avoid missing data that Lotus Web Content Management requires for site creation, you need to have the XML file conform to an XSD. This conformance guarantees that the validations listed in table 1 hold true.

Table 1. XML schema element/ attributes validations
ElementElement/attributeTypeValid rangeValue
LibrarySites Element0..nNA
LibraryNameAttributeMandatorystring
SiteSiteAreaElement0..nNA
SiteNameAttributeMandatorystring
SiteDisplayNameAttributeOptionalstring
SiteSettingsElementOptionalNA
SiteAreaSiteAreaElement0..nNA
SiteAreaNameAttributeMandatorystring
SiteAreaDisplayNameAttributeOptionalstring
SiteAreaSettingsElementOptionalNA
SiteAreaDefaultContentElementOptionalNA
DefaultContentNameElementMandatoryNA
DefaultContentDisplayNameElementOptionalNA
DefaultContentAuthoringTempElementOptional (if item already created before)NA
DefaultContentTextComponentElement0..nNA
DefaultContentRichTextComponentElementOptionalNA
TextComponentFieldNameElementMandatory (referencing the Lotus Web Content Management TextComponent field name as in the authoring template)NA
TextComponentTextComponentElementMandatoryNA
TextComponentFieldNameElementMandatory (referencing the Lotus Web Content Management RichTextComponent field name as in the authoring template)NA
TextComponentTextComponentElementMandatoryNA
SettingsTemplateMappingElement0..nNA
SettingsSecuritySettingsElementOptionalNA
TemplateMappingAuthoringTempElementMandatory (references the Lotus Web Content Management authoring template name)NA
TemplateMappingPresentationTempElementMandatory (references the Lotus Web Content Management presentation template)NA
SecuritySettingsAccessRightElement0..nNA
AccessRightTypeAttributeMandatoryaddReadAccessMembers/
addEditAccessMembers
or
addDeleteAccessMembers
AccessRightAccessElement1..nNA

JSP component

Now that you have defined your site structure in an XML file that conforms to the XSD, you need to create a JSP component to handle the parsing of the XML file and do the actual Lotus Web Content Management site creation using the Lotus Web Content Management APIs to import your site structure into the Lotus Web Content Management library.

Select New - JSP component. Create the JSP component with the name jsp_createSiteStructure, and let it point to a JSP file whose path is /jsp/html/createSiteStructure.jsp. Store your JSP components in the local Rendering portlet. The physical path of the JSP file is in a directory similar to the code shown in listing 2.

Listing 2. Physical path directory
<websphere portal installation path>\installedApps\
WCM_Local_ng_Portlet_PA_dvme0nk.ear\PA_dvme0nk.war\jsp\html\
createSiteStructure.jsp

The JSP file creates a button called Create Site Structure that, when clicked, starts parsing the XML file by first parsing every site. The path to the XML file can be edited. The file used in listing 3 is assumed to be at the same location as the JSP file. The code gets the workspace and connects to the library defined in the file. See the code in listing 3.

Listing 3. The JSP file that creates the new comment content
<%@page language="java" contentType="text/html; 
charset=UTF-8" pageEncoding="UTF-8"%>
.
.
.
<%@ include file="wcmUtil.jsp"%>
<FORM name="form1" method="post" action="#">
		
    <INPUT TYPE="HIDDEN" NAME="buttonName" VALUE="CreateSiteStructure">
           
    <INPUT TYPE="SUBMIT" value="Create Site Structure">
</FORM>
<%

try {	 	  
	  	
//if button clicked
if( request.getParameter("buttonName") != 
null && request.getParameter("buttonName").equals("CreateSiteStructure")) {

  //path to the XML file containing the site structure
  File file = newFile("/opt/app/WebSphere/PortalServer/installedApps/WCM_Local_ng_
  Portlet_PA_dm010y1.ear/dm010y1.war/jsp/html/NewsSiteStructure.xml");
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      DocumentBuilder db = dbf.newDocumentBuilder();
      Document doc = db.parse(file);
			
      doc.getDocumentElement().normalize();

      Element docEle = doc.getDocumentElement();			
      String libraryName = docEle.getAttribute("Name");
				
      System.out.println("libraryName = " +libraryName);
      workspace = openWorkspaceLibrary(request, libraryName);
		 
      //retrieve all site elements
      NodeList nl = docEle.getElementsByTagName("Site");		
		 
      //loop over site elements
      if(nl != null) {
        for(int i = 0 ; i < nl.getLength();i++) {
	
          Element el = (Element)nl.item(i);
          Site site = createSite(el);
					
          DocumentId siteId =  site.getId();
          System.out.println("site = "+ site.getName());
					
          //for every site element, retrieve site area child elements
          NodeList SiteAreaNodeList = el.getChildNodes();	
          for (Node node = el.getFirstChild(); node != null; 
          node = node.getNextSibling()) {
		  if (node.getNodeType() == Node.ELEMENT_NODE && 
		  node.getNodeName().equals("SiteArea")) {
		  Element siteAreaEL = (Element)node;
			    			
		    SiteArea sa = createSiteArea(siteAreaEL, siteId);
			if (sa != null){
			System.out.println("site area = " + sa.getName());
			}
			else{
			out.println("Error in creation of site area tree, 
			check logs for more information about the error");
			}
		  }
		}
	  }
    }		
	closeWorkspace();	
	out.println("Cretion Completed");				
  }
	}catch(FileNotFoundException e){
	  out.println("XML File not found!");
	}catch (org.xml.sax.SAXParseException saxEx){
	  out.println("Exception In parsing document: "+ saxEx.getMessage());
	} 
	catch (Exception e) {
	  System.out.println("Exception: "+ e.getClass());
	  e.printStackTrace();
	}	 
%>

A utility class is used that contains all helper methods used from the JSP code to create the site structure. For this article's purpose, a JSP component can be created called wcmUtil.jsp that contains all those methods. The JSP component is included in createSiteStructure.jsp, as it is shown in listing 3, using the following listing <%@ include file="wcmUtil.jsp"%>.

Listings 4 - 20 show the methods used in a helper class to create the site structure.

Listing 4. Connect to workspace and library
private Workspace workspace;
/*
	*Connect to Lotus Web Content Management workspace with current user if 
	*logged in or anonymous if user is not logged in
	*
	*Set the Lotus Web Content Management document library to aLibraryName
*/
public Workspace openWorkspaceLibrary(HttpServletRequest request, String aLibraryName) 
throws ServiceNotAvailableException, OperationFailedException {
	// Connect to WCM Workspace
	if (request.getUserPrincipal() != null)
	{
		workspace = WCM_API.getRepository().getWorkspace
		(request.getUserPrincipal());
	} else
	{
		workspace = WCM_API.getRepository().getAnonymousWorkspace();
	}
	
	//set library to the passed library name
	if (workspace != null) {
		DocumentLibrary docLib = workspace.getDocumentLibrary
		(aLibraryName);
		if(docLib != null){
			workspace.setCurrentDocumentLibrary(docLib);
		}
	}
	
	return workspace;
}
Listing 5. Parse and create site
/*
	*Parse site element 
	*If site already available, retrieve the site object, edit the site
	*If site not already created, create a new site and set the name and 
	*display name and its settings
	*Save the site to the workspace
*/
public Site createSite(Element aSiteElement){
	
	String siteName = aSiteElement.getAttribute("Name");
	String siteDisplayName = aSiteElement.getAttribute("DisplayName");
	Site site = null;	
	try{
	
		DocumentId siteId = getWCMDocumentByName(siteName, DocumentTypes.Site);
		if (siteId != null){
			site = (Site)workspace.getById(siteId);
		}
		else{
			site = workspace.createSite();		
			site.setName(siteName);
		}
		site.setTitle(siteDisplayName);			
		site = (Site)retrieveAddSettings(site, aSiteElement, false);	
		
		workspace.save(site);
	
	}catch(Exception e){
		System.out.println("Exception = "+e);
		e.printStackTrace();
		
	}	
	return site;
}
Listing 6. Parse and create site area
/*
*Parse site area element 
*If site area already available, retrieve the site area object, edit the site area
*If site area not already created, create a new site area and set the name 
*and display name and its settings
*Add a default content to the site area if available
*Save the site area to the workspace
*/
public SiteArea createSiteArea(Element aSiteAreaElement, DocumentId parentId){
  String siteAreaName = aSiteAreaElement.getAttribute("Name");
  String siteAreaDisplayName = aSiteAreaElement.getAttribute("DisplayName");
		
  SiteArea sa = null;
  try{
    String parentPath = workspace.getPathById(parentId,  true, true);
    String siteAreaPath = parentPath+ "/"+ siteAreaName;
    DocumentId siteAreaId = getWCMDocumentByPath(siteAreaPath,  
    Workspace.WORKFLOWSTATUS_ALL);
				
    if (siteAreaId != null){
      sa = (SiteArea)workspace.getById(siteAreaId);
    }else{
      sa = workspace.createSiteArea(parentId, null, 1);
    }
		
    sa = (SiteArea)retrieveAddSettings(sa, aSiteAreaElement, true);			
    if (sa != null){
      sa.setTitle(siteAreaDisplayName);
			
      sa.setName(siteAreaName);	
      workspace.save(sa);
      sa = addDefaultContentToSiteArea(sa, aSiteAreaElement);			
			
      if (sa != null){
			
        boolean saved = saveToWorkspace(sa);
        System.out.println("site area = " + sa.getName());
				
        if (!saved){
          return null;
        }					
				
        //checking if site area contains any other site area children
        NodeList SiteAreaNodeList = aSiteAreaElement.getChildNodes();
				
        for (Node node = aSiteAreaElement.getFirstChild(); node != null; 
        node = node.getNextSibling()) {
          if (node.getNodeType() == Node.ELEMENT_NODE && 
	      node.getNodeName().equals("SiteArea")) {
		  Element siteAreaEL = (Element)node;
		    			
		    SiteArea childSA = createSiteArea(siteAreaEL, sa.getId());
		    if (childSA != null){
			System.out.println("childSA  for = " +sa.getName()+ " = 
			" + childSA.getName());
		  }
		  else{
		  return null;
		  }
		}
	  }				
	}
      else{
        return null;
      }
    }			
    return sa;
  }catch(Exception e){
    System.out.println("Exception = "+e);
    e.printStackTrace();
		
  }		
  return null;
}
Listing 7. Parse and create default content
/*
*Parse the default content element 
*If content already available, retrieve the content object, and edit it
*If content not already created, create a new content object and set the 
*name and display name and its settings
*If authoring template provided, overwrite if already set
*Add text components and rich text components to the content
*Save the default content to the site area
*/
public SiteArea addDefaultContentToSiteArea(SiteArea aSiteArea, 
Element aSiteAreaElement){
	
	DocumentId defaultContentId = null;				
	
	Element defaultel = getChildByName(aSiteAreaElement, "DefaultContent");
	String contentName = getElementValueByTagName("Name", defaultel);
	
	defaultContentId = getWCMDocumentByName(contentName, DocumentTypes.Content);
	
	Content content = null;		
	
	String contentDisplayName = getElementValueByTagName("DisplayName", defaultel);
	
	String authoringTempName = getElementValueByTagName("AuthoringTemp", defaultel);
	
	DocumentId defaultAuthId = null;
	
	if (! authoringTempName.equals("")){
	  defaultAuthId = getWCMDocumentByName(authoringTempName, 
	  DocumentTypes.AuthoringTemplate);
		
	}
	System.out.println("defaultAuthId = "+ defaultAuthId);
	try{
	    
	  //if content already existing in the library, re-use it
      if (defaultContentId != null){
	    content = (Content)workspace.getById(defaultContentId);
			 
	    //if authoring template provided in the file, overwrite the existing one
	    if (defaultAuthId != null){
	      content.setAuthoringTemplateID(defaultAuthId);
	    }
	  }
	  else if (defaultAuthId != null){
	    //if content not available, create a new one
	    content = workspace.createContent(defaultAuthId, aSiteArea.getId(),null, 
	    ChildPosition.START);
	   	defaultContentId = content.getId();
	   	content.setName(contentName);
	  }
	  else{
		System.out.println("Exception = Authoring Template for default content "+ 
		contentName + " is missing");
		return null;
	  }
		
	  if (! contentDisplayName.equals("")){
		content.setTitle(contentDisplayName);
	  }
		
	  content = retrieveAddTextComponentToContent(content, defaultel);
		
	  if (content == null){
		return null;
	  }
	  content = retrieveAddRichTextComponentToContent(content, defaultel);
		
	  if (content == null){
		return null;
	  }
		
while(!content.isPublished()){
content.nextWorkflowStage();
}
workspace.save(content);
		
  }catch(Exception e){
	System.out.println("Exception = "+e);
	e.printStackTrace();							
  }
	
  System.out.println("defaultContent  for = " +aSiteArea.getName()+ " = " + 
  defaultContentId.getName());
  aSiteArea.setDefaultContent(defaultContentId);			
  return aSiteArea;
}
Listing 8. Parse text component
/*
*Parse DefaultContent element 
*Search for text component elements
*Looping over all text component child elements
*Calling method addTextComponent to add the 
*text component to the content
*/
public Content retriveAddTextComponentToContent(Content aContent, 
Element aContentElement){
	
  NodeList texttnl = aContentElement.getChildNodes();
	
  for (Node node = aContentElement.getFirstChild(); 
  node != null; 
  node = node.getNextSibling()) {
	if (node.getNodeType() == 
	Node.ELEMENT_NODE && 
	node.getNodeName().equals("TextComponent")) {
	  Element textCompel = (Element)node;
		
	  String textField = 
	  getElementValueByTagName("FieldName", textCompel);				
	  String text = 
	  getElementValueByTagName("Value", textCompel);
	  aContent = 
	  addTextComponent(aContent, textField, text);
								
	  if (aContent != null){
	    System.out.println("adding textField = 
	    "+ textField+" to content "
	    +aContent.getName());						
	  }
	}
  }	
  if (aContent == null){
	return null;
  }
  else{
		
	return aContent;
  }
	
}
Listing 9. Parse rich text component
/*
*Parse DefaultContent element 
*Search for rich text component elements
*Looping over all rich text component child elements
*Calling method addRichTextComponent to add the rich text 
*component to the content
*/
public Content retrieveAddRichTextComponentToContent
(Content aContent, Element aContentElement){
  NodeList richTexttnl = aContentElement.getChildNodes();
  for (Node node = aContentElement.getFirstChild(); node != null; 
  node = node.getNextSibling()) {
	if (node.getNodeType() == Node.ELEMENT_NODE && 
	node.getNodeName().equals("RichTextComponent")) {
	  Element richtextCompel = (Element)node;
			
	  String textField = 
	  getElementValueByTagName("FieldName", 
	  richtextCompel);					
	  String text = 
	  getElementValueByTagName("Value", 
	  richtextCompel);				
			
	  aContent = 
	  addRichTextComponent(aContent, textField, text);
			
	  if (aContent != null){
	    System.out.println("adding richtextField = 
	    "+ textField+" to content "+
	    aContent.getName());						
	  }
	}
  }
  if (aContent == null){
	return null;
  }
  else{
    return aContent;
  }
}
Listing 10. Create and add text component
/*
* Get text component from the content according to 
*the text component name
* Set the text component with the value sent
* Add the text component to the content
*/
public Content addTextComponent
(Content aContent, String aTextField, String aValue){
	
	try{			
		TextComponent txtComp = 
		(TextComponent) aContent.getComponent(aTextField);
		txtComp.setText(aValue);		
		aContent.setComponent(aTextField,  txtComp);
	}catch(ComponentNotFoundException ex){
		System.out.println
		("Exception: "+aTextField+" is not a valid TextComponent");
		return null;
	}catch(Exception e){
		System.out.println("Exception = "+e);
		return null;
	}
	
	return aContent;
}
Listing 11. Create and add rich text component
/*
* Get rich text component from the content according to the RTF name
* Set the rich text component with the value sent
* Add the rich text component to the content
*/
public Content addRichTextComponent(Content aContent, 
String aTextField, String aValue){
	try{
		RichTextComponent richTxtComp = 
		(RichTextComponent) aContent.getComponent(aTextField);
		richTxtComp.setRichText(aValue);		
		aContent.setComponent(aTextField,  richTxtComp);
		RichTextComponent rtf = 
		(RichTextComponent)aContent.getComponent(aTextField);
	}catch(ComponentNotFoundException ex){
		System.out.println("Exception: 
		"+aTextField+" is not a valid RichTextComponent");
		return null;
	}catch(Exception e){
		System.out.println("Exception = "+e);
		return null;
	}
	
	return aContent;
}
Listing 12. Parse settings element
/*
*Parse site area or site element 
*Search for settings element
*call method retrieveAddTemplateMapping to add template mapping to site or site area
*call method addSecuritySettings to add security settings to site or site area
*/
public Object retrieveAddSettings(SiteFrameworkContainer aWCMObject, 
Element aObjectElement, boolean isSiteArea){

	Element settingsel = getChildByName(aObjectElement, "Settings");
	if ( settingsel!= null){
		if(isSiteArea )
		{
			aWCMObject = (SiteArea)retrieveAddTemplateMapping
			(aWCMObject, settingsel);
			aWCMObject = (SiteArea)addSecuritySettings
			(aWCMObject, settingsel);
		}
		else
		{
			aWCMObject = (Site)retrieveAddTemplateMapping
			(aWCMObject, settingsel);
			aWCMObject = (Site)addSecuritySettings
			(aWCMObject, settingsel);
		}
	}
	return aWCMObject;
}
Listing 13. Add SecuritySettings to Lotus Web Content Management objects
/*
*Parse settings element 
*Search for SecuritySettings element
*For every SecuritySettings element, find the AccessRight element
*loop over the AccessRight elements and get the type of the access
*According to the access type, a specific method in Lotus 
*Web Content Management 
*will be called to add the access rights
*/
public Object addSecuritySettings
(SiteFrameworkContainer aWCMObject, Element settingsel){
	
  for (Node node = settingsel.getFirstChild(); node != null; 
  node = node.getNextSibling()) {
    if (node.getNodeType() == Node.ELEMENT_NODE && 
    node.getNodeName().equals("SecuritySettings")) {
      Element secel = (Element)node;	
      NodeList accessRightsnl = secel.getChildNodes();
			
      for (Node accessRightNode = secel.getFirstChild(); accessRightNode != 
      null; accessRightNode = accessRightNode.getNextSibling()) {
        if (accessRightNode.getNodeType() == Node.ELEMENT_NODE && 
        accessRightNode.getNodeName().equals("AccessRight")) {
         Element accessRightsel = (Element)accessRightNode;
				
         String accessType = accessRightsel.getAttribute("Type");
					
         NodeList accessnl = accessRightsel.getChildNodes();
					
         if(accessnl != null ) {	
		
            for(int y = 0 ; y < accessnl.getLength();y++) {			
							
              Node accnode = accessnl.item(y);
							
           if (accnode.getNodeType() == 
           accnode.ELEMENT_NODE && 
           accnode.getNodeName().equals("Access")) {
           Element el = (Element)accnode;			
           String access = el.getFirstChild().getNodeValue();	
           if (accessType.equals("addReadAccessMembers")){
           aWCMObject.addReadAccessMembers(new String[]{access});
             System.out.println("addReadAccessMembers for Object = 
             "+aWCMObject.getName()+" members = "+access);
			  }else if(accessType.equals
			  ("addEditAccessMembers")){
			  aWCMObject.addEditAccessMembers(new String[]{access});
			  System.out.println("addEditAccessMembers for Object = 
                "+aWCMObject.getName()+" members = 
                "+access);
                
              }else if(accessType.equals
              
              ("addDeleteAccessMembers")){	
              										
              aWCMObject.addDeleteAccessMembers
              (new String[]{access});
              System.out.println
              ("addDeleteAccessMembers for Object = 
              "+aWCMObject.getName()+" members = "+access);
            }		
            										
          }
        }
      }	
    }
  }		
  }		
  }	
	return aWCMObject;
}
Listing 14. Parse and add Template Mapping SiteArea
/*
*Parse settings element 
*Search for TemplateMapping element
*For every TemplateMapping element
*Get the authoring template and presentation template names
*Retrieve the Lotus Web Content Management object from the names
*If item already contains a template mapping with the same authoring template, 
*remove it and add the new one
*Else, add the new template mapping
*Save the object, either the site or site area
*/
public Object retrieveAddTemplateMapping
(SiteFrameworkContainer aWCMObject, 
Element settingsel){
  DocumentId authId = null;
  DocumentId presId = null;
		
  NodeList tempnl = settingsel.getChildNodes();
	
  for (Node node = settingsel.getFirstChild(); node != 
  null; node = node.getNextSibling()) {
    if (node.getNodeType() == Node.ELEMENT_NODE && 
    node.getNodeName().equals("TemplateMapping")) {
      Element tempel = (Element)node;
			
      String authoringTemp = 
	  getElementValueByTagName("AuthoringTemp", tempel );
	  String presTemp = 
	  getElementValueByTagName("PresentationTemp", tempel );
			
	  authId = getWCMDocumentByName(authoringTemp, 
	  DocumentTypes.AuthoringTemplate);
		   	
	  presId = getWCMDocumentByName(presTemp, 
	  DocumentTypes.PresentationTemplate);
		   				    
	  if (authId != null){
	    try{
		if (aWCMObject.hasTemplateMapping(authId)){
		}
					
		if (!aWCMObject.hasTemplateMapping(authId)){
		  aWCMObject.addTemplateMapping(authId, presId);	
		}
		else{
				
		  DocumentIdIterator docIt = aWCMObject.getAuthoringTemplateIds();
		    if (docIt.hasNext()){
		  DocumentId dids = (DocumentId)docIt.next();
		  aWCMObject.removeTemplateMapping(dids);
		  aWCMObject.addTemplateMapping(authId, presId);			
		}
	}
					
		  System.out.println("TemplateMapping authName = "+authoringTemp+" 
		  and presName = "+presTemp +" added to object " + aWCMObject.getName());
		  workspace.save(aWCMObject);
		  }catch(Exception e){
		  System.out.println("Exception ="+e);
		  e.printStackTrace();
		}
		}else{
	return null;
	}
  }
}
	
  return aWCMObject;		
}
Listing 15. Saving Lotus Web Content Management objects to the workspace
/*
 * This is a helper method that receives a Lotus Web Content Management 
 * document object and adds it to the workspace
 */
public boolean saveToWorkspace(com.ibm.workplace.wcm.api.Document wcmDocument){

	try{
		String[] errors = workspace.save(wcmDocument);
					
		for (int i = 0; i < errors.length; i++){
			System.out.println("Error while saving "+ 
			wcmDocument.getName()+ " : "+errors[i]);
		}
		if (errors.length > 0 ){
			return false;
		}
	}catch(Exception e){
		System.out.println("Exception = "+e);
		e.printStackTrace();
		return false;
	}		
	return true;		
}
Listing 16. Retrieve Lotus Web Content Management objects by path
/*
 * This is a helper method that retrieves a Lotus Web Content Management 
 * object by its path and returns the DocumentId
 */
public DocumentId getWCMDocumentByPath(String wcmPath, int workFlowStatus) {
	DocumentId wcmDocumentId = null;
	try{
	
	
    if(wcmPath != null){					
     DocumentIdIterator docIdIter = workspace.findByPath(wcmPath, workFlowStatus);
     if(docIdIter != null && docIdIter.hasNext()){
        wcmDocumentId = docIdIter.nextId();
      }
    }
  }catch(Exception e){
    System.out.println("Exception = "+e);
    e.printStackTrace();
	}
	
	return wcmDocumentId;
}
Listing 17. Retrieve child element by name
/*
 * This is a helper method that gets the child element according to
 * its name of another element if 
 * it contains only one child with that name
 */
private Element getChildByName(Element element, String name) {
	Element rEl = null;
	for (Node node = element.getFirstChild(); node != null; node = 
	node.getNextSibling()) {
	   if (node.getNodeType() == Node.ELEMENT_NODE && 
	   node.getNodeName().equals(name)) {
	    	rEl = (Element)node;
	    		break;
	    }
	}	    
	return rEl;
}
Listing 18. Retrieve element value by name
/*
 * This is a helper method that  returns a string value of the given element
 */
public String getElementValueByTagName(String aTagName, Element aElement){
	String elementValue = "";

	NodeList nodeList = aElement.getElementsByTagName(aTagName);
	if(nodeList != null && nodeList.getLength() > 0) {
		Element el = (Element)nodeList.item(0);			
		elementValue = el.getFirstChild().getNodeValue();			
	}
	
	return elementValue;			
}
Listing 19. Retrieve Lotus Web Content Management object by name
/*
 * This is a helper method that returns the DocumentId of a Lotus Web  
 * Content Management object based on its name
 */
public DocumentId getWCMDocumentByName(String wcmName, DocumentType documentTypes){
	
  DocumentId wcmDocumentId = null;
  try{
    if(wcmName != null){	
							
      DocumentIdIterator docIdIter = workspace.findByName(documentTypes, wcmName);
      if(docIdIter != null && docIdIter.hasNext()){
        wcmDocumentId = docIdIter.nextId();
				
      }
    }
  }catch(Exception e){
    System.out.println("Exception = "+e);
    e.printStackTrace();
  }
  if (wcmDocumentId == null && ( (documentTypes.equals
  (DocumentTypes.AuthoringTemplate)) || (documentTypes.equals
  (DocumentTypes.PresentationTemplate)) )){
    System.out.println("Exception:  "+wcmName+" could not be found in the Repository");
  }
  return wcmDocumentId;
}
Listing 20. Close Lotus Web Content Management workspace
/**
   * Closes the Lotus Web Content Management workspace
   */
public void closeWorkspace() {
	WCM_API.getRepository().endWorkspace();
}

NOTE: Exception handling is done only for illustration purposes rather than production-quality handling. It should be modified if needed to meet your expectations and requirements.

Key warnings have been reported by the helper class:

  • Users are notified by a warning message that there were errors and that the creation was not completed successfully.
  • Errors are logged in the SystemOut.log file so that you can examine more information about the error.
  • Errors that occur when users in the repository are not found result in an error being logged, but Creation Completed messages for the users are also generated.

Enhancements

Using the proposed solution in this article, you can enhance it. For example, you can do the following:

  • Create contents using XML
  • Add more complex components to the default content and contents
  • Change the XML to create the same structure any number of times by changing only the name of the site area

Conclusion

In this article, we present a simple solution that enables you to define site structures in an automated fashion. The uses for such a solution are various; for example, you might need to define site areas on several servers, or you might have a site with a large amount of repeating site structures within it . This solution allows you to save time on an otherwise time-consuming and monotonous task.


Acknowledgments

The authors would like to express gratitude to Ahmed Abbass, Mourad El-Badry, Raul Munoz Serrano, and Tamer El-Mekky who took time out of their busy schedules to review this article and provide their comments.


Downloads

DescriptionNameSize
Code sampleSiteCreation.xsd3628B
Code sampleNewsSiteStructure.xml1933B

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into IBM collaboration and social software on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Lotus, WebSphere
ArticleID=449234
ArticleTitle=Creating an IBM Lotus Web Content Management site structure with one click
publish-date=12082009