/* (c) 2014 - 2016 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.wps.remote.plugin;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.geoserver.wps.remote.RemoteProcessClientListener;
import org.geoserver.wps.remote.plugin.output.XMPPOutputDefaultProducer;
import org.geotools.util.logging.Logging;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import net.razorvine.pickle.PickleException;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
/**
* Listens for "COMPLETE" messages from XMPP service channels and takes action accordingly.
*
* @author Alessio Fabiani, GeoSolutions
*
*/
public class XMPPCompletedMessage implements XMPPMessage {
/** The LOGGER */
public static final Logger LOGGER = Logging.getLogger(XMPPMessage.class.getPackage().getName());
@Override
public boolean canHandle(Map<String, String> signalArgs) {
if (signalArgs != null && signalArgs.get("topic") != null)
return signalArgs.get("topic").equals("completed");
return false;
}
@Override
public void handleSignal(XMPPClient xmppClient, Packet packet, Message message,
Map<String, String> signalArgs) {
final String pID = signalArgs.get("id");
final String msg = signalArgs.get("message");
final String baseURL = signalArgs.get("baseURL");
final XMPPOutputDefaultProducer outputProducer = new XMPPOutputDefaultProducer();
// NOTIFY THE LISTENERS
if (msg != null && msg.equals("completed")) {
final Map<String, Object> outputs = new HashMap<String, Object>();
try {
for (Entry<String, String> result : new TreeMap<String, String>(signalArgs).entrySet()) {
if (result.getKey().startsWith("result")) {
final String serviceResultString = URLDecoder.decode(result.getValue(),
"UTF-8");
final JSONObject serviceResultJSON = (JSONObject) JSONSerializer
.toJSON(serviceResultString);
final Object output = xmppClient
.unPickle(xmppClient.pickle(serviceResultJSON));
// XMPP Output Visitor
if (output instanceof Map) {
final Map<String, Object> resultParams = (Map<String, Object>) output;
// transform the textual value into a real WPS
// output
try {
final Object value = (resultParams
.get(result.getKey() + "_value") != null
? resultParams.get(result.getKey() + "_value")
: null);
final String type = (String) (resultParams
.get(result.getKey() + "_type") != null
? resultParams.get(result.getKey() + "_type")
: null);
final String description = (resultParams
.get(result.getKey() + "_description") != null
&& resultParams.get(
result.getKey() + "_description") instanceof String
? (String) resultParams.get(
result.getKey() + "_description")
: null);
final String title = (resultParams
.get(result.getKey() + "_title") != null
&& resultParams
.get(result.getKey() + "_title") instanceof String
? (String) resultParams
.get(result.getKey() + "_title")
: null);
final String layerName = (resultParams
.get(result.getKey() + "_layer_name") != null
&& resultParams.get(
result.getKey() + "_layer_name") instanceof String
? (String) resultParams.get(
result.getKey() + "_layer_name")
: null);
final String defaultStyle = (resultParams
.get(result.getKey() + "_style") != null
&& resultParams
.get(result.getKey() + "_style") instanceof String
? (String) resultParams
.get(result.getKey() + "_style")
: null);
final String targetWorkspace = (resultParams
.get(result.getKey() + "_workspace") != null
&& resultParams.get(
result.getKey() + "_workspace") instanceof String
? (String) resultParams
.get(result.getKey() + "_workspace")
: null);
final String metadata = (resultParams
.get(result.getKey() + "_metadata") != null
&& resultParams.get(
result.getKey() + "_metadata") instanceof String
? (String) resultParams
.get(result.getKey() + "_metadata")
: null);
Boolean publish = true;
if (resultParams.get(result.getKey() + "_pub") != null) {
if (resultParams
.get(result.getKey() + "_pub") instanceof String)
publish = Boolean.valueOf((String) resultParams
.get(result.getKey() + "_pub"));
else if (resultParams
.get(result.getKey() + "_pub") instanceof Boolean)
publish = (Boolean) resultParams
.get(result.getKey() + "_pub");
}
Object wpsOutputValue = outputProducer.produceOutput(value, type,
pID, baseURL, xmppClient, publish, layerName, title,
description, defaultStyle, targetWorkspace, metadata);
LOGGER.finest(
"[XMPPCompletedMessage] wpsOutputValue:" + wpsOutputValue);
// add the transformed result to the process
// outputs
if (wpsOutputValue != null) {
outputs.put(result.getKey(), wpsOutputValue);
continue;
} else {
// throw new Exception("All the Output
// Producers failed transforming the WPS
// Output!");
LOGGER.warning(
"At least one of the Oputput Producres failed transforming the WPS Output!");
}
} catch (Exception e) {
LOGGER.log(Level.SEVERE,
"Exception occurred while trying to produce the result:",
e);
}
}
}
}
for (RemoteProcessClientListener listener : xmppClient.getRemoteClientListeners()) {
listener.complete(pID, outputs);
}
} catch (PickleException e) {
LOGGER.log(Level.FINER, e.getMessage(), e);
} catch (IOException e) {
LOGGER.log(Level.FINER, e.getMessage(), e);
}
}
// In any case stop the process by notifying the listeners ...
else {
for (RemoteProcessClientListener listener : xmppClient.getRemoteClientListeners()) {
listener.complete(pID, null);
}
}
// NOTIFY THE SERVICE
final String serviceJID = message.getFrom();
xmppClient.sendMessage(serviceJID, "topic=finish");
}
}