Sun Java System Portal Server 7 Developer's Guide

ProcedureTo Create a Provider by Extending the ProfileProviderAdapter Class

This section provides the instructions for creating a custom provider by extending the ProfileProviderAdapter. The process includes creating a sample provider that prints “Hello World!” on the provider’s channel. The following sample HelloWorldProvider reads a string property from the user’s display profile and allows the user to edit the string.

The sample HelloWorldProvider described here will also support EDIT_COMPLETE, which means this provider is responsible for generating the complete edit form with header, footer, and handling of the form submit actions. To accomplish this:

Steps
  1. Create the Java class, which will generate the content for the channels backed by this provider.

    For the sample HelloWorldProvider, create the class file.


    package custom.helloworld;
    
    import java.util.Hashtable;
    import java.util.ResourceBundle;
    
    import java.net.URL;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.sun.portal.providers.ProfileProviderAdapter;
    import com.sun.portal.providers.ProviderException;
    import com.sun.portal.providers.context.ProviderContext;
    import com.sun.portal.providers.context.ProviderContextException;
    import com.sun.portal.providers.context.Theme;
    
    public class HelloWorldProviderPPA2 extends ProfileProviderAdapter {
        private ResourceBundle bundle = null;
        private final static String BANNER          = "banner";
        private final static String BANNER_TEMPLATE = "banner.template";
        private final static String BORDER_COLOR    = "borderColor";
        private final static String BORDER_WIDTH    = "borderWidth";
        private final static String BULLET_COLOR    = "bulletColor";
        private final static String BULLET_COLOR_JS = "bulletColor.js";
        private final static String BG_COLOR        = "bgColor";
        private final static String CONTENT_LAYOUT          = "contentLayout";
        private final static String CONTENT_LAYOUT_TEMPLATE = "contentLayout.template";
        private final static String DESKTOP_URL = "desktop_url";
        private final static String EDIT_PROVIDER_TEMPLATE = "editTemplate.template";
        private final static String ERR_MESSAGE            = "errMessage";
        private final static String FONT_COLOR           = "fontColor";
        private final static String FONT_FACE            = "fontFace";
        private final static String FONT_FACE1           = "fontFace1";
        private final static String FRONT_CONTAINER_NAME = "frontContainerName";
        private final static String INLINE_ERROR     = "inlineError";
        private final static String MENUBAR          = "menubar";
        private final static String MENUBAR_TEMPLATE = "menubar.template";
        private final static String MESSAGE          = "message";
        private final static String NO_CACHE          = "noCache";
        private final static String NO_CACHE_TEMPLATE = "noCache.template";
        private final static String PARENT_CONTAINER_NAME = "parentContainerName";
        private final static String PRODUCT_NAME          = "productName";
        private final static String THEME_CHANNEL       = "theme_channel";
        private final static String TITLE_BAR_COLOR     = "titleBarColor";
        private final static String TOOLBAR_ROLLOVER    = "toolbarRollover";
        private final static String TOOLBAR_ROLLOVER_JS = "toolbarRollovers.js";
    
    /*Implement the getContent method*/
         public StringBuffer getContent(
         HttpServletRequest req, HttpServletResponse res
         ) throws ProviderException {
            Hashtable<String,Object> tags = getStandardTags(req);
            if (bundle == null) {
                 bundle = getResourceBundle();
            } tags.put("welcome", bundle.getString("welcome"));
            tags.put("message", getStringProperty("message"));
            StringBuffer b = getTemplate("content.template", tags);
            return b;
        }
    
    /*Implement the getEdit method*/
        public StringBuffer getEdit(
        HttpServletRequest req, HttpServletResponse res)
        throws ProviderException {
            String containerName = req.getParameter("containerName");
            String providerName = req.getParameter("targetprovider");
            String editChannelName = req.getParameter("provider");
            // Get the standard tags, which will include the menubar, footer, etc.
            Hashtable<String,Object> tags = getStandardTags(req);
            tags.put("help_link", getHelpLink("editPage",req));
            // Provider specific tags
            tags.put(MESSAGE, getStringProperty(MESSAGE));
            tags.put("title", getTitle());
            tags.put( "providerName", providerName);
            tags.put( "contentOptions", getTemplate("edit.template", tags).toString());
            if (containerName != null) {
                 tags.put(FRONT_CONTAINER_NAME, containerName);
            }
             StringBuffer b = getTemplate(EDIT_PROVIDER_TEMPLATE, tags);;
             return b;
        }
    
        /* Implement Process Edit Method */
        public URL processEdit(
        HttpServletRequest req, HttpServletResponse res
        ) throws ProviderException {
            String message = req.getParameter(MESSAGE);
            if(message != null) {
                if( !message.equals(getStringProperty(MESSAGE)) ) {
                    setStringProperty(MESSAGE,message);
                    return null;
                }
            } else {
                 setStringProperty(MESSAGE,"");
            }
            return null;
        }
    
    /* HelloWorld Provider supports, edit_type=edit_complete which means, the provider is responsible for generating a complete edit form with header,footer and html buttons. getStandardTags method populates the hashtable with all the standard tags */
        protected Hashtable getStandardTags(HttpServletRequest req) throws ProviderException {
            Hashtable<String,Object> tags = new Hashtable<String,Object>();
            ProviderContext pc = getProviderContext();
            String property = null;
            property = FONT_FACE1;
            tags.put(FONT_FACE1, getStringProperty(FONT_FACE1));
            property = PRODUCT_NAME;
            tags.put(PRODUCT_NAME, getStringProperty(PRODUCT_NAME));
            tags.put(PARENT_CONTAINER_NAME, pc.getDefaultChannelName());
            // templates
            tags.put(MENUBAR, getTemplate(MENUBAR_TEMPLATE));
            tags.put(CONTENT_LAYOUT, getTemplate(CONTENT_LAYOUT_TEMPLATE));
            tags.put(TOOLBAR_ROLLOVER, getTemplate(TOOLBAR_ROLLOVER_JS));
            tags.put(NO_CACHE, getTemplate(NO_CACHE_TEMPLATE));
            tags.put(DESKTOP_URL, pc.getDesktopURL(req));
            tags.put(BULLET_COLOR, getTemplate(BULLET_COLOR_JS));
             tags.put(BANNER, getTemplate(BANNER_TEMPLATE));
            // error tags (if any)
             String err = req.getParameter("error");
             if (err != null) {
                 tags.put(ERR_MESSAGE, err);
                 tags.put("inlineError", getTemplate("inlineError.template"));
             } else {
                 // no error, put in dummy tags so lookup doesn’t fail
                 tags.put(ERR_MESSAGE, "");
                 tags.put(INLINE_ERROR, "");
            }
            // theme attributes
                try {
                    tags.put( BG_COLOR, Theme.getAttribute( getName(), pc, BG_COLOR ));
                    tags.put( TITLE_BAR_COLOR, Theme.getAttribute( getName(), pc, TITLE_BAR_COLOR ));
                    tags.put( BORDER_COLOR, Theme.getAttribute( getName(), pc, BORDER_COLOR ));
                    tags.put( FONT_COLOR, Theme.getAttribute( getName(), pc, FONT_COLOR ));
                    tags.put( BORDER_WIDTH, Theme.getAttribute( getName(), pc, BORDER_WIDTH ));
                    tags.put( FONT_FACE, Theme.getAttribute( getName(), pc, FONT_FACE));
                    if( Theme.getSelectedName(getName(), pc).equals( Theme.CUSTOM_THEME ) ) {
                        tags.put(THEME_CHANNEL, getStringProperty("customThemeChannel"));
                    } else {
                        tags.put(THEME_CHANNEL, getStringProperty("presetThemeChannel"));
                    }
                } catch (ProviderContextException pce) {
                    throw new ProviderException( "TemplateContainerProvider.getStardardTags(): failed to obtain theme related attribute ", pce );
                }
                 return tags;
            }
    /* GetHelpLink for the Help button in the banner and footer of the edit page */
            protected String getHelpLink(String key, HttpServletRequest req) throws ProviderException{
                try {
                    URL helpLink = getHelp(req, key);
                    if (helpLink != null) {
                        return helpLink.toString();
                    }
                    else {
                        return "";
                }
            }  catch (Throwable t ) {
                throw new ProviderException("HelloWorldProvider.getHelpLink(): could not get help URL for " + key, t);
            }
        }
    }
  2. Compile the class file.

    To compile the HelloWorldProviderPPA2.java file, type:


    javac -d PortalServer-DataDir/portals/portal-ID/desktop/classes -classpath PortalServer-base/sdk/desktop/desktopsdk.jar:AccessManager-base/lib/servlet.jar HelloWorldProviderPPA2.java
  3. Create the provider and channel definition for the display profile and load the provider and channel display profile definitions using the psadmin add-display-profile subcommand.

    The HelloWorldProvider provider display profile XML fragment (in file HelloProviderPPA2.xml) is shown here:


    <?xml version="1.0" encoding="utf-8" standalone="no"?>
    <!DOCTYPE DisplayProfile SYSTEM "jar://resources/psdp.dtd">
    
    <Provider name="HelloWorldProviderPPA2" class="custom.helloworld.HelloWorldProviderPPA2">
        <Properties>
            <String name="title" value="*** TITLE ***"/>
            <String name="presetThemeChannel" value="JSPPresetThemeContainer" advanced="true"/>
            <String name="customThemeChannel" value="JSPCustomThemeContainer" advanced="true"/>
            <String name="description" value="*** DESCRIPTION ***"/>
            <String name="refreshTime" value="0"/>
            <Boolean name="isEditable" value="true"/>
            <String name="editType" value="edit_subset"/>
            <Collection name="aList">
                <String value="i’m aList"/>
            </Collection>
            <Collection name="aMap">
                <String name="title" value="Ramag"/>
                <String name="desc" value="My Map"/>
                <Boolean name="removable" value="true"/>
                <Boolean name="renamable" value="true"/>
            </Collection>
            <String name="message" value="Hello World Test Provider"/>
        </Properties>
    </Provider>

    The HelloWorldProvider channel display profile XML fragment (in file HelloChannelPPA2.xml) is shown here:


    <?xml version="1.0" encoding="utf-8" standalone="no"?>
    <!DOCTYPE DisplayProfile SYSTEM "jar://resources/psdp.dtd">
    
    <Channel name="HelloWorldPPA2" provider="HelloWorldProviderPPA2">
        <Properties>
            <String name="title" value="Hello World Channel"/>
            <String name="fontFace1" value="sans-serif"/>
            <String name="productName" value="Sun Java System Portal Server"/>
            <String name="editType" value="edit_complete"/>
            <String name="description">This is a test of the hello world provider</String>
            <String name="width" value="thin"/>
            <String name="message" value="Hello World Test!!! - non-localized "/>
            <Locale language="en" country="US">
                <String name="message" value="Hello World - I am speaking English in the United States!!!"/>
            </Locale>
        </Properties>
    </Channel>

    Note –

    See the Sun Java System Portal Server 7 Command-Line Reference for more information on the psadmin subcommands.


  4. Create the resource bundle properties file for the HelloWorldProvider (HelloWorldProviderPPA2.properties) and include the following string:


    welcome=Welcome to Hello World!!
  5. Copy the resource bundle properties file, HelloWorldProviderPPA2.properties, into PortalServer-DataDir/portals/portal-ID/desktop/classes directory.

  6. Develop the template files for the provider.

    The HelloWorldProvider requires the following template files:

    content.template

    <head></head>
    <body bgcolor="white">
        [tag:welcome]<br><br>
        [tag:message]<br><br>
    </body>
    </html>
    edit.template

    This file generates the editable fields in the form.


    <p>
    <table border="0" cellpadding="2" cellspacing="0" width="100%">
    
        <tr>
            <td colspan="3" bgcolor="#333366">
                <font size=+1 face="[tag:fontFace1]" color="#FFFFFF"><b>Welcome</b></font>
            </td>
        </tr>
    
        <tr><td><br><br><br></td></tr>
    
        <tr>
            <td width="20%" align="RIGHT" NOWRAP>
                <font face="[tag:fontFace1]" color="#000000"><label for="message"><b>Greeting:</b></label></font>
            </td>
            <td width="45%">
                <font face="[tag:fontFace1]" size="+0">
                    <input type="TEXT" name="message" size="50" maxlength="50" value="[tag:message]" id="message">
                </font>
            </td>
        </tr>
    
        <tr>
            <td width="20%">&nbsp;</td>
            <td width="45%">&nbsp;</td>
        </tr>
    
    </table>
    editTemplate.template

    This file generates a complete form


    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
    <HTML>
        <HEAD>
            [tag:noCache]
            <TITLE>[tag:productName]</TITLE>
        </HEAD>
        <BODY BGCOLOR="#FFFFFF">
            <FONT SIZE=+0 FACE="[tag:fontFace1]">
            <LINK REL="stylesheet" TYPE="text/css" HREF="[surl:/desktop/css/style.css]" TITLE="fonts">
            <CENTER>
    
            [tag:bulletColor]
            [tag:banner]
    
            <FORM ACTION="dt" NAME="edit_form" METHOD=POST ENCTYPE="application/x-www-form-urlencoded">
            <INPUT TYPE=HIDDEN NAME="action" SIZE=-1 VALUE="process">
            <INPUT TYPE=HIDDEN NAME="provider" SIZE=-1 VALUE="[tag:providerName]">
    
            [tag:inlineError]
    
            <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=3 WIDTH="100%">
                <TR>
                    <TD WIDTH="100%" VALIGN=TOP>
                        <CENTER>
                            <BR>
                            <FONT SIZE="+2" FACE="[tag:fontFace1]">
                            <B>
                            Edit [tag:title]</B></FONT>
                            <BR>
                            [tag:contentOptions]
                        </CENTER>
                    </TD>
                    </TR>
            </TABLE>
    
            <BR>
    
            <FONT SIZE=+0 FACE="[tag:fontFace1]">
            <INPUT TYPE=SUBMIT NAME="Submit" VALUE="Finished" CLASS="button">
            <INPUT TYPE=BUTTON OnClick="location=’[tag:desktop_url]’" VALUE="Cancel" CLASS="button">
            </font>
    
            <br>
    
            <P>
            </FORM>
            <BR>
            [tag:menubar]
            </font>
        </BODY>
    </HTML>
  7. Create the channel directory under the template root directory and copy the templates for the provider into the channel directory under the templates root directory.

    By default, the template root directory is PortalServer-DataDir/portals/portal-ID/desktop/desktoptype. For this example, create a HelloWorldPPA2 directory under PortalServer-DataDir/portals/portal-ID/desktop/desktoptype directory. To copy the templates, for example, type:


    cp content.template PortalServer-DataDir/portals/portal-ID/desktop/desktoptype/HelloWorldPPA2
    cp edit.template PortalServer-DataDir/portals/portal-ID/desktop/desktoptype/HelloWorldPPA2
    cp editTemplate.template PortalServer-DataDir/portals/portal-ID/desktop/desktoptype/HelloWorldPPA2
  8. Access the channel from a browser. To access, type the following URL in your browser:


    http://hostname:port/portal-ID/dt?provider=HelloWorldPPA2

    To display the provider’s channel as one of the leaf channels for a container, you have to add the channel into the container’s available and selected list. To accomplish this:

  9. Add it to the Available and Selected list for the container.

    For example, to add the HelloWorldProvider to the TemplateTableContainer, use the psadmin modify-display-profile subcommand. For more information on the psadmin utility and its subcommands, see the Sun Java System Portal Server 7 Command-Line Reference.

  10. Access the HelloWorld Channel inside the TemplateTableContainer. To access, log in to the Desktop and type the following URL in your browser:


    http://hostname:port/portal-ID/dt?provider=TemplateTableContainer

    Utilize the psadmin utility for transporting channels and providers. Using the psadmin command, the contents of the helloworld.par can be imported to as HelloWorld channel in a different Portal Server software installation. For more information on the psadmin utility and its subcommands, see the Sun Java System Portal Server 7 Command-Line Reference.