All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.cq.social.scf.core.SocialEvent Maven / Gradle / Ivy

/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  Copyright 2013 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 **************************************************************************/

package com.adobe.cq.social.scf.core;

import java.io.Serializable;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.jackrabbit.util.Text;
import org.osgi.service.event.Event;

import com.adobe.cq.social.scf.core.SocialEvent.SocialActions;

/**
 * A generic class to define a Social Event and provide the basic framework and data exposed by
 *         events triggered by social actions. This class can be subtyped to define specific social events.
 * @param  type representing the actions supported by the SocialEvent
 */
public abstract class SocialEvent extends Event implements Serializable {

    private static final long serialVersionUID = 1L;
    protected static final Map EMPTY_MAP = new HashMap();

    /**
     * Describes the entity that performed the activity.
     */
    protected static final String USER_ID = "userId";
    /**
     * Identifies the action that the activity describes. An activity SHOULD contain a verb property whose value is a
     * String that is non-empty and matches either the "isegment-nz-nc" or the "IRI" production in [RFC3339]. Note
     * that the use of a relative reference other than a simple name is not allowed. If the verb is not specified, or
     * if the value is null, the verb is assumed to be "post".
     * {@link com.adobe.granite.activitystreams.Verbs}
     */
    protected static final String ACTION = "action";
    /**
     * Identifies the path of the object. This is here for backward compatibility. Use the object {@link EventObject}
     */
    protected static final String PATH = "path";
    /**
     * The target {@link EventObject} instance of this event.
     */
    public static String TARGET = "target";
    /**
     * Describes the primary object of the activity. An activity SHOULD contain an object property whose value is a
     * single Object.
     */
    public static String OBJECT = "object";

    /**
     * Representation of an event object. An activity has a primary object and a target activity. For instance, in the
     * activity, "John added a comment to the article", the object of the activity is "comment".
     */
    public interface EventObject {

        /**
         * Provides a permanent, universally unique identifier for the object. In our implementation, this should be
         * the path of the SCF component.
         * @return String id
         */
        String getId();

        /**
         * Provides the display name of the object.
         * @return String displayName
         */
        String getDisplayName();

        /**
         * Get object types
         * {@link com.adobe.granite.activitystreams.ObjectTypes}
         * @return String type
         */
        String getType();

        /**
         * Get the object metadata
         * @return Map properties map
         */
        Map getProperties();
    }

    /**
     * All {@link Event} instances created using SocialEvents will have an event topic starting with this string.
     */
    public static final String SOCIAL_EVENT_TOPIC_PREFIX = "com/adobe/cq/social/";

    /**
     * {@link com.adobe.granite.activitystreams.Verbs} for a list of predefined action.
     */
    public interface SocialActions {
        /**
         * Get the {@link com.adobe.granite.activitystreams.Verbs}
         * @return String
         */
        String getVerb();
    }

    /**
     * Default implementation of the {@link EventObject}
     *
     */
    public static class BaseEventObject implements EventObject {
        private final String displayName, id, objectType;
        private final Map properties;

        /**
         * Constructor
         * @param id String
         * @param objectType String
         */
        public BaseEventObject(final String id, final String objectType) {
            this(id, objectType, EMPTY_MAP);
        }

        /**
         * Constructor
         * @param id String
         * @param ObjectType String
         * @param properties Map
         */
        public BaseEventObject(final String id, final String ObjectType, final Map properties) {
            this(Text.getName(id), id, ObjectType, properties);
        }

        /**
         * Constructor
         * @param displayName String
         * @param id String
         * @param objectType String
         */
        public BaseEventObject(final String displayName, final String id, final String objectType) {
            this(displayName, id, objectType, new HashMap());
        }

        public BaseEventObject(final String displayName, final String id, final String objectType,
            final Map properties) {
            this.displayName = displayName;
            this.id = id;
            this.objectType = objectType;
            this.properties = properties;
        }

        @Override
        public String getDisplayName() {
            return displayName;
        }

        @Override
        public String getId() {
            return id;
        }

        @Override
        public String getType() {
            return objectType;
        }

        @Override
        public Map getProperties() {
            return properties;
        }
    }

    /**
     * This constructor should be used to create a Social Event given an OSGi Event.
     * @param event an OSGi event that is known to be a social event
     */
    public SocialEvent(final Event event) {
        super(event.getTopic(), buildPropertiesFromEvent(event));
    }

    private static Dictionary buildPropertiesFromEvent(final Event event) {
        final Dictionary props = new Hashtable(event.getPropertyNames().length);
        for (final String key : event.getPropertyNames()) {
            props.put(key, event.getProperty(key));
        }
        return props;
    }

    /**
     * @param topic - the topic string for the event.
     * @param path - the jcr node path where the event occurred.
     * @param userId - the user id of the user who triggered the event.
     * @param action - the action that was taken to trigger the event.
     * @param additionalData - a key value pair of any other data that should be part of the event payload.
     */
    public SocialEvent(final String topic, final String path, final String userId, final T action,
        final Map additionalData) {
        super(SOCIAL_EVENT_TOPIC_PREFIX + topic, buildProps(path, userId, action, null, null, additionalData));
    }

    public SocialEvent(final String topic, final String path, final String userId, final T action,
        final EventObject source, final EventObject destination, final Map additionalData) {
        super(SOCIAL_EVENT_TOPIC_PREFIX + topic,
            buildProps(path, userId, action, source, destination, additionalData));
    }

    private static Dictionary buildProps(final String path, final String userId,
        final SocialActions action, final EventObject object, final EventObject target,
        final Map additionalData) {
        int size = 5;
        if (null != additionalData) {
            size += additionalData.size();
        }
        final Dictionary props = new Hashtable(size);
        if (null != additionalData) {
            for (final Entry datum : additionalData.entrySet()) {
                props.put(datum.getKey(), datum.getValue());
            }
        }
        props.put(PATH, path);
        props.put(ACTION, action);
        props.put(USER_ID, userId);
        if (target != null) {
            props.put(TARGET, target);
        }
        if (object != null) {
            props.put(OBJECT, object);
        }
        return props;
    }

    /**
     * @return the user id of the user who triggered the event
     */
    public String getUserId() {
        return (String) this.getProperty(USER_ID);
    }

    /**
     * @return the action that triggered this event.
     */
    @SuppressWarnings("unchecked")
    public T getAction() {
        return (T) this.getProperty(ACTION);
    }

    /**
     * @return the jcr node path where this event occurred.
     */
    public String getPath() {
        return (String) this.getProperty(PATH);
    }

    /**
     * @return the {@link EventObject} Target of the activity.
     */
    public EventObject getTarget() {
        return (EventObject) getProperty(TARGET);
    }

    /**
     * @return the {@link EventObject} Object of the activity.
     */
    public EventObject getObject() {
        return (EventObject) getProperty(OBJECT);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy