Search in sources :

Example 61 with PropertyKey

use of org.structr.core.property.PropertyKey in project structr by structr.

the class ValidationTest method testArrayPropertyNotNullValidation.

// ----- array property validation tests -----
@Test
public void testArrayPropertyNotNullValidation() {
    final String keyName = "stringArray";
    final Class testType = createTypeWithProperty("Test", keyName, "+String[]");
    final PropertyKey key = StructrApp.key(testType, keyName);
    if (key != null) {
        try (final Tx tx = app.tx()) {
            app.create(testType, new NodeAttribute<>(key, null));
            tx.success();
            fail("Array property validation failed!");
        } catch (FrameworkException fex) {
            final ErrorToken token = fex.getErrorBuffer().getErrorTokens().get(0);
            assertEquals("Invalid uniqueness validation result", 422, fex.getStatus());
            assertEquals("Invalid uniqueness validation result", keyName, token.getProperty());
            assertEquals("Invalid uniqueness validation result", "Test", token.getType());
            assertEquals("Invalid uniqueness validation result", "must_not_be_empty", token.getToken());
        }
    }
}
Also used : Tx(org.structr.core.graph.Tx) FrameworkException(org.structr.common.error.FrameworkException) ErrorToken(org.structr.common.error.ErrorToken) PropertyKey(org.structr.core.property.PropertyKey) StructrTest(org.structr.common.StructrTest) Test(org.junit.Test)

Example 62 with PropertyKey

use of org.structr.core.property.PropertyKey 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);
    }
}
Also used : App(org.structr.core.app.App) StructrApp(org.structr.core.app.StructrApp) Tx(org.structr.core.graph.Tx) FrameworkException(org.structr.common.error.FrameworkException) DecimalFormat(java.text.DecimalFormat) Resource(org.structr.rest.resource.Resource) JsonParseException(com.google.gson.JsonParseException) Result(org.structr.core.Result) RestMethodResult(org.structr.rest.RestMethodResult) JsonSyntaxException(com.google.gson.JsonSyntaxException) Authenticator(org.structr.core.auth.Authenticator) PropertyKey(org.structr.core.property.PropertyKey) Writer(java.io.Writer)

Example 63 with PropertyKey

use of org.structr.core.property.PropertyKey in project structr by structr.

the class CsvServlet method writeCsv.

/**
 * Write list of objects to output
 *
 * @param result
 * @param out
 * @param propertyView
 * @throws IOException
 */
public static void writeCsv(final Result result, final Writer out, final String propertyView) throws IOException {
    final List<GraphObject> list = result.getResults();
    final StringBuilder row = new StringBuilder();
    boolean headerWritten = false;
    for (final GraphObject obj : list) {
        // Write column headers
        if (!headerWritten) {
            row.setLength(0);
            for (PropertyKey key : obj.getPropertyKeys(propertyView)) {
                row.append("\"").append(key.dbName()).append("\"").append(DEFAULT_FIELD_SEPARATOR);
            }
            // remove last ;
            int pos = row.lastIndexOf("" + DEFAULT_FIELD_SEPARATOR);
            if (pos >= 0) {
                row.deleteCharAt(pos);
            }
            // append DOS-style line feed as defined in RFC 4180
            out.append(row).append("\r\n");
            // flush each line
            out.flush();
            headerWritten = true;
        }
        row.setLength(0);
        for (PropertyKey key : obj.getPropertyKeys(propertyView)) {
            Object value = obj.getProperty(key);
            row.append("\"").append((value != null ? escapeForCsv(value) : "")).append("\"").append(DEFAULT_FIELD_SEPARATOR);
        }
        // remove last ;
        row.deleteCharAt(row.lastIndexOf("" + DEFAULT_FIELD_SEPARATOR));
        out.append(row).append("\r\n");
        // flush each line
        out.flush();
    }
}
Also used : GraphObject(org.structr.core.GraphObject) GraphObject(org.structr.core.GraphObject) PropertyKey(org.structr.core.property.PropertyKey)

Example 64 with PropertyKey

use of org.structr.core.property.PropertyKey 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());
        }
    }
}
Also used : App(org.structr.core.app.App) StructrApp(org.structr.core.app.StructrApp) Tx(org.structr.core.graph.Tx) FrameworkException(org.structr.common.error.FrameworkException) DecimalFormat(java.text.DecimalFormat) Resource(org.structr.rest.resource.Resource) StaticRelationshipResource(org.structr.rest.resource.StaticRelationshipResource) StaticRelationshipResource(org.structr.rest.resource.StaticRelationshipResource) StreamingHtmlWriter(org.structr.rest.serialization.StreamingHtmlWriter) RetryException(org.structr.api.RetryException) JsonParseException(com.google.gson.JsonParseException) Result(org.structr.core.Result) RestMethodResult(org.structr.rest.RestMethodResult) JsonSyntaxException(com.google.gson.JsonSyntaxException) StreamingJsonWriter(org.structr.rest.serialization.StreamingJsonWriter) SecurityContext(org.structr.common.SecurityContext) Authenticator(org.structr.core.auth.Authenticator) PropertyKey(org.structr.core.property.PropertyKey) Writer(java.io.Writer) StreamingHtmlWriter(org.structr.rest.serialization.StreamingHtmlWriter) StreamingJsonWriter(org.structr.rest.serialization.StreamingJsonWriter)

Example 65 with PropertyKey

use of org.structr.core.property.PropertyKey in project structr by structr.

the class StreamingWriter method stream.

public void stream(final SecurityContext securityContext, final Writer output, final Result result, final String baseUrl) throws IOException {
    long t0 = System.nanoTime();
    RestWriter writer = getRestWriter(securityContext, output);
    if (indent) {
        writer.setIndent("	");
    }
    // result fields in alphabetical order
    List<? extends GraphObject> results = result.getResults();
    Integer outputNestingDepth = result.getOutputNestingDepth();
    Integer page = result.getPage();
    Integer pageCount = result.getPageCount();
    Integer pageSize = result.getPageSize();
    String queryTime = result.getQueryTime();
    Integer resultCount = result.getRawResultCount();
    String searchString = result.getSearchString();
    String sortKey = result.getSortKey();
    String sortOrder = result.getSortOrder();
    GraphObject metaData = result.getMetaData();
    writer.beginDocument(baseUrl, propertyView.get(securityContext));
    // open result set
    writer.beginObject();
    if (outputNestingDepth != null) {
        writer.name("output_nesting_depth").value(outputNestingDepth);
    }
    if (page != null) {
        writer.name("page").value(page);
    }
    if (pageCount != null) {
        writer.name("page_count").value(pageCount);
    }
    if (pageSize != null) {
        writer.name("page_size").value(pageSize);
    }
    if (queryTime != null) {
        writer.name("query_time").value(queryTime);
    }
    if (resultCount != null && renderResultCount) {
        writer.name("result_count").value(resultCount);
    }
    if (results != null) {
        if (results.isEmpty() && result.isPrimitiveArray()) {
            writer.name(resultKeyName).nullValue();
        } else if (results.isEmpty() && !result.isPrimitiveArray()) {
            writer.name(resultKeyName).beginArray().endArray();
        } else if (result.isPrimitiveArray()) {
            writer.name(resultKeyName);
            if (results.size() > 1) {
                writer.beginArray();
            }
            for (final Object object : results) {
                if (object != null) {
                    if (object instanceof GraphObject) {
                        // keep track of serialization time
                        final long startTime = System.currentTimeMillis();
                        final String localPropertyView = propertyView.get(null);
                        final GraphObject obj = (GraphObject) object;
                        final Iterator<PropertyKey> keyIt = obj.getPropertyKeys(localPropertyView).iterator();
                        while (keyIt.hasNext()) {
                            PropertyKey k = keyIt.next();
                            Object value = obj.getProperty(k);
                            root.serializeProperty(writer, k, value, localPropertyView, 0);
                        }
                        // check for timeout
                        if (System.currentTimeMillis() > startTime + MAX_SERIALIZATION_TIME) {
                            logger.error("JSON serialization of {} with {} results took more than {} ms, aborted. Please review output view size or adjust timeout.", new Object[] { securityContext.getCompoundRequestURI(), results.size(), MAX_SERIALIZATION_TIME });
                            // TODO: create some output indicating that streaming was interrupted
                            break;
                        }
                    } else {
                        writer.value(object.toString());
                    }
                }
            }
            if (results.size() > 1) {
                writer.endArray();
            }
        } else {
            // result is an attribute called via REST API
            if (results.size() > 1 && !result.isCollection()) {
                throw new IllegalStateException(result.getClass().getSimpleName() + " is not a collection resource, but result set has size " + results.size());
            }
            // keep track of serialization time
            long startTime = System.currentTimeMillis();
            String localPropertyView = propertyView.get(null);
            if (result.isCollection()) {
                writer.name(resultKeyName).beginArray();
                // serialize list of results
                for (GraphObject graphObject : results) {
                    root.serialize(writer, graphObject, localPropertyView, 0);
                    // check for timeout
                    if (System.currentTimeMillis() > startTime + MAX_SERIALIZATION_TIME) {
                        logger.error("JSON serialization of {} with {} results took more than {} ms, aborted. Please review output view size or adjust timeout.", new Object[] { securityContext.getRequest().getRequestURI().concat((securityContext.getRequest().getQueryString() == null) ? "" : "?".concat(securityContext.getRequest().getQueryString())), results.size(), MAX_SERIALIZATION_TIME });
                        // TODO: create some output indicating that streaming was interrupted
                        break;
                    }
                }
                writer.endArray();
            } else {
                writer.name(resultKeyName);
                root.serialize(writer, results.get(0), localPropertyView, 0);
            }
        }
    }
    if (searchString != null) {
        writer.name("search_string").value(searchString);
    }
    if (sortKey != null) {
        writer.name("sort_key").value(sortKey);
    }
    if (sortOrder != null) {
        writer.name("sort_order").value(sortOrder);
    }
    if (metaData != null) {
        String localPropertyView = propertyView.get(null);
        writer.name("meta_data");
        root.serialize(writer, metaData, localPropertyView, 0);
    }
    if (renderSerializationTime) {
        writer.name("serialization_time").value(decimalFormat.format((System.nanoTime() - t0) / 1000000000.0));
    }
    // finished
    writer.endObject();
    writer.endDocument();
}
Also used : GraphObject(org.structr.core.GraphObject) GraphObject(org.structr.core.GraphObject) PropertyKey(org.structr.core.property.PropertyKey)

Aggregations

PropertyKey (org.structr.core.property.PropertyKey)177 FrameworkException (org.structr.common.error.FrameworkException)108 Test (org.junit.Test)69 NodeInterface (org.structr.core.graph.NodeInterface)62 Tx (org.structr.core.graph.Tx)61 GraphObject (org.structr.core.GraphObject)59 StructrTest (org.structr.common.StructrTest)39 PropertyMap (org.structr.core.property.PropertyMap)37 List (java.util.List)31 Result (org.structr.core.Result)28 ConfigurationProvider (org.structr.schema.ConfigurationProvider)27 SecurityContext (org.structr.common.SecurityContext)26 LinkedList (java.util.LinkedList)22 StringProperty (org.structr.core.property.StringProperty)22 ErrorToken (org.structr.common.error.ErrorToken)20 Map (java.util.Map)18 PropertyConverter (org.structr.core.converter.PropertyConverter)18 NodeAttribute (org.structr.core.graph.NodeAttribute)17 App (org.structr.core.app.App)16 StructrApp (org.structr.core.app.StructrApp)16