NIHVIVO-3772 NIHVIVO-3721 Incorporate the OpenSocial integration from Eric Meeks at CTSI, UCSF. Add instructions on how to install and configure ORNG Shindig.
This commit is contained in:
parent
dfb955f39f
commit
f4e5c31aa8
13 changed files with 1851 additions and 1 deletions
190
opensocial/shindig.orng.properties
Normal file
190
opensocial/shindig.orng.properties
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you 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.
|
||||||
|
|
||||||
|
##################################################################
|
||||||
|
#
|
||||||
|
# Note from UCSF. Compare this to the latest in shindig-common/conf/shindig.properties
|
||||||
|
# whenever you download a new version of shindig
|
||||||
|
#
|
||||||
|
##################################################################
|
||||||
|
|
||||||
|
# Location of feature manifests (comma separated)
|
||||||
|
shindig.features.default=res://features/features.txt
|
||||||
|
|
||||||
|
# Location of container configurations (comma separated)
|
||||||
|
#shindig.containers.default=res://containers/default/container.js
|
||||||
|
shindig.containers.default=res://orng-container.js
|
||||||
|
|
||||||
|
# A file containing blacklisted gadgets.
|
||||||
|
shindig.blacklist.file=
|
||||||
|
|
||||||
|
### Inbound OAuth support
|
||||||
|
# The URL base to use for full OAuth support (three-legged)
|
||||||
|
shindig.oauth.base-url=/oauth/
|
||||||
|
shindig.oauth.authorize-action=/WEB-INF/authorize.jsp
|
||||||
|
|
||||||
|
### Outbound OAuth support
|
||||||
|
shindig.signing.state-key=
|
||||||
|
shindig.signing.key-name=
|
||||||
|
shindig.signing.key-file=
|
||||||
|
shindig.signing.global-callback-url=http://localhost:8080/shindigorng/gadgets/oauthcallback
|
||||||
|
shindig.signing.enable-signed-callbacks=true
|
||||||
|
|
||||||
|
# Set to true if you want to allow the use of 3-legged OAuth tokens when viewer != owner.
|
||||||
|
# This setting is not recommeneded for pages that allow user-controlled javascript, since
|
||||||
|
# that javascript could be used to make unauthorized requests on behalf of the viewer of the page
|
||||||
|
shindig.signing.viewer-access-tokens-enabled=false
|
||||||
|
|
||||||
|
# If enabled here, configuration values can be found in container configuration files.
|
||||||
|
shindig.locked-domain.enabled=false
|
||||||
|
|
||||||
|
# TODO: This needs to be moved to container configuration.
|
||||||
|
# Note by Eric. This is set up to now exclude everything and include nothing
|
||||||
|
shindig.content-rewrite.only-allow-excludes=false
|
||||||
|
shindig.content-rewrite.include-urls=.*
|
||||||
|
shindig.content-rewrite.exclude-urls=
|
||||||
|
shindig.content-rewrite.include-tags=body,embed,img,input,link,script,style
|
||||||
|
shindig.content-rewrite.expires=86400
|
||||||
|
shindig.content-rewrite.proxy-url=/shindigorng/gadgets/proxy?container=default&url=
|
||||||
|
shindig.content-rewrite.concat-url=/shindigorng/gadgets/concat?container=default&
|
||||||
|
shindig.content-rewrite.enable-split-js-concat=false
|
||||||
|
|
||||||
|
#
|
||||||
|
# Default set of forced libs to allow for better caching
|
||||||
|
#
|
||||||
|
# NOTE: setting this causes the EndToEnd test to fail the opensocial-templates test
|
||||||
|
shindig.gadget-rewrite.default-forced-libs=core:rpc
|
||||||
|
shindig.gadget-rewrite.default-forced-libs=
|
||||||
|
|
||||||
|
#
|
||||||
|
# Allow supported JavaScript features required by a gadget to be externalized on demand
|
||||||
|
shindig.gadget-rewrite.externalize-feature-libs=true
|
||||||
|
|
||||||
|
# Configuration for image rewriter
|
||||||
|
shindig.image-rewrite.max-inmem-bytes = 1048576
|
||||||
|
shindig.image-rewrite.max-palette-size = 256
|
||||||
|
shindig.image-rewrite.allow-jpeg-conversion = true
|
||||||
|
shindig.image-rewrite.jpeg-compression = 0.75
|
||||||
|
shindig.image-rewrite.min-threshold-bytes = 200
|
||||||
|
|
||||||
|
# Configuration for the os:Flash tag
|
||||||
|
shindig.flash.min-version = 9.0.115
|
||||||
|
|
||||||
|
# Configuration for template rewriter
|
||||||
|
shindig.template-rewrite.extension-tag-namespace=http://ns.opensocial.org/2009/extensions
|
||||||
|
|
||||||
|
# These values provide default TTLs for HTTP responses that don't use caching headers.
|
||||||
|
shindig.cache.http.defaultTtl=3600000
|
||||||
|
shindig.cache.http.negativeCacheTtl=60000
|
||||||
|
|
||||||
|
# A default refresh interval for XML files, since there is no natural way for developers to
|
||||||
|
# specify this value, and most HTTP responses don't include good cache control headers.
|
||||||
|
shindig.cache.xml.refreshInterval=300000
|
||||||
|
|
||||||
|
# Add entries in the form shindig.cache.lru.<name>.capacity to specify capacities for different
|
||||||
|
# caches when using the LruCacheProvider.
|
||||||
|
# It is highly recommended that the EhCache implementation be used instead of the LRU cache.
|
||||||
|
shindig.cache.lru.default.capacity=1000
|
||||||
|
shindig.cache.lru.expressions.capacity=1000
|
||||||
|
shindig.cache.lru.gadgetSpecs.capacity=1000
|
||||||
|
shindig.cache.lru.messageBundles.capacity=1000
|
||||||
|
shindig.cache.lru.httpResponses.capacity=10000
|
||||||
|
|
||||||
|
# The location of the EhCache configuration file.
|
||||||
|
shindig.cache.ehcache.config=res://org/apache/shindig/common/cache/ehcache/ehcacheConfig.xml
|
||||||
|
|
||||||
|
# True to enable JMX integration with cache stats
|
||||||
|
shindig.cache.ehcache.jmx.enabled=true
|
||||||
|
|
||||||
|
# true to enable JMX stats.
|
||||||
|
shindig.cache.ehcache.jmx.stats=true
|
||||||
|
|
||||||
|
# true to skip expensive encoding detection.
|
||||||
|
# if true, will only attempt to validate utf-8. Assumes all other encodings are ISO-8859-1.
|
||||||
|
shindig.http.fast-encoding-detection=true
|
||||||
|
|
||||||
|
# Configuration for the HttpFetcher
|
||||||
|
# Connection timeout, in milliseconds, for requests.
|
||||||
|
shindig.http.client.connection-timeout-ms=5000
|
||||||
|
|
||||||
|
# Maximum size, in bytes, of the object we fetched, 0 == no limit
|
||||||
|
shindig.http.client.max-object-size-bytes=0
|
||||||
|
|
||||||
|
# Strict-mode parsing for proxy and concat URIs ensures that the authority/host and path
|
||||||
|
# for the URIs match precisely what is found in the container config for it. This is
|
||||||
|
# useful where statistics and traffic routing patterns, typically in large installations,
|
||||||
|
# key on hostname (and occasionally path). Enforcing this does come at the cost that
|
||||||
|
# mismatches break, which in turn mandates that URI generation always happen in consistent
|
||||||
|
# fashion, ie. by the class itself or tightly controlled code.
|
||||||
|
shindig.uri.proxy.use-strict-parsing=false
|
||||||
|
shindig.uri.concat.use-strict-parsing=false
|
||||||
|
|
||||||
|
# Host:port of the proxy to use while fetching urls. Leave blank if proxy is
|
||||||
|
# not to be used.
|
||||||
|
org.apache.shindig.gadgets.http.basicHttpFetcherProxy=
|
||||||
|
|
||||||
|
org.apache.shindig.serviceExpirationDurationMinutes=60
|
||||||
|
|
||||||
|
#
|
||||||
|
# Older versions of shindig used 'data' in the json-rpc response format
|
||||||
|
# The spec calls for using 'result' instead, however to avoid breakage we
|
||||||
|
# allow you to set it back to the old way here
|
||||||
|
#
|
||||||
|
# valid values are
|
||||||
|
# result - new form
|
||||||
|
# data - old broken form
|
||||||
|
# both - return both fields for full compatibility
|
||||||
|
#
|
||||||
|
shindig.json-rpc.result-field=result
|
||||||
|
|
||||||
|
# Remap "Internal server error"s received from the basicHttpFetcherProxy server to
|
||||||
|
# "Bad Gateway error"s, so that it is clear to the user that the proxy server is
|
||||||
|
# the one that threw the exception.
|
||||||
|
shindig.accelerate.remapInternalServerError=true
|
||||||
|
shindig.proxy.remapInternalServerError=true
|
||||||
|
|
||||||
|
shindig.signing.key-file=/shindig/openssl/oauthkey.pem
|
||||||
|
shindig.signing.key-name=
|
||||||
|
|
||||||
|
####################################################################################
|
||||||
|
#
|
||||||
|
# Open Research Networking Gadgets Items
|
||||||
|
#
|
||||||
|
#####################################################################################
|
||||||
|
|
||||||
|
# orng.system must be set to Profiles or VIVO
|
||||||
|
#orng.system = Profiles
|
||||||
|
orng.system = VIVO
|
||||||
|
|
||||||
|
# orng.dbDriver is likely com.microsoft.sqlserver.jdbc.SQLServerDriver for Profiles and com.mysql.jdbc.Driver for VIVO
|
||||||
|
#orng.dbDriver = com.microsoft.sqlserver.jdbc.SQLServerDriver
|
||||||
|
orng.dbDriver = com.mysql.jdbc.Driver
|
||||||
|
orng.dbURL = jdbc:mysql://localhost/vitrodb
|
||||||
|
orng.dbUser = vitrodb
|
||||||
|
orng.dbPassword = vitrodb
|
||||||
|
orng.tokenservice.port = 8777
|
||||||
|
# orng.RDFConverter = elda | babel
|
||||||
|
orng.RDFConverter = elda
|
||||||
|
#orng.RDFConverter = babel
|
||||||
|
|
||||||
|
# until Profiles has RDF
|
||||||
|
orng.profilesXMLService = http://dev-profiles.ucsf.edu/api_100810/ProfileService.svc/ProfileSearch
|
||||||
|
orng.profilesRDF = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
28
opensocial/shindig_example_gadgets.sql
Normal file
28
opensocial/shindig_example_gadgets.sql
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
|
||||||
|
-- Add some gadgets to play with ------------------------
|
||||||
|
--
|
||||||
|
|
||||||
|
INSERT INTO `shindig_apps` (`appid`, `name`, `url`, `PersonFilterID`, `enabled`, `channels`) VALUES
|
||||||
|
(100, 'Google Search', 'http://dev-profiles.ucsf.edu/apps/GoogleSearch.xml', NULL, 1, NULL),
|
||||||
|
(101, 'Featured Presentations', 'http://dev-profiles.ucsf.edu/apps/SlideShare.xml', NULL, 1, NULL),
|
||||||
|
(102, 'Faculty Mentor', 'http://dev-profiles.ucsf.edu/apps/Mentor.xml', NULL, 1, NULL),
|
||||||
|
(103, 'Websites', 'http://dev-profiles.ucsf.edu/apps/Links.xml', NULL, 1, NULL),
|
||||||
|
(104, 'Profile List', 'http://dev-profiles.ucsf.edu/apps/ProfileListTool.xml', NULL, 1, 'JSONPersonIds'),
|
||||||
|
(105, 'Publication Export', 'http://dev-profiles.ucsf.edu/apps/PubExportTool.xml', NULL, 1, 'JSONPubMedIds'),
|
||||||
|
(106, 'RDF Test Gadget', 'http://dev-profiles.ucsf.edu/gadgets/RDFTest.xml', NULL, 1, NULL);
|
||||||
|
|
||||||
|
INSERT INTO `shindig_app_views` (`appid`, `viewer_req`, `owner_req`, `page`, `view`, `closed_width`, `open_width`, `start_closed`, `chromeId`, `display_order`) VALUES
|
||||||
|
(100, NULL, NULL, 'search', NULL, 600, 600, 1, 'gadgets-search', NULL),
|
||||||
|
(101, NULL, 'R', 'individual', 'profile', 291, 590, 1, 'gadgets-view', 3),
|
||||||
|
(101, NULL, NULL, 'individual-EDIT-MODE', 'home', 700, 700, 1, 'gadgets-edit', NULL),
|
||||||
|
(102, NULL, 'R', 'individual', 'profile', 291, 590, 1, 'gadgets-view', 2),
|
||||||
|
(102, NULL, NULL, 'individual-EDIT-MODE', 'home', 700, 700, 1, 'gadgets-edit', NULL),
|
||||||
|
(103, NULL, NULL, 'individual-EDIT-MODE', 'home', 700, 700, 1, 'gadgets-edit', NULL),
|
||||||
|
(103, NULL, 'R', 'individual', 'profile', 291, 590, 0, 'gadgets-view', 1),
|
||||||
|
(104, 'U', NULL, 'search', 'small', 160, 160, 0, 'gadgets-tools', NULL),
|
||||||
|
(104, 'U', NULL, 'gadgetDetails', 'canvas', 700, 700, 0, 'gadgets-detail', NULL),
|
||||||
|
(104, 'U', NULL, 'SimilarPeople.aspx', 'small', 160, 160, 0, 'gadgets-tools', NULL),
|
||||||
|
(104, 'U', NULL, 'individual', 'small', 160, 160, 0, 'gadgets-view', NULL),
|
||||||
|
(104, 'U', NULL, 'CoAuthors.aspx', 'small', 160, 160, 0, 'gadgets-tools', NULL),
|
||||||
|
(105, 'U', NULL, 'individual', 'small', 160, 160, 0, 'gadgets-view', NULL),
|
||||||
|
(105, 'U', NULL, 'gadgetDetails', 'canvas', 700, 700, 0, 'gadgets-detail', NULL);
|
145
opensocial/shindig_orng_tables.sql
Normal file
145
opensocial/shindig_orng_tables.sql
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `shindig_activity`
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `shindig_activity` (
|
||||||
|
`activityId` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`userId` varchar(255) default NULL,
|
||||||
|
`appId` int(11) default NULL,
|
||||||
|
`createdDT` datetime default NULL,
|
||||||
|
`activity` text,
|
||||||
|
PRIMARY KEY (`activityId`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||||
|
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `shindig_appdata`
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `shindig_appdata` (
|
||||||
|
`userId` varchar(255) NOT NULL,
|
||||||
|
`appId` int(11) NOT NULL,
|
||||||
|
`keyname` varchar(255) NOT NULL,
|
||||||
|
`value` varchar(4000) default NULL,
|
||||||
|
`createdDT` datetime default NULL,
|
||||||
|
`updatedDT` datetime default NULL,
|
||||||
|
KEY `userId` (`userId`,`appId`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||||
|
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `shindig_apps`
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `shindig_apps` (
|
||||||
|
`appid` int(11) NOT NULL,
|
||||||
|
`name` varchar(255) NOT NULL,
|
||||||
|
`url` varchar(255) NOT NULL,
|
||||||
|
`PersonFilterID` int(11) default NULL,
|
||||||
|
`enabled` tinyint(1) NOT NULL default '1',
|
||||||
|
`channels` varchar(255) default NULL,
|
||||||
|
PRIMARY KEY (`appid`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||||
|
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `shindig_app_registry`
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `shindig_app_registry` (
|
||||||
|
`appid` int(11) NOT NULL,
|
||||||
|
`personId` varchar(255) NOT NULL,
|
||||||
|
`createdDT` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`appid`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||||
|
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `shindig_app_views`
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `shindig_app_views` (
|
||||||
|
`appid` int(11) NOT NULL,
|
||||||
|
`viewer_req` char(1) default NULL,
|
||||||
|
`owner_req` char(1) default NULL,
|
||||||
|
`page` varchar(50) default NULL,
|
||||||
|
`view` varchar(50) default NULL,
|
||||||
|
`closed_width` int(11) default NULL,
|
||||||
|
`open_width` int(11) default NULL,
|
||||||
|
`start_closed` tinyint(1) default NULL,
|
||||||
|
`chromeId` varchar(50) default NULL,
|
||||||
|
`display_order` int(11) default NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||||
|
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `shindig_messages`
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `shindig_messages` (
|
||||||
|
`msgId` varchar(255) NOT NULL,
|
||||||
|
`senderId` varchar(255) default NULL,
|
||||||
|
`recipientId` varchar(255) default NULL,
|
||||||
|
`coll` varchar(255) default NULL,
|
||||||
|
`title` varchar(255) default NULL,
|
||||||
|
`body` varchar(4000) default NULL,
|
||||||
|
`createdDT` datetime default NULL,
|
||||||
|
PRIMARY KEY (`msgId`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||||
|
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
DELIMITER //
|
||||||
|
CREATE PROCEDURE shindig_registerAppPerson (uid varchar(255), aid INT, v BOOL)
|
||||||
|
BEGIN
|
||||||
|
IF (v)
|
||||||
|
THEN
|
||||||
|
INSERT INTO shindig_app_registry (appId, personId, createdDT) values (aid, uid, now());
|
||||||
|
ELSE
|
||||||
|
DELETE FROM shindig_app_registry where appId = aid AND personId = uid;
|
||||||
|
END IF;
|
||||||
|
END //
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
DELIMITER //
|
||||||
|
CREATE PROCEDURE shindig_upsertAppData(uid varchar(255), aid INT, kn varchar(255),v varchar(4000))
|
||||||
|
BEGIN
|
||||||
|
DECLARE cnt int;
|
||||||
|
SELECT count(*) FROM shindig_appdata WHERE userId = uid AND appId = aid and keyname = kn INTO cnt;
|
||||||
|
IF (cnt > 0)
|
||||||
|
THEN
|
||||||
|
UPDATE shindig_appdata set `value` = v, updatedDT = NOW() WHERE userId = uid AND appId = aid and keyname = kn;
|
||||||
|
ELSE
|
||||||
|
INSERT INTO shindig_appdata (userId, appId, keyname, `value`) values (uid, aid, kn, v);
|
||||||
|
END IF;
|
||||||
|
-- if keyname is VISIBLE, do more
|
||||||
|
IF (kn = 'VISIBLE' AND v = 'Y')
|
||||||
|
THEN
|
||||||
|
CALL shindig_registerAppPerson(uid, aid, 1);
|
||||||
|
ELSEIF (kn = 'VISIBLE' )
|
||||||
|
THEN
|
||||||
|
CALL shindig_registerAppPerson(uid, aid, 0);
|
||||||
|
END IF;
|
||||||
|
END //
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
DELIMITER //
|
||||||
|
CREATE PROCEDURE shindig_deleteAppData(uid varchar(255),aid INT, kn varchar(255))
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM shindig_appdata WHERE userId = uid AND appId = aid and keyname = kn;
|
||||||
|
-- if keyname is VISIBLE, do more
|
||||||
|
IF (kn = 'VISIBLE' )
|
||||||
|
THEN
|
||||||
|
CALL shindig_registerAppPerson(uid, aid, 0);
|
||||||
|
END IF;
|
||||||
|
END //
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
|
BIN
opensocial/shindigorng.war
Normal file
BIN
opensocial/shindigorng.war
Normal file
Binary file not shown.
|
@ -2,9 +2,15 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.controller.individual;
|
package edu.cornell.mannlib.vitro.webapp.controller.individual;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.json.JSONException;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
|
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||||
|
@ -22,6 +28,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.beanswrappers.ReadOnlyBeansWrapper;
|
import edu.cornell.mannlib.vitro.webapp.web.beanswrappers.ReadOnlyBeansWrapper;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.IndividualTemplateModel;
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.IndividualTemplateModel;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individuallist.ListedIndividual;
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individuallist.ListedIndividual;
|
||||||
|
import edu.ucsf.vitro.opensocial.OpenSocialManager;
|
||||||
import freemarker.ext.beans.BeansWrapper;
|
import freemarker.ext.beans.BeansWrapper;
|
||||||
import freemarker.template.TemplateModel;
|
import freemarker.template.TemplateModel;
|
||||||
import freemarker.template.TemplateModelException;
|
import freemarker.template.TemplateModelException;
|
||||||
|
@ -33,6 +40,9 @@ import freemarker.template.TemplateModelException;
|
||||||
* TODO clean this up.
|
* TODO clean this up.
|
||||||
*/
|
*/
|
||||||
class IndividualResponseBuilder {
|
class IndividualResponseBuilder {
|
||||||
|
private static final Log log = LogFactory
|
||||||
|
.getLog(IndividualResponseBuilder.class);
|
||||||
|
|
||||||
private static final Map<String, String> namespaces = new HashMap<String, String>() {{
|
private static final Map<String, String> namespaces = new HashMap<String, String>() {{
|
||||||
put("display", VitroVocabulary.DISPLAY);
|
put("display", VitroVocabulary.DISPLAY);
|
||||||
put("vitro", VitroVocabulary.vitroURI);
|
put("vitro", VitroVocabulary.vitroURI);
|
||||||
|
@ -78,6 +88,24 @@ class IndividualResponseBuilder {
|
||||||
//If special values required for individuals like menu, include values in template values
|
//If special values required for individuals like menu, include values in template values
|
||||||
body.putAll(getSpecialEditingValues());
|
body.putAll(getSpecialEditingValues());
|
||||||
|
|
||||||
|
// VIVO OpenSocial Extension by UCSF
|
||||||
|
try {
|
||||||
|
OpenSocialManager openSocialManager = new OpenSocialManager(vreq,
|
||||||
|
itm.isEditable() ? "individual-EDIT-MODE" : "individual", itm.isEditable());
|
||||||
|
openSocialManager.setPubsubData(OpenSocialManager.JSON_PERSONID_CHANNEL,
|
||||||
|
OpenSocialManager.buildJSONPersonIds(individual, "1 person found"));
|
||||||
|
body.put(OpenSocialManager.TAG_NAME, openSocialManager);
|
||||||
|
if (openSocialManager.isVisible()) {
|
||||||
|
body.put("bodyOnload", "my.init();");
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
log.error("JSONException in doTemplate()", e);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("IOException in doTemplate()", e);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("SQLException in doTemplate()", e);
|
||||||
|
}
|
||||||
|
|
||||||
String template = new IndividualTemplateLocator(vreq, individual).findTemplate();
|
String template = new IndividualTemplateLocator(vreq, individual).findTemplate();
|
||||||
|
|
||||||
return new TemplateResponseValues(template, body);
|
return new TemplateResponseValues(template, body);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
package edu.cornell.mannlib.vitro.webapp.search.controller;
|
package edu.cornell.mannlib.vitro.webapp.search.controller;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -51,6 +52,7 @@ import edu.cornell.mannlib.vitro.webapp.search.beans.VitroQueryFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.LinkTemplateModel;
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.LinkTemplateModel;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.searchresult.IndividualSearchResult;
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.searchresult.IndividualSearchResult;
|
||||||
|
import edu.ucsf.vitro.opensocial.OpenSocialManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Paged search controller that uses Solr
|
* Paged search controller that uses Solr
|
||||||
|
@ -268,6 +270,23 @@ public class PagedSearchController extends FreemarkerHttpServlet {
|
||||||
vreq.getServletPath(), pagingLinkParams));
|
vreq.getServletPath(), pagingLinkParams));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VIVO OpenSocial Extension by UCSF
|
||||||
|
try {
|
||||||
|
OpenSocialManager openSocialManager = new OpenSocialManager(vreq, "search");
|
||||||
|
// put list of people found onto pubsub channel
|
||||||
|
List<String> ids = OpenSocialManager.getOpenSocialId(individuals);
|
||||||
|
openSocialManager.setPubsubData(OpenSocialManager.JSON_PERSONID_CHANNEL,
|
||||||
|
OpenSocialManager.buildJSONPersonIds(ids, "" + ids.size() + " people found"));
|
||||||
|
body.put("openSocial", openSocialManager);
|
||||||
|
if (openSocialManager.isVisible()) {
|
||||||
|
body.put("bodyOnload", "my.init();");
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("IOException in doTemplate()", e);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("SQLException in doTemplate()", e);
|
||||||
|
}
|
||||||
|
|
||||||
String template = templateTable.get(format).get(Result.PAGED);
|
String template = templateTable.get(format).get(Result.PAGED);
|
||||||
|
|
||||||
return new TemplateResponseValues(template, body);
|
return new TemplateResponseValues(template, body);
|
||||||
|
|
100
webapp/src/edu/ucsf/vitro/opensocial/GadgetController.java
Normal file
100
webapp/src/edu/ucsf/vitro/opensocial/GadgetController.java
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
package edu.ucsf.vitro.opensocial;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ExceptionResponseValues;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.RedirectResponseValues;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||||
|
|
||||||
|
public class GadgetController extends FreemarkerHttpServlet {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private static final Log log = LogFactory.getLog(GadgetController.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ResponseValues processRequest(VitroRequest vreq) {
|
||||||
|
if (vreq.getServletPath().endsWith("/sandbox")) {
|
||||||
|
boolean sandbox = "True".equalsIgnoreCase(ConfigurationProperties.getBean(vreq.getSession()
|
||||||
|
.getServletContext()).getProperty("OpenSocial.sandbox"));
|
||||||
|
if (!sandbox) {
|
||||||
|
return new ExceptionResponseValues( new Exception("Sandbox not available"));
|
||||||
|
}
|
||||||
|
return processGadgetSandbox(vreq);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return processGadgetDetails(vreq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ResponseValues processGadgetDetails(VitroRequest vreq) {
|
||||||
|
try {
|
||||||
|
Map<String, Object> body = new HashMap<String, Object>();
|
||||||
|
|
||||||
|
body.put("title", "Gadget Details");
|
||||||
|
// VIVO OpenSocial Extension by UCSF
|
||||||
|
try {
|
||||||
|
OpenSocialManager openSocialManager = new OpenSocialManager(vreq, "gadgetDetails");
|
||||||
|
body.put(OpenSocialManager.TAG_NAME, openSocialManager);
|
||||||
|
if (openSocialManager.isVisible()) {
|
||||||
|
body.put("bodyOnload", "my.init();");
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("IOException in doTemplate()", e);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("SQLException in doTemplate()", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new TemplateResponseValues("gadgetDetails.ftl", body);
|
||||||
|
|
||||||
|
} catch (Throwable e) {
|
||||||
|
log.error(e, e);
|
||||||
|
return new ExceptionResponseValues(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getTitle(String siteName, VitroRequest vreq) {
|
||||||
|
return "Gadget Details";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ResponseValues processGadgetSandbox(VitroRequest vreq) {
|
||||||
|
if ("POST".equalsIgnoreCase(vreq.getMethod())) {
|
||||||
|
vreq.getSession().setAttribute(OpenSocialManager.OPENSOCIAL_GADGETS, vreq.getParameter("gadgetURLS"));
|
||||||
|
vreq.getSession().setAttribute(OpenSocialManager.OPENSOCIAL_DEBUG, vreq.getParameter("debug") != null);
|
||||||
|
vreq.getSession().setAttribute(OpenSocialManager.OPENSOCIAL_NOCACHE, vreq.getParameter("useCache") == null);
|
||||||
|
return new RedirectResponseValues("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> body = new HashMap<String, Object>();
|
||||||
|
body.put("title", "Gadget Sandbox");
|
||||||
|
|
||||||
|
try {
|
||||||
|
OpenSocialManager openSocialManager = new OpenSocialManager(vreq, "gadgetSandbox");
|
||||||
|
String gadgetURLS = "";
|
||||||
|
for (PreparedGadget gadget : openSocialManager.getVisibleGadgets())
|
||||||
|
{
|
||||||
|
gadgetURLS += gadget.getGadgetURL() + System.getProperty("line.separator");
|
||||||
|
}
|
||||||
|
body.put("gadgetURLS", gadgetURLS);
|
||||||
|
body.put(OpenSocialManager.TAG_NAME, openSocialManager);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("IOException in doTemplate()", e);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("SQLException in doTemplate()", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return new TemplateResponseValues("gadgetLogin.ftl", body);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
204
webapp/src/edu/ucsf/vitro/opensocial/GadgetSpec.java
Normal file
204
webapp/src/edu/ucsf/vitro/opensocial/GadgetSpec.java
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
package edu.ucsf.vitro.opensocial;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.dbcp.BasicDataSource;
|
||||||
|
|
||||||
|
public class GadgetSpec {
|
||||||
|
private String openSocialGadgetURL;
|
||||||
|
private String name;
|
||||||
|
private int appId = 0;
|
||||||
|
private List<String> channels = new ArrayList<String>();
|
||||||
|
private boolean unknownGadget = false;
|
||||||
|
private Map<String, GadgetViewRequirements> viewRequirements = new HashMap<String, GadgetViewRequirements>();
|
||||||
|
|
||||||
|
// For preloading
|
||||||
|
public GadgetSpec(int appId, String name, String openSocialGadgetURL,
|
||||||
|
List<String> channels) {
|
||||||
|
this.appId = appId;
|
||||||
|
this.name = name;
|
||||||
|
this.openSocialGadgetURL = openSocialGadgetURL;
|
||||||
|
this.channels.addAll(channels);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GadgetSpec(int appId, String name, String openSocialGadgetURL,
|
||||||
|
String channelsStr) {
|
||||||
|
this(appId, name, openSocialGadgetURL, Arrays.asList(channelsStr != null
|
||||||
|
&& channelsStr.length() > 0 ? channelsStr.split(" ") : new String[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public GadgetSpec(int appId, String name, String openSocialGadgetURL,
|
||||||
|
List<String> channels, boolean unknownGadget, BasicDataSource ds)
|
||||||
|
throws SQLException {
|
||||||
|
this(appId, name, openSocialGadgetURL, channels);
|
||||||
|
this.unknownGadget = unknownGadget;
|
||||||
|
// Load gadgets from the DB first
|
||||||
|
if (!unknownGadget) {
|
||||||
|
Connection conn = null;
|
||||||
|
Statement stmt = null;
|
||||||
|
ResultSet rset = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
String sqlCommand = "select page, viewer_req, owner_req, view, closed_width, open_width, start_closed, chromeId, display_order from shindig_app_views where appId = "
|
||||||
|
+ appId;
|
||||||
|
conn = ds.getConnection();
|
||||||
|
stmt = conn.createStatement();
|
||||||
|
rset = stmt.executeQuery(sqlCommand);
|
||||||
|
while (rset.next()) {
|
||||||
|
viewRequirements.put(
|
||||||
|
rset.getString(1),
|
||||||
|
new GadgetViewRequirements(rset.getString(1), rset
|
||||||
|
.getString(2), rset.getString(3), rset
|
||||||
|
.getString(4), rset.getInt(5), rset
|
||||||
|
.getInt(6), rset.getBoolean(7), rset
|
||||||
|
.getString(8), rset.getInt(9)));
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (rset != null) {
|
||||||
|
rset.close();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (stmt != null) {
|
||||||
|
stmt.close();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (conn != null) {
|
||||||
|
conn.close();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAppId() {
|
||||||
|
return appId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGadgetURL() {
|
||||||
|
return openSocialGadgetURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getChannels() {
|
||||||
|
return channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean listensTo(String channel) { // if an unknown gadget just say yes,
|
||||||
|
// we don't care about
|
||||||
|
// performance in this situation
|
||||||
|
return unknownGadget || channels.contains(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GadgetViewRequirements getGadgetViewRequirements(String page) {
|
||||||
|
if (viewRequirements.containsKey(page)) {
|
||||||
|
return viewRequirements.get(page);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean show(String viewerId, String ownerId, String page,
|
||||||
|
BasicDataSource ds) throws SQLException {
|
||||||
|
boolean show = true;
|
||||||
|
// if there are no view requirements, go ahead and show it. We are
|
||||||
|
// likely testing out a new gadget
|
||||||
|
// if there are some, turn it off unless this page is
|
||||||
|
if (viewRequirements.size() > 0) {
|
||||||
|
show = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (viewRequirements.containsKey(page)) {
|
||||||
|
show = true;
|
||||||
|
GadgetViewRequirements req = getGadgetViewRequirements(page);
|
||||||
|
if ('U' == req.getViewerReq() && viewerId != null) {
|
||||||
|
show = false;
|
||||||
|
} else if ('R' == req.getViewerReq()) {
|
||||||
|
show &= isRegisteredTo(viewerId, ds);
|
||||||
|
}
|
||||||
|
if ('R' == req.getOwnerReq()) {
|
||||||
|
show &= isRegisteredTo(ownerId, ds);
|
||||||
|
} else if ('S' == req.getOwnerReq()) {
|
||||||
|
show &= (viewerId == ownerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return show;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRegisteredTo(String personId, BasicDataSource ds)
|
||||||
|
throws SQLException {
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
Connection conn = null;
|
||||||
|
Statement stmt = null;
|
||||||
|
ResultSet rset = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
String sqlCommand = "select count(*) from shindig_app_registry where appId = "
|
||||||
|
+ getAppId() + " and personId = '" + personId + "';";
|
||||||
|
conn = ds.getConnection();
|
||||||
|
stmt = conn.createStatement();
|
||||||
|
rset = stmt.executeQuery(sqlCommand);
|
||||||
|
while (rset.next()) {
|
||||||
|
count = rset.getInt(1);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (rset != null) {
|
||||||
|
rset.close();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (stmt != null) {
|
||||||
|
stmt.close();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (conn != null) {
|
||||||
|
conn.close();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (count == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean fromSandbox() {
|
||||||
|
return unknownGadget;
|
||||||
|
}
|
||||||
|
|
||||||
|
// who sees it? Return the viewerReq for the ProfileDetails page
|
||||||
|
public char getVisibleScope() {
|
||||||
|
GadgetViewRequirements req = getGadgetViewRequirements("/display");
|
||||||
|
return req != null ? req.getViewerReq() : ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "" + this.appId + ":" + this.name + ":" + this.openSocialGadgetURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package edu.ucsf.vitro.opensocial;
|
||||||
|
|
||||||
|
public class GadgetViewRequirements {
|
||||||
|
private String page;
|
||||||
|
private char viewerReq; // U for User or null for no requirement
|
||||||
|
private char ownerReq; // R for Registered or null for no requirement
|
||||||
|
private String view;
|
||||||
|
private int closedWidth;
|
||||||
|
private int openWidth;
|
||||||
|
private boolean startClosed;
|
||||||
|
private String chromeId;
|
||||||
|
private int display_order;
|
||||||
|
|
||||||
|
public GadgetViewRequirements(String page, char viewerReq, char ownerReq,
|
||||||
|
String view, int closedWidth, int openWidth, boolean startClosed,
|
||||||
|
String chromeId, int display_order) {
|
||||||
|
this.page = page;
|
||||||
|
this.viewerReq = viewerReq;
|
||||||
|
this.ownerReq = ownerReq;
|
||||||
|
this.view = view;
|
||||||
|
this.closedWidth = closedWidth;
|
||||||
|
this.openWidth = openWidth;
|
||||||
|
this.startClosed = startClosed;
|
||||||
|
this.chromeId = chromeId;
|
||||||
|
this.display_order = display_order;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GadgetViewRequirements(String page, String viewerReq,
|
||||||
|
String ownerReq, String view, int closedWidth, int openWidth,
|
||||||
|
boolean startClosed, String chromeId, int display_order) {
|
||||||
|
this(page, viewerReq != null ? viewerReq.charAt(0) : ' ',
|
||||||
|
ownerReq != null ? ownerReq.charAt(0) : ' ', view, closedWidth,
|
||||||
|
openWidth, startClosed, chromeId, display_order);
|
||||||
|
}
|
||||||
|
|
||||||
|
public char getViewerReq() {
|
||||||
|
return viewerReq;
|
||||||
|
}
|
||||||
|
|
||||||
|
public char getOwnerReq() {
|
||||||
|
return ownerReq;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getView() {
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getClosedWidth() {
|
||||||
|
return closedWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOpenWidth() {
|
||||||
|
return openWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getStartClosed() {
|
||||||
|
return startClosed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChromeId() {
|
||||||
|
return chromeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getDisplayOrder() {
|
||||||
|
return display_order;
|
||||||
|
}
|
||||||
|
}
|
483
webapp/src/edu/ucsf/vitro/opensocial/OpenSocialManager.java
Normal file
483
webapp/src/edu/ucsf/vitro/opensocial/OpenSocialManager.java
Normal file
|
@ -0,0 +1,483 @@
|
||||||
|
package edu.ucsf.vitro.opensocial;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.dbcp.BasicDataSource;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.individual.IndividualRequestAnalysisContextImpl;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.individual.IndividualRequestAnalyzer;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.individual.IndividualRequestInfo;
|
||||||
|
|
||||||
|
public class OpenSocialManager {
|
||||||
|
public static final String SHINDIG_URL_PROP = "OpenSocial.shindigURL";
|
||||||
|
|
||||||
|
public static final String OPENSOCIAL_DEBUG = "OPENSOCIAL_DEBUG";
|
||||||
|
public static final String OPENSOCIAL_NOCACHE = "OPENSOCIAL_NOCACHE";
|
||||||
|
public static final String OPENSOCIAL_GADGETS = "OPENSOCIAL_GADGETS";
|
||||||
|
|
||||||
|
public static final String JSON_PERSONID_CHANNEL = "JSONPersonIds";
|
||||||
|
public static final String JSON_PMID_CHANNEL = "JSONPubMedIds";
|
||||||
|
public static final String TAG_NAME = "openSocial";
|
||||||
|
|
||||||
|
private static final String DEFAULT_DRIVER = "com.mysql.jdbc.Driver";
|
||||||
|
|
||||||
|
private List<PreparedGadget> gadgets = new ArrayList<PreparedGadget>();
|
||||||
|
private Map<String, String> pubsubdata = new HashMap<String, String>();
|
||||||
|
private String viewerId = null;
|
||||||
|
private String ownerId = null;
|
||||||
|
private boolean isDebug = false;
|
||||||
|
private boolean noCache = false;
|
||||||
|
private String pageName;
|
||||||
|
private ConfigurationProperties configuration;
|
||||||
|
|
||||||
|
private BasicDataSource dataSource;
|
||||||
|
|
||||||
|
public OpenSocialManager(VitroRequest vreq, String pageName) throws SQLException, IOException {
|
||||||
|
this(vreq, pageName, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenSocialManager(VitroRequest vreq, String pageName, boolean editMode) throws SQLException, IOException {
|
||||||
|
this.isDebug = vreq.getSession() != null
|
||||||
|
&& Boolean.TRUE.equals(vreq.getSession().getAttribute(OPENSOCIAL_DEBUG));
|
||||||
|
this.noCache = vreq.getSession() != null
|
||||||
|
&& Boolean.TRUE.equals(vreq.getSession().getAttribute(OPENSOCIAL_NOCACHE));
|
||||||
|
this.pageName = pageName;
|
||||||
|
|
||||||
|
configuration = ConfigurationProperties.getBean(vreq.getSession()
|
||||||
|
.getServletContext());
|
||||||
|
|
||||||
|
if (configuration.getProperty(SHINDIG_URL_PROP) == null) {
|
||||||
|
// do nothing
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Analyze the request to figure out whose page we are viewing.
|
||||||
|
this.ownerId = figureOwnerId(vreq);
|
||||||
|
|
||||||
|
// in editMode we need to set the viewer to be the same as the owner
|
||||||
|
// otherwise, the gadget will not be able to save appData correctly
|
||||||
|
if (editMode) {
|
||||||
|
this.viewerId = ownerId;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
UserAccount viewer = LoginStatusBean.getCurrentUser(vreq);
|
||||||
|
this.viewerId = viewer != null ? viewer.getUri() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean gadgetSandbox = "gadgetSandbox".equals(pageName);
|
||||||
|
String requestAppId = vreq.getParameter("appId");
|
||||||
|
|
||||||
|
Map<String, GadgetSpec> dbApps = new HashMap<String, GadgetSpec>();
|
||||||
|
Map<String, GadgetSpec> officialApps = new HashMap<String, GadgetSpec>();
|
||||||
|
|
||||||
|
dataSource = new BasicDataSource();
|
||||||
|
dataSource.setDriverClassName(DEFAULT_DRIVER);
|
||||||
|
dataSource.setUsername(configuration
|
||||||
|
.getProperty("VitroConnection.DataSource.username"));
|
||||||
|
dataSource.setPassword(configuration
|
||||||
|
.getProperty("VitroConnection.DataSource.password"));
|
||||||
|
dataSource.setUrl(configuration
|
||||||
|
.getProperty("VitroConnection.DataSource.url"));
|
||||||
|
|
||||||
|
// Load gadgets from the DB first
|
||||||
|
Connection conn = null;
|
||||||
|
Statement stmt = null;
|
||||||
|
ResultSet rset = null;
|
||||||
|
try {
|
||||||
|
|
||||||
|
String sqlCommand = "select appId, name, url, channels, enabled from shindig_apps";
|
||||||
|
// if a specific app is requested, only grab it
|
||||||
|
if (requestAppId != null) {
|
||||||
|
sqlCommand += " where appId = " + requestAppId;
|
||||||
|
}
|
||||||
|
conn = dataSource.getConnection();
|
||||||
|
stmt = conn.createStatement();
|
||||||
|
rset = stmt.executeQuery(sqlCommand);
|
||||||
|
|
||||||
|
while (rset.next()) {
|
||||||
|
GadgetSpec spec = new GadgetSpec(rset.getInt(1),
|
||||||
|
rset.getString(2), rset.getString(3), rset.getString(4));
|
||||||
|
String gadgetFileName = getGadgetFileNameFromURL(rset
|
||||||
|
.getString(3));
|
||||||
|
|
||||||
|
dbApps.put(gadgetFileName, spec);
|
||||||
|
if (requestAppId != null || rset.getBoolean(5)) {
|
||||||
|
officialApps.put(gadgetFileName, spec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (rset != null) {
|
||||||
|
rset.close();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (stmt != null) {
|
||||||
|
stmt.close();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (conn != null) {
|
||||||
|
conn.close();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add manual gadgets if there are any
|
||||||
|
// Note that this block of code only gets executed after someone fills in the
|
||||||
|
// gadget/sandbox form!
|
||||||
|
int moduleId = 0;
|
||||||
|
if (vreq.getSession() != null
|
||||||
|
&& vreq.getSession().getAttribute(OPENSOCIAL_GADGETS) != null) {
|
||||||
|
String openSocialGadgetURLS = (String) vreq.getSession()
|
||||||
|
.getAttribute(OPENSOCIAL_GADGETS);
|
||||||
|
String[] urls = openSocialGadgetURLS.split(System.getProperty("line.separator"));
|
||||||
|
for (String openSocialGadgetURL : urls) {
|
||||||
|
if (openSocialGadgetURL.length() == 0)
|
||||||
|
continue;
|
||||||
|
int appId = 0; // if URL matches one in the DB, use DB provided
|
||||||
|
// appId, otherwise generate one
|
||||||
|
String gadgetFileName = getGadgetFileNameFromURL(openSocialGadgetURL);
|
||||||
|
String name = gadgetFileName;
|
||||||
|
List<String> channels = new ArrayList<String>();
|
||||||
|
boolean unknownGadget = true;
|
||||||
|
if (dbApps.containsKey(gadgetFileName)) {
|
||||||
|
appId = dbApps.get(gadgetFileName).getAppId();
|
||||||
|
name = dbApps.get(gadgetFileName).getName();
|
||||||
|
channels = dbApps.get(gadgetFileName).getChannels();
|
||||||
|
unknownGadget = false;
|
||||||
|
} else {
|
||||||
|
appId = openSocialGadgetURL.hashCode();
|
||||||
|
}
|
||||||
|
// if they asked for a specific one, only let it in
|
||||||
|
if (requestAppId != null
|
||||||
|
&& Integer.getInteger(requestAppId) != appId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
GadgetSpec gadget = new GadgetSpec(appId, name,
|
||||||
|
openSocialGadgetURL, channels, unknownGadget, dataSource);
|
||||||
|
// only add ones that are visible in this context!
|
||||||
|
if (unknownGadget
|
||||||
|
|| gadget.show(viewerId, ownerId, pageName, dataSource)) {
|
||||||
|
String securityToken = socketSendReceive(viewerId, ownerId,
|
||||||
|
"" + gadget.getAppId());
|
||||||
|
gadgets.add(new PreparedGadget(gadget, this, moduleId++,
|
||||||
|
securityToken));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no manual one were added, use the ones from the DB
|
||||||
|
if (gadgets.size() == 0) {
|
||||||
|
// Load DB gadgets
|
||||||
|
if (gadgetSandbox) {
|
||||||
|
officialApps = dbApps;
|
||||||
|
}
|
||||||
|
for (GadgetSpec spec : officialApps.values()) {
|
||||||
|
GadgetSpec gadget = new GadgetSpec(spec.getAppId(),
|
||||||
|
spec.getName(), spec.getGadgetURL(),
|
||||||
|
spec.getChannels(), false, dataSource);
|
||||||
|
// only add ones that are visible in this context!
|
||||||
|
if (gadgetSandbox
|
||||||
|
|| gadget.show(viewerId, ownerId, pageName, dataSource)) {
|
||||||
|
String securityToken = socketSendReceive(viewerId, ownerId,
|
||||||
|
"" + gadget.getAppId());
|
||||||
|
gadgets.add(new PreparedGadget(gadget, this, moduleId++,
|
||||||
|
securityToken));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort the gadgets
|
||||||
|
Collections.sort(gadgets);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String figureOwnerId(VitroRequest vreq) {
|
||||||
|
IndividualRequestAnalyzer requestAnalyzer = new IndividualRequestAnalyzer(vreq,
|
||||||
|
new IndividualRequestAnalysisContextImpl(vreq));
|
||||||
|
IndividualRequestInfo requestInfo = requestAnalyzer.analyze();
|
||||||
|
Individual owner = requestInfo.getIndividual();
|
||||||
|
return owner != null ? owner.getURI() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getGadgetFileNameFromURL(String url) {
|
||||||
|
String[] urlbits = url.split("/");
|
||||||
|
return urlbits[urlbits.length - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDebug() {
|
||||||
|
return isDebug;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean noCache() {
|
||||||
|
return noCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOwnerId() {
|
||||||
|
return ownerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasGadgetListeningTo(String channel) {
|
||||||
|
for (PreparedGadget gadget : getVisibleGadgets()) {
|
||||||
|
if (gadget.getGadgetSpec().listensTo(channel)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> getOpenSocialId(List<Individual> individuals) {
|
||||||
|
List<String> personIds = new ArrayList<String>();
|
||||||
|
for (Individual ind : individuals) {
|
||||||
|
personIds.add(ind.getURI());
|
||||||
|
}
|
||||||
|
return personIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSON Helper Functions
|
||||||
|
public static String buildJSONPersonIds(List<String> personIds,
|
||||||
|
String message) throws JSONException {
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
json.put("message", message);
|
||||||
|
json.put("personIds", personIds);
|
||||||
|
return json.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String buildJSONPersonIds(String personId, String message) throws JSONException {
|
||||||
|
List<String> personIds = new ArrayList<String>();
|
||||||
|
personIds.add(personId);
|
||||||
|
return buildJSONPersonIds(personIds, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String buildJSONPersonIds(Individual ind, String message) throws JSONException {
|
||||||
|
List<String> personIds = new ArrayList<String>();
|
||||||
|
personIds.add(ind.getURI());
|
||||||
|
return buildJSONPersonIds(personIds, message);
|
||||||
|
}
|
||||||
|
/****
|
||||||
|
* public static String BuildJSONPubMedIds(Person person) { List<Int32>
|
||||||
|
* pubIds = new List<Int32>(); foreach (Publication pub in
|
||||||
|
* person.PublicationList) { foreach (PublicationSource pubSource in
|
||||||
|
* pub.PublicationSourceList) { if ("PubMed".Equals(pubSource.Name)) {
|
||||||
|
* pubIds.Add(Int32.Parse(pubSource.ID)); } } } Dictionary<string, Object>
|
||||||
|
* foundPubs = new Dictionary<string, object>(); foundPubs.Add("pubIds",
|
||||||
|
* pubIds); foundPubs.Add("message", "PubMedIDs for " +
|
||||||
|
* person.Name.FullName); JavaScriptSerializer serializer = new
|
||||||
|
* JavaScriptSerializer(); return serializer.Serialize(foundPubs); }
|
||||||
|
***/
|
||||||
|
|
||||||
|
public void setPubsubData(String key, String value) {
|
||||||
|
if (pubsubdata.containsKey(key)) {
|
||||||
|
pubsubdata.remove(key);
|
||||||
|
}
|
||||||
|
if (value != null && !value.isEmpty()) {
|
||||||
|
pubsubdata.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getPubsubData() {
|
||||||
|
return pubsubdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removePubsubGadgetsWithoutData() {
|
||||||
|
// if any visible gadgets depend on pubsub data that isn't present,
|
||||||
|
// throw them out
|
||||||
|
List<PreparedGadget> removedGadgets = new ArrayList<PreparedGadget>();
|
||||||
|
for (PreparedGadget gadget : gadgets) {
|
||||||
|
for (String channel : gadget.getGadgetSpec().getChannels()) {
|
||||||
|
if (!pubsubdata.containsKey(channel)) {
|
||||||
|
removedGadgets.add(gadget);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (PreparedGadget gadget : removedGadgets) {
|
||||||
|
gadgets.remove(gadget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeGadget(String name) {
|
||||||
|
// if any visible gadgets depend on pubsub data that isn't present,
|
||||||
|
// throw them out
|
||||||
|
PreparedGadget gadgetToRemove = null;
|
||||||
|
for (PreparedGadget gadget : gadgets) {
|
||||||
|
if (name.equals(gadget.getName())) {
|
||||||
|
gadgetToRemove = gadget;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gadgets.remove(gadgetToRemove);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPageName() {
|
||||||
|
return pageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIdToUrlMapJavascript() {
|
||||||
|
String retval = "var idToUrlMap = {";
|
||||||
|
for (PreparedGadget gadget : gadgets) {
|
||||||
|
// retval += gadget.GetAppId() + ":'" + gadget.GetGadgetURL() +
|
||||||
|
// "', ";
|
||||||
|
retval += "'remote_iframe_" + gadget.getAppId() + "':'"
|
||||||
|
+ gadget.getGadgetURL() + "', ";
|
||||||
|
}
|
||||||
|
return retval.substring(0, retval.length() - 2) + "};";
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isVisible() {
|
||||||
|
// always have turned on for ProfileDetails.aspx because we want to
|
||||||
|
// generate the "profile was viewed" in Javascript (bot proof)
|
||||||
|
// regardless of any gadgets being visible, and we need this to be True
|
||||||
|
// for the shindig javascript libraries to load
|
||||||
|
return (configuration.getProperty(SHINDIG_URL_PROP) != null
|
||||||
|
&& (getVisibleGadgets().size() > 0) || getPageName().equals(
|
||||||
|
"/display"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PreparedGadget> getVisibleGadgets() {
|
||||||
|
return gadgets;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postActivity(int userId, String title) throws SQLException {
|
||||||
|
postActivity(userId, title, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postActivity(int userId, String title, String body) throws SQLException {
|
||||||
|
postActivity(userId, title, body, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postActivity(int userId, String title, String body,
|
||||||
|
String xtraId1Type, String xtraId1Value) throws SQLException {
|
||||||
|
Connection conn = null;
|
||||||
|
Statement stmt = null;
|
||||||
|
String sqlCommand = "INSERT INTO shindig_activity (userId, activity, xtraId1Type, xtraId1Value) VALUES ('"
|
||||||
|
+ userId + "','<activity xmlns=\"http://ns.opensocial.org/2008/opensocial\"><postedTime>"
|
||||||
|
+ System.currentTimeMillis() + "</postedTime><title>" + title + "</title>"
|
||||||
|
+ (body != null ? "<body>" + body + "</body>" : "") + "</activity>','"
|
||||||
|
+ xtraId1Type + "','" + xtraId1Value + "');";
|
||||||
|
try {
|
||||||
|
conn = dataSource.getConnection();
|
||||||
|
stmt = conn.createStatement();
|
||||||
|
stmt.executeUpdate(sqlCommand);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (stmt != null) {
|
||||||
|
stmt.close();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (conn != null) {
|
||||||
|
conn.close();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String socketSendReceive(String viewer, String owner, String gadget)
|
||||||
|
throws IOException {
|
||||||
|
// These keys need to match what you see in
|
||||||
|
// edu.ucsf.orng.shindig.service.SecureTokenGeneratorService in
|
||||||
|
// Shindig
|
||||||
|
String[] tokenService = configuration.getProperty(
|
||||||
|
"OpenSocial.tokenService").split(":");
|
||||||
|
String request = "c=default" + (viewer != null ? "&v=" + URLEncoder.encode(viewer, "UTF-8") : "") +
|
||||||
|
(owner != null ? "&o=" + URLEncoder.encode(owner, "UTF-8") : "") + "&g=" + gadget + "\r\n";
|
||||||
|
|
||||||
|
// Create a socket connection with the specified server and port.
|
||||||
|
Socket s = new Socket(tokenService[0],
|
||||||
|
Integer.parseInt(tokenService[1]));
|
||||||
|
|
||||||
|
// Send request to the server.
|
||||||
|
s.getOutputStream().write(request.getBytes());
|
||||||
|
|
||||||
|
// Receive the encoded content.
|
||||||
|
int bytes = 0;
|
||||||
|
String page = "";
|
||||||
|
byte[] bytesReceived = new byte[256];
|
||||||
|
|
||||||
|
// The following will block until the page is transmitted.
|
||||||
|
while ((bytes = s.getInputStream().read(bytesReceived)) > 0) {
|
||||||
|
page += new String(bytesReceived, 0, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContainerJavascriptSrc() {
|
||||||
|
return configuration.getProperty(SHINDIG_URL_PROP)
|
||||||
|
+ "/gadgets/js/core:dynamic-height:osapi:pubsub:rpc:views:shindig-container.js?c=1"
|
||||||
|
+ (isDebug ? "&debug=1" : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGadgetJavascript() {
|
||||||
|
String lineSeparator = System.getProperty("line.separator");
|
||||||
|
String gadgetScriptText = lineSeparator
|
||||||
|
+ "var my = {};"
|
||||||
|
+ lineSeparator
|
||||||
|
+ "my.gadgetSpec = function(appId, name, url, secureToken, view, closed_width, open_width, start_closed, chrome_id, visible_scope) {"
|
||||||
|
+ lineSeparator + "this.appId = appId;" + lineSeparator
|
||||||
|
+ "this.name = name;" + lineSeparator + "this.url = url;"
|
||||||
|
+ lineSeparator + "this.secureToken = secureToken;"
|
||||||
|
+ lineSeparator + "this.view = view || 'default';"
|
||||||
|
+ lineSeparator + "this.closed_width = closed_width;"
|
||||||
|
+ lineSeparator + "this.open_width = open_width;"
|
||||||
|
+ lineSeparator + "this.start_closed = start_closed;"
|
||||||
|
+ lineSeparator + "this.chrome_id = chrome_id;" + lineSeparator
|
||||||
|
+ "this.visible_scope = visible_scope;" + lineSeparator + "};"
|
||||||
|
+ lineSeparator + "my.pubsubData = {};" + lineSeparator;
|
||||||
|
for (String key : getPubsubData().keySet()) {
|
||||||
|
gadgetScriptText += "my.pubsubData['" + key + "'] = '"
|
||||||
|
+ getPubsubData().get(key) + "';" + lineSeparator;
|
||||||
|
}
|
||||||
|
gadgetScriptText += "my.openSocialURL = '"
|
||||||
|
+ configuration.getProperty(SHINDIG_URL_PROP) + "';"
|
||||||
|
+ lineSeparator + "my.debug = " + (isDebug() ? "1" : "0") + ";"
|
||||||
|
+ lineSeparator + "my.noCache = " + (noCache() ? "1" : "0")
|
||||||
|
+ ";" + lineSeparator + "my.gadgets = [";
|
||||||
|
for (PreparedGadget gadget : getVisibleGadgets()) {
|
||||||
|
gadgetScriptText += "new my.gadgetSpec(" + gadget.getAppId() + ",'"
|
||||||
|
+ gadget.getName() + "','" + gadget.getGadgetURL() + "','"
|
||||||
|
+ gadget.getSecurityToken() + "','" + gadget.getView()
|
||||||
|
+ "'," + gadget.getClosedWidth() + ","
|
||||||
|
+ gadget.getOpenWidth() + ","
|
||||||
|
+ (gadget.getStartClosed() ? "1" : "0") + ",'"
|
||||||
|
+ gadget.getChromeId() + "','"
|
||||||
|
+ gadget.getGadgetSpec().getVisibleScope() + "'), ";
|
||||||
|
}
|
||||||
|
gadgetScriptText = gadgetScriptText.substring(0,
|
||||||
|
gadgetScriptText.length() - 2)
|
||||||
|
+ "];"
|
||||||
|
+ lineSeparator;
|
||||||
|
|
||||||
|
return gadgetScriptText;
|
||||||
|
}
|
||||||
|
}
|
123
webapp/src/edu/ucsf/vitro/opensocial/PreparedGadget.java
Normal file
123
webapp/src/edu/ucsf/vitro/opensocial/PreparedGadget.java
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
package edu.ucsf.vitro.opensocial;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
|
||||||
|
public class PreparedGadget implements Comparable<PreparedGadget> {
|
||||||
|
private GadgetSpec gadgetSpec;
|
||||||
|
private OpenSocialManager helper;
|
||||||
|
private int moduleId;
|
||||||
|
private String securityToken;
|
||||||
|
|
||||||
|
public PreparedGadget(GadgetSpec gadgetSpec, OpenSocialManager helper,
|
||||||
|
int moduleId, String securityToken) {
|
||||||
|
this.gadgetSpec = gadgetSpec;
|
||||||
|
this.helper = helper;
|
||||||
|
this.moduleId = moduleId;
|
||||||
|
this.securityToken = securityToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compareTo(PreparedGadget other) {
|
||||||
|
GadgetViewRequirements gvr1 = this.getGadgetViewRequirements();
|
||||||
|
GadgetViewRequirements gvr2 = other.getGadgetViewRequirements();
|
||||||
|
return ("" + this.getView() + (gvr1 != null ? gvr1.getDisplayOrder()
|
||||||
|
: Integer.MAX_VALUE)).compareTo("" + other.getView()
|
||||||
|
+ (gvr2 != null ? gvr2.getDisplayOrder() : Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
public GadgetSpec getGadgetSpec() {
|
||||||
|
return gadgetSpec;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSecurityToken() {
|
||||||
|
return securityToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAppId() {
|
||||||
|
return gadgetSpec.getAppId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return gadgetSpec.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getModuleId() {
|
||||||
|
return moduleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGadgetURL() {
|
||||||
|
return gadgetSpec.getGadgetURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
GadgetViewRequirements getGadgetViewRequirements() {
|
||||||
|
return gadgetSpec.getGadgetViewRequirements(helper.getPageName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getView() {
|
||||||
|
GadgetViewRequirements reqs = getGadgetViewRequirements();
|
||||||
|
if (reqs != null) {
|
||||||
|
return reqs.getView();
|
||||||
|
}
|
||||||
|
// default behavior that will get invoked when there is no reqs. Useful
|
||||||
|
// for sandbox gadgets
|
||||||
|
else if (helper.getPageName().equals("individual-EDIT-MODE")) {
|
||||||
|
return "home";
|
||||||
|
} else if (helper.getPageName().equals("individual")) {
|
||||||
|
return "profile";
|
||||||
|
} else if (helper.getPageName().equals("gadgetDetails")) {
|
||||||
|
return "canvas";
|
||||||
|
} else if (gadgetSpec.getGadgetURL().contains("Tool")) {
|
||||||
|
return "small";
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOpenWidth() {
|
||||||
|
GadgetViewRequirements reqs = getGadgetViewRequirements();
|
||||||
|
return reqs != null ? reqs.getOpenWidth() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getClosedWidth() {
|
||||||
|
GadgetViewRequirements reqs = getGadgetViewRequirements();
|
||||||
|
return reqs != null ? reqs.getClosedWidth() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getStartClosed() {
|
||||||
|
GadgetViewRequirements reqs = getGadgetViewRequirements();
|
||||||
|
// if the page specific reqs are present, honor those. Otherwise defaut
|
||||||
|
// to true for regular gadgets, false for sandbox gadgets
|
||||||
|
return reqs != null ? reqs.getStartClosed() : !gadgetSpec.fromSandbox();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChromeId() {
|
||||||
|
GadgetViewRequirements reqs = getGadgetViewRequirements();
|
||||||
|
if (reqs != null) {
|
||||||
|
return reqs.getChromeId();
|
||||||
|
}
|
||||||
|
// default behavior that will get invoked when there is no reqs. Useful
|
||||||
|
// for sandbox gadgets
|
||||||
|
else if (gadgetSpec.getGadgetURL().contains("Tool")) {
|
||||||
|
return "gadgets-tools";
|
||||||
|
} else if (helper.getPageName().equals("individual-EDIT-MODE")) {
|
||||||
|
return "gadgets-edit";
|
||||||
|
} else if (helper.getPageName().equals("individual")) {
|
||||||
|
return "gadgets-view";
|
||||||
|
} else if (helper.getPageName().equals("gadgetDetails")) {
|
||||||
|
return "gadgets-detail";
|
||||||
|
} else if (helper.getPageName().equals("search")) {
|
||||||
|
return "gadgets-search";
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCanvasURL() throws UnsupportedEncodingException {
|
||||||
|
return "~/gadget?appId=" + getAppId() + "&Person="
|
||||||
|
+ URLEncoder.encode(helper.getOwnerId(), "UTF-8");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "" + this.moduleId + ", (" + this.gadgetSpec.toString() + ")";
|
||||||
|
}
|
||||||
|
}
|
|
@ -1300,6 +1300,20 @@
|
||||||
<url-pattern>/admin/getObjectClasses</url-pattern>
|
<url-pattern>/admin/getObjectClasses</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<!-- VIVO OpenSocial Extension by UCSF -->
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>GadgetController</servlet-name>
|
||||||
|
<servlet-class>edu.ucsf.vitro.opensocial.GadgetController</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>GadgetController</servlet-name>
|
||||||
|
<url-pattern>/gadget</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>GadgetController</servlet-name>
|
||||||
|
<url-pattern>/gadget/sandbox</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
<!-- ==================== tag libraries ============================== -->
|
<!-- ==================== tag libraries ============================== -->
|
||||||
<jsp-config>
|
<jsp-config>
|
||||||
<taglib>
|
<taglib>
|
||||||
|
|
449
webapp/web/js/openSocial/shindig.js
Normal file
449
webapp/web/js/openSocial/shindig.js
Normal file
|
@ -0,0 +1,449 @@
|
||||||
|
/*
|
||||||
|
Profiles Shindig Helper functions for gadget-to-container commands
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// dummy function so google analytics does not break for institutions who do not use it
|
||||||
|
|
||||||
|
_gaq = {};
|
||||||
|
_gaq.push = function(data) { //
|
||||||
|
};
|
||||||
|
|
||||||
|
// pubsub
|
||||||
|
gadgets.pubsubrouter.init(function(id) {
|
||||||
|
return my.gadgets[shindig.container.gadgetService.getGadgetIdFromModuleId(id)].url;
|
||||||
|
}, {
|
||||||
|
onSubscribe: function(sender, channel) {
|
||||||
|
setTimeout("my.onSubscribe('" + sender + "', '" + channel + "')", 3000);
|
||||||
|
// return true to reject the request.
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
onUnsubscribe: function(sender, channel) {
|
||||||
|
//alert(sender + " unsubscribes from channel '" + channel + "'");
|
||||||
|
// return true to reject the request.
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
onPublish: function(sender, channel, message) {
|
||||||
|
// return true to reject the request.
|
||||||
|
|
||||||
|
// track with google analytics
|
||||||
|
if (sender != '..' ) {
|
||||||
|
var moduleId = shindig.container.gadgetService.getGadgetIdFromModuleId(sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channel == 'VISIBLE') {
|
||||||
|
var statusId = document.getElementById(sender + '_status');
|
||||||
|
if (statusId) {
|
||||||
|
// only act on these in HOME view since they are only meant to be seen when viewer=owner
|
||||||
|
if (my.gadgets[moduleId].view != 'home') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (message == 'Y') {
|
||||||
|
statusId.style.color = 'GREEN';
|
||||||
|
statusId.innerHTML = 'This section is VISIBLE';
|
||||||
|
if (my.gadgets[moduleId].visible_scope == 'U') {
|
||||||
|
statusId.innerHTML += ' to UCSF';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
statusId.innerHTML += ' to the public';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
statusId.style.color = '#CC0000';
|
||||||
|
statusId.innerHTML = 'This section is HIDDEN';
|
||||||
|
if (my.gadgets[moduleId].visible_scope == 'U') {
|
||||||
|
statusId.innerHTML += ' from UCSF';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
statusId.innerHTML += ' from the public';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (channel == 'added' && my.gadgets[moduleId].view == 'home') {
|
||||||
|
if (message == 'Y') {
|
||||||
|
_gaq.push(['_trackEvent', my.gadgets[moduleId].name, 'SHOW', 'profile_edit_view']);
|
||||||
|
osapi.activities.create(
|
||||||
|
{ 'userId': gadgets.util.getUrlParameters()['Person'],
|
||||||
|
'appId': my.gadgets[moduleId].appId,
|
||||||
|
'activity': {'postedTime': new Date().getTime(), 'title': 'added a gadget', 'body': 'added the ' + my.gadgets[moduleId].name + ' gadget to their profile' }
|
||||||
|
}).execute(function(response){});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_gaq.push(['_trackEvent', my.gadgets[moduleId].name, 'HIDE', 'profile_edit_view']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (channel == 'status') {
|
||||||
|
// message should be of the form 'COLOR:Message Content'
|
||||||
|
var statusId = document.getElementById(sender + '_status');
|
||||||
|
if (statusId) {
|
||||||
|
var messageSplit = message.split(':');
|
||||||
|
if (messageSplit.length == 2) {
|
||||||
|
statusId.style.color = messageSplit[0];
|
||||||
|
statusId.innerHTML = messageSplit[1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
statusId.innerHTML = message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (channel == 'analytics') {
|
||||||
|
// publish to google analytics
|
||||||
|
// message should be JSON encoding object with required action and optional label and value
|
||||||
|
// as documented here: http://code.google.com/apis/analytics/docs/tracking/eventTrackerGuide.html
|
||||||
|
// note that event category will be set to the gadget name automatically by this code
|
||||||
|
// Note: message will be already converted to an object
|
||||||
|
if (message.hasOwnProperty('value')) {
|
||||||
|
_gaq.push(['_trackEvent', my.gadgets[moduleId].name, message.action, message.label, message.value]);
|
||||||
|
}
|
||||||
|
else if (message.hasOwnProperty('label')) {
|
||||||
|
_gaq.push(['_trackEvent', my.gadgets[moduleId].name, message.action, message.label]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_gaq.push(['_trackEvent', my.gadgets[moduleId].name, message.action]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (channel == 'profile') {
|
||||||
|
_gaq.push(['_trackEvent', my.gadgets[moduleId].name, 'go_to_profile', message]);
|
||||||
|
document.location.href = '/' + location.pathname.split('/')[1] + '/display/n' + message;
|
||||||
|
}
|
||||||
|
else if (channel == 'JSONPersonIds' || channel == 'JSONPubMedIds') {
|
||||||
|
// do nothing, no need to alert
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
alert(sender + " publishes '" + message + "' to channel '" + channel + "'");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// helper functions
|
||||||
|
my.findGadgetsAttachingTo = function(chromeId) {
|
||||||
|
var retval = [];
|
||||||
|
for (var i = 0; i < my.gadgets.length; i++) {
|
||||||
|
if (my.gadgets[i].chrome_id == chromeId) {
|
||||||
|
retval[retval.length] = my.gadgets[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
};
|
||||||
|
|
||||||
|
my.removeGadgets = function(gadgetsToRemove) {
|
||||||
|
for (var i = 0; i < gadgetsToRemove.length; i++) {
|
||||||
|
for (var j = 0; j < my.gadgets.length; j++) {
|
||||||
|
if (gadgetsToRemove[i].url == my.gadgets[j].url) {
|
||||||
|
my.gadgets.splice(j, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
my.onSubscribe = function(sender, channel) {
|
||||||
|
// lookup pubsub data based on channel and if a match is found, publish the data to that channel after a delay
|
||||||
|
if (my.pubsubData[channel]) {
|
||||||
|
gadgets.pubsubrouter.publish(channel, my.pubsubData[channel]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
alert(sender + " subscribes to channel '" + channel + "'");
|
||||||
|
}
|
||||||
|
//PageMethods.onSubscribe(sender, channel, my.pubsubHint, my.CallSuccess, my.CallFailed);
|
||||||
|
};
|
||||||
|
|
||||||
|
my.removeParameterFromURL = function(url, parameter) {
|
||||||
|
var urlparts= url.split('?'); // prefer to use l.search if you have a location/link object
|
||||||
|
if (urlparts.length>=2) {
|
||||||
|
var prefix= encodeURIComponent(parameter)+'=';
|
||||||
|
var pars= urlparts[1].split(/[&;]/g);
|
||||||
|
for (var i= pars.length; i-->0;) //reverse iteration as may be destructive
|
||||||
|
if (pars[i].lastIndexOf(prefix, 0)!==-1) //idiom for string.startsWith
|
||||||
|
pars.splice(i, 1);
|
||||||
|
url= urlparts[0]+'?'+pars.join('&');
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
};
|
||||||
|
|
||||||
|
// publish the people
|
||||||
|
my.CallSuccess = function(result) {
|
||||||
|
gadgets.pubsubrouter.publish('person', result);
|
||||||
|
};
|
||||||
|
|
||||||
|
// alert message on some failure
|
||||||
|
my.CallFailed = function(error) {
|
||||||
|
alert(error.get_message());
|
||||||
|
};
|
||||||
|
|
||||||
|
my.requestGadgetMetaData = function(view, opt_callback) {
|
||||||
|
var request = {
|
||||||
|
context: {
|
||||||
|
country: "default",
|
||||||
|
language: "default",
|
||||||
|
view: view,
|
||||||
|
ignoreCache : my.noCache,
|
||||||
|
container: "default"
|
||||||
|
},
|
||||||
|
gadgets: []
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var moduleId = 0; moduleId < my.gadgets.length; moduleId++) {
|
||||||
|
// only add those with matching views
|
||||||
|
if (my.gadgets[moduleId].view == view) {
|
||||||
|
request.gadgets[request.gadgets.length] = {'url': my.gadgets[moduleId].url, 'moduleId': moduleId};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var makeRequestParams = {
|
||||||
|
"CONTENT_TYPE" : "JSON",
|
||||||
|
"METHOD" : "POST",
|
||||||
|
"POST_DATA" : gadgets.json.stringify(request)};
|
||||||
|
|
||||||
|
gadgets.io.makeNonProxiedRequest(my.openSocialURL + "/gadgets/metadata",
|
||||||
|
function(data) {
|
||||||
|
data = data.data;
|
||||||
|
if (opt_callback) {
|
||||||
|
opt_callback(data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
makeRequestParams,
|
||||||
|
"application/javascript"
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
my.renderableGadgets = [];
|
||||||
|
|
||||||
|
my.generateGadgets = function(metadata) {
|
||||||
|
// put them in moduleId order
|
||||||
|
for (var i = 0; i < metadata.gadgets.length; i++) {
|
||||||
|
var moduleId = metadata.gadgets[i].moduleId;
|
||||||
|
// Notes by Eric. Not sure if I should have to calculate this myself, but I will.
|
||||||
|
var height = metadata.gadgets[i].height;
|
||||||
|
var width = metadata.gadgets[i].width;
|
||||||
|
var viewPrefs = metadata.gadgets[i].views[my.gadgets[moduleId].view];
|
||||||
|
if (viewPrefs) {
|
||||||
|
height = viewPrefs.preferredHeight || height;
|
||||||
|
width = viewPrefs.preferredWidth || width;
|
||||||
|
}
|
||||||
|
my.renderableGadgets[moduleId] = shindig.container.createGadget({'specUrl': metadata.gadgets[i].url, 'secureToken': my.gadgets[moduleId].secureToken,
|
||||||
|
'title': metadata.gadgets[i].title, 'userPrefs': metadata.gadgets[i].userPrefs,
|
||||||
|
'height': height, 'width': width, 'debug': my.debug});
|
||||||
|
// set the metadata for easy access
|
||||||
|
my.renderableGadgets[moduleId].setMetadata(metadata.gadgets[i]);
|
||||||
|
}
|
||||||
|
// this will be called multiple times, only render when all gadgets have been processed
|
||||||
|
var ready = my.renderableGadgets.length == my.gadgets.length;
|
||||||
|
for (var i = 0; ready && i < my.renderableGadgets.length; i++) {
|
||||||
|
if (!my.renderableGadgets[i]) {
|
||||||
|
ready = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ready) {
|
||||||
|
shindig.container.addGadgets(my.renderableGadgets );
|
||||||
|
shindig.container.renderGadgets();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
my.init = function() {
|
||||||
|
// overwrite this RPC function. Do it at this level so that rpc.f (this.f) is accessible for getting module ID
|
||||||
|
// gadgets.rpc.register('requestNavigateTo', doProfilesNavigation);
|
||||||
|
|
||||||
|
shindig.container.gadgetClass = ProfilesGadget;
|
||||||
|
shindig.container.layoutManager = new ProfilesLayoutManager();
|
||||||
|
shindig.container.setNoCache(my.noCache);
|
||||||
|
shindig.container.gadgetService = new ProfilesGadgetService();
|
||||||
|
|
||||||
|
// since we render multiple views, we need to do somethign fancy by swapping out this value in getIframeUrl
|
||||||
|
shindig.container.setView('REPLACE_THIS_VIEW');
|
||||||
|
|
||||||
|
// do multiple times as needed if we have multiple views
|
||||||
|
// find out what views are being used and call requestGadgetMetaData for each one
|
||||||
|
var views = {};
|
||||||
|
for (var moduleId = 0; moduleId < my.gadgets.length; moduleId++) {
|
||||||
|
var view = my.gadgets[moduleId].view;
|
||||||
|
if (!views[view]) {
|
||||||
|
views[view] = view;
|
||||||
|
my.requestGadgetMetaData(view, my.generateGadgets);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ProfilesGadgetService
|
||||||
|
|
||||||
|
ProfilesGadgetService = function() {
|
||||||
|
shindig.IfrGadgetService.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
ProfilesGadgetService.inherits(shindig.IfrGadgetService);
|
||||||
|
|
||||||
|
ProfilesGadgetService.prototype.requestNavigateTo = function(view, opt_params) {
|
||||||
|
var urlTemplate = gadgets.config.get('views')[view].urlTemplate;
|
||||||
|
var url = urlTemplate || 'OpenSocial.aspx?';
|
||||||
|
|
||||||
|
url += window.location.search.substring(1);
|
||||||
|
|
||||||
|
// remove appId if present
|
||||||
|
url = my.removeParameterFromURL(url, 'appId');
|
||||||
|
|
||||||
|
// Add appId if the URL Template begins with the word 'gadget'
|
||||||
|
if (urlTemplate.toLowerCase().indexOf('gadget') == 0) {
|
||||||
|
var moduleId = shindig.container.gadgetService.getGadgetIdFromModuleId(this.f);
|
||||||
|
var appId = my.gadgets[moduleId].appId;
|
||||||
|
url += (url.indexOf('?') != url.length - 1 ? '&' : '') + 'appId=' + appId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt_params) {
|
||||||
|
var paramStr = gadgets.json.stringify(opt_params);
|
||||||
|
if (paramStr.length > 0) {
|
||||||
|
url += (url.indexOf('?') != url.length - 1 ? '&' : '') + 'appParams=' + encodeURIComponent(paramStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (url && document.location.href.indexOf(url) == -1) {
|
||||||
|
document.location.href = url;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ProfilesGadget
|
||||||
|
|
||||||
|
ProfilesGadget = function(opt_params) {
|
||||||
|
shindig.Gadget.call(this, opt_params);
|
||||||
|
this.debug = my.debug;
|
||||||
|
this.serverBase_ = my.openSocialURL + "/gadgets/";
|
||||||
|
var gadget = this;
|
||||||
|
var subClass = shindig.IfrGadget;
|
||||||
|
this.metadata = {};
|
||||||
|
for (var name in subClass) if (subClass.hasOwnProperty(name)) {
|
||||||
|
if (name == 'getIframeUrl') {
|
||||||
|
// we need to keep this old one
|
||||||
|
gadget['originalGetIframeUrl'] = subClass[name];
|
||||||
|
}
|
||||||
|
else if (name != 'finishRender') {
|
||||||
|
gadget[name] = subClass[name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ProfilesGadget.inherits(shindig.BaseIfrGadget);
|
||||||
|
|
||||||
|
ProfilesGadget.prototype.setMetadata = function(metadata) {
|
||||||
|
this.metadata = metadata;
|
||||||
|
};
|
||||||
|
|
||||||
|
ProfilesGadget.prototype.hasFeature = function(feature) {
|
||||||
|
for (var i = 0; i < this.metadata.features.length; i++) {
|
||||||
|
if (this.metadata.features[i] == feature) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
ProfilesGadget.prototype.getAdditionalParams = function() {
|
||||||
|
var params = '';
|
||||||
|
for (var key in my.gadgets[this.id].additionalParams) {
|
||||||
|
params += '&' + key + '=' + my.gadgets[this.id].additionalParams[key];
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
ProfilesGadget.prototype.finishRender = function(chrome) {
|
||||||
|
window.frames[this.getIframeId()].location = this.getIframeUrl();
|
||||||
|
if (my.gadgets[this.id].start_closed) {
|
||||||
|
this.handleToggle();
|
||||||
|
}
|
||||||
|
else if (chrome) {
|
||||||
|
// set the gadget box width, and remember that we always render as open
|
||||||
|
chrome.style.width = (my.gadgets[this.id].open_width || 600) + 'px';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ProfilesGadget.prototype.getIframeUrl = function() {
|
||||||
|
var url = this.originalGetIframeUrl();
|
||||||
|
return url.replace('REPLACE_THIS_VIEW', my.gadgets[this.id].view);
|
||||||
|
};
|
||||||
|
|
||||||
|
ProfilesGadget.prototype.handleToggle = function() {
|
||||||
|
var gadgetIframe = document.getElementById(this.getIframeId());
|
||||||
|
if (gadgetIframe) {
|
||||||
|
var gadgetContent = gadgetIframe.parentNode;
|
||||||
|
var gadgetImg = document.getElementById('gadgets-gadget-title-image-' + this.id);
|
||||||
|
if (gadgetContent.style.display) {
|
||||||
|
//OPEN
|
||||||
|
gadgetContent.parentNode.style.width = (my.gadgets[this.id].open_width || 600) + 'px';
|
||||||
|
gadgetContent.style.display = '';
|
||||||
|
gadgetImg.src = '/' + location.pathname.split('/')[1] + '/themes/opensocial/images/openSocial/icon_squareDownArrow.gif';
|
||||||
|
// refresh if certain features require so
|
||||||
|
//if (this.hasFeature('dynamic-height')) {
|
||||||
|
if (my.gadgets[this.id].chrome_id == 'gadgets-search') {
|
||||||
|
this.refresh();
|
||||||
|
document.getElementById(this.getIframeId()).contentWindow.location.reload(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (my.gadgets[this.id].view == 'home') {
|
||||||
|
// record in google analytics
|
||||||
|
_gaq.push(['_trackEvent', my.gadgets[this.id].name, 'OPEN_IN_EDIT', 'profile_edit_view']);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
osapi.activities.create(
|
||||||
|
{ 'userId': gadgets.util.getUrlParameters()['Person'],
|
||||||
|
'appId': my.gadgets[this.id].appId,
|
||||||
|
'activity': {'postedTime': new Date().getTime(), 'title': 'gadget viewed', 'body': my.gadgets[this.id].name + ' gadget was viewed' }
|
||||||
|
}).execute(function(response){});
|
||||||
|
// record in google analytics
|
||||||
|
_gaq.push(['_trackEvent', my.gadgets[this.id].name, 'OPEN']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//CLOSE
|
||||||
|
gadgetContent.parentNode.style.width = (my.gadgets[this.id].closed_width || 600) + 'px';
|
||||||
|
gadgetContent.style.display = 'none';
|
||||||
|
gadgetImg.src = '/' + location.pathname.split('/')[1] + '/themes/opensocial/images/openSocial/icon_squareArrow.gif';
|
||||||
|
if (my.gadgets[this.id].view == 'home') {
|
||||||
|
// record in google analytics
|
||||||
|
_gaq.push(['_trackEvent', my.gadgets[this.id].name, 'CLOSE_IN_EDIT', 'profile_edit_view']);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// record in google analytics
|
||||||
|
_gaq.push(['_trackEvent', my.gadgets[this.id].name, 'CLOSE']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ProfilesGadget.prototype.getTitleBarContent = function(continuation) {
|
||||||
|
if (my.gadgets[this.id].view == 'canvas') {
|
||||||
|
document.getElementById("gadgets-title").innerHTML = (this.title ? this.title : 'Gadget');
|
||||||
|
continuation('<span class="gadgets-gadget-canvas-title"></span>');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
continuation(
|
||||||
|
'<div id="' + this.cssClassTitleBar + '-' + this.id +
|
||||||
|
'" class="' + this.cssClassTitleBar + '"><span class="' +
|
||||||
|
this.cssClassTitleButtonBar + '">' +
|
||||||
|
'<a href="#" onclick="shindig.container.getGadget(' + this.id +
|
||||||
|
').handleToggle();return false;" class="' + this.cssClassTitleButton +
|
||||||
|
'"><img id="gadgets-gadget-title-image-' + this.id + '" src="/' + location.pathname.split('/')[1] + '/themes/opensocial/images/openSocial/icon_squareDownArrow.gif"/></a></span> <span id="' +
|
||||||
|
this.getIframeId() + '_title" class="' + this.cssClassTitle + '">' +
|
||||||
|
'<a href="#" onclick="shindig.container.getGadget(' + this.id + ').handleToggle();return false;">' +
|
||||||
|
(this.title ? this.title : 'Gadget') + '</a>' + '</span><span id="' +
|
||||||
|
this.getIframeId() + '_status" class="gadgets-gadget-status"></span></div>');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ProfilesLayoutManager. Creates a FloatLeftLayoutManager for every chromeId in our gadgets
|
||||||
|
ProfilesLayoutManager = function() {
|
||||||
|
shindig.LayoutManager.call(this);
|
||||||
|
// find out what chromeId's are being used, create a FloatLeftLayoutManager for each
|
||||||
|
this.layoutManagers = {};
|
||||||
|
for (var moduleId = 0; moduleId < my.gadgets.length; moduleId++) {
|
||||||
|
var chromeId = my.gadgets[moduleId].chrome_id;
|
||||||
|
if (!this.layoutManagers[chromeId]) {
|
||||||
|
this.layoutManagers[chromeId] = new shindig.FloatLeftLayoutManager(chromeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ProfilesLayoutManager.inherits(shindig.LayoutManager);
|
||||||
|
|
||||||
|
ProfilesLayoutManager.prototype.getGadgetChrome = function(gadget) {
|
||||||
|
return this.layoutManagers[my.gadgets[gadget.id].chrome_id].getGadgetChrome(gadget);
|
||||||
|
};
|
Loading…
Add table
Reference in a new issue