use of org.structr.rest.resource.Resource in project structr by structr.
the class ResourceHelper method optimizeNestedResourceChain.
/**
* Optimize the resource chain by trying to combine two resources to a new one
*
* @param securityContext
* @param request
* @param resourceMap
* @param propertyView
* @return finalResource
* @throws FrameworkException
*/
public static Resource optimizeNestedResourceChain(final SecurityContext securityContext, final HttpServletRequest request, final Map<Pattern, Class<? extends Resource>> resourceMap, final Value<String> propertyView) throws FrameworkException {
final List<Resource> resourceChain = ResourceHelper.parsePath(securityContext, request, resourceMap, propertyView);
ViewFilterResource view = null;
int num = resourceChain.size();
boolean found = false;
do {
for (Iterator<Resource> it = resourceChain.iterator(); it.hasNext(); ) {
Resource constr = it.next();
if (constr instanceof ViewFilterResource) {
view = (ViewFilterResource) constr;
it.remove();
}
}
found = false;
try {
for (int i = 0; i < num; i++) {
Resource firstElement = resourceChain.get(i);
Resource secondElement = resourceChain.get(i + 1);
Resource combinedConstraint = firstElement.tryCombineWith(secondElement);
if (combinedConstraint != null) {
// remove source constraints
resourceChain.remove(firstElement);
resourceChain.remove(secondElement);
// add combined constraint
resourceChain.add(i, combinedConstraint);
// signal success
found = true;
}
}
} catch (Throwable t) {
// ignore exceptions thrown here
}
} while (found);
if (resourceChain.size() == 1) {
Resource finalResource = resourceChain.get(0);
if (view != null) {
finalResource = finalResource.tryCombineWith(view);
}
if (finalResource == null) {
// fall back to original resource
finalResource = resourceChain.get(0);
}
return finalResource;
} else {
logger.warn("Resource chain evaluation for path {} resulted in {} entries, returning status code 400.", new Object[] { request.getPathInfo(), resourceChain.size() });
}
throw new IllegalPathException("Cannot resolve URL path");
}
use of org.structr.rest.resource.Resource in project structr by structr.
the class WrappedRestCommand method processMessage.
@Override
public void processMessage(final WebSocketMessage webSocketData) throws FrameworkException {
final Map<String, Object> nodeData = webSocketData.getNodeData();
final String method = (String) nodeData.get("method");
if (method == null || !(method.equals("POST") || method.equals("PUT"))) {
logger.warn("Method not supported: {}", method);
getWebSocket().send(MessageBuilder.wrappedRest().code(422).message("Method not supported: " + method).build(), true);
return;
}
ResourceProvider resourceProvider;
try {
resourceProvider = UiResourceProvider.class.newInstance();
} catch (Throwable t) {
logger.error("Couldn't establish a resource provider", t);
getWebSocket().send(MessageBuilder.wrappedRest().code(422).message("Couldn't establish a resource provider").build(), true);
return;
}
final Map<Pattern, Class<? extends Resource>> resourceMap = new LinkedHashMap<>();
resourceMap.putAll(resourceProvider.getResources());
final StructrWebSocket socket = this.getWebSocket();
final String url = (String) nodeData.get("url");
// mimic HTTP request
final HttpServletRequest wrappedRequest = new HttpServletRequestWrapper(socket.getRequest()) {
@Override
public Enumeration<String> getParameterNames() {
return new IteratorEnumeration(getParameterMap().keySet().iterator());
}
@Override
public String getParameter(String key) {
String[] p = getParameterMap().get(key);
return p != null ? p[0] : null;
}
@Override
public Map<String, String[]> getParameterMap() {
String[] parts = StringUtils.split(getQueryString(), "&");
Map<String, String[]> parameterMap = new HashMap();
for (String p : parts) {
String[] kv = StringUtils.split(p, "=");
if (kv.length > 1) {
parameterMap.put(kv[0], new String[] { kv[1] });
}
}
return parameterMap;
}
@Override
public String getQueryString() {
return StringUtils.substringAfter(url, "?");
}
@Override
public String getPathInfo() {
return StringUtils.substringBefore(url, "?");
}
@Override
public StringBuffer getRequestURL() {
return new StringBuffer(url);
}
};
Resource resource;
final StaticValue fakePropertyView = new StaticValue(PropertyView.Public);
try {
resource = ResourceHelper.applyViewTransformation(wrappedRequest, socket.getSecurityContext(), ResourceHelper.optimizeNestedResourceChain(socket.getSecurityContext(), wrappedRequest, resourceMap, fakePropertyView), fakePropertyView);
} catch (IllegalPathException | NotFoundException e) {
logger.warn("Illegal path for REST query");
getWebSocket().send(MessageBuilder.wrappedRest().code(422).message("Illegal path for REST query").build(), true);
return;
}
final String data = (String) nodeData.get("data");
final Gson gson = new GsonBuilder().create();
final Map<String, Object> jsonData = gson.fromJson(data, Map.class);
RestMethodResult result = null;
switch(method) {
case "PUT":
// we want to update data
result = resource.doPut(jsonData);
break;
case "POST":
// we either want to create data or call a method on an object
result = resource.doPost(jsonData);
break;
}
// right now we do not send messages
if (result != null) {
// getWebSocket().send(MessageBuilder.wrappedRest().code(result.getResponseCode()).message(result.jsonMessage()).build(), true);
}
}
Aggregations