package org.societies.webapp.controller.userfeedback;
import org.societies.api.comm.xmpp.pubsub.PubsubClient;
import org.societies.api.comm.xmpp.pubsub.Subscriber;
import org.societies.api.identity.IIdentity;
import org.societies.api.identity.Requestor;
import org.societies.api.internal.schema.useragent.feedback.NegotiationDetailsBean;
import org.societies.api.internal.useragent.feedback.IUserFeedback;
import org.societies.api.internal.useragent.feedback.IUserFeedbackResponseEventListener;
import org.societies.api.internal.useragent.model.ExpProposalContent;
import org.societies.api.internal.useragent.model.ExpProposalType;
import org.societies.api.internal.useragent.model.ImpProposalContent;
import org.societies.api.internal.useragent.model.ImpProposalType;
import org.societies.api.osgi.event.EventTypes;
import org.societies.api.schema.identity.RequestorBean;
import org.societies.api.schema.privacytrust.privacy.model.privacypolicy.*;
import org.societies.webapp.ILoginListener;
import org.societies.webapp.controller.BasePageController;
import org.societies.webapp.service.UserService;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@ManagedBean(name = "ufTestController")
@SessionScoped
public class UserFeedbackTestController extends BasePageController {
private class PubSubListener implements Subscriber {
public void registerForEvents() {
if (getPubsubClient() == null) {
log.error("PubSubClient was null, cannot register for events");
return;
}
try {
getPubsubClient().subscriberSubscribe(getUserService().getIdentity(),
EventTypes.UF_PRIVACY_NEGOTIATION_RESPONSE,
this);
log.debug("Subscribed to " + EventTypes.UF_PRIVACY_NEGOTIATION_RESPONSE + " events");
} catch (Exception e) {
addGlobalMessage("Error subscribing to pubsub notifications",
e.getMessage(),
FacesMessage.SEVERITY_ERROR);
log.error("Error subscribing to pubsub notifications (id="
+ getUserService().getIdentity()
+ " event=" + EventTypes.UF_PRIVACY_NEGOTIATION_RESPONSE, e);
}
}
@Override
public void pubsubEvent(IIdentity pubsubService, String node, String itemId, Object item) {
if (log.isDebugEnabled())
log.debug("pubsubEvent(): node=" + node + " item=" + item);
}
}
private class LoginListener implements ILoginListener {
@Override
public void userLoggedIn() {
pubSubListener.registerForEvents();
}
@Override
public void userLoggedOut() {
}
}
private static final String[] COLORS = new String[]{
"RED", "ORANGE", "YELLOW", "GREEN", "BLUE", "INDIGO", "VIOLET"
};
private static final String[] FEATURES = new String[]{
"2 LEGS", "4 LEGS", "SWIMS", "JUMPS", "LONG NECK", "REALLY HEAVY", "WILL EAT YOU"
};
private static final String[] CLASSIFICATIONS = new String[]{
"KINGDOM", "PHYLYM", "CLASS", "ORDER", "FAMILY", "GENUS", "SPECIES"
};
private static final String[] ANIMALS = new String[]{
"CAT", "OTTER", "MOUSE", "DOG", "HORSE", "BADGER", "OSTRICH", "SEAL", "HEDGEHOG", "LION", "TIGER", "GIRAFFE", "HEFFALUMP"
};
private static final Random random = new Random();
@ManagedProperty(value = "#{pubsubClient}")
private PubsubClient pubsubClient;
@ManagedProperty(value = "#{userService}")
private UserService userService;
@ManagedProperty(value = "#{userFeedback}")
private IUserFeedback userFeedback;
private final PubSubListener pubSubListener = new PubSubListener();
private final LoginListener loginListener = new LoginListener();
private static int req_counter = 0;
public UserFeedbackTestController() {
log.debug("UserFeedbackTestController ctor()");
}
@PostConstruct
public void postConstruct() {
// NB: Generally you DON'T want to use this method to set up your class - you want to use the LoginListener
// - This method is called whenever the bean is created at the start of the session, while the login listener
// - is called when the user actually logs in and an identity is available
// call this in case we're set up after the user has logged in
if (userService.isUserLoggedIn()) {
loginListener.userLoggedIn();
}
}
@SuppressWarnings("UnusedDeclaration")
public PubsubClient getPubsubClient() {
return pubsubClient;
}
@SuppressWarnings("UnusedDeclaration")
public void setPubsubClient(PubsubClient pubsubClient) {
this.pubsubClient = pubsubClient;
}
@SuppressWarnings("UnusedDeclaration")
public UserService getUserService() {
return userService;
}
@SuppressWarnings("UnusedDeclaration")
public void setUserService(UserService userService) {
// if (log.isDebugEnabled())
// log.debug("setUserService() = " + userService);
if (this.userService != null) {
this.userService.removeLoginListener(loginListener);
}
this.userService = userService;
this.userService.addLoginListener(loginListener);
}
@SuppressWarnings("UnusedDeclaration")
public IUserFeedback getUserFeedback() {
return userFeedback;
}
@SuppressWarnings("UnusedDeclaration")
public void setUserFeedback(IUserFeedback userFeedback) {
this.userFeedback = userFeedback;
}
public void sendPpnEvent() throws ExecutionException, InterruptedException {
RequestorBean requestorBean = new RequestorBean();
requestorBean.setRequestorId("req" + ++req_counter);
SecureRandom random = new SecureRandom();
String guid = new BigInteger(130, random).toString(32);
ResponsePolicy responsePolicy = buildResponsePolicy(guid, requestorBean);
NegotiationDetailsBean negotiationDetails = new NegotiationDetailsBean();
negotiationDetails.setRequestor(requestorBean);
negotiationDetails.setNegotiationID(new BigInteger(130, random).intValue());
log.info("PPN: Sending event");
userFeedback.getPrivacyNegotiationFBAsync(responsePolicy, negotiationDetails, new IUserFeedbackResponseEventListener<ResponsePolicy>() {
@Override
public void responseReceived(ResponsePolicy result) {
addGlobalMessage("PPN Response received",
result.getResponsePolicyId() + " = " + result.getNegotiationStatus(),
FacesMessage.SEVERITY_INFO);
}
});
}
public void sendSimpleNotificationEvent() {
String proposalText = "I'm thinking of an animal: " + randomIdentifier();
log.info("Simple: Sending event");
userFeedback.showNotification(proposalText);
log.info("Simple: Done");
}
public void sendAckNackEvent() {
String proposalText = "Do you like " + randomIdentifier() + "?";
String[] options = new String[]{"Yes", "No"}; // this actually has no effect for acknack
log.info("Acknack: Sending event");
ExpProposalContent content = new ExpProposalContent(proposalText, options);
userFeedback.getExplicitFBAsync(ExpProposalType.ACKNACK, content, new IUserFeedbackResponseEventListener<List<String>>() {
@Override
public void responseReceived(List<String> result) {
log.info("Acknack: Response received");
addGlobalMessage("AckNack Response received",
(result != null && result.size() > 0) ? result.get(0) : "null",
FacesMessage.SEVERITY_INFO);
}
});
log.info("Acknack: Sent");
}
public void sendSelectOneEvent_blocking() throws InterruptedException, ExecutionException {
String proposalText = "What colour is a " + randomIdentifier() + "? (testing)";
ExpProposalContent content = new ExpProposalContent(proposalText, COLORS);
Future<List<String>> result = userFeedback.getExplicitFB(ExpProposalType.RADIOLIST, content);
// USE YOUR RESULT HERE
addGlobalMessage("SelectOne Response received",
(result.get() != null && result.get().size() > 0) ? result.get().get(0) : "null",
FacesMessage.SEVERITY_INFO);
}
public void sendSelectOneEvent() {
String proposalText = "What colour is a " + randomIdentifier() + "? (testing)";
log.info("SelectOne: Sending event");
ExpProposalContent content = new ExpProposalContent(proposalText, COLORS);
userFeedback.getExplicitFBAsync(ExpProposalType.RADIOLIST, content, new IUserFeedbackResponseEventListener<List<String>>() {
@Override
public void responseReceived(List<String> result) {
log.info("SelectOne: Response received");
addGlobalMessage("SelectOne Response received",
(result != null && result.size() > 0) ? result.get(0) : "null",
FacesMessage.SEVERITY_INFO);
}
});
log.info("SelectOne: Sent");
}
public void sendSelectManyEvent() {
String proposalText = "Select features of a " + randomIdentifier() + ": (testing)";
log.info("SelectMany: Sending event");
ExpProposalContent content = new ExpProposalContent(proposalText, FEATURES);
userFeedback.getExplicitFBAsync(ExpProposalType.CHECKBOXLIST, content, new IUserFeedbackResponseEventListener<List<String>>() {
@Override
public void responseReceived(List<String> result) {
log.info("SelectMany: Response received");
addGlobalMessage("SelectMany Response received",
(result != null) ? Arrays.toString(result.toArray()) : "null",
FacesMessage.SEVERITY_INFO);
}
});
log.info("SelectMany: Sent");
}
public void sendTimedAbortEvent(long sec) {
String proposalText = "This is a timed abort";
log.info("TimedAbort: Sending event");
ImpProposalContent content = new ImpProposalContent(proposalText, (int) sec * 1000);
userFeedback.getImplicitFBAsync(ImpProposalType.TIMED_ABORT, content, new IUserFeedbackResponseEventListener<Boolean>() {
@Override
public void responseReceived(Boolean result) {
log.info("TimedAbort: Response received");
addGlobalMessage("TimedAbort Response received",
(result != null) ? result.toString() : "null",
FacesMessage.SEVERITY_INFO);
}
});
log.info("TimedAbort: Sent");
}
public void sendAccessControlEvent() {
Requestor requestor = new Requestor(userService.getIdentity());
List<ResponseItem> responseItems = new ArrayList<ResponseItem>();
responseItems.add(buildResponseItem("http://this.is.a.win/", "data item #1"));
responseItems.add(buildResponseItem("http://paddy.rules/", "data item #2"));
responseItems.add(buildResponseItem("http://something.something.something/", "data item #3"));
userFeedback.getAccessControlFBAsync(requestor, responseItems, new IUserFeedbackResponseEventListener<List<ResponseItem>>() {
@Override
public void responseReceived(List<ResponseItem> result) {
log.info("AccessControl: Response received");
addGlobalMessage("AccessControl Response received",
(result != null && result.size() > 0) ? result.get(0).getDecision().toString() : "null",
FacesMessage.SEVERITY_INFO);
}
});
log.info("AccessControl: Sent");
}
public void resetUserFeedback() {
userFeedback.clear();
}
private static ResponsePolicy buildResponsePolicy(String guid, RequestorBean requestorBean) {
List<ResponseItem> responseItems = new ArrayList<ResponseItem>();
responseItems.add(buildResponseItem("http://this.is.a.win/", "Location"));
responseItems.add(buildResponseItem("http://paddy.rules/", "Status"));
responseItems.add(buildResponseItem("http://something.something.something/", "Hair colour"));
ResponsePolicy responsePolicy = new ResponsePolicy();
responsePolicy.setRequestor(requestorBean);
responsePolicy.setNegotiationStatus(NegotiationStatus.ONGOING);
responsePolicy.setResponseItems(responseItems);
return responsePolicy;
}
private static ResponseItem buildResponseItem(String uri, String dataType) {
Action action1 = new Action();
action1.setActionConstant(ActionConstants.CREATE);
action1.setOptional(true);
Action action2 = new Action();
action2.setActionConstant(ActionConstants.DELETE);
action2.setOptional(false);
Action action3 = new Action();
action3.setActionConstant(ActionConstants.READ);
action3.setOptional(false);
Action action4 = new Action();
action4.setActionConstant(ActionConstants.WRITE);
action4.setOptional(true);
Condition condition1 = new Condition();
condition1.setConditionConstant(ConditionConstants.DATA_RETENTION_IN_HOURS);
condition1.setValue("1");
condition1.setOptional(false);
Condition condition2 = new Condition();
condition2.setConditionConstant(ConditionConstants.RIGHT_TO_ACCESS_HELD_DATA);
condition2.setValue("2");
condition2.setOptional(true);
Condition condition3 = new Condition();
condition3.setConditionConstant(ConditionConstants.RIGHT_TO_OPTOUT);
condition3.setValue("3");
condition3.setOptional(false);
Condition condition4 = new Condition();
condition4.setConditionConstant(ConditionConstants.STORE_IN_SECURE_STORAGE);
condition4.setValue("4");
condition4.setOptional(true);
Resource resource = new Resource();
resource.setDataIdUri(uri);
resource.setDataType(dataType);
RequestItem requestItem = new RequestItem();
requestItem.getActions().add(action1);
requestItem.getActions().add(action2);
requestItem.getActions().add(action3);
requestItem.getActions().add(action4);
requestItem.getConditions().add(condition1);
requestItem.getConditions().add(condition2);
requestItem.getConditions().add(condition3);
requestItem.getConditions().add(condition4);
requestItem.setOptional(false);
requestItem.setResource(resource);
ResponseItem responseItem = new ResponseItem();
responseItem.setDecision(Decision.INDETERMINATE);
responseItem.setRequestItem(requestItem);
return responseItem;
}
private static String randomIdentifier() {
return COLORS[random.nextInt(COLORS.length)]
+ " " + ANIMALS[random.nextInt(ANIMALS.length)]
+ " " + random.nextInt(10000);
}
}