You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by fm...@apache.org on 2013/07/26 13:22:14 UTC
[09/51] [partial] initial commit
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/OrderByParserImpl.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/OrderByParserImpl.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/OrderByParserImpl.java
new file mode 100644
index 0000000..d81a412
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/OrderByParserImpl.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * 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.uri.expression;
+
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.uri.expression.CommonExpression;
+import org.apache.olingo.odata2.api.uri.expression.ExpressionParserException;
+import org.apache.olingo.odata2.api.uri.expression.OrderByExpression;
+import org.apache.olingo.odata2.api.uri.expression.SortOrder;
+
+public class OrderByParserImpl extends FilterParserImpl implements OrderByParser {
+ public OrderByParserImpl(final EdmEntityType resourceEntityType) {
+ super(resourceEntityType);
+ }
+
+ @Override
+ public OrderByExpression parseOrderByString(final String orderByExpression) throws ExpressionParserException, ExpressionParserInternalError {
+ curExpression = orderByExpression;
+ OrderByExpressionImpl orderCollection = new OrderByExpressionImpl(curExpression);
+
+ try {
+ tokenList = new Tokenizer(orderByExpression).tokenize(); //throws TokenizerMessage
+ } catch (TokenizerException tokenizerException) {
+ throw FilterParserExceptionImpl.createERROR_IN_TOKENIZER(tokenizerException, curExpression);
+ }
+
+ while (true) {
+ CommonExpression node = null;
+ try {
+ CommonExpression nodeLeft = readElement(null);
+ node = readElements(nodeLeft, 0);
+ } catch (ExpressionParserException expressionException) {
+ expressionException.setFilterTree(orderCollection);
+ throw expressionException;
+ }
+
+ OrderExpressionImpl orderNode = new OrderExpressionImpl(node);
+
+ //read the sort order
+ Token token = tokenList.lookToken();
+ if (token == null) {
+ orderNode.setSortOrder(SortOrder.asc);
+ } else if ((token.getKind() == TokenKind.LITERAL) && (token.getUriLiteral().equals("asc"))) {
+ orderNode.setSortOrder(SortOrder.asc);
+ tokenList.next();
+ token = tokenList.lookToken();
+ } else if ((token.getKind() == TokenKind.LITERAL) && (token.getUriLiteral().equals("desc"))) {
+ orderNode.setSortOrder(SortOrder.desc);
+ tokenList.next();
+ token = tokenList.lookToken();
+ } else if (token.getKind() == TokenKind.COMMA) {
+ orderNode.setSortOrder(SortOrder.asc);
+ } else {
+ // Tested with TestParserExceptions.TestOPMparseOrderByString CASE 1
+ throw FilterParserExceptionImpl.createINVALID_SORT_ORDER(token, curExpression);
+ }
+
+ orderCollection.addOrder(orderNode);
+
+ //ls_token may be a ',' or empty.
+ if (token == null) {
+ break;
+ } else if (token.getKind() == TokenKind.COMMA) {
+ Token oldToken = token;
+ tokenList.next();
+ token = tokenList.lookToken();
+
+ if (token == null) {
+ // Tested with TestParserExceptions.TestOPMparseOrderByString CASE 2
+ throw FilterParserExceptionImpl.createEXPRESSION_EXPECTED_AFTER_POS(oldToken, curExpression);
+ }
+ } else { //e.g. in case $orderby=String asc a
+
+ throw FilterParserExceptionImpl.createCOMMA_OR_END_EXPECTED_AT_POS(token, curExpression);
+ }
+
+ }
+ return orderCollection;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/OrderExpressionImpl.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/OrderExpressionImpl.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/OrderExpressionImpl.java
new file mode 100644
index 0000000..f07829f
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/OrderExpressionImpl.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * 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.uri.expression;
+
+import org.apache.olingo.odata2.api.edm.EdmType;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+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.ExpressionVisitor;
+import org.apache.olingo.odata2.api.uri.expression.OrderExpression;
+import org.apache.olingo.odata2.api.uri.expression.SortOrder;
+
+/**
+ * @author SAP AG
+ */
+public class OrderExpressionImpl implements OrderExpression {
+
+ SortOrder orderType = SortOrder.asc;
+ CommonExpression expression;
+
+ OrderExpressionImpl(final CommonExpression expression) {
+ this.expression = expression;
+ }
+
+ @Override
+ public SortOrder getSortOrder() {
+ return orderType;
+ }
+
+ @Override
+ public CommonExpression getExpression() {
+ return expression;
+ }
+
+ void setSortOrder(final SortOrder orderType) {
+ this.orderType = orderType;
+ }
+
+ @Override
+ public ExpressionKind getKind() {
+ return ExpressionKind.ORDER;
+ }
+
+ @Override
+ public EdmType getEdmType() {
+ return null;
+ }
+
+ @Override
+ public CommonExpression setEdmType(final EdmType edmType) {
+ return this;
+ }
+
+ @Override
+ public String getUriLiteral() {
+ return "";
+ }
+
+ @Override
+ public Object accept(final ExpressionVisitor visitor) throws ExceptionVisitExpression, ODataApplicationException {
+ Object obj = expression.accept(visitor);
+ Object ret = visitor.visitOrder(this, obj, orderType);
+ return ret;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/ParameterSet.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/ParameterSet.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/ParameterSet.java
new file mode 100644
index 0000000..410a590
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/ParameterSet.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * 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.uri.expression;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.edm.EdmSimpleType;
+import org.apache.olingo.odata2.api.edm.EdmType;
+import org.apache.olingo.odata2.api.edm.EdmTypeKind;
+
+/**
+ * Parameter set is a vector of 1 or more EDM types, it is used to store the possible
+ * input and return types of a <i>OData filter operator</i> or <i>OData filter method</i>
+ * @see InfoMethod
+ * @see InfoBinaryOperator
+ * @see InfoUnaryOperator
+ * @author SAP AG
+ */
+@SuppressWarnings("javadoc")
+public class ParameterSet {
+ private EdmType returnType = null;
+ public ArrayList<EdmSimpleType> types = new ArrayList<EdmSimpleType>();
+ private EdmSimpleType furtherType = null;
+
+ public ParameterSet(final EdmType returnType, final EdmSimpleType type1) {
+ this.returnType = returnType;
+ types.add(type1);
+ }
+
+ public ParameterSet(final EdmSimpleType returnType, final EdmSimpleType type1, final EdmSimpleType type2) {
+ this.returnType = returnType;
+ types.add(type1);
+ types.add(type2);
+ }
+
+ public ParameterSet(final EdmSimpleType returnType, final EdmSimpleType type1, final EdmSimpleType type2, final EdmSimpleType type3) {
+ this.returnType = returnType;
+ types.add(type1);
+ types.add(type2);
+ types.add(type3);
+ }
+
+ public EdmType getReturnType() {
+ return returnType;
+ }
+
+ public EdmSimpleType getFurtherType() {
+ return furtherType;
+ }
+
+ public ParameterSet setFurtherType(final EdmSimpleType furtherType) {
+ this.furtherType = furtherType;
+ return this;
+ }
+
+ /**
+ * Compares a list of EdmTypes with the EdmTypes stored in {@link #types}.
+ * The lists are compared sequentially, e.g index N of actualParameterTypes with index N of {@link #types}.
+ * If the input list contains more elements than stored in {@link #types} (which is allowed when validating the <i>concat</i> method
+ * which takes a variable number of input parameters), the actual parameter type is compared against the {@link #furtherType}.
+ * @param actualParameterTypes
+ * @param allowPromotion
+ * @return true if equals
+ * @throws ExpressionParserInternalError
+ */
+ public boolean equals(final List<EdmType> actualParameterTypes, final boolean allowPromotion) throws ExpressionParserInternalError {
+ int actSize = actualParameterTypes.size();
+ int paramSize = types.size();
+
+ if (actSize < paramSize) {
+ return false;
+ //throw FilterParserInternalError.createINVALID_TYPE_COUNT(); //to few actual Parameters
+ }
+
+ //This may happen if the number of supplied actual method parameters is higher then than the number
+ //of allowed method parameters but this should be checked before, hence this is an internal error in the parser
+ if ((actSize > paramSize) && (furtherType == null)) {
+ return false;
+ //throw FilterParserInternalError.createINVALID_TYPE_COUNT();
+ }
+
+ for (int i = 0; i < actSize; i++) {
+ EdmType actType = actualParameterTypes.get(i);
+ if (actType == null) {
+ return false;
+ }
+
+ EdmSimpleType paramType = null;
+ if (i < paramSize) {
+ paramType = types.get(i);
+ } else {
+ paramType = furtherType; // for methods with variable amount of method parameters
+ }
+
+ if (!actType.equals(paramType)) {
+ //this the parameter type does not fit and if it is not allowed to promoted the actual parameter then
+ //this parameter combination does not fit
+ if (!allowPromotion) {
+ return false;
+ }
+
+ //Its allowed to promoted the actual parameter!!!
+
+ //Promotion only allowed for simple types
+ if (actType.getKind() != EdmTypeKind.SIMPLE) {
+ return false; //Tested with TestParserExceptions.testAdditionalStuff CASE 8
+ }
+
+ //The type simply don't match
+ if (!paramType.isCompatible((EdmSimpleType) actType)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/ParameterSetCombination.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/ParameterSetCombination.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/ParameterSetCombination.java
new file mode 100644
index 0000000..a989055
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/ParameterSetCombination.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * 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.uri.expression;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.edm.EdmType;
+
+public interface ParameterSetCombination {
+
+ void add(ParameterSet parameterSet);
+
+ ParameterSet validate(List<EdmType> actualParameterTypes) throws ExpressionParserInternalError;
+
+ void addFirst(ParameterSet parameterSet);
+
+ EdmType getReturnType();
+
+ public static class PSCflex implements ParameterSetCombination {
+ public List<ParameterSet> combinations = new ArrayList<ParameterSet>();
+
+ @Override
+ public void add(final ParameterSet parameterSet) {
+ combinations.add(parameterSet);
+ }
+
+ @Override
+ public EdmType getReturnType() {
+ int parameterCount = combinations.size();
+ if (parameterCount == 0) {
+ return null;
+ }
+
+ if (parameterCount == 1) {
+ return combinations.get(0).getReturnType();
+ }
+
+ //There are more than 1 possible return type, check if they are equal, if not return null.
+ EdmType returnType = combinations.get(0).getReturnType();
+ for (int i = 1; i < parameterCount; i++) {
+ if (returnType != combinations.get(i)) {
+ return null;
+ }
+ }
+
+ return returnType;
+
+ }
+
+ @Override
+ public void addFirst(final ParameterSet parameterSet) {
+ List<ParameterSet> oldCombinations = combinations;
+ combinations = new ArrayList<ParameterSet>();
+ combinations.add(parameterSet);
+ for (ParameterSet parameterSet1 : oldCombinations) {
+ combinations.add(parameterSet1);
+ }
+
+ }
+
+ @Override
+ public ParameterSet validate(final List<EdmType> actualParameterTypes) throws ExpressionParserInternalError {
+ if (combinations.size() == 0) {
+ return new ParameterSet(null, null);
+ }
+
+ //first check for exact parameter combination
+ for (ParameterSet parameterSet : combinations) {
+ boolean s = parameterSet.equals(actualParameterTypes, false);
+ if (s) {
+ return parameterSet;
+ }
+ }
+
+ //first check for parameter combination with promotion
+ for (ParameterSet parameterSet : combinations) {
+ boolean s = parameterSet.equals(actualParameterTypes, true);
+ if (s) {
+ return parameterSet;
+ }
+ }
+ return null;
+ }
+
+ }
+
+ public static class PSCReturnTypeEqLastParameter implements ParameterSetCombination {
+
+ @Override
+ public void add(final ParameterSet parameterSet) {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public void addFirst(final ParameterSet parameterSet) {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public ParameterSet validate(final List<EdmType> actualParameterTypes) throws ExpressionParserInternalError {
+ EdmType xxx = actualParameterTypes.get(actualParameterTypes.size() - 1);
+ return new ParameterSet(xxx, null);
+ //return actualParameterTypes.get(actualParameterTypes.size() - 1);
+ }
+
+ @Override
+ public EdmType getReturnType() {
+ //If the return type is always the type of the last parameter of the actual parameters ( e.g. when using the method operator)
+ //then the return type can not predicted.
+ return null;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/PropertyExpressionImpl.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/PropertyExpressionImpl.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/PropertyExpressionImpl.java
new file mode 100644
index 0000000..7e13237
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/PropertyExpressionImpl.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * 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.uri.expression;
+
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmLiteral;
+import org.apache.olingo.odata2.api.edm.EdmType;
+import org.apache.olingo.odata2.api.edm.EdmTyped;
+import org.apache.olingo.odata2.api.uri.expression.CommonExpression;
+import org.apache.olingo.odata2.api.uri.expression.ExpressionKind;
+import org.apache.olingo.odata2.api.uri.expression.ExpressionVisitor;
+import org.apache.olingo.odata2.api.uri.expression.PropertyExpression;
+
+public class PropertyExpressionImpl implements PropertyExpression {
+ private String uriLiteral;
+ private EdmType edmType;
+ private EdmTyped edmProperty;
+ private EdmLiteral edmLiteral;
+
+ public PropertyExpressionImpl(final String uriLiteral, final EdmLiteral edmLiteral) {
+ this.uriLiteral = uriLiteral;
+
+ this.edmLiteral = edmLiteral;
+ if (edmLiteral != null) {
+ edmType = edmLiteral.getType();
+ }
+ }
+
+ public CommonExpression setEdmProperty(final EdmTyped edmProperty) {
+ //used EdmTyped because it may be a EdmProperty or a EdmNavigationProperty
+ this.edmProperty = edmProperty;
+ return this;
+ }
+
+ @Override
+ public CommonExpression setEdmType(final EdmType edmType) {
+ this.edmType = edmType;
+ return this;
+ }
+
+ @Override
+ public String getPropertyName() {
+ if (edmProperty == null) {
+ return "";
+ }
+
+ try {
+ return edmProperty.getName();
+ } catch (EdmException e) {
+ return "";
+ }
+ }
+
+ public EdmLiteral getEdmLiteral() {
+ return edmLiteral;
+ }
+
+ @Override
+ public EdmTyped getEdmProperty() {
+ return edmProperty;
+ }
+
+ @Override
+ public ExpressionKind getKind() {
+ return ExpressionKind.PROPERTY;
+ }
+
+ @Override
+ public String getUriLiteral() {
+ return uriLiteral;
+ }
+
+ @Override
+ public EdmType getEdmType() {
+ return edmType;
+ }
+
+ @Override
+ public Object accept(final ExpressionVisitor visitor) {
+ Object ret = visitor.visitProperty(this, uriLiteral, edmProperty);
+ return ret;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/Token.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/Token.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/Token.java
new file mode 100644
index 0000000..e1f0354
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/Token.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * 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.uri.expression;
+
+/*1*/
+
+import org.apache.olingo.odata2.api.edm.EdmLiteral;
+import org.apache.olingo.odata2.api.edm.EdmType;
+
+public class Token {
+
+ private TokenKind kind;
+ private int position;
+ private String uriLiteral;
+ private EdmLiteral javaLiteral;
+
+ public Token(final TokenKind kind, final int position, final String uriLiteral, final EdmLiteral javaLiteral) {
+ this.kind = kind;
+ this.position = position;
+ this.uriLiteral = uriLiteral;
+ this.javaLiteral = javaLiteral;
+ }
+
+ public Token(final TokenKind kind, final int position, final String uriLiteral) {
+ this.kind = kind;
+ this.position = position;
+ this.uriLiteral = uriLiteral;
+ javaLiteral = null;
+ }
+
+ public TokenKind getKind() {
+ return kind;
+ }
+
+ public int getPosition() {
+ return position;
+ }
+
+ public EdmType getEdmType() {
+ if (javaLiteral == null) {
+ return null;
+ }
+ return javaLiteral.getType();
+ }
+
+ public String getUriLiteral() {
+ return uriLiteral;
+ }
+
+ public EdmLiteral getJavaLiteral() {
+ return javaLiteral;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/TokenKind.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/TokenKind.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/TokenKind.java
new file mode 100644
index 0000000..fff6bb2
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/TokenKind.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * 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.uri.expression;
+
+/*1*/
+
+/**
+ * The token kind is used to categorize a single {@link Token}.
+ * The Expression parser ({@link FilterParserImpl}) uses this information
+ * to build the expression tree.
+ */
+public enum TokenKind {
+ /**
+ * Indicates that the token is a whitespace character
+ */
+ WHITESPACE,
+
+ /**
+ * Indicates that the token is a '(' character
+ */
+ OPENPAREN,
+
+ /**
+ * Indicates that the token is a ')' character
+ */
+ CLOSEPAREN,
+
+ /**
+ * Indicates that the token is a ',' character
+ */
+ COMMA,
+
+ /**
+ * Indicates that the token is a typed literal. That may be a
+ * Edm.String like 'TEST'
+ * Edm.Double like '1.1D'
+ * or any other Edm.Simple Type
+ */
+ SIMPLE_TYPE,
+
+ /**
+ * Indicates that the token is a single symbol. That may be a
+ * '-', '=', '/', '?', '.' or a '*' character
+ */
+ SYMBOL,
+
+ /**
+ * Indicates that the token is a set of alphanumeric characters starting
+ * with a letter
+ */
+ LITERAL, TYPED_LITERAL_TODO_CHECK, UNKNOWN
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/TokenList.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/TokenList.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/TokenList.java
new file mode 100644
index 0000000..e08ba17
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/TokenList.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * 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.uri.expression;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.olingo.odata2.api.edm.EdmLiteral;
+
+public class TokenList implements Iterator<Token> {
+ private ArrayList<Token> tokens = null;
+ int currentToken = 0;
+
+ public TokenList() {
+ tokens = new ArrayList<Token>();
+ }
+
+ /**
+ * Append StringValue Token to tokens parameter
+ * @param position Position of parsed token
+ * @param kind Kind of parsed token
+ * @param uriLiteral String value of parsed token
+ */
+ public void appendToken(final int position, final TokenKind kind, final String uriLiteral) {
+ Token token = new Token(kind, position, uriLiteral);
+ tokens.add(token);
+ return;
+ }
+
+ /**
+ * Append CharValue Token to tokens parameter
+ * @param position Position of parsed token
+ * @param kind Kind of parsed token
+ * @param charValue Char value of parsed token
+ */
+ public void appendToken(final int position, final TokenKind kind, final char charValue) {
+ Token token = new Token(kind, position, Character.toString(charValue));
+ tokens.add(token);
+ return;
+ }
+
+ /**
+ * Append UriLiteral Token to tokens parameter
+ * @param position Position of parsed token
+ * @param kind Kind of parsed token
+ * @param javaLiteral EdmLiteral of parsed token containing type and value of UriLiteral
+ */
+ public void appendEdmTypedToken(final int position, final TokenKind kind, final String uriLiteral, final EdmLiteral javaLiteral) {
+ Token token = new Token(kind, position, uriLiteral, javaLiteral);
+ tokens.add(token);
+ return;
+ }
+
+ public Token lookToken() {
+ if (currentToken >= tokens.size()) {
+ return null;
+ }
+
+ return tokens.get(currentToken);
+ }
+
+ public Token lookPrevToken() {
+ if (currentToken - 1 < 0) {
+ return null;
+ }
+
+ return tokens.get(currentToken - 1);
+ }
+
+ public boolean hasTokens() {
+ return (tokens.size() > 0);
+ }
+
+ public int tokenCount() {
+ int i = tokens.size();
+
+ return i;
+ }
+
+ public Token expectToken(final TokenKind comma) throws TokenizerExpectError {
+ Token actual = next();
+ if (actual == null) {
+ throw TokenizerExpectError.createNO_TOKEN_AVAILABLE(comma.toString());
+ }
+
+ if (comma != actual.getKind()) {
+ throw TokenizerExpectError.createINVALID_TOKENKIND_AT(comma, actual);
+ }
+ return actual;
+ }
+
+ public Token expectToken(final TokenKind comma, final boolean throwFilterExpression) throws ExpressionParserInternalError {
+ Token actual = next();
+ if (actual == null) {
+ throw ExpressionParserInternalError.createNO_TOKEN_AVAILABLE(comma.toString());
+ }
+
+ if (comma != actual.getKind()) {
+ if (throwFilterExpression) {
+ throw ExpressionParserInternalError.createINVALID_TOKENKIND_AT(comma, actual);
+ }
+ }
+ return actual;
+ }
+
+ public Token expectToken(final String literal) throws TokenizerExpectError {
+ Token actual = next();
+ if (actual == null) {
+ throw TokenizerExpectError.createNO_TOKEN_AVAILABLE(literal);
+ }
+
+ if (!literal.equals(actual.getUriLiteral())) {
+ throw TokenizerExpectError.createINVALID_TOKEN_AT(literal, actual);
+ }
+ return actual;
+ }
+
+ public Token expectToken(final String literal, final boolean throwInternal) throws ExpressionParserInternalError {
+ Token actual = next();
+ if (actual == null) {
+ throw ExpressionParserInternalError.createNO_TOKEN_AVAILABLE(literal);
+ }
+
+ if (!literal.equals(actual.getUriLiteral())) {
+ if (throwInternal) {
+ throw ExpressionParserInternalError.createINVALID_TOKEN_AT(literal, actual);
+ }
+ }
+ return actual;
+ }
+
+ public void skip() {
+ currentToken++;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return (currentToken < tokens.size());
+ }
+
+ @Override
+ public Token next() {
+ if (currentToken >= tokens.size()) {
+ return null;
+ }
+
+ Token ret = tokens.get(currentToken);
+ currentToken++;
+ return ret;
+ }
+
+ @Override
+ public void remove() {
+ throw new IllegalArgumentException("Method not allowed");
+ }
+
+ public Token elementAt(final int index) {
+
+ return tokens.get(index);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/Tokenizer.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/Tokenizer.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/Tokenizer.java
new file mode 100644
index 0000000..d449208
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/Tokenizer.java
@@ -0,0 +1,323 @@
+/*******************************************************************************
+ * 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.uri.expression;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.olingo.odata2.api.edm.EdmLiteral;
+import org.apache.olingo.odata2.api.edm.EdmLiteralException;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeFacade;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.uri.expression.ExpressionParserException;
+import org.apache.olingo.odata2.core.edm.EdmSimpleTypeFacadeImpl;
+
+/**
+ * Expression tokenizer
+ * @author SAP AG
+ */
+public class Tokenizer {
+
+ //Pattern OTHER_LIT = Pattern.compile("^([[A-Za-z0-9]._~%!$&*+;:@-]+)");
+ private static final Pattern OTHER_LIT = Pattern.compile("(?:\\p{L}|\\p{Digit}|[-._~%!$&*+;:@])+");
+ private static final Pattern FUNK = Pattern.compile("^(startswith|endswith|substring|substring|substringof|indexof|replace|tolower|toupper|trim|concat|length|year|mounth|day|hour|minute|second|round|ceiling|floor)( *)\\(");
+ private static final Pattern AND_SUB1 = Pattern.compile("^(add|sub|mul|div|mod|not) ");
+ private static final Pattern AND_SUB = Pattern.compile("^(and|or|eq|ne|lt|gt|le|ge) ");
+ private static final Pattern prefix = Pattern.compile("^(X|binary|guid|datetime|datetimeoffset|time)'");
+ private boolean flagIncludeWhitespace = false;
+ private EdmSimpleTypeFacade typeDectector = null;
+
+ int curPosition;
+ final String expression;
+ final int expressionLength;
+ TokenList tokens;
+
+ public Tokenizer(final String expression) {
+ typeDectector = new EdmSimpleTypeFacadeImpl();
+ this.expression = expression;
+ expressionLength = expression.length();
+ tokens = new TokenList();
+ }
+
+ /**
+ * Inform the Tokenizer whether extra tokens for whitespace characters should be added to the token list or not.
+ * @param flagIncludeWhitespace True -> Whitespace token will be added to token list; False otherwise
+ * @return this
+ */
+ public Tokenizer setFlagWhiteSpace(final Boolean flagIncludeWhitespace) {
+ this.flagIncludeWhitespace = flagIncludeWhitespace;
+ return this;
+ }
+
+ /**
+ * Tokenizes an expression as defined per OData specification
+ * @return Token list
+ */
+ public TokenList tokenize() throws TokenizerException, ExpressionParserException {
+ curPosition = 0;
+ int oldPosition;
+ char curCharacter;
+ String token = "";
+
+ while (curPosition < expressionLength) {
+ oldPosition = curPosition;
+
+ curCharacter = expression.charAt(curPosition);
+ switch (curCharacter) {
+ case ' ':
+ //count whitespace and move pointer to next non-whitespace char
+ eatWhiteSpaces(curPosition, curCharacter);
+ break;
+
+ case '(':
+ tokens.appendToken(curPosition, TokenKind.OPENPAREN, curCharacter);
+ curPosition = curPosition + 1;
+
+ break;
+
+ case ')':
+ tokens.appendToken(curPosition, TokenKind.CLOSEPAREN, curCharacter);
+ curPosition = curPosition + 1;
+ break;
+
+ case '\'':
+ token = "";
+ readLiteral(curCharacter);
+
+ break;
+
+ case ',':
+ tokens.appendToken(oldPosition, TokenKind.COMMA, curCharacter);
+ curPosition = curPosition + 1;
+ break;
+
+ case '=':
+ case '/':
+ case '?':
+ case '.':
+ case '*':
+ curPosition = curPosition + 1;
+ tokens.appendToken(oldPosition, TokenKind.SYMBOL, curCharacter);
+ break;
+
+ default:
+ String rem_expr = expression.substring(curPosition); //remaining expression
+
+ boolean isBinary = checkForBinary(oldPosition, rem_expr);
+ if (isBinary) {
+ break;
+ }
+
+ //check for prefixes like X, binary, guid, datetime
+ boolean isPrefix = checkForPrefix(rem_expr);
+ if (isPrefix) {
+ break;
+ }
+
+ //check for math
+ boolean isMath = checkForMath(oldPosition, rem_expr);
+ if (isMath) {
+ break;
+ }
+
+ //check for function
+ boolean isFunction = checkForMethod(oldPosition, rem_expr);
+ if (isFunction) {
+ break;
+ }
+
+ boolean isBoolean = checkForBoolean(oldPosition, rem_expr);
+ if (isBoolean) {
+ break;
+ }
+
+ boolean isLiteral = checkForLiteral(oldPosition, curCharacter, rem_expr);
+ if (isLiteral) {
+ break;
+ }
+
+ token = new Character(curCharacter).toString();
+ throw TokenizerException.createUNKNOWN_CHARACTER(oldPosition, token, expression);
+ }
+ }
+ return tokens;
+ }
+
+ private boolean checkForLiteral(final int oldPosition, final char curCharacter, final String rem_expr) {
+ final Matcher matcher = OTHER_LIT.matcher(rem_expr);
+ boolean isLiteral = false;
+ if (matcher.lookingAt()) {
+ String token = matcher.group();
+ try {
+ EdmLiteral edmLiteral = typeDectector.parseUriLiteral(token);
+ curPosition = curPosition + token.length();
+ // It is a simple type.
+ tokens.appendEdmTypedToken(oldPosition, TokenKind.SIMPLE_TYPE, token, edmLiteral);
+ isLiteral = true;
+ } catch (EdmLiteralException e) {
+ // We treat it as normal untyped literal.
+
+ // The '-' is checked here (and not in the switch statement) because it may be
+ // part of a negative number.
+ if (curCharacter == '-') {
+ curPosition = curPosition + 1;
+ tokens.appendToken(oldPosition, TokenKind.SYMBOL, curCharacter);
+ isLiteral = true;
+ } else {
+ curPosition = curPosition + token.length();
+ tokens.appendToken(oldPosition, TokenKind.LITERAL, token);
+ isLiteral = true;
+ }
+ }
+ }
+ return isLiteral;
+ }
+
+ private boolean checkForBoolean(final int oldPosition, final String rem_expr) {
+ boolean isBoolean = false;
+ if (rem_expr.equals("true") || rem_expr.equals("false")) {
+ curPosition = curPosition + rem_expr.length();
+ tokens.appendEdmTypedToken(oldPosition, TokenKind.SIMPLE_TYPE, rem_expr, new EdmLiteral(EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Boolean), rem_expr));
+ isBoolean = true;
+ }
+ return isBoolean;
+ }
+
+ private void eatWhiteSpaces(final int oldPosition, char curCharacter) {
+ int lv_token_len;
+ String expression_sub;
+ while ((curCharacter == ' ') && (curPosition < expressionLength)) {
+ curPosition = curPosition + 1;
+ if (curPosition < expressionLength) {
+ curCharacter = expression.charAt(curPosition);
+ }
+ }
+
+ lv_token_len = curPosition - oldPosition;
+
+ if (flagIncludeWhitespace == true) {
+ expression_sub = expression.substring(oldPosition, oldPosition + lv_token_len);
+ tokens.appendEdmTypedToken(oldPosition, TokenKind.WHITESPACE, expression_sub, null);
+ }
+ }
+
+ private boolean checkForMethod(final int oldPosition, final String rem_expr) {
+ boolean isMethod = false;
+ Matcher matcher = FUNK.matcher(rem_expr);
+ if (matcher.find()) {
+ String token = matcher.group(1);
+ curPosition = curPosition + token.length();
+ tokens.appendToken(oldPosition, TokenKind.LITERAL, token);
+ isMethod = true;
+ }
+ return isMethod;
+ }
+
+ private boolean checkForMath(final int oldPosition, final String rem_expr) {
+ boolean isMath = false;
+ Matcher matcher1 = AND_SUB1.matcher(rem_expr);
+ if (matcher1.find()) {
+ String token = matcher1.group(1);
+ curPosition = curPosition + token.length();
+ tokens.appendToken(oldPosition, TokenKind.LITERAL, token);
+ isMath = true;
+ }
+ return isMath;
+ }
+
+ private boolean checkForBinary(final int oldPosition, final String rem_expr) {
+ boolean isBinary = false;
+ Matcher matcher1 = AND_SUB.matcher(rem_expr);
+ if (matcher1.find()) {
+ String token = matcher1.group(1);
+ curPosition = curPosition + token.length();
+ tokens.appendToken(oldPosition, TokenKind.LITERAL, token);
+ isBinary = true;
+ }
+ return isBinary;
+ }
+
+ private boolean checkForPrefix(final String rem_expr) throws ExpressionParserException, TokenizerException {
+ boolean isPrefix = false;
+ Matcher matcher = prefix.matcher(rem_expr);
+ String token = "";
+ char curCharacter;
+
+ if (matcher.find()) {
+ token = matcher.group(1);
+ curPosition = curPosition + token.length();
+ curCharacter = expression.charAt(curPosition); //"should be '
+ readLiteral(curCharacter, token);
+ isPrefix = true;
+ }
+ return isPrefix;
+ }
+
+ private void readLiteral(final char curCharacter) throws ExpressionParserException, TokenizerException {
+ readLiteral(curCharacter, "");
+ }
+
+ /**
+ * Read up to single ' and move pointer to the following char and tries a type detection
+ * @param curCharacter
+ * @param token
+ * @throws ExpressionParserException
+ * @throws TokenizerException
+ */
+ private void readLiteral(char curCharacter, String token) throws ExpressionParserException, TokenizerException {
+ int offsetPos = -token.length();
+ int oldPosition = curPosition;
+ token = token + Character.toString(curCharacter);
+ curPosition = curPosition + 1;
+
+ boolean wasApostroph = false; //leading ' does not count
+ while (curPosition < expressionLength) {
+ curCharacter = expression.charAt(curPosition);
+
+ if (curCharacter != '\'') {
+ if (wasApostroph == true) {
+ break;
+ }
+
+ token = token + curCharacter;
+ wasApostroph = false;
+ } else {
+ if (wasApostroph) {
+ wasApostroph = false; //a double ' is a normal character '
+ } else {
+ wasApostroph = true;
+ token = token + curCharacter;
+ }
+ }
+ curPosition = curPosition + 1;
+ }
+
+ if (!wasApostroph) {
+ //Exception tested within TestPMparseFilterString
+ throw FilterParserExceptionImpl.createTOKEN_UNDETERMINATED_STRING(oldPosition, expression);
+ }
+
+ try {
+ EdmLiteral edmLiteral = typeDectector.parseUriLiteral(token);
+ tokens.appendEdmTypedToken(oldPosition + offsetPos, TokenKind.SIMPLE_TYPE, token, edmLiteral);
+ } catch (EdmLiteralException ex) {
+ throw TokenizerException.createTYPEDECTECTION_FAILED_ON_STRING(ex, oldPosition, token);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/TokenizerException.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/TokenizerException.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/TokenizerException.java
new file mode 100644
index 0000000..695bc8a
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/TokenizerException.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * 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.uri.expression;
+
+import org.apache.olingo.odata2.api.edm.EdmLiteralException;
+import org.apache.olingo.odata2.api.exception.MessageReference;
+import org.apache.olingo.odata2.api.exception.ODataMessageException;
+
+/**
+ * This exception is thrown if there is an error during tokenizing.<br>
+ * <b>This exception in not in the public API</b>, but may be added as cause for
+ * the {@link org.apache.olingo.odata2.api.uri.expression.ExpressionParserException} exception.
+ * @author SAP AG
+ */
+public class TokenizerException extends ODataMessageException {
+ private static final long serialVersionUID = 77L;
+
+ public static final MessageReference TYPEDECTECTION_FAILED_ON_STRING = createMessageReference(TokenizerException.class, "TYPEDECTECTION_FAILED_ON_STRING");
+ public static final MessageReference UNKNOWN_CHARACTER = createMessageReference(TokenizerException.class, "UNKNOWN_CHARACTER");
+
+ private Token token;
+ private int position;
+
+ public Token getToken() {
+ return token;
+ }
+
+ public TokenizerException setToken(final Token token) {
+ this.token = token;
+ return this;
+ }
+
+ public int getPosition() {
+ return position;
+ }
+
+ public void setPosition(final int position) {
+ this.position = position;
+ }
+
+ public TokenizerException(final MessageReference messageReference) {
+ super(messageReference);
+ }
+
+ public TokenizerException(final MessageReference messageReference, final Throwable cause) {
+ super(messageReference, cause);
+ }
+
+ static public TokenizerException createTYPEDECTECTION_FAILED_ON_STRING(final EdmLiteralException ex, final int position, final String uriLiteral) {
+ MessageReference msgRef = TokenizerException.TYPEDECTECTION_FAILED_ON_STRING.create();
+
+ msgRef.addContent(uriLiteral);
+ msgRef.addContent(position);
+ Token token = new Token(TokenKind.UNKNOWN, position, uriLiteral);
+
+ return new TokenizerException(msgRef, ex).setToken(token);
+ }
+
+ /*
+ static public TokenizerException createTYPEDECTECTION_FAILED_ON_EDMTYPE(EdmLiteralException ex, int position, String uriLiteral)
+ {
+ MessageReference msgRef = TokenizerException.TYPEDECTECTION_FAILED_ON_EDMTYPE.create();
+
+ msgRef.addContent(uriLiteral);
+ msgRef.addContent(position);
+ Token token = new Token(TokenKind.UNKNOWN, position, uriLiteral);
+
+ return new TokenizerException(msgRef).setToken(token);
+ }
+ */
+ static public TokenizerException createUNKNOWN_CHARACTER(final int position, final String uriLiteral, final String expression) {
+ MessageReference msgRef = TokenizerException.UNKNOWN_CHARACTER.create();
+
+ msgRef.addContent(uriLiteral);
+ msgRef.addContent(position);
+ msgRef.addContent(expression);
+ Token token = new Token(TokenKind.UNKNOWN, position, uriLiteral);
+
+ return new TokenizerException(msgRef).setToken(token);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/TokenizerExpectError.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/TokenizerExpectError.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/TokenizerExpectError.java
new file mode 100644
index 0000000..1b84b2c
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/TokenizerExpectError.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * 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.uri.expression;
+
+import org.apache.olingo.odata2.api.exception.MessageReference;
+import org.apache.olingo.odata2.api.exception.ODataMessageException;
+
+/**
+ * This exception is thrown if a token should be read
+ * from the top of the {@link TokenList} which does not match an
+ * expected token. The cause for using this exception <b>MUST</b> indicate an internal error
+ * in the {@link Tokenizer} or inside the {@link FilterParserImpl}.
+ * <br><br>
+ * <b>This exception in not in the public API</b>, but may be added as cause for
+ * the {@link ExpressionParserInternalError} exception.
+ * @author SAP AG
+ */
+public class TokenizerExpectError extends ODataMessageException {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final int parseStringpoken = 1;
+
+ //Invalid token detected at position &POSITION&
+ public static final MessageReference NO_TOKEN_AVAILABLE = createMessageReference(TokenizerExpectError.class, "NO_TOKEN_AVAILABLE");
+ public static final MessageReference INVALID_TOKEN_AT = createMessageReference(TokenizerExpectError.class, "INVALID_TOKEN_AT");
+ public static final MessageReference INVALID_TOKENKIND_AT = createMessageReference(TokenizerExpectError.class, "INVALID_TOKENKIND_AT");
+
+ private String token;
+ private Exception previous;
+ private int position;
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(final String token) {
+ this.token = token;
+ }
+
+ public Exception getPrevious() {
+ return previous;
+ }
+
+ public void setPrevious(final Exception previous) {
+ this.previous = previous;
+ }
+
+ public int getPosition() {
+ return position;
+ }
+
+ public void setPosition(final int position) {
+ this.position = position;
+ }
+
+ public TokenizerExpectError(final MessageReference messageReference) {
+ super(messageReference);
+ }
+
+ public static TokenizerExpectError createINVALID_TOKEN_AT(final String expectedToken, final Token actualToken) {
+ MessageReference msgRef = TokenizerExpectError.INVALID_TOKEN_AT.create();
+
+ msgRef.addContent(expectedToken);
+ msgRef.addContent(actualToken.getUriLiteral());
+ msgRef.addContent(actualToken.getPosition());
+
+ return new TokenizerExpectError(msgRef);
+ }
+
+ public static TokenizerExpectError createINVALID_TOKENKIND_AT(final TokenKind expectedTokenKind, final Token actualToken) {
+ MessageReference msgRef = TokenizerExpectError.INVALID_TOKEN_AT.create();
+
+ msgRef.addContent(expectedTokenKind.toString());
+ msgRef.addContent(actualToken.getKind().toString());
+ msgRef.addContent(actualToken.getUriLiteral());
+ msgRef.addContent(actualToken.getPosition());
+
+ return new TokenizerExpectError(msgRef);
+ }
+
+ public static TokenizerExpectError createNO_TOKEN_AVAILABLE(final String expectedToken) {
+ MessageReference msgRef = TokenizerExpectError.INVALID_TOKEN_AT.create();
+
+ msgRef.addContent(expectedToken);
+
+ return new TokenizerExpectError(msgRef);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/TokenizerRTException.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/TokenizerRTException.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/TokenizerRTException.java
new file mode 100644
index 0000000..e230919
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/TokenizerRTException.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * 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.uri.expression;
+
+/**
+ * Internal error. If used(thrown) the thrower
+ * @author SAP AG
+ */
+public class TokenizerRTException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ *
+ */
+ public TokenizerRTException() {
+ super();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/UnaryExpressionImpl.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/UnaryExpressionImpl.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/UnaryExpressionImpl.java
new file mode 100644
index 0000000..06be49e
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/UnaryExpressionImpl.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * 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.uri.expression;
+
+import org.apache.olingo.odata2.api.edm.EdmType;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+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.ExpressionVisitor;
+import org.apache.olingo.odata2.api.uri.expression.UnaryExpression;
+import org.apache.olingo.odata2.api.uri.expression.UnaryOperator;
+
+/**
+ * @author SAP AG
+ */
+public class UnaryExpressionImpl implements UnaryExpression {
+ private InfoUnaryOperator operatorInfo = null;
+ private CommonExpression operand = null;
+ private EdmType edmType = null;
+
+ public UnaryExpressionImpl(final InfoUnaryOperator operatorInfo, final CommonExpression operand) {
+ this.operatorInfo = operatorInfo;
+ this.operand = operand;
+ }
+
+ @Override
+ public ExpressionKind getKind() {
+ return ExpressionKind.UNARY;
+ }
+
+ @Override
+ public UnaryOperator getOperator() {
+ return operatorInfo.operator;
+ }
+
+ @Override
+ public CommonExpression getOperand() {
+ return operand;
+ }
+
+ @Override
+ public EdmType getEdmType() {
+ return edmType;
+ }
+
+ @Override
+ public CommonExpression setEdmType(final EdmType edmType) {
+ this.edmType = edmType;
+ return this;
+ }
+
+ @Override
+ public String getUriLiteral() {
+ return operatorInfo.getSyntax();
+ }
+
+ @Override
+ public Object accept(final ExpressionVisitor visitor) throws ExceptionVisitExpression, ODataApplicationException {
+ Object retOperand = operand.accept(visitor);
+
+ return visitor.visitUnary(this, operatorInfo.getOperator(), retOperand);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/resources/i18n.properties
----------------------------------------------------------------------
diff --git a/odata-core/src/main/resources/i18n.properties b/odata-core/src/main/resources/i18n.properties
new file mode 100644
index 0000000..1627223
--- /dev/null
+++ b/odata-core/src/main/resources/i18n.properties
@@ -0,0 +1,229 @@
+#-------------------------------------------------------------------------------
+# 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.
+#-------------------------------------------------------------------------------
+# Fallback
+#
+##################################
+# CommonExceptions (Should these exist?)
+##################################
+org.apache.olingo.odata2.api.exception.ODataMessageException.COMMON=Common exception
+
+##################################
+# UriParserExceptions
+##################################
+org.apache.olingo.odata2.api.uri.UriNotMatchingException.MATCHPROBLEM=Could not match segment: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriNotMatchingException.NOTFOUND=Could not find an entity set or function import for '%1$s'.
+org.apache.olingo.odata2.api.uri.UriNotMatchingException.CONTAINERNOTFOUND=Could not find container with name: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriNotMatchingException.ENTITYNOTFOUND=Could not find entity with name: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriNotMatchingException.PROPERTYNOTFOUND=Could not find property with name: '%1$s'.
+
+org.apache.olingo.odata2.api.uri.UriSyntaxException.URISYNTAX=Invalid URI syntax.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.ENTITYSETINSTEADOFENTITY=Must be an entity set instead of an entity: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.NOTEXT=An exception occurred.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.NOMEDIARESOURCE=The requested resource is no media resource.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.NONAVIGATIONPROPERTY=Property '%1$s' must be a navigation property.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.MISSINGPARAMETER=Missing parameter.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.MISSINGKEYPREDICATENAME=Missing key predicate name for key: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.DUPLICATEKEYNAMES=Duplicate key names: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.EMPTYSEGMENT=No empty segment allowed.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.MUSTNOTBELASTSEGMENT='%1$s' must not be the last segment.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.MUSTBELASTSEGMENT='%1$s' must be the last segment.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INVALIDSEGMENT=Invalid segment: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INVALIDVALUE=Invalid value: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INVALIDNULLVALUE=Value for '%1$s' must not be null.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INVALIDNEGATIVEVALUE=Provided value '%1$s' must not be negative.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INVALIDRETURNTYPE=Invalid return type: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INVALIDPROPERTYTYPE=Invalid type for property: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INVALIDKEYPREDICATE=Invalid key predicate: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INVALIDSYSTEMQUERYOPTION=Invalid system query option: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INVALIDFILTEREXPRESSION=Invalid filter expression: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INVALIDORDERBYEXPRESSION=Invalid order by expression: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.LITERALFORMAT=Wrong literal format for literal: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.UNKNOWNLITERAL=Unknown literal: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INCOMPATIBLELITERAL=Format of '%1$s' is not compatible with '%2$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INCOMPATIBLESYSTEMQUERYOPTION=System query option '%1$s' is not compatible with the return type.
+
+##################################
+# EDMExceptions
+##################################
+org.apache.olingo.odata2.api.edm.EdmLiteralException.NOTEXT=An exception occurred.
+org.apache.olingo.odata2.api.edm.EdmLiteralException.LITERALFORMAT=Wrong literal format for literal: '%1$s'.
+org.apache.olingo.odata2.api.edm.EdmLiteralException.UNKNOWNLITERAL=Unknown literal: '%1$s'.
+
+org.apache.olingo.odata2.api.edm.EdmException.COMMON=An exception occurred.
+org.apache.olingo.odata2.api.edm.EdmException.PROVIDERPROBLEM=A problem has been detected in the metadata provided by the EDM provider.
+
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.COMMON=An exception occurred.
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.LITERAL_KIND_MISSING=The literal kind is missing.
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.LITERAL_KIND_NOT_SUPPORTED=The literal kind '%1$s' is not supported.
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.LITERAL_NULL_NOT_ALLOWED=The metadata do not allow a null literal.
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT=The literal '%1$s' is not formatted properly.
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.LITERAL_FACETS_NOT_MATCHED=The metadata constraints '%2$s' do not match the literal '%1$s'.
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE=The literal '%1$s' can not be converted into the type '%1$s'.
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED=The type '%1$s' of the value object is not supported.
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.VALUE_NULL_NOT_ALLOWED=The metadata do not allow a null value.
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.VALUE_ILLEGAL_CONTENT=The value object '%1$s' can not be formatted properly due to its content.
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.VALUE_FACETS_NOT_MATCHED=The metadata constraints '%2$s' do not allow to format the value '%1$s'.
+
+##################################
+# EPexceptions
+##################################
+org.apache.olingo.odata2.api.ep.EntityProviderException.COMMON=An exception occurred.
+org.apache.olingo.odata2.api.ep.EntityProviderException.EXCEPTION_OCCURRED=An exception of type '%1$s' occurred.
+org.apache.olingo.odata2.api.ep.EntityProviderException.ILLEGAL_ARGUMENT=Illegal argument for method call with message '%1$s'.
+org.apache.olingo.odata2.api.ep.EntityProviderException.INLINECOUNT_INVALID=Invalid inline count found.
+org.apache.olingo.odata2.api.ep.EntityProviderException.INVALID_STATE=Invalid consuming state for parsing with message '%1$s'.
+org.apache.olingo.odata2.api.ep.EntityProviderException.INVALID_INLINE_CONTENT=Invalid '%1$s' found for parsing of inline content.
+org.apache.olingo.odata2.api.ep.EntityProviderException.INVALID_PROPERTY=Invalid property '%1$s' found.
+org.apache.olingo.odata2.api.ep.EntityProviderException.INVALID_NAMESPACE=Invalid or missing namespace for '%1$s'.
+org.apache.olingo.odata2.api.ep.EntityProviderException.INVALID_PARENT_TAG=Invalid parent tag. Expected '%1$s' but found '%2$s'.
+org.apache.olingo.odata2.api.ep.EntityProviderException.INVALID_MAPPING=Invalid mapping value for property '%1$s'.
+org.apache.olingo.odata2.api.ep.EntityProviderException.INVALID_ENTITYTYPE=Supplied entity type '%1$s' does not match the content entity type '%2$s'.
+org.apache.olingo.odata2.api.ep.EntityProviderException.INVALID_COMPLEX_TYPE=Supplied complex type '%1$s' does not match the content complex type '%2$s'.
+org.apache.olingo.odata2.api.ep.EntityProviderException.INVALID_CONTENT='%1$s' not expected in '%2$s'.
+org.apache.olingo.odata2.api.ep.EntityProviderException.INVALID_PROPERTY_VALUE=Provided value for the property '%1$s' is not compatible with the property.
+org.apache.olingo.odata2.api.ep.EntityProviderException.MISSING_ATTRIBUTE=Mandatory attribute '%1$s' at tag '%2$s' was not found.
+org.apache.olingo.odata2.api.ep.EntityProviderException.MISSING_PROPERTY=Property with name '%1$s' was not found.
+org.apache.olingo.odata2.api.ep.EntityProviderException.NOT_SET_CHARACTER_ENCODING=Mandatory character encoding is not set.
+org.apache.olingo.odata2.api.ep.EntityProviderException.DOUBLE_PROPERTY=Double occurrence of property with name '%1$s'.
+org.apache.olingo.odata2.api.ep.EntityProviderException.UNSUPPORTED_CHARACTER_ENCODING=The given character encoding '%1$s' is not supported.
+org.apache.olingo.odata2.api.ep.EntityProviderException.UNSUPPORTED_PROPERTY_TYPE=The given property type '%1$s' is not supported.
+org.apache.olingo.odata2.api.ep.EntityProviderException.EXPANDNOTSUPPORTED=Expand of the navigation property '%1$s' is not supported.
+org.apache.olingo.odata2.api.ep.EntityProviderException.MEDIA_DATA_NOT_INITIAL=Resource is not a media resource but media metadata was provided.
+org.apache.olingo.odata2.api.ep.EntityProviderException.END_DOCUMENT_EXPECTED=End of document expected but was '%1$s'.
+org.apache.olingo.odata2.api.ep.EntityProviderException.MISSING_RESULTS_ARRAY=Mandatory results array not found.
+
+##################################
+# BatchParserexceptions
+##################################
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_CHANGESET_BOUNDARY=The boundary of the ChangeSet should be different from that used by the Batch: line '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_BOUNDARY_DELIMITER=The boundary delimiter must begin with two hyphen characters: line '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.MISSING_BOUNDARY_DELIMITER=Missing boundary delimiter at line '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.MISSING_CLOSE_DELIMITER=Missing close delimiter at line '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_QUERY_OPERATION_METHOD=Invalid method: a Query Operation cannot contain insert, update or delete requests at line '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_CHANGESET_METHOD= Invalid method: a ChangeSet cannot contain retrieve requests at line '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_QUERY_PARAMETER=Invalid query parameters.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_URI=Invalid URI.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_BOUNDARY=Invalid boundary at line '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.NO_MATCH_WITH_BOUNDARY_STRING=The boundary string does not match the boundary from the Content-Type header field '%1$s': line '%2$s'.
+org.apache.olingo.odata2.api.batch.BatchException.MISSING_CONTENT_TYPE=No Content-Type field for MIME-header is present.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_CONTENT_TYPE=Content-Type should be '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.MISSING_PARAMETER_IN_CONTENT_TYPE=The Content-Type field for multipart entities requires boundary parameter.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_CONTENT_TRANSFER_ENCODING=The Content-Transfer-Encoding should be binary.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_ACCEPT_HEADER=Invalid Accept header: '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_ACCEPT_LANGUAGE_HEADER=Invalid Accept-Language: '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_HEADER=Invalid header: '%1$s' at line '%2$s'.
+org.apache.olingo.odata2.api.batch.BatchException.MISSING_BLANK_LINE=Expected empty line but was '%1$s': line '%2$s' .
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_PATHINFO=PathInfo should not be null.
+org.apache.olingo.odata2.api.batch.BatchException.MISSING_METHOD=Missing method in request line '%1$s'.
+org.apache.olingo.odata2.api.batch.BatchException.INVALID_REQUEST_LINE=Invalid request line '%1$s' at line '%2$s'.
+org.apache.olingo.odata2.api.batch.BatchException.TRUNCATED_BODY=Body is truncated: line '%1$s'.
+
+##################################
+# HttpExceptions
+##################################
+org.apache.olingo.odata2.api.exception.ODataHttpException.COMMON=Common exception
+
+org.apache.olingo.odata2.api.exception.ODataBadRequestException.COMMON=Bad Request.
+org.apache.olingo.odata2.api.exception.ODataBadRequestException.NOTSUPPORTED=The request is not supported by the processor.
+org.apache.olingo.odata2.api.exception.ODataBadRequestException.INVALID_HEADER=The request contains an invalid header parameter '%1$s' with value '%2$s'.
+org.apache.olingo.odata2.api.exception.ODataBadRequestException.INVALID_SYNTAX=The Data Services Request could not be understood due to malformed syntax.
+org.apache.olingo.odata2.api.exception.ODataBadRequestException.URLTOOSHORT=The URL is too short.
+org.apache.olingo.odata2.api.exception.ODataBadRequestException.VERSIONERROR=The Data Services Request version '%1$s' is not supported for the request payload.
+org.apache.olingo.odata2.api.exception.ODataBadRequestException.PARSEVERSIONERROR=The Data Services Request version '%1$s' cannot be parsed.
+org.apache.olingo.odata2.api.exception.ODataBadRequestException.BODY=The request body is malformed.
+org.apache.olingo.odata2.api.exception.ODataBadRequestException.AMBIGUOUS_XMETHOD=Ambiguous X-HTTP-Method and X-HTTP-Method-Override header.
+
+org.apache.olingo.odata2.api.exception.ODataForbiddenException.COMMON=Forbidden
+
+org.apache.olingo.odata2.api.exception.ODataNotFoundException.MATRIX=Matrix parameter '%1$s' with path segment '%2$s' not found!
+org.apache.olingo.odata2.api.exception.ODataNotFoundException.ENTITY=Requested entity could not be found.
+
+org.apache.olingo.odata2.api.exception.ODataMethodNotAllowedException.DISPATCH=The request dispatcher does not allow the HTTP method used for the request.
+
+org.apache.olingo.odata2.api.exception.ODataNotAcceptableException.COMMON=The request can not be accepted.
+org.apache.olingo.odata2.api.exception.ODataNotAcceptableException.NOT_SUPPORTED_CONTENT_TYPE=Content type '%1$s' is not supported.
+org.apache.olingo.odata2.api.exception.ODataNotAcceptableException.NOT_SUPPORTED_ACCEPT_HEADER=The accept header '%1$s' is not supported for this resource.
+
+org.apache.olingo.odata2.api.exception.ODataConflictException.COMMON=Conflict
+
+org.apache.olingo.odata2.api.exception.ODataPreconditionFailedException.COMMON=Precondition failed
+
+org.apache.olingo.odata2.api.exception.ODataUnsupportedMediaTypeException.NOT_SUPPORTED=Media type %1$s is not supported.
+org.apache.olingo.odata2.api.exception.ODataUnsupportedMediaTypeException.NOT_SUPPORTED_CONTENT_TYPE=Content type %1$s is not supported for this resource.
+org.apache.olingo.odata2.api.exception.ODataUnsupportedMediaTypeException.NOT_SUPPORTED_ACCEPT_HEADER=Accept header %1$s is not supported for this resource.
+
+org.apache.olingo.odata2.api.exception.ODataPreconditionRequiredException.COMMON=Precondition required
+
+org.apache.olingo.odata2.api.exception.ODataNotImplementedException.COMMON=Not implemented
+org.apache.olingo.odata2.api.exception.ODataNotImplementedException.TUNNELING=Method not recognized for X-HTTP-Method or X-HTTP-Method-Override header.
+
+org.apache.olingo.odata2.api.exception.ODataServiceUnavailableException.COMMON=Service Unavailable
+
+##################################
+# FilterParserExceptions
+##################################
+org.apache.olingo.odata2.api.uri.expression.ExceptionVisitExpression.COMMON=Error while traversing a ODATA expression tree.
+
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.COMMON=Error while parsing a ODATA expression.
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.INVALID_TRAILING_TOKEN_DETECTED_AFTER_PARSING=Invalid token "%1$s" detected after parsing at position %2$s in "%3$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.TOKEN_UNDETERMINATED_STRING=Unterminated string literal at position %1$s in "%2$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.INVALID_TYPES_FOR_BINARY_OPERATOR=Operator "%1$s" incompatible with operand types "%2$s" and "%3$s" at position %4$s in "%5$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.MISSING_CLOSING_PHARENTHESIS=Missing closing parenthesis ")" for opening parenthesis "(" at position %1$s in "%2$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.ERROR_IN_TOKENIZER=Error while tokenizing a ODATA expression on token "%1$s" at position %2$s in "%3$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.EXPRESSION_EXPECTED_AFTER_POS=Expression expected after position %1$s in "%2$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.COMMA_OR_END_EXPECTED_AT_POS=Comma or end of expression expected at position %1$s in "%2$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.EXPRESSION_EXPECTED_AT_POS=Expression expected at position %1$s in "%2$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.COMMA_OR_CLOSING_PHARENTHESIS_EXPECTED_AFTER_POS=")" or "," expected after position %1$s in "%2$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.INVALID_METHOD_CALL=Unknown function "%1$s" at position %2$s in "%3$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.METHOD_WRONG_ARG_EXACT=No applicable method found for "%1$s" at position %2$s in "%3$s" with the specified arguments. Method "%1$s" requires exact %4$s argument(s).
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.METHOD_WRONG_ARG_BETWEEN=No applicable method found for "%1$s" at position %2$s in "%3$s" with the specified arguments. Method "%1$s" requires between %4$s and %5$s arguments.
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.METHOD_WRONG_ARG_X_OR_MORE=No applicable method found for "%1$s" at position %2$s in "%3$s" with the specified arguments. Method "%1$s" requires %4$s or more arguments.
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.METHOD_WRONG_ARG_X_OR_LESS=No applicable method found for "%1$s" at position %2$s in "%3$s" with the specified arguments. Method "%1$s" requires maximal %4$s arguments.
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.METHOD_WRONG_INPUT_TYPE=No applicable method found for "%1$s" at position %2$s in "%3$s" for the specified argument types.
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.LEFT_SIDE_NOT_STRUCTURAL_TYPE=No property "%1$s" exists in type "%2$s" at position %3$s in "%4$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.LEFT_SIDE_NOT_A_PROPERTY=Leftside of method operator at position %1$s is not a property in "%2$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.PROPERTY_NAME_NOT_FOUND_IN_TYPE=No property "%1$s" exists in type "%2$s" at position %3$s in "%4$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.INVALID_SORT_ORDER=Invalid sort order in OData orderby parser at position %1$s in "%2$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.TYPE_EXPECTED_AT=Expression of type "%1$s" expected at position %2$s in "%3$s" (actual type is "%4$s").
+org.apache.olingo.odata2.core.uri.expression.ExpressionParserInternalError.ERROR_PARSING_METHOD=Internal error in OData filter parser while parsing a method expression.
+org.apache.olingo.odata2.core.uri.expression.ExpressionParserInternalError.ERROR_PARSING_PARENTHESIS=Internal error in OData filter parser while parsing a parenthesis expression.
+org.apache.olingo.odata2.core.uri.expression.ExpressionParserInternalError.ERROR_ACCESSING_EDM=Internal error in OData filter parser while accessing the EDM.
+org.apache.olingo.odata2.core.uri.expression.ExpressionParserInternalError.INVALID_TYPE_COUNT=Internal error in OData filter parser while validating the allowed types.
+org.apache.olingo.odata2.core.uri.expression.ExpressionParserInternalError.INVALID_TOKEN_AT =Expect token '%1$s', but invalid token '%2$s' detected at position '%3$s'.
+org.apache.olingo.odata2.core.uri.expression.ExpressionParserInternalError.INVALID_TOKENKIND_AT=Expect tokenkind '%1$s', but invalid tokenkind '%2$s'(with value:'%3$s' detected at position '%4$s'.
+
+org.apache.olingo.odata2.core.uri.expression.TokenizerExpectError.NO_TOKEN_AVAILABLE =Expect token %1$s, but no token left in token list.
+org.apache.olingo.odata2.core.uri.expression.TokenizerExpectError.INVALID_TOKEN_AT =Expect token '%1$s', but invalid token '%2$s' detected at position '%3$s'.
+org.apache.olingo.odata2.core.uri.expression.TokenizerExpectError.INVALID_TOKENKIND_AT =Expect tokenkind '%1$s', but invalid tokenkind '%2$s'(with value:'%3$s' detected at position '%4$s'.
+org.apache.olingo.odata2.core.uri.expression.TokenizerException.TYPEDECTECTION_FAILED_ON_STRING=Type detection error for string like token '%1$s' at position '%2$s'.
+org.apache.olingo.odata2.core.uri.expression.TokenizerException.TYPEDECTECTION_FAILED_ON_EDMTYPE=Type detection error for edmType like token '%1$s' at position '%2$s'.
+org.apache.olingo.odata2.core.uri.expression.TokenizerException.UNKNOWN_CHARACTER=Unknown character '%1$s' at position '%2$s' detected in "%3$s".
+
+#########################################
+# For testing
+# (please keep this inside this file and keep the english text in other languages)
+#########################################
+org.apache.olingo.odata2.testutil.mock.SampleClassForInvalidMessageReferences.EXIST=Exist
+#keep DOES_NOT_EXIST out commented
+#org.apache.olingo.odata2.testutil.mock.SampleClassForInvalidMessageReferences.DOES_NOT_EXIST=Does not exist
+#keep EXITS_BUT_EMPTY text empty
+org.apache.olingo.odata2.testutil.mock.SampleClassForInvalidMessageReferences.EXITS_BUT_EMPTY=
+
+
+
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/resources/i18n_de.properties
----------------------------------------------------------------------
diff --git a/odata-core/src/main/resources/i18n_de.properties b/odata-core/src/main/resources/i18n_de.properties
new file mode 100644
index 0000000..f34cea7
--- /dev/null
+++ b/odata-core/src/main/resources/i18n_de.properties
@@ -0,0 +1,23 @@
+#-------------------------------------------------------------------------------
+# 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.
+#-------------------------------------------------------------------------------
+# German translations
+#
+org.apache.olingo.odata2.api.exception.ODataMessageException.COMMON=Allgemeiner Fehler
+
+org.apache.olingo.odata2.api.exception.ODataNotFoundException.ENTITY=Die angefragte Entit\u00e4t wurde nicht gefunden.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/resources/i18n_de_DE.properties
----------------------------------------------------------------------
diff --git a/odata-core/src/main/resources/i18n_de_DE.properties b/odata-core/src/main/resources/i18n_de_DE.properties
new file mode 100644
index 0000000..ac6c760
--- /dev/null
+++ b/odata-core/src/main/resources/i18n_de_DE.properties
@@ -0,0 +1,21 @@
+#-------------------------------------------------------------------------------
+# 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.
+#-------------------------------------------------------------------------------
+# German translations
+#
+org.apache.olingo.odata2.api.exception.ODataMessageException.COMMON=Allgemeiner Fehler