/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.web.config; import static com.opengamma.web.json.AbstractJSONBuilder.fudgeToJson; import java.net.URI; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.EntityTag; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Request; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.Response.Status; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import org.joda.beans.impl.flexi.FlexiBean; import com.opengamma.core.config.impl.ConfigItem; import com.opengamma.id.UniqueId; import com.opengamma.master.config.ConfigDocument; import com.opengamma.web.json.JSONBuilder; /** * RESTful resource for a configuration document. * */ @Path("/configs/{configId}") public class WebConfigResource extends AbstractWebConfigResource { /** * Creates the resource. * @param parent the parent resource, not null */ public WebConfigResource(final AbstractWebConfigResource parent) { super(parent); } //------------------------------------------------------------------------- @GET @Produces(MediaType.TEXT_HTML) public String getHTML() { final FlexiBean out = createRootData(); final ConfigDocument doc = data().getConfig(); out.put(CONFIG_XML, StringEscapeUtils.escapeJava(createBeanXML(doc.getConfig().getValue()))); return getFreemarker().build(HTML_DIR + "config.ftl", out); } @GET @Produces(MediaType.APPLICATION_JSON) public Response getJSON(@Context final Request request) { final EntityTag etag = new EntityTag(data().getConfig().getUniqueId().toString()); final ResponseBuilder builder = request.evaluatePreconditions(etag); if (builder != null) { return builder.build(); } final FlexiBean out = createRootData(); final ConfigDocument doc = data().getConfig(); final String jsonConfig = StringUtils.stripToNull(toJSON(doc.getConfig().getValue(), doc.getType())); if (jsonConfig != null) { out.put("configJSON", jsonConfig); } out.put(CONFIG_XML, StringEscapeUtils.escapeJava(createBeanXML(doc.getConfig().getValue()))); out.put("type", doc.getType().getSimpleName()); final String json = getFreemarker().build(JSON_DIR + "config.ftl", out); return Response.ok(json).tag(etag).build(); } @SuppressWarnings("unchecked") private <T> String toJSON(final Object configObj, final Class<T> configType) { final JSONBuilder<T> jsonBuilder = (JSONBuilder<T>) data().getJsonBuilderMap().get(configType); String result = null; if (jsonBuilder != null) { result = jsonBuilder.toJSON((T) configObj); } else { result = fudgeToJson(configObj); } return result; } //------------------------------------------------------------------------- @PUT @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Produces(MediaType.TEXT_HTML) public Response putHTML( @FormParam("name") String name, @FormParam(CONFIG_XML) String configXml) { if (data().getConfig().isLatest() == false) { return Response.status(Status.FORBIDDEN).entity(getHTML()).build(); } name = StringUtils.trimToNull(name); configXml = StringUtils.trimToNull(configXml); if (name == null || configXml == null) { final FlexiBean out = createRootData(); out.put(CONFIG_XML, StringEscapeUtils.escapeJavaScript(StringUtils.defaultString(configXml))); if (name == null) { out.put("err_nameMissing", true); } if (configXml == null) { out.put("err_xmlMissing", true); } final String html = getFreemarker().build(HTML_DIR + "config-update.ftl", out); return Response.ok(html).build(); } Object parsed = parseXML(configXml, data().getConfig().getConfig().getType()); final URI uri = updateConfig(name, parsed); return Response.seeOther(uri).build(); } @PUT @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Produces(MediaType.APPLICATION_JSON) public Response putJSON( @FormParam("name") String name, @FormParam("configJSON") String json, @FormParam(CONFIG_XML) String configXml) { if (data().getConfig().isLatest() == false) { return Response.status(Status.FORBIDDEN).entity(getHTML()).build(); } name = StringUtils.trimToNull(name); json = StringUtils.trimToNull(json); configXml = StringUtils.trimToNull(configXml); // JSON allows a null config to just change the name if (name == null) { return Response.status(Status.BAD_REQUEST).build(); } Object configValue = null; if (json != null) { configValue = parseJSON(json); } else if (configXml != null) { Object parsed = parseXML(configXml, data().getConfig().getConfig().getType()); configValue = parsed; } updateConfig(name, configValue); return Response.ok().build(); } private URI updateConfig(final String name, final Object newConfigValue) { final ConfigDocument oldDoc = data().getConfig(); final ConfigItem<?> newItem = ConfigItem.of(newConfigValue); newItem.setName(name); newItem.setType(oldDoc.getType()); ConfigDocument doc = new ConfigDocument(newItem); doc.setUniqueId(oldDoc.getUniqueId()); doc = data().getConfigMaster().update(doc); data().setConfig(doc); final URI uri = WebConfigResource.uri(data()); return uri; } //------------------------------------------------------------------------- @DELETE @Produces(MediaType.TEXT_HTML) public Response deleteHTML() { final ConfigDocument doc = data().getConfig(); if (doc.isLatest() == false) { return Response.status(Status.FORBIDDEN).entity(getHTML()).build(); } data().getConfigMaster().remove(doc.getUniqueId()); final URI uri = WebConfigsResource.uri(data()); return Response.seeOther(uri).build(); } @DELETE @Produces(MediaType.APPLICATION_JSON) public Response deleteJSON() { final ConfigDocument doc = data().getConfig(); if (doc.isLatest()) { data().getConfigMaster().remove(doc.getUniqueId()); } return Response.ok().build(); } //------------------------------------------------------------------------- /** * Creates the output root data. * @return the output root data, not null */ @Override protected FlexiBean createRootData() { final FlexiBean out = super.createRootData(); final ConfigDocument doc = data().getConfig(); out.put("configDoc", doc); out.put("config", doc.getConfig().getValue()); out.put("configDescription", getConfigTypesProvider().getDescription(doc.getConfig().getType())); out.put("deleted", !doc.isLatest()); return out; } //------------------------------------------------------------------------- @Path("versions") public WebConfigVersionsResource findVersions() { return new WebConfigVersionsResource(this); } //------------------------------------------------------------------------- /** * Builds a URI for this resource. * @param data the data, not null * @return the URI, not null */ public static URI uri(final WebConfigData data) { return uri(data, null); } /** * Builds a URI for this resource. * @param data the data, not null * @param overrideConfigId the override config id, null uses information from data * @return the URI, not null */ public static URI uri(final WebConfigData data, final UniqueId overrideConfigId) { final String configId = data.getBestConfigUriId(overrideConfigId); return data.getUriInfo().getBaseUriBuilder().path(WebConfigResource.class).build(configId); } }