use of org.structr.rest.resource.Resource in project structr by structr.
the class CsvServlet method doGet.
@Override
protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws UnsupportedEncodingException {
Authenticator authenticator = null;
Result result = null;
Resource resource = null;
try {
// 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);
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/csv; charset=utf-8");
// set default value for property view
propertyView.set(securityContext, defaultPropertyView);
// evaluate constraints and measure query time
double queryTimeStart = System.nanoTime();
// 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();
}
try (final Tx tx = app.tx()) {
String resourceSignature = resource.getResourceSignature();
// let authenticator examine request again
authenticator.checkResourceAccess(securityContext, request, resourceSignature, propertyView.get(securityContext));
// add sorting & paging
String pageSizeParameter = request.getParameter(JsonRestServlet.REQUEST_PARAMETER_PAGE_SIZE);
String pageParameter = request.getParameter(JsonRestServlet.REQUEST_PARAMETER_PAGE_NUMBER);
String sortOrder = request.getParameter(JsonRestServlet.REQUEST_PARAMETER_SORT_ORDER);
String sortKeyName = request.getParameter(JsonRestServlet.REQUEST_PARAMETER_SORT_KEY);
boolean sortDescending = (sortOrder != null && "desc".equals(sortOrder.toLowerCase()));
int pageSize = Services.parseInt(pageSizeParameter, NodeFactory.DEFAULT_PAGE_SIZE);
int page = Services.parseInt(pageParameter, NodeFactory.DEFAULT_PAGE);
PropertyKey sortKey = null;
// set sort key
if (sortKeyName != null) {
Class<? extends GraphObject> type = resource.getEntityClass();
sortKey = StructrApp.getConfiguration().getPropertyKeyForDatabaseName(type, sortKeyName, false);
}
// Should line breaks be removed?
removeLineBreaks = StringUtils.equals(request.getParameter(REMOVE_LINE_BREAK_PARAM), "1");
// Should a leading BOM be written?
writeBom = StringUtils.equals(request.getParameter(WRITE_BOM), "1");
// do action
result = resource.doGet(sortKey, sortDescending, pageSize, page);
if (result != null) {
result.setIsCollection(resource.isCollectionResource());
result.setIsPrimitiveArray(resource.isPrimitiveArray());
PagingHelper.addPagingParameter(result, pageSize, page);
// timing..
final double queryTimeEnd = System.nanoTime();
// store property view that will be used to render the results
result.setPropertyView(propertyView.get(securityContext));
// allow resource to modify result set
resource.postProcessResultSet(result);
DecimalFormat decimalFormat = new DecimalFormat("0.000000000", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
result.setQueryTime(decimalFormat.format((queryTimeEnd - queryTimeStart) / 1000000000.0));
Writer writer = response.getWriter();
if (writeBom) {
writeUtf8Bom(writer);
}
// gson.toJson(result, writer);
writeCsv(result, writer, propertyView.get(securityContext));
response.setStatus(HttpServletResponse.SC_OK);
writer.flush();
writer.close();
} else {
logger.warn("Result was null!");
int code = HttpServletResponse.SC_NO_CONTENT;
response.setStatus(code);
Writer writer = response.getWriter();
writer.flush();
writer.close();
}
tx.success();
}
} catch (FrameworkException frameworkException) {
// set status
response.setStatus(frameworkException.getStatus());
} catch (JsonSyntaxException jsex) {
logger.warn("JsonSyntaxException in GET", jsex);
int code = HttpServletResponse.SC_BAD_REQUEST;
response.setStatus(code);
} catch (JsonParseException jpex) {
logger.warn("JsonParseException in GET", jpex);
int code = HttpServletResponse.SC_BAD_REQUEST;
response.setStatus(code);
} catch (Throwable t) {
logger.warn("Exception in GET", t);
int code = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
response.setStatus(code);
}
}
use of org.structr.rest.resource.Resource in project structr by structr.
the class CsvServlet method doPost.
@Override
protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
final String fieldSeparatorHeader = request.getHeader(DEFAULT_FIELD_SEPARATOR_HEADER_NAME);
final char fieldSeparator = (fieldSeparatorHeader == null) ? DEFAULT_FIELD_SEPARATOR : fieldSeparatorHeader.charAt(0);
final String quoteCharacterHeader = request.getHeader(DEFAULT_QUOTE_CHARACTER_HEADER_NAME);
final char quoteCharacter = (quoteCharacterHeader == null) ? DEFAULT_QUOTE_CHARACTER : quoteCharacterHeader.charAt(0);
final String doPeridicCommitHeader = request.getHeader(DEFAULT_PERIODIC_COMMIT_HEADER_NAME);
final boolean doPeriodicCommit = (doPeridicCommitHeader == null) ? DEFAULT_PERIODIC_COMMIT : Boolean.parseBoolean(doPeridicCommitHeader);
final String periodicCommitIntervalHeader = request.getHeader(DEFAULT_PERIODIC_COMMIT_INTERVAL_HEADER_NAME);
final int periodicCommitInterval = (periodicCommitIntervalHeader == null) ? DEFAULT_PERIODIC_COMMIT_INTERVAL : Integer.parseInt(periodicCommitIntervalHeader);
final String rangeHeader = request.getHeader(DEFAULT_RANGE_HEADER_NAME);
final List<RestMethodResult> results = new LinkedList<>();
final Authenticator authenticator;
final Resource resource;
try {
// 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 Reader input = 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);
if (securityContext != null) {
// 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();
}
// do not send websocket notifications for created objects
securityContext.setDoTransactionNotifications(false);
securityContext.disableModificationOfAccessTime();
securityContext.ignoreResultCount(true);
securityContext.disableEnsureCardinality();
final String username = securityContext.getUser(false).getName();
final long startTime = System.currentTimeMillis();
final Map<String, Object> data = new LinkedHashMap();
data.put("type", "CSV_IMPORT_STATUS");
data.put("subtype", "BEGIN");
data.put("username", username);
TransactionCommand.simpleBroadcastGenericMessage(data);
// isolate doPost
boolean retry = true;
while (retry) {
retry = false;
final Iterable<JsonInput> csv = CsvHelper.cleanAndParseCSV(securityContext, input, resource.getEntityClass(), fieldSeparator, quoteCharacter, rangeHeader);
if (resource.createPostTransaction()) {
if (doPeriodicCommit) {
final List<JsonInput> list = new ArrayList<>();
csv.iterator().forEachRemaining(list::add);
final List<List<JsonInput>> chunkedCsv = ListUtils.partition(list, periodicCommitInterval);
final int totalChunkNo = chunkedCsv.size();
int currentChunkNo = 0;
for (final List<JsonInput> currentChunk : chunkedCsv) {
try (final Tx tx = app.tx()) {
currentChunkNo++;
for (final JsonInput propertySet : currentChunk) {
handleCsvPropertySet(results, resource, propertySet);
}
tx.success();
logger.info("CSV: Finished importing chunk " + currentChunkNo + " / " + totalChunkNo);
final Map<String, Object> chunkMsgData = new LinkedHashMap();
chunkMsgData.put("type", "CSV_IMPORT_STATUS");
chunkMsgData.put("subtype", "CHUNK");
chunkMsgData.put("currentChunkNo", currentChunkNo);
chunkMsgData.put("totalChunkNo", totalChunkNo);
chunkMsgData.put("username", username);
TransactionCommand.simpleBroadcastGenericMessage(chunkMsgData);
} catch (RetryException ddex) {
retry = true;
}
}
} else {
try (final Tx tx = app.tx()) {
for (final JsonInput propertySet : csv) {
handleCsvPropertySet(results, resource, propertySet);
}
tx.success();
} catch (RetryException ddex) {
retry = true;
}
}
} else {
if (doPeriodicCommit) {
logger.warn("Resource auto-creates POST transaction - can not commit periodically!");
}
try {
for (final JsonInput propertySet : csv) {
handleCsvPropertySet(results, resource, propertySet);
}
} catch (RetryException ddex) {
retry = true;
}
}
}
final long endTime = System.currentTimeMillis();
DecimalFormat decimalFormat = new DecimalFormat("0.00", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
final String duration = decimalFormat.format(((endTime - startTime) / 1000.0)) + "s";
logger.info("CSV: Finished importing CSV data (Time: {})", duration);
final Map<String, Object> endMsgData = new LinkedHashMap();
endMsgData.put("type", "CSV_IMPORT_STATUS");
endMsgData.put("subtype", "END");
endMsgData.put("duration", duration);
endMsgData.put("username", username);
TransactionCommand.simpleBroadcastGenericMessage(endMsgData);
// set default value for property view
propertyView.set(securityContext, config.getDefaultPropertyView());
// isolate write output
try (final Tx tx = app.tx()) {
if (!results.isEmpty()) {
final RestMethodResult result = results.get(0);
final int resultCount = results.size();
if (result != null) {
if (resultCount > 1) {
for (final RestMethodResult r : results) {
final GraphObject objectCreated = r.getContent().get(0);
if (!result.getContent().contains(objectCreated)) {
result.addContent(objectCreated);
}
}
// remove Location header if more than one object was
// written because it may only contain a single URL
result.addHeader("Location", null);
}
result.commitResponse(gson.get(), response);
}
}
tx.success();
}
} else {
// isolate write output
try (final Tx tx = app.tx()) {
new RestMethodResult(HttpServletResponse.SC_FORBIDDEN).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("POST: Invalid JSON syntax", jsex.getMessage());
int code = HttpServletResponse.SC_BAD_REQUEST;
response.setStatus(code);
response.getWriter().append(RestMethodResult.jsonError(code, "JsonSyntaxException in POST: " + jsex.getMessage()));
} catch (JsonParseException jpex) {
logger.warn("Unable to parse JSON string", jpex.getMessage());
int code = HttpServletResponse.SC_BAD_REQUEST;
response.setStatus(code);
response.getWriter().append(RestMethodResult.jsonError(code, "JsonParseException in POST: " + jpex.getMessage()));
} catch (UnsupportedOperationException uoe) {
logger.warn("POST not supported");
int code = HttpServletResponse.SC_BAD_REQUEST;
response.setStatus(code);
response.getWriter().append(RestMethodResult.jsonError(code, "POST not supported: " + uoe.getMessage()));
} catch (Throwable t) {
logger.warn("Exception in POST", t);
int code = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
response.setStatus(code);
response.getWriter().append(RestMethodResult.jsonError(code, "JsonSyntaxException in POST: " + 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 doPost.
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="POST">
@Override
protected void doPost(final HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
final List<RestMethodResult> results = new LinkedList<>();
final SecurityContext securityContext;
final Authenticator authenticator;
final Resource resource;
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()) {
resource = ResourceHelper.applyViewTransformation(request, securityContext, ResourceHelper.optimizeNestedResourceChain(securityContext, request, resourceMap, propertyView), propertyView);
authenticator.checkResourceAccess(securityContext, request, resource.getResourceSignature(), propertyView.get(securityContext));
tx.success();
}
// isolate doPost
boolean retry = true;
while (retry) {
if (resource.createPostTransaction()) {
try (final Tx tx = app.tx()) {
for (JsonInput propertySet : jsonInput.getJsonInputs()) {
results.add(resource.doPost(convertPropertySetToMap(propertySet)));
}
tx.success();
retry = false;
} catch (RetryException ddex) {
retry = true;
}
} else {
try {
for (JsonInput propertySet : jsonInput.getJsonInputs()) {
results.add(resource.doPost(convertPropertySetToMap(propertySet)));
}
retry = false;
} catch (RetryException ddex) {
retry = true;
}
}
}
// set default value for property view
propertyView.set(securityContext, config.getDefaultPropertyView());
// isolate write output
try (final Tx tx = app.tx()) {
if (!results.isEmpty()) {
final RestMethodResult result = results.get(0);
final int resultCount = results.size();
if (result != null) {
if (resultCount > 1) {
for (final RestMethodResult r : results) {
final GraphObject objectCreated = r.getContent().get(0);
if (!result.getContent().contains(objectCreated)) {
result.addContent(objectCreated);
}
}
// remove Location header if more than one object was
// written because it may only contain a single URL
result.addHeader("Location", null);
}
result.commitResponse(gson.get(), response);
}
}
tx.success();
}
} else {
// isolate write output
try (final Tx tx = app.tx()) {
new RestMethodResult(HttpServletResponse.SC_FORBIDDEN).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("POST: Invalid JSON syntax", jsex.getMessage());
int code = HttpServletResponse.SC_BAD_REQUEST;
response.setStatus(code);
response.getWriter().append(RestMethodResult.jsonError(code, "JsonSyntaxException in POST: " + jsex.getMessage()));
} catch (JsonParseException jpex) {
logger.warn("Unable to parse JSON string", jpex.getMessage());
int code = HttpServletResponse.SC_BAD_REQUEST;
response.setStatus(code);
response.getWriter().append(RestMethodResult.jsonError(code, "JsonParseException in POST: " + jpex.getMessage()));
} catch (UnsupportedOperationException uoe) {
logger.warn("POST not supported");
int code = HttpServletResponse.SC_BAD_REQUEST;
response.setStatus(code);
response.getWriter().append(RestMethodResult.jsonError(code, "POST not supported: " + uoe.getMessage()));
} catch (Throwable t) {
logger.warn("Exception in POST", t);
int code = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
response.setStatus(code);
response.getWriter().append(RestMethodResult.jsonError(code, "JsonSyntaxException in POST: " + 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 doGetOrHead.
private void doGetOrHead(final HttpServletRequest request, final HttpServletResponse response, final boolean returnContent) throws ServletException, IOException {
SecurityContext securityContext = null;
Authenticator authenticator = null;
Result result = null;
Resource resource = null;
try {
// 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);
// set default value for property view
propertyView.set(securityContext, config.getDefaultPropertyView());
// evaluate constraints and measure query time
double queryTimeStart = System.nanoTime();
// 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();
}
// add sorting & paging
String pageSizeParameter = request.getParameter(REQUEST_PARAMETER_PAGE_SIZE);
String pageParameter = request.getParameter(REQUEST_PARAMETER_PAGE_NUMBER);
String sortOrder = request.getParameter(REQUEST_PARAMETER_SORT_ORDER);
String sortKeyName = request.getParameter(REQUEST_PARAMETER_SORT_KEY);
String outputDepth = request.getParameter(REQUEST_PARAMTER_OUTPUT_DEPTH);
boolean sortDescending = (sortOrder != null && "desc".equals(sortOrder.toLowerCase()));
int pageSize = Services.parseInt(pageSizeParameter, NodeFactory.DEFAULT_PAGE_SIZE);
int page = Services.parseInt(pageParameter, NodeFactory.DEFAULT_PAGE);
int depth = Services.parseInt(outputDepth, config.getOutputNestingDepth());
String baseUrl = request.getRequestURI();
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);
}
// isolate doGet
boolean retry = true;
while (retry) {
try (final Tx tx = app.tx()) {
result = resource.doGet(sortKey, sortDescending, pageSize, page);
tx.success();
retry = false;
} catch (RetryException ddex) {
retry = true;
}
}
if (result == null) {
throw new FrameworkException(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "Unable to retrieve result, check database connection");
}
if (returnContent) {
if (!(resource instanceof StaticRelationshipResource) && !result.isPrimitiveArray() && !result.isEmpty()) {
result.setIsCollection(resource.isCollectionResource());
result.setIsPrimitiveArray(resource.isPrimitiveArray());
}
PagingHelper.addPagingParameter(result, pageSize, page);
// timing..
double queryTimeEnd = System.nanoTime();
// store property view that will be used to render the results
result.setPropertyView(propertyView.get(securityContext));
// allow resource to modify result set
resource.postProcessResultSet(result);
DecimalFormat decimalFormat = new DecimalFormat("0.000000000", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
result.setQueryTime(decimalFormat.format((queryTimeEnd - queryTimeStart) / 1000000000.0));
if (outputDepth != null) {
result.setOutputNestingDepth(depth);
}
String accept = request.getHeader("Accept");
if (accept != null && accept.contains("text/html")) {
final StreamingHtmlWriter htmlStreamer = new StreamingHtmlWriter(this.propertyView, indentJson, depth);
// isolate write output
try (final Tx tx = app.tx()) {
// no trailing semicolon so we dont trip MimeTypes.getContentTypeWithoutCharset
response.setContentType("text/html; charset=utf-8");
final Writer writer = response.getWriter();
htmlStreamer.stream(securityContext, writer, result, baseUrl);
// useful newline
writer.append("\n");
tx.success();
}
} else {
final StreamingJsonWriter jsonStreamer = new StreamingJsonWriter(this.propertyView, indentJson, depth);
// isolate write output
try (final Tx tx = app.tx()) {
// no trailing semicolon so we dont trip MimeTypes.getContentTypeWithoutCharset
response.setContentType("application/json; charset=utf-8");
final Writer writer = response.getWriter();
jsonStreamer.stream(securityContext, writer, result, baseUrl);
// useful newline
writer.append("\n");
tx.success();
}
}
}
response.setStatus(HttpServletResponse.SC_OK);
} 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 GET", jsex);
int code = HttpServletResponse.SC_BAD_REQUEST;
response.setStatus(code);
response.getWriter().append(RestMethodResult.jsonError(code, "Json syntax exception in GET: " + jsex.getMessage()));
} catch (JsonParseException jpex) {
logger.warn("JsonParseException in GET", jpex);
int code = HttpServletResponse.SC_BAD_REQUEST;
response.setStatus(code);
response.getWriter().append(RestMethodResult.jsonError(code, "Parser exception in GET: " + jpex.getMessage()));
} catch (Throwable t) {
logger.warn("Exception in GET (URI: {})", securityContext != null ? securityContext.getCompoundRequestURI() : "(null SecurityContext)");
logger.warn(" => Error thrown: ", t);
int code = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
response.setStatus(code);
response.getWriter().append(RestMethodResult.jsonError(code, "Exception in GET: " + 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 ResourceHelper method parsePath.
// ~--- methods --------------------------------------------------------
/**
* Parse the request path and match with possible resource patterns
*
* @param securityContext
* @param request
* @param resourceMap
* @param propertyView
* @return resourceChain
* @throws FrameworkException
*/
public static List<Resource> parsePath(final SecurityContext securityContext, final HttpServletRequest request, final Map<Pattern, Class<? extends Resource>> resourceMap, final Value<String> propertyView) throws FrameworkException {
final String path = request.getPathInfo();
// intercept empty path and send 204 No Content
if (StringUtils.isBlank(path)) {
throw new NoResultsException("No content");
}
// 1.: split request path into URI parts
final String[] pathParts = path.split("[/]+");
// 2.: create container for resource constraints
final Set<String> propertyViews = Services.getInstance().getConfigurationProvider().getPropertyViews();
final List<Resource> resourceChain = new ArrayList<>(pathParts.length);
// 3.: try to assign resource constraints for each URI part
for (int i = 0; i < pathParts.length; i++) {
// eliminate empty strings
final String part = pathParts[i].trim();
if (part.length() > 0) {
boolean found = false;
// check views first
if (propertyViews.contains(part)) {
Resource resource = new ViewFilterResource();
resource.checkAndConfigure(part, securityContext, request);
resource.configurePropertyView(propertyView);
resourceChain.add(resource);
// mark this part as successfully parsed
found = true;
} else {
// look for matching pattern
for (Map.Entry<Pattern, Class<? extends Resource>> entry : resourceMap.entrySet()) {
Pattern pattern = entry.getKey();
Matcher matcher = pattern.matcher(pathParts[i]);
if (matcher.matches()) {
Class<? extends Resource> type = entry.getValue();
Resource resource = null;
try {
// instantiate resource constraint
resource = type.newInstance();
} catch (Throwable t) {
logger.warn("Error instantiating resource class", t);
}
if (resource != null) {
// set security context
resource.setSecurityContext(securityContext);
if (resource.checkAndConfigure(part, securityContext, request)) {
logger.debug("{} matched, adding resource of type {} for part {}", new Object[] { matcher.pattern(), type.getName(), part });
// allow constraint to modify context
resource.configurePropertyView(propertyView);
// add constraint and go on
resourceChain.add(resource);
found = true;
// first match wins, so choose priority wisely ;)
break;
}
}
}
}
}
if (!found) {
throw new NotFoundException("Cannot resolve URL path");
}
}
}
return resourceChain;
}
Aggregations