use of org.structr.rest.resource.Resource in project structr by structr.
the class ResourceHelper method applyViewTransformation.
/**
* Apply view transformation on final resource, if any
*
* @param request
* @param securityContext
* @param finalResource
* @param propertyView
* @return transformedResource
* @throws FrameworkException
*/
public static Resource applyViewTransformation(final HttpServletRequest request, final SecurityContext securityContext, final Resource finalResource, final Value<String> propertyView) throws FrameworkException {
Resource transformedResource = finalResource;
// add view transformation
Class type = finalResource.getEntityClass();
if (type != null) {
ViewTransformation transformation = StructrApp.getConfiguration().getViewTransformation(type, propertyView.get(securityContext));
if (transformation != null) {
transformedResource = transformedResource.tryCombineWith(new TransformationResource(securityContext, transformation));
}
}
return transformedResource;
}
use of org.structr.rest.resource.Resource in project structr by structr.
the class RestDataSource method getData.
// FIXME: this method is needed by the websocket search command because there is no reference node for the above method
public List<GraphObject> getData(final RenderContext renderContext, final String restQuery) throws FrameworkException {
final Map<Pattern, Class<? extends Resource>> resourceMap = new LinkedHashMap<>();
final SecurityContext securityContext = renderContext.getSecurityContext();
ResourceProvider resourceProvider = renderContext.getResourceProvider();
if (resourceProvider == null) {
try {
resourceProvider = UiResourceProvider.class.newInstance();
} catch (Throwable t) {
logger.error("Couldn't establish a resource provider", t);
return Collections.EMPTY_LIST;
}
}
// inject resources
resourceMap.putAll(resourceProvider.getResources());
Value<String> propertyView = new ThreadLocalPropertyView();
propertyView.set(securityContext, PropertyView.Ui);
HttpServletRequest request = securityContext.getRequest();
if (request == null) {
request = renderContext.getRequest();
}
// initialize variables
// mimic HTTP request
final HttpServletRequest wrappedRequest = new HttpServletRequestWrapper(request) {
@Override
public Enumeration<String> getParameterNames() {
return new IteratorEnumeration(getParameterMap().keySet().iterator());
}
@Override
public String getParameter(final String key) {
String[] p = getParameterMap().get(key);
return p != null ? p[0] : null;
}
@Override
public String[] getParameterValues(final String key) {
return getParameterMap().get(key);
}
@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(restQuery, "?");
}
@Override
public String getPathInfo() {
return StringUtils.substringBefore(restQuery, "?");
}
@Override
public StringBuffer getRequestURL() {
return new StringBuffer(restQuery);
}
};
// store original request
final HttpServletRequest origRequest = securityContext.getRequest();
// update request in security context
securityContext.setRequest(wrappedRequest);
// HttpServletResponse response = renderContext.getResponse();
Resource resource = null;
try {
resource = ResourceHelper.applyViewTransformation(wrappedRequest, securityContext, ResourceHelper.optimizeNestedResourceChain(securityContext, wrappedRequest, resourceMap, propertyView), propertyView);
} catch (IllegalPathException | NotFoundException e) {
logger.warn("Illegal path for REST query: {}", restQuery);
}
// reset request to old context
securityContext.setRequest(origRequest);
if (resource == null) {
return Collections.EMPTY_LIST;
}
// experimental: disable result count, prevents instantiation
// of large collections just for counting all the objects..
securityContext.ignoreResultCount(true);
// TODO: decide if we need to rest the REST request here
// securityContext.checkResourceAccess(request, resource.getResourceSignature(), resource.getGrant(request, response), PropertyView.Ui);
// add sorting & paging
String pageSizeParameter = wrappedRequest.getParameter(JsonRestServlet.REQUEST_PARAMETER_PAGE_SIZE);
String pageParameter = wrappedRequest.getParameter(JsonRestServlet.REQUEST_PARAMETER_PAGE_NUMBER);
String sortOrder = wrappedRequest.getParameter(JsonRestServlet.REQUEST_PARAMETER_SORT_ORDER);
String sortKeyName = wrappedRequest.getParameter(JsonRestServlet.REQUEST_PARAMETER_SORT_KEY);
boolean sortDescending = (sortOrder != null && "desc".equals(sortOrder.toLowerCase()));
int pageSize = parseInt(pageSizeParameter, NodeFactory.DEFAULT_PAGE_SIZE);
int page = parseInt(pageParameter, NodeFactory.DEFAULT_PAGE);
PropertyKey sortKey = null;
// set sort key
if (sortKeyName != null) {
Class<? extends GraphObject> type = resource.getEntityClass();
if (type == null) {
// fallback to default implementation
// if no type can be determined
type = AbstractNode.class;
}
sortKey = StructrApp.getConfiguration().getPropertyKeyForDatabaseName(type, sortKeyName, false);
}
// do action
Result result = Result.EMPTY_RESULT;
try {
result = resource.doGet(sortKey, sortDescending, pageSize, page);
} catch (NotFoundException nfe) {
logger.warn("No result from internal REST query: {}", restQuery);
}
result.setIsCollection(resource.isCollectionResource());
result.setIsPrimitiveArray(resource.isPrimitiveArray());
// Integer rawResultCount = (Integer) Services.getAttribute(NodeFactory.RAW_RESULT_COUNT + Thread.currentThread().getId());
PagingHelper.addPagingParameter(result, pageSize, page);
List<GraphObject> res = result.getResults();
renderContext.setResult(result);
return res != null ? res : Collections.EMPTY_LIST;
}
use of org.structr.rest.resource.Resource in project structr by structr.
the class JsonRestServlet method doDelete.
// <editor-fold defaultstate="collapsed" desc="DELETE">
@Override
protected void doDelete(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
SecurityContext securityContext = null;
Authenticator authenticator = null;
RestMethodResult result = null;
Resource resource = null;
try {
assertInitialized();
// first thing to do!
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
// isolate request authentication in a transaction
try (final Tx tx = StructrApp.getInstance().tx()) {
authenticator = config.getAuthenticator();
securityContext = authenticator.initializeAndExamineRequest(request, response);
tx.success();
}
final App app = StructrApp.getInstance(securityContext);
// isolate resource authentication
try (final Tx tx = app.tx()) {
resource = ResourceHelper.optimizeNestedResourceChain(securityContext, request, resourceMap, propertyView);
authenticator.checkResourceAccess(securityContext, request, resource.getResourceSignature(), propertyView.get(securityContext));
tx.success();
}
// isolate doDelete
boolean retry = true;
while (retry) {
try {
result = resource.doDelete();
retry = false;
} catch (RetryException ddex) {
retry = true;
}
}
// isolate write output
try (final Tx tx = app.tx()) {
result.commitResponse(gson.get(), response);
tx.success();
}
} catch (FrameworkException frameworkException) {
// set status & write JSON output
response.setStatus(frameworkException.getStatus());
gson.get().toJson(frameworkException, response.getWriter());
response.getWriter().println();
} catch (JsonSyntaxException jsex) {
logger.warn("JsonSyntaxException in DELETE", jsex);
int code = HttpServletResponse.SC_BAD_REQUEST;
response.setStatus(code);
response.getWriter().append(RestMethodResult.jsonError(code, "JsonSyntaxException in DELETE: " + jsex.getMessage()));
} catch (JsonParseException jpex) {
logger.warn("JsonParseException in DELETE", jpex);
int code = HttpServletResponse.SC_BAD_REQUEST;
response.setStatus(code);
response.getWriter().append(RestMethodResult.jsonError(code, "JsonSyntaxException in DELETE: " + jpex.getMessage()));
} catch (Throwable t) {
logger.warn("Exception in DELETE", t);
int code = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
response.setStatus(code);
response.getWriter().append(RestMethodResult.jsonError(code, "JsonSyntaxException in DELETE: " + t.getMessage()));
} finally {
try {
// response.getWriter().flush();
response.getWriter().close();
} catch (IOException t) {
logger.warn("Unable to flush and close response: {}", t.getMessage());
}
}
}
use of org.structr.rest.resource.Resource in project structr by structr.
the class JsonRestServlet method doPut.
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="PUT">
@Override
protected void doPut(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
final SecurityContext securityContext;
final Authenticator authenticator;
final Resource resource;
RestMethodResult result = new RestMethodResult(HttpServletResponse.SC_BAD_REQUEST);
try {
assertInitialized();
// first thing to do!
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
// get reader before initalizing security context
final String input = IOUtils.toString(request.getReader());
// isolate request authentication in a transaction
try (final Tx tx = StructrApp.getInstance().tx()) {
authenticator = config.getAuthenticator();
securityContext = authenticator.initializeAndExamineRequest(request, response);
tx.success();
}
final App app = StructrApp.getInstance(securityContext);
final IJsonInput jsonInput = cleanAndParseJsonString(app, input);
if (securityContext != null) {
// isolate resource authentication
try (final Tx tx = app.tx()) {
// evaluate constraint chain
resource = ResourceHelper.applyViewTransformation(request, securityContext, ResourceHelper.optimizeNestedResourceChain(securityContext, request, resourceMap, propertyView), propertyView);
authenticator.checkResourceAccess(securityContext, request, resource.getResourceSignature(), propertyView.get(securityContext));
tx.success();
}
// isolate doPut
boolean retry = true;
while (retry) {
try (final Tx tx = app.tx()) {
result = resource.doPut(convertPropertySetToMap(jsonInput.getJsonInputs().get(0)));
tx.success();
retry = false;
} catch (RetryException ddex) {
retry = true;
}
}
// isolate write output
try (final Tx tx = app.tx()) {
result.commitResponse(gson.get(), response);
tx.success();
}
} else {
// isolate write output
try (final Tx tx = app.tx()) {
result = new RestMethodResult(HttpServletResponse.SC_FORBIDDEN);
result.commitResponse(gson.get(), response);
tx.success();
}
}
} catch (FrameworkException frameworkException) {
// set status & write JSON output
response.setStatus(frameworkException.getStatus());
gson.get().toJson(frameworkException, response.getWriter());
response.getWriter().println();
} catch (JsonSyntaxException jsex) {
logger.warn("PUT: Invalid JSON syntax", jsex.getMessage());
int code = HttpServletResponse.SC_BAD_REQUEST;
response.setStatus(code);
response.getWriter().append(RestMethodResult.jsonError(code, "JsonSyntaxException in PUT: " + jsex.getMessage()));
} catch (JsonParseException jpex) {
logger.warn("PUT: Unable to parse JSON string", jpex.getMessage());
int code = HttpServletResponse.SC_BAD_REQUEST;
response.setStatus(code);
response.getWriter().append(RestMethodResult.jsonError(code, "JsonSyntaxException in PUT: " + jpex.getMessage()));
} catch (Throwable t) {
logger.warn("Exception in PUT", t);
logger.warn("", t);
int code = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
response.setStatus(code);
response.getWriter().append(RestMethodResult.jsonError(code, "JsonSyntaxException in PUT: " + t.getMessage()));
} finally {
try {
// response.getWriter().flush();
response.getWriter().close();
} catch (Throwable t) {
logger.warn("Unable to flush and close response: {}", t.getMessage());
}
}
}
use of org.structr.rest.resource.Resource in project structr by structr.
the class JsonRestServlet method doOptions.
// <editor-fold defaultstate="collapsed" desc="OPTIONS">
@Override
protected void doOptions(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
final SecurityContext securityContext;
final Authenticator authenticator;
final Resource resource;
RestMethodResult result = new RestMethodResult(HttpServletResponse.SC_BAD_REQUEST);
try {
assertInitialized();
// first thing to do!
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
// isolate request authentication in a transaction
try (final Tx tx = StructrApp.getInstance().tx()) {
authenticator = config.getAuthenticator();
securityContext = authenticator.initializeAndExamineRequest(request, response);
tx.success();
}
final App app = StructrApp.getInstance(securityContext);
// isolate resource authentication
try (final Tx tx = app.tx()) {
resource = ResourceHelper.applyViewTransformation(request, securityContext, ResourceHelper.optimizeNestedResourceChain(securityContext, request, resourceMap, propertyView), propertyView);
authenticator.checkResourceAccess(securityContext, request, resource.getResourceSignature(), propertyView.get(securityContext));
tx.success();
}
// isolate doOptions
boolean retry = true;
while (retry) {
try (final Tx tx = app.tx()) {
result = resource.doOptions();
tx.success();
retry = false;
} catch (RetryException ddex) {
retry = true;
}
}
// isolate write output
try (final Tx tx = app.tx()) {
result.commitResponse(gson.get(), response);
tx.success();
}
} catch (FrameworkException frameworkException) {
// set status & write JSON output
response.setStatus(frameworkException.getStatus());
gson.get().toJson(frameworkException, response.getWriter());
response.getWriter().println();
} catch (JsonSyntaxException jsex) {
logger.warn("JsonSyntaxException in OPTIONS", jsex);
int code = HttpServletResponse.SC_BAD_REQUEST;
response.setStatus(code);
response.getWriter().append(RestMethodResult.jsonError(code, "JsonSyntaxException in OPTIONS: " + jsex.getMessage()));
} catch (JsonParseException jpex) {
logger.warn("JsonParseException in OPTIONS", jpex);
int code = HttpServletResponse.SC_BAD_REQUEST;
response.setStatus(code);
response.getWriter().append(RestMethodResult.jsonError(code, "JsonSyntaxException in OPTIONS: " + jpex.getMessage()));
} catch (Throwable t) {
logger.warn("Exception in OPTIONS", t);
int code = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
response.setStatus(code);
response.getWriter().append(RestMethodResult.jsonError(code, "JsonSyntaxException in OPTIONS: " + t.getMessage()));
} finally {
try {
// response.getWriter().flush();
response.getWriter().close();
} catch (Throwable t) {
logger.warn("Unable to flush and close response: {}", t.getMessage());
}
}
}
Aggregations