package com.psddev.cms.tool;
import com.psddev.cms.db.ToolUser;
import com.psddev.dari.db.State;
import com.psddev.dari.util.ObjectUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
/** Widget at a remote location that is accessible through web APIs. */
public class RemoteWidget extends Widget {
public static final String OBJECT_PARAMETER = "_object";
public static final String USER_ID_PARAMETER = "_userId";
public static final String WIDGET_PARAMETER = "_widget";
private String displayApi;
private String updateApi;
/** Creates a JSON string that represents the given {@code object}. */
private static String getJson(Object object) {
State state = State.getInstance(object);
Map<String, Object> values = state.getSimpleValues();
values.put("_id", state.getId().toString());
values.put("_typeId", state.getTypeId().toString());
return ObjectUtils.toJson(values);
}
/** Displays the given {@code widget}. */
public static String displayWidget(Widget widget, String api, ToolPageContext page, Object object) throws Exception {
HttpClient client = new DefaultHttpClient();
try {
HttpPost post = new HttpPost(widget.getTool().getUrl() + api);
List<NameValuePair> pairs = new ArrayList<NameValuePair>();
for (String name : page.paramNames()) {
for (String value : page.params(name)) {
pairs.add(new BasicNameValuePair(name, value));
}
}
ToolUser user = page.getUser();
if (user != null) {
pairs.add(new BasicNameValuePair(USER_ID_PARAMETER, user.getId().toString()));
}
pairs.add(new BasicNameValuePair(OBJECT_PARAMETER, getJson(object)));
pairs.add(new BasicNameValuePair(WIDGET_PARAMETER, getJson(widget)));
post.setEntity(new UrlEncodedFormEntity(pairs, HTTP.UTF_8));
return client.execute(post, new BasicResponseHandler());
} finally {
client.getConnectionManager().shutdown();
}
}
/** Updates with the given {@code widget}. */
public static void updateWithWidget(Widget widget, String api, ToolPageContext page, Object object) throws Exception {
String json = displayWidget(widget, api, page, object);
Map<String, Object> values = (Map<String, Object>) ObjectUtils.fromJson(json);
State.getInstance(object).setValues(values);
}
/** Returns the display API location. */
public String getDisplayApi() {
return displayApi;
}
/** Sets the display API location. */
public void setDisplayApi(String api) {
this.displayApi = api;
}
/** Returns the update API location. */
public String getUpdateApi() {
return updateApi;
}
/** Sets the update API location. */
public void setUpdateApi(String api) {
this.updateApi = api;
}
// --- Widget support ---
@Override
public String display(ToolPageContext page, Object object) throws Exception {
return displayWidget(this, getDisplayApi(), page, object);
}
@Override
public void update(ToolPageContext page, Object object) throws Exception {
updateWithWidget(this, getUpdateApi(), page, object);
}
}