/**
* Copyright (c) 2011, SOCIETIES Consortium (WATERFORD INSTITUTE OF TECHNOLOGY (TSSG), HERIOT-WATT UNIVERSITY (HWU), SOLUTA.NET
* (SN), GERMAN AEROSPACE CENTRE (Deutsches Zentrum fuer Luft- und Raumfahrt e.V.) (DLR), Zavod za varnostne tehnologije
* informacijske družbe in elektronsko poslovanje (SETCCE), INSTITUTE OF COMMUNICATION AND COMPUTER SYSTEMS (ICCS), LAKE
* COMMUNICATIONS (LAKE), INTEL PERFORMANCE LEARNING SOLUTIONS LTD (INTEL), PORTUGAL TELECOM INOVAÇÃO, SA (PTIN), IBM Corp.,
* INSTITUT TELECOM (ITSUD), AMITEC DIACHYTI EFYIA PLIROFORIKI KAI EPIKINONIES ETERIA PERIORISMENIS EFTHINIS (AMITEC), TELECOM
* ITALIA S.p.a.(TI), TRIALOG (TRIALOG), Stiftelsen SINTEF (SINTEF), NEC EUROPE LTD (NEC))
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.societies.personalisation.socialprofiler.service;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.TimeZone;
import org.apache.shindig.social.opensocial.model.ActivityEntry;
import org.apache.shindig.social.opensocial.model.ActivityObject;
import org.apache.shindig.social.opensocial.model.Person;
import org.json.JSONException;
import org.json.JSONObject;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.societies.api.internal.sns.ISocialData;
import org.societies.personalisation.socialprofiler.Variables;
import org.societies.personalisation.socialprofiler.datamodel.Interests;
import org.societies.personalisation.socialprofiler.datamodel.SocialPage;
import org.societies.personalisation.socialprofiler.datamodel.SocialPerson;
import org.societies.personalisation.socialprofiler.datamodel.behaviour.Profile;
import org.societies.personalisation.socialprofiler.datamodel.impl.RelTypes;
import org.societies.personalisation.socialprofiler.datamodel.impl.SocialPersonImpl;
import org.societies.personalisation.socialprofiler.exception.NeoException;
public class ProfilerEngine implements Variables{
private static final Logger logger = LoggerFactory.getLogger(ProfilerEngine.class);
private GraphManager graph;
// private DatabaseConnection databaseConnection;
private ISocialData socialData;
private List<?> friends = new ArrayList<Person>();
private List<?> profiles = new ArrayList<Person>();
private List<?> activities = new ArrayList<ActivityEntry>();
public static final String INITIAL_USER_ID = "0";
// public ProfilerEngine(GraphManager graph, DatabaseConnection databaseConnection, ISocialData socialData){
public ProfilerEngine(GraphManager graph, ISocialData socialData){
this.graph = graph;
// this.databaseConnection = databaseConnection;
this.socialData = socialData;
generateCompleteNetwork();
}
public ISocialData getSocialData(){
return this.socialData;
}
public void setSocialData(ISocialData socialData){
this.socialData = socialData;
}
/**
*
* @param option can be 1:FIRST TIME or 2:UPDATE ONLY if option is 1
* then this function also generates info but no updates are
* done if option 2 , the function generates if necessary but
* also updates
*/
public void UpdateNetwork(int option){
logger.info("=============================================================");
logger.info("==== SOCIAL PROFILER UPDATE =====");
logger.info("=============================================================");
logger.info("=== UPDATING NETWORK , all new users will be added to network");
logger.info("=== updating or removing if necessary the existing users ");
logger.info("=============================================================");
socialData.updateSocialData();
// Update data source
profiles = socialData.getSocialProfiles();
friends = socialData.getSocialPeople();
activities = socialData.getSocialActivity();
// if (!databaseConnection.connectMysql()){
// logger.error("Cannot proceed with request due to database connection problems.");
// return;
// }
logger.debug("=============================");
logger.debug("=== Traversing NEO GRAPH ===");
logger.debug("=============================");
// ANALIZZO ESISTENTI
ArrayList<String> list_usersIds = new ArrayList<String>(); // empty LIST
try {
list_usersIds = graph.getGraphNodesIds(graph.getAllGraphNodes());
}
catch (NeoException e) {
logger.error("Cannot get graph nodes IDs: " + e.getMessage());
return;
}
// If the Graph Node contains at least one node ....
if (list_usersIds.size()>0){
for (int i=0;i<list_usersIds.size();i++){
if (list_usersIds.get(i)!=null){
generateTree(list_usersIds.get(i), null, option);
}
}
}
// databaseConnection.addInfoForCommunityProfile();
// databaseConnection.closeMysql();
logger.debug("=============================================================");
logger.debug("==== SOCIAL PROFILER COMPLETED UPDATE =====");
logger.debug("=============================================================");
}
private void generateCompleteNetwork(){
logger.debug("GENERATING the whole network including isolated clusters and/or nodes");
graph.createPerson(SocialPerson.ROOT);
// if (!databaseConnection.connectMysql()){
// logger.error("Cannot proceed with request due to database connection problems.");
// return;
// }
createInitialUsers();
// databaseConnection.addInfoForCommunityProfile();
// databaseConnection.closeMysql();
}
private void createInitialUsers(){
// creating base user (needs to be a number)
logger.debug("Creating initial user: "+INITIAL_USER_ID);
generateTree(INITIAL_USER_ID,null,FIRST_TIME);
}
/**
* Add a new User
* @param p
*/
public void linkToRoot(SocialPerson p){
Transaction tx = graph.getNeoService().beginTx();
try{
Node startPersonNode = ((SocialPersonImpl) p).getUnderlyingNode();
Node rootNode = ((SocialPersonImpl) graph.getPerson(SocialPerson.ROOT)).getUnderlyingNode();
startPersonNode.createRelationshipTo(rootNode, RelTypes.TRAVERSER);
tx.success();
}
finally{
tx.finish();
}
}
public void generateTree(String current_id, String previous_id, int option) {
logger.info("=============================================================");
logger.info("==== GENERATING TREE ===");
logger.info("=============================================================");
logger.info("->> current_id : "+current_id+" previous_id: "+previous_id+" opt:"+option);
logger.info("=============================================================");
logger.info("--- checking if current user "+current_id+" exists on neo network");
SocialPerson currentPerson=graph.getPerson(current_id);
if (currentPerson==null){
logger.info("----the current user "+current_id+" doesn't exist on Neo network");
// friends List but not used any more!
//List<SocialPerson> list= new ArrayList(getSocialData().getSocialPeople()); //serviceXml.friendsGetFacebook(client);
logger.debug("-->creating user "+current_id+" on Neo network");
SocialPerson startPerson=graph.createPerson(current_id);
linkToRoot(startPerson);
// databaseConnection.addUserToDatabase(current_id, startPerson.getName());
logger.debug("---# initialising user"+current_id+" profile percentages");
// TODO - initialize percentages
graph.updatePersonPercentages(current_id,"0", "0", "0", "0","0","0");
logger.debug("---*checking previous user id in order to create relationship");
if (previous_id==null){
logger.info("previous user id is null -> no relationship will be created");
}
else{
String nameDescription=current_id+previous_id;
SocialPerson endPerson=graph.getPerson(previous_id);
logger.info("---# Trying to create relationship between "+current_id+" and "+previous_id+" with name "+nameDescription);
graph.createDescription(startPerson, endPerson, current_id, previous_id);
}
// Initialize USER Generic information
initialiseUserInformation(current_id, startPerson);
generateUserInformation(current_id, profiles);
// Initialize USER Behavioural profiles
initialiseUserProfiles(current_id, startPerson);
createFanPagesAndCategories(current_id, startPerson, profiles);
//// SET WINDOW TIME to get the last Activities
//current time- 1 week
java.util.TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
java.util.Date today = new java.util.Date();
java.sql.Timestamp timestamp=new java.sql.Timestamp(today.getTime());
long current_time = (timestamp.getTime())/1000;
//1 week=7 x 24 x 60 x 60=604800
long week_time=604800;
long end_date=current_time-week_time;
long end_date1=end_date*1000;
// ANALYSE ACTIVITIES
generateProfileContent(current_id, activities, end_date1); //till one week before , then update
for(int i=0;i<friends.size();i++){
String friend= ((Person)friends.get(i)).getId();
if (friend==null){
logger.warn("retrieved a null friends");
}else{
logger.debug("friend id "+ friend);
}
generateTree(friend, current_id, option);
}
}
else{
logger.info("---current user "+current_id+" exists on Neo network");
if (option==FIRST_TIME){
SocialPerson startPerson=graph.getPerson(current_id);
if (previous_id==null){
logger.debug("previous user is null => nothing to check - end of this sub-branch");
}else{
logger.debug("####checking if there is a relationship between current "+current_id+" and previous"+previous_id);
SocialPerson endPerson=graph.getPerson(previous_id);
boolean exists= false; //service.existsRelationship(startPerson, endPerson);
if (exists==false){
logger.debug("#### the relationship doesn't exist");
logger.debug("####looking through user friends to determine if a relationship is necessary");
boolean necessary=false;
ArrayList<String> list= null; //serviceXml.friendsGetFacebook(client);
for(int i=0;i<list.size();i++){
String friend=list.get(i);
if (friend.equals(previous_id)){
necessary=true;
}
}
if (necessary==true){
logger.debug("a relationship is necessary and will be created");
String nameDescription=current_id+previous_id;
logger.debug("---Creating relationship between "+current_id+" and "+previous_id+" with name "+nameDescription);
graph.createDescription(startPerson, endPerson, current_id, previous_id);
}else{
logger.debug("NO relationship is necessary - end of check");
}
}else{
logger.debug("####a relationship was found between the 2 nodes- end of check");
}
}
}
else if((option==UPDATE_EVERYTHING) ||
(option==UPDATE_ONLY_STREAM) ||
(option==UPDATE_STREAM_AND_FANPAGES) ||
(option==UPDATE_STREAM_AND_USER_INFORMATION)){
// checking if current user still exists. always true for now
boolean exists=true;
if (exists){
logger.debug("--current user "+current_id+" found");
// checking if current user has valid credentials (eg token). always true for now
boolean valid=true;
if (!valid){
logger.debug("the credentials of user "+current_id+" don't function : Reason : possible invalid token");
logger.debug("removing current id "+current_id+" from neo network, index and database");
logger.info("REMOVING USER + DELETING FROM NEO: "+current_id);
graph.deletePerson(current_id);
}else{
SocialPerson startPerson=graph.getPerson(current_id);
if (previous_id==null){
logger.debug("previous user is null=> nothing to check - end of this sub-branch");
}else{
logger.debug("####checking if there is a relationship between current "+current_id+" and previous"+previous_id);
SocialPerson endPerson=graph.getPerson(previous_id);
boolean existsRel=graph.existsRelationship(startPerson, endPerson);
if (!existsRel){
logger.info("#### the relationship doesn't exist");
logger.debug("####looking through user friends to determine if a relationship is necessary");
boolean necessary=false;
// TODO. should retrieve contact list
ArrayList<String> contacts=new ArrayList<String>();
for(int i=0;i<contacts.size();i++){
String c=contacts.get(i);
if (c.equals(previous_id)){
necessary=true;
}
}
if (necessary==true){
logger.debug("a relationship is necessary and will be created");
String nameDescription=current_id+previous_id;
logger.debug("---Creating relationship between "+current_id+" and "+previous_id+" with name "+nameDescription);
graph.createDescription(startPerson, endPerson, current_id,previous_id);
}else{
logger.debug("NO relationship is necessary - end of check");
}
}else{
logger.info("####a relationship was found between the 2 nodes- end of check");
}
}
switch (option){
case UPDATE_EVERYTHING :{
createFanPagesAndCategories(current_id, startPerson, profiles); //adding additional fan pages if necessary
updateUserInformation(current_id, startPerson, profiles);//modifying general info if necessary
updateProfileContent(current_id, startPerson, activities);//updating profile content information if necessary
break;
}
case UPDATE_ONLY_STREAM :{
updateProfileContent(current_id, startPerson, activities);//updating profile content information if necessary
break;
}
case UPDATE_STREAM_AND_FANPAGES :{
createFanPagesAndCategories(current_id, startPerson, profiles); //adding additional fan pages if necessary
updateProfileContent(current_id, startPerson, activities);//updating profile content information if necessary
break;
}
case UPDATE_STREAM_AND_USER_INFORMATION :{
updateUserInformation(current_id, startPerson, profiles);//modifying general info if necessary
updateProfileContent(current_id, startPerson, activities);//updating profile content information if necessary
break;
}
default :{
logger.debug("ERROR , nothing will be updated , the update option introduced doesn't exist");
}
}
}
}else{ // dead code for now.
logger.debug("removing current id"+current_id+" from neo network , index ");
graph.deletePerson(current_id);
// databaseConnection.deleteUserFromDatabase(current_id);
}
}
}
logger.info("=============================================================");
logger.info("==== END of TREE GENERATION for "+current_id+" =====");
logger.info("=============================================================");
}
public void initialiseUserInformation(String current_id, SocialPerson person){
logger.debug("[INIT] GeneralInfo and Interests for user "+current_id);
logger.debug("[INTERESTS]");
graph.linkInterests(person,current_id+"_Interests");
graph.updateInterests(current_id+"_Interests","","","","","","","","0");
logger.debug("[GENERAL_INFO]");
graph.linkGeneralInfo(person,current_id+"_GeneralInfo");
graph.updateGeneralInfo(current_id+"_GeneralInfo","","","","", "","","","");
}
public void updateUserInformation(String current_id,SocialPerson person, List<?> profiles){
logger.debug("Checking if update is necessary for user"+current_id);
Person information= (Person) profiles.get(0); // only considers first profile
String new_profileUpdateTime="";
try {
new_profileUpdateTime=information.getUpdated().toString();
} catch (NullPointerException e) {}
if (new_profileUpdateTime.equals("0")){
logger.debug("no update is necessary");
}else {
String profileUpdateTime="";
Transaction tx = graph.getNeoService().beginTx();
try{
Interests interests=graph.getInterests(current_id+"_Interests");
profileUpdateTime=interests.getProfileUpdateTime();
tx.success();
}catch (Exception e) {}
finally{
tx.finish();
}
if ((profileUpdateTime==null)||(profileUpdateTime.equals(""))||(profileUpdateTime.equals("0")) ){
generateUserInformation(current_id, profiles);
}else if ((Long)Long.parseLong(new_profileUpdateTime)>(Long)Long.parseLong(profileUpdateTime)){
generateUserInformation(current_id, profiles);
}
}
}
public void createFanPagesAndCategories(String current_id,SocialPerson startPerson,List<?> profiles)
{
logger.debug("retrieving the fanpages ,for which user "+current_id+" is fan of");
ArrayList <String> pages_ids=new ArrayList <String> ();
Person information = null;
if (profiles.size()>0)
information = (Person) profiles.get(0);
Hashtable <String,ArrayList<String>> pages_data = new Hashtable<String, ArrayList<String>>();
if (information != null && information.getTurnOns() != null) {
List<String> turnOns = information.getTurnOns();
Iterator<String> it = turnOns.iterator();
while(it.hasNext()){
try {
JSONObject info = new JSONObject(it.next());
ArrayList<String> pageData = new ArrayList<String>();
pageData.add(info.getString("value"));
pageData.add(info.getString("type"));
pages_data.put(info.getString("id"), pageData);
pages_ids.add(info.getString("id"));
}
catch (JSONException e) {
e.printStackTrace();
}
}
}
ArrayList <Long> existent_pages_ids=graph.getListOfPagesOfInterest(current_id);
ArrayList <Long> remaining_pages_ids=graph.convertArrayOfStringToLong(pages_ids);
graph.projectArrays(remaining_pages_ids, existent_pages_ids);
for(int j=0;j<remaining_pages_ids.size();j++){
String page=remaining_pages_ids.get(j).toString();
if (page==null){
logger.warn("retrieved a null page");
}else{
logger.debug("---- page id "+ page);
SocialPage fanPage=graph.linkPageOfInterest(startPerson, page);
ArrayList<String> page_data=pages_data.get(page);
String type=page_data.get(1);
graph.updatePageOfInterest(page, page_data.get(0),type );
if ((!type.equals(""))&&(type!=null)){
graph.linkPageOfInterestCategory(fanPage, type, startPerson);
}
}
}
}
public void updateProfileContent(String current_id, SocialPerson person, List<?> activities){
ArrayList <Long> lastTimes=new ArrayList<Long>();
// try {
// lastTimes.add(Long.parseLong(graph.getNarcissismManiacLastTime(current_id+"_NarcissismManiac")));
// } catch (NumberFormatException e) {
// logger.warn("Error parsing service.getNarcissismManiacLastTime() into date. Property set to 0. Details: " + e.getMessage());
// lastTimes.add(new Long("0"));
// }
// try {
// lastTimes.add(Long.parseLong(graph.getSuperActiveManiacLastTime(current_id+"_SuperActiveManiac")));
// } catch (NumberFormatException e) {
// logger.warn("Error parsing service.getSuperActiveManiacLastTime() into date. Property set to 0. Details: " + e.getMessage());
// lastTimes.add(new Long("0"));
// }
// try {
// lastTimes.add(Long.parseLong(graph.getPhotoManiacLastTime(current_id+"_PhotoManiac")));
// } catch (NumberFormatException e) {
// logger.warn("Error parsing service.getPhotoManiacLastTime() into date. Property set to 0. Details: " + e.getMessage());
// lastTimes.add(new Long("0"));
// }
// try {
// lastTimes.add(Long.parseLong(graph.getSurfManiacLastTime(current_id+"_SurfManiac")));
// } catch (NumberFormatException e) {
// logger.warn("Error parsing service.getSurfManiacLastTime() into date. Property set to 0. Details: " + e.getMessage());
// lastTimes.add(new Long("0"));
// }
// try {
// lastTimes.add(Long.parseLong(graph.getQuizManiacLastTime(current_id+"_QuizManiac")));
// } catch (NumberFormatException e) {
// logger.warn("Error parsing service.getQuizManiacLastTime() into date. Property set to 0. Details: " + e.getMessage());
// lastTimes.add(new Long("0"));
// }
// graph.qsortSimple(lastTimes,0, lastTimes.size()-1);
// Workaround
lastTimes.add(new Long("0"));
long date=lastTimes.get(lastTimes.size()-1);
// logger.debug("updating stream information for user "+current_id+" starting from timestamp : "+date);
generateProfileContent(current_id, activities, date);
}
public void generateProfileContent(String current_id,List<?> posts,long date ){
logger.debug("Generating profile information from stream of "+posts.size() + " activities for user "+current_id+" .....");
long date_s=date*1000;
Date d = new Date(date_s);
logger.info("analysing each post of the user "+current_id+" 's Wall");
//NOTE going backwards through the DOM, the most recent are first
for(int j=posts.size()-1;j>=0;j--){
ActivityEntry activity=(ActivityEntry) posts.get(j);
String viewer=current_id;
try {
//TODO improve to match viewer/source over all profiles
Person p = (Person) profiles.get(0);
viewer = p.getDisplayName();
if (viewer == null || viewer.equals(""))
viewer = p.getId();
} catch (Exception e) {}
String source=viewer;
ActivityObject a = activity.getActor();
if (a != null) {
source = a.getDisplayName();
if (source == null || source.equals(""))
source = a.getId();
}
String type="note";
try {
type = activity.getObject().getObjectType();
} catch (Exception e) {}
String message=activity.getContent();
// TODO support multiple users. check if viewer (current_id) equals the source (author)
// if (viewer.equals(source)){ //viewer=source -> the posts of the actual user from his Wall
postFiltering(activity, current_id, viewer, source, type, message);
repliesComments(activity, source, viewer, current_id, REPLY_TO_ME);
// } else {
//// String actor = source;
//// String target =activity.getTarget();
//// if (viewer.equals(actor)){
//// postFilteringAdvanced(activity, current_id, actor, target, type, message);
//// } // if (!serviceXml.checkIfUserExists(credentials_facebook_auxiliary, "facebook", source)){ //viewer!=source and source not on AUP ->posts of other non AUP users on his Wall
// repliesComments(activity, source, viewer, current_id, REPLY_TO_STRANGER_CA);
// }
}//for each post
}
private void postFiltering(ActivityEntry activity ,String current_id,String viewer, String source , String type , String message){
String lastTime=activity.getPublished();
if ("note".equals(type)){ //status message
if (viewer.equals(source)) {
if (activity.getTarget() == null) // no target, go to wall -> this is consider narcissist
incrementManiacStatistics(lastTime, current_id, "_NarcissismManiac", Profile.Type.EGO_CENTRIC, NARCISSISM_PROFILE);
else // post to someone else's activity or wall
incrementManiacStatistics(lastTime, current_id, "_SuperActiveManiac", Profile.Type.SUPER_ACTIVE, SUPERACTIVE_PROFILE);
} else // remote post from someone else. no impact on user behaviour profile
logger.info("----(neutral) post: viewer "+viewer+", source: "+source+", type: "+type+", content: "+message+", object: "+activity.getObject().getDisplayName());
} else if ("image".equals(type)){
incrementManiacStatistics(lastTime, current_id, "_PhotoManiac", Profile.Type.PHOTO_MANIAC, PHOTO_PROFILE);
} else if ("bookmark".equals(type)){ //link , youtube or others
incrementManiacStatistics(lastTime, current_id, "_SurfManiac", Profile.Type.SURF_MANIAC, SURF_PROFILE);
} else if ("video".equals(type)){ //TODO posts containing movies , mp4 link inside the post
incrementManiacStatistics(lastTime, current_id, "_SurfManiac", Profile.Type.SURF_MANIAC, SURF_PROFILE);
} else if ("application".equals(type)){ //TODO quiz, applications
incrementManiacStatistics(lastTime, current_id, "_QuizManiac", Profile.Type.QUIZ_MANIAC, QUIZ_PROFILE);
} else if ("person".equals(type)){
if ("update".equals(activity.getVerb()) && viewer.equals(source)) // update profile photos -> this is consider narcissist
incrementManiacStatistics(lastTime, current_id, "_NarcissismManiac", Profile.Type.EGO_CENTRIC, NARCISSISM_PROFILE);
else { // e.g. "tag" someone or "make-friend".
//TODO this is actually receiving tags, so it is a sign of popularity (as well as the number of likes or comments to own activities)
logger.info("----(popularity) post: viewer "+viewer+", source: "+source+", type: "+type+", content: "+message+", object: "+activity.getObject().getDisplayName());
incrementManiacStatistics(lastTime, current_id, "_SuperActiveManiac", Profile.Type.SUPER_ACTIVE, SUPERACTIVE_PROFILE);
}
} else if ("comment".equals(type)){ // comment someone else's activity
incrementManiacStatistics(lastTime, current_id, "_SuperActiveManiac", Profile.Type.SUPER_ACTIVE, SUPERACTIVE_PROFILE);
} else if ("event".equals(type)){ // deal with events (e.g. attend). TODO improve
incrementManiacStatistics(lastTime, current_id, "_SuperActiveManiac", Profile.Type.SUPER_ACTIVE, SUPERACTIVE_PROFILE);
} else if ("question".equals(type)){ // ask a question
incrementManiacStatistics(lastTime, current_id, "_SuperActiveManiac", Profile.Type.SUPER_ACTIVE, SUPERACTIVE_PROFILE);
} else if ("place".equals(type) && viewer.equals(source)){ // checkin a place
incrementManiacStatistics(lastTime, current_id, "_NarcissismManiac", Profile.Type.EGO_CENTRIC, NARCISSISM_PROFILE);
} else {
logger.info("----post: viewer "+viewer+", source: "+source+", type: "+type+", content: "+message+", object: "+activity.getObject().getDisplayName());
logger.info("****WARNING this type is unknown for the engine *** :"+type);
// } else if ("message".equals(type)){ //TODO
// //logger.debug("the user received a direct message- however since no Popularity Profile still available nothing will be done with this post information");
// } else if ("message-event".equals(type)){ //TODO
// //messages with events , for the moment are not treated since no Informative Profile,
// //could be added to the narcissist category and also super active
// } else if ("message-link".equals(type)){ //TODO
// //messages with link , events , for the moment are not treated since no Informative Profile,
// //could be added to the narcissist category and also super active
} //end switch case
}
private void incrementManiacStatistics(String lastTime, String current_id, String maniacType, Profile.Type ptype, int profile) {
String profile_last_time=graph.getManiacLastTime(current_id+maniacType, ptype);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
try {
if (sdf.parse(profile_last_time).
before(sdf.parse(lastTime))){
graph.incrementManiacNumber(current_id+maniacType, ptype);
updateProfileStatistics(current_id, lastTime, profile_last_time, profile);
}
} catch (ParseException e){
e.printStackTrace();
}
}
private void repliesComments(ActivityEntry activity, String source , String viewer , String current_id,int option ){
// logger.debug("analysing possible comments of the post");
// org.w3c.dom.Element comments=(Element)activity.item(12);
// NodeList comment_list=comments.getElementsByTagName("comment");
// for (int k=0;k<comment_list.getLength();k++){
// org.w3c.dom.Node comment=comment_list.item(k).getFirstChild();
// if(comment.getNodeName().equals("fromid")){
//
// //comments of the stream post
// String comment_sourceId=comment.getTextContent();
// String profile_lastTime=service.getSuperActiveManiacLastTime(current_id+"_SuperActiveManiac");
// String lastTime=comment.getNextSibling().getTextContent();
// String text=comment.getNextSibling().getNextSibling().getTextContent();
// logger.debug(" comment fromid "+comment_sourceId+" text "+text+" lastTime "+lastTime );
//
// if (comment_sourceId.equals(viewer)){
// if (Integer.parseInt(profile_lastTime)<Integer.parseInt(lastTime)){
// logger.debug("Super Active Altruist Maniac interaction - comment reply");
// service.incrementSuperActiveManiacNumber(current_id+"_SuperActiveManiac");
// updateProfileStatistics(current_id, lastTime, profile_lastTime, SUPERACTIVE_PROFILE);
//
//// try { //FIXME: disabilitato la pubblicazione sul blog
//// switch(option){
//// case REPLY_TO_ME:{
//// publishOnBlog("Super - Active Interaction",textGenerator.replyCommentToMe(lastTime, text),service.getPersonCAName(current_id));
//// break;
//// }
//// case REPLY_TO_OTHER_CA:{
//// publishOnBlog("Super - Active Interaction",textGenerator.replyCommentToCAUser(lastTime.toString(), text, service.getPersonCAName(source)), service.getPersonCAName(current_id));
//// break;
//// }
//// case REPLY_TO_STRANGER_CA:{
//// publishOnBlog("Super - Active Interaction",textGenerator.replyCommentToCAStranger(lastTime, text), service.getPersonCAName(current_id));
//// break;
//// }
//// }
////
//// } catch (MalformedURLException e) {
//// logger.error("unable to publish post on blog;Reason "+e);
//// e.printStackTrace();
//// } catch (XmlRpcException e) {
//// logger.error("unable to publish post on blog;Reason "+e);
//// e.printStackTrace();
//// }
// }
// }
// }// if from_id
// }//for comment_list
}
public void generateUserInformation(String current_id, List<?> profiles){
logger.info("===== [MAKE Basic INFO] GeneralInfo and Interests for user "+current_id);
ArrayList <Long> userId=new ArrayList<Long> ();
userId.add(Long.parseLong(current_id));
Person user = null;
if (profiles.size()>0)
user = (Person) profiles.get(0); // to be improved!!!!
if (user != null) {
// TODO: Transform List of values into strings!
java.util.Date updatedDate = user.getUpdated();
String updatedDateS = null;
if (updatedDate != null)
updatedDateS = updatedDate.toString();
graph.updateInterests(current_id+"_Interests",
"",
"",
"",
"",
"",
"",
user.getAboutMe(),
updatedDateS);
try {
String first = null;
if (user.getName() != null) {
first = user.getName().getGivenName();
if (first == null)
first = user.getName().getFormatted();
}
String currentLoc = null;
if (user.getCurrentLocation() != null)
currentLoc = user.getCurrentLocation().getFormatted();
String birthday = null;
if (user.getBirthday() != null)
birthday = user.getBirthday().toString();
String gender = null;
if (user.getGender() != null)
gender = user.getGender().toString();
graph.updateGeneralInfo(current_id+"_GeneralInfo",
first,
user.getName().getFamilyName(),
birthday,
gender,
user.getLivingArrangement(),
currentLoc,
user.getPoliticalViews(),
user.getReligion());
} catch (Exception e){
e.printStackTrace();
}
}else {
graph.updateInterests(current_id+"_Interests",
"",
"",
"",
"",
"",
"",
null,
null);
graph.updateGeneralInfo(current_id+"_GeneralInfo",
null,
null,
null,
null,
null,
null,
null,
null);
}
}
public void initialiseUserProfiles(String current_id, SocialPerson person){
Date d = new Date(0);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
logger.info("@@@@ creating and initialising the user profiles @@@@");
logger.debug(" ---- NarcissismManiac---Profile ");
graph.linkManiac(person,current_id+"_NarcissismManiac", Profile.Type.EGO_CENTRIC);
graph.updateManiac(current_id+"_NarcissismManiac", Profile.Type.EGO_CENTRIC, "0", sdf.format(d), "0");
logger.debug(" ---- SuperActiveManiac---Profile ");
graph.linkManiac(person, current_id+"_SuperActiveManiac", Profile.Type.SUPER_ACTIVE);
graph.updateManiac(current_id+"_SuperActiveManiac", Profile.Type.SUPER_ACTIVE, "0", sdf.format(d), "0");
logger.debug(" ---- PhotoManiac---Profile ");
graph.linkManiac(person, current_id+"_PhotoManiac", Profile.Type.PHOTO_MANIAC);
graph.updateManiac(current_id+"_PhotoManiac", Profile.Type.PHOTO_MANIAC, "0", sdf.format(d), "0");
logger.debug(" ---- SurfManiac---Profile ");
graph.linkManiac(person, current_id+"_SurfManiac", Profile.Type.SURF_MANIAC);
graph.updateManiac(current_id+"_SurfManiac", Profile.Type.SURF_MANIAC, "0", sdf.format(d), "0");
logger.debug(" ---- QuizManiac---Profile ");
graph.linkManiac(person, current_id+"_QuizManiac", Profile.Type.QUIZ_MANIAC);
graph.updateManiac(current_id+"_QuizManiac", Profile.Type.QUIZ_MANIAC, "0", sdf.format(d),"0");
}
public void updateProfileStatistics(String userId, String lastTime, String lastTime_old,int option)
{
String maniacType;
Profile.Type ptype;
switch(option){
case NARCISSISM_PROFILE:{
maniacType="_NarcissismManiac";
ptype=Profile.Type.EGO_CENTRIC;
break;
}
case SUPERACTIVE_PROFILE:{
maniacType="_SuperActiveManiac";
ptype=Profile.Type.SUPER_ACTIVE;
break;
}
case PHOTO_PROFILE:{
maniacType="_PhotoManiac";
ptype=Profile.Type.PHOTO_MANIAC;
break;
}
case SURF_PROFILE:{
maniacType="_SurfManiac";
ptype=Profile.Type.SURF_MANIAC;
break;
}
case QUIZ_PROFILE:{
maniacType="_QuizManiac";
ptype=Profile.Type.QUIZ_MANIAC;
break;
}
default:{
return;
}
}
int number= graph.getManiacNumber(userId+maniacType, ptype);
// databaseConnection.sendMomentToDatabase(userId,lastTime,number,option);
if (number >=2){
long old_frequency=graph.getManiacFrequency(userId+maniacType, ptype);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
long frequency;
try {
frequency = (sdf.parse(lastTime).getTime() - sdf.parse(lastTime_old).getTime()+((number-2)*old_frequency))/(number-1);
graph.updateManiac(userId+maniacType, ptype, String.valueOf(frequency),lastTime, null);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
graph.updateManiac(userId+maniacType, ptype, null,lastTime, null);
}
}
public void generateUniformProfilePercentagesUsingBayesianSystem() {
ArrayList<String> list_usersIds;
try {
list_usersIds = graph.getGraphNodesIds(graph.getAllGraphNodes());
} catch (NeoException e) {
logger.error("Cannot get graph nodes IDs: " + e.getMessage());
return;
}
update_Users_Profile_Percentages(list_usersIds);
//ArrayList<Float> parameters=calculate_Parameters_mc(list_usersIds);
ArrayList<Float> parameters1=calculate_Parameters_mc_BoxPlot(list_usersIds);
updateProfilePercentages_UsingBayesianEstimator(list_usersIds,parameters1);
}
private void update_Users_Profile_Percentages(ArrayList <String> list_usersIds){
logger.debug("going through the network and updating the profile percentages for each user ..");
for (int i=0;i<list_usersIds.size();i++){
String userId=list_usersIds.get(i);
int narcissismNumber=graph.getManiacNumber(userId+"_NarcissismManiac", Profile.Type.EGO_CENTRIC);
int photoNumber=graph.getManiacNumber(userId+"_PhotoManiac", Profile.Type.PHOTO_MANIAC);
int superActiveNumber=graph.getManiacNumber(userId+"_SuperActiveManiac", Profile.Type.SUPER_ACTIVE);
int surfNumber=graph.getManiacNumber(userId+"_SurfManiac", Profile.Type.SURF_MANIAC);
int quizNumber=graph.getManiacNumber(userId+"_QuizManiac", Profile.Type.QUIZ_MANIAC);
float total=narcissismNumber+photoNumber+superActiveNumber+surfNumber+quizNumber;
if(total==0){
logger.info("person "+userId+" hasn't done any type of actions ->will be ignored from this analysis");
graph.updatePersonPercentages(userId, "0","0","0","0","0","0");
}else{
logger.info("person "+userId+" has done "+narcissismNumber+" narcissism, "+superActiveNumber
+" super active, "+photoNumber +" photoManiac, "+surfNumber +" surfManiac, "+quizNumber +" quizManiac, ");
float narcissismPercentage=(float)(narcissismNumber/total);
float superActivePercentage=(float)(superActiveNumber/total);
float photoPercentage=(float)(photoNumber/total);
float surfPercentage=(float)(surfNumber/total);
float quizPercentage=(float)(quizNumber/total);
graph.updatePersonPercentages(userId, String.valueOf(narcissismPercentage),
String.valueOf(superActivePercentage),String.valueOf(photoPercentage),
String.valueOf(surfPercentage),String.valueOf(quizPercentage),
String.valueOf(total));
logger.info("profile percentages : narcissism "+narcissismPercentage+
", superActive "+superActivePercentage+", photo "+photoPercentage+", surf "+
surfPercentage+", quiz "+quizPercentage);
}
}
}
private ArrayList<Float> calculate_Parameters_mc_BoxPlot(ArrayList <String> list_usersIds){
//parameter m = average number of points for a profile
//parameter c=average rating for a profile
ArrayList <Float> parameters=new ArrayList<Float>();
ArrayList <Float> narcissismNumbers = new ArrayList<Float>(),
superActiveNumbers= new ArrayList<Float>(),
photoNumbers= new ArrayList<Float>(),
surfNumbers= new ArrayList<Float>(),
quizNumbers= new ArrayList<Float>();
ArrayList <Float>narcissismPercentages= new ArrayList<Float>(),
superActivePercentages= new ArrayList<Float>(),
photoPercentages= new ArrayList<Float>(),
surfPercentages= new ArrayList<Float>(),
quizPercentages=new ArrayList<Float>();
logger.debug("calculating parameters M and C for each profile ");
int narcissism=0,superActive=0,photo=0,surf=0,quiz=0;
float narcissismPercentage=0,superActivePercentage=0,photoPercentage=0,surfPercentage=0,quizPercentage=0;
for (int i=0;i<list_usersIds.size();i++){
String userId=list_usersIds.get(i);
narcissism=graph.getManiacNumber(userId+"_NarcissismManiac", Profile.Type.EGO_CENTRIC);
photo=graph.getManiacNumber(userId+"_PhotoManiac", Profile.Type.PHOTO_MANIAC);
superActive=graph.getManiacNumber(userId+"_SuperActiveManiac", Profile.Type.SUPER_ACTIVE);
surf=graph.getManiacNumber(userId+"_SurfManiac", Profile.Type.SURF_MANIAC);
quiz=graph.getManiacNumber(userId+"_QuizManiac", Profile.Type.QUIZ_MANIAC);
logger.info("calculating parameters M and C for " + userId + ": n " + narcissism);
if (narcissism>0){
narcissismNumbers.add(Float.valueOf((float)narcissism));
narcissismPercentage=Float.parseFloat(graph.getPersonProfilePercentage(userId, Profile.Type.EGO_CENTRIC));
narcissismPercentages.add(narcissismPercentage);
}
if (superActive>0){
superActiveNumbers.add(Float.valueOf((float)superActive));
superActivePercentage=Float.parseFloat(graph.getPersonProfilePercentage(userId, Profile.Type.SUPER_ACTIVE));
superActivePercentages.add(superActivePercentage);
}
if (photo>0){
photoNumbers.add(Float.valueOf((float)photo));
photoPercentage=Float.parseFloat(graph.getPersonProfilePercentage(userId, Profile.Type.PHOTO_MANIAC));
photoPercentages.add(photoPercentage);
}
if (surf>0){
surfNumbers.add(Float.valueOf((float)surf));
surfPercentage=Float.parseFloat(graph.getPersonProfilePercentage(userId, Profile.Type.SURF_MANIAC));
surfPercentages.add(surfPercentage);
}
if (quiz>0){
quizNumbers.add(Float.valueOf((float)quiz));
quizPercentage=Float.parseFloat(graph.getPersonProfilePercentage(userId, Profile.Type.QUIZ_MANIAC));
quizPercentages.add(quizPercentage);
}
}
//m parameters
parameters.add(graph.calculateAverageUsingBoxplot(narcissismNumbers));
parameters.add(graph.calculateAverageUsingBoxplot(superActiveNumbers));
parameters.add(graph.calculateAverageUsingBoxplot(photoNumbers));
parameters.add(graph.calculateAverageUsingBoxplot(surfNumbers));
parameters.add(graph.calculateAverageUsingBoxplot(quizNumbers));
//c parameters
parameters.add(graph.calculateAverageUsingBoxplot(narcissismPercentages));
parameters.add(graph.calculateAverageUsingBoxplot(superActivePercentages));
parameters.add(graph.calculateAverageUsingBoxplot(photoPercentages));
parameters.add(graph.calculateAverageUsingBoxplot(surfPercentages));
parameters.add(graph.calculateAverageUsingBoxplot(quizPercentages));
logger.info("Parameters m :narcissism "+parameters.get(0)+
" superActive "+graph.calculateAverageUsingBoxplot(superActiveNumbers)+" photo "+
graph.calculateAverageUsingBoxplot(photoNumbers)+" surf "+
graph.calculateAverageUsingBoxplot(surfNumbers)+" quiz "+
graph.calculateAverageUsingBoxplot(quizNumbers));
logger.info("Parameters c :narcissism "+graph.calculateAverageUsingBoxplot(narcissismPercentages)+
" superActive "+graph.calculateAverageUsingBoxplot(superActivePercentages)+" photo "+
graph.calculateAverageUsingBoxplot(photoPercentages)+" surf "+
graph.calculateAverageUsingBoxplot(surfPercentages)+" quiz "+
graph.calculateAverageUsingBoxplot(quizPercentages));
return parameters;
}
private void updateProfilePercentages_UsingBayesianEstimator(ArrayList <String> list_usersIds,ArrayList <Float> parameters){
//parameter m = average number of points for a profile
//parameter c=average rating for a profile
//Weighted rating -> replaces the old rating (percentage) using bayes formula
logger.debug("updating profiles percentages using bayesian estimator");
//ArrayList <String> list_usersIds=service.getGraphNodesIds(service.getGraphNodes(person));
for (int i=0;i<list_usersIds.size();i++){
String userId=list_usersIds.get(i);
logger.debug("userId "+userId);
boolean updated = false;
float narcissismNumber=(float) graph.getManiacNumber(userId+"_NarcissismManiac", Profile.Type.EGO_CENTRIC);
float wr_narcissism=Float.parseFloat(graph.getPersonProfilePercentage(userId, Profile.Type.EGO_CENTRIC));
if (narcissismNumber!=parameters.get(0)){
wr_narcissism=((narcissismNumber*wr_narcissism)+(parameters.get(0)*parameters.get(5)))/(narcissismNumber+parameters.get(0));
updated = true;
logger.info("replacing narcissist global percentage ,previous value "+narcissismNumber+
" current value"+wr_narcissism+" limit "+parameters.get(0));
}
float superActiveNumber=(float)graph.getManiacNumber(userId+"_SuperActiveManiac", Profile.Type.SUPER_ACTIVE);
float wr_superActive=Float.parseFloat(graph.getPersonProfilePercentage(userId, Profile.Type.SUPER_ACTIVE));
if (superActiveNumber!=parameters.get(1)){
wr_superActive=((superActiveNumber*wr_superActive)+(parameters.get(1)*parameters.get(6)))/(superActiveNumber+parameters.get(1));
updated = true;
logger.debug("replacing super active global percentage ,previous value "+superActiveNumber+
" current value"+wr_superActive+" limit "+parameters.get(0));
}
float photoNumber=graph.getManiacNumber(userId+"_PhotoManiac", Profile.Type.PHOTO_MANIAC);
float wr_photo=Float.parseFloat(graph.getPersonProfilePercentage(userId, Profile.Type.PHOTO_MANIAC));
if (photoNumber!=parameters.get(2)){
wr_photo=((photoNumber*wr_photo)+(parameters.get(2)*parameters.get(7)))/(photoNumber+parameters.get(2));
updated = true;
logger.debug("replacing photo global percentage ,previous value "+photoNumber+
" current value"+wr_photo+" limit "+parameters.get(0));
}
float surfNumber=graph.getManiacNumber(userId+"_SurfManiac", Profile.Type.SURF_MANIAC);
float wr_surf=Float.parseFloat(graph.getPersonProfilePercentage(userId, Profile.Type.SURF_MANIAC));
if (surfNumber!=parameters.get(3)){
wr_surf=((surfNumber*wr_surf)+(parameters.get(3)*parameters.get(8)))/(surfNumber+parameters.get(3));
updated = true;
logger.debug("replacing surf global percentage ,previous value "+surfNumber+
" current value"+wr_surf+" limit "+parameters.get(0));
}
int quizNumber=graph.getManiacNumber(userId+"_QuizManiac", Profile.Type.QUIZ_MANIAC);
float wr_quiz=Float.parseFloat(graph.getPersonProfilePercentage(userId, Profile.Type.QUIZ_MANIAC));
if (quizNumber!=parameters.get(4)){
wr_quiz=((quizNumber*wr_quiz)+(parameters.get(4)*parameters.get(9)))/(quizNumber+parameters.get(4));
updated = true;
logger.debug("replacing quiz global percentage ,previous value "+quizNumber+
" current value"+wr_quiz+" limit "+parameters.get(0));
}
if (updated)
graph.updatePersonPercentages(userId, String.valueOf(wr_narcissism), String.valueOf(wr_superActive),
String.valueOf(wr_photo), String.valueOf(wr_surf), String.valueOf(wr_quiz),null);
}
}
}