package org.limewire.facebook.service.livemessage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.codec.binary.Base64;
import org.json.JSONException;
import org.json.JSONObject;
import org.limewire.facebook.service.FacebookFriendConnection;
import org.limewire.friend.api.FriendException;
import org.limewire.friend.api.FriendPresence;
import org.limewire.friend.api.feature.FeatureTransport;
import org.limewire.io.Connectable;
import org.limewire.io.GUID;
import org.limewire.logging.Log;
import org.limewire.logging.LogFactory;
import org.limewire.net.ConnectBackRequest;
import org.limewire.net.address.ConnectableSerializer;
import org.limewire.util.StringUtils;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
/**
* Handles incoming connect back request through the facebook connection and
* fowards them to the {@link Handler} for {@link ConnectBackRequest connect back requests}.
* <p>
* Sends {@link ConnectBackRequest connect back requests} to facebook friends.
*/
public class ConnectBackRequestHandler implements FeatureTransport<ConnectBackRequest>,
LiveMessageHandler {
private static final Log LOG = LogFactory.getLog(AddressHandler.class);
private static final String TYPE = "connect-back-request";
private final Handler<ConnectBackRequest> connectBackRequestHandler;
private final FacebookFriendConnection connection;
@Inject
public ConnectBackRequestHandler(@Assisted FacebookFriendConnection connection,
FeatureTransport.Handler<ConnectBackRequest> connectBackRequestHandler) {
this.connection = connection;
this.connectBackRequestHandler = connectBackRequestHandler;
}
@Inject
@Override
public void register(LiveMessageHandlerRegistry registry) {
registry.register(TYPE, this);
}
@Override
public void handle(String messageType, JSONObject message) throws JSONException {
assert messageType.equals(TYPE);
GUID clientGuid;
try {
clientGuid = new GUID(message.getString("client-guid"));
} catch (IllegalArgumentException iae) {
LOG.debug("invalid guid", iae);
throw new JSONException(iae);
}
int fwtVersion = message.getInt("supported-fwt-version");
Connectable address = deserializeAddress(message.getJSONObject("address"));
String from = message.getString("from");
connectBackRequestHandler.featureReceived(from, new ConnectBackRequest(address, clientGuid, fwtVersion));
}
static Connectable deserializeAddress(JSONObject address) throws JSONException {
ConnectableSerializer serializer = new ConnectableSerializer();
String type = address.getString("type");
if (!type.equals(serializer.getAddressType())) {
LOG.debugf("invalid address type: {0}", type);
throw new JSONException("wrong address type: " + type);
}
try {
return serializer.deserialize(Base64.decodeBase64(StringUtils.toUTF8Bytes(address.getString("value"))));
} catch (IOException ie) {
LOG.debug("invalid address", ie);
throw new JSONException(ie);
}
}
@Override
public void sendFeature(FriendPresence presence, ConnectBackRequest data)
throws FriendException {
try {
Map<String, Object> message = new HashMap<String, Object>();
message.put("client-guid", data.getClientGuid().toHexString());
message.put("supported-fwt-version", data.getSupportedFWTVersion());
Map<String, Object> address = new HashMap<String, Object>();
ConnectableSerializer serializer = new ConnectableSerializer();
address.put("type", serializer.getAddressType());
address.put("value", StringUtils.toUTF8String(Base64.encodeBase64(serializer.serialize(data.getAddress()))));
message.put("address", address);
connection.sendLiveMessage(presence, TYPE, message);
} catch (IOException ie) {
// not supposed to happen, would indicate internal erro in address serializer
throw new RuntimeException(ie);
}
}
}