/** * 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.cis.manager; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.CollectionTable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.OneToMany; import javax.persistence.OneToOne; import javax.persistence.Table; import javax.persistence.Transient; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.annotations.CollectionOfElements; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.societies.activity.client.ActivityFeedClient; import org.societies.api.activity.IActivity; import org.societies.api.activity.IActivityFeed; import org.societies.api.activity.IActivityFeedManager; import org.societies.api.cis.attributes.MembershipCriteria; import org.societies.api.cis.attributes.Rule; import org.societies.api.cis.management.ICisManagerCallback; import org.societies.api.cis.management.ICisOwned; import org.societies.api.cis.management.ICisParticipant; import org.societies.api.cis.model.CisAttributeTypes; import org.societies.api.comm.xmpp.datatypes.Stanza; import org.societies.api.comm.xmpp.exceptions.CommunicationException; import org.societies.api.comm.xmpp.exceptions.XMPPError; import org.societies.api.comm.xmpp.interfaces.ICommManager; import org.societies.api.comm.xmpp.interfaces.IFeatureServer; import org.societies.api.context.model.CtxAttributeValueType; import org.societies.api.context.model.MalformedCtxIdentifierException; import org.societies.api.css.directory.ICssDirectoryCallback; import org.societies.api.css.directory.ICssDirectoryRemote; import org.societies.api.identity.IIdentity; import org.societies.api.identity.InvalidFormatException; import org.societies.api.identity.Requestor; import org.societies.api.identity.RequestorCis; import org.societies.api.identity.util.DataIdentifierFactory; import org.societies.api.identity.util.RequestorUtils; import org.societies.api.internal.comm.ICISCommunicationMgrFactory; import org.societies.api.internal.privacytrust.privacyprotection.IPrivacyDataManager; import org.societies.api.internal.privacytrust.privacyprotection.IPrivacyPolicyManager; import org.societies.api.internal.privacytrust.privacyprotection.util.remote.Util; import org.societies.api.privacytrust.privacy.model.PrivacyException; import org.societies.api.privacytrust.privacy.util.privacypolicy.DecisionUtils; import org.societies.api.schema.activityfeed.AddActivityResponse; import org.societies.api.schema.activityfeed.CleanUpActivityFeedResponse; import org.societies.api.schema.activityfeed.DeleteActivityResponse; import org.societies.api.schema.activityfeed.GetActivitiesResponse; import org.societies.api.schema.activityfeed.MarshaledActivityFeed; import org.societies.api.schema.cis.community.AddMemberResponse; import org.societies.api.schema.cis.community.Community; import org.societies.api.schema.cis.community.CommunityMethods; import org.societies.api.schema.cis.community.Criteria; import org.societies.api.schema.cis.community.DeleteMemberResponse; import org.societies.api.schema.cis.community.GetInfoResponse; import org.societies.api.schema.cis.community.GetMembershipCriteriaResponse; import org.societies.api.schema.cis.community.Join; import org.societies.api.schema.cis.community.JoinResponse; import org.societies.api.schema.cis.community.LeaveResponse; import org.societies.api.schema.cis.community.MembershipCrit; import org.societies.api.schema.cis.community.Participant; import org.societies.api.schema.cis.community.ParticipantRole; import org.societies.api.schema.cis.community.Qualification; import org.societies.api.schema.cis.community.SetInfoResponse; import org.societies.api.schema.cis.community.SetMembershipCriteriaResponse; import org.societies.api.schema.cis.community.WhoResponse; import org.societies.api.schema.cis.manager.CommunityManager; import org.societies.api.schema.cis.manager.DeleteMemberNotification; import org.societies.api.schema.cis.manager.DeleteNotification; import org.societies.api.schema.cis.manager.Notification; import org.societies.api.schema.cis.manager.SubscribedTo; import org.societies.api.schema.css.directory.CssAdvertisementRecord; import org.societies.api.schema.identity.DataIdentifier; import org.societies.api.schema.identity.DataIdentifierScheme; import org.societies.api.schema.identity.RequestorBean; import org.societies.api.schema.identity.RequestorCisBean; import org.societies.api.schema.privacytrust.privacy.model.privacypolicy.Action; import org.societies.api.schema.privacytrust.privacy.model.privacypolicy.Decision; import org.societies.api.schema.privacytrust.privacy.model.privacypolicy.ResponseItem; import org.societies.cis.manager.CisParticipant.MembershipType; import org.societies.cis.mgmtClient.CisManagerClient; /** * @author Thomas Vilarinho (Sintef) */ /** * This object corresponds to an owned CIS. The CIS record will be the CIS data which is stored on DataBase */ @Entity @Table(name = "org_societies_cis_manager_Cis") public class Cis implements IFeatureServer, ICisOwned { private static final long serialVersionUID = 1L; @Transient private final static List<String> NAMESPACES = Collections .unmodifiableList( Arrays.asList("http://societies.org/api/schema/cis/manager", "http://societies.org/api/schema/activityfeed", "http://societies.org/api/schema/cis/community")); @Transient private final static List<String> PACKAGES = Collections .unmodifiableList( Arrays.asList("org.societies.api.schema.cis.manager", "org.societies.api.schema.activityfeed", "org.societies.api.schema.cis.community")); @Transient private SessionFactory sessionFactory; @Transient private Session session; public SessionFactory getSessionFactory() { return sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name="cis_id") private Long id; // minimun attributes @OneToOne(cascade=CascadeType.ALL) public CisRecord cisRecord; @Transient public IActivityFeed activityFeed = null; //TODO: should this be persisted? @Transient private ICommManager CISendpoint; @Transient IPrivacyPolicyManager privacyPolicyManager = null; @Transient IPrivacyDataManager privacyDataManager = null; @Transient private ICssDirectoryRemote cssDirectoryRemote; public IPrivacyDataManager getPrivacyDataManager() { return privacyDataManager; } public void setPrivacyDataManager(IPrivacyDataManager privacyDataManager) { this.privacyDataManager = privacyDataManager; } public void setPrivacyPolicyManager(IPrivacyPolicyManager privacyPolicyManager) { this.privacyPolicyManager = privacyPolicyManager; } /**@return the cssDirectoryRemote */ public ICssDirectoryRemote getCssDirectoryRemote() { return cssDirectoryRemote; } /**@param cssDirectoryRemote the cssDirectoryRemote to set */ public void setCssDirectoryRemote(ICssDirectoryRemote cssDirectoryRemote) { this.cssDirectoryRemote = cssDirectoryRemote; } @Transient private IIdentity cisIdentity; @OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER,orphanRemoval=true) @JoinTable( name="org_societies_cis_manager_Cis_CisParticipant", joinColumns = @JoinColumn( name="cis_id"), inverseJoinColumns = @JoinColumn( name="cisparticipant_id") ) public Set<CisParticipant> membersCss; // TODO: this may be implemented in the CommunityManagement bundle. we need to define how they work together @Column public String cisType; @Column public String owner; @Column public String description = ""; @Column public String cisName = ""; @CollectionOfElements(targetElement = java.lang.String.class,fetch=FetchType.EAGER) @CollectionTable(name="org_societies_cis_manager_Cis_criteria",joinColumns = @JoinColumn(name = "cis_id")) @Column(name="criteria",length=500) public Set<String> membershipCritOnDb;// we will store it in the db as "context,rank,operator,value1,value2" @Transient Hashtable<String, MembershipCriteria> cisCriteria = null; private Set<String> getMembershipCritOnDb() { return membershipCritOnDb; } private void setMembershipCritOnDb(Set<String> membershipCritOnDb) { this.membershipCritOnDb = membershipCritOnDb; } public boolean checkQualification(HashMap<String,String> qualification){ for (String cisContext : cisCriteria.keySet()) { // loop through all my criterias if(qualification.containsKey(cisContext)){ MembershipCriteria m = cisCriteria.get(cisContext); // retrieves the context for that criteria if(m != null){ // if there is a rule we check it String valueToBeCompared = qualification.get(cisContext); if (! (m.getRule().checkRule(CtxAttributeValueType.STRING, valueToBeCompared))){ //TODO: this CtxAttributeValueType.STRING should be changed!! return false; } } } else{// did not have a needed context attribute in its qualification return false; } } return true; } private void buildCriteriaFromDb(){ for (String s : membershipCritOnDb) { // loop through all my criterias LOG.warn("on the loop to build criteria with crit = " + s); String[] tokens = s.split(":"); if(tokens == null || tokens.length < 4){ LOG.warn("Badly coded criteria on db"); return; }else{ MembershipCriteria m = new MembershipCriteria(); m.setRank(Integer.parseInt(tokens[1])); LOG.debug("rank set"); Rule r = new Rule(); r.setOperation(tokens[2]); LOG.debug("op set"); List<String> o = new ArrayList<String>(); o.add(tokens[3]); LOG.debug("token set"); if(tokens.length>4) o.add(tokens[4]); if( (r.setValues(o) && m.setRule(r)) != true) LOG.warn("Badly typed criteria on db"); LOG.debug("adding on table"); cisCriteria.put(tokens[0], m); LOG.debug("added on table"); } } } // TODO: restrict so someone can not add the same criteria twice public boolean addCriteria(String contextAtribute, MembershipCriteria m){ LOG.warn("adding criteria on db"); String s = contextAtribute; if(m.getRule() == null || m.getRule().getOperation() == null || m.getRule().getValues() == null || m.getRule().getValues().isEmpty()) return false; s += ":" + m.getRank(); s += ":" + m.getRule().getOperation(); LOG.warn("got operation"); for(int i=0; i<m.getRule().getValues().size() && i<2; i++){ s+= ":" + m.getRule().getValues().get(i); } LOG.warn("calling the list add inside the add criteria and s = " + s); membershipCritOnDb.add(s); LOG.warn("going to persist"); this.updatePersisted(this); LOG.warn("before putting on the table"); cisCriteria.put(contextAtribute, m); LOG.warn("criteria added on db"); return true; } //to be used only for the constructor public boolean addCriteriaWithoutDBcall(String contextAtribute, MembershipCriteria m){ LOG.warn("adding criteria on db"); String s = contextAtribute; if(m.getRule() == null || m.getRule().getOperation() == null || m.getRule().getValues() == null || m.getRule().getValues().isEmpty()) return false; s += ":" + m.getRank(); s += ":" + m.getRule().getOperation(); LOG.warn("got operation"); for(int i=0; i<m.getRule().getValues().size() && i<2; i++){ s+= ":" + m.getRule().getValues().get(i); } LOG.warn("calling the list add inside the add criteria and s = " + s); membershipCritOnDb.add(s); LOG.warn("going to persist"); LOG.warn("before putting on the table"); cisCriteria.put(contextAtribute, m); LOG.warn("criteria added on db"); return true; } public boolean removeCriteria(String contextAtribute, MembershipCriteria m){ if(cisCriteria.containsKey(contextAtribute) && cisCriteria.get(contextAtribute).equals(m)){ //rule is there, lets remove it String s = contextAtribute; if(m.getRule() == null || m.getRule().getOperation() == null || m.getRule().getValues() == null || m.getRule().getValues().isEmpty()) return false; s += ":" + m.getRank(); s += ":" + m.getRule().getOperation(); for(int i=0; i<m.getRule().getValues().size() && i<2; i++){ s+= ":" + m.getRule().getValues().get(i); } if( membershipCritOnDb.remove(s) != true) return false; this.updatePersisted(this); cisCriteria.remove(contextAtribute); // TODO: maybe inver this from the remove return true; } else { return false; } } @Override public String getDescription() { return description; } @Override public void setDescription(String description) { this.description = description; } @Override public IActivityFeed getActivityFeed() { return activityFeed; } private void setActivityFeed(IActivityFeed activityFeed) { this.activityFeed = activityFeed; } private static Logger LOG = LoggerFactory .getLogger(Cis.class); public Cis(){ } // internal method public CisParticipant getMember(String cssJid){ Set<CisParticipant> se = this.getMembersCss(); Iterator<CisParticipant> it = se.iterator(); while(it.hasNext()){ CisParticipant element = it.next(); if (element.getMembersJid().equals(cssJid)) return element; } return null; } // constructor of a CIS without a pre-determined ID or host public Cis(String cssOwner, String cisName, String cisType, ICISCommunicationMgrFactory ccmFactory, IPrivacyPolicyManager privacyPolicyManager, SessionFactory sessionFactory, String description, Hashtable<String, MembershipCriteria> inputCisCriteria,IActivityFeedManager iActivityFeedManager) { this.privacyPolicyManager = privacyPolicyManager; this.description = description; this.owner = cssOwner; this.cisType = cisType; this.cisName = cisName; membershipCritOnDb= new HashSet<String>(); membersCss = new HashSet<CisParticipant>(); membersCss.add(new CisParticipant(cssOwner,MembershipType.owner)); cisCriteria = new Hashtable<String, MembershipCriteria> (); LOG.debug("before adding membership criteria"); // adding membership criteria if(inputCisCriteria != null && inputCisCriteria.size() >0){ Iterator<Map.Entry<String, MembershipCriteria>> it = inputCisCriteria.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, MembershipCriteria> pairs = (Map.Entry<String, MembershipCriteria>)it.next(); LOG.debug("going to add criteria of attribute" + pairs.getKey()); if (this.addCriteriaWithoutDBcall(pairs.getKey(), pairs.getValue()) == false) LOG.debug("Got a false return when trying to add the criteria on the db");// TODO: add an exception here } } LOG.debug("CIS editor created"); try{ CISendpoint = ccmFactory.getNewCommManager(); } catch (CommunicationException e) { e.printStackTrace(); LOG.debug("could not start comm manager!"); } LOG.debug("CIS got new comm manager"); try { cisIdentity = CISendpoint.getIdManager().getThisNetworkNode();//CISendpoint.getIdManager().fromJid(CISendpoint.getIdManager().getThisNetworkNode().getJid()); } catch (Exception e) { e.printStackTrace(); } LOG.debug("CIS endpoint created"); try { CISendpoint.register(this); } catch (CommunicationException e) { e.printStackTrace(); this.unregisterCIS(); LOG.debug("could not start comm manager!"); } LOG.debug("CIS listener registered"); cisRecord = new CisRecord(cisName, cisIdentity.getJid(), cssOwner, description, cisType); LOG.debug("getting a new activity feed"); activityFeed = iActivityFeedManager.getOrCreateFeed(cssOwner, cisIdentity.getJid(), true ); // TODO: broadcast its creation to other nodes? LOG.debug("activityFeed: "+activityFeed); this.sessionFactory = sessionFactory; this.persist(this); IActivity iActivity = activityFeed.getEmptyIActivity(); iActivity.setActor(this.getOwnerId()); iActivity.setObject(cisIdentity.getJid()); iActivity.setVerb("created"); activityFeed.addActivity(iActivity, new ActivityFeedClient()) ; } public void startAfterDBretrieval(SessionFactory sessionFactory,ICISCommunicationMgrFactory ccmFactory,IPrivacyPolicyManager privacyPolicyManager, IPrivacyDataManager privacyDataManager, IActivityFeedManager iActivityFeedManager){ this.privacyPolicyManager = privacyPolicyManager; this.privacyDataManager = privacyDataManager; // first Ill try without members try { CISendpoint = ccmFactory.getNewCommManager(this.getCisId()); } catch (CommunicationException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } LOG.debug("retrieved COM manager"); try { cisIdentity = CISendpoint.getIdManager().getThisNetworkNode();//CISendpoint.getIdManager().fromJid(CISendpoint.getIdManager().getThisNetworkNode().getJid()); } catch (Exception e) { e.printStackTrace(); } LOG.debug("CIS endpoint created"); try { CISendpoint.register(this); } catch (CommunicationException e) { e.printStackTrace(); LOG.debug("could not start comm manager!"); this.unregisterCIS(); } LOG.debug("CIS listener registered"); this.setSessionFactory(sessionFactory); LOG.debug("building criteria from db"); cisCriteria = new Hashtable<String, MembershipCriteria> (); this.buildCriteriaFromDb(); LOG.debug("done building criteria from db"); // retrieve activity feed this.activityFeed = iActivityFeedManager.getOrCreateFeed(this.getOwnerId(), cisIdentity.getJid(), true); } public Set<CisParticipant> getMembersCss() { return membersCss; } public void setMembersCss(Set<CisParticipant> membersCss) { this.membersCss = membersCss; } // notifies cloud node private void nofityAddedUser(String jid, String role){ Stanza sta; LOG.debug("new member added, going to notify the user"); IIdentity targetCssIdentity = null; try { targetCssIdentity = this.CISendpoint.getIdManager().fromJid(jid); } catch (InvalidFormatException e) { LOG.debug("could not send addd notification"); e.printStackTrace(); } CommunityManager cMan = new CommunityManager(); Notification n = new Notification(); SubscribedTo s = new SubscribedTo(); Community com = new Community(); this.fillCommmunityXMPPobj(com); s.setRole(role.toString()); s.setCommunity(com); n.setSubscribedTo(s); cMan.setNotification(n); LOG.debug("finished building notification"); sta = new Stanza(targetCssIdentity); try { CISendpoint.sendMessage(sta, cMan); } catch (CommunicationException e) { // TODO Auto-generated catch block LOG.debug("problem sending notification to cis"); e.printStackTrace(); } LOG.debug("notification sent to the new user"); } @Override public boolean addMember(String jid, String role){ MembershipType typedRole; try{ typedRole = MembershipType.valueOf(role); }catch(IllegalArgumentException e) { return false; //the string was not valid } catch( NullPointerException e) { return false; //the string was not valid } boolean ret; ret = this.insertMember(jid, typedRole); // 1) Notifying the added user this.nofityAddedUser( jid, role); return ret; } // internal implementation of the method above private boolean insertMember(String jid, MembershipType role) { LOG.debug("add member invoked"); if (role == null) role = MembershipType.participant; // default role is participant if (membersCss.add(new CisParticipant(jid, role))){ //persist in database this.updatePersisted(this); //activityFeed notification IActivity iActivity = this.activityFeed.getEmptyIActivity(); iActivity.setActor(jid); iActivity.setObject(cisIdentity.getJid()); iActivity.setVerb("joined"); // TODO: perhaps, treat dummy return activityFeed.addActivity(iActivity,new ActivityFeedClient()) ; return true; }else{ return false; } } @Override public boolean removeMemberFromCIS(String jid) { IIdentity targetCssIdentity; try { targetCssIdentity = this.CISendpoint.getIdManager().fromJid(jid); } catch (InvalidFormatException e) { LOG.warn("bad jid when trying to delete from CIS!"); e.printStackTrace(); return false; } if (!this.removeMember(jid)) return false; // 2) Notification to deleted user here CommunityManager message = new CommunityManager(); Notification n = new Notification(); DeleteMemberNotification d = new DeleteMemberNotification(); d.setCommunityJid(this.getCisId()); d.setMemberJid(jid); n.setDeleteMemberNotification(d); message.setNotification(n); try { targetCssIdentity = this.CISendpoint.getIdManager().fromJid(jid); Stanza sta = new Stanza(targetCssIdentity); LOG.debug("stanza created"); this.CISendpoint.sendMessage(sta, message); } catch (InvalidFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (CommunicationException e) { // TODO Auto-generated catch block e.printStackTrace(); } return true; } // true if we were able to remove the user // false if not private boolean removeMember(String jid) { //TODO: add a check if it is a valid JID LOG.debug("remove member invoked"); if (membersCss.contains(new CisParticipant(jid))){ LOG.debug("user is a participant of the community"); // for database update CisParticipant temp; temp = this.getMember(jid); // 1) Removing the user if (membersCss.remove( new CisParticipant(jid)) == false) return false; // updating the database database this.updatePersisted(this); this.deletePersisted(temp); //activityFeed notification IActivity iActivity = activityFeed.getEmptyIActivity(); iActivity.setActor(jid); iActivity.setObject(cisIdentity.getJid()); iActivity.setVerb("left"); activityFeed.addActivity(iActivity,new ActivityFeedClient()); return true; }else{ return false; } } // constructor for creating a CIS from a CIS record, maybe the case when we are retrieving data from a database // TODO: review as it is almost empty!! public Cis(CisRecord cisRecord) { this.cisRecord = cisRecord; } // equals comparing only cisRecord @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((cisRecord == null) ? 0 : cisRecord.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Cis other = (Cis) obj; if (cisRecord == null) { if (other.cisRecord != null) return false; } else if (!cisRecord.equals(other.cisRecord)) return false; return true; } public CisRecord getCisRecord() { return cisRecord; } public void setCisRecord(CisRecord cisRecord) { this.cisRecord = cisRecord; } @Override public List<String> getJavaPackages() { return PACKAGES; } @Override public Object getQuery(Stanza stanza, Object payload) { // all received IQs contain a community element LOG.debug("get Query received"); if (payload.getClass().equals(CommunityMethods.class)) { LOG.debug("community type received"); CommunityMethods c = (CommunityMethods) payload; //>>>>>>>>>>>>>>>>>>>>>>>>>>>> JOIN >>>>>>>>>>>>>>>>>>>>>>>>>>> if (c.getJoin() != null) { //String jid = ""; LOG.debug("join received"); String senderjid = stanza.getFrom().getBareJid(); // information sent on the xmpp in case of failure or success Community com = new Community(); CommunityMethods result = new CommunityMethods(); Participant p = new Participant(); JoinResponse j = new JoinResponse(); boolean addresult = false; p.setJid(senderjid); this.fillCommmunityXMPPobj(com); j.setCommunity(com); // THE COMMUNITY MUST BE SET IN THE RESPONSE. THE CALLBACKS ARE COUNTING ON THIS!! result.setJoinResponse(j); // checking the criteria if(this.cisCriteria.size()>0){ Join join = (Join) c.getJoin(); if(join.getQualification() != null && join.getQualification().size()>0 ){ // retrieving from marshalled object the qualifications to be checked HashMap<String,String> qualification = new HashMap<String,String>(); for (Qualification q : join.getQualification()) { qualification.put(q.getAttrib(), q.getValue()); } if (this.checkQualification(qualification) == false){ j.setResult(addresult); LOG.debug("qualification mismatched"); return result; } } else{ j.setResult(addresult); LOG.debug("qualification not found"); return result; } } addresult = this.insertMember(senderjid, MembershipType.participant); j.setResult(addresult); // TODO: add the criteria to the response if(addresult == true){ // information sent on the xmpp just in the case of success p.setRole( ParticipantRole.fromValue("participant") ); } j.setParticipant(p); return result; } //>>>>>>>>>>>>>>>>>>>>>>>>>>>> LEAVE CIS >>>>>>>>>>>>>>>>>>>>>>>>>>>> if (c.getLeave() != null) { LOG.debug("get leave received"); CommunityMethods result = new CommunityMethods(); String jid = stanza.getFrom().getBareJid(); boolean b = false; b = this.removeMember(jid); LeaveResponse l = new LeaveResponse(); l.setCommunityJid(this.getCisId()); l.setResult(b); result.setLeaveResponse(l); return result; } //>>>>>>>>>>>>>>>>>>>>>>>>>>>> LIST MEMBERS >>>>>>>>>>>>>>>>>>>>>>>>>>>> if (c.getWhoRequest() != null) { // WHO LOG.debug("get who received"); CommunityMethods result = new CommunityMethods(); WhoResponse who = new WhoResponse(); result.setWhoResponse(who); who.setResult(false); if(null == c.getWhoRequest().getRequestor())return result; // fails if there is no requestor // otherwise we call locally RequestorBean requestor = c.getWhoRequest().getRequestor(); CisManagerClient callbac = new CisManagerClient(); this.getListOfMembers(requestor, callbac); CommunityMethods callbackResp = callbac.getComMethObj(); if (null != callbackResp){ who.setResult(callbackResp.getWhoResponse().isResult()); who.setParticipant(callbackResp.getWhoResponse().getParticipant()); } return result; } //>>>>>>>>>>>>>>>>>>>>>>>>>>>> ADD MEMBER >>>>>>>>>>>>>>>>>>>>>>>>>>>> if (c.getAddMember() != null) { // ADD CommunityMethods result = new CommunityMethods(); AddMemberResponse ar = new AddMemberResponse(); Participant p = c.getAddMember().getParticipant(); ar.setParticipant(p); // if(!senderJid.equalsIgnoreCase(this.getOwnerId())){//first check if the one requesting the add has the rights //requester is not the owner // ar.setResult(false); // }else{ if(p!= null && p.getJid() != null){ String role = ""; if (p.getRole() != null) role = p.getRole().value(); try{ if(this.addMember(p.getJid(), role)){ ar.setParticipant(p); ar.setResult(true); } else{ ar.setResult(false); } } catch(Exception e){ e.printStackTrace(); ar.setResult(false); } } else{ ar.setResult(false); } // } result.setAddMemberResponse(ar); return result; } //>>>>>>>>>>>>>>>>>>>>>>>>>>>> REMOVE MEMBER >>>>>>>>>>>>>>>>>>>>>>>>>>>> if (c.getDeleteMember() != null) { // DELETE MEMBER CommunityMethods result = new CommunityMethods(); DeleteMemberResponse dr = new DeleteMemberResponse(); Participant p = c.getDeleteMember().getParticipant(); dr.setParticipant(p); if(null == p || null == p.getJid()){ dr.setResult(false); } else{ // if(!senderJid.equalsIgnoreCase(this.getOwnerId())){//first check if the one requesting the add has the rights //requester is not the owner // dr.setResult(false); // }else{ try{ dr.setResult(this.removeMemberFromCIS(p.getJid())); } catch(Exception e){ e.printStackTrace(); dr.setResult(false); } // } } result.setDeleteMemberResponse(dr); return result; } //>>>>>>>>>>>>>>>>>>>>>>>>>>>> GET INFO >>>>>>>>>>>>>>>>>>>>>>>>>>>> if (c.getGetInfo()!= null) { CommunityMethods result = new CommunityMethods(); Community com = new Community(); GetInfoResponse r = new GetInfoResponse(); r.setResult(false); r.setCommunity(com); RequestorBean rb = c.getGetInfo().getRequestor(); if(null == rb)return result; // fails if there is no requestor // otherwise we call locally CisManagerClient callbac = new CisManagerClient(); this.getInfo(rb, callbac); CommunityMethods callbackResp = callbac.getComMethObj(); if (null != callbackResp){ return callbackResp; } return result; } //>>>>>>>>>>>>>>>>>>>>>>>>>>>> SET INFO >>>>>>>>>>>>>>>>>>>>>>>>>>>> // at the moment we limit this to description and type if (c.getSetInfo()!= null && c.getSetInfo().getCommunity() != null) { CommunityMethods result = new CommunityMethods(); Community com = new Community(); SetInfoResponse r = new SetInfoResponse(); //if(!senderJid.equalsIgnoreCase(this.getOwnerId())){//first check if the one requesting the add has the rights // r.setResult(false); //}else{ //if((!c.getCommunityName().isEmpty()) && (!c.getCommunityName().equals(this.getName()))) // if is not empty and is different from current value Community inputCommunity = c.getSetInfo().getCommunity(); if( (inputCommunity.getCommunityType() != null) && (!inputCommunity.getCommunityType().isEmpty()) && (!inputCommunity.getCommunityType().equals(this.getCisType()))) // if is not empty and is different from current value this.setCisType(inputCommunity.getCommunityType()); if( (inputCommunity.getDescription() != null) && (!inputCommunity.getDescription().isEmpty()) && (!inputCommunity.getDescription().equals(this.getDescription()))) // if is not empty and is different from current value this.setDescription(inputCommunity.getDescription()); r.setResult(true); // updating at DB this.updatePersisted(this); //} this.fillCommmunityXMPPobj(com); r.setCommunity(com); result.setSetInfoResponse(r); return result; } // >>>>>>>>>>>>>>>>>>>>>>>>>>>> GET MEMBERSHIP CRITERIA >>>>>>>>>>>>>>>>>>>>>>>>>>>> if (c.getGetMembershipCriteria()!= null) { CommunityMethods result = new CommunityMethods(); GetMembershipCriteriaResponse g = new GetMembershipCriteriaResponse(); MembershipCrit m = new MembershipCrit(); this.fillMembershipCritXMPPobj(m); g.setMembershipCrit(m); result.setGetMembershipCriteriaResponse(g); return result; } // >>>>>>>>>>>>>>>>>>>>>>>>>>>> SET MEMBERSHIP CRITERIA if (c.getSetMembershipCriteria()!= null) { CommunityMethods result = new CommunityMethods(); SetMembershipCriteriaResponse r = new SetMembershipCriteriaResponse(); result.setSetMembershipCriteriaResponse(r); // retrieving from marshalled object the incoming criteria MembershipCrit m = c.getSetMembershipCriteria().getMembershipCrit(); if (m!=null && m.getCriteria() != null && m.getCriteria().size()>0){ // populate the hashtable for (Criteria crit : m.getCriteria()) { MembershipCriteria meb = new MembershipCriteria(); meb.setRank(crit.getRank()); Rule rule = new Rule(); if( rule.setOperation(crit.getOperator()) == false) {r.setResult(false); return result;} ArrayList<String> a = new ArrayList<String>(); a.add(crit.getValue1()); if (crit.getValue2() != null && !crit.getValue2().isEmpty()) a.add(crit.getValue2()); if( rule.setValues(a) == false) {r.setResult(false); return result;} meb.setRule(rule); if( this.addCriteria(crit.getAttrib(), meb) == false) {r.setResult(false); return result;} } } r.setResult(true); m = new MembershipCrit(); this.fillMembershipCritXMPPobj(m); r.setMembershipCrit(m); return result; } } //>>>>>>>>>>>>>>>>>>>>>>>>>>>> ACTIVITIES MESSAGE BEAN >>>>>>>>>>>>>>>>>>>>>>>>>>>> if (payload.getClass().equals(MarshaledActivityFeed.class)) { LOG.info("activity feed type received"); MarshaledActivityFeed c = (MarshaledActivityFeed) payload; // >>>>>>>>>>>>>>>>>>>>>>>>>>>> DELETE ACTIVITY >>>>>>>>>>>>>>>>>>>>>>>>>>>> if (c.getDeleteActivity() != null) { MarshaledActivityFeed result = new MarshaledActivityFeed(); DeleteActivityResponse r = new DeleteActivityResponse(); //String senderJid = stanza.getFrom().getBareJid(); //if(!senderJid.equalsIgnoreCase(this.getOwnerId())){//first check if the one requesting the add has the rights // r.setResult(false); //}else{ //if((!c.getCommunityName().isEmpty()) && (!c.getCommunityName().equals(this.getName()))) // if is not empty and is different from current value IActivity iActivity = activityFeed.getEmptyIActivity(); iActivity.setActor(c.getDeleteActivity().getMarshaledActivity().getActor()); iActivity.setObject(c.getDeleteActivity().getMarshaledActivity().getObject()); iActivity.setTarget(c.getDeleteActivity().getMarshaledActivity().getTarget()); iActivity.setVerb(c.getDeleteActivity().getMarshaledActivity().getVerb()); ActivityFeedClient d = new ActivityFeedClient(); activityFeed.deleteActivity(iActivity,d); MarshaledActivityFeed m = d.getActivityFeed(); if(null != m && null != m.getDeleteActivityResponse()){ r.setResult(m.getDeleteActivityResponse().isResult()); }else{ LOG.warn("no callback object after immediate call of delecte activity feed"); r.setResult(false); } result.setDeleteActivityResponse(r); return result; } // >>>>>>>>>>>>>>>>>>>>>>>>>>>> GET ACTIVITIES >>>>>>>>>>>>>>>>>>>>>>>>>>>> if (c.getGetActivities() != null) { LOG.debug("get activities called"); org.societies.api.schema.activityfeed.MarshaledActivityFeed result = new org.societies.api.schema.activityfeed.MarshaledActivityFeed(); GetActivitiesResponse r = new GetActivitiesResponse(); //String senderJid = stanza.getFrom().getBareJid(); //List<IActivity> iActivityList; //List<org.societies.api.schema.activity.MarshaledActivity> marshalledActivList = new ArrayList<org.societies.api.schema.activity.MarshaledActivity>(); ActivityFeedClient d = new ActivityFeedClient(); //if(!senderJid.equalsIgnoreCase(this.getOwnerId())){//first check if the one requesting the add has the rights // r.setResult(false); //}else{ //if((!c.getCommunityName().isEmpty()) && (!c.getCommunityName().equals(this.getName()))) // if is not empty and is different from current value if(c.getGetActivities().getQuery()==null || c.getGetActivities().getQuery().isEmpty()) activityFeed.getActivities(c.getGetActivities().getTimePeriod(),d); else activityFeed.getActivities(c.getGetActivities().getQuery(),c.getGetActivities().getTimePeriod(),d); //} MarshaledActivityFeed m = d.getActivityFeed(); if(null != m && null != m.getGetActivitiesResponse()){ r.setMarshaledActivity(m.getGetActivitiesResponse().getMarshaledActivity()); }else{ LOG.warn("no callback object after immediate call of get activities"); // ill set an empty list r.setMarshaledActivity(new ArrayList<org.societies.api.schema.activity.MarshaledActivity>()); } result.setGetActivitiesResponse(r); return result; } // >>>>>>>>>>>>>>>>>>>>>>>>>>>> ADD ACTIVITY >>>>>>>>>>>>>>>>>>>>>>>>>>>> if (c.getAddActivity() != null) { org.societies.api.schema.activityfeed.MarshaledActivityFeed result = new org.societies.api.schema.activityfeed.MarshaledActivityFeed(); AddActivityResponse r = new AddActivityResponse(); //String senderJid = stanza.getFrom().getBareJid(); //if(!senderJid.equalsIgnoreCase(this.getOwnerId())){//first check if the one requesting the add has the rights // r.setResult(false); //}else{ //if((!c.getCommunityName().isEmpty()) && (!c.getCommunityName().equals(this.getName()))) // if is not empty and is different from current value IActivity iActivity = activityFeed.getEmptyIActivity(); iActivity.setActor(c.getAddActivity().getMarshaledActivity().getActor()); iActivity.setObject(c.getAddActivity().getMarshaledActivity().getObject()); iActivity.setTarget(c.getAddActivity().getMarshaledActivity().getTarget()); iActivity.setVerb(c.getAddActivity().getMarshaledActivity().getVerb()); ActivityFeedClient d = new ActivityFeedClient(); activityFeed.addActivity(iActivity,d); MarshaledActivityFeed m = d.getActivityFeed(); if(null != m && null != m.getAddActivityResponse()){ r.setResult(m.getAddActivityResponse().isResult()); }else{ LOG.warn("no callback object after immediate call of add activity"); r.setResult(false); } result.setAddActivityResponse(r); return result; } // >>>>>>>>>>>>>>>>>>>>>>>>>>>> CLEAN UP ACTIVITIES >>>>>>>>>>>>>>>>>>>>>>>>>>>> if (c.getCleanUpActivityFeed() != null) { org.societies.api.schema.activityfeed.MarshaledActivityFeed result = new org.societies.api.schema.activityfeed.MarshaledActivityFeed(); CleanUpActivityFeedResponse r = new CleanUpActivityFeedResponse(); //String senderJid = stanza.getFrom().getBareJid(); //if(!senderJid.equalsIgnoreCase(this.getOwnerId())){//first check if the one requesting the add has the rights // r.setResult(false); //}else{ //if((!c.getCommunityName().isEmpty()) && (!c.getCommunityName().equals(this.getName()))) // if is not empty and is different from current value ActivityFeedClient d = new ActivityFeedClient(); activityFeed.cleanupFeed(c.getCleanUpActivityFeed().getCriteria(),d); MarshaledActivityFeed m = d.getActivityFeed(); if(null != m && null != m.getCleanUpActivityFeedResponse()){ r.setResult(m.getCleanUpActivityFeedResponse().getResult()); }else{ LOG.warn("no callback object after immediate call of clean up activity feed"); r.setResult(0); } result.setCleanUpActivityFeedResponse(r); return result; } } return null; } @Override public Set<ICisParticipant> getMemberList(){ LOG.debug("local get member list WITHOUT CALLBACK called"); Set<ICisParticipant> s = new HashSet<ICisParticipant>(); s.addAll(this.getMembersCss()); return s; } // do the ACL and then call internal method // version using old Requestor, to be deleted in the future @Override public void getListOfMembers(Requestor requestor, ICisManagerCallback callback){ LOG.debug("local get member list WITH CALLBACK called with requestor"); CommunityMethods c = new CommunityMethods(); // object to be returned in case of failure WhoResponse w = new WhoResponse(); c.setWhoResponse(w); w.setResult(false); // -- Access control if(null != this.privacyDataManager && null != requestor){ List<ResponseItem> permission = null; DataIdentifier dataId = null; try { dataId = DataIdentifierFactory.fromUri(DataIdentifierScheme.CIS.value() + "://" + this.getCisId() + "/"+CisAttributeTypes.MEMBER_LIST); Action act = new Action(); act.setActionConstant(org.societies.api.schema.privacytrust.privacy.model.privacypolicy.ActionConstants.READ); RequestorBean rb = Util.createRequestorBean(requestor); permission = this.privacyDataManager.checkPermission(rb, dataId, act); } catch (MalformedCtxIdentifierException e) { LOG.error("The identifier of the requested data is malformed", e); } catch (PrivacyException e) { LOG.error("Error during access control of this data", e); } // No permission if(null == permission || permission.size() <=0 || !Decision.PERMIT.equals(permission.get(0).getDecision())){ LOG.debug("This requestor: "+requestor); LOG.debug("doesn't have the permission to retrieve this data: "+dataId); callback.receiveResult(c); return; } } else{ LOG.debug("Privacy data manager or requestor is null"); } LOG.debug("permission was granted"); // -- Retrieve the list of members getListOfMembers(callback); } @Override // do the ACL and then call internal method public void getListOfMembers(RequestorBean requestor, ICisManagerCallback callback){ LOG.debug("local get member list WITH CALLBACK called with requestor bean"); CommunityMethods c = new CommunityMethods(); // object to be returned in case of failure WhoResponse w = new WhoResponse(); c.setWhoResponse(w); w.setResult(false); // -- Access control if(null != this.privacyDataManager && null != requestor){ List<ResponseItem> permission = null; DataIdentifier dataId = null; try { dataId = DataIdentifierFactory.fromUri(DataIdentifierScheme.CIS.value() + "://" + this.getCisId() + "/"+CisAttributeTypes.MEMBER_LIST); Action act = new Action(); act.setActionConstant(org.societies.api.schema.privacytrust.privacy.model.privacypolicy.ActionConstants.READ); permission = this.privacyDataManager.checkPermission(requestor, dataId, act); } catch (MalformedCtxIdentifierException e) { LOG.error("The identifier of the requested data is malformed", e); } catch (PrivacyException e) { LOG.error("Error during access control of this data", e); } // No permission if(null == permission || permission.size() <=0 || !Decision.PERMIT.equals(permission.get(0).getDecision())){ LOG.debug("This requestor: "+requestor); LOG.debug("doesn't have the permission to retrieve this data: "+dataId); callback.receiveResult(c); return; } } else{ LOG.debug("Privacy data manager or requestor is null"); } LOG.debug("permission was granted"); // -- Retrieve the list of members getListOfMembers(callback); } // this method does the proper getting list of members private void getListOfMembers(final ICisManagerCallback callback){ LOG.debug("getListOfMembers: callback"); LOG.debug("local get member list WITH CALLBACK called"); final CommunityMethods community = new CommunityMethods(); final WhoResponse who = new WhoResponse(); community.setWhoResponse(who); who.setResult(true); List<String> listMemberIDs = new ArrayList<String>(); //USED AS PARAM TO CSS DIR TO GET MEMBER NAMES final List<Participant> listParticipants = new ArrayList<Participant>(); //RETURNED TO CALLER //GET MEMBER LIST FROM DATABASE final Set<ICisParticipant> setParticipants = this.getMemberList(); Iterator<ICisParticipant> it = setParticipants.iterator(); while(it.hasNext()){ ICisParticipant element = it.next(); Participant p = new Participant(); p.setJid(element.getMembersJid()); p.setRole( ParticipantRole.fromValue(element.getMembershipType()) ); listParticipants.add(p); listMemberIDs.add(element.getMembersJid()); } //GET PARTICIPANT NAMES FROM CSS DIR getCssDirectoryRemote().searchByID(listMemberIDs, new ICssDirectoryCallback() { @Override public void getResult(List<CssAdvertisementRecord> results) { for (CssAdvertisementRecord record: results) { //CHECK WHICH RECORD BELONGS TO WHO for (Participant participant: listParticipants) { if (record.getId().equals(participant.getJid()) ) participant.setName(record.getName()); } } who.setParticipant(listParticipants); callback.receiveResult(community); } }); } @Override public List<String> getXMLNamespaces() { return NAMESPACES; } @Override public void receiveMessage(Stanza arg0, Object arg1) { } @Override public Object setQuery(Stanza arg0, Object arg1) throws XMPPError { // TODO Auto-generated method stub return null; } public String getCisId() { return this.cisRecord.getCisJID(); } //"destructor" class which send a message to all users and closes the connection immediately public boolean deleteCIS(){ boolean ret = true; // TODO: do we need to make sure that at this point we are not taking any other XMPP input or api call? //**** delete all members and send them a xmpp notification that the community has been deleted CommunityManager message = new CommunityManager(); Notification n = new Notification(); DeleteNotification d = new DeleteNotification(); d.setCommunityJid(this.getCisId()); n.setDeleteNotification(d); message.setNotification(n); Set<CisParticipant> s = this.getMembersCss(); Iterator<CisParticipant> it = s.iterator(); // deleting from DB // the remove of the activityFeed will be done by the CIS MANAGER!! activityFeed = null; this.deletePersisted(this); // unregistering policy //IIdentity cssOwnerId; try { //cssOwnerId = this.CISendpoint.getIdManager().fromJid(this.getOwnerId()); //RequestorCis requestorCis = new RequestorCis(cssOwnerId, cisIdentity); RequestorCisBean requestorCis = (RequestorCisBean) RequestorUtils.create(this.getOwnerId(), this.getCisId()); if(this.privacyPolicyManager != null) this.privacyPolicyManager.deletePrivacyPolicy(requestorCis); } catch (PrivacyException e) { // TODO Auto-generated catch block LOG.debug("problem deleting policy"); e.printStackTrace(); } while(it.hasNext()){ CisParticipant element = it.next(); try { // send notification LOG.debug("sending delete notification to " + element.getMembersJid()); IIdentity targetCssIdentity = this.CISendpoint.getIdManager().fromJid(element.getMembersJid());//new IdentityImpl(element.getMembersJid()); LOG.debug("iidentity created"); Stanza sta = new Stanza(targetCssIdentity); LOG.debug("stanza created"); this.CISendpoint.sendMessage(sta, message); } catch (CommunicationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvalidFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } // delete user it.remove(); } //if(session!=null) // session.close(); //**** end of delete all members and send them a xmpp notification //cisRecord = null; this cant be called as it will be used for comparisson later. I hope the garbage collector can take care of it... //activityFeed = null; // TODO: replace with proper way of destroying it ret = CISendpoint.UnRegisterCommManager(); if(ret) CISendpoint = null; else LOG.warn("could not unregister CIS"); //TODO: possibly do something in case we cant close it membersCss = null; return ret; } public boolean unregisterCIS(){ boolean ret = CISendpoint.UnRegisterCommManager(); return ret; } // getters and setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } @Override public String getName() { return this.cisRecord.getCisName(); } @Override public String getOwnerId() { return this.cisRecord.getOwner(); } @Override public String getCisType() { return this.cisType; } @Override public String setCisType(String type) { return this.cisType = type; } @Override public void getInfo(Requestor req, ICisManagerCallback callback){ LOG.debug("local client call to get info from this CIS with requestor"); GetInfoResponse r = new GetInfoResponse(); CommunityMethods result = new CommunityMethods(); Community c = new Community (); r.setCommunity(c); result.setGetInfoResponse(r); CisManagerClient internalCallback = new CisManagerClient(); RequestorBean rb = (RequestorBean) Util.createRequestorBean(req); getListOfMembers(rb, internalCallback); CommunityMethods internallCabackResult = internalCallback.getComMethObj(); r.setResult(true); this.fillCommmunityXMPPobj(c); // TODO: move the filling of the object to be conditional with privacy if(internallCabackResult.getWhoResponse().isResult()){ c.setParticipant((internallCabackResult.getWhoResponse().getParticipant())); } callback.receiveResult(result); } @Override public void getInfo(RequestorBean req, ICisManagerCallback callback){ LOG.debug("local client call to get info from this CIS with requestor"); GetInfoResponse r = new GetInfoResponse(); CommunityMethods result = new CommunityMethods(); Community c = new Community (); r.setCommunity(c); result.setGetInfoResponse(r); CisManagerClient internalCallback = new CisManagerClient(); getListOfMembers(req, internalCallback); CommunityMethods internallCabackResult = internalCallback.getComMethObj(); r.setResult(true); this.fillCommmunityXMPPobj(c); // TODO: move the filling of the object to be conditional with privacy if(internallCabackResult.getWhoResponse().isResult()){ c.setParticipant((internallCabackResult.getWhoResponse().getParticipant())); } callback.receiveResult(result); } @Override public void setInfo(Community c, ICisManagerCallback callback) { // TODO Auto-generated method stub LOG.debug("local client call to set info from this CIS"); SetInfoResponse r = new SetInfoResponse(); //check if he is not trying to set things which cant be set if( ( (c.getCommunityJid() !=null) && (! c.getCommunityJid().equalsIgnoreCase(this.getCisId())) ) || (( (c.getCommunityName() !=null)) && (! c.getCommunityName().equals(this.getName())) ) //( (!c.getCommunityType().isEmpty()) && (! c.getCommunityJid().equalsIgnoreCase(this.getCisType())) ) || //|| ( (c.getMembershipMode() != null) && ( c.getMembershipMode() != this.getMembershipCriteria())) ){ r.setResult(false); } else{ r.setResult(true); if(c.getDescription() != null && !c.getDescription().isEmpty()) this.description = c.getDescription(); if(c.getCommunityType() != null && !c.getCommunityType().isEmpty()) this.cisType = c.getCommunityType(); // commit in database this.updatePersisted(this); } CommunityMethods result = new CommunityMethods(); Community resp = new Community(); this.fillCommmunityXMPPobj(resp); result.setSetInfoResponse(r); r.setCommunity(resp); callback.receiveResult(result); } // session related methods private void persist(Object o){ Session session = this.sessionFactory.openSession(); Transaction t = session.beginTransaction(); try{ session.save(o); t.commit(); LOG.debug("Saving CIS object succeded!"); }catch(Exception e){ e.printStackTrace(); t.rollback(); LOG.warn("Saving CIS object failed, rolling back"); }finally{ if(session!=null){ session.close(); } } } private void deletePersisted(Object o){ Session session = this.sessionFactory.openSession(); Transaction t = session.beginTransaction(); try{ session.delete(o); t.commit(); LOG.debug("Deleting object in CisManager succeded!"); }catch(Exception e){ e.printStackTrace(); t.rollback(); LOG.warn("Deleting object in CisManager failed, rolling back"); }finally{ if(session!=null){ session.close(); } } } private void updatePersisted(Object o){ Session session = this.sessionFactory.openSession(); Transaction t = session.beginTransaction(); try{ session.update(o); t.commit(); LOG.debug("Updated CIS object succeded!"); }catch(Exception e){ e.printStackTrace(); t.rollback(); LOG.warn("Updating CIS object failed, rolling back"); }finally{ if(session!=null){ session.close(); } } } // local method public Hashtable<String, MembershipCriteria> getMembershipCriteria() { //return this.cisCriteria; // TODO: maybe we should return a copy instead //returns a home-made clone Hashtable<String, MembershipCriteria> h = new Hashtable<String, MembershipCriteria> (); for(Map.Entry<String, MembershipCriteria> entry : this.cisCriteria.entrySet()){ MembershipCriteria orig = entry.getValue(); MembershipCriteria clone = new MembershipCriteria(); clone.setRank(orig.getRank()); clone.setRule(new Rule(orig.getRule().getOperation(), orig.getRule().getValues())); h.put(new String(entry.getKey()),clone ); } return h; } @Override public void getMembershipCriteria(ICisManagerCallback callback) { CommunityMethods result = new CommunityMethods(); GetMembershipCriteriaResponse g = new GetMembershipCriteriaResponse(); MembershipCrit m = new MembershipCrit(); this.fillMembershipCritXMPPobj(m); g.setMembershipCrit(m); result.setGetMembershipCriteriaResponse(g); callback.receiveResult(result); } // internal method for filling up the MembershipCriteria marshalled object public void fillMembershipCritXMPPobj(MembershipCrit m){ List<Criteria> l = new ArrayList<Criteria>(); for(Map.Entry<String, MembershipCriteria> entry : this.cisCriteria.entrySet()){ MembershipCriteria orig = entry.getValue(); Criteria c = new Criteria(); c.setAttrib(entry.getKey()); c.setOperator(orig.getRule().getOperation()); c.setRank(orig.getRank()); c.setValue1(orig.getRule().getValues().get(0)); if(orig.getRule().getValues().size()==2) c.setValue1(orig.getRule().getValues().get(1)); l.add(c); } m.setCriteria(l); } // internal method for filling up the Community marshalled object public void fillCommmunityXMPPobj(Community c){ c.setCommunityJid(this.getCisId()); c.setCommunityName(this.getName()); c.setCommunityType(this.getCisType()); c.setOwnerJid(this.getOwnerId()); c.setDescription(this.getDescription()); /*RequestPolicy p; try { p = this.privacyPolicyManager.getPrivacyPolicy(new RequestorCis(this.CISendpoint.getIdManager().fromJid(owner) ,this.cisIdentity)); if (p != null && p.toXMLString().isEmpty()==false){ c.setPrivacyPolicy("<![CDATA[" + p.toXMLString() + "]]>"); } } catch (PrivacyException e) { LOG.warn("Privacy excpetion when getting privacy on fillCommmunityXMPPobj"); e.printStackTrace(); } catch (InvalidFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } */ // fill criteria MembershipCrit m = new MembershipCrit(); this.fillMembershipCritXMPPobj(m); c.setMembershipCrit(m); } }