package org.societies.platform.socialdata; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.concurrent.ExecutionException; import org.apache.shindig.social.opensocial.model.Group; import org.apache.shindig.social.opensocial.model.Person; import org.json.JSONException; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.societies.api.context.CtxException; import org.societies.api.context.model.CtxAssociation; import org.societies.api.context.model.CtxAssociationIdentifier; import org.societies.api.context.model.CtxAssociationTypes; import org.societies.api.context.model.CtxAttribute; import org.societies.api.context.model.CtxAttributeTypes; import org.societies.api.context.model.CtxAttributeValueType; import org.societies.api.context.model.CtxEntity; import org.societies.api.context.model.CtxEntityIdentifier; import org.societies.api.context.model.CtxEntityTypes; import org.societies.api.context.model.CtxIdentifier; import org.societies.api.context.model.CtxModelType; import org.societies.api.context.model.IndividualCtxEntity; import org.societies.api.identity.IIdentity; import org.societies.api.internal.context.broker.ICtxBroker; import org.societies.api.internal.sns.ISocialConnector; import org.societies.platform.socialdata.converters.FriendsConverter; import org.societies.platform.socialdata.converters.FriendsConveterFactory; import org.societies.platform.socialdata.converters.GroupConverter; import org.societies.platform.socialdata.converters.GroupConveterFactory; import org.societies.platform.socialdata.converters.PersonConverter; import org.societies.platform.socialdata.converters.PersonConverterFactory; public class ContextUpdater { /** The logging facility. */ private static final Logger LOG = LoggerFactory .getLogger(ContextUpdater.class); ICtxBroker internalCtxBroker = null; IIdentity cssId = null; String snName; CtxEntity socialNetworkEntity = null; List<ISocialConnector> connectors = new ArrayList<ISocialConnector>(); public ContextUpdater(ICtxBroker internalCtxBroker, IIdentity cssId) { LOG.debug("updating user profile in context: broker service: " + internalCtxBroker); this.cssId = cssId; this.internalCtxBroker = internalCtxBroker; } Runnable updateCtxProfileThread = new Runnable() { @Override public void run() { LOG.debug(" Updating CtxBroker - Updater thread started ...."); for (ISocialConnector connector : connectors) updateCtxProfile(connector); LOG.debug("CtxBroker Updated - Updater thread is over."); } }; public void updateSocialData(List<ISocialConnector> connectors) { this.connectors = connectors; new Thread(updateCtxProfileThread).start(); } public void updateCtxProfile(ISocialConnector connector) { LOG.debug(" Updating profile data for " + connector.getConnectorName()); this.snName = connector.getConnectorName(); this.socialNetworkEntity = this.getSnCtxEntity(); // Update Simple Profile PersonConverter parser = PersonConverterFactory.getConverter(connector); Person profile = parser.load(connector.getUserProfile()); // updateStringFieldIfExists(snName, CtxAttributeTypes.TYPE); updateStringFieldIfExist(profile.getAboutMe(), CtxAttributeTypes.ABOUT); updateStringFieldIfExist(profile.getProfileUrl(), CtxAttributeTypes.PROFILE_IMAGE_URL); updateStringFieldIfExist(profile.getDisplayName(), CtxAttributeTypes.NAME); if (profile.getName() != null) { updateStringFieldIfExist(profile.getName().getGivenName(),CtxAttributeTypes.NAME_FIRST); updateStringFieldIfExist(profile.getName().getFamilyName(), CtxAttributeTypes.NAME_LAST); } // updateStringFieldIfExist(profile.getPhoneNumbers(), // CtxAttributeTypes.PHONES); updateStringFieldIfExist(profile.getPoliticalViews(), CtxAttributeTypes.POLITICAL_VIEWS); updateStringFieldIfExist(profile.getPreferredUsername(),CtxAttributeTypes.USERNAME); updateStringFieldIfExist(profile.getThumbnailUrl(),CtxAttributeTypes.USERNAME); updateStringFieldIfExist(profile.getRelationshipStatus(),CtxAttributeTypes.STATUS); updateStringFieldIfExist(profile.getReligion(),CtxAttributeTypes.RELIGIOUS_VIEWS); if (profile.getGender() != null) updateStringFieldIfExist(profile.getGender().name(),CtxAttributeTypes.SEX); if (profile.getBirthday() != null) updateStringFieldIfExist(profile.getBirthday().toGMTString(), CtxAttributeTypes.BIRTHDAY); if (profile.getCurrentLocation() != null) updateStringFieldIfExist(profile.getCurrentLocation().getFormatted(), CtxAttributeTypes.LOCATION_SYMBOLIC); updateStringFieldIfExist(profile.getBooks(), CtxAttributeTypes.BOOKS); updateStringFieldIfExist(profile.getMusic(), CtxAttributeTypes.MUSIC); updateStringFieldIfExist(profile.getInterests(),CtxAttributeTypes.INTERESTS); updateStringFieldIfExist(profile.getJobInterests(),CtxAttributeTypes.JOBS_INTERESTS); updateStringFieldIfExist(profile.getLanguagesSpoken(),CtxAttributeTypes.LANGUAGES); updateStringFieldIfExist(profile.getMovies(), CtxAttributeTypes.MOVIES); updateStringFieldIfExist(profile.getTurnOns(),CtxAttributeTypes.TURNSON); updateStringFieldIfExist(profile.getActivities(),CtxAttributeTypes.ACTIVITIES); // updateStringFieldIfExist(profile.getEmails(), // CtxAttributeTypes.EMAIL); LOG.debug(" Updating Friends List ..."); // Add Friends List FriendsConverter friendsParser = FriendsConveterFactory.getConverter(connector); List<Person> friends = friendsParser.load(connector.getUserFriends()); storeFriendsIntoContextBroker(friends); LOG.debug(" Updating Groups list ..."); // Add Group List GroupConverter groupConverter = GroupConveterFactory.getConverter(connector); List<Group> groups = groupConverter.load(connector.getUserGroups()); storeGroupsIntoContextBroker(groups); } private void updateStringFieldIfExist(String value, String type) { try { if (value != null) { LOG.info("update " + type + " data" + value); storeSocialDataIntoContextBroker(type, value); LOG.info(snName + " entity updated with " + type + " data " + socialNetworkEntity.getId()); } else LOG.debug(type + " value is NULL"); } catch (Exception ex) { LOG.error("Unable to store :" + type + " -> " + value + " because " + ex, ex); } } private void updateStringFieldIfExist(List<String> listOfvalues, String type) { if (listOfvalues != null) { String value = updateListData(listOfvalues); updateStringFieldIfExist(value, type); } else LOG.debug(type + " value is NULL"); } private CtxEntity getSnCtxEntity() { IndividualCtxEntity individualEntity; CtxAssociation snsAssoc = null; CtxEntity socialNetwork = null; try { individualEntity = this.internalCtxBroker.retrieveIndividualEntity( this.cssId).get(); Set<CtxAssociationIdentifier> snsAssocSet = individualEntity .getAssociations(CtxAssociationTypes.IS_CONNECTED_TO_SNS); LOG.debug("There are " + snsAssocSet.size() + " associations with SocialNetworks"); if (snsAssocSet.size() > 0) { List<CtxAssociationIdentifier> snsAssocList = new ArrayList<CtxAssociationIdentifier>( snsAssocSet); for (CtxAssociationIdentifier assocID : snsAssocList) { snsAssoc = (CtxAssociation) this.internalCtxBroker .retrieve(assocID).get(); Set<CtxEntityIdentifier> snsEntitiesSet = snsAssoc .getChildEntities(CtxEntityTypes.SOCIAL_NETWORK); List<CtxEntityIdentifier> snsEntitiesList = new ArrayList<CtxEntityIdentifier>( snsEntitiesSet); LOG.debug("lookup SN association" + snName); // List<CtxEntityIdentifier> snEntList = // this.internalCtxBroker.lookupEntities(snsEntitiesList, // CtxAttributeTypes.NAME, snName).get(); List<CtxEntityIdentifier> snEntList = this.internalCtxBroker .lookupEntities(snsEntitiesList, CtxAttributeTypes.TYPE, snName).get(); // List<CtxEntityIdentifier> snEntList = // this.internalCtxBroker.lookupEntities(snsEntitiesList, // CtxAttributeTypes.NAME, snName).get(); if (snEntList.size() > 0) { socialNetwork = (CtxEntity) this.internalCtxBroker .retrieve(snEntList.get(0)).get(); return socialNetwork; } } } LOG.info("NO Asscotiation found the User Entity"); snsAssoc = this.internalCtxBroker.createAssociation( CtxAssociationTypes.IS_CONNECTED_TO_SNS).get(); LOG.info("---> snsAssoc created "); List<CtxEntityIdentifier> snEntitiesList = this.internalCtxBroker .lookupEntities(CtxEntityTypes.SOCIAL_NETWORK, CtxAttributeTypes.TYPE, snName, snName).get(); if (snEntitiesList.size() == 0) { LOG.info("No SocialNetwork entity for this SN:" + snName); socialNetwork = this.internalCtxBroker.createEntity( CtxEntityTypes.SOCIAL_NETWORK).get(); LOG.info("SOCIAL_NETWORK entity created" + socialNetwork.getId()); CtxAttribute snsNameAttr = this.internalCtxBroker .createAttribute(socialNetwork.getId(), CtxAttributeTypes.TYPE).get(); snsNameAttr.setStringValue(snName); this.internalCtxBroker.update(snsNameAttr); } else { socialNetwork = (CtxEntity) this.internalCtxBroker.retrieve( snEntitiesList.get(0)).get(); } LOG.debug("Add Association ..."); snsAssoc.addChildEntity(socialNetwork.getId()); snsAssoc.addChildEntity(individualEntity.getId()); snsAssoc.setParentEntity(individualEntity.getId()); snsAssoc = (CtxAssociation) this.internalCtxBroker.update(snsAssoc) .get(); this.internalCtxBroker.update(individualEntity); } catch (InterruptedException e) { LOG.error("Error:" + e, e); e.printStackTrace(); } catch (ExecutionException e) { LOG.error("Error:" + e, e); e.printStackTrace(); } catch (CtxException e) { LOG.error("Error:" + e, e); e.printStackTrace(); } return socialNetwork; } private CtxEntity storeSocialDataIntoContextBroker(String type, Serializable value) { CtxAttribute attribute = null; try { if (socialNetworkEntity != null) { LOG.info(">>>>> Updating user profile in context " + type + " values" + value); List<CtxIdentifier> attributeIdentifiers = this.internalCtxBroker .lookup(socialNetworkEntity.getId(), CtxModelType.ATTRIBUTE, type).get(); if (attributeIdentifiers.size() > 0) { LOG.info("updating " + snName + " profile in context 1"); CtxIdentifier attrId = attributeIdentifiers.get(0); attribute = (CtxAttribute) this.internalCtxBroker.retrieve( attrId).get(); attribute = setAttrValueType(attribute, type, value); attribute = (CtxAttribute) this.internalCtxBroker.update( attribute).get(); } else { LOG.info("Insert attribute in user profile in context 2"); attribute = this.internalCtxBroker.createAttribute( socialNetworkEntity.getId(), type).get(); attribute = setAttrValueType(attribute, type, value); attribute = (CtxAttribute) this.internalCtxBroker.update( attribute).get(); } socialNetworkEntity = (CtxEntity) this.internalCtxBroker .update(socialNetworkEntity).get(); } else LOG.warn("Social Network Entity is NULL"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (CtxException e) { // TODO Auto-generated catch block e.printStackTrace(); } return socialNetworkEntity; } private CtxEntity storeFriendsIntoContextBroker(List<Person> friends) { CtxAttribute attribute = null; try { if (socialNetworkEntity != null) { LOG.info(">>>>> Check if FRIENDS fiels is already stored "); List<CtxIdentifier> attributeFriendsIdentifiers = this.internalCtxBroker .lookup(socialNetworkEntity.getId(), CtxModelType.ATTRIBUTE, CtxAttributeTypes.FRIENDS).get(); for (CtxIdentifier ctxID : attributeFriendsIdentifiers) { this.internalCtxBroker.remove(ctxID); } attribute = this.internalCtxBroker.createAttribute( socialNetworkEntity.getId(), CtxAttributeTypes.FRIENDS) .get(); attribute = setAttrValueType(attribute, CtxAttributeTypes.FRIENDS, friends.size() + " " + snName + " friends"); attribute = (CtxAttribute) this.internalCtxBroker.update( attribute).get(); for (Person friend : friends) { String name = ""; if (friend.getAccounts() != null) { if (friend.getAccounts().size() > 0) { name += friend.getAccounts().get(0).getDomain() + ","; } } name += friend.getId() + ","; // First just the name name = ""; try { if (friend.getName() != null) { if (friend.getName().getFormatted() != null) name += friend.getName().getFormatted(); else { if (friend.getName().getFamilyName() != null) name += friend.getName().getFamilyName(); if (friend.getName().getGivenName() != null) { if (name.length() > 0) name += " "; name += friend.getName().getGivenName(); } } } if (name.length() == 0) name = friend.getId(); LOG.info("Add friend [attribute]:" + name); attribute = this.internalCtxBroker.createAttribute( socialNetworkEntity.getId(), CtxAttributeTypes.FRIENDS).get(); attribute = setAttrValueType(attribute, CtxAttributeTypes.FRIENDS, name); attribute = (CtxAttribute) this.internalCtxBroker .update(attribute).get(); } catch (Exception ex) { LOG.error("Unable to find a name for this friend", ex); } } socialNetworkEntity = (CtxEntity) this.internalCtxBroker .update(socialNetworkEntity).get(); } else LOG.warn("Social Network Entity is NULL"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (CtxException e) { // TODO Auto-generated catch block e.printStackTrace(); } return socialNetworkEntity; } private CtxEntity storeGroupsIntoContextBroker(List<Group> groups) { CtxAttribute attribute = null; try { if (socialNetworkEntity != null) { LOG.info(">>>>> Check if GROUPS fiels is already stored "); List<CtxIdentifier> attributeGroupssIdentifiers = this.internalCtxBroker .lookup(socialNetworkEntity.getId(), CtxModelType.ATTRIBUTE, CtxAttributeTypes.GROUP) .get(); for (CtxIdentifier ctxID : attributeGroupssIdentifiers) { this.internalCtxBroker.remove(ctxID); } for (Group group : groups) { String value = group.getDescription(); LOG.info("Insert Group:" + value + "+ to user profile"); attribute = this.internalCtxBroker.createAttribute( socialNetworkEntity.getId(), CtxAttributeTypes.GROUP).get(); attribute = setAttrValueType(attribute, CtxAttributeTypes.GROUP, value); attribute = (CtxAttribute) this.internalCtxBroker.update( attribute).get(); } socialNetworkEntity = (CtxEntity) this.internalCtxBroker .update(socialNetworkEntity).get(); } else LOG.warn("Social Network Entity is NULL"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (CtxException e) { // TODO Auto-generated catch block e.printStackTrace(); } return socialNetworkEntity; } private String updateListData(List<String> data) { String valueString = ""; try { for (int i = 0; i < data.size(); i++) { JSONObject jsonResponse = new JSONObject(data.get(i)); String value = jsonResponse.get("value").toString(); if (valueString.length() > 0) valueString += ","; valueString += value; } } catch (JSONException e) { e.printStackTrace(); } return valueString; } private CtxAttribute setAttrValueType(CtxAttribute attribute, String type, Serializable value) { CtxAttribute updatedAttr = attribute; if (value == null) { updatedAttr.setValueType(CtxAttributeValueType.EMPTY); return updatedAttr; } else if (value instanceof String) { updatedAttr.setValueType(CtxAttributeValueType.STRING); updatedAttr.setStringValue(value.toString()); return updatedAttr; } else if (value instanceof Integer) { updatedAttr.setValueType(CtxAttributeValueType.INTEGER); updatedAttr.setIntegerValue((Integer) value); return updatedAttr; } else if (value instanceof Double) { updatedAttr.setValueType(CtxAttributeValueType.DOUBLE); updatedAttr.setDoubleValue((Double) value); return updatedAttr; } else if (value instanceof byte[]) { updatedAttr.setValueType(CtxAttributeValueType.BINARY); updatedAttr.setStringValue("_BLOB_"); return updatedAttr; } else throw new IllegalArgumentException(value + ": Invalid value type"); } public void removeConnectorData(ISocialConnector connector) { IndividualCtxEntity individualEntity; CtxAssociation snsAssoc = null; CtxEntity socialNetwork = null; LOG.debug("Removing data for" + connector.getConnectorName() + " social Network..."); try { individualEntity = this.internalCtxBroker.retrieveIndividualEntity( this.cssId).get(); Set<CtxAssociationIdentifier> snsAssocSet = individualEntity .getAssociations(CtxAssociationTypes.IS_CONNECTED_TO_SNS); LOG.debug("There are " + snsAssocSet.size() + " associations with SocialNetworks"); if (snsAssocSet.size() > 0) { List<CtxAssociationIdentifier> snsAssocList = new ArrayList<CtxAssociationIdentifier>( snsAssocSet); for (CtxAssociationIdentifier assocID : snsAssocList) { snsAssoc = (CtxAssociation) this.internalCtxBroker .retrieve(assocID).get(); Set<CtxEntityIdentifier> snsEntitiesSet = snsAssoc .getChildEntities(CtxEntityTypes.SOCIAL_NETWORK); List<CtxEntityIdentifier> snsEntitiesList = new ArrayList<CtxEntityIdentifier>( snsEntitiesSet); LOG.debug("lookup SN association" + snName); List<CtxEntityIdentifier> snEntList = this.internalCtxBroker .lookupEntities(snsEntitiesList, CtxAttributeTypes.TYPE, connector.getConnectorName()).get(); // List<CtxEntityIdentifier> snEntList = // this.internalCtxBroker // .lookupEntities(snsEntitiesList, // CtxAttributeTypes.NAME, // connector.getConnectorName()).get(); if (snEntList.size() > 0) { socialNetwork = (CtxEntity) this.internalCtxBroker .retrieve(snEntList.get(0)).get(); this.internalCtxBroker.remove(socialNetwork.getId()); this.internalCtxBroker.remove(assocID); LOG.debug("All data about " + connector.getConnectorName() + " has been removed."); } } } return; } catch (InterruptedException e) { LOG.error("Error " + e, e); e.printStackTrace(); } catch (ExecutionException e) { LOG.error("Error " + e, e); e.printStackTrace(); } catch (CtxException e) { LOG.error("Error " + e, e); e.printStackTrace(); } LOG.error("An unexpected has broken cleaning data of " + connector.getConnectorName()); } }