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/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); 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); 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..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 @@ -20,6 +20,9 @@ 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; import java.util.Map; @@ -60,16 +63,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 +88,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 +124,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 +132,60 @@ protected ResWrap doDeserialize(final JsonParser parser) throw tree.remove(toRemove); return new ResWrap<>(contextURL, metadataETag, entitySet); } + + private URI getUri(String str) throws IOException { + try { + URL url = new URL(str); + 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(); + String anchor = StringUtils.substringAfterLast(str, "#"); + + if (query == null || query.isEmpty()) { + return URI.create(str); + } + + 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); + + 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 { + String decoded = URLDecoder.decode(param, "UTF-8"); + 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); + + } catch (Exception e) { + throw new IOException("Failed to normalize URI: " + str, e); + } + } } 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/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..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(); @@ -851,8 +854,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()); 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))); 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-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/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 7ebeeee4de..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 @@ -25,6 +25,8 @@ */ public interface EdmAnnotation extends EdmAnnotatable { + String getTermAsString(); + /** * @return the term of this annotation */ @@ -36,4 +38,6 @@ public interface EdmAnnotation extends EdmAnnotatable { String getQualifier(); EdmExpression getExpression(); + + String getExpressionAsString(); } 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..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 @@ -61,4 +61,8 @@ public interface EdmEntityType extends EdmStructuredType { */ @Override EdmEntityType getBaseType(); + + String getPrimaryKey(); + + String getLabel(); } 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..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 @@ -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 getSearchable(); + + EdmComplexType getComplexType(); + + boolean isComplex(); + + boolean isEnum(); } 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/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/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 c4ab9107e5..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 { @@ -38,6 +40,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) { @@ -63,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/EdmEntityTypeImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEntityTypeImpl.java index 07285bee83..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 @@ -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; @@ -143,4 +144,41 @@ public boolean hasStream() { } return false; } + + @Override + public String getPrimaryKey() { + List keyRefs = getKeyPropertyRefs(); + if (keyRefs != null && !keyRefs.isEmpty()) { + return keyRefs.get(0).getName(); + } + 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; + } + } + } + } + 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 b504340257..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 @@ -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,32 @@ 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; + } + } + } + } + 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 62fc64560d..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 @@ -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,97 @@ 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) { + String lookupName = annot.getExpressionAsString(); + if (!"".equals(lookupName) && !"null".equals(lookupName)) { + return lookupName; + } + } + 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; + } + } + } + } + String name = getName(); + if (name != null) { + name = name.trim(); + if (!name.isEmpty()) { + return name; + } + } + return null; + } + + @Override + public Boolean getSearchable() { + EdmAnnotation annot = getAnnotation("RESO.OData.Metadata.Searchable"); + if (annot != null) { + return Boolean.valueOf(annot.getExpressionAsString()); + } + return null; + } + + @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/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..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,6 +128,9 @@ private EdmTypeInfo(final Edm edm, final String typeExpression, final boolean in } } } + if (primitiveType==null && typeDefinition==null && enumType==null && complexType==null && entityType==null) { + primitiveType = EdmPrimitiveTypeKind.String; + } } public String internal() { 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/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."); } 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..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; @@ -60,6 +61,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); @@ -77,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; 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/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..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 @@ -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 getSearchable() { + return null; + } + + @Override + public EdmComplexType getComplexType() { + return null; + } + + @Override + public boolean isComplex() { + return false; + } + + @Override + public boolean isEnum() { + return false; + } } 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 @@ - + diff --git a/pom.xml b/pom.xml index e16eaf1341..8ccecaa25c 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 @@ -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 + +