blob: eb6d8b66bb2fd9bd377a34baa1795f4b6b097ae0 [file] [log] [blame]
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.odata2.core.debug;
import java.io.IOException;
import java.io.Writer;
import org.apache.olingo.odata2.api.edm.EdmException;
import org.apache.olingo.odata2.api.edm.EdmProperty;
import org.apache.olingo.odata2.api.exception.ODataApplicationException;
import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
import org.apache.olingo.odata2.api.uri.UriInfo;
import org.apache.olingo.odata2.api.uri.expression.BinaryExpression;
import org.apache.olingo.odata2.api.uri.expression.CommonExpression;
import org.apache.olingo.odata2.api.uri.expression.ExceptionVisitExpression;
import org.apache.olingo.odata2.api.uri.expression.ExpressionKind;
import org.apache.olingo.odata2.api.uri.expression.ExpressionParserException;
import org.apache.olingo.odata2.api.uri.expression.FilterExpression;
import org.apache.olingo.odata2.api.uri.expression.MemberExpression;
import org.apache.olingo.odata2.api.uri.expression.MethodExpression;
import org.apache.olingo.odata2.api.uri.expression.OrderByExpression;
import org.apache.olingo.odata2.api.uri.expression.OrderExpression;
import org.apache.olingo.odata2.api.uri.expression.UnaryExpression;
import org.apache.olingo.odata2.core.ep.util.JsonStreamWriter;
import org.apache.olingo.odata2.core.uri.ExpandSelectTreeCreator;
import org.apache.olingo.odata2.core.uri.ExpandSelectTreeNodeImpl;
import org.apache.olingo.odata2.core.uri.expression.JsonVisitor;
/**
* URI parser debug information.
*/
public class DebugInfoUri implements DebugInfo {
private final UriInfo uriInfo;
private final FilterExpression filter;
private final OrderByExpression orderBy;
private final ExpandSelectTreeNodeImpl expandSelectTree;
private final ExpressionParserException exception;
public DebugInfoUri(final UriInfo uriInfo, final ExpressionParserException exception) {
this.uriInfo = uriInfo;
filter = uriInfo == null ? null : uriInfo.getFilter();
orderBy = uriInfo == null ? null : uriInfo.getOrderBy();
expandSelectTree = uriInfo == null ? null : getExpandSelect();
this.exception = exception;
}
private ExpandSelectTreeNodeImpl getExpandSelect() {
try {
return uriInfo.getExpand().isEmpty() && uriInfo.getSelect().isEmpty() ? null :
new ExpandSelectTreeCreator(uriInfo.getSelect(), uriInfo.getExpand()).create();
} catch (final EdmException e) {
return null;
}
}
@Override
public String getName() {
return "URI";
}
@Override
public void appendJson(final JsonStreamWriter jsonStreamWriter) throws IOException {
jsonStreamWriter.beginObject();
if (exception != null && exception.getFilterTree() != null) {
jsonStreamWriter.name("error")
.beginObject()
.namedStringValue("expression", exception.getFilterTree().getUriLiteral())
.endObject();
if (filter != null || orderBy != null || expandSelectTree != null) {
jsonStreamWriter.separator();
}
}
if (filter != null) {
String filterString;
try {
filterString = (String) filter.accept(new JsonVisitor());
} catch (final ExceptionVisitExpression e) {
filterString = null;
} catch (final ODataApplicationException e) {
filterString = null;
}
jsonStreamWriter.name("filter").unquotedValue(filterString);
if (orderBy != null || expandSelectTree != null) {
jsonStreamWriter.separator();
}
}
if (orderBy != null) {
String orderByString;
try {
orderByString = (String) orderBy.accept(new JsonVisitor());
} catch (final ExceptionVisitExpression e) {
orderByString = null;
} catch (final ODataApplicationException e) {
orderByString = null;
}
jsonStreamWriter.name("orderby").unquotedValue(orderByString);
if (expandSelectTree != null) {
jsonStreamWriter.separator();
}
}
if (expandSelectTree != null) {
jsonStreamWriter.name("expandSelect").unquotedValue(expandSelectTree.toJsonString());
}
jsonStreamWriter.endObject();
}
@Override
public void appendHtml(final Writer writer) throws IOException {
if (exception != null && exception.getFilterTree() != null) {
writer.append("<h2>Expression Information</h2>\n")
.append("<pre class=\"code\">").append(exception.getFilterTree().getUriLiteral())
.append("</pre>\n");
// TODO: filter error position, filter tokens, filter tree
}
if (filter != null) {
writer.append("<h2>Filter</h2>\n")
.append("<ul class=\"expr\"><li>");
appendExpression(filter.getExpression(), writer);
writer.append("</li></ul>\n");
}
if (orderBy != null) {
writer.append("<h2>Orderby</h2>\n")
.append(orderBy.getOrdersCount() == 1 ? "<ul" : "<ol").append(" class=\"expr\">\n");
for (final OrderExpression order : orderBy.getOrders()) {
writer.append("<li>");
appendExpression(order.getExpression(), writer);
final ExpressionKind kind = order.getExpression().getKind();
if (kind == ExpressionKind.PROPERTY || kind == ExpressionKind.LITERAL) {
writer.append("<br />");
}
writer.append("<span class=\"order\">")
.append(order.getSortOrder().toString())
.append("</span></li>\n");
}
writer.append(orderBy.getOrdersCount() == 1 ? "</ul" : "</ol").append(">\n");
}
if (expandSelectTree != null) {
writer.append("<h2>Expand/Select</h2>\n");
appendExpandSelect(expandSelectTree, writer);
}
}
private void appendExpression(final CommonExpression expression, final Writer writer) throws IOException {
final ExpressionKind kind = expression.getKind();
writer.append("<span class=\"kind\">")
.append(kind.toString())
.append("</span> <span class=\"literal\">")
.append(kind == ExpressionKind.MEMBER ? ((MemberExpression) expression).getProperty().getUriLiteral() :
expression.getUriLiteral())
.append("</span>, type <span class=\"type\">")
.append(expression.getEdmType().toString())
.append("</span>");
if (kind == ExpressionKind.UNARY) {
writer.append("<ul class=\"expr\"><li>");
appendExpression(((UnaryExpression) expression).getOperand(), writer);
writer.append("</li></ul>");
} else if (kind == ExpressionKind.BINARY) {
writer.append("<ol class=\"expr\"><li>");
appendExpression(((BinaryExpression) expression).getLeftOperand(), writer);
writer.append("</li><li>");
appendExpression(((BinaryExpression) expression).getRightOperand(), writer);
writer.append("</li></ol>");
} else if (kind == ExpressionKind.METHOD) {
final MethodExpression methodExpression = (MethodExpression) expression;
if (methodExpression.getParameterCount() > 0) {
writer.append("<ol class=\"expr\">");
for (final CommonExpression parameter : methodExpression.getParameters()) {
writer.append("<li>");
appendExpression(parameter, writer);
writer.append("</li>");
}
writer.append("</ol>");
}
} else if (kind == ExpressionKind.MEMBER) {
writer.append("<ul class=\"expr\"><li>");
appendExpression(((MemberExpression) expression).getPath(), writer);
writer.append("</li></ul>");
}
}
private void appendExpandSelect(final ExpandSelectTreeNode expandSelect, final Writer writer) throws IOException {
writer.append("<ul class=\"expand\">\n")
.append("<li>");
if (expandSelect.isAll()) {
writer.append("all properties");
} else {
for (final EdmProperty property : expandSelect.getProperties()) {
try {
writer.append("property <span class=\"prop\">")
.append(property.getName())
.append("</span><br />");
} catch (final EdmException e) {}
}
}
writer.append("</li>\n");
if (!expandSelect.getLinks().isEmpty()) {
for (final String name : expandSelect.getLinks().keySet()) {
writer.append("<li>link <span class=\"link\">").append(name).append("</span>");
final ExpandSelectTreeNode link = expandSelect.getLinks().get(name);
if (link != null) {
writer.append('\n');
appendExpandSelect(link, writer);
}
writer.append("</li>\n");
}
}
writer.append("</ul>\n");
}
}