[Olingo-731] add json uri tab support
This commit is contained in:
parent
f2c7be2d12
commit
36ae03957c
|
@ -85,7 +85,7 @@ public interface ExpressionVisitor<T> {
|
|||
* @throws ExpressionVisitException Thrown if an exception while traversing occured
|
||||
* @throws ODataApplicationException Thrown by the application
|
||||
*/
|
||||
T visitLiteral(String literal) throws ExpressionVisitException, ODataApplicationException;
|
||||
T visitLiteral(Literal literal) throws ExpressionVisitException, ODataApplicationException;
|
||||
|
||||
/**
|
||||
* Called for each traversed {@link Member} expression
|
||||
|
|
|
@ -113,12 +113,10 @@ public class DebugResponseHelperImpl implements DebugResponseHelper {
|
|||
parts.add(new DebugTabServer(serverEnvironmentVaribles));
|
||||
}
|
||||
|
||||
// TODO:Enable URIDebugInfo
|
||||
// URI
|
||||
// if (uriInfo != null && (uriInfo.getFilterOption() != null || uriInfo.getOrderByOption() != null
|
||||
// || uriInfo.getExpandOption() != null || uriInfo.getSelectOption() != null)) {
|
||||
// parts.add(new DebugInfoUri(uriInfo));
|
||||
// }
|
||||
if (debugInfo.getUriInfo() != null ) {
|
||||
parts.add(new DebugTabUri(debugInfo.getUriInfo()));
|
||||
}
|
||||
|
||||
// runtime measurements
|
||||
List<RuntimeMeasurement> runtimeInformation = debugInfo.getRuntimeInformation();
|
||||
|
|
|
@ -20,21 +20,31 @@ package org.apache.olingo.server.core.debug;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.api.uri.UriResource;
|
||||
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.OrderByItem;
|
||||
import org.apache.olingo.server.api.uri.queryoption.SelectItem;
|
||||
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
|
||||
|
||||
/**
|
||||
* URI parser debug information.
|
||||
*/
|
||||
public class DebugTabUri implements DebugTab {
|
||||
|
||||
private UriInfo uriInfo;
|
||||
private final UriInfo uriInfo;
|
||||
private final SelectOption selectOption;
|
||||
private final ExpandOption expandOption;
|
||||
|
||||
public DebugTabUri(UriInfo uriInfo) {
|
||||
this.uriInfo = uriInfo;
|
||||
this.selectOption = uriInfo == null ? null : uriInfo.getSelectOption();
|
||||
this.expandOption = uriInfo == null ? null : uriInfo.getExpandOption();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -43,9 +53,87 @@ public class DebugTabUri implements DebugTab {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void appendJson(JsonGenerator jsonGenerator) throws IOException {
|
||||
// TODO Auto-generated method stub
|
||||
public void appendJson(JsonGenerator gen) throws IOException {
|
||||
if (uriInfo == null) {
|
||||
gen.writeNull();
|
||||
return;
|
||||
}
|
||||
|
||||
gen.writeStartObject();
|
||||
|
||||
if (uriInfo.getFilterOption() != null) {
|
||||
gen.writeFieldName("filter");
|
||||
appendJsonExpressionString(gen, uriInfo.getFilterOption().getExpression());
|
||||
}
|
||||
|
||||
if (uriInfo.getOrderByOption() != null && uriInfo.getOrderByOption().getOrders() != null
|
||||
&& !uriInfo.getOrderByOption().getOrders().isEmpty()) {
|
||||
gen.writeFieldName("orderby");
|
||||
gen.writeStartObject();
|
||||
gen.writeStringField("nodeType", "orderCollection");
|
||||
gen.writeFieldName("orders");
|
||||
gen.writeStartArray();
|
||||
for(OrderByItem item : uriInfo.getOrderByOption().getOrders()){
|
||||
gen.writeStartObject();
|
||||
gen.writeStringField("nodeType", "order");
|
||||
gen.writeStringField("sortorder", item.isDescending() ? "desc" : "asc");
|
||||
gen.writeFieldName("expression");
|
||||
appendJsonExpressionString(gen, item.getExpression());
|
||||
gen.writeEndObject();
|
||||
}
|
||||
gen.writeEndArray();
|
||||
gen.writeEndObject();
|
||||
}
|
||||
|
||||
if (selectOption != null && !selectOption.getSelectItems().isEmpty()) {
|
||||
appendSelectedPropertiesJson(gen, selectOption.getSelectItems());
|
||||
}
|
||||
|
||||
gen.writeEndObject();
|
||||
}
|
||||
|
||||
private void appendJsonExpressionString(JsonGenerator gen, Expression expression) throws IOException {
|
||||
if(expression == null){
|
||||
gen.writeNull();
|
||||
return;
|
||||
}
|
||||
String expressionJsonString;
|
||||
try {
|
||||
expressionJsonString = expression.accept(new ExpressionJsonVisitor());
|
||||
} catch (Exception e) {
|
||||
expressionJsonString = "Exception in Debug Filter visitor occoured: " + e.getMessage();
|
||||
}
|
||||
|
||||
gen.writeRawValue(expressionJsonString);
|
||||
}
|
||||
|
||||
private void appendSelectedPropertiesJson(JsonGenerator gen, List<SelectItem> selectItems) throws IOException {
|
||||
gen.writeFieldName("select");
|
||||
|
||||
gen.writeStartArray();
|
||||
for (SelectItem selectItem : selectItems) {
|
||||
appendSelectItemJson(gen, selectItem);
|
||||
}
|
||||
gen.writeEndArray();
|
||||
}
|
||||
|
||||
private void appendSelectItemJson(JsonGenerator gen, SelectItem selectItem) throws IOException {
|
||||
String selectedProperty = "";
|
||||
if (selectItem.isStar()) {
|
||||
if (selectItem.getAllOperationsInSchemaNameSpace() == null) {
|
||||
selectedProperty = "*";
|
||||
} else {
|
||||
selectedProperty = selectItem.getAllOperationsInSchemaNameSpace().getFullQualifiedNameAsString() + ".*";
|
||||
}
|
||||
} else {
|
||||
boolean first = true;
|
||||
for (UriResource resourcePart : selectItem.getResourcePath().getUriResourceParts()) {
|
||||
if (!first) {
|
||||
selectedProperty = selectedProperty + "/";
|
||||
}
|
||||
selectedProperty = resourcePart.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,361 @@
|
|||
/*
|
||||
* 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.server.core.debug;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.EdmEnumType;
|
||||
import org.apache.olingo.commons.api.edm.EdmType;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.uri.UriInfoResource;
|
||||
import org.apache.olingo.server.api.uri.UriResource;
|
||||
import org.apache.olingo.server.api.uri.UriResourceLambdaAll;
|
||||
import org.apache.olingo.server.api.uri.UriResourceLambdaAny;
|
||||
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitor;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.Literal;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.MethodKind;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.UnaryOperatorKind;
|
||||
|
||||
/**
|
||||
* A custom expression visitor which writes down the tree from top to bottom
|
||||
*/
|
||||
public class ExpressionJsonVisitor implements ExpressionVisitor<String> {
|
||||
|
||||
@Override
|
||||
public String visitBinaryOperator(BinaryOperatorKind operator, String left, String right)
|
||||
throws ExpressionVisitException, ODataApplicationException {
|
||||
try {
|
||||
StringWriter writer = new StringWriter();
|
||||
JsonStreamWriter jsonStreamWriter = new JsonStreamWriter(writer);
|
||||
jsonStreamWriter.beginObject().namedStringValue("nodeType", "binary").separator().namedStringValue("operator",
|
||||
operator.toString()).separator().namedStringValueRaw("type", getType(operator)).separator().name("left")
|
||||
.unquotedValue(left).separator().name("right").unquotedValue(right).endObject();
|
||||
writer.flush();
|
||||
return writer.toString();
|
||||
} catch (final IOException e) {
|
||||
throw new ExpressionVisitException("IOException occoured", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitUnaryOperator(UnaryOperatorKind operator, String operand) throws ExpressionVisitException,
|
||||
ODataApplicationException {
|
||||
try {
|
||||
StringWriter writer = new StringWriter();
|
||||
JsonStreamWriter jsonStreamWriter = new JsonStreamWriter(writer);
|
||||
jsonStreamWriter.beginObject().namedStringValue("nodeType", "unary").separator()
|
||||
.namedStringValueRaw("operator", operator.toString()).separator().namedStringValueRaw("type",
|
||||
getType(operator)).separator().name("operand").unquotedValue(operand).endObject();
|
||||
writer.flush();
|
||||
return writer.toString();
|
||||
} catch (final IOException e) {
|
||||
throw new ExpressionVisitException("IOException occoured", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitMethodCall(MethodKind methodCall, List<String> parameters) throws ExpressionVisitException,
|
||||
ODataApplicationException {
|
||||
try {
|
||||
StringWriter writer = new StringWriter();
|
||||
JsonStreamWriter jsonStreamWriter = new JsonStreamWriter(writer);
|
||||
jsonStreamWriter.beginObject().namedStringValueRaw("nodeType", "method").separator()
|
||||
.namedStringValueRaw("operator", methodCall.toString()).separator().namedStringValueRaw("type",
|
||||
getType(methodCall)).separator().name("parameters").beginArray();
|
||||
boolean first = true;
|
||||
for (String parameter : parameters) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
jsonStreamWriter.separator();
|
||||
}
|
||||
jsonStreamWriter.unquotedValue(parameter);
|
||||
}
|
||||
jsonStreamWriter.endArray().endObject();
|
||||
writer.flush();
|
||||
return writer.toString();
|
||||
} catch (final IOException e) {
|
||||
throw new ExpressionVisitException("IOException occoured", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitLambdaExpression(String lambdaFunction, String lambdaVariable, Expression expression)
|
||||
throws ExpressionVisitException, ODataApplicationException {
|
||||
try {
|
||||
StringWriter writer = new StringWriter();
|
||||
JsonStreamWriter jsonStreamWriter = new JsonStreamWriter(writer);
|
||||
jsonStreamWriter.beginObject().namedStringValue("nodeType", "lambdaFunction").separator()
|
||||
.namedStringValue("lambdaVariable", lambdaVariable).separator().name("expression");
|
||||
|
||||
// Write expression string object
|
||||
String expressionJsonTree = expression.accept(this);
|
||||
jsonStreamWriter.unquotedValue(expressionJsonTree).endObject();
|
||||
writer.flush();
|
||||
return writer.toString();
|
||||
} catch (final IOException e) {
|
||||
throw new ExpressionVisitException("IOException occoured", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitLiteral(Literal literal) throws ExpressionVisitException, ODataApplicationException {
|
||||
try {
|
||||
StringWriter writer = new StringWriter();
|
||||
JsonStreamWriter jsonStreamWriter = new JsonStreamWriter(writer);
|
||||
jsonStreamWriter.beginObject().namedStringValueRaw("nodeType", "literal").separator().namedStringValueRaw("type",
|
||||
getTypeString(literal.getType())).separator().namedStringValue("value", literal.getText()).endObject();
|
||||
writer.flush();
|
||||
return writer.toString();
|
||||
} catch (final IOException e) {
|
||||
throw new ExpressionVisitException("IOException occoured");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitMember(UriInfoResource member) throws ExpressionVisitException, ODataApplicationException {
|
||||
try {
|
||||
StringWriter writer = new StringWriter();
|
||||
JsonStreamWriter jsonStreamWriter = new JsonStreamWriter(writer);
|
||||
List<UriResource> uriResourceParts = member.getUriResourceParts();
|
||||
jsonStreamWriter.beginObject().namedStringValue("nodeType", "member").separator()
|
||||
.namedStringValueRaw("type", getType(uriResourceParts)).separator();
|
||||
|
||||
// write all member properties in an array
|
||||
jsonStreamWriter.name("resourceSegments").beginArray();
|
||||
if (uriResourceParts != null) {
|
||||
boolean first = true;
|
||||
for (UriResource segment : uriResourceParts) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
jsonStreamWriter.separator();
|
||||
}
|
||||
appendUriResourcePartObject(jsonStreamWriter, segment);
|
||||
}
|
||||
}
|
||||
jsonStreamWriter.endArray();
|
||||
|
||||
jsonStreamWriter.endObject();
|
||||
writer.flush();
|
||||
return writer.toString();
|
||||
} catch (final IOException e) {
|
||||
throw new ExpressionVisitException("IOException occoured", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitAlias(String aliasName) throws ExpressionVisitException, ODataApplicationException {
|
||||
try {
|
||||
StringWriter writer = new StringWriter();
|
||||
JsonStreamWriter jsonStreamWriter = new JsonStreamWriter(writer);
|
||||
jsonStreamWriter.beginObject().namedStringValueRaw("nodeType", "alias").separator()
|
||||
.namedStringValue("alias", aliasName).endObject();
|
||||
writer.flush();
|
||||
return writer.toString();
|
||||
} catch (final IOException e) {
|
||||
throw new ExpressionVisitException("IOException occoured", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitTypeLiteral(EdmType type) throws ExpressionVisitException, ODataApplicationException {
|
||||
try {
|
||||
StringWriter writer = new StringWriter();
|
||||
JsonStreamWriter jsonStreamWriter = new JsonStreamWriter(writer);
|
||||
jsonStreamWriter.beginObject().namedStringValueRaw("nodeType", "type").separator()
|
||||
.namedStringValueRaw("type", getTypeString(type)).endObject();
|
||||
writer.flush();
|
||||
return writer.toString();
|
||||
} catch (final IOException e) {
|
||||
throw new ExpressionVisitException("IOException occoured", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitLambdaReference(String variableName) throws ExpressionVisitException, ODataApplicationException {
|
||||
try {
|
||||
StringWriter writer = new StringWriter();
|
||||
JsonStreamWriter jsonStreamWriter = new JsonStreamWriter(writer);
|
||||
jsonStreamWriter.beginObject().namedStringValueRaw("nodeType", "lambdaReference").separator()
|
||||
.namedStringValueRaw("name", variableName).endObject();
|
||||
writer.flush();
|
||||
return writer.toString();
|
||||
} catch (final IOException e) {
|
||||
throw new ExpressionVisitException("IOException occoured", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitEnum(EdmEnumType type, List<String> enumValues) throws ExpressionVisitException,
|
||||
ODataApplicationException {
|
||||
try {
|
||||
StringWriter writer = new StringWriter();
|
||||
JsonStreamWriter jsonStreamWriter = new JsonStreamWriter(writer);
|
||||
jsonStreamWriter.beginObject().namedStringValueRaw("nodeType", "enum").separator()
|
||||
.namedStringValueRaw("type", getTypeString(type)).separator();
|
||||
jsonStreamWriter.name("values").beginArray();
|
||||
if (enumValues != null) {
|
||||
boolean first = true;
|
||||
for (String value : enumValues) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
jsonStreamWriter.separator();
|
||||
}
|
||||
jsonStreamWriter.stringValue(value);
|
||||
}
|
||||
}
|
||||
jsonStreamWriter.endArray();
|
||||
|
||||
jsonStreamWriter.endObject();
|
||||
writer.flush();
|
||||
return writer.toString();
|
||||
} catch (final IOException e) {
|
||||
throw new ExpressionVisitException("IOException occoured", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String getType(UnaryOperatorKind operator) {
|
||||
switch (operator) {
|
||||
case MINUS:
|
||||
return "Number";
|
||||
case NOT:
|
||||
return "Boolean";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
private String getType(MethodKind methodCall) {
|
||||
switch (methodCall) {
|
||||
case STARTSWITH:
|
||||
case CONTAINS:
|
||||
case ENDSWITH:
|
||||
case ISOF:
|
||||
return "Boolean";
|
||||
case INDEXOF:
|
||||
case LENGTH:
|
||||
case ROUND:
|
||||
case FLOOR:
|
||||
case CEILING:
|
||||
case DAY:
|
||||
case HOUR:
|
||||
case MINUTE:
|
||||
case MONTH:
|
||||
case SECOND:
|
||||
case FRACTIONALSECONDS:
|
||||
return "Number";
|
||||
case CAST:
|
||||
case CONCAT:
|
||||
case DATE:
|
||||
case GEODISTANCE:
|
||||
case GEOINTERSECTS:
|
||||
case GEOLENGTH:
|
||||
case MAXDATETIME:
|
||||
case MINDATETIME:
|
||||
case NOW:
|
||||
case SUBSTRING:
|
||||
case TIME:
|
||||
case TOLOWER:
|
||||
case TOTALOFFSETMINUTES:
|
||||
case TOTALSECONDS:
|
||||
case TOUPPER:
|
||||
case TRIM:
|
||||
case YEAR:
|
||||
return "String";
|
||||
default:
|
||||
return "unkown";
|
||||
}
|
||||
}
|
||||
|
||||
private void appendUriResourcePartObject(JsonStreamWriter jsonStreamWriter, UriResource segment) throws IOException,
|
||||
ExpressionVisitException, ODataApplicationException {
|
||||
if (segment instanceof UriResourceLambdaAll) {
|
||||
UriResourceLambdaAll all = (UriResourceLambdaAll) segment;
|
||||
String lambdaJsonObjectString = visitLambdaExpression("ALL", all.getLambdaVariable(), all.getExpression());
|
||||
jsonStreamWriter.unquotedValue(lambdaJsonObjectString);
|
||||
return;
|
||||
} else if (segment instanceof UriResourceLambdaAny) {
|
||||
UriResourceLambdaAny any = (UriResourceLambdaAny) segment;
|
||||
String lambdaJsonObjectString = visitLambdaExpression("ANY", any.getLambdaVariable(), any.getExpression());
|
||||
jsonStreamWriter.unquotedValue(lambdaJsonObjectString);
|
||||
return;
|
||||
} else if (segment instanceof UriResourcePartTyped) {
|
||||
String typeName =
|
||||
((UriResourcePartTyped) segment).getType().getFullQualifiedName().getFullQualifiedNameAsString();
|
||||
jsonStreamWriter.beginObject().namedStringValue("nodeType", segment.getKind().toString()).separator()
|
||||
.namedStringValue("name", segment.toString()).separator().namedStringValueRaw("type", typeName).endObject();
|
||||
} else {
|
||||
jsonStreamWriter.beginObject().namedStringValue("nodeType", segment.getKind().toString()).separator()
|
||||
.namedStringValue("name", segment.toString()).separator().namedStringValueRaw("type", null).endObject();
|
||||
}
|
||||
}
|
||||
|
||||
private String getType(BinaryOperatorKind operator) {
|
||||
switch (operator) {
|
||||
case MUL:
|
||||
case DIV:
|
||||
case MOD:
|
||||
case ADD:
|
||||
case SUB:
|
||||
return "Number";
|
||||
|
||||
case HAS:
|
||||
case GT:
|
||||
case GE:
|
||||
case LT:
|
||||
case LE:
|
||||
case EQ:
|
||||
case NE:
|
||||
case AND:
|
||||
case OR:
|
||||
return "Boolean";
|
||||
|
||||
default:
|
||||
return "unkown";
|
||||
}
|
||||
}
|
||||
|
||||
private String getTypeString(EdmType type) {
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
return type.getFullQualifiedName().getFullQualifiedNameAsString();
|
||||
}
|
||||
|
||||
private String getType(List<UriResource> uriResourceParts) {
|
||||
if (uriResourceParts == null || uriResourceParts.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
UriResource lastSegment = uriResourceParts.get(uriResourceParts.size() - 1);
|
||||
EdmType type = null;
|
||||
if (lastSegment instanceof UriResourcePartTyped) {
|
||||
type = ((UriResourcePartTyped) lastSegment).getType();
|
||||
}
|
||||
return type == null ? "unknown" : type.getFullQualifiedName().getFullQualifiedNameAsString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* 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.server.core.debug;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* Writes JSON output.
|
||||
*
|
||||
*/
|
||||
class JsonStreamWriter {
|
||||
private final Writer writer;
|
||||
|
||||
public JsonStreamWriter(final Writer writer) {
|
||||
this.writer = writer;
|
||||
}
|
||||
|
||||
public JsonStreamWriter beginObject() throws IOException {
|
||||
writer.append('{');
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonStreamWriter endObject() throws IOException {
|
||||
writer.append('}');
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonStreamWriter beginArray() throws IOException {
|
||||
writer.append('[');
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonStreamWriter endArray() throws IOException {
|
||||
writer.append(']');
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonStreamWriter name(final String name) throws IOException {
|
||||
writer.append('"').append(name).append('"').append(':');
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonStreamWriter unquotedValue(final String value) throws IOException {
|
||||
writer.append(value == null ? "null" : value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonStreamWriter stringValueRaw(final String value) throws IOException {
|
||||
if (value == null) {
|
||||
writer.append("null");
|
||||
} else {
|
||||
writer.append('"').append(value).append('"');
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonStreamWriter stringValue(final String value) throws IOException {
|
||||
if (value == null) {
|
||||
writer.append("null");
|
||||
} else {
|
||||
writer.append('"');
|
||||
escape(value);
|
||||
writer.append('"');
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonStreamWriter namedStringValueRaw(final String name, final String value) throws IOException {
|
||||
name(name);
|
||||
stringValueRaw(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonStreamWriter namedStringValue(final String name, final String value) throws IOException {
|
||||
name(name);
|
||||
stringValue(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonStreamWriter separator() throws IOException {
|
||||
writer.append(',');
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the JSON-escaped form of a Java String value according to RFC 4627.
|
||||
* @param value the Java String
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
protected void escape(final String value) throws IOException {
|
||||
// RFC 4627 says: "All Unicode characters may be placed within the
|
||||
// quotation marks except for the characters that must be escaped:
|
||||
// quotation mark, reverse solidus, and the control characters
|
||||
// (U+0000 through U+001F)."
|
||||
// All output here is done on character basis which should be faster
|
||||
// than writing Strings.
|
||||
for (int i = 0; i < value.length(); i++) {
|
||||
final char c = value.charAt(i);
|
||||
switch (c) {
|
||||
case '\\':
|
||||
writer.append('\\').append(c);
|
||||
break;
|
||||
case '"':
|
||||
writer.append('\\').append(c);
|
||||
break;
|
||||
case '\b':
|
||||
writer.append('\\').append('b');
|
||||
break;
|
||||
case '\t':
|
||||
writer.append('\\').append('t');
|
||||
break;
|
||||
case '\n':
|
||||
writer.append('\\').append('n');
|
||||
break;
|
||||
case '\f':
|
||||
writer.append('\\').append('f');
|
||||
break;
|
||||
case '\r':
|
||||
writer.append('\\').append('r');
|
||||
break;
|
||||
case '\u0000':
|
||||
case '\u0001':
|
||||
case '\u0002':
|
||||
case '\u0003':
|
||||
case '\u0004':
|
||||
case '\u0005':
|
||||
case '\u0006':
|
||||
case '\u0007':
|
||||
case '\u000B':
|
||||
case '\u000E':
|
||||
case '\u000F':
|
||||
case '\u0010':
|
||||
case '\u0011':
|
||||
case '\u0012':
|
||||
case '\u0013':
|
||||
case '\u0014':
|
||||
case '\u0015':
|
||||
case '\u0016':
|
||||
case '\u0017':
|
||||
case '\u0018':
|
||||
case '\u0019':
|
||||
case '\u001A':
|
||||
case '\u001B':
|
||||
case '\u001C':
|
||||
case '\u001D':
|
||||
case '\u001E':
|
||||
case '\u001F':
|
||||
final int lastHexDigit = c % 0x10;
|
||||
writer.append('\\').append('u').append('0').append('0')
|
||||
.append(c >= '\u0010' ? '1' : '0')
|
||||
.append((char) ((lastHexDigit > 9 ? 'A' : '0') + lastHexDigit % 10));
|
||||
break;
|
||||
default:
|
||||
writer.append(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -51,7 +51,7 @@ public class LiteralImpl extends ExpressionImpl implements Literal {
|
|||
|
||||
@Override
|
||||
public <T> T accept(final ExpressionVisitor<T> visitor) throws ExpressionVisitException, ODataApplicationException {
|
||||
return visitor.visitLiteral(text);
|
||||
return visitor.visitLiteral(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKin
|
|||
import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitor;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.Literal;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.MethodKind;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.UnaryOperatorKind;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operand.TypedOperand;
|
||||
|
@ -167,9 +168,8 @@ public class ExpressionVisitorImpl implements ExpressionVisitor<VisitorOperand>
|
|||
}
|
||||
|
||||
@Override
|
||||
public VisitorOperand visitLiteral(final String literal) throws ExpressionVisitException, ODataApplicationException {
|
||||
|
||||
return new UntypedOperand(literal);
|
||||
public VisitorOperand visitLiteral(final Literal literal) throws ExpressionVisitException, ODataApplicationException {
|
||||
return new UntypedOperand(literal.getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKin
|
|||
import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitor;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.Literal;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.MethodKind;
|
||||
import org.apache.olingo.server.api.uri.queryoption.expression.UnaryOperatorKind;
|
||||
|
||||
|
@ -82,8 +83,8 @@ public class FilterTreeToText implements ExpressionVisitor<String> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String visitLiteral(final String literal) throws ExpressionVisitException {
|
||||
return "<" + literal + ">";
|
||||
public String visitLiteral(final Literal literal) throws ExpressionVisitException {
|
||||
return "<" + literal.getText() + ">";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue