+

Search Tips   |   Advanced Search

Allow custom content to be tagged and rated


For example, you have a portlet application that can display photos, and to make use of tagging and rating functions. If all photos have a unique URI, we can integrate tags and ratings widgets into the presentation layer, for example a jsp...

<script type="text/javascript">

function showAddTagWidget()
{
    var widget = new com.ibm.widgets.AddTag({
        resourceID: "<c:out value="${photo.uri}" />", 
        resourceTitle: "<c:out value="${photo.title}" />"
    });
    widget.show();
}

function showAddRatingWidget(){
    var widget = new com.ibm.widgets.AddRating({
        resourceID: "<c:out value="${photo.uri}" />", 
        resourceTitle: "<c:out value="${photo.title}" />"
    });
    widget.show();
}
</script>

...

<a href="http://setgetweb.com/p/portal80/javascript:showAddTagWidget('<c:out value="${photo.uri}" />', 
                                     '<c:out value="${photo.title}" />');">Add Tags</a>
...
<a href="http://setgetweb.com/p/portal80/javascript:showAddRatingWidget('<c:out value="${photo.uri}" />', 
                                        '<c:out value="${photo.title}" />');">Add Ratings</a>


Implementing the resolution service

We identify content by assigning a URI.

The portal provides a URI resolution framework that allows us to define custom identifiers for all types of content that users can access in the portal. A URI starts with a URI scheme that describes its purpose.

For example, to make has a set of images available for tagging or rating, we can register them for portal tagging and rating by specifying an unique URI for each individual image. A possible URI format could be image:. We can then address the identified content by plugging resolvers into the portal that display portal pages in a specific configuration defined with these URIs.

Example: Registering a resolution service for photos:

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<plugin id="com.ibm.wps.cp.photo" name="Sample Plug-in for a photo application" 
        version="1.0.0" provider-name="IBM">
   <extension point="com.ibm.content.operations.registry.locationTypeContribution">
  <contentLocationType class="com.ibm.portal.resolver.helper.cor.DefaultContentLocationFactory"
   id="com.ibm.portal.cp.photo" match.uri.scheme="photo"
    />
 </extension>
 <extension point="com.ibm.content.operations.registry.locationServiceHandler">
  <serviceHandler class="com.ibm.wps.cp.sample.photo.PhotoResolutionService"
   locationTypeId="com.ibm.portal.cp.photo" id="com.ibm.portal.resolver.ResolutionService" />
   </extension> 
</plugin>
In particular you need to write a resolution services that is a class that implements the com.ibm.portal.resolver.ResolutionService and can to modify the navigational state in a was that allows the portal to render a view of an image addressed by a unique URI.

Example: The main logic of the resolution service for photos:

/*
     * (non-Javadoc)
     * 
     * @see com.ibm.portal.resolver.ResolutionService#resolve
     * (com.ibm.portal.resolver.Resolved, java.net.URI, 
     *                                    java.lang.String, 
     *                                    * java.util.Map, 
     *                                    java.util.Set, 
     *                                    * com.ibm.content.operations.registry.api.Context)
     */
public boolean resolve(final Resolved res, 
                       final URI uri,
                       final String verb, 
                       final Map<String, String[]> params,         
                       final Set<Binding> acceptedBindings, 
                       final Context ctx)
            throws ResolutionException, StateException 
{        
    final boolean isLogging = LOGGER.isLogging(Logger.TRACE_HIGH);
    if (isLogging) 
    {
        LOGGER.entry(Logger.TRACE_HIGH, "resolve", new Object[] { uri, StringUtils.printMap(params), acceptedBindings });
        LOGGER.text(Logger.TRACE_HIGH, "resolve", "State Before: " + res.getStateHolderController());
    }
    final StateHolderController state = res.getStateHolderController();
    final StateManagerService stateSvc = stateHome.getStateManagerService(ctx);
    try 
    {
        setSelection(stateSvc, state);
        setPortletRenderParameters(stateSvc, state, uri);
    } 
    finally 
    {
        stateSvc.dispose();
    }

    if (isLogging) {
        LOGGER.text(Logger.TRACE_HIGH, "resolve", "State After: " + state);
        LOGGER.exit(Logger.TRACE_HIGH, "resolve", true);
    }
    return true;
}

For example, such a resolution service can change the page selection of the navigational state to a page with a well known unique name.

Example: Change the selection to a page with a well known unique name:

/**
     * Changes the selection of the given state to a well known unique name.
     * 
     * @param stateSvc
     *  The state manager service valid for the current request      
     * @param state
     *  The state holder to modify      */

private void setSelection(final StateManagerService stateSvc,         
                          final StateHolderController state)
            throws UnknownAccessorTypeException,         
                   CannotInstantiateAccessorException,         
                   CannotInsertSelectionNodeException, MissingUniqueNameException,         
                   UnknownUniqueNameException {
    final SelectionAccessorFactory selFct = stateSvc.getAccessorFactory(SelectionAccessorFactory.class);
    final SelectionAccessorController selCtrl = selFct.getSelectionAccessorController(state);
    try {
        selCtrl.setSelection(UN_PAGE_PHOTO);
    } finally {
        selCtrl.dispose();
    }
}
Additionally the resolution service can set render parameters for a portlet on that page. These render parameters in turn can influence a Photo Portlet to display the addressed photo.

Example: Setting render parameters for a portlet with a well known unique name:

    
/**
 * Changes the selection of the given state to a well known unique name.
 * 
 * @param stateSvc
 *            The state manager service valid for the current request      
 * @param state
 * The state holder to modify      */

private void setSelection(final StateManagerService stateSvc,         
                          final StateHolderController state)
            throws UnknownAccessorTypeException,         
                   CannotInstantiateAccessorException,         
                   CannotInsertSelectionNodeException, 
                   MissingUniqueNameException,         
                   UnknownUniqueNameException 
{
    final SelectionAccessorFactory selFct = stateSvc.getAccessorFactory(SelectionAccessorFactory.class);
    final SelectionAccessorController selCtrl = selFct.getSelectionAccessorController(state);
    try {
        selCtrl.setSelection(UN_PAGE_PHOTO);
    } finally {
        selCtrl.dispose();
    }
}

For details about how to register a resolution service refer to the following article at this URL: http://www.ibm.com/developerworks/websphere/library/techarticles/0710_koeth/0710_koeth.html.


Add localization and filtering mechanisms

The resources that have been tagged can be displayed in the Tag Result portlet. In a default portal installation the Tag Result portlet is located on the Tag Center page. If you enable tagging and rating for custom resources, these resources show up in the Tag Result portlet whenever a user selects a tag that has been applied on such a custom resource.

To provide the URI of a custom resource to the portal tagging and rating infrastructure, you pass the URI to the AddTag or AddRating widget. The Tag Result portlet can display a title and description for every tagged resource. This is called localization information in the portal. the portal provides a plug point that we can implement to provide the localization information.

Additionally there might be cases where you want specific resources not be visible for all users. We can use Portal Access Control to filter out resources from users by not giving those users access to those resources.

For custom resources the portal provides a plug point that combines this access filtering mechanism with providing the localization information. This plug point is defined in the interface com.ibm.portal.cp.resources.builder.CustomResourceBuilder . A CustomResourceBuilder must be able to construct a custom resource com.ibm.portal.cp.resources.CustomResource for given input parameters, including the URI.

Example: Filtering custom resources, provide localized information:

/*
 * (non-Javadoc)
 * 
 * @see
 * com.ibm.portal.cp.resources.builder.CustomResourceBuilder#build(com.ibm.portal.cp.resources.builder.CustomResourceBuilder.ResourceParameters
 * )
 */
@Override
public CustomResource build(final ResourceParameters params)
        throws ResourceBuilderException 
{
    final URI uri = params.getURI();
    // Cache lookup
    Photo photo = photoCache.get(uri);
    if (photo == null) 
    {
        // Construct the photo
        photo = new Photo(params.getObjectID(), params.getCategories(), uri, getLocalizedInformation(uri));
            
    }
    if (photo != null && !isAllowedToViewPhoto(getCurrentUser(), photo)) 
    {
        // Hide the photo for the current user                 
        photo = null;
    }
        return photo;
}


Parent: Tagging and rating
Related:
Search for tagged content
Federating tags
Related reference:
How tagging and rating works in the portal
The tagging and rating user interface
Tagging and rating for static pages
Configuration reference
Security for tagging and rating
Use xmlaccess.sh to administer tags and ratings
Administration of tag federation
Tips for tagging and rating
Related:

Access portal content with custom URLs - http://www.ibm.com/developerworks/websphere/library/techarticles/0710_koeth/0710_koeth.html