|
|

[an error occurred while processing this directive]
|
 |
 |
 |
introduction |
 |
 |
 |
|
The greatest benefit of writing component-based applications is that components can, if written properly, be reused in many parts of the application with minimal maintenance issues and code duplication. This paper presents some ideas for coding components to achieve maximum reusability. It assumes a basic understanding of component authoring in the e-Portal framework.
|
 |
 |
default values |
 |
 |
 |
When components are uploaded to the portal they are defined to the portal using the "portal_application.xml" file. One section of the component descriptor is the "defaults" section. Components can have an unlimited number of defaults. Following is an example of a component description with a default value:
<component>
...
<defaults>
<default>
<name>debug</name>
<value>false</value>
</default>
</defaults>
...
</component>
In this example the debug value for the component is set in the defaults so that is can be changed on the fly using the PAC (Portal Administration Console), thus eliminating the need to recompile the class to change the component behavior.
In the component there has to be some mechanism for reading the defaults and placing the value into variables inside the components. The following example code reads out the values in the defaults and uses those values to set internal variables:
EbiPortal portal = EboPortalFactory.getPortal();
EbiComponentManager componentMgr = (EbiComponentManager) portal.getPortalManagerInterface(EbiPortalConstants.PORTAL_COMPONENT_MGR);
EbiPortalComponentInfo compInfo = componentMgr.getComponentInfo(session,ComponentClassName,false);
Properties defaultProp = compInfo.getComponentDefaultValues();
String debugProp = (String) defaultProp.getProperty("debug");
if (debugProp!=null)
{
debug = (new Boolean(debugProp)).booleanValue();
}
The default values can also be used to control more complicated component behavior. Several examples of possible default items are as follows:
- Links to be used on the components
- URLs to images displayed on the component
- Sorting instructions
- Component title
- Data retrieval options
The benefit of setting items such as these in the defaults is to make the component flexible. If, for example, you are using the Content Management system to store data for your site, one common component needed is a component that lists items from a particular folder or category in the system. So if you wanted to search the "Current Events" folder, you would set a default value to that folder name. The component, instead of having a hard-coded folder or category name, would then simply retrieve documents based on the value in the default. If there was ever a need to change the component, the default could simply be changed to contain another folder name, at which point the component would continue to function normally but would now retrieve the contents of the new folder.
While defaults are a great way to move items out of the component so it can be flexible, they don't help if you want to deploy the same component multiple times in an application. This is because components can only be registered once in the system, and therefore can only have one set of default values.
|
 |
 |
parameters |
 |
 |
 |
When components are processed via JSP pages or portal pages, developers have the ability to pass information to the portal at run time. This allows components to be deployed in any number of locations across an application with different settings and behaviors. To display a component on a portal page, the tag is used. The required elements of this tag are "ID" and "NAME." ID is actually the component class name, and NAME is the descriptive name of one particular instance of a component. If a component were placed twice on a page, the NAME would be different in each tag as shown in the following example:
<S3COMP ID="com.sssw.portal.component.DocList" NAME="doclist1"/>
<S3COMP ID="com.sssw.portal.component.DocList" NAME="doclist2"/>
If the Content Management folder example mentioned earlier were implemented, it would have the same component on a single page supplying different information as follows:
<S3COMP ID="com.sssw.portal.component.DocList" NAME="doclist1" foldername="Best Sellers" title="Check out these best sellers" />
<S3COMP ID="com.sssw.portal.component.DocList" NAME="doclist2" foldername="Sale Items" title="Click here for great deals" />
In this example, the component would appear with completely different titles and list completely different information, but it would still be generated by a single component. The parameters are automatically passed into the "getComponentData" and "processRequest" methods of the component in a Map. The parameter information is retrieved by simply getting the parameter out of the Map object (params) as follows:
String currentFolderName = (String) params.get("foldername");
String currentTitle = (String) params.get("title");
The local variables of "currentFolderName" and "currentTitle" would then be used to create the component content.
|
 |
 |
combining defaults and parameters |
 |
 |
 |
For many components, subscribing to these notions of parameterizing components can lead to a long and complicated list of default values and possible parameter settings. For this reason, it is often a good idea to list all possible incoming information as defaults but still allow the values to be overridden by parameters. This way, if a parameter is forgotten or doesn't need to be changed, it does not need to be added to the tag. If for instance a logo graphic were added to the example above, the name of the image would be added as a default. (Note that while the logo image is unlikely to change, it is important not to hard code the name of the image in the component.) The example component would now have variables defined to hold each of the incoming values as follows:
String currentFolderName, defaultFolderName;
String currentTitle, defaultTitle;
boolean debug;
String imageName, defaultImageName;
In the defaults section of the "portal_application.xml" file, the starting values for these items would be defined as follows:
<component>
...
<defaults>
<default>
<name>debug</name>
<value>false</value>
</default>
<default>
<name>foldername</name>
<value>false</value>
</default>
<default>
<name>debug</name>
<value>title</value>
</default>
</defaults>
<default>
<name>imagename</name>
<value>false</value>
</default>
...
</component>
In the initialize method of the component retrieve, the defaults and local variables would be set as follows:
EbiPortal portal = EboPortalFactory.getPortal();
EbiComponentManager componentMgr = (EbiComponentManager) portal.getPortalManagerInterface(EbiPortalConstants.PORTAL_COMPONENT_MGR);
EbiPortalComponentInfo compInfo = componentMgr.getComponentInfo(session,ComponentClassName,false);
Properties defaultProp = compInfo.getComponentDefaultValues();
String debugProp = (String) defaultProp.getProperty("debug");
if (debugProp!=null)
{
debug = (new Boolean(debugProp)).booleanValue();
}
String foldernameProp = (String) defaultProp.getProperty("foldername");
if (foldernameProp!=null)
{
defaultFolderName = foldernameProp;
}
String titleProp = (String) defaultProp.getProperty("title");
if (titleProp!=null)
{
defaultTitle = titleProp;
}
String imagenameProp = (String) defaultProp.getProperty("imagename");
if (imagenameProp!=null)
{
defaultImageName = imagenameProp;
}
Finally, in the "getComponentData" method, a check would be made to see if any new values were passed in. The check would run as follows:
String paramFolderName = (String) params.get("foldername");
if (paramFolderName!=null){
currentFolderName = paramFolderName;
}else {
currentFolderName = defaultFolderName;
}
String paramTitle = (String) params.get("title");
if (paramTitle!=null){
currentTitle = paramTitle;
}else {
currentTitle = defaultTitle;
}
String paramImageName = (String) params.get("imagename");
if (paramImageName!=null){
imageName = paramImageName;
}else {
imageName = defaultImageName;
}
|
 |
 |
HTML vs. XML/XSL |
 |
 |
 |
The use of reusable component techniques is equally beneficial whether the components are HTML-based or XML/XSL-based. In the case of XML/XSL components, some of the values that are placed in the defaults need to be included in the XML that is returned from the component. Links and images are good examples of items that would most likely be returned as part of the XML to be processed by the XSL in order to create the final HTML that contains the actual links and image tags. A good standard practice is to keep these values in a separate section of the XML. This allows greater caching opportunities by keeping dynamic portions of the XML separate, and creates consistency for XML patterns across the application. Any node name can hold these parameters. The Knowledge Base sample application uses this technique in the following format:
<display-settings>
<actionurl>discussion_doc_tree.html&C=com.sssw.portal.component.documentmgmt.DiscussionDocumentTree&dt_sel=</actionurl> <selecturl>discussion_view.html&C=com.sssw.portal.component.documentmgmt.DiscussionViewer&dv_doc=</selecturl> <newurl>pg_addThread.html&C=com.sssw.portal.component.documentmgmt.AddDiscussionDocument&folder=</newurl> <refreshurl>discussion_doc_tree.html&C=com.sssw.portal.component.documentmgmt.DiscussionDocumentTree</refreshurl> </display-settings>
In the case of XML/XSL, the values contained in the defaults are not used within the component but are returned as part of the XML. When using XML/XSL it is easier to get the values that are needed inside the code, set local variables as described above, and then create a properties object that contains only the remaining items, such as the URLs. And then when the XML is being generated in the component, simply loop through the properties object by adding a new node under "display-settings" for each item in the properties object. An example of this technique is shown below. Further examples can be found in the Knowledge Base sample code located in com.sssw.portal.component.documentmgmt.
if (displayProps!=null)
{
Element displayMetadata = newDoc.createElement("display-settings");
base.appendChild(displayMetadata);
Enumeration names = displayProps.propertyNames();
while (names.hasMoreElements())
{
String displayPropName = (String)names.nextElement();
String displayPropValue = displayProps.getProperty(displayPropName);
Element name = newDoc.createElement(displayPropName);
displayMetadata.appendChild(name);
String linkUrl = displayPropValue;
Text displayValue = newDoc.createTextNode(linkUrl);
name.appendChild(displayValue);
}
}
|
 |
 |
conclusion |
 |
 |
 |
|
By combining the value of component-default and parameter settings, component behavior can be controlled and changed without having to recompile or recreate components in an application. These settings can be used to control presentation items in the components, the internal processing of the component, and how the component interacts with other components in an application. Using these features will greatly increase the flexibility of components and maximize their ability to be reused throughout an application.
|
 |
|
 |
 |
 |