martes, 15 de abril de 2014

Integrando WebCenter Likes / Comments API - I

Este post es un ejemplo de como usar el API de Activity Streaming para manejar los Likes y Comentarios de los servicios / contenidos de WebCenter Portal.


Enlace a la versión en inglés
 

Lista de gente que ha hecho Like a una actividad

"La parte de los comentarios será ampliada en Integrando WebCenter Likes / Comments API-II" (Pronto)

Hay un servicio por defecto que permite aplicar la funcionalidad de Likes sobre contenidos.

Descargar LikesCommentsExtension JDeveloper Project

Por ejemplo:
Document Manager Task Flow permite la funcionalidad de “Like“/“Unlike” sobre los contenidos almacenados en WebCenter Content.

Document Explorer trae por defecto Like

How can I add the same functionality to the Content Presenter Templates?

Este ejemplo hace uso de Activity Streaming API aplicado sobre un contenido mostrado por Content Presenter. Para ello, obtiene toda la información necesaria del contenido a partir de la variable  oracle.webcenter.content.integration.Node presente en las plantillas de Content Presenter.

package custom.oracle.webcenter.likescomments;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import oracle.adf.share.logging.ADFLogger;

import oracle.webcenter.activitystreaming.ActivityException;
import oracle.webcenter.activitystreaming.ActivityObject;
import oracle.webcenter.activitystreaming.ActivityStreamingService;
import oracle.webcenter.activitystreaming.ActivityStreamingServiceFactory;
import oracle.webcenter.comments.Comment;
import oracle.webcenter.comments.CommentsSummary;
import oracle.webcenter.content.integration.Node;
import oracle.webcenter.content.integration.RepositoryException;
import oracle.webcenter.content.integration.spi.ucm.UCMConstants;
import oracle.webcenter.doclib.internal.model.VCRUtils;
import oracle.webcenter.framework.service.Scope;
import oracle.webcenter.framework.service.ServiceContext;
import oracle.webcenter.framework.service.ServiceObjectType;
import oracle.webcenter.likes.Like;
import oracle.webcenter.likes.LikesSummary;

/**
 * Utility class to access to Likes and Comments of a specific Node.
 * This class will access in Map EL Expression way
 * TODO: Implement a Declarative Component / or bean bigger scope to don't recalculate everything
 * @author Daniel Merchan Garcia
 * @version 1.0
 */
public final class LikesCommentsProcessor {
    
    /**
     * Logger
     */
    private static final ADFLogger LOG =
        ADFLogger.createADFLogger(LikesCommentsProcessor.class);
    
    /**
     * Class name to be used by the logger
     */
    private static final String CLASS_NAME =
        LikesCommentsProcessor.class.getName();

    /**
     * Map holding nodeLikesComments
     */
    private Map nodeLikesComments;

    /**
     * Default Constructor
     */
    public LikesCommentsProcessor() {
        super();
        
        // Implementation via Map EL expression
        nodeLikesComments = new HashMap() {
                @Override
                public NodeLikeComments get(Object key) {
                    if (key != null && key instanceof Node) {
                        Node node = (Node)key;
                        NodeLikeComments nlc = this.getCommentsLikes(node);
                        return nlc;
                    } else {
                        return super.get(key);
                    }
                }

                /**
                 * Extract from a Node all Comments and Likes
                 * @param node
                 */
                private NodeLikeComments getCommentsLikes(Node node) {
                    LOG.entering(CLASS_NAME, "getCommentsLikes");
                    // FIXME prevent Folder item asking about isFolder
                    NodeLikeComments nlc = new NodeLikeComments();
                    nlc.setNode(node);
                    try {
                        ActivityStreamingService as = ActivityStreamingServiceFactory.getInstance().getActivityStreamingService();
                        // Extract inforamtion required for ActivityStreaming API and Likes Tag
                        String resourceId = getResourceId(node);
                        String serviceId = VCRUtils.getStringProperty(node, UCMConstants.SERVICE_ID_PROP_DEF_NAME);
                        String resourceType = VCRUtils.getStringProperty(node, UCMConstants.RESOURCE_TYPE_PROP_DEF_NAME);
                        String name = node.getName();
                        ServiceObjectType serviceObjType = as.findObjectType(serviceId, resourceType);
                        ActivityObject activityObject = as.createObject(resourceId, serviceObjType, name);
                        activityObject.setServiceID(serviceId);
                        ActivityObject actObj = ActivityStreamingServiceFactory.getInstance().getActivityStreamingService().getObjectDetailsManager().getObjectDetail(activityObject);
                        // Extract all information using ActivityObject and node information
                        if (actObj != null) {
                            nlc = getCommentsLikesFromActivityObject(actObj, nlc);
                        } else {
                            // In case of not being registered yet the Id and the Type must to be provided
                            // FIXME: Current GUID or default GUID???? to be decided...
                            nlc.setScopeGUID(ServiceContext.getContext().getScope().getGUID());
                            //nlc.setScopeGUID(ServiceContext.getContext().getDefaultScope().getGUID());
                            nlc.setActivityId(activityObject.getId());
                            nlc.setActivityType(activityObject.getType().getName());
                        }
                    } catch (RepositoryException e) {
                        e.printStackTrace();
                    } catch (ActivityException e) {
                        e.printStackTrace();
                    }
                    return nlc;
                }

                /**
                 * Auxiliar method to get the resourceId expected from the content
                 * @param node
                 * @return [repositoryName]#dDocName:[dDocNameValue]
                 */
                private String getResourceId(Node node) {
                    String repository = node.getId().getRepositoryName();
                    String dDocName = node.getId().getUid();
                    return repository + "#dDocName:" + dDocName;
                }

                /**
                 * Extract and store likes and comments from an ActivityObject
                 * @param actObj with all content information about comments and Likes
                 * @param nlc NodeLikeComments to fill
                 */
                private NodeLikeComments getCommentsLikesFromActivityObject(ActivityObject actObj,
                                                                            NodeLikeComments nlc) {
                    int commentsCount = 0;
                    int likesCount = 0;
                    Like myLike = null;
                    List recentComments = null;
                    try {
                        // Retrieving all comments 
                        CommentsSummary commentsSummary = actObj.getCommentsSummary();
                        if (commentsSummary != null) {
                            commentsCount = commentsSummary.getCount();
                            recentComments = commentsSummary.getRecentComments();
                            for (Comment o : recentComments) {
                                // TODO: Testing API purpose
                                LOG.fine("Comment:" + o.toString());
//                                LOG.fine("AuthorId:" + o.getId());
//                                LOG.fine("CommentText:" + o.getCommentText());
//                                LOG.fine("Creation Date:" + o.getCreationDate());
                            }
                        }
                        LikesSummary likesSummary = actObj.getLikesSummary();
                        if (likesSummary != null) {
                            likesCount = likesSummary.getCount();
                            myLike = likesSummary.getMyLike();
                        }
                        nlc.setActivityType(actObj.getType().getName());
                        nlc.setActivityId(actObj.getId());
                        Scope scope = actObj.getScope();
                        if (scope != null) {
                            nlc.setScopeGUID(scope.getGUID());
                        } else {
                            nlc.setScopeGUID(ServiceContext.getContext().getDefaultScope().getGUID());
                        }
                        // nlc.setScopeGUID(actObj.getScope().getGUID());
                        //nlc.setScopeGUID(ServiceContext.getContext().getScope().getGUID());
                        nlc.setRecentComments(recentComments);
                        nlc.setCommentsCount(Integer.valueOf(commentsCount));
                        nlc.setLikesCount(Integer.valueOf(likesCount));
                        nlc.setMyLike(myLike);
                        if (LOG.isFinest()) {
                            LOG.finest(CLASS_NAME,"getCommentsLikes",nlc.toString());
                        }
                    } catch (ActivityException e) {
                        LOG.warning(CLASS_NAME,"getCommentsLikes","Error using Activity Stream API for Likes / Comments",e);
                    }
                    LOG.exiting(CLASS_NAME, "getCommentsLikes");
                    return nlc;
                }
            };
    }

    /**
     * Get map containing the nodes and likes associated to the content
     * @return Map
     */
    public Map getNodeLikesComments() {
        return nodeLikesComments;
    }
}


El API esta implementando de tal forma que se pueda acceder en modo Map / EL Expression.

Los parámetros requeridos por el TAG que implementa Likes (<likes:likesLink>) son:

ParámetroDescripciónTipo
idIdentificador del componenteString
renderedFlag que indica si el componente debe ser renderizadoBoolean
serviceIdIdentificador de servicio de WebCenter (Por ejemplo: oracle.webcenter.content, oracle.webcenter.doclib… para contenidos)String
objectTypeTipo de contenido. En caso de ser contenido de WebCenter Content puede ser: webContent, content, blog, wiki, folderString
objectIdIdentificador del objeto de la actividad. Por ejemplo para oracle.webcenter.content/doclib es [repoName]#dDocName:[dDocNameValue]String
scopeIdIdentificador del Portal / Espacio propietario el contenidoString
likesCountNúmero actual de LikesInt
myLikeLikes Services asociado con el usuario actualoracle.webcenter.likes.Like

La plantilla de ejemplo usada con Content Presenter es la siguiente.


    
        
            
            
            
            
            
            
            
            
            
            
            
         
        
    



Como se puede observar, se usa un Managed Bean que ha sido declarado customizando Content Presenter para usar el API implementado en LikesCommentsProcessor.

Al hacer Click en el botón de Like, éste funcionara de igual manera que el que puede aparecer en el Task Flow de Document Explorer.

Botón Like en Content Presenter

Además, el popup que muestra la información de usuarios que han hecho Like funciona perfectamente.

Popup con la gente que hizo Like

Cómo usarlo?

El proyecto despliega una librería compartida que debe ser registrada en el fichero de configuración weblogic.xml de WebCenter Portal / Framework Portal.

Además, (no incluído). Se ha customizado el Task Flow de Content Presenter para añadir un Managed Bean para invocar al API.

La plantilla de Content Presenter de la imagen es la misma que la del código mostrado.

No hay comentarios:

Publicar un comentario