added linkedIn Public Profile URL import
git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portlets/user/social-profile@100139 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
8e829f6fd7
commit
417fe2d580
5
pom.xml
5
pom.xml
|
@ -84,6 +84,11 @@
|
||||||
<groupId>com.googlecode.json-simple</groupId>
|
<groupId>com.googlecode.json-simple</groupId>
|
||||||
<artifactId>json-simple</artifactId>
|
<artifactId>json-simple</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.eliasbalasis</groupId>
|
||||||
|
<artifactId>tibcopagebus4gwt</artifactId>
|
||||||
|
<version>1.2.0</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.gcube.applicationsupportlayer</groupId>
|
<groupId>org.gcube.applicationsupportlayer</groupId>
|
||||||
<artifactId>aslcore</artifactId>
|
<artifactId>aslcore</artifactId>
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
package org.gcube.portlets.user.socialprofile.client;
|
package org.gcube.portlets.user.socialprofile.client;
|
||||||
|
|
||||||
|
import net.eliasbalasis.tibcopagebus4gwt.client.PageBusAdapter;
|
||||||
|
import net.eliasbalasis.tibcopagebus4gwt.client.PageBusAdapterException;
|
||||||
|
import net.eliasbalasis.tibcopagebus4gwt.testsubscriber.client.Person;
|
||||||
|
import net.eliasbalasis.tibcopagebus4gwt.testsubscriber.client.PersonJsonizer;
|
||||||
|
|
||||||
import org.gcube.portal.databook.client.GCubeSocialNetworking;
|
import org.gcube.portal.databook.client.GCubeSocialNetworking;
|
||||||
import org.gcube.portal.databook.client.util.Encoder;
|
import org.gcube.portal.databook.client.util.Encoder;
|
||||||
import org.gcube.portlets.user.socialprofile.client.ui.DisplayProfile;
|
import org.gcube.portlets.user.socialprofile.client.ui.DisplayProfile;
|
||||||
|
@ -7,13 +12,13 @@ import org.gcube.portlets.user.socialprofile.client.ui.DisplaySummary;
|
||||||
import org.gcube.portlets.user.socialprofile.client.ui.ErrorAlert;
|
import org.gcube.portlets.user.socialprofile.client.ui.ErrorAlert;
|
||||||
import org.gcube.portlets.user.socialprofile.client.ui.OkAlert;
|
import org.gcube.portlets.user.socialprofile.client.ui.OkAlert;
|
||||||
import org.gcube.portlets.user.socialprofile.shared.UserContext;
|
import org.gcube.portlets.user.socialprofile.shared.UserContext;
|
||||||
|
import org.jsonmaker.gwt.client.Jsonizer;
|
||||||
|
|
||||||
import com.google.gwt.core.client.EntryPoint;
|
import com.google.gwt.core.client.EntryPoint;
|
||||||
import com.google.gwt.core.client.GWT;
|
import com.google.gwt.core.client.GWT;
|
||||||
import com.google.gwt.user.client.Cookies;
|
import com.google.gwt.user.client.Cookies;
|
||||||
import com.google.gwt.user.client.Window;
|
import com.google.gwt.user.client.Window;
|
||||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||||
import com.google.gwt.user.client.ui.HTML;
|
|
||||||
import com.google.gwt.user.client.ui.RootPanel;
|
import com.google.gwt.user.client.ui.RootPanel;
|
||||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||||
|
|
||||||
|
@ -23,6 +28,7 @@ import com.google.gwt.user.client.ui.VerticalPanel;
|
||||||
public class SocialProfile implements EntryPoint {
|
public class SocialProfile implements EntryPoint {
|
||||||
|
|
||||||
private final SocialServiceAsync socialService = GWT.create(SocialService.class);
|
private final SocialServiceAsync socialService = GWT.create(SocialService.class);
|
||||||
|
private final PageBusAdapter pageBusAdapter = new PageBusAdapter();
|
||||||
|
|
||||||
private VerticalPanel mainPanel = new VerticalPanel();
|
private VerticalPanel mainPanel = new VerticalPanel();
|
||||||
private DisplayProfile dispProfile = new DisplayProfile();
|
private DisplayProfile dispProfile = new DisplayProfile();
|
||||||
|
@ -32,10 +38,10 @@ public class SocialProfile implements EntryPoint {
|
||||||
String authorizationCode = checkLinkedInAuthZ();
|
String authorizationCode = checkLinkedInAuthZ();
|
||||||
if (authorizationCode != null) {
|
if (authorizationCode != null) {
|
||||||
mainPanel.add(new OkAlert("Authorization OK! Please wait while we import from LinkedIn ... ", false));
|
mainPanel.add(new OkAlert("Authorization OK! Please wait while we import from LinkedIn ... ", false));
|
||||||
socialService.fetchUserProfile(authorizationCode, DisplayProfile.getRedirectURI(), new AsyncCallback<Boolean>() {
|
socialService.fetchUserProfile(authorizationCode, DisplayProfile.getRedirectURI(), new AsyncCallback<String>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Boolean result) {
|
public void onSuccess(String result) {
|
||||||
if (!result) {
|
if (result == null) {
|
||||||
mainPanel.clear();
|
mainPanel.clear();
|
||||||
mainPanel.add(new ErrorAlert("Something went wrong while parsing your professional summary from LinkedIn, please report the issue.", true));
|
mainPanel.add(new ErrorAlert("Something went wrong while parsing your professional summary from LinkedIn, please report the issue.", true));
|
||||||
displayProfile();
|
displayProfile();
|
||||||
|
@ -44,6 +50,8 @@ public class SocialProfile implements EntryPoint {
|
||||||
mainPanel.clear();
|
mainPanel.clear();
|
||||||
mainPanel.add(new OkAlert("Your data have been imported successfully, anything you want to edit or add? Please use Edit Profile Manually.", true));
|
mainPanel.add(new OkAlert("Your data have been imported successfully, anything you want to edit or add? Please use Edit Profile Manually.", true));
|
||||||
displayProfile();
|
displayProfile();
|
||||||
|
//result contain the publicProfileLinkedInUrl
|
||||||
|
sendRefreshClientEvent(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
@ -61,6 +69,19 @@ public class SocialProfile implements EntryPoint {
|
||||||
|
|
||||||
RootPanel.get("SocialProfileDiv").add(mainPanel);
|
RootPanel.get("SocialProfileDiv").add(mainPanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void sendRefreshClientEvent(String inPublicProfileURL) {
|
||||||
|
//create the Contact bean data
|
||||||
|
Person person = new Person();
|
||||||
|
person.setName(inPublicProfileURL);
|
||||||
|
// publish a message with Contact bean data
|
||||||
|
try {
|
||||||
|
pageBusAdapter.PageBusPublish("net.eliasbalasis.tibcopagebus4gwt.testsubscriber.client.Person", person, (Jsonizer)GWT.create(PersonJsonizer.class));
|
||||||
|
} catch (PageBusAdapterException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* display the profile of the user
|
* display the profile of the user
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -16,5 +16,5 @@ public interface SocialService extends RemoteService {
|
||||||
|
|
||||||
Boolean saveIsti(String institution);
|
Boolean saveIsti(String institution);
|
||||||
|
|
||||||
Boolean fetchUserProfile(String authCode, String redirectURI);
|
String fetchUserProfile(String authCode, String redirectURI);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ public interface SocialServiceAsync {
|
||||||
|
|
||||||
void saveIsti(String institution, AsyncCallback<Boolean> callback);
|
void saveIsti(String institution, AsyncCallback<Boolean> callback);
|
||||||
|
|
||||||
void fetchUserProfile(String authCode, String redirectURI, AsyncCallback<Boolean> callback);
|
void fetchUserProfile(String authCode, String redirectURI,
|
||||||
|
AsyncCallback<String> callback);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,8 +48,12 @@ import org.slf4j.LoggerFactory;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
|
|
||||||
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
|
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
|
||||||
|
import com.liferay.portal.kernel.cache.CacheRegistryUtil;
|
||||||
import com.liferay.portal.kernel.util.WebKeys;
|
import com.liferay.portal.kernel.util.WebKeys;
|
||||||
|
import com.liferay.portal.model.Contact;
|
||||||
import com.liferay.portal.model.User;
|
import com.liferay.portal.model.User;
|
||||||
|
import com.liferay.portal.service.ContactLocalServiceUtil;
|
||||||
|
import com.liferay.portal.service.ContactServiceUtil;
|
||||||
import com.liferay.portal.service.UserLocalServiceUtil;
|
import com.liferay.portal.service.UserLocalServiceUtil;
|
||||||
import com.liferay.portal.theme.ThemeDisplay;
|
import com.liferay.portal.theme.ThemeDisplay;
|
||||||
|
|
||||||
|
@ -65,7 +69,7 @@ public class SocialServiceImpl extends RemoteServiceServlet implements SocialSer
|
||||||
private static final String LINKEDIN_CLIEND_ID_PROPNAME = "client_id";
|
private static final String LINKEDIN_CLIEND_ID_PROPNAME = "client_id";
|
||||||
private static final String LINKEDIN_CLIEND_SECRET_PROPNAME = "client_secret";
|
private static final String LINKEDIN_CLIEND_SECRET_PROPNAME = "client_secret";
|
||||||
|
|
||||||
private static final String LINKEDIN_API_REQUEST = "https://api.linkedin.com/v1/people/~:(id,headline,summary,location:(name),industry,positions,picture-urls::(original))";
|
private static final String LINKEDIN_API_REQUEST = "https://api.linkedin.com/v1/people/~:(id,headline,summary,location:(name),industry,positions,picture-urls::(original),public-profile-url)";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the current ASLSession
|
* the current ASLSession
|
||||||
|
@ -242,7 +246,7 @@ public class SocialServiceImpl extends RemoteServiceServlet implements SocialSer
|
||||||
* @return true if everything goes ok, false otherwise.
|
* @return true if everything goes ok, false otherwise.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Boolean fetchUserProfile(String authCode, String redirectURI) {
|
public String fetchUserProfile(String authCode, String redirectURI) {
|
||||||
try {
|
try {
|
||||||
HashMap<String, String> infoMap = getLinkedInUASInfo();
|
HashMap<String, String> infoMap = getLinkedInUASInfo();
|
||||||
HttpClient httpClient = HttpClients.createDefault();
|
HttpClient httpClient = HttpClients.createDefault();
|
||||||
|
@ -268,7 +272,7 @@ public class SocialServiceImpl extends RemoteServiceServlet implements SocialSer
|
||||||
String jsonText = IOUtils.toString(myInputStream, "UTF-8");
|
String jsonText = IOUtils.toString(myInputStream, "UTF-8");
|
||||||
_log.debug("LinkedIn response: " + jsonText);
|
_log.debug("LinkedIn response: " + jsonText);
|
||||||
if (jsonText == null)
|
if (jsonText == null)
|
||||||
return false;
|
return null;
|
||||||
|
|
||||||
JSONParser parser = new JSONParser();
|
JSONParser parser = new JSONParser();
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
|
@ -284,33 +288,33 @@ public class SocialServiceImpl extends RemoteServiceServlet implements SocialSer
|
||||||
Map<String, String> json = (Map<String, String>) parser.parse(jsonText, containerFactory);
|
Map<String, String> json = (Map<String, String>) parser.parse(jsonText, containerFactory);
|
||||||
|
|
||||||
if (json.get("error") != null)
|
if (json.get("error") != null)
|
||||||
return false;
|
return null;
|
||||||
|
|
||||||
String token = json.get("access_token");
|
String token = json.get("access_token");
|
||||||
if (token == null)
|
if (token == null)
|
||||||
return false;
|
return null;
|
||||||
//here we got authorized by the user
|
//here we got authorized by the user
|
||||||
return parseProfile(httpClient, token);
|
return parseProfile(httpClient, token);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
myInputStream.close();
|
myInputStream.close();
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
|
return null;
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Ask the basic profile to LinkedIn API for the authenticated user, parse rge profile and write info into local DB.
|
* Ask the basic profile to LinkedIn API for the authenticated user, parse rge profile and write info into local DB.
|
||||||
* @param httpClient
|
* @param httpClient
|
||||||
* @param token
|
* @param token
|
||||||
* @return
|
* @return the LinkedIn public URL of the user, or null in case of errors
|
||||||
*/
|
*/
|
||||||
private boolean parseProfile(HttpClient httpClient, String token) {
|
private String parseProfile(HttpClient httpClient, String token) {
|
||||||
HttpGet request = new HttpGet(LINKEDIN_API_REQUEST);
|
HttpGet request = new HttpGet(LINKEDIN_API_REQUEST);
|
||||||
// add request header as in the documentation, @see https://developer.linkedin.com/documents/authentication
|
// add request header as in the documentation, @see https://developer.linkedin.com/documents/authentication
|
||||||
request.addHeader("Authorization", "Bearer " + token);
|
request.addHeader("Authorization", "Bearer " + token);
|
||||||
|
@ -403,6 +407,12 @@ public class SocialServiceImpl extends RemoteServiceServlet implements SocialSer
|
||||||
pictureURL = currValue.get(0);
|
pictureURL = currValue.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String publicProfileURL = "";
|
||||||
|
currValue = helper.evaluate("/person/public-profile-url/text()");
|
||||||
|
if (currValue != null && currValue.size() > 0) {
|
||||||
|
publicProfileURL = currValue.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
//add the positions to the summary
|
//add the positions to the summary
|
||||||
summary += positions;
|
summary += positions;
|
||||||
|
|
||||||
|
@ -422,6 +432,13 @@ public class SocialServiceImpl extends RemoteServiceServlet implements SocialSer
|
||||||
if (summary.compareTo("") != 0)
|
if (summary.compareTo("") != 0)
|
||||||
user.setComments(escapeHtml(summary));
|
user.setComments(escapeHtml(summary));
|
||||||
|
|
||||||
|
//public profile URL
|
||||||
|
if (publicProfileURL.compareTo("") != 0) {
|
||||||
|
Contact contact = user.getContact();
|
||||||
|
contact.setMySpaceSn(publicProfileURL);
|
||||||
|
ContactLocalServiceUtil.updateContact(contact);
|
||||||
|
}
|
||||||
|
|
||||||
boolean toReturn = (UserLocalServiceUtil.updateUser(user) != null);
|
boolean toReturn = (UserLocalServiceUtil.updateUser(user) != null);
|
||||||
//set the picture
|
//set the picture
|
||||||
if (pictureURL.compareTo("") != 0 && pictureURL.startsWith("http")) {
|
if (pictureURL.compareTo("") != 0 && pictureURL.startsWith("http")) {
|
||||||
|
@ -431,20 +448,25 @@ public class SocialServiceImpl extends RemoteServiceServlet implements SocialSer
|
||||||
UserLocalServiceUtil.updatePortrait(user.getUserId(), pictureData);
|
UserLocalServiceUtil.updatePortrait(user.getUserId(), pictureData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return toReturn;
|
if (toReturn)
|
||||||
|
return publicProfileURL;
|
||||||
|
else return null;
|
||||||
} else {
|
} else {
|
||||||
_log.warn("Development Mode ON, not attempting to write into DB");
|
_log.warn("Development Mode ON, not attempting to write into DB");
|
||||||
|
return "fakePublicURL";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
myInputStream.close();
|
myInputStream.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
else
|
||||||
|
return null;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -534,25 +556,5 @@ public class SocialServiceImpl extends RemoteServiceServlet implements SocialSer
|
||||||
return html.replaceAll("&", "&").replaceAll("<", "<")
|
return html.replaceAll("&", "&").replaceAll("<", "<")
|
||||||
.replaceAll(">", ">");
|
.replaceAll(">", ">");
|
||||||
}
|
}
|
||||||
//test metho
|
|
||||||
private String testParsing() {
|
|
||||||
return
|
|
||||||
"<person><id>KbR7LHuOer</id><headline>Technical Director at D4Science Hybrid Data Infrastructure</headline><summary>Senior Researcher at the Networked Multimedia Information Systems Laboratory of the "Istituto di Scienza e Tecnologie della Informazione A. Faedo" (ISTI) of the Italian National Research Council (CNR). I received my M.Sc. in Information Systems Technologies from the Department of Computer Science of the University of Pisa (1998), and the Ph.D. degree in Information Engineering from the Department of Information Engineering: Electronics, Information Theory, Telecommunications of the same university (2006). The aim of my research is the study and experimentation of models, methodologies and techniques for the design and development of distributed virtual research environments (VREs) which require the handling of heterogeneous computational and storage resources, provided by Grid and Cloud based e-Infrastructures, for the management of heterogenous data sources. I have a strong background on distributed architectures. I participated to the design of the most relevant distributed systems and e-Infrastructure enabling middleware developed by ISTI - CNR.I am currently the Technical Director of the Data e-Infrastructure Initiative for Fisheries Management and Conservation of Marine Living Resources (iMarine). I am also serving EUBrazilOpenBio initiative and ENVRI - Environmental Research Infrastructure - as consultant."
|
|
||||||
+"In the past, I have been involved in the Venus-C, GRDI2020, D4Science-II, D4Science, Diligent, DRIVER, DRIVER II, BELIEF, BELIEF II, Scholnet, Cyclades, and ARCA European projects.</summary>"
|
|
||||||
+"<location><name>Pisa Area, Italy</name></location><industry>Research</industry>"
|
|
||||||
+"<positions total=\"3\">"
|
|
||||||
+ "<position><id>421485155</id><title>Technical Director</title><summary>Summary D4Science.org .... the D4Science.org Agreement</summary>"
|
|
||||||
+"<start-date><year>2012</year><month>1</month></start-date><is-current>true</is-current><company><name>D4Science Hybrid Data Infrastructure</name><industry>Research</industry></company>"
|
|
||||||
+"</position>"
|
|
||||||
+ "<position><id>421485155</id><title>Senior Researcher</title><summary>Summary CNR The aim of my research is the study and experimentation of models</summary>"
|
|
||||||
+"<start-date><year>2013</year><month>4</month></start-date><is-current>true</is-current>"
|
|
||||||
+"<company><id>565371</id><name>ISTI-CNR</name><size>201-500 employees</size><type>Public Company</type><industry>Research</industry></company>"
|
|
||||||
+"</position>"
|
|
||||||
+ "<position><id>421485155</id><title>Technical Director</title><summary>Summary iMarine launches an initiative to establi</summary>"
|
|
||||||
+"<start-date><year>2014</year><month>7</month></start-date><is-current>true</is-current><company><name>D4Science Hybrid Data Infrastructure</name><industry>Research</industry></company>"
|
|
||||||
+"</position>"
|
|
||||||
+"</positions>"
|
|
||||||
+"<picture-urls total=\"1\"><picture-url key=\"original\">http://m.c.lnkd.licdn.com/mpr/mprx/0_mK4hvD9T0-r5MTo1elJa92JfJvOLMh61WlQSPuFDc3x6j3NgI8M2AQ6jLEE</picture-url></picture-urls>"
|
|
||||||
+"</person>";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
<inherits name='org.gcube.portlets.user.gcubewidgets.WidgetFactory' />
|
<inherits name='org.gcube.portlets.user.gcubewidgets.WidgetFactory' />
|
||||||
<inherits name='org.gcube.portlets.widgets.wsmail.WsMail_Widget' />
|
<inherits name='org.gcube.portlets.widgets.wsmail.WsMail_Widget' />
|
||||||
<inherits name='org.gcube.portal.databook.GCubeSocialNetworking' />
|
<inherits name='org.gcube.portal.databook.GCubeSocialNetworking' />
|
||||||
|
<inherits name="net.eliasbalasis.tibcopagebus4gwt.tibcopagebus4gwt" />
|
||||||
|
<inherits name="org.jsonmaker.gwt.Gwt_jsonmaker" />
|
||||||
|
<inherits
|
||||||
|
name="net.eliasbalasis.tibcopagebus4gwt.testsubscriber.TestSubscriber" />
|
||||||
<!-- Specify the app entry point class. -->
|
<!-- Specify the app entry point class. -->
|
||||||
<entry-point
|
<entry-point
|
||||||
class='org.gcube.portlets.user.socialprofile.client.SocialProfile' />
|
class='org.gcube.portlets.user.socialprofile.client.SocialProfile' />
|
||||||
|
|
|
@ -2,6 +2,11 @@
|
||||||
<%@page pageEncoding="UTF-8"%>
|
<%@page pageEncoding="UTF-8"%>
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
if(window.parent.PageBus) {
|
||||||
|
window.PageBus = window.parent.PageBus;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
<script type="text/javascript" language="javascript" src="<%=request.getContextPath()%>/socialprofile/socialprofile.nocache.js"></script>
|
<script type="text/javascript" language="javascript" src="<%=request.getContextPath()%>/socialprofile/socialprofile.nocache.js"></script>
|
||||||
<div id="SocialProfileDiv">
|
<div id="SocialProfileDiv">
|
||||||
</div>
|
</div>
|
|
@ -8,6 +8,7 @@
|
||||||
<instanceable>false</instanceable>
|
<instanceable>false</instanceable>
|
||||||
<ajaxable>false</ajaxable>
|
<ajaxable>false</ajaxable>
|
||||||
<header-portlet-css>/SocialProfile.css</header-portlet-css>
|
<header-portlet-css>/SocialProfile.css</header-portlet-css>
|
||||||
|
<header-portlet-javascript>/js/pagebus.js</header-portlet-javascript>
|
||||||
</portlet>
|
</portlet>
|
||||||
<role-mapper>
|
<role-mapper>
|
||||||
<role-name>administrator</role-name>
|
<role-name>administrator</role-name>
|
||||||
|
|
|
@ -0,0 +1,182 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2006-2007, TIBCO Software Inc.
|
||||||
|
* Use, modification, and distribution subject to terms of license.
|
||||||
|
*
|
||||||
|
* TIBCO(R) PageBus 1.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(typeof window.PageBus == 'undefined') {
|
||||||
|
|
||||||
|
PageBus = {
|
||||||
|
version: "1.1.0",
|
||||||
|
S: {c:{},s:[]},
|
||||||
|
X: 0,
|
||||||
|
P: 0,
|
||||||
|
U: [],
|
||||||
|
H: "undefined"
|
||||||
|
};
|
||||||
|
|
||||||
|
PageBus.subscribe = function(name, scope, callback, subscriberData)
|
||||||
|
{
|
||||||
|
if(name == null)
|
||||||
|
this._badName();
|
||||||
|
if(scope == null)
|
||||||
|
scope = window;
|
||||||
|
var path = name.split(".");
|
||||||
|
var sub = { f: callback, d: subscriberData, i: this.X++, p: path, w: scope };
|
||||||
|
for(var i = 0; i < path.length; i++) {
|
||||||
|
if((path[i].indexOf("*") != -1) && (path[i] != "*") && (path[i] != "**"))
|
||||||
|
this._badName();
|
||||||
|
}
|
||||||
|
this._subscribe(this.S, path, 0, sub);
|
||||||
|
return sub;
|
||||||
|
}
|
||||||
|
|
||||||
|
PageBus.publish = function (name, message)
|
||||||
|
{
|
||||||
|
if((name == null) || (name.indexOf("*") != -1))
|
||||||
|
this._badName();
|
||||||
|
var path = name.split(".");
|
||||||
|
if(this.P > 100)
|
||||||
|
this._throw("StackOverflow");
|
||||||
|
try {
|
||||||
|
this.P++;
|
||||||
|
this._publish(this.S, path, 0, name, message);
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
this.P--;
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.P--;
|
||||||
|
if((this.U.length > 0) && (this.P == 0)) {
|
||||||
|
for(var i = 0; i < this.U.length; i++)
|
||||||
|
this.unsubscribe(this.U[i]);
|
||||||
|
this.U = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
// All unsubscribe exceptions should already have
|
||||||
|
// been handled when unsubscribe was called in the
|
||||||
|
// publish callback. This is a repeat appearance
|
||||||
|
// of this exception. Discard it.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PageBus.unsubscribe = function(sub)
|
||||||
|
{
|
||||||
|
this._unsubscribe(this.S, sub.p, 0, sub.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @private @jsxobf-clobber
|
||||||
|
*/
|
||||||
|
PageBus._throw = function(n)
|
||||||
|
{
|
||||||
|
throw new Error("PageBus." + n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @private @jsxobf-clobber
|
||||||
|
*/
|
||||||
|
PageBus._badName = function(n)
|
||||||
|
{
|
||||||
|
this._throw("BadName");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @private @jsxobf-clobber
|
||||||
|
*/
|
||||||
|
PageBus._subscribe = function(tree, path, index, sub)
|
||||||
|
{
|
||||||
|
var tok = path[index];
|
||||||
|
if(tok == "")
|
||||||
|
this._badName();
|
||||||
|
if(index == path.length)
|
||||||
|
tree.s.push(sub);
|
||||||
|
else {
|
||||||
|
if(typeof tree.c == this.H)
|
||||||
|
tree.c = {};
|
||||||
|
if(typeof tree.c[tok] == this.H) {
|
||||||
|
try {
|
||||||
|
tree.c[tok] = { c: {}, s: [] };
|
||||||
|
this._subscribe(tree.c[tok], path, index + 1, sub);
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
delete tree.c[tok];
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this._subscribe( tree.c[tok], path, index + 1, sub );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @private @jsxobf-clobber
|
||||||
|
*/
|
||||||
|
PageBus._publish = function(tree, path, index, name, msg) {
|
||||||
|
if(path[index] == "")
|
||||||
|
this._badName();
|
||||||
|
if(typeof tree != this.H) {
|
||||||
|
if(index < path.length) {
|
||||||
|
this._publish(tree.c[path[index]], path, index + 1, name, msg);
|
||||||
|
this._publish(tree.c["*"], path, index + 1, name, msg);
|
||||||
|
this._call(tree.c["**"], name, msg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this._call(tree, name, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @private @jsxobf-clobber
|
||||||
|
*/
|
||||||
|
PageBus._call = function(node, name, msg) {
|
||||||
|
if(typeof node != this.H) {
|
||||||
|
var callbacks = node.s;
|
||||||
|
var max = callbacks.length;
|
||||||
|
for(var i = 0; i < max; i++)
|
||||||
|
if(callbacks[i].f != null)
|
||||||
|
callbacks[i].f.apply(callbacks[i].w, [name, msg, callbacks[i].d]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @jsxobf-clobber
|
||||||
|
*/
|
||||||
|
PageBus._unsubscribe = function(tree, path, index, sid) {
|
||||||
|
if(typeof tree != this.H) {
|
||||||
|
if(index < path.length) {
|
||||||
|
var childNode = tree.c[path[index]];
|
||||||
|
this._unsubscribe(childNode, path, index + 1, sid);
|
||||||
|
if(childNode.s.length == 0) {
|
||||||
|
for(var x in childNode.c) // not empty. We're done.
|
||||||
|
return;
|
||||||
|
delete tree.c[path[index]]; // if we got here, c is empty
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var callbacks = tree.s;
|
||||||
|
var max = callbacks.length;
|
||||||
|
for(var i = 0; i < max; i++) {
|
||||||
|
if(sid == callbacks[i].i) {
|
||||||
|
if(this.P > 0) {
|
||||||
|
if(callbacks[i].f == null)
|
||||||
|
this._throw("BadParameter");
|
||||||
|
callbacks[i].f = null;
|
||||||
|
this.U.push(callbacks[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
callbacks.splice(i, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Not found. Fall through
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._throw("BadParameter");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue