Skip to main content link. Accesskey S
  • Anonymous
  • Log on
  • Help
  • IBM logo
  • IBM Composite Applications wiki
  • All Wikis
  • Home
  • Community Articles
  • Product Documentation
  • Learning Center


Search

Advanced Search

Categories

Tag Cloud

  • 6.2
  • 6.2.1
  • 8.0.1
  • 8.5
  • 8.5+
  • 8.5.1
  • advanced features
  • advantages
  • API
  • app dev
  • assembling
  • basics
  • benefits
  • Browser
  • CAE
  • catalog
  • changing page properties
  • changing value to another type of value
  • code snippet
  • component library
  • component properties
  • components
  • Composite Application Editor
  • Composite Applications
  • container components
  • containers
  • custom actions
  • debugging
  • demos
  • deploying
  • designing
  • developing
  • Eclipse
  • Eclipse components
  • editing properties
  • Editor
  • education
  • enablement
  • Expeditor
  • extending
  • extensions
  • FAQ
  • feature rules
  • framework
  • getting started
  • Help
  • HOD
  • host on demand
  • how to
  • Java
  • lead manager
  • linking
  • live text
  • match rules
  • new users
  • Notes
  • Notes components
  • nsf
  • NSF components
  • overview
  • page navigation
  • page properties
  • Palette
  • PBE
  • PIM
  • plugins
  • Portal
  • preference
  • product documentation
  • programming
  • properties
  • property broker
  • property broker editor
  • Property Broker Monitor tool
  • provisioning
  • resources
  • roadmap
  • samples
  • setting component properties
  • Sidebar
  • sideshelf
  • Symphony
  • Symphony view component
  • technote
  • testing
  • toolkit
  • TopologyHandler
  • troubleshooting
  • tutorial
  • update site
  • updating
  • upgrading
  • video
  • view
  • Web
  • web services
  • white lists
  • widgets
  • Wiring
  • WSDL
InformationInformation
You are currently viewing machine translated content. IBM translation might be available. Click IBM Translated Product Documentation to see what is available.X


Home > Tutorials: Advanced > Creating state in a custom action
Rate this article 1 starRate this article 2 starsRate this article 3 starsRate this article 4 starsRate this article 5 stars

Creating state in a custom action 

expanded Abstract
collapsed Abstract
This tutorial walks you through the steps of creating state in a custom action, so that you can create your own actions for any kinds of containers.
ShowTable of Contents
HideTable of Contents
  • 1 Introduction
  • 2 Creating the Eclipse plugin
  • 3 Creating the Action code
  • 4 Packaging and installing the AppendToQueue action
  • 5 Assembling a composite application with AppendToQueue action
    • 5.1 Configuring our main browser component
    • 5.2 Configuring the receive browser component
    • 5.3 Wiring our components
  • 6 Using the newly created composite application
  • 7 Conclusion

Introduction


The action in this tutorial is created for the browser container and can be used to save state for each container instance. The "state" is the history of the property values that are wired to each container instance, each of which will have its own state. We also explain how to deploy this action to IBM Lotus Notes and how to use the Composite Application Editor (CAE) to make a composite application with this action.

To get the most from this tutorial, you need to have Lotus Notes 8.5.1 and the Lotus Expeditor 6.2.1 toolkit installed into your Eclipse 3.4 Integrated Development Environment (IDE). Also, it's be best to complete the wiki tutorial, "Creating custom actions in Java," prior to performing this one.

Creating the Eclipse plugin


a) Create a new Eclipse plugin project just as you did in Step 1 of "Creating custom actions in Java." For this tutorial, the plugin should be named "com.ibm.ca.wiki.action.state".

b) Add the required bundles and imported packages for this plugin as shown in figure 1.

Figure 1. Dependencies window


c) Create a custom action by extending the com.ibm.rcp.composite.container.core.actionConfiguration extension-point. You can refer to Step 2 of Creating a custom action in Java. For this tutorial, the action is named AppendToQueue, and it's targeted for browser container. Figure 2 shows the configuration.

Figure 2. Extensions window



Creating the Action code


Now we create the Java code for our AppendToQueue action, which is extended from the com.ibm.rcp.composite.container.core.actions.Action. We need to override the execute() method to do our work. The AppendToQueue action code is shown in listing 1. It saves state for each container instance in an internal Map (field is named "state" in the code), and also updates the browser UI to show states of current instance when the action is executed.

Listing 1. AppendToQueue action code

package com.ibm.ca.wiki.action.state;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.eclipse.core.runtime.Platform;
import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.swt.widgets.Display;

import com.ibm.rcp.browser.service.WebBrowser;
import com.ibm.rcp.composite.container.browser.BrowserAppContainer;
import com.ibm.rcp.composite.container.core.AppContainer;
import com.ibm.rcp.composite.container.core.actions.Action;
import com.ibm.rcp.composite.container.core.events.LandmarkEvent;

public class AppendToQueue extends Action 
{	
	private final int MAX_HISTORY_SIZE = 10;
	
	private Map state;
	private String htmlRoot;
	
	private BrowserAppContainer bc ;
	private Object context;
	private String viewId;
	private String html;
	
	private final static String CLAZZ_NAME = AppendToQueue.class.getName();
	private final static Logger _logger = Logger.getLogger(CLAZZ_NAME);  
	
	public AppendToQueue() 
	{
		super();
		state = new HashMap();
		
		Location location = Platform.getInstanceLocation();
		String instanceAreaPath = location.getURL().getPath();
		htmlRoot = instanceAreaPath;
	}

	@Override
	public void execute(AppContainer container, LandmarkEvent event,Object context) 
	{
		bc = (BrowserAppContainer)container;
		//Need to replace the : in viewId , to avoid non-supported char in url
		viewId = bc.getViewId().replace(':', '-');
		
		this.context = context;
		File f = new File( htmlRoot );
		html = f.getAbsolutePath() + File.separatorChar + viewId + ".html";
		
		String pValue = event.getPropertyValue();
		String p = event.getProperty();
		
		if(pValue != null)
			saveAndPresentState( p, pValue.trim());
	}
	
	private void saveAndPresentState(String property, String value)
	{
		saveState(property, value);
		generateStateHTML();
		updateUI();
	}
	
	private void saveState(String property, String value)
	{
		_logger.info("Saving state. Property : " + property + " Value : " + value);
		
		Map instanceState = (Map)state.get(viewId);
		if(instanceState == null){
			instanceState = new HashMap();
		}
		
		List propHistory = (List)instanceState.get(property);
		if(propHistory == null){
			propHistory = new LinkedList();
		}
				
		if(propHistory.size() == MAX_HISTORY_SIZE)
			propHistory.remove(0);
		
		propHistory.add(value);
		
		instanceState.put(property, propHistory);
		state.put(viewId, instanceState);
	}
	
	private void generateStateHTML()
	{
		final String _method = "generateStateHTML";
		Map instanceState = (Map)state.get(viewId);
		String content = HtmlHelper.generateStateTable(instanceState);
		
		File file = new File(html);
		if(file.exists())
			file.delete();
		
		FileWriter writer = null; 
		try {
			writer = new FileWriter(file);
			writer.write(content);
			writer.flush();
		} catch (IOException e) {
			_logger.logp(Level.WARNING, CLAZZ_NAME, _method,"Fail to generate html file " + html, e);
		}finally{
			if(writer != null)
				try {
					writer.close();
				} catch (IOException e) {
					_logger.logp(Level.WARNING, CLAZZ_NAME, _method,"Fail to generate html file " + html, e);
				}
		}
	}
	
	private void updateUI()
	{				
		final WebBrowser browser = bc.getWebBrowser(context);
		Display display = browser.getDisplay();
		display.asyncExec(new Runnable(){
			public void run() 
			{				
				browser.setUrl(html);
			}			
		});
	}
	
}


In the AppendToQueue action, we use an HtmlHelper util class to help generate the html markup. The code of HtmlHelper is shown in listing 2.

Listing 2. HtmlHelper code

package com.ibm.ca.wiki.action.state;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class HtmlHelper 
{
	private HtmlHelper()
	{
		
	}
	
	public static String generateStateTable(Map state)
	{
		StringBuilder sb = new StringBuilder();
		String header = "<html><body><table border=\"1\"><tr><th>Property</th><th>State</th></tr>";
		sb.append(header);
		
		Set properties = state.keySet();
		for(Iterator it = properties.iterator(); it.hasNext(); ){
			String property = (String)it.next();
			List history = (List)state.get(property);
			String row = generateRow(property, history);
			sb.append(row);
		}
		
		String footer = "</table></body></html>";
		sb.append(footer);
		return sb.toString();		
	}
	
	private static String generateRow(String property, List history)
	{
		StringBuilder sb = new StringBuilder();
		String header = "<tr>";
		sb.append(header);
		
		sb.append("<td>" + property + "</td>");
		
		StringBuilder historyString = new StringBuilder();
		for(Iterator it = history.iterator(); it.hasNext();){
			historyString.append((String)it.next() + "</br>");
		}
		
		sb.append("<td>" + historyString.toString() + "</td>");
		
		String footer = "</tr>";
		sb.append(footer);
		return sb.toString();
	}
}



Packaging and installing the AppendToQueue action


Follow Step 4 in the "Creating custom actions in Java" tutorial to create an Eclipse feature/update site, and deploy the AppendToQueue action to Lotus Notes. After restarting Lotus Notes, we will begin to create a composite application with the AppendToQueue action. Alternatively, you can use widgets to deploy the new update site to the Notes client.

Assembling a composite application with AppendToQueue action


Now let's create a new composite application to demonstrate our newly created custom action:

a) Create a new Composite Application NSF, using the menu options File -- Application -- New; you are presented with a dialog box to create a new application (see figure 3).

b) Make sure you select "Blank Composite Application" for the default template.

Figure 3. New Application window


The composite for this tutorial are two side-by-side Managed Browser components. The left-hand component is our regular "browser" in which we surf the Internet for interesting information. The browser on the right-hand side is where we call our AppendToQueue action for two properties.

c) In the left-hand browser, open the Advanced properties dialog by right-clicking on the component in the left-hand navigation tree. We will name the left-hand component "Main Browser" and the right-hand component "ReceiveBrowser" (see figure 4).

Figure 4. Two browser components


Configuring our main browser component


a) First, we must define what properties we want to publish from our left-hand component. Let's create two properties, one called "BaseballPlayersName" and the other "BaseballTeamsName" (see figure 5). We will publish these properties at two different landmarks.

Figure 5. Create properties


b) As you can imagine by their name, we will publish a baseball player's name when we navigate to a player profile, and we will publish a baseball team's name when we navigate to a team roster. Figure 6 shows the landmark definitions for these two kinds of pages.

Figure 6. Landmark definitions


Here is the text representation of the landmark values, so you can copy and paste:

*?player_id=*
*mlb.com/team/roster_active.jsp?c_id=*

Configuring the receive browser component


a) Now we configure the right-hand component to have our custom action called when the main browser publishes a property. Once again, in the Advanced properties section of the receive browser, we add two wireable properties, PlayersName and TeamName (see figure 7).

Figure 7. Add wireable properties


b) We now must define our landmarks and have our custom action called with the incoming property values. Figure 8 shows the Landmarks tab for our receive component.

Figure 8. Landmarks tab


As you can see, we merely map the two properties in the Data Change event to our AppendToQueue action, meaning that any time these properties are wired and data comes in, our new action will be called.

Wiring our components


The last step in creating our application is wiring the two new components together. Since the property's names are almost the same, this should be easy. We prefer using the wiring dialog for this. Figure 9 shows the end result with the two new wires.

Figure 9. Create New Wire window


Using the newly created composite application


We are now ready to use our new application and see the custom action working:

a) Change the URL on the left-hand window and navigate throughout MLB.com (see figure 10). The team name and players name states should get added to the previously visited players and teams. Here are some sample rosters and player URLs:

Yankees: http://newyork.yankees.mlb.com/team/roster_active.jsp?c_id=nyy
Red Sox: http://boston.redsox.mlb.com/team/roster_active.jsp?c_id=bos

Derek Jeter: http://newyork.yankees.mlb.com/team/player.jsp?player_id=116539
Jason Veritek: http://boston.redsox.mlb.com/team/player.jsp?player_id=123660

Figure 10. Navigate through MLB.com


Conclusion


This article adds a new example of custom actions and shows how to leverage the custom action in composite applications. The concept for this action is to show the ability for each container instance to keep its own state. From this article, you can see the custom action is quite useful and easy to extend.

expanded Article information
collapsed Article information
Category:
Tutorials: Advanced
Tags:
Custom Actions, Browser, tutorial

This Version: Version 6 March 31, 2010 10:26:36 AM by Leslie Gallo  IBMer

expanded Attachments (0)
collapsed Attachments (0)

 


expanded Versions (6)
collapsed Versions (6)
Version Comparison     
Version Date Changed by               Summary of changes
This version (6) Mar 31, 2010 10:26:36 AM Leslie Gallo  
5 Mar 30, 2010 6:59:53 PM Leslie Gallo  
4 Mar 30, 2010 6:56:53 PM Leslie Gallo  
3 Mar 30, 2010 6:34:44 PM Leslie Gallo  
2 Dec 3, 2009 10:22:53 AM Bob Balfe  
1 Dec 2, 2009 3:04:54 PM Bob Balfe  
expanded Comments (0)
collapsed Comments (0)
Copy and paste this wiki markup to link to this article from another article in this wiki.
Go ElsewhereStay ConnectedSubscribe to RSSHelpAbout
  • All Lotus and WebSphere Portal wikis
  • IBM developerWorks
  • IBM Software support
  • IBM Social Business User Experience Blog
  • IBMSocialBizUX on Twitter
  • IBMSocialBizUX on Facebook
  • Lotus product forums
  • IBM Social Business UX blog
  • IBM Collaboration Solutions
  • Recently added feedRecently added
  • Recently edited feedRecently edited
  • Recently added comments feedRecently Added Comments
  • Wiki Help
  • Forgot user name/password
  • Wiki design feedback
  • Content feedback
  • About the wiki
  • About IBM
  • Privacy
  • Contact IBM
  • IBM Terms of use
  • Wiki terms of use