/* * Copyright 2013 Jive Software * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * API for managing events. Use this to register event handlers for the various types of events emitted by the system, * and also for definining your custom events and handlers. @see {@link module:constants} for a list of emitted system events. * @module events */ /////////////////////////////////////////////////////////////////////////////////// // private var events = require('events'); var jive = require('../../api'); var pusher = require('../tile/dataPusher'); var comments = require('../tile/comments'); var regHandler = require('../tile/registration.js'); function addTargetedEventListener(eventListener, event, description, handler) { jive.logger.debug("Registered event for", eventListener, ": '" + event + "' ", description || ''); if (!exports.eventHandlerMap[eventListener]) { exports.eventHandlerMap[eventListener] = {}; } if (!exports.eventHandlerMap[eventListener][event]) { exports.eventHandlerMap[eventListener][event] = []; } // duplicate definition event listeners aren't permitted if (exports.eventHandlerMap[eventListener][event].indexOf(handler) == -1) { exports.eventHandlerMap[eventListener][event].push(handler); } else { jive.logger.warn("Event", event, "eventListener", eventListener, "already exists; ignoring event listener add."); } } function addUntargetedEventListener(event, description, handler) { jive.logger.debug("Registered system event ", event, ": ", description || 'no description'); if (!exports.eventHandlerMap[event]) { exports.eventHandlerMap[event] = []; } // duplicate system event listeners are permitted, tile-contributed // system event handlers exports.eventHandlerMap[event].push(handler); } /////////////////////////////////////////////////////////////////////////////////// // public exports = module.exports = new events.EventEmitter(); exports.eventHandlerMap = {}; /** * Add an event handler. The handler is invoked when an event is fired which * specifies the target event listener and event type, if both are specified in the event firing. * If only event is specified, then the handler will be invoked whenever that event is fired. * <br><br> * The handler is added to an array of handler functions assigned for the * event listener. Only one function per event listener per event is permitted. * @param {String} event - the event id * @param {function} handler - the function to call * @param {object} options * @param {String} options.eventListener the name of the listener * @param {String} options.description * */ exports.registerEventListener = function( event, handler, options) { if ( !event ) { throw new Error("Must specify a target event."); } if ( !handler ) { throw new Error("Must specify an event handler function."); } if ( typeof handler !== 'function' ) { throw new Error("Event handler must be a function."); } var targetListener; var description; if ( options ) { targetListener = options['eventListener']; description = options['description']; } if ( targetListener ) { addTargetedEventListener(targetListener, event, description, handler); } else { addUntargetedEventListener(event, description, handler ); } }; /** * Returns array of registered event handling functions for the given event listener and event. * Otherwise returns undefined. * @param {String} event * @param {String} eventListener * @returns {Array} */ exports.getEventListeners = function(event, eventListener) { if ( eventListener && event ) { if ( !exports.eventHandlerMap[eventListener] || !exports.eventHandlerMap[eventListener][event] ) { return null; } return exports.eventHandlerMap[eventListener][event]; } else { if ( eventListener && !event ) { var events = exports.eventHandlerMap[eventListener]; if ( !events ) { return null; } if ( events['indexOf'] ) { return events; } var handlers = []; for (var key in events) { if (events.hasOwnProperty(key)) { handlers.push(events[key]); } } return handlers; } else if ( !eventListener && event ) { var events = exports.eventHandlerMap; var handlers = []; for (var key in events) { if (events.hasOwnProperty(key)) { var listeners = events[key]; if ( listeners && !listeners['indexOf'] ) { var handler = listeners[event]; if ( handler ) { handlers.push(handler) } } } } return handlers; } else { return null; } } }; /** * Adds a local event handler. * @param {String} event * @param {function} handler */ exports.addLocalEventListener = function( event, handler ) { exports.addListener( event, function(context) { return handler(context, event); } ); }; /** * There are events that pusher nodes are allowed to handle. See {@link module:constants.tileEventNames}. * @private * @property {String} PUSH_DATA_TO_JIVE Fired on request to push tile data update to Jive. * @property {String} PUSH_ACTIVITY_TO_JIVE Fired on request to push externatstream activity to Jive. * @property {String} PUSH_COMMENT_TO_JIVE Fired on request to push a comment into Jive. */ exports.pushQueueEvents = [ jive.constants.tileEventNames.PUSH_DATA_TO_JIVE, jive.constants.tileEventNames.PUSH_ACTIVITY_TO_JIVE, jive.constants.tileEventNames.PUSH_COMMENT_TO_JIVE ]; /** * Array of system defined events. See {@link module:constants.globalEventNames}. * @private * @property {String} NEW_INSTANCE Fired when a new tile or externalstream instance is created. * @property {String} INSTANCE_UPDATED Fired when a tile or externalstream instance is updated. * @property {String} INSTANCE_REMOVED Fired when a tile or externalstream instance is destroyed. * @property {String} DATA_PUSHED Fired when a tile instance updated is pushed into Jive. * @property {String} ACTIVITY_PUSHED Fired when an externalstream instance is pushed into Jive. * @property {String} COMMENT_PUSHED Fired when an externalstream instance comment is pushed into Jive. * @property {String} CLIENT_APP_REGISTRATION_SUCCESS Fired when a community registers itself with the addon service successfully. * @property {String} CLIENT_APP_REGISTRATION_FAILED Fired when a community registers itself with the addon service unsuccessfully. */ exports.globalEvents = [ jive.constants.globalEventNames.NEW_INSTANCE, jive.constants.globalEventNames.INSTANCE_UPDATED, jive.constants.globalEventNames.INSTANCE_REMOVED, jive.constants.globalEventNames.DATA_PUSHED, jive.constants.globalEventNames.ACTIVITY_PUSHED, jive.constants.globalEventNames.COMMENT_PUSHED, jive.constants.globalEventNames.CLIENT_APP_REGISTRATION_SUCCESS, jive.constants.globalEventNames.CLIENT_APP_REGISTRATION_FAILED ]; /** * This is a map of system defined events to their respective event handlers. * @property {Object} NEW_INSTANCE Fired on request to push tile data update to Jive. * @property {function} NEW_INSTANCE.handler Logs the request context * @property {Object} INSTANCE_UPDATED Fired on request to push tile data update to Jive. * @property {function} INSTANCE_UPDATED.handler Logs the request context * @property {Object} INSTANCE_REMOVED Fired on request to push tile data update to Jive. * @property {function} INSTANCE_REMOVED.handler Logs the request context * @property {Object} PUSH_DATA_TO_JIVE Fired on request to push tile data update to Jive. * @property {function} PUSH_DATA_TO_JIVE.handler Passed <b>context</b> contains <i>theInstance</i> and <i>data</i> attributes. These are used * to push a tile update into Jive. * @property {Object} PUSH_ACTIVITY_TO_JIVE Fired on request to push externatstream activity to Jive. * @property {function} PUSH_ACTIVITY_TO_JIVE.handler Passed <b>context</b> contains <i>theInstance</i> and <i>activity</i> attributes. These are used * to push an extstreamstream activity entry into Jive. * @property {Object} PUSH_COMMENT_TO_JIVE Fired on request to push a comment into Jive. * @property {function} PUSH_COMMENT_TO_JIVE.handler Logs the request context * @property {Object} COMMENT_ON_ACTIVITY Fired on request to push a comment on an activity entry into Jive. * @property {function} COMMENT_ON_ACTIVITY.handler * @property {Object} COMMENT_ON_ACTIVITY_BY_EXTERNAL_ID Fired on request to push a comment on an activity entry into Jive. * @property {function} COMMENT_ON_ACTIVITY_BY_EXTERNAL_ID.handler * @property {Object} FETCH_COMMENTS_ON_ACTIVITY Fired on request for activity comments from Jive. * @property {function} FETCH_COMMENTS_ON_ACTIVITY.handler * @property {Object} FETCH_ALL_COMMENTS_FOR_EXT_STREAM Fired on request for activity comments from Jive. * @property {function} FETCH_ALL_COMMENTS_FOR_EXT_STREAM.handler * @property {Object} INSTANCE_REGISTRATION Fired on request to register a new tile or externalstream instance. * @property {function} INSTANCE_REGISTRATION.handler * @property {Object} INSTANCE_UNREGISTRATION Fired on request to destroy a tile or externalstream instance. * @property {function} INSTANCE_UNREGISTRATION.handler * @property {Object} CLIENT_APP_REGISTRATION Fired on request to register a Jive instance on the service. * @property {function} CLIENT_APP_REGISTRATION.handler * @property {Object} GET_PAGINATED_RESULTS Fired on request for paginated results from a Jive service. * @property {function} GET_PAGINATED_RESULTS.handler * @property {Object} GET_EXTERNAL_PROPS Fired on request for retrieving external props on a tile or externalstream instance. * @property {function} GET_EXTERNAL_PROPS.handler * @property {Object} SET_EXTERNAL_PROPS Fired on request for setting external props on a tile or externalstream instance. * @property {function} SET_EXTERNAL_PROPS.handler * @property {Object} DELETE_EXTERNAL_PROPS Fired on request for deleting external props on a tile or externalstream instance. * @property {function} DELETE_EXTERNAL_PROPS.handler */ exports.systemEvents = [ { 'event': jive.constants.globalEventNames.NEW_INSTANCE, 'handler' : function(context){ jive.logger.info("A new instance was created", context); }, 'description' : 'Framework handler' }, { 'event': jive.constants.globalEventNames.INSTANCE_UPDATED, 'handler' : function(context){ jive.logger.info("An instance was updated", context); }, 'description' : 'Framework handler' }, { 'event': jive.constants.globalEventNames.INSTANCE_REMOVED, 'handler' : function(context){ jive.logger.info("Instance has been destroyed", context); }, 'description' : 'Framework handler' }, { 'event': jive.constants.globalEventNames.DATA_PUSHED, 'handler' : function(context){ var theInstance = context['theInstance'], pushedData = context['pushedData'], response = context['response']; jive.logger.info('Data push to', theInstance.url, response ? response.statusCode : '', theInstance.name); }, 'description' : 'Framework handler' }, { 'event': jive.constants.globalEventNames.ACTIVITY_PUSHED, 'handler' : function(context){ var theInstance = context['theInstance'], pushedData = context['pushedData'], response = context['response']; jive.logger.info('Activity push to', theInstance.url, response ? response.statusCode : '', theInstance.name); }, 'description' : 'Framework handler' }, { 'event': jive.constants.globalEventNames.COMMENT_PUSHED, 'handler' : function(context){ var theInstance = context['theInstance'], pushedData = context['pushedData'], response = context['response']; jive.logger.info('Comment push to', theInstance.url, response ? response.statusCode : '', theInstance.name); }, 'description' : 'Framework handler' }, { 'event':jive.constants.tileEventNames.PUSH_DATA_TO_JIVE, 'handler':function(context) { var tileInstance = context['tileInstance']; var data = context['data']; return pusher.pushData(tileInstance, data); }, 'description' : 'Framework handler' }, { 'event':jive.constants.tileEventNames.PUSH_ACTIVITY_TO_JIVE, 'handler':function(context) { var tileInstance = context['tileInstance']; var activity = context['activity']; return pusher.pushActivity(tileInstance, activity); }, 'description' : 'Framework handler' }, { 'event':jive.constants.tileEventNames.PUSH_COMMENT_TO_JIVE, 'handler':function(context) { var tileInstance = context['tileInstance']; var commentURL = context['commentsURL']; var comment = context['comment']; return pusher.pushComment(tileInstance, commentURL, comment); }, 'description' : 'Framework handler' }, { 'event':jive.constants.tileEventNames.COMMENT_ON_ACTIVITY, 'handler':function(context) { var activity = context['activity']; var comment = context['comment']; return comments.commentOnActivity( activity, comment); }, 'description' : 'Framework handler' }, { 'event':jive.constants.tileEventNames.COMMENT_ON_ACTIVITY_BY_EXTERNAL_ID, 'handler':function(context) { var extstream = context['extstream']; var externalActivityID = context['externalActivityID']; var comment = context['comment']; return comments.commentOnActivityByExternalID( extstream, externalActivityID, comment ); }, 'description' : 'Framework handler' }, { 'event':jive.constants.tileEventNames.FETCH_COMMENTS_ON_ACTIVITY, 'handler':function(context) { var activity = context['activity']; var opts = context['opts']; return comments.fetchCommentsOnActivity( activity, opts ); }, 'description' : 'Framework handler' }, { 'event':jive.constants.tileEventNames.FETCH_ALL_COMMENTS_FOR_EXT_STREAM, 'handler':function(context) { var extstream = context['extstream']; var opts = context['opts']; return comments.fetchAllCommentsForExtstream( extstream, opts ); }, 'description' : 'Framework handler' }, { 'event':jive.constants.tileEventNames.INSTANCE_REGISTRATION, 'handler':function(context) { return regHandler.registration(context); } }, { 'event':jive.constants.tileEventNames.INSTANCE_UNREGISTRATION, 'handler':function(context) { return regHandler.unregistration(context); } }, { 'event':jive.constants.tileEventNames.CLIENT_APP_REGISTRATION, 'handler':function(context) { return jive.community.register(context); }, 'description' : 'Framework handler' }, { 'event': jive.constants.tileEventNames.GET_PAGINATED_RESULTS, 'handler':function(context) { return pusher.getPaginated( context['extstream'], context['commentsURL'] ); }, 'description' : 'Framework handler' }, { 'event': jive.constants.tileEventNames.GET_EXTERNAL_PROPS, 'handler':function(context) { return pusher.fetchExtendedProperties( context['instance'] ); }, 'description' : 'Framework handler' }, { 'event': jive.constants.tileEventNames.SET_EXTERNAL_PROPS, 'handler':function(context) { return pusher.pushExtendedProperties( context['instance'], context['props'] ); }, 'description' : 'Framework handler' }, { 'event': jive.constants.tileEventNames.DELETE_EXTERNAL_PROPS, 'handler':function(context) { return pusher.removeExtendedProperties( context['instance'] ); }, 'description' : 'Framework handler' } ]; /** * Removes all event handlers. */ exports.reset = function() { exports.eventHandlerMap = {}; exports.removeAllListeners(); };