From 670c71ce1fca3732476ebdd7b1e07d6790548efe Mon Sep 17 00:00:00 2001 From: iegoshin Date: Tue, 13 Oct 2020 10:08:09 -0500 Subject: [PATCH 01/28] bug fix: error code and message not parsed. e.g or raw response: { "code": 400, "message": "Replication requests to the PropertyLand resource can only be filtered using the following fields: MlgCanView, ModificationTimestamp, OriginatingSystemName, StandardStatus, ListingId", "target": "query", "details": [] } --- .../JsonODataErrorDeserializer.java | 125 ++++++++++++------ .../apache/olingo/client/core/EntityTest.java | 2 +- 2 files changed, 82 insertions(+), 45 deletions(-) diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonODataErrorDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonODataErrorDeserializer.java index 2584db9abc..9a0e9ecf96 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonODataErrorDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonODataErrorDeserializer.java @@ -34,54 +34,91 @@ public class JsonODataErrorDeserializer extends JsonDeserializer { - public JsonODataErrorDeserializer(final boolean serverMode) { - super(serverMode); - } + public JsonODataErrorDeserializer(final boolean serverMode) { + super(serverMode); + } - protected ODataError doDeserialize(final JsonParser parser) throws IOException { + protected ODataError doDeserialize(final JsonParser parser) throws IOException { - final ODataError error = new ODataError(); + final ODataError error = new ODataError(); - final ObjectNode tree = parser.getCodec().readTree(parser); - if (tree.has(Constants.JSON_ERROR)) { - final JsonNode errorNode = tree.get(Constants.JSON_ERROR); + final ObjectNode tree = parser.getCodec().readTree(parser); + if (tree.has(Constants.JSON_ERROR)) { + final JsonNode errorNode = tree.get(Constants.JSON_ERROR); - if (errorNode.has(Constants.ERROR_CODE)) { - error.setCode(errorNode.get(Constants.ERROR_CODE).textValue()); - } - if (errorNode.has(Constants.ERROR_MESSAGE)) { - final JsonNode message = errorNode.get(Constants.ERROR_MESSAGE); - if (message.isValueNode()) { - error.setMessage(message.textValue()); - } else if (message.isObject()) { - error.setMessage(message.get(Constants.VALUE).asText()); - } - } - if (errorNode.has(Constants.ERROR_TARGET)) { - error.setTarget(errorNode.get(Constants.ERROR_TARGET).textValue()); - } - if (errorNode.hasNonNull(Constants.ERROR_DETAILS)) { - List details = new ArrayList<>(); - JsonODataErrorDetailDeserializer detailDeserializer = new JsonODataErrorDetailDeserializer(serverMode); - for (JsonNode jsonNode : errorNode.get(Constants.ERROR_DETAILS)) { - details.add(detailDeserializer.doDeserialize(jsonNode.traverse(parser.getCodec())) - .getPayload()); - } + if (errorNode.has(Constants.ERROR_CODE)) { + error.setCode(errorNode.get(Constants.ERROR_CODE).textValue()); + } + if (errorNode.has(Constants.ERROR_MESSAGE)) { + final JsonNode message = errorNode.get(Constants.ERROR_MESSAGE); + if (message.isValueNode()) { + error.setMessage(message.textValue()); + } else if (message.isObject()) { + error.setMessage(message.get(Constants.VALUE).asText()); + } + } + if (errorNode.has(Constants.ERROR_TARGET)) { + error.setTarget(errorNode.get(Constants.ERROR_TARGET).textValue()); + } + if (errorNode.hasNonNull(Constants.ERROR_DETAILS)) { + List details = new ArrayList<>(); + JsonODataErrorDetailDeserializer detailDeserializer = + new JsonODataErrorDetailDeserializer(serverMode); + for (JsonNode jsonNode : errorNode.get(Constants.ERROR_DETAILS)) { + details.add(detailDeserializer.doDeserialize( + jsonNode.traverse(parser.getCodec())).getPayload()); + } - error.setDetails(details); - } - if (errorNode.hasNonNull(Constants.ERROR_INNERERROR)) { - HashMap innerErrorMap = new HashMap<>(); - final JsonNode innerError = errorNode.get(Constants.ERROR_INNERERROR); - for (final Iterator itor = innerError.fieldNames(); itor.hasNext();) { - final String keyTmp = itor.next(); - final String val = innerError.get(keyTmp).toString(); - innerErrorMap.put(keyTmp, val); - } - error.setInnerError(innerErrorMap); - } - } + error.setDetails(details); + } + if (errorNode.hasNonNull(Constants.ERROR_INNERERROR)) { + HashMap innerErrorMap = new HashMap<>(); + final JsonNode innerError = errorNode.get(Constants.ERROR_INNERERROR); + for (final Iterator itor = innerError.fieldNames(); itor.hasNext();) { + final String keyTmp = itor.next(); + final String val = innerError.get(keyTmp).toString(); + innerErrorMap.put(keyTmp, val); + } + error.setInnerError(innerErrorMap); + } + } else if (tree.has(Constants.ERROR_CODE)) { + if (tree.has(Constants.ERROR_CODE)) { + error.setCode(tree.get(Constants.ERROR_CODE).textValue()); + } + if (tree.has(Constants.ERROR_MESSAGE)) { + final JsonNode message = tree.get(Constants.ERROR_MESSAGE); + if (message.isValueNode()) { + error.setMessage(message.textValue()); + } else if (message.isObject()) { + error.setMessage(message.get(Constants.VALUE).asText()); + } + } + if (tree.has(Constants.ERROR_TARGET)) { + error.setTarget(tree.get(Constants.ERROR_TARGET).textValue()); + } + if (tree.hasNonNull(Constants.ERROR_DETAILS)) { + List details = new ArrayList<>(); + JsonODataErrorDetailDeserializer detailDeserializer = + new JsonODataErrorDetailDeserializer(serverMode); + for (JsonNode jsonNode : tree.get(Constants.ERROR_DETAILS)) { + details.add(detailDeserializer.doDeserialize( + jsonNode.traverse(parser.getCodec())).getPayload()); + } - return error; - } + error.setDetails(details); + } + if (tree.hasNonNull(Constants.ERROR_INNERERROR)) { + HashMap innerErrorMap = new HashMap<>(); + final JsonNode innerError = tree.get(Constants.ERROR_INNERERROR); + for (final Iterator itor = innerError.fieldNames(); itor.hasNext();) { + final String keyTmp = itor.next(); + final String val = innerError.get(keyTmp).toString(); + innerErrorMap.put(keyTmp, val); + } + error.setInnerError(innerErrorMap); + } + } + + return error; + } } diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/EntityTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/EntityTest.java index bc08918e69..e61251ebc4 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/EntityTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/EntityTest.java @@ -363,7 +363,7 @@ private void annotated(final ContentType contentType) throws EdmPrimitiveTypeExc assertEquals("com.contoso.display.styleType", annotation.getValue().getTypeName()); assertTrue(annotation.hasComplexValue()); assertEquals(2, - annotation.getValue().asComplex().get("order").getPrimitiveValue().toCastValue(Integer.class), 0); + annotation.getValue().asComplex().get("order").getPrimitiveValue().toCastValue(Integer.class).intValue(), 0); final ClientEntity written = client.getBinder().getODataEntity( new ResWrap((URI) null, null, client.getBinder().getEntity(entity))); From 6d292e2117c8728856a0b74bc399a4f1eba98b3e Mon Sep 17 00:00:00 2001 From: iegoshin Date: Mon, 2 Nov 2020 15:17:54 -0600 Subject: [PATCH 02/28] bug fix: null pointer exception on parsing a null value for enum type, e.g. "StreetDirPrefix": null --- .../olingo/client/core/serialization/ODataBinderImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java index dfd3d41a0e..ce3d0a709b 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java @@ -851,8 +851,9 @@ protected ClientValue getODataValue(FullQualifiedName type, value.asCollection().add(getODataValue(type, fake, contextURL, metadataETag)); } } else if (valuable.isEnum()) { + Object enumValue = valuable.asEnum(); value = client.getObjectFactory().newEnumValue(type == null ? null : type.toString(), - valuable.asEnum().toString()); + enumValue==null? null: enumValue.toString()); } else if (valuable.isComplex()) { final ClientComplexValue lcValue = client.getObjectFactory().newComplexValue(type == null ? null : type.toString()); From 029952f71b5a4b2509afacdecafe5515c76d338a Mon Sep 17 00:00:00 2001 From: iegoshin Date: Mon, 2 Nov 2020 15:55:55 -0600 Subject: [PATCH 03/28] bug fix: EdmPropertyImpl is throwing EdmException "Cannot find type with name: " when enumeration is missing in the metadata --- .../java/org/apache/olingo/commons/core/edm/EdmTypeInfo.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeInfo.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeInfo.java index f886c84089..4109a64fe3 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeInfo.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeInfo.java @@ -128,6 +128,9 @@ private EdmTypeInfo(final Edm edm, final String typeExpression, final boolean in } } } + if (primitiveType==null && enumType==null && complexType==null && entityType==null) { + primitiveType = EdmPrimitiveTypeKind.String; + } } public String internal() { From 762736e47d884b8226fdc158b12e09eed32a5e27 Mon Sep 17 00:00:00 2001 From: iegoshin Date: Mon, 2 Nov 2020 16:01:37 -0600 Subject: [PATCH 04/28] bug fix: missed typeDefinition in the previous bug fix --- .../java/org/apache/olingo/commons/core/edm/EdmTypeInfo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeInfo.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeInfo.java index 4109a64fe3..2d38b2949e 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeInfo.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmTypeInfo.java @@ -128,7 +128,7 @@ private EdmTypeInfo(final Edm edm, final String typeExpression, final boolean in } } } - if (primitiveType==null && enumType==null && complexType==null && entityType==null) { + if (primitiveType==null && typeDefinition==null && enumType==null && complexType==null && entityType==null) { primitiveType = EdmPrimitiveTypeKind.String; } } From b85510d6c1fe101f772ec6bc654757f4fa318c45 Mon Sep 17 00:00:00 2001 From: iegoshin Date: Thu, 18 Mar 2021 09:55:13 -0500 Subject: [PATCH 05/28] supressing nonsense exceptions --- .../olingo/client/core/domain/ClientPrimitiveValueImpl.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPrimitiveValueImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPrimitiveValueImpl.java index 4824632bdb..a8590a73c6 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPrimitiveValueImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPrimitiveValueImpl.java @@ -56,7 +56,8 @@ public BuilderImpl setType(final EdmType type) { @Override public BuilderImpl setType(final EdmPrimitiveTypeKind type) { - if (type == EdmPrimitiveTypeKind.Stream) { + // Ilya: throwing these exceptions from here doesn't make sense + /*if (type == EdmPrimitiveTypeKind.Stream) { throw new IllegalArgumentException(String.format( "Cannot build a primitive value for %s", EdmPrimitiveTypeKind.Stream.toString())); } @@ -66,7 +67,7 @@ public BuilderImpl setType(final EdmPrimitiveTypeKind type) { + "An entity can declare a property to be of type Geometry. " + "An instance of an entity MUST NOT have a value of type Geometry. " + "Each value MUST be of some subtype."); - } + }*/ instance.typeKind = type == null ? EdmPrimitiveTypeKind.String : type; instance.type = EdmPrimitiveTypeFactory.getInstance(instance.typeKind); From 73d10a738e3b5da5c7416f6205b46d379c5bff19 Mon Sep 17 00:00:00 2001 From: iegoshin Date: Thu, 18 Mar 2021 10:23:58 -0500 Subject: [PATCH 06/28] commented out buggy plugin --- lib/server-tecsvc/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/server-tecsvc/pom.xml b/lib/server-tecsvc/pom.xml index 8955382298..4036bea0fc 100644 --- a/lib/server-tecsvc/pom.xml +++ b/lib/server-tecsvc/pom.xml @@ -97,7 +97,7 @@ - + From bde075274b5e4942ea574e321a6fe84ca09fc4b9 Mon Sep 17 00:00:00 2001 From: iegoshin Date: Thu, 18 Mar 2021 10:29:13 -0500 Subject: [PATCH 07/28] test --- lib/client-core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/client-core/pom.xml b/lib/client-core/pom.xml index bd665e7d2c..3058571a99 100644 --- a/lib/client-core/pom.xml +++ b/lib/client-core/pom.xml @@ -32,7 +32,7 @@ odata-lib 4.8.0-SNAPSHOT .. - + From 04a36e4ac9874d29cdfc16c90dd46642c1cc7812 Mon Sep 17 00:00:00 2001 From: iegoshin Date: Thu, 18 Mar 2021 10:29:44 -0500 Subject: [PATCH 08/28] test --- lib/client-core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/client-core/pom.xml b/lib/client-core/pom.xml index 3058571a99..bd665e7d2c 100644 --- a/lib/client-core/pom.xml +++ b/lib/client-core/pom.xml @@ -32,7 +32,7 @@ odata-lib 4.8.0-SNAPSHOT .. - + From 66da9c953486cad78ff89c330126983cc489c700 Mon Sep 17 00:00:00 2001 From: iegoshin Date: Wed, 23 Feb 2022 11:22:40 -0600 Subject: [PATCH 09/28] Update EdmAnnotation.java EdmAnnotation.getTermAsString() --- .../java/org/apache/olingo/commons/api/edm/EdmAnnotation.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmAnnotation.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmAnnotation.java index 7ebeeee4de..3487790449 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmAnnotation.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmAnnotation.java @@ -25,6 +25,8 @@ */ public interface EdmAnnotation extends EdmAnnotatable { + String getTermAsString(); + /** * @return the term of this annotation */ From ae4bf9d4eca92a4b14f60c845fcee816934f4314 Mon Sep 17 00:00:00 2001 From: iegoshin Date: Wed, 23 Feb 2022 11:23:46 -0600 Subject: [PATCH 10/28] Update EdmAnnotationImpl.java EdmAnnotationImpl.getTermAsString() --- .../apache/olingo/commons/core/edm/EdmAnnotationImpl.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmAnnotationImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmAnnotationImpl.java index c4ab9107e5..b44ed3ee39 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmAnnotationImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmAnnotationImpl.java @@ -38,6 +38,11 @@ public EdmAnnotationImpl(final Edm edm, final CsdlAnnotation annotation) { this.annotation = annotation; } + @Override + public String getTermAsString() { + return annotation.getTerm(); + } + @Override public EdmTerm getTerm() { if (term == null) { From a902d4b7f6894898ba85a357c8ac891098eb1609 Mon Sep 17 00:00:00 2001 From: Ilya Egoshin Date: Tue, 19 Nov 2024 13:03:20 -0600 Subject: [PATCH 11/28] ignore missing @odata.nextLink; update version; disable unnecessary sub-projects --- lib/client-api/pom.xml | 2 +- lib/client-core/pom.xml | 2 +- .../olingo/client/core/serialization/ODataBinderImpl.java | 3 +++ lib/commons-api/pom.xml | 2 +- lib/commons-core/pom.xml | 2 +- lib/pom.xml | 7 +------ pom.xml | 2 +- 7 files changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/client-api/pom.xml b/lib/client-api/pom.xml index 30cf83010f..a592b444f3 100644 --- a/lib/client-api/pom.xml +++ b/lib/client-api/pom.xml @@ -30,7 +30,7 @@ org.apache.olingo odata-lib - 4.8.0-SNAPSHOT + 4.8.1-SNAPSHOT .. diff --git a/lib/client-core/pom.xml b/lib/client-core/pom.xml index bd665e7d2c..403b34db59 100644 --- a/lib/client-core/pom.xml +++ b/lib/client-core/pom.xml @@ -30,7 +30,7 @@ org.apache.olingo odata-lib - 4.8.0-SNAPSHOT + 4.8.1-SNAPSHOT .. diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java index ce3d0a709b..4b9d131d49 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java @@ -442,6 +442,9 @@ protected void odataNavigationLinks(final EdmType edmType, final Linked linked, final ClientLinked odataLinked, final String metadataETag, final URI base) { for (Link link : linked.getNavigationLinks()) { final String href = link.getHref(); + if (href==null) { + continue; // @odata.nextLink is missing, ignore. + } final String title = link.getTitle(); final Entity inlineEntity = link.getInlineEntity(); final EntityCollection inlineEntitySet = link.getInlineEntitySet(); diff --git a/lib/commons-api/pom.xml b/lib/commons-api/pom.xml index 70a4e5af76..100b405390 100644 --- a/lib/commons-api/pom.xml +++ b/lib/commons-api/pom.xml @@ -30,7 +30,7 @@ org.apache.olingo odata-lib - 4.8.0-SNAPSHOT + 4.8.1-SNAPSHOT .. diff --git a/lib/commons-core/pom.xml b/lib/commons-core/pom.xml index a77fd852e0..59eefc9b88 100644 --- a/lib/commons-core/pom.xml +++ b/lib/commons-core/pom.xml @@ -30,7 +30,7 @@ org.apache.olingo odata-lib - 4.8.0-SNAPSHOT + 4.8.1-SNAPSHOT .. diff --git a/lib/pom.xml b/lib/pom.xml index b3b675dffa..129f1e42f8 100644 --- a/lib/pom.xml +++ b/lib/pom.xml @@ -30,7 +30,7 @@ org.apache.olingo odata-parent - 4.8.0-SNAPSHOT + 4.8.1-SNAPSHOT .. @@ -39,11 +39,6 @@ commons-core client-api client-core - server-api - server-core - server-core-ext - server-tecsvc - server-test diff --git a/pom.xml b/pom.xml index e16eaf1341..d64a436799 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ org.apache.olingo odata-parent - 4.8.0-SNAPSHOT + 4.8.1-SNAPSHOT pom Olingo-OData From 6db925c533bc4a24e33f84586c44e4d6636d7e25 Mon Sep 17 00:00:00 2001 From: Ilya Egoshin Date: Tue, 19 Nov 2024 13:14:08 -0600 Subject: [PATCH 12/28] test --- lib/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pom.xml b/lib/pom.xml index 129f1e42f8..6860aa984b 100644 --- a/lib/pom.xml +++ b/lib/pom.xml @@ -18,6 +18,7 @@ specific language governing permissions and limitations under the License. + --> From 601cf3fbc87654bbe35c659fa7fece0973b455b4 Mon Sep 17 00:00:00 2001 From: Ilya Egoshin Date: Tue, 19 Nov 2024 13:14:51 -0600 Subject: [PATCH 13/28] test --- lib/pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/pom.xml b/lib/pom.xml index 6860aa984b..129f1e42f8 100644 --- a/lib/pom.xml +++ b/lib/pom.xml @@ -18,7 +18,6 @@ specific language governing permissions and limitations under the License. - --> From 926ce7f9a237c0c889c9173edbc918429fc10a3b Mon Sep 17 00:00:00 2001 From: Ilya Egoshin Date: Thu, 3 Apr 2025 17:13:03 -0500 Subject: [PATCH 14/28] bug fix for nested value: "@odata.associationLink": { "@odata.associationLink": "https://api-trestle.corelogic.com/trestle/odata/Property('554256689')/Media/$ref" } --- .../client/core/serialization/JsonDeserializer.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonDeserializer.java index efd2963f66..d53219c91c 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonDeserializer.java @@ -155,7 +155,17 @@ private void clientLinks(final Map.Entry field, final Linked l final Link link = new Link(); link.setTitle(getTitle(field)); link.setRel(Constants.NS_ASSOCIATION_LINK_REL + getTitle(field)); - link.setHref(field.getValue().textValue()); + if (field.getValue() instanceof ObjectNode) { + ObjectNode values = (ObjectNode)field.getValue(); + JsonNode value = values.findValue(Constants.JSON_ASSOCIATION_LINK); + if (value!=null) { + link.setHref(value.textValue()); + } else { + link.setHref(field.getValue().textValue()); + } + } else { + link.setHref(field.getValue().textValue()); + } link.setType(Constants.ASSOCIATION_LINK_TYPE); linked.getAssociationLinks().add(link); From 7d485580cd32f5a77c368e6c24fbbd024991b2b8 Mon Sep 17 00:00:00 2001 From: Ilya Egoshin Date: Fri, 23 May 2025 10:07:19 -0500 Subject: [PATCH 15/28] fixing broken nextLink --- .../JsonEntitySetDeserializer.java | 41 ++++++++++++++++--- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetDeserializer.java index 765905558d..fd881d4424 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetDeserializer.java @@ -20,6 +20,8 @@ import java.io.IOException; import java.net.URI; +import java.net.URL; +import java.net.URLEncoder; import java.util.HashSet; import java.util.Iterator; import java.util.Map; @@ -60,16 +62,16 @@ protected ResWrap doDeserialize(final JsonParser parser) throw URI contextURL; if (tree.hasNonNull(Constants.JSON_CONTEXT)) { - contextURL = URI.create(tree.get(Constants.JSON_CONTEXT).textValue()); + contextURL = getUri(tree.get(Constants.JSON_CONTEXT).textValue()); tree.remove(Constants.JSON_CONTEXT); } else if (tree.hasNonNull(Constants.JSON_METADATA)) { - contextURL = URI.create(tree.get(Constants.JSON_METADATA).textValue()); + contextURL = getUri(tree.get(Constants.JSON_METADATA).textValue()); tree.remove(Constants.JSON_METADATA); } else { contextURL = null; } if (contextURL != null) { - entitySet.setBaseURI(URI.create(StringUtils.substringBefore(contextURL.toASCIIString(), Constants.METADATA))); + entitySet.setBaseURI(getUri(StringUtils.substringBefore(contextURL.toASCIIString(), Constants.METADATA))); } final String metadataETag; @@ -85,11 +87,11 @@ protected ResWrap doDeserialize(final JsonParser parser) throw tree.remove(Constants.JSON_COUNT); } if (tree.hasNonNull(Constants.JSON_NEXT_LINK)) { - entitySet.setNext(URI.create(tree.get(Constants.JSON_NEXT_LINK).textValue())); + entitySet.setNext(getUri(tree.get(Constants.JSON_NEXT_LINK).textValue())); tree.remove(Constants.JSON_NEXT_LINK); } if (tree.hasNonNull(Constants.JSON_DELTA_LINK)) { - entitySet.setDeltaLink(URI.create(tree.get(Constants.JSON_DELTA_LINK).textValue())); + entitySet.setDeltaLink(getUri(tree.get(Constants.JSON_DELTA_LINK).textValue())); tree.remove(Constants.JSON_DELTA_LINK); } @@ -121,7 +123,7 @@ protected ResWrap doDeserialize(final JsonParser parser) throw final ObjectNode opNode = (ObjectNode) tree.get(field.getKey()); operation.setTitle(opNode.get(Constants.ATTR_TITLE).asText()); - operation.setTarget(URI.create(opNode.get(Constants.ATTR_TARGET).asText())); + operation.setTarget(getUri(opNode.get(Constants.ATTR_TARGET).asText())); entitySet.getOperations().add(operation); toRemove.add(field.getKey()); } @@ -129,4 +131,31 @@ protected ResWrap doDeserialize(final JsonParser parser) throw tree.remove(toRemove); return new ResWrap<>(contextURL, metadataETag, entitySet); } + + private URI getUri(String str) throws IOException { + if (StringUtils.containsAny(str, " $()")) { + URL url = new URL(str); + String baseUrl = url.getProtocol() + "://" + url.getHost() + url.getPath(); + String query = url.getQuery(); + StringBuilder fixedQuery = new StringBuilder(); + for (String param : query.split("&")) { + int idx = param.indexOf('='); + if (idx > 0) { + String key = param.substring(0, idx); + String value = param.substring(idx + 1); + if (!StringUtils.startsWith( key, "$" )) + key = "$"+key; + String encodedKey = URLEncoder.encode(key, "UTF-8").replace("+", "%20"); + String encodedValue = URLEncoder.encode(value, "UTF-8").replace("+", "%20"); + if (fixedQuery.length() > 0) + fixedQuery.append("&"); + fixedQuery.append(encodedKey).append("=").append(encodedValue); + } else { + fixedQuery.append(URLEncoder.encode(param, "UTF-8")); + } + } + str = baseUrl + "?" + fixedQuery; + } + return URI.create(str); + } } From 4f4a9d61afe2074c1df6a5e710b5aabf01241066 Mon Sep 17 00:00:00 2001 From: Ilya Egoshin Date: Fri, 23 May 2025 10:16:29 -0500 Subject: [PATCH 16/28] source format fix --- .../core/serialization/JsonEntitySetDeserializer.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetDeserializer.java index fd881d4424..a65c72c954 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetDeserializer.java @@ -143,12 +143,14 @@ private URI getUri(String str) throws IOException { if (idx > 0) { String key = param.substring(0, idx); String value = param.substring(idx + 1); - if (!StringUtils.startsWith( key, "$" )) + if (!StringUtils.startsWith( key, "$" )) { key = "$"+key; + } String encodedKey = URLEncoder.encode(key, "UTF-8").replace("+", "%20"); String encodedValue = URLEncoder.encode(value, "UTF-8").replace("+", "%20"); - if (fixedQuery.length() > 0) + if (fixedQuery.length() > 0) { fixedQuery.append("&"); + } fixedQuery.append(encodedKey).append("=").append(encodedValue); } else { fixedQuery.append(URLEncoder.encode(param, "UTF-8")); From 97e2e066880accd1f1802cec9482ea5e7b6db03d Mon Sep 17 00:00:00 2001 From: Ilya Egoshin Date: Fri, 23 May 2025 11:05:35 -0500 Subject: [PATCH 17/28] url normalization --- .../JsonEntitySetDeserializer.java | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetDeserializer.java index a65c72c954..0810fa9e6e 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetDeserializer.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.net.URI; import java.net.URL; +import java.net.URLDecoder; import java.net.URLEncoder; import java.util.HashSet; import java.util.Iterator; @@ -133,31 +134,51 @@ protected ResWrap doDeserialize(final JsonParser parser) throw } private URI getUri(String str) throws IOException { - if (StringUtils.containsAny(str, " $()")) { + try { URL url = new URL(str); - String baseUrl = url.getProtocol() + "://" + url.getHost() + url.getPath(); + String scheme = url.getProtocol(); + String host = url.getHost(); + int port = url.getPort(); + String path = url.getPath(); + String baseUrl = scheme + "://" + host + (port != -1 ? ":" + port : "") + path; String query = url.getQuery(); + + if (query == null || query.isEmpty()) { + return URI.create(baseUrl); + } + StringBuilder fixedQuery = new StringBuilder(); for (String param : query.split("&")) { int idx = param.indexOf('='); if (idx > 0) { String key = param.substring(0, idx); String value = param.substring(idx + 1); - if (!StringUtils.startsWith( key, "$" )) { - key = "$"+key; + + key = URLDecoder.decode(key, "UTF-8"); + value = URLDecoder.decode(value, "UTF-8"); + + if (!key.startsWith("$")) { + key = "$" + key; } + String encodedKey = URLEncoder.encode(key, "UTF-8").replace("+", "%20"); String encodedValue = URLEncoder.encode(value, "UTF-8").replace("+", "%20"); + if (fixedQuery.length() > 0) { fixedQuery.append("&"); } + fixedQuery.append(encodedKey).append("=").append(encodedValue); } else { - fixedQuery.append(URLEncoder.encode(param, "UTF-8")); + String decoded = URLDecoder.decode(param, "UTF-8"); + fixedQuery.append(URLEncoder.encode(decoded, "UTF-8").replace("+", "%20")); } } - str = baseUrl + "?" + fixedQuery; + + return new URI(baseUrl + "?" + fixedQuery); + + } catch (Exception e) { + throw new IOException("Failed to normalize URI: " + str, e); } - return URI.create(str); } } From 8b8b05d1764e1b31e3f7f976c31781a3467be6bd Mon Sep 17 00:00:00 2001 From: Ilya Egoshin Date: Mon, 26 May 2025 11:34:54 -0500 Subject: [PATCH 18/28] bug fix: anchor is missing in URL --- .../core/serialization/JsonEntitySetDeserializer.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetDeserializer.java index 0810fa9e6e..0169a1aedf 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonEntitySetDeserializer.java @@ -142,9 +142,10 @@ private URI getUri(String str) throws IOException { String path = url.getPath(); String baseUrl = scheme + "://" + host + (port != -1 ? ":" + port : "") + path; String query = url.getQuery(); + String anchor = StringUtils.substringAfterLast(str, "#"); if (query == null || query.isEmpty()) { - return URI.create(baseUrl); + return URI.create(str); } StringBuilder fixedQuery = new StringBuilder(); @@ -174,6 +175,12 @@ private URI getUri(String str) throws IOException { fixedQuery.append(URLEncoder.encode(decoded, "UTF-8").replace("+", "%20")); } } + + if (StringUtils.isNotBlank(anchor)) { + anchor = URLDecoder.decode(anchor, "UTF-8"); + String encodedAnchor = URLEncoder.encode(anchor, "UTF-8").replace("+", "%20"); + fixedQuery.append("#").append(encodedAnchor); + } return new URI(baseUrl + "?" + fixedQuery); From e86563fa5fef498ab74ca9af1b77fcde7398dd79 Mon Sep 17 00:00:00 2001 From: Ilya Egoshin Date: Thu, 21 Aug 2025 08:20:12 -0500 Subject: [PATCH 19/28] small fix for EdmBoolean --- .../olingo/commons/core/edm/primitivetype/EdmBoolean.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmBoolean.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmBoolean.java index 6c5ec9f0f4..116039fef0 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmBoolean.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmBoolean.java @@ -45,7 +45,7 @@ public boolean validate(final String value, } private static boolean validateLiteral(final String value) { - return "true".equals(value) || "false".equals(value); + return "true".equals(value) || "false".equals(value) || "1".equals(value) || "0".equals(value); } @Override @@ -55,7 +55,7 @@ protected T internalValueOfString(final String value, if (validateLiteral(value)) { if (returnType.isAssignableFrom(Boolean.class)) { - return returnType.cast(Boolean.valueOf("true".equals(value))); + return returnType.cast(Boolean.valueOf("true".equals(value) || "1".equals(value))); } else { throw new EdmPrimitiveTypeException("The value type " + returnType + " is not supported."); } From 32ae8bf9268eb70c5aed01e93fb316d44646df15 Mon Sep 17 00:00:00 2001 From: Ilya Egoshin Date: Thu, 21 Aug 2025 10:54:52 -0500 Subject: [PATCH 20/28] bug fix: exception on empty value for timestamp field --- .../commons/core/edm/primitivetype/EdmDateTimeOffset.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java index 0280c5ff09..f44bc3dcd4 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java @@ -60,6 +60,9 @@ public Class getDefaultType() { protected T internalValueOfString(final String value, final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale, final Boolean isUnicode, final Class returnType) throws EdmPrimitiveTypeException { + if (value==null || "".equals(value)) { + return null; + } try { ZonedDateTime zdt = parseZonedDateTime(value); From 33a0b0b76821c4ec1b457ccbda469c606924b9e9 Mon Sep 17 00:00:00 2001 From: Ilya Egoshin Date: Thu, 21 Aug 2025 13:37:08 -0500 Subject: [PATCH 21/28] allow to parse just date without the time and zone --- .../edm/primitivetype/EdmDateTimeOffset.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java index f44bc3dcd4..d90bdf1994 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java @@ -20,6 +20,7 @@ import java.sql.Timestamp; import java.time.Instant; +import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZoneOffset; @@ -80,12 +81,18 @@ private static ZonedDateTime parseZonedDateTime(final String value) { // ISO-8601 conform pattern zdt = ZonedDateTime.parse(value); } catch (DateTimeParseException ex) { - // for backward compatibility - allow patterns that don't specify a time zone - final Matcher matcher = PATTERN.matcher(value); - if (matcher.matches() && matcher.group(9) == null) { - zdt = ZonedDateTime.parse(value + "Z"); - } else { - throw ex; + try { + LocalDate ld = LocalDate.parse(value, DateTimeFormatter.ISO_LOCAL_DATE); + // start of day in UTC + zdt = ld.atStartOfDay(ZoneOffset.UTC); + } catch (DateTimeParseException e2) { + // for backward compatibility - allow patterns that don't specify a time zone + final Matcher matcher = PATTERN.matcher(value); + if (matcher.matches() && matcher.group(9) == null) { + zdt = ZonedDateTime.parse(value + "Z"); + } else { + throw ex; + } } } return zdt; From 8cc89d7f58c9a8ff332b4025010fd7ec8ddd2c60 Mon Sep 17 00:00:00 2001 From: Ilya Egoshin Date: Fri, 27 Mar 2026 09:38:13 -0500 Subject: [PATCH 22/28] helper methods for Property Searchable annotations --- .../commons/api/edm/EdmAnnotatable.java | 2 ++ .../olingo/commons/api/edm/EdmAnnotation.java | 2 ++ .../core/edm/AbstractEdmAnnotatable.java | 10 ++++++++++ .../commons/core/edm/EdmAnnotationImpl.java | 11 ++++++++++ ...stractEdmAnnotatableDynamicExpression.java | 5 +++++ pom.xml | 20 +++++++++++++++++++ 6 files changed, 50 insertions(+) diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmAnnotatable.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmAnnotatable.java index a73659b4c1..6acf41d480 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmAnnotatable.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmAnnotatable.java @@ -38,4 +38,6 @@ public interface EdmAnnotatable { * @return list of all annotations */ List getAnnotations(); + + EdmAnnotation getAnnotation(String termName); } diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmAnnotation.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmAnnotation.java index 3487790449..5c0731df9e 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmAnnotation.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmAnnotation.java @@ -38,4 +38,6 @@ public interface EdmAnnotation extends EdmAnnotatable { String getQualifier(); EdmExpression getExpression(); + + String getExpressionAsString(); } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmAnnotatable.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmAnnotatable.java index 858203020e..88c8795034 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmAnnotatable.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdmAnnotatable.java @@ -58,6 +58,16 @@ private boolean qualifierEqual(String qualifier, String annotationQualifier) { || (qualifier != null && qualifier.equals(annotationQualifier)); } + @Override + public EdmAnnotation getAnnotation(final String termName) { + for (EdmAnnotation annotation : getAnnotations()) { + if (termName.equals(annotation.getTermAsString())) { + return annotation; + } + } + return null; + } + @Override public List getAnnotations() { if (annotations == null) { diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmAnnotationImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmAnnotationImpl.java index b44ed3ee39..117abda59c 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmAnnotationImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmAnnotationImpl.java @@ -25,6 +25,8 @@ import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.edm.annotation.EdmExpression; import org.apache.olingo.commons.api.edm.provider.CsdlAnnotation; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlConstantExpression; +import org.apache.olingo.commons.api.edm.provider.annotation.CsdlExpression; import org.apache.olingo.commons.core.edm.annotation.AbstractEdmExpression; public class EdmAnnotationImpl extends AbstractEdmAnnotatable implements EdmAnnotation { @@ -68,4 +70,13 @@ public EdmExpression getExpression() { } return expression; } + + @Override + public String getExpressionAsString() { + CsdlExpression expr = annotation.getExpression(); + if (expr instanceof CsdlConstantExpression) { + return ((CsdlConstantExpression) expr).getValue(); + } + return null; + } } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/annotation/AbstractEdmAnnotatableDynamicExpression.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/annotation/AbstractEdmAnnotatableDynamicExpression.java index 5ac562ba27..8cc2af06c1 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/annotation/AbstractEdmAnnotatableDynamicExpression.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/annotation/AbstractEdmAnnotatableDynamicExpression.java @@ -47,6 +47,11 @@ public List getAnnotations() { return helper.getAnnotations(); } + @Override + public EdmAnnotation getAnnotation(final String termName) { + return helper.getAnnotation(termName); + } + private class AnnotationHelper extends AbstractEdmAnnotatable { public AnnotationHelper(Edm edm, CsdlAnnotatable annotatable) { diff --git a/pom.xml b/pom.xml index d64a436799..8ccecaa25c 100644 --- a/pom.xml +++ b/pom.xml @@ -310,6 +310,13 @@ + + + org.apache.maven.wagon + wagon-ssh + 3.5.1 + + ${project.name}-${project.version} @@ -661,4 +668,17 @@ + + + + mrp + MRP Repo + scp://mavenrepo.myrealpage.com:/data/vol2/sites/mavenrepo.myrealpage.com/m2/repo + + + mrp + MRP Repo + scp://mavenrepo.myrealpage.com:/data/vol2/sites/mavenrepo.myrealpage.com/m2/repo + + From b3be1b04bb53e89cb85a70e0a47ff5e643085fe2 Mon Sep 17 00:00:00 2001 From: Ilya Egoshin Date: Fri, 27 Mar 2026 10:36:50 -0500 Subject: [PATCH 23/28] helper methods added --- .../apache/olingo/commons/api/edm/Edm.java | 2 + .../olingo/commons/api/edm/EdmEntityType.java | 2 + .../olingo/commons/api/edm/EdmMember.java | 2 + .../olingo/commons/api/edm/EdmProperty.java | 16 ++++ .../olingo/commons/core/edm/AbstractEdm.java | 14 ++++ .../commons/core/edm/EdmEntityTypeImpl.java | 9 ++ .../commons/core/edm/EdmMemberImpl.java | 22 +++++ .../commons/core/edm/EdmPropertyImpl.java | 83 +++++++++++++++++++ .../queryoption/apply/DynamicProperty.java | 47 +++++++++++ 9 files changed, 197 insertions(+) diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/Edm.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/Edm.java index b24f82abb9..6a5f220a15 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/Edm.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/Edm.java @@ -206,4 +206,6 @@ List getBoundFunctionsWithBindingType(FullQualifiedName bindingPara * @return {@link EdmAnnotations} */ EdmAnnotations getAnnotationGroup(FullQualifiedName targetName, String qualifier); + + EdmEntityType getEntityType(String name); } diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmEntityType.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmEntityType.java index eaf346376b..be1ee31535 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmEntityType.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmEntityType.java @@ -61,4 +61,6 @@ public interface EdmEntityType extends EdmStructuredType { */ @Override EdmEntityType getBaseType(); + + String getPrimaryKey(); } diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmMember.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmMember.java index 19303bca50..181dd7dda1 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmMember.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmMember.java @@ -27,4 +27,6 @@ public interface EdmMember extends EdmNamed, EdmAnnotatable { * @return value of this member as string */ String getValue(); + + String getLabel(); } diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmProperty.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmProperty.java index 71cce4db1a..c408a6ab69 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmProperty.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmProperty.java @@ -87,4 +87,20 @@ public interface EdmProperty extends EdmElement, EdmMappable, EdmAnnotatable { * @return {@link EdmType} */ EdmType getTypeWithAnnotations(); + + String getLookupName(); + + String getLookupId(); + + EdmEnumType getLookup(); + + String getLabel(); + + boolean isSearchable(); + + EdmComplexType getComplexType(); + + boolean isComplex(); + + boolean isEnum(); } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdm.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdm.java index aa5a52eee9..0bca4fd196 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdm.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/AbstractEdm.java @@ -391,6 +391,20 @@ public EdmAnnotations getAnnotationGroup(final FullQualifiedName targetName, Str return _annotations; } + @Override + public EdmEntityType getEntityType(final String name) { + if (name != null && name.contains(".")) { + return getEntityType(new FullQualifiedName(name)); + } + for (EdmSchema schema : getSchemas()) { + EdmEntityType entityType = getEntityType(new FullQualifiedName(schema.getNamespace(), name)); + if (entityType != null) { + return entityType; + } + } + return null; + } + private FullQualifiedName resolvePossibleAlias(final FullQualifiedName namespaceOrAliasFQN) { if (aliasToNamespaceInfo == null) { loadAliasToNamespaceInfo(); diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityTypeImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityTypeImpl.java index 07285bee83..672c649dae 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityTypeImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityTypeImpl.java @@ -143,4 +143,13 @@ public boolean hasStream() { } return false; } + + @Override + public String getPrimaryKey() { + List keyRefs = getKeyPropertyRefs(); + if (keyRefs != null && !keyRefs.isEmpty()) { + return keyRefs.get(0).getName(); + } + return null; + } } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmMemberImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmMemberImpl.java index b504340257..80de0bad0a 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmMemberImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmMemberImpl.java @@ -19,6 +19,7 @@ package org.apache.olingo.commons.core.edm; import org.apache.olingo.commons.api.edm.Edm; +import org.apache.olingo.commons.api.edm.EdmAnnotation; import org.apache.olingo.commons.api.edm.EdmMember; import org.apache.olingo.commons.api.edm.provider.CsdlEnumMember; @@ -35,4 +36,25 @@ public EdmMemberImpl(final Edm edm, final CsdlEnumMember member) { public String getValue() { return member.getValue(); } + + @Override + public String getLabel() { + for (EdmAnnotation annot : getAnnotations()) { + String term = annot.getTermAsString(); + if ("RESO.OData.Metadata.StandardName".equals(term) + || "RESO.OData.Metadata.TrestleName".equals(term) + || "MLS.OData.Metadata.mred".equals(term) + || "Core.Description".equals(term) + || "DDF.Core.Description".equals(term)) { + String value = annot.getExpressionAsString(); + if (value != null) { + value = value.trim(); + if (!value.isEmpty()) { + return value; + } + } + } + } + return getName(); + } } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java index 62fc64560d..a4aef819fc 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java @@ -19,6 +19,9 @@ package org.apache.olingo.commons.core.edm; import org.apache.olingo.commons.api.edm.Edm; +import org.apache.olingo.commons.api.edm.EdmAnnotation; +import org.apache.olingo.commons.api.edm.EdmComplexType; +import org.apache.olingo.commons.api.edm.EdmEnumType; import org.apache.olingo.commons.api.edm.EdmException; import org.apache.olingo.commons.api.edm.EdmMapping; import org.apache.olingo.commons.api.edm.EdmProperty; @@ -146,4 +149,84 @@ public boolean isPrimitive() { } return typeInfo.isPrimitiveType(); } + + @Override + public String getLookupName() { + EdmType type = getType(); + if (type instanceof EdmEnumType) { + return type.getName(); + } + EdmAnnotation annot = getAnnotation("MLS.OData.Metadata.LookupName"); + if (annot == null) { + annot = getAnnotation("RESO.OData.Metadata.LookupName"); + } + if (annot != null) { + return annot.getExpressionAsString(); + } + return null; + } + + @Override + public String getLookupId() { + EdmType type = getType(); + if (type instanceof EdmEnumType) { + return type.getFullQualifiedName().getFullQualifiedNameAsString(); + } + return null; + } + + @Override + public EdmEnumType getLookup() { + EdmType type = getType(); + if (type instanceof EdmEnumType) { + return (EdmEnumType) type; + } + return null; + } + + @Override + public String getLabel() { + for (EdmAnnotation annot : getAnnotations()) { + String term = annot.getTermAsString(); + if ("RESO.OData.Metadata.StandardName".equals(term) + || "RESO.OData.Metadata.TrestleName".equals(term) + || "MLS.OData.Metadata.mred".equals(term) + || "Core.Description".equals(term) + || "DDF.Core.Description".equals(term)) { + String value = annot.getExpressionAsString(); + if (value != null) { + value = value.trim(); + if (!value.isEmpty()) { + return value; + } + } + } + } + return getName(); + } + + @Override + public boolean isSearchable() { + EdmAnnotation annot = getAnnotation("RESO.OData.Metadata.Searchable"); + return annot != null && Boolean.parseBoolean(annot.getExpressionAsString()); + } + + @Override + public EdmComplexType getComplexType() { + EdmType type = getType(); + if (type instanceof EdmComplexType) { + return (EdmComplexType) type; + } + return null; + } + + @Override + public boolean isComplex() { + return getType() instanceof EdmComplexType; + } + + @Override + public boolean isEnum() { + return getType() instanceof EdmEnumType; + } } diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/DynamicProperty.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/DynamicProperty.java index 654bb04ab1..e84b7377cc 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/DynamicProperty.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/DynamicProperty.java @@ -22,6 +22,8 @@ import java.util.List; import org.apache.olingo.commons.api.edm.EdmAnnotation; +import org.apache.olingo.commons.api.edm.EdmComplexType; +import org.apache.olingo.commons.api.edm.EdmEnumType; import org.apache.olingo.commons.api.edm.EdmMapping; import org.apache.olingo.commons.api.edm.EdmProperty; import org.apache.olingo.commons.api.edm.EdmTerm; @@ -143,4 +145,49 @@ public DynamicProperty setScaleAsString(String scaleAsString) { this.scaleAsString = scaleAsString; return this; } + + @Override + public EdmAnnotation getAnnotation(final String termName) { + return null; + } + + @Override + public String getLookupName() { + return null; + } + + @Override + public String getLookupId() { + return null; + } + + @Override + public EdmEnumType getLookup() { + return null; + } + + @Override + public String getLabel() { + return name; + } + + @Override + public boolean isSearchable() { + return false; + } + + @Override + public EdmComplexType getComplexType() { + return null; + } + + @Override + public boolean isComplex() { + return false; + } + + @Override + public boolean isEnum() { + return false; + } } From 969afaf76740eb214971721ed9abb35e1138fb05 Mon Sep 17 00:00:00 2001 From: Ilya Egoshin Date: Fri, 27 Mar 2026 10:45:51 -0500 Subject: [PATCH 24/28] helper method added --- .../olingo/commons/api/edm/EdmEntityType.java | 2 ++ .../commons/core/edm/EdmEntityTypeImpl.java | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmEntityType.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmEntityType.java index be1ee31535..8c7daea485 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmEntityType.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmEntityType.java @@ -63,4 +63,6 @@ public interface EdmEntityType extends EdmStructuredType { EdmEntityType getBaseType(); String getPrimaryKey(); + + String getLabel(); } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityTypeImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityTypeImpl.java index 672c649dae..0ead3e8cbb 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityTypeImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityTypeImpl.java @@ -25,6 +25,7 @@ import java.util.Map; import org.apache.olingo.commons.api.edm.Edm; +import org.apache.olingo.commons.api.edm.EdmAnnotation; import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.edm.EdmException; import org.apache.olingo.commons.api.edm.EdmKeyPropertyRef; @@ -152,4 +153,25 @@ public String getPrimaryKey() { } return null; } + + @Override + public String getLabel() { + for (EdmAnnotation annot : getAnnotations()) { + String term = annot.getTermAsString(); + if ("RESO.OData.Metadata.StandardName".equals(term) + || "RESO.OData.Metadata.TrestleName".equals(term) + || "MLS.OData.Metadata.mred".equals(term) + || "Core.Description".equals(term) + || "DDF.Core.Description".equals(term)) { + String value = annot.getExpressionAsString(); + if (value != null) { + value = value.trim(); + if (!value.isEmpty()) { + return value; + } + } + } + } + return getName(); + } } From c1f458355446921ce050dd62e917b6ed63913e59 Mon Sep 17 00:00:00 2001 From: Ilya Egoshin Date: Fri, 27 Mar 2026 17:22:56 -0500 Subject: [PATCH 25/28] bug fix: null lookup name --- .../org/apache/olingo/commons/core/edm/EdmPropertyImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java index a4aef819fc..f7bca9333e 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java @@ -161,7 +161,9 @@ public String getLookupName() { annot = getAnnotation("RESO.OData.Metadata.LookupName"); } if (annot != null) { - return annot.getExpressionAsString(); + String lookupName = annot.getExpressionAsString(); + if (!"".equals(lookupName) && !"null".equals(lookupName)) + return lookupName; } return null; } From 4099c2a11a18f8b4a85040d6e8ce7582b3401805 Mon Sep 17 00:00:00 2001 From: Ilya Egoshin Date: Fri, 27 Mar 2026 17:23:30 -0500 Subject: [PATCH 26/28] style --- .../org/apache/olingo/commons/core/edm/EdmPropertyImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java index f7bca9333e..96acb91ffa 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java @@ -162,8 +162,9 @@ public String getLookupName() { } if (annot != null) { String lookupName = annot.getExpressionAsString(); - if (!"".equals(lookupName) && !"null".equals(lookupName)) + if (!"".equals(lookupName) && !"null".equals(lookupName)) { return lookupName; + } } return null; } From e321ba4df422b0e3d1569f46ad7ce99178f8022d Mon Sep 17 00:00:00 2001 From: Ilya Egoshin Date: Fri, 27 Mar 2026 17:32:13 -0500 Subject: [PATCH 27/28] searchable should return 3 values: true, false and null --- .../org/apache/olingo/commons/api/edm/EdmProperty.java | 2 +- .../apache/olingo/commons/core/edm/EdmPropertyImpl.java | 7 +++++-- .../server/core/uri/queryoption/apply/DynamicProperty.java | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmProperty.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmProperty.java index c408a6ab69..debce205c5 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmProperty.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/EdmProperty.java @@ -96,7 +96,7 @@ public interface EdmProperty extends EdmElement, EdmMappable, EdmAnnotatable { String getLabel(); - boolean isSearchable(); + Boolean getSearchable(); EdmComplexType getComplexType(); diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java index 96acb91ffa..dde69cd835 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java @@ -209,9 +209,12 @@ public String getLabel() { } @Override - public boolean isSearchable() { + public Boolean getSearchable() { EdmAnnotation annot = getAnnotation("RESO.OData.Metadata.Searchable"); - return annot != null && Boolean.parseBoolean(annot.getExpressionAsString()); + if (annot != null) { + return Boolean.valueOf(annot.getExpressionAsString()); + } + return null; } @Override diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/DynamicProperty.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/DynamicProperty.java index e84b7377cc..a206e4cbc1 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/DynamicProperty.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/DynamicProperty.java @@ -172,8 +172,8 @@ public String getLabel() { } @Override - public boolean isSearchable() { - return false; + public Boolean getSearchable() { + return null; } @Override From ddc60fcfbd0cfc0ca240a409964d7f8b9a92612e Mon Sep 17 00:00:00 2001 From: Ilya Egoshin Date: Mon, 30 Mar 2026 08:18:29 -0500 Subject: [PATCH 28/28] trim leading and trailing spaces from labels --- .../olingo/commons/core/edm/EdmEntityTypeImpl.java | 9 ++++++++- .../apache/olingo/commons/core/edm/EdmMemberImpl.java | 9 ++++++++- .../apache/olingo/commons/core/edm/EdmPropertyImpl.java | 9 ++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityTypeImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityTypeImpl.java index 0ead3e8cbb..2b8a546377 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityTypeImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityTypeImpl.java @@ -172,6 +172,13 @@ public String getLabel() { } } } - return getName(); + String name = getName(); + if (name != null) { + name = name.trim(); + if (!name.isEmpty()) { + return name; + } + } + return null; } } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmMemberImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmMemberImpl.java index 80de0bad0a..8ff022fe0d 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmMemberImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmMemberImpl.java @@ -55,6 +55,13 @@ public String getLabel() { } } } - return getName(); + String name = getName(); + if (name != null) { + name = name.trim(); + if (!name.isEmpty()) { + return name; + } + } + return null; } } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java index dde69cd835..5828785f6f 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java @@ -205,7 +205,14 @@ public String getLabel() { } } } - return getName(); + String name = getName(); + if (name != null) { + name = name.trim(); + if (!name.isEmpty()) { + return name; + } + } + return null; } @Override