Merge branch 'master' into olingo472
Conflicts: lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java lib/server-core/src/main/resources/server-core-exceptions-i18n.properties lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
This commit is contained in:
commit
4f820fe533
|
@ -22,6 +22,7 @@ import org.apache.olingo.commons.api.ODataRuntimeException;
|
|||
import org.apache.olingo.server.api.edmx.EdmxReference;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
import org.apache.olingo.server.api.edm.provider.EdmProvider;
|
||||
import org.apache.olingo.server.api.serializer.FixedFormatSerializer;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
|
||||
|
@ -57,10 +58,16 @@ public abstract class OData {
|
|||
* Creates a new serializer object for rendering content in the specified format.
|
||||
* Serializers are used in Processor implementations.
|
||||
*
|
||||
* @param format - any format supported by Olingo (XML, JSON ...)
|
||||
* @param format any format supported by Olingo (XML, JSON ...)
|
||||
*/
|
||||
public abstract ODataSerializer createSerializer(ODataFormat format) throws SerializerException;
|
||||
|
||||
/**
|
||||
* Creates a new serializer object for rendering content in a fixed format, e.g., for binary output.
|
||||
* Serializers are used in Processor implementations.
|
||||
*/
|
||||
public abstract FixedFormatSerializer createFixedFormatSerializer() throws SerializerException;
|
||||
|
||||
/**
|
||||
* Creates a new ODataHttpHandler for handling OData requests in an HTTP context.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.server.api.processor;
|
||||
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
|
||||
/**
|
||||
* Processor interface for handling a collection of complex-type instances, e.g.,
|
||||
* a property of an entity defined as collection of complex-type instances.
|
||||
*/
|
||||
public interface ComplexCollectionProcessor extends Processor {
|
||||
|
||||
/**
|
||||
* Reads complex-type collection.
|
||||
* If it is not available, for example due to permissions, the service responds with 404 Not Found.
|
||||
* @param request OData request object containing raw HTTP information
|
||||
* @param response OData response object for collecting response data
|
||||
* @param uriInfo information of a parsed OData URI
|
||||
* @param format requested content type after content negotiation
|
||||
* @throws ODataApplicationException if the service implementation encounters a failure
|
||||
* @throws SerializerException if serialization failed
|
||||
*/
|
||||
void readComplexCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.server.api.processor;
|
||||
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
|
||||
/**
|
||||
* Processor interface for handling an instance of a complex type, e.g., a complex property of an entity.
|
||||
*/
|
||||
public interface ComplexProcessor extends Processor {
|
||||
|
||||
/**
|
||||
* Reads complex-type instance.
|
||||
* If it is not available, for example due to permissions, the service responds with 404 Not Found.
|
||||
* @param request OData request object containing raw HTTP information
|
||||
* @param response OData response object for collecting response data
|
||||
* @param uriInfo information of a parsed OData URI
|
||||
* @param format requested content type after content negotiation
|
||||
* @throws ODataApplicationException if the service implementation encounters a failure
|
||||
* @throws SerializerException if serialization failed
|
||||
*/
|
||||
void readComplex(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.server.api.processor;
|
||||
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
|
||||
/**
|
||||
* Processor interface for handling counting a collection of entities, e.g., an Entity Set.
|
||||
*/
|
||||
public interface CountEntityCollectionProcessor extends Processor {
|
||||
|
||||
/**
|
||||
* Counts entities from persistence and puts serialized content and status into the response.
|
||||
* Response content type is <code>text/plain</code> by default.
|
||||
* @param request OData request object containing raw HTTP information.
|
||||
* @param response OData response object for collecting response data
|
||||
* @param uriInfo information of a parsed OData URI
|
||||
* @param format requested content type after content negotiation
|
||||
* @throws ODataApplicationException if the service implementation encounters a failure
|
||||
* @throws SerializerException if serialization failed
|
||||
*/
|
||||
void countEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
}
|
|
@ -26,33 +26,19 @@ import org.apache.olingo.server.api.serializer.SerializerException;
|
|||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
|
||||
/**
|
||||
* Processor interface for handling EntitySets (i.e. collection of entities).
|
||||
* Processor interface for handling a collection of entities, e.g., an Entity Set.
|
||||
*/
|
||||
public interface EntitySetProcessor extends Processor {
|
||||
public interface EntityCollectionProcessor extends Processor {
|
||||
|
||||
/**
|
||||
* Reads entities data from persistence and puts serialized content and status into the response.
|
||||
*
|
||||
* @param request - OData request object containing raw HTTP information
|
||||
* @param response - OData response object for collecting response data
|
||||
* @param uriInfo - information of a parsed OData URI
|
||||
* @param requestedContentType - requested content type after content negotiation
|
||||
* @throws ODataApplicationException
|
||||
* @throws SerializerException
|
||||
* @param request OData request object containing raw HTTP information
|
||||
* @param response OData response object for collecting response data
|
||||
* @param uriInfo information of a parsed OData URI
|
||||
* @param format requested content type after content negotiation
|
||||
* @throws ODataApplicationException if the service implementation encounters a failure
|
||||
* @throws SerializerException if serialization failed
|
||||
*/
|
||||
void readEntitySet(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestedContentType)
|
||||
void readEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
|
||||
/**
|
||||
* Count entities from persistence and puts serialized content and status into the response.
|
||||
* Response content type is <code>text/plain</code> by default.
|
||||
*
|
||||
* @param request - OData request object containing raw http information.
|
||||
* @param response - OData response object for collecting response data
|
||||
* @param uriInfo - information of a parsed OData uri
|
||||
* @throws ODataApplicationException
|
||||
* @throws SerializerException
|
||||
*/
|
||||
void countEntitySet(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException,
|
||||
SerializerException;
|
||||
}
|
|
@ -26,19 +26,19 @@ import org.apache.olingo.server.api.serializer.SerializerException;
|
|||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
|
||||
/**
|
||||
* Processor interface for handling a single Entity.
|
||||
* Processor interface for handling a single instance of an Entity Type.
|
||||
*/
|
||||
public interface EntityProcessor extends Processor {
|
||||
|
||||
/**
|
||||
* Reads entity data from persistence and puts serialized content and status into the response.
|
||||
* @param request - OData request object containing raw HTTP information
|
||||
* @param response - OData response object for collecting response data
|
||||
* @param uriInfo - information of a parsed OData URI
|
||||
* @param requestedContentType - requested content type after content negotiation
|
||||
* @throws ODataApplicationException
|
||||
* @throws SerializerException
|
||||
* @param request OData request object containing raw HTTP information
|
||||
* @param response OData response object for collecting response data
|
||||
* @param uriInfo information of a parsed OData URI
|
||||
* @param format requested content type after content negotiation
|
||||
* @throws ODataApplicationException if the service implementation encounters a failure
|
||||
* @throws SerializerException if serialization failed
|
||||
*/
|
||||
void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestedContentType)
|
||||
void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
}
|
||||
|
|
|
@ -30,11 +30,11 @@ public interface ExceptionProcessor extends Processor {
|
|||
|
||||
/**
|
||||
* Processes an exception. MUST NOT throw an exception!
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param serverError the server error
|
||||
* @param requestedContentType the requested format for the error message
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param serverError the server error
|
||||
* @param format the requested format for the error message
|
||||
*/
|
||||
public void processException(ODataRequest request, ODataResponse response, ODataServerError serverError,
|
||||
ContentType requestedContentType);
|
||||
ContentType format);
|
||||
}
|
||||
|
|
|
@ -32,13 +32,13 @@ public interface MetadataProcessor extends Processor {
|
|||
|
||||
/**
|
||||
* Reads data from persistency and puts serialized content and status into the response.
|
||||
* @param request - OData request object containing raw HTTP information
|
||||
* @param response - OData response object for collecting response data
|
||||
* @param uriInfo - information of a parsed OData URI
|
||||
* @param requestedContentType - requested content type after content negotiation
|
||||
* @throws ODataApplicationException
|
||||
* @throws SerializerException
|
||||
* @param request OData request object containing raw HTTP information
|
||||
* @param response OData response object for collecting response data
|
||||
* @param uriInfo information of a parsed OData URI
|
||||
* @param format requested content type after content negotiation
|
||||
* @throws ODataApplicationException if the service implementation encounters a failure
|
||||
* @throws SerializerException if serialization failed
|
||||
*/
|
||||
void readMetadata(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestedContentType)
|
||||
void readMetadata(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.server.api.processor;
|
||||
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
|
||||
/**
|
||||
* Processor interface for handling a collection of primitive-type instances, e.g.,
|
||||
* a property of an entity defined as collection of primitive-type instances.
|
||||
*/
|
||||
public interface PrimitiveCollectionProcessor extends Processor {
|
||||
|
||||
/**
|
||||
* Reads primitive-type collection.
|
||||
* If it is not available, for example due to permissions, the service responds with 404 Not Found.
|
||||
* @param request OData request object containing raw HTTP information
|
||||
* @param response OData response object for collecting response data
|
||||
* @param uriInfo information of a parsed OData URI
|
||||
* @param format requested content type after content negotiation
|
||||
* @throws ODataApplicationException if the service implementation encounters a failure
|
||||
* @throws SerializerException if serialization failed
|
||||
*/
|
||||
void readPrimitiveCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.server.api.processor;
|
||||
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
|
||||
/**
|
||||
* Processor interface for handling an instance of a primitive type, e.g., a primitive property of an entity.
|
||||
*/
|
||||
public interface PrimitiveProcessor extends Processor {
|
||||
|
||||
/**
|
||||
* Reads primitive-type instance.
|
||||
* If its value is <code>null</code>, the service responds with 204 No Content.
|
||||
* If it is not available, for example due to permissions, the service responds with 404 Not Found.
|
||||
* @param request OData request object containing raw HTTP information
|
||||
* @param response OData response object for collecting response data
|
||||
* @param uriInfo information of a parsed OData URI
|
||||
* @param format requested content type after content negotiation
|
||||
* @throws ODataApplicationException if the service implementation encounters a failure
|
||||
* @throws SerializerException if serialization failed
|
||||
*/
|
||||
void readPrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
|
||||
/**
|
||||
* Reads raw value of a primitive-type instance, e.g., of a primitive property of an entity.
|
||||
* If the value is <code>null</code>, the service responds with 204 No Content.
|
||||
* If it is not available, for example due to permissions, the service responds with 404 Not Found.
|
||||
* @param request OData request object containing raw HTTP information
|
||||
* @param response OData response object for collecting response data
|
||||
* @param uriInfo information of a parsed OData URI
|
||||
* @param format requested content type after content negotiation
|
||||
* @throws ODataApplicationException if the service implementation encounters a failure
|
||||
* @throws SerializerException if serialization failed
|
||||
*/
|
||||
void readPrimitiveAsValue(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.server.api.processor;
|
||||
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
|
||||
/**
|
||||
* Processor interface for handling a property of an entity.
|
||||
*/
|
||||
public interface PropertyProcessor extends Processor {
|
||||
|
||||
/**
|
||||
* Reads primitive or complex property from entity.
|
||||
* If the property is single-valued and has the null value, the service responds with 204 No Content.
|
||||
* If the property is not available, for example due to permissions, the service responds with 404 Not Found
|
||||
*
|
||||
* @param request - OData request object containing raw HTTP information
|
||||
* @param response - OData response object for collecting response data
|
||||
* @param uriInfo - information of a parsed OData URI
|
||||
* @param format - requested content type after content negotiation
|
||||
* @throws ODataApplicationException if service implementation encounters a failure
|
||||
* @throws SerializerException if serialization failed
|
||||
*/
|
||||
void readProperty(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
|
||||
/**
|
||||
* Reads value for primitive property from entity.
|
||||
* If the property is single-valued and has the null value, the service responds with 204 No Content.
|
||||
* If the property is not available, for example due to permissions, the service responds with 404 Not Found
|
||||
*
|
||||
* @param request - OData request object containing raw HTTP information
|
||||
* @param response - OData response object for collecting response data
|
||||
* @param uriInfo - information of a parsed OData URI
|
||||
* @param format - requested content type after content negotiation
|
||||
* @throws ODataApplicationException if service implementation encounters a failure
|
||||
* @throws SerializerException if serialization failed
|
||||
*/
|
||||
void readPropertyValue(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
}
|
|
@ -32,11 +32,13 @@ public interface ServiceDocumentProcessor extends Processor {
|
|||
|
||||
/**
|
||||
* Reads service-document information from persistency and puts serialized content and status into the response.
|
||||
* @param request - OData request object containing raw HTTP information
|
||||
* @param response - OData response object for collecting response data
|
||||
* @param uriInfo - information of a parsed OData URI
|
||||
* @param requestedContentType - requested content type after content negotiation
|
||||
* @param request OData request object containing raw HTTP information
|
||||
* @param response OData response object for collecting response data
|
||||
* @param uriInfo information of a parsed OData URI
|
||||
* @param format requested content type after content negotiation
|
||||
* @throws ODataApplicationException if the service implementation encounters a failure
|
||||
* @throws SerializerException if serialization failed
|
||||
*/
|
||||
void readServiceDocument(ODataRequest request, ODataResponse response, UriInfo uriInfo,
|
||||
ContentType requestedContentType) throws ODataApplicationException, SerializerException;
|
||||
void readServiceDocument(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.server.api.serializer;
|
||||
|
||||
import org.apache.olingo.commons.api.data.ContextURL;
|
||||
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
||||
|
||||
/** Options for the OData serializer. */
|
||||
public class ComplexSerializerOptions {
|
||||
|
||||
private ContextURL contextURL;
|
||||
private ExpandOption expand;
|
||||
private SelectOption select;
|
||||
|
||||
/** Gets the {@link ContextURL}. */
|
||||
public ContextURL getContextURL() {
|
||||
return contextURL;
|
||||
}
|
||||
|
||||
/** Gets the $expand system query option. */
|
||||
public ExpandOption getExpand() {
|
||||
return expand;
|
||||
}
|
||||
|
||||
/** Gets the $select system query option. */
|
||||
public SelectOption getSelect() {
|
||||
return select;
|
||||
}
|
||||
|
||||
private ComplexSerializerOptions() {}
|
||||
|
||||
/** Initializes the options builder. */
|
||||
public static Builder with() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/** Builder of OData serializer options. */
|
||||
public static final class Builder {
|
||||
|
||||
private ComplexSerializerOptions options;
|
||||
|
||||
private Builder() {
|
||||
options = new ComplexSerializerOptions();
|
||||
}
|
||||
|
||||
/** Sets the {@link ContextURL}. */
|
||||
public Builder contextURL(final ContextURL contextURL) {
|
||||
options.contextURL = contextURL;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the $expand system query option. */
|
||||
public Builder expand(final ExpandOption expand) {
|
||||
options.expand = expand;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the $select system query option. */
|
||||
public Builder select(final SelectOption select) {
|
||||
options.select = select;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds the OData serializer options. */
|
||||
public ComplexSerializerOptions build() {
|
||||
return options;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,7 +24,7 @@ import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
|||
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
||||
|
||||
/** Options for the OData serializer. */
|
||||
public class ODataSerializerOptions {
|
||||
public class EntityCollectionSerializerOptions {
|
||||
|
||||
private ContextURL contextURL;
|
||||
private CountOption count;
|
||||
|
@ -51,8 +51,6 @@ public class ODataSerializerOptions {
|
|||
return select;
|
||||
}
|
||||
|
||||
private ODataSerializerOptions() {}
|
||||
|
||||
/** Initializes the options builder. */
|
||||
public static Builder with() {
|
||||
return new Builder();
|
||||
|
@ -61,10 +59,10 @@ public class ODataSerializerOptions {
|
|||
/** Builder of OData serializer options. */
|
||||
public static final class Builder {
|
||||
|
||||
private ODataSerializerOptions options;
|
||||
private EntityCollectionSerializerOptions options;
|
||||
|
||||
private Builder() {
|
||||
options = new ODataSerializerOptions();
|
||||
options = new EntityCollectionSerializerOptions();
|
||||
}
|
||||
|
||||
/** Sets the {@link ContextURL}. */
|
||||
|
@ -92,7 +90,7 @@ public class ODataSerializerOptions {
|
|||
}
|
||||
|
||||
/** Builds the OData serializer options. */
|
||||
public ODataSerializerOptions build() {
|
||||
public EntityCollectionSerializerOptions build() {
|
||||
return options;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.server.api.serializer;
|
||||
|
||||
import org.apache.olingo.commons.api.data.ContextURL;
|
||||
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
||||
|
||||
/** Options for the OData serializer. */
|
||||
public class EntitySerializerOptions {
|
||||
private ContextURL contextURL;
|
||||
private ExpandOption expand;
|
||||
private SelectOption select;
|
||||
|
||||
/** Gets the {@link ContextURL}. */
|
||||
public ContextURL getContextURL() {
|
||||
return contextURL;
|
||||
}
|
||||
|
||||
/** Gets the $expand system query option. */
|
||||
public ExpandOption getExpand() {
|
||||
return expand;
|
||||
}
|
||||
|
||||
/** Gets the $select system query option. */
|
||||
public SelectOption getSelect() {
|
||||
return select;
|
||||
}
|
||||
|
||||
private EntitySerializerOptions() {}
|
||||
|
||||
/** Initializes the options builder. */
|
||||
public static final Builder with() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/** Builder of OData serializer options. */
|
||||
public static final class Builder {
|
||||
|
||||
private EntitySerializerOptions options;
|
||||
|
||||
private Builder() {
|
||||
options = new EntitySerializerOptions();
|
||||
}
|
||||
|
||||
/** Sets the {@link ContextURL}. */
|
||||
public Builder contextURL(final ContextURL contextURL) {
|
||||
options.contextURL = contextURL;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the $expand system query option. */
|
||||
public Builder expand(final ExpandOption expand) {
|
||||
options.expand = expand;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the $select system query option. */
|
||||
public Builder select(final SelectOption select) {
|
||||
options.select = select;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds the OData serializer options. */
|
||||
public EntitySerializerOptions build() {
|
||||
return options;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.server.api.serializer;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
||||
|
||||
/** OData serializer for fixed output formats. */
|
||||
public interface FixedFormatSerializer {
|
||||
|
||||
/**
|
||||
* Writes binary output into an InputStream.
|
||||
* @param binary the binary data
|
||||
*/
|
||||
InputStream binary(byte[] binary) throws SerializerException;
|
||||
|
||||
/**
|
||||
* Writes a count into an InputStream as plain text.
|
||||
* @param count the count
|
||||
*/
|
||||
InputStream count(Integer count) throws SerializerException;
|
||||
|
||||
/**
|
||||
* Writes the raw value of a primitive-type instance into an InputStream.
|
||||
* @param type the primitive type
|
||||
* @param value the value
|
||||
* @param options options for the serializer
|
||||
*/
|
||||
InputStream primitiveValue(EdmPrimitiveType type, Object value, PrimitiveValueSerializerOptions options)
|
||||
throws SerializerException;
|
||||
}
|
|
@ -25,8 +25,10 @@ import org.apache.olingo.commons.api.data.Entity;
|
|||
import org.apache.olingo.commons.api.data.EntitySet;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.edm.Edm;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
import org.apache.olingo.commons.api.edm.EdmComplexType;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
||||
import org.apache.olingo.commons.api.edm.EdmStructuredType;
|
||||
import org.apache.olingo.server.api.ODataServerError;
|
||||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
import org.apache.olingo.server.api.uri.UriParameter;
|
||||
|
@ -52,33 +54,6 @@ public interface ODataSerializer {
|
|||
*/
|
||||
InputStream metadataDocument(ServiceMetadata serviceMetadata) throws SerializerException;
|
||||
|
||||
/**
|
||||
* Writes entity data into an InputStream.
|
||||
* @param edmEntitySet the {@link EdmEntitySet}
|
||||
* @param entity the data of the entity
|
||||
* @param options options for the serializer
|
||||
*/
|
||||
InputStream entity(EdmEntitySet edmEntitySet, Entity entity, ODataSerializerOptions options)
|
||||
throws SerializerException;
|
||||
|
||||
/**
|
||||
* Writes entity data into an InputStream.
|
||||
* @param edmProperty property definition
|
||||
* @param property property value
|
||||
* @param options options for the serializer
|
||||
*/
|
||||
InputStream entityProperty(EdmProperty edmProperty, Property property, ODataSerializerOptions options)
|
||||
throws SerializerException;
|
||||
|
||||
/**
|
||||
* Writes entity-set data into an InputStream.
|
||||
* @param edmEntitySet the {@link EdmEntitySet}
|
||||
* @param entitySet the data of the entity set
|
||||
* @param options options for the serializer
|
||||
*/
|
||||
InputStream entitySet(EdmEntitySet edmEntitySet, EntitySet entitySet, ODataSerializerOptions options)
|
||||
throws SerializerException;
|
||||
|
||||
/**
|
||||
* Writes an ODataError into an InputStream.
|
||||
* @param error the main error
|
||||
|
@ -86,14 +61,68 @@ public interface ODataSerializer {
|
|||
*/
|
||||
InputStream error(ODataServerError error) throws SerializerException;
|
||||
|
||||
/**
|
||||
* Writes entity-collection data into an InputStream.
|
||||
* @param entityType the {@link EdmEntityType}
|
||||
* @param entitySet the data of the entity set
|
||||
* @param options options for the serializer
|
||||
*/
|
||||
InputStream entityCollection(EdmEntityType entityType, EntitySet entitySet,
|
||||
EntityCollectionSerializerOptions options) throws SerializerException;
|
||||
|
||||
/**
|
||||
* Writes entity data into an InputStream.
|
||||
* @param entityType the {@link EdmEntityType}
|
||||
* @param entity the data of the entity
|
||||
* @param options options for the serializer
|
||||
*/
|
||||
InputStream entity(EdmEntityType entityType, Entity entity, EntitySerializerOptions options)
|
||||
throws SerializerException;
|
||||
|
||||
/**
|
||||
* Writes primitive-type instance data into an InputStream.
|
||||
* @param type primitive type
|
||||
* @param property property value
|
||||
* @param options options for the serializer
|
||||
*/
|
||||
InputStream primitive(EdmPrimitiveType type, Property property, PrimitiveSerializerOptions options)
|
||||
throws SerializerException;
|
||||
|
||||
/**
|
||||
* Writes complex-type instance data into an InputStream.
|
||||
* @param type complex type
|
||||
* @param property property value
|
||||
* @param options options for the serializer
|
||||
*/
|
||||
InputStream complex(EdmComplexType type, Property property, ComplexSerializerOptions options)
|
||||
throws SerializerException;
|
||||
|
||||
/**
|
||||
* Writes data of a collection of primitive-type instances into an InputStream.
|
||||
* @param type primitive type
|
||||
* @param property property value
|
||||
* @param options options for the serializer
|
||||
*/
|
||||
InputStream primitiveCollection(EdmPrimitiveType type, Property property, PrimitiveSerializerOptions options)
|
||||
throws SerializerException;
|
||||
|
||||
/**
|
||||
* Writes data of a collection of complex-type instances into an InputStream.
|
||||
* @param type complex type
|
||||
* @param property property value
|
||||
* @param options options for the serializer
|
||||
*/
|
||||
InputStream complexCollection(EdmComplexType type, Property property, ComplexSerializerOptions options)
|
||||
throws SerializerException;
|
||||
|
||||
/**
|
||||
* Builds the select-list part of a {@link org.apache.olingo.commons.api.data.ContextURL ContextURL}.
|
||||
* @param edmEntitySet the Entity Set
|
||||
* @param expand the $expand option
|
||||
* @param select the $select option
|
||||
* @param type the {@link EdmStructuredType}
|
||||
* @param expand the $expand option
|
||||
* @param select the $select option
|
||||
* @return a String with the select list
|
||||
*/
|
||||
String buildContextURLSelectList(EdmEntitySet edmEntitySet, ExpandOption expand, SelectOption select)
|
||||
String buildContextURLSelectList(EdmStructuredType type, ExpandOption expand, SelectOption select)
|
||||
throws SerializerException;
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.server.api.serializer;
|
||||
|
||||
import org.apache.olingo.commons.api.data.ContextURL;
|
||||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
|
||||
/** Options for the OData serializer. */
|
||||
public class PrimitiveSerializerOptions {
|
||||
|
||||
private ContextURL contextURL;
|
||||
private Boolean isNullable;
|
||||
private Integer maxLength;
|
||||
private Integer precision;
|
||||
private Integer scale;
|
||||
private Boolean isUnicode;
|
||||
|
||||
/** Gets the {@link ContextURL}. */
|
||||
public ContextURL getContextURL() {
|
||||
return contextURL;
|
||||
}
|
||||
|
||||
/** Gets the nullable facet. */
|
||||
public Boolean isNullable() {
|
||||
return isNullable;
|
||||
}
|
||||
|
||||
/** Gets the maxLength facet. */
|
||||
public Integer getMaxLength() {
|
||||
return maxLength;
|
||||
}
|
||||
|
||||
/** Gets the precision facet. */
|
||||
public Integer getPrecision() {
|
||||
return precision;
|
||||
}
|
||||
|
||||
/** Gets the scale facet. */
|
||||
public Integer getScale() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
/** Gets the unicode facet. */
|
||||
public Boolean isUnicode() {
|
||||
return isUnicode;
|
||||
}
|
||||
|
||||
private PrimitiveSerializerOptions() {}
|
||||
|
||||
/** Initializes the options builder. */
|
||||
public static Builder with() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/** Builder of OData serializer options. */
|
||||
public static final class Builder {
|
||||
|
||||
private PrimitiveSerializerOptions options;
|
||||
|
||||
private Builder() {
|
||||
options = new PrimitiveSerializerOptions();
|
||||
}
|
||||
|
||||
/** Sets the {@link ContextURL}. */
|
||||
public Builder contextURL(final ContextURL contextURL) {
|
||||
options.contextURL = contextURL;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the nullable facet. */
|
||||
public Builder nullable(final Boolean isNullable) {
|
||||
options.isNullable = isNullable;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the maxLength facet. */
|
||||
public Builder maxLength(final Integer maxLength) {
|
||||
options.maxLength = maxLength;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the precision facet. */
|
||||
public Builder precision(final Integer precision) {
|
||||
options.precision = precision;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the scale facet. */
|
||||
public Builder scale(final Integer scale) {
|
||||
options.scale = scale;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the unicode facet. */
|
||||
public Builder unicode(final Boolean isUnicode) {
|
||||
options.isUnicode = isUnicode;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets all facets from an EDM property. */
|
||||
public Builder facetsFrom(final EdmProperty property) {
|
||||
options.isNullable = property.isNullable();
|
||||
options.maxLength = property.getMaxLength();
|
||||
options.precision = property.getPrecision();
|
||||
options.scale = property.getScale();
|
||||
options.isUnicode = property.isUnicode();
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds the OData serializer options. */
|
||||
public PrimitiveSerializerOptions build() {
|
||||
return options;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.server.api.serializer;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
|
||||
/** Options for the OData serializer. */
|
||||
public class PrimitiveValueSerializerOptions {
|
||||
|
||||
private Boolean isNullable;
|
||||
private Integer maxLength;
|
||||
private Integer precision;
|
||||
private Integer scale;
|
||||
private Boolean isUnicode;
|
||||
|
||||
/** Gets the nullable facet. */
|
||||
public Boolean isNullable() {
|
||||
return isNullable;
|
||||
}
|
||||
|
||||
/** Gets the maxLength facet. */
|
||||
public Integer getMaxLength() {
|
||||
return maxLength;
|
||||
}
|
||||
|
||||
/** Gets the precision facet. */
|
||||
public Integer getPrecision() {
|
||||
return precision;
|
||||
}
|
||||
|
||||
/** Gets the scale facet. */
|
||||
public Integer getScale() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
/** Gets the unicode facet. */
|
||||
public Boolean isUnicode() {
|
||||
return isUnicode;
|
||||
}
|
||||
|
||||
private PrimitiveValueSerializerOptions() {}
|
||||
|
||||
/** Initializes the options builder. */
|
||||
public static Builder with() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/** Builder of OData serializer options. */
|
||||
public static final class Builder {
|
||||
|
||||
private PrimitiveValueSerializerOptions options;
|
||||
|
||||
private Builder() {
|
||||
options = new PrimitiveValueSerializerOptions();
|
||||
}
|
||||
|
||||
/** Sets the nullable facet. */
|
||||
public Builder nullable(final Boolean isNullable) {
|
||||
options.isNullable = isNullable;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the maxLength facet. */
|
||||
public Builder maxLength(final Integer maxLength) {
|
||||
options.maxLength = maxLength;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the precision facet. */
|
||||
public Builder precision(final Integer precision) {
|
||||
options.precision = precision;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the scale facet. */
|
||||
public Builder scale(final Integer scale) {
|
||||
options.scale = scale;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the unicode facet. */
|
||||
public Builder unicode(final Boolean isUnicode) {
|
||||
options.isUnicode = isUnicode;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets all facets from an EDM property. */
|
||||
public Builder facetsFrom(final EdmProperty property) {
|
||||
options.isNullable = property.isNullable();
|
||||
options.maxLength = property.getMaxLength();
|
||||
options.precision = property.getPrecision();
|
||||
options.scale = property.getScale();
|
||||
options.isUnicode = property.isUnicode();
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds the OData serializer options. */
|
||||
public PrimitiveValueSerializerOptions build() {
|
||||
return options;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -36,7 +36,8 @@ public class SerializerException extends ODataTranslatedException {
|
|||
/** parameter: property name */ UNSUPPORTED_PROPERTY_TYPE,
|
||||
/** parameter: property name */ INCONSISTENT_PROPERTY_TYPE,
|
||||
/** parameter: property name */ MISSING_PROPERTY,
|
||||
/** parameters: property name, property value */ WRONG_PROPERTY_VALUE;
|
||||
/** parameters: property name, property value */ WRONG_PROPERTY_VALUE,
|
||||
/** parameters: primitive-type name, value */ WRONG_PRIMITIVE_VALUE;
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
|
|
|
@ -37,20 +37,24 @@ import org.apache.olingo.server.api.ODataServerError;
|
|||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
import org.apache.olingo.server.api.batch.BatchException;
|
||||
import org.apache.olingo.server.api.processor.BatchProcessor;
|
||||
import org.apache.olingo.server.api.processor.ComplexCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.ComplexProcessor;
|
||||
import org.apache.olingo.server.api.processor.CountEntityCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.DefaultProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntitySetProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntityProcessor;
|
||||
import org.apache.olingo.server.api.processor.ExceptionProcessor;
|
||||
import org.apache.olingo.server.api.processor.MetadataProcessor;
|
||||
import org.apache.olingo.server.api.processor.PrimitiveCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.PrimitiveProcessor;
|
||||
import org.apache.olingo.server.api.processor.Processor;
|
||||
import org.apache.olingo.server.api.processor.PropertyProcessor;
|
||||
import org.apache.olingo.server.api.processor.ServiceDocumentProcessor;
|
||||
import org.apache.olingo.server.api.serializer.CustomContentTypeSupport;
|
||||
import org.apache.olingo.server.api.serializer.RepresentationType;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.api.uri.UriResource;
|
||||
import org.apache.olingo.server.api.uri.UriResourceKind;
|
||||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||
import org.apache.olingo.server.api.uri.UriResourceNavigation;
|
||||
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
|
||||
import org.apache.olingo.server.api.uri.UriResourceProperty;
|
||||
|
@ -130,11 +134,10 @@ public class ODataHandler {
|
|||
switch (uriInfo.getKind()) {
|
||||
case metadata:
|
||||
if (method.equals(HttpMethod.GET)) {
|
||||
MetadataProcessor mp = selectProcessor(MetadataProcessor.class);
|
||||
|
||||
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
|
||||
customContentTypeSupport, RepresentationType.METADATA);
|
||||
mp.readMetadata(request, response, uriInfo, requestedContentType);
|
||||
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, customContentTypeSupport, RepresentationType.METADATA);
|
||||
selectProcessor(MetadataProcessor.class)
|
||||
.readMetadata(request, response, uriInfo, requestedContentType);
|
||||
} else {
|
||||
throw new ODataHandlerException("HttpMethod " + method + " not allowed for metadata document",
|
||||
ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED, method.toString());
|
||||
|
@ -143,15 +146,13 @@ public class ODataHandler {
|
|||
case service:
|
||||
if (method.equals(HttpMethod.GET)) {
|
||||
if ("".equals(request.getRawODataPath())) {
|
||||
RedirectProcessor rdp = selectProcessor(RedirectProcessor.class);
|
||||
rdp.redirect(request, response);
|
||||
selectProcessor(RedirectProcessor.class).redirect(request, response);
|
||||
} else {
|
||||
ServiceDocumentProcessor sdp = selectProcessor(ServiceDocumentProcessor.class);
|
||||
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, customContentTypeSupport, RepresentationType.SERVICE);
|
||||
|
||||
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
|
||||
customContentTypeSupport, RepresentationType.SERVICE);
|
||||
|
||||
sdp.readServiceDocument(request, response, uriInfo, requestedContentType);
|
||||
selectProcessor(ServiceDocumentProcessor.class)
|
||||
.readServiceDocument(request, response, uriInfo, requestedContentType);
|
||||
}
|
||||
} else {
|
||||
throw new ODataHandlerException("HttpMethod " + method + " not allowed for service document",
|
||||
|
@ -195,113 +196,118 @@ public class ODataHandler {
|
|||
|
||||
private void handleResourceDispatching(final ODataRequest request, final ODataResponse response)
|
||||
throws ODataHandlerException, ContentNegotiatorException, ODataApplicationException, SerializerException {
|
||||
final HttpMethod method = request.getMethod();
|
||||
final int lastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 1;
|
||||
UriResource lastPathSegment = uriInfo.getUriResourceParts().get(lastPathSegmentIndex);
|
||||
final UriResource lastPathSegment = uriInfo.getUriResourceParts().get(lastPathSegmentIndex);
|
||||
|
||||
switch (lastPathSegment.getKind()) {
|
||||
case entitySet:
|
||||
if (((UriResourcePartTyped) lastPathSegment).isCollection()) {
|
||||
if (request.getMethod().equals(HttpMethod.GET)) {
|
||||
EntitySetProcessor cp = selectProcessor(EntitySetProcessor.class);
|
||||
|
||||
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
|
||||
customContentTypeSupport, RepresentationType.COLLECTION_ENTITY);
|
||||
|
||||
cp.readEntitySet(request, response, uriInfo, requestedContentType);
|
||||
} else {
|
||||
throw new ODataHandlerException("not implemented",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
}
|
||||
} else {
|
||||
if (request.getMethod().equals(HttpMethod.GET)) {
|
||||
EntityProcessor ep = selectProcessor(EntityProcessor.class);
|
||||
|
||||
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
|
||||
customContentTypeSupport, RepresentationType.ENTITY);
|
||||
|
||||
ep.readEntity(request, response, uriInfo, requestedContentType);
|
||||
} else {
|
||||
throw new ODataHandlerException("not implemented",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case navigationProperty:
|
||||
if (((UriResourceNavigation) lastPathSegment).isCollection()) {
|
||||
if (request.getMethod().equals(HttpMethod.GET)) {
|
||||
EntitySetProcessor cp = selectProcessor(EntitySetProcessor.class);
|
||||
if (((UriResourcePartTyped) lastPathSegment).isCollection()) {
|
||||
if (method.equals(HttpMethod.GET)) {
|
||||
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, customContentTypeSupport, RepresentationType.COLLECTION_ENTITY);
|
||||
|
||||
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
|
||||
customContentTypeSupport, RepresentationType.COLLECTION_ENTITY);
|
||||
|
||||
cp.readEntitySet(request, response, uriInfo, requestedContentType);
|
||||
selectProcessor(EntityCollectionProcessor.class)
|
||||
.readEntityCollection(request, response, uriInfo, requestedContentType);
|
||||
} else {
|
||||
throw new ODataHandlerException("not implemented",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
}
|
||||
} else {
|
||||
if (request.getMethod().equals(HttpMethod.GET)) {
|
||||
EntityProcessor ep = selectProcessor(EntityProcessor.class);
|
||||
if (method.equals(HttpMethod.GET)) {
|
||||
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, customContentTypeSupport, RepresentationType.ENTITY);
|
||||
|
||||
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
|
||||
customContentTypeSupport, RepresentationType.ENTITY);
|
||||
|
||||
ep.readEntity(request, response, uriInfo, requestedContentType);
|
||||
selectProcessor(EntityProcessor.class)
|
||||
.readEntity(request, response, uriInfo, requestedContentType);
|
||||
} else {
|
||||
throw new ODataHandlerException("not implemented",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case count:
|
||||
if (request.getMethod().equals(HttpMethod.GET)) {
|
||||
EntitySetProcessor cp = selectProcessor(EntitySetProcessor.class);
|
||||
cp.countEntitySet(request, response, uriInfo);
|
||||
if (method.equals(HttpMethod.GET)) {
|
||||
final UriResource resource = uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1);
|
||||
if (resource instanceof UriResourceEntitySet || resource instanceof UriResourceNavigation) {
|
||||
selectProcessor(CountEntityCollectionProcessor.class)
|
||||
.countEntityCollection(request, response, uriInfo, ContentType.TEXT_PLAIN);
|
||||
} else {
|
||||
throw new ODataHandlerException(
|
||||
"Count of collections of primitive-type or complex-type instances is not implemented.",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
}
|
||||
} else {
|
||||
throw new ODataHandlerException("not implemented",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
throw new ODataHandlerException("HTTP method " + method + " is not allowed for count.",
|
||||
ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED, method.toString());
|
||||
}
|
||||
break;
|
||||
|
||||
case primitiveProperty:
|
||||
case complexProperty:
|
||||
if (request.getMethod().equals(HttpMethod.GET)) {
|
||||
PropertyProcessor ep = selectProcessor(PropertyProcessor.class);
|
||||
|
||||
if (method.equals(HttpMethod.GET)) {
|
||||
final UriResourceProperty propertyResource = (UriResourceProperty) lastPathSegment;
|
||||
final boolean isCollection = propertyResource.isCollection();
|
||||
final boolean isComplex = propertyResource.getKind() == UriResourceKind.complexProperty;
|
||||
final RepresentationType representationType =
|
||||
isComplex ? isCollection ? RepresentationType.COLLECTION_COMPLEX : RepresentationType.COMPLEX :
|
||||
isCollection ? RepresentationType.COLLECTION_PRIMITIVE : RepresentationType.PRIMITIVE;
|
||||
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
|
||||
customContentTypeSupport, representationType);
|
||||
|
||||
ep.readProperty(request, response, uriInfo, requestedContentType);
|
||||
final RepresentationType representationType = propertyResource.isCollection() ?
|
||||
RepresentationType.COLLECTION_PRIMITIVE : RepresentationType.PRIMITIVE;
|
||||
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, customContentTypeSupport, representationType);
|
||||
if (representationType == RepresentationType.PRIMITIVE) {
|
||||
selectProcessor(PrimitiveProcessor.class)
|
||||
.readPrimitive(request, response, uriInfo, requestedContentType);
|
||||
} else {
|
||||
selectProcessor(PrimitiveCollectionProcessor.class)
|
||||
.readPrimitiveCollection(request, response, uriInfo, requestedContentType);
|
||||
}
|
||||
} else {
|
||||
throw new ODataHandlerException("not implemented",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
}
|
||||
break;
|
||||
|
||||
case complexProperty:
|
||||
if (method.equals(HttpMethod.GET)) {
|
||||
final UriResourceProperty propertyResource = (UriResourceProperty) lastPathSegment;
|
||||
final RepresentationType representationType = propertyResource.isCollection() ?
|
||||
RepresentationType.COLLECTION_COMPLEX : RepresentationType.COMPLEX;
|
||||
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, customContentTypeSupport, representationType);
|
||||
if (representationType == RepresentationType.COMPLEX) {
|
||||
selectProcessor(ComplexProcessor.class)
|
||||
.readComplex(request, response, uriInfo, requestedContentType);
|
||||
} else {
|
||||
selectProcessor(ComplexCollectionProcessor.class)
|
||||
.readComplexCollection(request, response, uriInfo, requestedContentType);
|
||||
}
|
||||
} else {
|
||||
throw new ODataHandlerException("not implemented",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
}
|
||||
break;
|
||||
|
||||
case value:
|
||||
if (request.getMethod().equals(HttpMethod.GET)) {
|
||||
PropertyProcessor ep = selectProcessor(PropertyProcessor.class);
|
||||
if (method.equals(HttpMethod.GET)) {
|
||||
final UriResource resource = uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1);
|
||||
if (resource instanceof UriResourceProperty) {
|
||||
final RepresentationType representationType =
|
||||
(EdmPrimitiveType) ((UriResourceProperty) resource).getType() ==
|
||||
EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary) ?
|
||||
RepresentationType.BINARY : RepresentationType.VALUE;
|
||||
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, customContentTypeSupport, representationType);
|
||||
|
||||
final UriResourceProperty propertyResource =
|
||||
(UriResourceProperty) uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1);
|
||||
final RepresentationType representationType =
|
||||
(EdmPrimitiveType) propertyResource.getType() ==
|
||||
EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary) ?
|
||||
RepresentationType.BINARY :
|
||||
RepresentationType.VALUE;
|
||||
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
|
||||
customContentTypeSupport, representationType);
|
||||
|
||||
ep.readPropertyValue(request, response, uriInfo, requestedContentType);
|
||||
selectProcessor(PrimitiveProcessor.class)
|
||||
.readPrimitiveAsValue(request, response, uriInfo, requestedContentType);
|
||||
} else {
|
||||
throw new ODataHandlerException("Media Entity is not implemented.",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
}
|
||||
} else {
|
||||
throw new ODataHandlerException("not implemented",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ODataHandlerException("not implemented",
|
||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||
|
|
|
@ -25,10 +25,12 @@ import org.apache.olingo.server.api.OData;
|
|||
import org.apache.olingo.server.api.ODataHttpHandler;
|
||||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
import org.apache.olingo.server.api.edm.provider.EdmProvider;
|
||||
import org.apache.olingo.server.api.serializer.FixedFormatSerializer;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.core.serializer.ODataXmlSerializerImpl;
|
||||
import org.apache.olingo.server.core.serializer.FixedFormatSerializerImpl;
|
||||
import org.apache.olingo.server.core.serializer.json.ODataJsonSerializer;
|
||||
import org.apache.olingo.server.core.serializer.xml.ODataXmlSerializerImpl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -54,6 +56,11 @@ public class ODataImpl extends OData {
|
|||
return serializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FixedFormatSerializer createFixedFormatSerializer() throws SerializerException {
|
||||
return new FixedFormatSerializerImpl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ODataHttpHandler createHandler(final ServiceMetadata edm) {
|
||||
return new ODataHttpHandlerImpl(this, edm);
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.server.core.serializer;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
|
||||
import org.apache.olingo.server.api.serializer.FixedFormatSerializer;
|
||||
import org.apache.olingo.server.api.serializer.PrimitiveValueSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
|
||||
public class FixedFormatSerializerImpl implements FixedFormatSerializer {
|
||||
|
||||
@Override
|
||||
public InputStream binary(final byte[] binary) throws SerializerException {
|
||||
return new ByteArrayInputStream(binary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream count(final Integer count) throws SerializerException {
|
||||
return new ByteArrayInputStream(count.toString().getBytes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream primitiveValue(final EdmPrimitiveType type, final Object value,
|
||||
final PrimitiveValueSerializerOptions options) throws SerializerException {
|
||||
try {
|
||||
final String result = type.valueToString(value,
|
||||
options.isNullable(), options.getMaxLength(),
|
||||
options.getPrecision(), options.getScale(), options.isUnicode());
|
||||
return new ByteArrayInputStream(result.getBytes("UTF-8"));
|
||||
} catch (final EdmPrimitiveTypeException e) {
|
||||
throw new SerializerException("Error in primitive-value formatting.", e,
|
||||
SerializerException.MessageKeys.WRONG_PRIMITIVE_VALUE,
|
||||
type.getFullQualifiedName().getFullQualifiedNameAsString(), value.toString());
|
||||
} catch (final UnsupportedEncodingException e) {
|
||||
throw new SerializerException("Encoding exception.", e, SerializerException.MessageKeys.IO_EXCEPTION);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@ package org.apache.olingo.server.core.serializer.json;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -28,24 +29,28 @@ import org.apache.olingo.commons.api.data.ContextURL;
|
|||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.data.EntitySet;
|
||||
import org.apache.olingo.commons.api.data.Link;
|
||||
import org.apache.olingo.commons.api.data.Linked;
|
||||
import org.apache.olingo.commons.api.data.LinkedComplexValue;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.edm.Edm;
|
||||
import org.apache.olingo.commons.api.edm.EdmComplexType;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
||||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
import org.apache.olingo.commons.api.edm.EdmStructuredType;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
|
||||
import org.apache.olingo.server.api.ODataServerError;
|
||||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
import org.apache.olingo.server.api.serializer.ComplexSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
|
||||
import org.apache.olingo.server.api.uri.UriParameter;
|
||||
import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
|
||||
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
||||
|
@ -129,14 +134,14 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public InputStream entitySet(final EdmEntitySet edmEntitySet, final EntitySet entitySet,
|
||||
final ODataSerializerOptions options) throws SerializerException {
|
||||
public InputStream entityCollection(final EdmEntityType entityType, final EntitySet entitySet,
|
||||
final EntityCollectionSerializerOptions options) throws SerializerException {
|
||||
CircleStreamBuffer buffer = new CircleStreamBuffer();
|
||||
try {
|
||||
JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
|
||||
json.writeStartObject();
|
||||
|
||||
final ContextURL contextURL = checkContextURL(options);
|
||||
final ContextURL contextURL = checkContextURL(options == null ? null : options.getContextURL());
|
||||
if (contextURL != null) {
|
||||
json.writeStringField(Constants.JSON_CONTEXT,
|
||||
ContextURLBuilder.create(contextURL).toASCIIString());
|
||||
|
@ -147,7 +152,7 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
json.writeNumberField(Constants.JSON_COUNT, entitySet.getCount());
|
||||
}
|
||||
json.writeFieldName(Constants.VALUE);
|
||||
writeEntitySet(edmEntitySet.getEntityType(), entitySet,
|
||||
writeEntitySet(entityType, entitySet,
|
||||
options == null ? null : options.getExpand(), options == null ? null : options.getSelect(), json);
|
||||
if (entitySet.getNext() != null) {
|
||||
json.writeStringField(Constants.JSON_NEXT_LINK, entitySet.getNext().toASCIIString());
|
||||
|
@ -161,13 +166,13 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public InputStream entity(final EdmEntitySet edmEntitySet, final Entity entity,
|
||||
final ODataSerializerOptions options) throws SerializerException {
|
||||
final ContextURL contextURL = checkContextURL(options);
|
||||
public InputStream entity(final EdmEntityType entityType, final Entity entity,
|
||||
final EntitySerializerOptions options) throws SerializerException {
|
||||
final ContextURL contextURL = checkContextURL(options == null ? null : options.getContextURL());
|
||||
CircleStreamBuffer buffer = new CircleStreamBuffer();
|
||||
try {
|
||||
JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
|
||||
writeEntity(edmEntitySet.getEntityType(), entity, contextURL,
|
||||
writeEntity(entityType, entity, contextURL,
|
||||
options == null ? null : options.getExpand(), options == null ? null : options.getSelect(), json);
|
||||
json.close();
|
||||
} catch (final IOException e) {
|
||||
|
@ -177,16 +182,13 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
return buffer.getInputStream();
|
||||
}
|
||||
|
||||
private ContextURL checkContextURL(final ODataSerializerOptions options) throws SerializerException {
|
||||
private ContextURL checkContextURL(final ContextURL contextURL) throws SerializerException {
|
||||
if (format == ODataFormat.JSON_NO_METADATA) {
|
||||
return null;
|
||||
} else {
|
||||
final ContextURL contextURL = options == null ? null : options.getContextURL();
|
||||
if (contextURL == null) {
|
||||
throw new SerializerException("ContextURL null!", SerializerException.MessageKeys.NO_CONTEXT_URL);
|
||||
}
|
||||
return contextURL;
|
||||
} else if (contextURL == null) {
|
||||
throw new SerializerException("ContextURL null!", SerializerException.MessageKeys.NO_CONTEXT_URL);
|
||||
}
|
||||
return contextURL;
|
||||
}
|
||||
|
||||
protected void writeEntitySet(final EdmEntityType entityType, final EntitySet entitySet,
|
||||
|
@ -219,20 +221,20 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
}
|
||||
}
|
||||
}
|
||||
writeProperties(entityType, entity, select, json);
|
||||
writeProperties(entityType, entity.getProperties(), select, json);
|
||||
writeNavigationProperties(entityType, entity, expand, json);
|
||||
json.writeEndObject();
|
||||
}
|
||||
|
||||
protected void writeProperties(final EdmEntityType entityType, final Entity entity, final SelectOption select,
|
||||
JsonGenerator json) throws IOException, SerializerException {
|
||||
protected void writeProperties(final EdmStructuredType type, final List<Property> properties,
|
||||
final SelectOption select, JsonGenerator json) throws IOException, SerializerException {
|
||||
final boolean all = ExpandSelectHelper.isAll(select);
|
||||
final Set<String> selected = all ? null :
|
||||
ExpandSelectHelper.getSelectedPropertyNames(select.getSelectItems());
|
||||
for (final String propertyName : entityType.getPropertyNames()) {
|
||||
for (final String propertyName : type.getPropertyNames()) {
|
||||
if (all || selected.contains(propertyName)) {
|
||||
final EdmProperty edmProperty = entityType.getStructuralProperty(propertyName);
|
||||
final Property property = entity.getProperty(propertyName);
|
||||
final EdmProperty edmProperty = type.getStructuralProperty(propertyName);
|
||||
final Property property = findProperty(propertyName, properties);
|
||||
final Set<List<String>> selectedPaths = all || edmProperty.isPrimitive() ? null :
|
||||
ExpandSelectHelper.getSelectedPaths(select.getSelectItems(), propertyName);
|
||||
writeProperty(edmProperty, property, selectedPaths, json);
|
||||
|
@ -240,16 +242,16 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
}
|
||||
}
|
||||
|
||||
protected void writeNavigationProperties(final EdmEntityType entityType, final Entity entity,
|
||||
protected void writeNavigationProperties(final EdmStructuredType type, final Linked linked,
|
||||
final ExpandOption expand, final JsonGenerator json) throws SerializerException, IOException {
|
||||
if (ExpandSelectHelper.hasExpand(expand)) {
|
||||
final boolean expandAll = ExpandSelectHelper.isExpandAll(expand);
|
||||
final Set<String> expanded = expandAll ? null :
|
||||
ExpandSelectHelper.getExpandedPropertyNames(expand.getExpandItems());
|
||||
for (final String propertyName : entityType.getNavigationPropertyNames()) {
|
||||
for (final String propertyName : type.getNavigationPropertyNames()) {
|
||||
if (expandAll || expanded.contains(propertyName)) {
|
||||
final EdmNavigationProperty property = entityType.getNavigationProperty(propertyName);
|
||||
final Link navigationLink = entity.getNavigationLink(property.getName());
|
||||
final EdmNavigationProperty property = type.getNavigationProperty(propertyName);
|
||||
final Link navigationLink = linked.getNavigationLink(property.getName());
|
||||
final ExpandItem innerOptions = expandAll ? null :
|
||||
ExpandSelectHelper.getExpandItem(expand.getExpandItems(), propertyName);
|
||||
if (innerOptions != null && (innerOptions.isRef() || innerOptions.getLevelsOption() != null)) {
|
||||
|
@ -304,14 +306,25 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
final Property property, final Set<List<String>> selectedPaths,
|
||||
final JsonGenerator json) throws IOException, SerializerException {
|
||||
try {
|
||||
if (edmProperty.isCollection()) {
|
||||
writeCollection(edmProperty, property, selectedPaths, json);
|
||||
} else if (edmProperty.isPrimitive()) {
|
||||
writePrimitive(edmProperty, property, json);
|
||||
if (edmProperty.isPrimitive()) {
|
||||
if (edmProperty.isCollection()) {
|
||||
writePrimitiveCollection((EdmPrimitiveType) edmProperty.getType(), property,
|
||||
edmProperty.isNullable(), edmProperty.getMaxLength(),
|
||||
edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode(),
|
||||
json);
|
||||
} else {
|
||||
writePrimitive((EdmPrimitiveType) edmProperty.getType(), property,
|
||||
edmProperty.isNullable(), edmProperty.getMaxLength(),
|
||||
edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode(),
|
||||
json);
|
||||
}
|
||||
} else if (edmProperty.isCollection()) {
|
||||
writeComplexCollection((EdmComplexType) edmProperty.getType(), property, selectedPaths, json);
|
||||
} else if (property.isLinkedComplex()) {
|
||||
writeComplexValue(edmProperty, property.asLinkedComplex().getValue(), selectedPaths, json);
|
||||
writeComplexValue((EdmComplexType) edmProperty.getType(), property.asLinkedComplex().getValue(),
|
||||
selectedPaths, json);
|
||||
} else if (property.isComplex()) {
|
||||
writeComplexValue(edmProperty, property.asComplex(), selectedPaths, json);
|
||||
writeComplexValue((EdmComplexType) edmProperty.getType(), property.asComplex(), selectedPaths, json);
|
||||
} else {
|
||||
throw new SerializerException("Property type not yet supported!",
|
||||
SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, edmProperty.getName());
|
||||
|
@ -323,56 +336,75 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
}
|
||||
}
|
||||
|
||||
private void writeCollection(final EdmProperty edmProperty, final Property property,
|
||||
final Set<List<String>> selectedPaths, JsonGenerator json)
|
||||
throws IOException, EdmPrimitiveTypeException, SerializerException {
|
||||
private void writePrimitiveCollection(final EdmPrimitiveType type, final Property property,
|
||||
final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale,
|
||||
final Boolean isUnicode,
|
||||
JsonGenerator json) throws IOException, EdmPrimitiveTypeException, SerializerException {
|
||||
json.writeStartArray();
|
||||
for (Object value : property.asCollection()) {
|
||||
switch (property.getValueType()) {
|
||||
case COLLECTION_PRIMITIVE:
|
||||
writePrimitiveValue(edmProperty, value, json);
|
||||
writePrimitiveValue(type, value, isNullable, maxLength, precision, scale, isUnicode, json);
|
||||
break;
|
||||
case COLLECTION_GEOSPATIAL:
|
||||
throw new SerializerException("Property type not yet supported!",
|
||||
SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, edmProperty.getName());
|
||||
SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, property.getName());
|
||||
case COLLECTION_ENUM:
|
||||
json.writeString(value.toString());
|
||||
break;
|
||||
case COLLECTION_LINKED_COMPLEX:
|
||||
writeComplexValue(edmProperty, ((LinkedComplexValue) value).getValue(), selectedPaths, json);
|
||||
break;
|
||||
case COLLECTION_COMPLEX:
|
||||
writeComplexValue(edmProperty, property.asComplex(), selectedPaths, json);
|
||||
break;
|
||||
default:
|
||||
throw new SerializerException("Property type not yet supported!",
|
||||
SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, edmProperty.getName());
|
||||
SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, property.getName());
|
||||
}
|
||||
}
|
||||
json.writeEndArray();
|
||||
}
|
||||
|
||||
private void writePrimitive(EdmProperty edmProperty, Property property, JsonGenerator json)
|
||||
private void writeComplexCollection(final EdmComplexType type, final Property property,
|
||||
final Set<List<String>> selectedPaths, JsonGenerator json)
|
||||
throws IOException, EdmPrimitiveTypeException, SerializerException {
|
||||
json.writeStartArray();
|
||||
for (Object value : property.asCollection()) {
|
||||
switch (property.getValueType()) {
|
||||
case COLLECTION_LINKED_COMPLEX:
|
||||
writeComplexValue(type, ((LinkedComplexValue) value).getValue(), selectedPaths, json);
|
||||
break;
|
||||
case COLLECTION_COMPLEX:
|
||||
writeComplexValue(type, property.asComplex(), selectedPaths, json);
|
||||
break;
|
||||
default:
|
||||
throw new SerializerException("Property type not yet supported!",
|
||||
SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, property.getName());
|
||||
}
|
||||
}
|
||||
json.writeEndArray();
|
||||
}
|
||||
|
||||
private void writePrimitive(final EdmPrimitiveType type, final Property property,
|
||||
final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale,
|
||||
final Boolean isUnicode, JsonGenerator json)
|
||||
throws EdmPrimitiveTypeException, IOException, SerializerException {
|
||||
if (property.isPrimitive()) {
|
||||
writePrimitiveValue(edmProperty, property.asPrimitive(), json);
|
||||
writePrimitiveValue(type, property.asPrimitive(),
|
||||
isNullable, maxLength, precision, scale, isUnicode, json);
|
||||
} else if (property.isGeospatial()) {
|
||||
throw new SerializerException("Property type not yet supported!",
|
||||
SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, edmProperty.getName());
|
||||
SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, property.getName());
|
||||
} else if (property.isEnum()) {
|
||||
writePrimitiveValue(edmProperty, property.asEnum(), json);
|
||||
writePrimitiveValue(type, property.asEnum(),
|
||||
isNullable, maxLength, precision, scale, isUnicode, json);
|
||||
} else {
|
||||
throw new SerializerException("Inconsistent property type!",
|
||||
SerializerException.MessageKeys.INCONSISTENT_PROPERTY_TYPE, edmProperty.getName());
|
||||
SerializerException.MessageKeys.INCONSISTENT_PROPERTY_TYPE, property.getName());
|
||||
}
|
||||
}
|
||||
|
||||
protected void writePrimitiveValue(final EdmProperty edmProperty, final Object primitiveValue,
|
||||
protected void writePrimitiveValue(final EdmPrimitiveType type, final Object primitiveValue,
|
||||
final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale,
|
||||
final Boolean isUnicode,
|
||||
final JsonGenerator json) throws EdmPrimitiveTypeException, IOException {
|
||||
final EdmPrimitiveType type = (EdmPrimitiveType) edmProperty.getType();
|
||||
final String value = type.valueToString(primitiveValue,
|
||||
edmProperty.isNullable(), edmProperty.getMaxLength(),
|
||||
edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode());
|
||||
isNullable, maxLength, precision, scale, isUnicode);
|
||||
if (type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Boolean)) {
|
||||
json.writeBoolean(Boolean.parseBoolean(value));
|
||||
} else if (type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Byte)
|
||||
|
@ -389,18 +421,10 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
}
|
||||
}
|
||||
|
||||
protected void writeComplexValue(final EdmProperty edmProperty, final List<Property> properties,
|
||||
protected void writeComplexValue(final EdmComplexType type, final List<Property> properties,
|
||||
final Set<List<String>> selectedPaths, JsonGenerator json)
|
||||
throws IOException, EdmPrimitiveTypeException, SerializerException {
|
||||
json.writeStartObject();
|
||||
writePropertyValues(edmProperty, properties, selectedPaths, json);
|
||||
json.writeEndObject();
|
||||
}
|
||||
|
||||
private void writePropertyValues(final EdmProperty edmProperty,
|
||||
final List<Property> properties, final Set<List<String>> selectedPaths,
|
||||
JsonGenerator json) throws IOException, SerializerException {
|
||||
final EdmComplexType type = (EdmComplexType) edmProperty.getType();
|
||||
for (final String propertyName : type.getPropertyNames()) {
|
||||
final Property property = findProperty(propertyName, properties);
|
||||
if (selectedPaths == null || ExpandSelectHelper.isSelected(selectedPaths, propertyName)) {
|
||||
|
@ -409,6 +433,7 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
json);
|
||||
}
|
||||
}
|
||||
json.writeEndObject();
|
||||
}
|
||||
|
||||
private Property findProperty(final String propertyName, final List<Property> properties) {
|
||||
|
@ -421,9 +446,9 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public InputStream entityProperty(final EdmProperty edmProperty, final Property property,
|
||||
final ODataSerializerOptions options) throws SerializerException {
|
||||
final ContextURL contextURL = checkContextURL(options);
|
||||
public InputStream primitive(final EdmPrimitiveType type, final Property property,
|
||||
final PrimitiveSerializerOptions options) throws SerializerException {
|
||||
final ContextURL contextURL = checkContextURL(options == null ? null : options.getContextURL());
|
||||
CircleStreamBuffer buffer = new CircleStreamBuffer();
|
||||
try {
|
||||
JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
|
||||
|
@ -431,15 +456,45 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
if (contextURL != null) {
|
||||
json.writeStringField(Constants.JSON_CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString());
|
||||
}
|
||||
if (property.isPrimitive() && property.isNull()) {
|
||||
if (property.isNull()) {
|
||||
throw new SerializerException("Property value can not be null.", SerializerException.MessageKeys.NULL_INPUT);
|
||||
} else if (property.isComplex() && !property.isNull()) {
|
||||
writePropertyValues(edmProperty, property.asComplex(), null, json);
|
||||
} else if (property.isLinkedComplex() && !property.isNull()) {
|
||||
writePropertyValues(edmProperty, property.asLinkedComplex().getValue(), null, json);
|
||||
} else {
|
||||
json.writeFieldName(Constants.VALUE);
|
||||
writePropertyValue(edmProperty, property, null, json);
|
||||
writePrimitive(type, property,
|
||||
options.isNullable(), options.getMaxLength(), options.getPrecision(), options.getScale(),
|
||||
options.isUnicode(),
|
||||
json);
|
||||
}
|
||||
json.writeEndObject();
|
||||
json.close();
|
||||
} catch (final IOException e) {
|
||||
throw new SerializerException("An I/O exception occurred.", e,
|
||||
SerializerException.MessageKeys.IO_EXCEPTION);
|
||||
} catch (final EdmPrimitiveTypeException e) {
|
||||
throw new SerializerException("Wrong value for property!", e,
|
||||
SerializerException.MessageKeys.WRONG_PROPERTY_VALUE,
|
||||
property.getName(), property.getValue().toString());
|
||||
}
|
||||
return buffer.getInputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream complex(final EdmComplexType type, final Property property,
|
||||
final ComplexSerializerOptions options) throws SerializerException {
|
||||
final ContextURL contextURL = checkContextURL(options == null ? null : options.getContextURL());
|
||||
CircleStreamBuffer buffer = new CircleStreamBuffer();
|
||||
try {
|
||||
JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
|
||||
json.writeStartObject();
|
||||
if (contextURL != null) {
|
||||
json.writeStringField(Constants.JSON_CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString());
|
||||
}
|
||||
final List<Property> values = property.isNull() ? Collections.<Property> emptyList() :
|
||||
property.isComplex() ? property.asComplex() : property.asLinkedComplex().getValue();
|
||||
writeProperties(type, values, options == null ? null : options.getSelect(), json);
|
||||
if (!property.isNull() && property.isLinkedComplex()) {
|
||||
writeNavigationProperties(type, property.asLinkedComplex(),
|
||||
options == null ? null : options.getExpand(), json);
|
||||
}
|
||||
json.writeEndObject();
|
||||
json.close();
|
||||
|
@ -451,9 +506,64 @@ public class ODataJsonSerializer implements ODataSerializer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String buildContextURLSelectList(final EdmEntitySet edmEntitySet,
|
||||
public InputStream primitiveCollection(final EdmPrimitiveType type, final Property property,
|
||||
final PrimitiveSerializerOptions options) throws SerializerException {
|
||||
final ContextURL contextURL = checkContextURL(options == null ? null : options.getContextURL());
|
||||
CircleStreamBuffer buffer = new CircleStreamBuffer();
|
||||
try {
|
||||
JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
|
||||
json.writeStartObject();
|
||||
if (contextURL != null) {
|
||||
json.writeStringField(Constants.JSON_CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString());
|
||||
}
|
||||
json.writeFieldName(Constants.VALUE);
|
||||
writePrimitiveCollection(type, property,
|
||||
options.isNullable(), options.getMaxLength(), options.getPrecision(), options.getScale(),
|
||||
options.isUnicode(),
|
||||
json);
|
||||
json.writeEndObject();
|
||||
json.close();
|
||||
} catch (final IOException e) {
|
||||
throw new SerializerException("An I/O exception occurred.", e,
|
||||
SerializerException.MessageKeys.IO_EXCEPTION);
|
||||
} catch (final EdmPrimitiveTypeException e) {
|
||||
throw new SerializerException("Wrong value for property!", e,
|
||||
SerializerException.MessageKeys.WRONG_PROPERTY_VALUE,
|
||||
property.getName(), property.getValue().toString());
|
||||
}
|
||||
return buffer.getInputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream complexCollection(final EdmComplexType type, final Property property,
|
||||
final ComplexSerializerOptions options) throws SerializerException {
|
||||
final ContextURL contextURL = checkContextURL(options == null ? null : options.getContextURL());
|
||||
CircleStreamBuffer buffer = new CircleStreamBuffer();
|
||||
try {
|
||||
JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
|
||||
json.writeStartObject();
|
||||
if (contextURL != null) {
|
||||
json.writeStringField(Constants.JSON_CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString());
|
||||
}
|
||||
json.writeFieldName(Constants.VALUE);
|
||||
writeComplexCollection(type, property, null, json);
|
||||
json.writeEndObject();
|
||||
json.close();
|
||||
} catch (final IOException e) {
|
||||
throw new SerializerException("An I/O exception occurred.", e,
|
||||
SerializerException.MessageKeys.IO_EXCEPTION);
|
||||
} catch (final EdmPrimitiveTypeException e) {
|
||||
throw new SerializerException("Wrong value for property!", e,
|
||||
SerializerException.MessageKeys.WRONG_PROPERTY_VALUE,
|
||||
property.getName(), property.getValue().toString());
|
||||
}
|
||||
return buffer.getInputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildContextURLSelectList(final EdmStructuredType type,
|
||||
final ExpandOption expand, final SelectOption select) throws SerializerException {
|
||||
return ContextURLHelper.buildSelectList(edmEntitySet.getEntityType(), expand, select);
|
||||
return ContextURLHelper.buildSelectList(type, expand, select);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -56,12 +56,12 @@ public final class ContextURLBuilder {
|
|||
if (contextURL.getKeyPath() != null) {
|
||||
result.append('(').append(contextURL.getKeyPath()).append(')');
|
||||
}
|
||||
if (contextURL.getSelectList() != null) {
|
||||
result.append('(').append(contextURL.getSelectList()).append(')');
|
||||
}
|
||||
if (contextURL.getNavOrPropertyPath() != null) {
|
||||
result.append('/').append(contextURL.getNavOrPropertyPath());
|
||||
}
|
||||
if (contextURL.getSelectList() != null) {
|
||||
result.append('(').append(contextURL.getSelectList()).append(')');
|
||||
}
|
||||
if (contextURL.isReference()) {
|
||||
if (contextURL.getEntitySetOrSingletonOrType() != null) {
|
||||
throw new IllegalArgumentException("ContextURL: $ref with Entity Set");
|
||||
|
|
|
@ -24,8 +24,8 @@ import java.util.List;
|
|||
import java.util.Set;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.EdmComplexType;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
import org.apache.olingo.commons.api.edm.EdmStructuredType;
|
||||
import org.apache.olingo.commons.core.Encoder;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriParameter;
|
||||
|
@ -39,37 +39,37 @@ public final class ContextURLHelper {
|
|||
/** Builds a list of selected Properties for the ContextURL,
|
||||
* taking care to preserve the order as defined in the EDM;
|
||||
* returns NULL if no selection has taken place.
|
||||
* @param entityType the Entity Type
|
||||
* @param expand the Expand option (from the URL's $expand query option)
|
||||
* @param select the Select option (from the URL's $select query option)
|
||||
* @param type the structured type
|
||||
* @param expand the Expand option (from the URL's $expand query option)
|
||||
* @param select the Select option (from the URL's $select query option)
|
||||
* @return a select-list String
|
||||
* @throws SerializerException if an unsupported feature is used
|
||||
*/
|
||||
public static String buildSelectList(final EdmEntityType entityType,
|
||||
public static String buildSelectList(final EdmStructuredType type,
|
||||
final ExpandOption expand, final SelectOption select) throws SerializerException {
|
||||
StringBuilder result = new StringBuilder();
|
||||
if (ExpandSelectHelper.hasSelect(select)) {
|
||||
handleSelect(entityType, select, result);
|
||||
handleSelect(type, select, result);
|
||||
}
|
||||
|
||||
if (ExpandSelectHelper.hasExpand(expand) && !ExpandSelectHelper.isExpandAll(expand)) {
|
||||
handleExpand(entityType, expand, result);
|
||||
handleExpand(type, expand, result);
|
||||
}
|
||||
return result.length() == 0 ? null : result.toString();
|
||||
}
|
||||
|
||||
private static void handleSelect(final EdmEntityType entityType, final SelectOption select, StringBuilder result) {
|
||||
private static void handleSelect(final EdmStructuredType type, final SelectOption select, StringBuilder result) {
|
||||
if (ExpandSelectHelper.isAll(select)) {
|
||||
result.append('*');
|
||||
} else {
|
||||
final List<SelectItem> selectItems = select.getSelectItems();
|
||||
final Set<String> selectedPropertyNames = ExpandSelectHelper.getSelectedPropertyNames(selectItems);
|
||||
for (final String propertyName : entityType.getPropertyNames()) {
|
||||
for (final String propertyName : type.getPropertyNames()) {
|
||||
if (selectedPropertyNames.contains(propertyName)) {
|
||||
if (result.length() > 0) {
|
||||
result.append(',');
|
||||
}
|
||||
final EdmProperty edmProperty = (EdmProperty) entityType.getProperty(propertyName);
|
||||
final EdmProperty edmProperty = type.getStructuralProperty(propertyName);
|
||||
final Set<List<String>> selectedPaths = ExpandSelectHelper.getSelectedPaths(selectItems, propertyName);
|
||||
if (selectedPaths == null) {
|
||||
result.append(Encoder.encode(propertyName));
|
||||
|
@ -98,16 +98,16 @@ public final class ContextURLHelper {
|
|||
}
|
||||
}
|
||||
|
||||
private static void handleExpand(final EdmEntityType entityType, final ExpandOption expand, StringBuilder result)
|
||||
private static void handleExpand(final EdmStructuredType type, final ExpandOption expand, StringBuilder result)
|
||||
throws SerializerException {
|
||||
final Set<String> expandedPropertyNames = ExpandSelectHelper.getExpandedPropertyNames(expand.getExpandItems());
|
||||
for (final String propertyName : entityType.getNavigationPropertyNames()) {
|
||||
for (final String propertyName : type.getNavigationPropertyNames()) {
|
||||
if (expandedPropertyNames.contains(propertyName)) {
|
||||
final ExpandItem expandItem = ExpandSelectHelper.getExpandItem(expand.getExpandItems(), propertyName);
|
||||
if (ExpandSelectHelper.hasExpand(expandItem.getExpandOption())
|
||||
&& !ExpandSelectHelper.isExpandAll(expandItem.getExpandOption())
|
||||
|| ExpandSelectHelper.hasSelect(expandItem.getSelectOption())) {
|
||||
final String innerSelectList = buildSelectList(entityType.getNavigationProperty(propertyName).getType(),
|
||||
final String innerSelectList = buildSelectList(type.getNavigationProperty(propertyName).getType(),
|
||||
expandItem.getExpandOption(), expandItem.getSelectOption());
|
||||
if (innerSelectList != null) {
|
||||
if (result.length() > 0) {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.server.core.serializer;
|
||||
package org.apache.olingo.server.core.serializer.xml;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
@ -29,24 +29,31 @@ import org.apache.olingo.commons.api.data.Entity;
|
|||
import org.apache.olingo.commons.api.data.EntitySet;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.edm.Edm;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
import org.apache.olingo.commons.api.edm.EdmComplexType;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
||||
import org.apache.olingo.commons.api.edm.EdmStructuredType;
|
||||
import org.apache.olingo.server.api.ODataServerError;
|
||||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
import org.apache.olingo.server.api.serializer.ComplexSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
|
||||
import org.apache.olingo.server.api.uri.UriParameter;
|
||||
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
||||
import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
|
||||
import org.apache.olingo.server.core.serializer.utils.ContextURLHelper;
|
||||
import org.apache.olingo.server.core.serializer.xml.MetadataDocumentXmlSerializer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ODataXmlSerializerImpl implements ODataSerializer {
|
||||
|
||||
/** The default character set is UTF-8. */
|
||||
public static final String DEFAULT_CHARSET = "UTF-8";
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ODataXmlSerializerImpl.class);
|
||||
|
||||
@Override
|
||||
|
@ -87,15 +94,15 @@ public class ODataXmlSerializerImpl implements ODataSerializer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public InputStream entity(final EdmEntitySet edmEntitySet, final Entity entity,
|
||||
final ODataSerializerOptions options) throws SerializerException {
|
||||
public InputStream entity(final EdmEntityType entityType, final Entity entity,
|
||||
final EntitySerializerOptions options) throws SerializerException {
|
||||
throw new SerializerException("Entity serialization not implemented for XML format",
|
||||
SerializerException.MessageKeys.NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream entitySet(final EdmEntitySet edmEntitySet, final EntitySet entitySet,
|
||||
final ODataSerializerOptions options) throws SerializerException {
|
||||
public InputStream entityCollection(final EdmEntityType entityType, final EntitySet entitySet,
|
||||
final EntityCollectionSerializerOptions options) throws SerializerException {
|
||||
throw new SerializerException("Entityset serialization not implemented for XML format",
|
||||
SerializerException.MessageKeys.NOT_IMPLEMENTED);
|
||||
}
|
||||
|
@ -107,16 +114,37 @@ public class ODataXmlSerializerImpl implements ODataSerializer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public InputStream entityProperty(EdmProperty edmProperty, Property property,
|
||||
ODataSerializerOptions options) throws SerializerException{
|
||||
throw new SerializerException("error serialization not implemented for XML format",
|
||||
SerializerException.MessageKeys.NOT_IMPLEMENTED);
|
||||
public InputStream primitive(final EdmPrimitiveType type, final Property property,
|
||||
final PrimitiveSerializerOptions options) throws SerializerException {
|
||||
throw new SerializerException("Serialization not implemented for XML format.",
|
||||
SerializerException.MessageKeys.NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildContextURLSelectList(final EdmEntitySet edmEntitySet,
|
||||
public InputStream complex(final EdmComplexType type, final Property property,
|
||||
final ComplexSerializerOptions options) throws SerializerException {
|
||||
throw new SerializerException("Serialization not implemented for XML format.",
|
||||
SerializerException.MessageKeys.NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream primitiveCollection(final EdmPrimitiveType type, final Property property,
|
||||
final PrimitiveSerializerOptions options) throws SerializerException {
|
||||
throw new SerializerException("Serialization not implemented for XML format.",
|
||||
SerializerException.MessageKeys.NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream complexCollection(final EdmComplexType type, final Property property,
|
||||
final ComplexSerializerOptions options) throws SerializerException {
|
||||
throw new SerializerException("Serialization not implemented for XML format.",
|
||||
SerializerException.MessageKeys.NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildContextURLSelectList(final EdmStructuredType type,
|
||||
final ExpandOption expand, final SelectOption select) throws SerializerException {
|
||||
return ContextURLHelper.buildSelectList(edmEntitySet.getEntityType(), expand, select);
|
||||
return ContextURLHelper.buildSelectList(type, expand, select);
|
||||
}
|
||||
|
||||
@Override
|
|
@ -84,7 +84,6 @@ public class UriValidator {
|
|||
/* PUT 0 */ { false , false , false , false, false , false , false , false , false , false , false , false },
|
||||
/* DELETE 0 */ { false , false , false , false, false , false, false , false, false , false , false, false },
|
||||
/* PATCH 0 */ { false , false , false , false, false , false , false , false , false , false , false , false },
|
||||
/* MERGE 0 */ { false , false , false , false, false , false , false , false , false , false , false , false },
|
||||
};
|
||||
|
||||
//CHECKSTYLE:ON
|
||||
|
@ -154,8 +153,7 @@ public class UriValidator {
|
|||
POST(1),
|
||||
PUT(2),
|
||||
DELETE(3),
|
||||
MERGE(4),
|
||||
PATCH(5);
|
||||
PATCH(4);
|
||||
|
||||
private int idx;
|
||||
|
||||
|
@ -602,9 +600,6 @@ public class UriValidator {
|
|||
case PATCH:
|
||||
idx = RowIndexForHttpMethod.PATCH;
|
||||
break;
|
||||
case MERGE:
|
||||
idx = RowIndexForHttpMethod.MERGE;
|
||||
break;
|
||||
default:
|
||||
throw new UriValidationException("HTTP method not supported: " + httpMethod,
|
||||
UriValidationException.MessageKeys.UNSUPPORTED_HTTP_METHOD, httpMethod.toString());
|
||||
|
|
|
@ -94,6 +94,7 @@ SerializerException.UNSUPPORTED_PROPERTY_TYPE=The type of the property '%1$s' is
|
|||
SerializerException.INCONSISTENT_PROPERTY_TYPE=An inconsistency has been detected in the type definition of property '%1$s'.
|
||||
SerializerException.MISSING_PROPERTY=The non-nullable property '%1$s' is missing.
|
||||
SerializerException.WRONG_PROPERTY_VALUE=The value '%2$s' is not valid for property '%1$s'.
|
||||
SerializerException.WRONG_PRIMITIVE_VALUE=The value '%2$s' is not valid for the primitive type '%1$s' and the given facets.
|
||||
|
||||
BatchException.INVALID_BOUNDARY=Invalid boundary at line '%1$s'.
|
||||
BatchException.INVALID_CHANGESET_METHOD=Invalid method: a ChangeSet cannot contain retrieve requests at line '%1$s'.
|
||||
|
|
|
@ -38,7 +38,6 @@ public class ODataHttpHandlerImplTest {
|
|||
{ "GET", null, null, "GET" },
|
||||
{ "GET", "xxx", "yyy", "GET" },
|
||||
{ "PUT", "xxx", "yyy", "PUT" },
|
||||
{ "MERGE", "xxx", "yyy", "MERGE" },
|
||||
{ "DELETE", "xxx", "yyy", "DELETE" },
|
||||
{ "PATCH", "xxx", "yyy", "PATCH" },
|
||||
|
||||
|
@ -47,7 +46,7 @@ public class ODataHttpHandlerImplTest {
|
|||
{ "POST", null, "PATCH", "PATCH" },
|
||||
|
||||
{ "POST", "GET", null, "GET" },
|
||||
{ "POST", "MERGE", null, "MERGE" },
|
||||
{ "POST", "PATCH", null, "PATCH" },
|
||||
|
||||
{ "POST", "GET", "GET", "GET" },
|
||||
};
|
||||
|
@ -71,7 +70,7 @@ public class ODataHttpHandlerImplTest {
|
|||
public void extractMethodFail() throws Exception {
|
||||
String[][] mm = {
|
||||
{ "POST", "bla", null },
|
||||
{ "POST", "MERGE", "PATCH" },
|
||||
{ "POST", "PUT", "PATCH" },
|
||||
{ "OPTIONS", null, null },
|
||||
{ "HEAD", null, null },
|
||||
};
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.server.core.serializer;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
||||
import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.apache.olingo.server.api.serializer.FixedFormatSerializer;
|
||||
import org.apache.olingo.server.api.serializer.PrimitiveValueSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.junit.Test;
|
||||
|
||||
public class FixedFormatSerializerTest {
|
||||
|
||||
private final FixedFormatSerializer serializer;
|
||||
|
||||
public FixedFormatSerializerTest() throws SerializerException {
|
||||
serializer = OData.newInstance().createFixedFormatSerializer();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void binary() throws Exception {
|
||||
assertEquals("ABC", IOUtils.toString(serializer.binary(new byte [] { 0x41, 0x42, 0x43 })));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void count() throws Exception {
|
||||
assertEquals("42", IOUtils.toString(serializer.count(42)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void primitiveValue() throws Exception {
|
||||
final EdmPrimitiveType type = EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Int32);
|
||||
assertEquals("42", IOUtils.toString(serializer.primitiveValue(type, 42,
|
||||
PrimitiveValueSerializerOptions.with().nullable(true).build())));
|
||||
}
|
||||
}
|
|
@ -119,9 +119,10 @@ public class ContextURLBuilderTest {
|
|||
contextURL = ContextURL.with().serviceRoot(URI.create("http://host/service/"))
|
||||
.entitySet(entitySet)
|
||||
.keyPath("one=1,two='two'")
|
||||
.navOrPropertyPath("Name")
|
||||
.navOrPropertyPath("ComplexName")
|
||||
.selectList("Part1")
|
||||
.build();
|
||||
assertEquals("http://host/service/$metadata#Customers(one=1,two='two')/Name",
|
||||
assertEquals("http://host/service/$metadata#Customers(one=1,two='two')/ComplexName(Part1)",
|
||||
ContextURLBuilder.create(contextURL).toASCIIString());
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,8 @@ import org.apache.olingo.server.api.ServiceMetadata;
|
|||
import org.apache.olingo.server.api.edmx.EdmxReference;
|
||||
import org.apache.olingo.server.api.edmx.EdmxReferenceInclude;
|
||||
import org.apache.olingo.server.tecsvc.data.DataProvider;
|
||||
import org.apache.olingo.server.tecsvc.processor.TechnicalProcessor;
|
||||
import org.apache.olingo.server.tecsvc.processor.TechnicalEntityProcessor;
|
||||
import org.apache.olingo.server.tecsvc.processor.TechnicalPrimitiveComplexProcessor;
|
||||
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -64,7 +65,8 @@ public class TechnicalServlet extends HttpServlet {
|
|||
}
|
||||
|
||||
ODataHttpHandler handler = odata.createHandler(serviceMetadata);
|
||||
handler.register(new TechnicalProcessor(dataProvider));
|
||||
handler.register(new TechnicalEntityProcessor(dataProvider));
|
||||
handler.register(new TechnicalPrimitiveComplexProcessor(dataProvider));
|
||||
handler.process(req, resp);
|
||||
} catch (RuntimeException e) {
|
||||
LOG.error("Server Error", e);
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.server.tecsvc.processor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.olingo.commons.api.data.ContextURL;
|
||||
import org.apache.olingo.commons.api.data.ContextURL.Suffix;
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.data.EntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.processor.CountEntityCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntityProcessor;
|
||||
import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.api.uri.UriResource;
|
||||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
||||
import org.apache.olingo.server.tecsvc.data.DataProvider;
|
||||
|
||||
/**
|
||||
* Technical Processor for entity-related functionality.
|
||||
*/
|
||||
public class TechnicalEntityProcessor extends TechnicalProcessor
|
||||
implements EntityCollectionProcessor, CountEntityCollectionProcessor, EntityProcessor {
|
||||
|
||||
public TechnicalEntityProcessor(final DataProvider dataProvider) {
|
||||
super(dataProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntityCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
|
||||
validateOptions(uriInfo.asUriInfoResource());
|
||||
if (uriInfo.asUriInfoResource().getUriResourceParts().size() > 1) {
|
||||
throw new ODataApplicationException("Invalid resource type.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
|
||||
final EntitySet entitySet = readEntitySetInternal(edmEntitySet,
|
||||
uriInfo.getCountOption() != null && uriInfo.getCountOption().getValue());
|
||||
if (entitySet == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
|
||||
ODataSerializer serializer = odata.createSerializer(format);
|
||||
final ExpandOption expand = uriInfo.getExpandOption();
|
||||
final SelectOption select = uriInfo.getSelectOption();
|
||||
response.setContent(serializer.entityCollection(edmEntitySet.getEntityType(), entitySet,
|
||||
EntityCollectionSerializerOptions.with()
|
||||
.contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
|
||||
getContextUrl(serializer, edmEntitySet, false, expand, select))
|
||||
.count(uriInfo.getCountOption())
|
||||
.expand(expand).select(select)
|
||||
.build()));
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void countEntityCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
|
||||
validateOptions(uriInfo.asUriInfoResource());
|
||||
final List<UriResource> resourceParts = uriInfo.asUriInfoResource().getUriResourceParts();
|
||||
final int pos = resourceParts.size() - 2;
|
||||
if (pos > 0) {
|
||||
throw new ODataApplicationException("Invalid resource type.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
final EntitySet entitySet =
|
||||
readEntitySetInternal(((UriResourceEntitySet) resourceParts.get(pos)).getEntitySet(), true);
|
||||
if (entitySet == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
response.setContent(odata.createFixedFormatSerializer().count(entitySet.getCount()));
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
|
||||
validateOptions(uriInfo.asUriInfoResource());
|
||||
if (uriInfo.asUriInfoResource().getUriResourceParts().size() > 1) {
|
||||
throw new ODataApplicationException("Invalid resource type.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
|
||||
final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0);
|
||||
final Entity entity = dataProvider.read(edmEntitySet, resourceEntitySet.getKeyPredicates());
|
||||
|
||||
if (entity == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
|
||||
ODataSerializer serializer = odata.createSerializer(format);
|
||||
final ExpandOption expand = uriInfo.getExpandOption();
|
||||
final SelectOption select = uriInfo.getSelectOption();
|
||||
response.setContent(serializer.entity(edmEntitySet.getEntityType(), entity,
|
||||
EntitySerializerOptions.with()
|
||||
.contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
|
||||
getContextUrl(serializer, edmEntitySet, true, expand, select))
|
||||
.expand(expand).select(select)
|
||||
.build()));
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
|
||||
}
|
||||
}
|
||||
|
||||
private EntitySet readEntitySetInternal(final EdmEntitySet edmEntitySet, final boolean withCount)
|
||||
throws DataProvider.DataProviderException {
|
||||
EntitySet entitySet = dataProvider.readAll(edmEntitySet);
|
||||
// TODO: set count (correctly) and next link
|
||||
if (withCount && entitySet.getCount() == null) {
|
||||
entitySet.setCount(entitySet.getEntities().size());
|
||||
}
|
||||
return entitySet;
|
||||
}
|
||||
|
||||
private ContextURL getContextUrl(final ODataSerializer serializer,
|
||||
final EdmEntitySet entitySet, final boolean isSingleEntity,
|
||||
final ExpandOption expand, final SelectOption select) throws SerializerException {
|
||||
return ContextURL.with().entitySet(entitySet)
|
||||
.selectList(serializer.buildContextURLSelectList(entitySet.getEntityType(), expand, select))
|
||||
.suffix(isSingleEntity ? Suffix.ENTITY : null)
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.server.tecsvc.processor;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.olingo.commons.api.data.ContextURL;
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.edm.EdmComplexType;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
||||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
import org.apache.olingo.commons.api.edm.EdmStructuredType;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.processor.ComplexCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.ComplexProcessor;
|
||||
import org.apache.olingo.server.api.processor.PrimitiveCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.PrimitiveProcessor;
|
||||
import org.apache.olingo.server.api.serializer.ComplexSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.FixedFormatSerializer;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.PrimitiveValueSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.RepresentationType;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.api.uri.UriInfoResource;
|
||||
import org.apache.olingo.server.api.uri.UriResource;
|
||||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||
import org.apache.olingo.server.api.uri.UriResourceKind;
|
||||
import org.apache.olingo.server.api.uri.UriResourceProperty;
|
||||
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
||||
import org.apache.olingo.server.tecsvc.data.DataProvider;
|
||||
|
||||
/**
|
||||
* Technical Processor which provides functionality related to primitive and complex types and collections thereof.
|
||||
*/
|
||||
public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
|
||||
implements PrimitiveProcessor, PrimitiveCollectionProcessor, ComplexProcessor, ComplexCollectionProcessor {
|
||||
|
||||
public TechnicalPrimitiveComplexProcessor(final DataProvider dataProvider) {
|
||||
super(dataProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readPrimitive(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
||||
readProperty(response, uriInfo, contentType, RepresentationType.PRIMITIVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readPrimitiveCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
||||
readProperty(response, uriInfo, contentType, RepresentationType.COLLECTION_PRIMITIVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readComplex(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
||||
readProperty(response, uriInfo, contentType, RepresentationType.COMPLEX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readComplexCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
||||
readProperty(response, uriInfo, contentType, RepresentationType.COLLECTION_COMPLEX);
|
||||
}
|
||||
|
||||
private void readProperty(ODataResponse response, final UriInfo uriInfo, final ContentType contentType,
|
||||
final RepresentationType representationType) throws ODataApplicationException, SerializerException {
|
||||
final UriInfoResource resource = uriInfo.asUriInfoResource();
|
||||
validateOptions(resource);
|
||||
validatePath(resource);
|
||||
|
||||
final List<UriResource> resourceParts = resource.getUriResourceParts();
|
||||
final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) resourceParts.get(0);
|
||||
final List<String> path = getPropertyPath(resourceParts);
|
||||
|
||||
final Property property = getPropertyData(resourceEntitySet, path);
|
||||
|
||||
if (property == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
if (property.getValue() == null) {
|
||||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||
} else {
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(resource);
|
||||
final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(path.size())).getProperty();
|
||||
|
||||
final ODataFormat format = ODataFormat.fromContentType(contentType);
|
||||
ODataSerializer serializer = odata.createSerializer(format);
|
||||
final ExpandOption expand = uriInfo.getExpandOption();
|
||||
final SelectOption select = uriInfo.getSelectOption();
|
||||
final ContextURL contextURL = format == ODataFormat.JSON_NO_METADATA ? null :
|
||||
ContextURL.with().entitySet(edmEntitySet)
|
||||
.keyPath(serializer.buildContextURLKeyPredicate(
|
||||
((UriResourceEntitySet) resourceParts.get(0)).getKeyPredicates()))
|
||||
.navOrPropertyPath(buildPropertyPath(path))
|
||||
.selectList(edmProperty.isPrimitive() ? null :
|
||||
serializer.buildContextURLSelectList((EdmStructuredType) edmProperty.getType(), expand, select))
|
||||
.build();
|
||||
switch (representationType) {
|
||||
case PRIMITIVE:
|
||||
response.setContent(serializer.primitive((EdmPrimitiveType) edmProperty.getType(), property,
|
||||
PrimitiveSerializerOptions.with().contextURL(contextURL).facetsFrom(edmProperty).build()));
|
||||
break;
|
||||
case COMPLEX:
|
||||
response.setContent(serializer.complex((EdmComplexType) edmProperty.getType(), property,
|
||||
ComplexSerializerOptions.with().contextURL(contextURL)
|
||||
.expand(expand).select(select)
|
||||
.build()));
|
||||
break;
|
||||
case COLLECTION_PRIMITIVE:
|
||||
response.setContent(serializer.primitiveCollection((EdmPrimitiveType) edmProperty.getType(), property,
|
||||
PrimitiveSerializerOptions.with().contextURL(contextURL).facetsFrom(edmProperty).build()));
|
||||
break;
|
||||
case COLLECTION_COMPLEX:
|
||||
response.setContent(serializer.complexCollection((EdmComplexType) edmProperty.getType(), property,
|
||||
ComplexSerializerOptions.with().contextURL(contextURL)
|
||||
.expand(expand).select(select)
|
||||
.build()));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Property getPropertyData(final UriResourceEntitySet resourceEntitySet, final List<String> path)
|
||||
throws ODataApplicationException {
|
||||
final Entity entity = dataProvider.read(resourceEntitySet.getEntitySet(), resourceEntitySet.getKeyPredicates());
|
||||
if (entity == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
Property property = entity.getProperty(path.get(0));
|
||||
for (final String name : path.subList(1, path.size())) {
|
||||
if (property != null && (property.isLinkedComplex() || property.isComplex())) {
|
||||
final List<Property> complex = property.isLinkedComplex() ?
|
||||
property.asLinkedComplex().getValue() : property.asComplex();
|
||||
property = null;
|
||||
for (final Property innerProperty : complex) {
|
||||
if (innerProperty.getName().equals(name)) {
|
||||
property = innerProperty;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return property;
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getPropertyPath(final List<UriResource> path) {
|
||||
List<String> result = new LinkedList<String>();
|
||||
int index = 1;
|
||||
while (index < path.size() && path.get(index) instanceof UriResourceProperty) {
|
||||
result.add(((UriResourceProperty) path.get(index)).getProperty().getName());
|
||||
index++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private String buildPropertyPath(final List<String> path) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (final String segment : path) {
|
||||
result.append(result.length() == 0 ? "" : '/').append(segment);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readPrimitiveAsValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
||||
final UriInfoResource resource = uriInfo.asUriInfoResource();
|
||||
validateOptions(resource);
|
||||
validatePath(resource);
|
||||
|
||||
final List<UriResource> resourceParts = resource.getUriResourceParts();
|
||||
final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) resourceParts.get(0);
|
||||
final List<String> path = getPropertyPath(resourceParts);
|
||||
|
||||
final Property property = getPropertyData(resourceEntitySet, path);
|
||||
|
||||
if (property == null || property.getValue() == null) {
|
||||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||
} else {
|
||||
final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(path.size())).getProperty();
|
||||
final EdmPrimitiveType type = (EdmPrimitiveType) edmProperty.getType();
|
||||
final FixedFormatSerializer serializer = odata.createFixedFormatSerializer();
|
||||
response.setContent(type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary) ?
|
||||
serializer.binary((byte[]) property.getValue()) :
|
||||
serializer.primitiveValue(type, property.getValue(),
|
||||
PrimitiveValueSerializerOptions.with().facetsFrom(edmProperty).build()));
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
}
|
||||
}
|
||||
|
||||
private void validatePath(final UriInfoResource uriInfo) throws ODataApplicationException {
|
||||
final List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
|
||||
for (final UriResource segment : resourcePaths.subList(1, resourcePaths.size())) {
|
||||
final UriResourceKind kind = segment.getKind();
|
||||
if (kind != UriResourceKind.primitiveProperty
|
||||
&& kind != UriResourceKind.complexProperty
|
||||
&& kind != UriResourceKind.count
|
||||
&& kind != UriResourceKind.value) {
|
||||
throw new ODataApplicationException("Invalid resource type.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,67 +18,30 @@
|
|||
*/
|
||||
package org.apache.olingo.server.tecsvc.processor;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||
import org.apache.olingo.commons.api.data.ContextURL;
|
||||
import org.apache.olingo.commons.api.data.ContextURL.Suffix;
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.data.EntitySet;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.edm.EdmComplexType;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
||||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
import org.apache.olingo.commons.api.http.HttpContentType;
|
||||
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
import org.apache.olingo.server.api.batch.BatchException;
|
||||
import org.apache.olingo.server.api.batch.BatchOperation;
|
||||
import org.apache.olingo.server.api.batch.BatchRequestPart;
|
||||
import org.apache.olingo.server.api.batch.ODataResponsePart;
|
||||
import org.apache.olingo.server.api.processor.BatchProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntityProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntitySetProcessor;
|
||||
import org.apache.olingo.server.api.processor.PropertyProcessor;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.api.processor.Processor;
|
||||
import org.apache.olingo.server.api.uri.UriInfoResource;
|
||||
import org.apache.olingo.server.api.uri.UriParameter;
|
||||
import org.apache.olingo.server.api.uri.UriResource;
|
||||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||
import org.apache.olingo.server.api.uri.UriResourceKind;
|
||||
import org.apache.olingo.server.api.uri.UriResourceProperty;
|
||||
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
||||
import org.apache.olingo.server.tecsvc.data.DataProvider;
|
||||
|
||||
/**
|
||||
* Technical Processor which provides currently implemented processor functionality.
|
||||
* Technical Processor base.
|
||||
*/
|
||||
public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor, PropertyProcessor {
|
||||
public abstract class TechnicalProcessor implements Processor {
|
||||
|
||||
private OData odata;
|
||||
private DataProvider dataProvider;
|
||||
protected OData odata;
|
||||
protected DataProvider dataProvider;
|
||||
|
||||
public TechnicalProcessor(final DataProvider dataProvider) {
|
||||
protected TechnicalProcessor(final DataProvider dataProvider) {
|
||||
this.dataProvider = dataProvider;
|
||||
}
|
||||
|
||||
|
@ -87,92 +50,23 @@ public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor,
|
|||
this.odata = odata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntitySet(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
|
||||
validateOptions(uriInfo.asUriInfoResource());
|
||||
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
|
||||
final EntitySet entitySet = readEntitySetInternal(edmEntitySet,
|
||||
uriInfo.getCountOption() != null && uriInfo.getCountOption().getValue());
|
||||
if (entitySet == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
|
||||
ODataSerializer serializer = odata.createSerializer(format);
|
||||
final ExpandOption expand = uriInfo.getExpandOption();
|
||||
final SelectOption select = uriInfo.getSelectOption();
|
||||
response.setContent(serializer.entitySet(edmEntitySet, entitySet,
|
||||
ODataSerializerOptions.with()
|
||||
.contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
|
||||
getContextUrl(serializer, edmEntitySet, false, expand, select, null, null))
|
||||
.count(uriInfo.getCountOption())
|
||||
.expand(expand).select(select)
|
||||
.build()));
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
|
||||
protected EdmEntitySet getEdmEntitySet(final UriInfoResource uriInfo) throws ODataApplicationException {
|
||||
final List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
|
||||
// first must be entity set
|
||||
if (!(resourcePaths.get(0) instanceof UriResourceEntitySet)) {
|
||||
throw new ODataApplicationException("Invalid resource type.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
|
||||
validateOptions(uriInfo.asUriInfoResource());
|
||||
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
|
||||
final Entity entity = readEntityInternal(uriInfo.asUriInfoResource(), edmEntitySet);
|
||||
if (entity == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
|
||||
ODataSerializer serializer = odata.createSerializer(format);
|
||||
final ExpandOption expand = uriInfo.getExpandOption();
|
||||
final SelectOption select = uriInfo.getSelectOption();
|
||||
response.setContent(serializer.entity(edmEntitySet, entity,
|
||||
ODataSerializerOptions.with()
|
||||
.contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
|
||||
getContextUrl(serializer, edmEntitySet, true, expand, select, null, null))
|
||||
.count(uriInfo.getCountOption())
|
||||
.expand(expand).select(select)
|
||||
.build()));
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
|
||||
final UriResourceEntitySet uriResource = (UriResourceEntitySet) resourcePaths.get(0);
|
||||
if (uriResource.getTypeFilterOnCollection() != null || uriResource.getTypeFilterOnEntry() != null) {
|
||||
throw new ODataApplicationException("Type filters are not supported.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
return uriResource.getEntitySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void countEntitySet(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
|
||||
throws ODataApplicationException, SerializerException {
|
||||
final List<UriResource> resourceParts = uriInfo.asUriInfoResource().getUriResourceParts();
|
||||
final int pos = resourceParts.size() - 2;
|
||||
final EntitySet entitySet =
|
||||
readEntitySetInternal(((UriResourceEntitySet) resourceParts.get(pos)).getEntitySet(), true);
|
||||
if (entitySet == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
response.setContent(new ByteArrayInputStream(entitySet.getCount().toString().getBytes()));
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, HttpContentType.TEXT_PLAIN);
|
||||
}
|
||||
}
|
||||
|
||||
private EntitySet readEntitySetInternal(final EdmEntitySet edmEntitySet,
|
||||
final boolean withCount) throws DataProvider.DataProviderException {
|
||||
EntitySet entitySet = dataProvider.readAll(edmEntitySet);
|
||||
// TODO: set count (correctly) and next link
|
||||
if (withCount && entitySet.getCount() == null) {
|
||||
entitySet.setCount(entitySet.getEntities().size());
|
||||
}
|
||||
return entitySet;
|
||||
}
|
||||
|
||||
private Entity readEntityInternal(final UriInfoResource uriInfo, final EdmEntitySet entitySet)
|
||||
throws DataProvider.DataProviderException {
|
||||
final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0);
|
||||
return dataProvider.read(entitySet, resourceEntitySet.getKeyPredicates());
|
||||
}
|
||||
|
||||
private void validateOptions(final UriInfoResource uriInfo) throws ODataApplicationException {
|
||||
protected void validateOptions(final UriInfoResource uriInfo) throws ODataApplicationException {
|
||||
if (uriInfo.getCountOption() != null
|
||||
|| !uriInfo.getCustomQueryOptions().isEmpty()
|
||||
|| uriInfo.getFilterOption() != null
|
||||
|
@ -186,151 +80,4 @@ public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor,
|
|||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
private EdmEntitySet getEdmEntitySet(final UriInfoResource uriInfo) throws ODataApplicationException {
|
||||
final List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
|
||||
// first must be entity set
|
||||
if (!(resourcePaths.get(0) instanceof UriResourceEntitySet)) {
|
||||
throw new ODataApplicationException("Invalid resource type.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
List<UriResource> subResPaths = resourcePaths.subList(1, resourcePaths.size());
|
||||
for (UriResource subResPath : subResPaths) {
|
||||
UriResourceKind kind = subResPath.getKind();
|
||||
if (kind != UriResourceKind.primitiveProperty
|
||||
&& kind != UriResourceKind.complexProperty
|
||||
&& kind != UriResourceKind.count
|
||||
&& kind != UriResourceKind.value) {
|
||||
throw new ODataApplicationException("Invalid resource type.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
final UriResourceEntitySet uriResource = (UriResourceEntitySet) resourcePaths.get(0);
|
||||
if (uriResource.getTypeFilterOnCollection() != null || uriResource.getTypeFilterOnEntry() != null) {
|
||||
throw new ODataApplicationException("Type filters are not supported.",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
return uriResource.getEntitySet();
|
||||
}
|
||||
|
||||
private ContextURL getContextUrl(final ODataSerializer serializer,
|
||||
final EdmEntitySet entitySet, final boolean isSingleEntity,
|
||||
final ExpandOption expand, final SelectOption select,
|
||||
final List<UriParameter> keys, final String propertyPath) throws SerializerException {
|
||||
|
||||
return ContextURL.with().entitySet(entitySet)
|
||||
.selectList(serializer.buildContextURLSelectList(entitySet, expand, select))
|
||||
.suffix(isSingleEntity && propertyPath == null ? Suffix.ENTITY : null)
|
||||
.keyPath(serializer.buildContextURLKeyPredicate(keys))
|
||||
.navOrPropertyPath(propertyPath)
|
||||
.build();
|
||||
}
|
||||
@Override
|
||||
public void readProperty(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
||||
validateOptions(uriInfo.asUriInfoResource());
|
||||
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
|
||||
final List<UriResource> resourceParts = uriInfo.getUriResourceParts();
|
||||
final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) resourceParts.get(0);
|
||||
final Entity entity = readEntityInternal(uriInfo.asUriInfoResource(), edmEntitySet);
|
||||
|
||||
if (entity == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
final List<String> path = getPropertyPath(resourceParts);
|
||||
EdmProperty edmProperty = edmEntitySet.getEntityType().getStructuralProperty(path.get(0));
|
||||
Property property = entity.getProperty(path.get(0));
|
||||
for (final String name : path.subList(1, path.size())) {
|
||||
if (property != null && (property.isLinkedComplex() || property.isComplex())) {
|
||||
edmProperty = ((EdmComplexType) edmProperty.getType()).getStructuralProperty(name);
|
||||
final List<Property> complex = property.isLinkedComplex() ?
|
||||
property.asLinkedComplex().getValue() :
|
||||
property.asComplex();
|
||||
property = null;
|
||||
for (final Property innerProperty : complex) {
|
||||
if (innerProperty.getName().equals(name)) {
|
||||
property = innerProperty;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (property == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
if (property.getValue() == null) {
|
||||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||
} else {
|
||||
final ODataFormat format = ODataFormat.fromContentType(contentType);
|
||||
ODataSerializer serializer = odata.createSerializer(format);
|
||||
response.setContent(serializer.entityProperty(edmProperty, property,
|
||||
ODataSerializerOptions.with().contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
|
||||
getContextUrl(serializer, edmEntitySet, true, null, null,
|
||||
resourceEntitySet.getKeyPredicates(), buildPropertyPath(path)))
|
||||
.build()));
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getPropertyPath(final List<UriResource> path) {
|
||||
List<String> result = new LinkedList<String>();
|
||||
int index = path.size();
|
||||
while (path.get(--index) instanceof UriResourceProperty) {
|
||||
result.add(0, ((UriResourceProperty) path.get(index)).getProperty().getName());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private String buildPropertyPath(final List<String> path) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (final String segment : path) {
|
||||
result.append(result.length() == 0 ? "" : '/').append(segment);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readPropertyValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType contentType) throws ODataApplicationException, SerializerException {
|
||||
validateOptions(uriInfo.asUriInfoResource());
|
||||
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
|
||||
final Entity entity = readEntityInternal(uriInfo.asUriInfoResource(), edmEntitySet);
|
||||
if (entity == null) {
|
||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||
} else {
|
||||
final UriResourceProperty uriProperty =
|
||||
(UriResourceProperty) uriInfo.getUriResourceParts().get(uriInfo.getUriResourceParts().size() - 2);
|
||||
final EdmProperty edmProperty = uriProperty.getProperty();
|
||||
final Property property = entity.getProperty(edmProperty.getName());
|
||||
if (property == null || property.getValue() == null) {
|
||||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||
} else {
|
||||
final EdmPrimitiveType type = (EdmPrimitiveType) edmProperty.getType();
|
||||
if (type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary)) {
|
||||
response.setContent(new ByteArrayInputStream((byte[]) property.getValue()));
|
||||
} else {
|
||||
try {
|
||||
final String value = type.valueToString(property.getValue(),
|
||||
edmProperty.isNullable(), edmProperty.getMaxLength(),
|
||||
edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode());
|
||||
response.setContent(new ByteArrayInputStream(value.getBytes("UTF-8")));
|
||||
} catch (final EdmPrimitiveTypeException e) {
|
||||
throw new ODataApplicationException("Error in value formatting.",
|
||||
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, e);
|
||||
} catch (final UnsupportedEncodingException e) {
|
||||
throw new ODataApplicationException("Encoding exception.",
|
||||
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, e);
|
||||
}
|
||||
}
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,210 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.server.core;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.olingo.commons.api.ODataException;
|
||||
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.http.HttpMethod;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
import org.apache.olingo.server.api.edm.provider.EdmProvider;
|
||||
import org.apache.olingo.server.api.edm.provider.EntitySet;
|
||||
import org.apache.olingo.server.api.edmx.EdmxReference;
|
||||
import org.apache.olingo.server.api.processor.MetadataProcessor;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ODataHandlerExceptionHandlingTest {
|
||||
private ODataHandler handler;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
OData odata = OData.newInstance();
|
||||
ServiceMetadata metadata = odata.createServiceMetadata(
|
||||
new EdmTechProvider(), Collections.<EdmxReference>emptyList());
|
||||
|
||||
handler = new ODataHandler(odata, metadata);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrongHttpMethodForMetadataDocument() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
request.setMethod(HttpMethod.POST);
|
||||
request.setRawODataPath("$metadata");
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
|
||||
request = new ODataRequest();
|
||||
request.setMethod(HttpMethod.PUT);
|
||||
request.setRawODataPath("$metadata");
|
||||
response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
|
||||
request = new ODataRequest();
|
||||
request.setMethod(HttpMethod.PATCH);
|
||||
request.setRawODataPath("$metadata");
|
||||
response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
|
||||
request = new ODataRequest();
|
||||
request.setMethod(HttpMethod.MERGE);
|
||||
request.setRawODataPath("$metadata");
|
||||
response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
|
||||
request = new ODataRequest();
|
||||
request.setMethod(HttpMethod.DELETE);
|
||||
request.setRawODataPath("$metadata");
|
||||
response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrongHttpMethodForServiceDocument() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
request.setMethod(HttpMethod.POST);
|
||||
request.setRawODataPath("");
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
|
||||
request = new ODataRequest();
|
||||
request.setMethod(HttpMethod.PUT);
|
||||
request.setRawODataPath("");
|
||||
response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
|
||||
request = new ODataRequest();
|
||||
request.setMethod(HttpMethod.PATCH);
|
||||
request.setRawODataPath("");
|
||||
response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
|
||||
request = new ODataRequest();
|
||||
request.setMethod(HttpMethod.MERGE);
|
||||
request.setRawODataPath("");
|
||||
response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
|
||||
request = new ODataRequest();
|
||||
request.setMethod(HttpMethod.DELETE);
|
||||
request.setRawODataPath("");
|
||||
response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUriParserExceptionResultsInRightResponseNotFound() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("NotFound");
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUriParserExceptionResultsInRightResponseBadRequest() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("ESAllPrim('122')");
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUriParserExceptionResultsInRightResponseEdmCause() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("EdmException");
|
||||
|
||||
OData odata = OData.newInstance();
|
||||
ServiceMetadata serviceMetadata = odata.createServiceMetadata(new EdmProvider() {
|
||||
public EntitySet getEntitySet(final FullQualifiedName entityContainer, final String entitySetName)
|
||||
throws ODataException {
|
||||
throw new ODataException("msg");
|
||||
}
|
||||
}, Collections.<EdmxReference>emptyList());
|
||||
|
||||
ODataHandler localHandler = new ODataHandler(odata, serviceMetadata);
|
||||
|
||||
ODataResponse response = localHandler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithApplicationExceptionInProcessor() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("$metadata");
|
||||
|
||||
MetadataProcessor metadataProcessor = mock(MetadataProcessor.class);
|
||||
doThrow(new ODataApplicationException("msg", 425, Locale.ENGLISH)).when(metadataProcessor).readMetadata(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
|
||||
handler.register(metadataProcessor);
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
assertEquals(425, response.getStatusCode());
|
||||
}
|
||||
}
|
|
@ -18,15 +18,22 @@
|
|||
*/
|
||||
package org.apache.olingo.server.core;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.olingo.commons.api.ODataException;
|
||||
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
||||
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.http.HttpContentType;
|
||||
|
@ -34,311 +41,303 @@ import org.apache.olingo.commons.api.http.HttpHeader;
|
|||
import org.apache.olingo.commons.api.http.HttpMethod;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
import org.apache.olingo.server.api.edm.provider.EdmProvider;
|
||||
import org.apache.olingo.server.api.edm.provider.EntitySet;
|
||||
import org.apache.olingo.server.api.edmx.EdmxReference;
|
||||
import org.apache.olingo.server.api.processor.EntitySetProcessor;
|
||||
import org.apache.olingo.server.api.processor.ComplexCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.ComplexProcessor;
|
||||
import org.apache.olingo.server.api.processor.CountEntityCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntityProcessor;
|
||||
import org.apache.olingo.server.api.processor.MetadataProcessor;
|
||||
import org.apache.olingo.server.api.processor.PropertyProcessor;
|
||||
import org.apache.olingo.server.api.processor.PrimitiveCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.PrimitiveProcessor;
|
||||
import org.apache.olingo.server.api.processor.Processor;
|
||||
import org.apache.olingo.server.api.processor.ServiceDocumentProcessor;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class ODataHandlerTest {
|
||||
|
||||
private ODataHandler handler;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
OData odata = OData.newInstance();
|
||||
ServiceMetadata metadata = odata.createServiceMetadata(
|
||||
new EdmTechProvider(), Collections.<EdmxReference>emptyList());
|
||||
|
||||
handler = new ODataHandler(odata, metadata);
|
||||
}
|
||||
private static final String BASE_URI = "http://localhost/odata";
|
||||
|
||||
@Test
|
||||
public void testServiceDocumentNonDefault() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawBaseUri("http://localhost/odata");
|
||||
request.setRawODataPath("/");
|
||||
|
||||
ServiceDocumentProcessor processor = mock(ServiceDocumentProcessor.class);
|
||||
handler.register(processor);
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
|
||||
assertNotNull(response);
|
||||
public void serviceDocumentNonDefault() throws Exception {
|
||||
final ServiceDocumentProcessor processor = mock(ServiceDocumentProcessor.class);
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "/", processor);
|
||||
assertEquals(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatusCode());
|
||||
|
||||
verify(processor).readServiceDocument(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
|
||||
dispatchMethodNotAllowed(HttpMethod.POST, "/", processor);
|
||||
dispatchMethodNotAllowed(HttpMethod.PUT, "/", processor);
|
||||
dispatchMethodNotAllowed(HttpMethod.PATCH, "/", processor);
|
||||
dispatchMethodNotAllowed(HttpMethod.DELETE, "/", processor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServiceDocumentDefault() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawBaseUri("http://localhost/odata");
|
||||
request.setRawODataPath("/");
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
|
||||
assertNotNull(response);
|
||||
public void serviceDocumentDefault() throws Exception {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "/", null);
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
|
||||
|
||||
String ct = response.getHeaders().get(HttpHeader.CONTENT_TYPE);
|
||||
assertTrue(ct.contains("application/json"));
|
||||
assertTrue(ct.contains("odata.metadata=minimal"));
|
||||
assertThat(ct, containsString("application/json"));
|
||||
assertThat(ct, containsString("odata.metadata=minimal"));
|
||||
|
||||
assertNotNull(response.getContent());
|
||||
String doc = IOUtils.toString(response.getContent());
|
||||
|
||||
assertTrue(doc.contains("\"@odata.context\" : \"http://localhost/odata/$metadata\""));
|
||||
assertTrue(doc.contains("\"value\" :"));
|
||||
assertThat(doc, containsString("\"@odata.context\" : \"" + BASE_URI + "/$metadata\""));
|
||||
assertThat(doc, containsString("\"value\" :"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServiceDocumentRedirect() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawBaseUri("http://localhost/odata");
|
||||
request.setRawRequestUri("http://localhost/odata");
|
||||
request.setRawODataPath("");
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
|
||||
assertNotNull(response);
|
||||
public void serviceDocumentRedirect() throws Exception {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "", null);
|
||||
assertEquals(HttpStatusCode.TEMPORARY_REDIRECT.getStatusCode(), response.getStatusCode());
|
||||
assertEquals("http://localhost/odata/", response.getHeaders().get(HttpHeader.LOCATION));
|
||||
assertEquals(BASE_URI + "/", response.getHeaders().get(HttpHeader.LOCATION));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetadataNonDefault() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("$metadata");
|
||||
|
||||
MetadataProcessor processor = mock(MetadataProcessor.class);
|
||||
handler.register(processor);
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
|
||||
assertNotNull(response);
|
||||
public void metadataNonDefault() throws Exception {
|
||||
final MetadataProcessor processor = mock(MetadataProcessor.class);
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", processor);
|
||||
assertEquals(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatusCode());
|
||||
|
||||
verify(processor).readMetadata(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
|
||||
dispatchMethodNotAllowed(HttpMethod.POST, "$metadata", processor);
|
||||
dispatchMethodNotAllowed(HttpMethod.PUT, "$metadata", processor);
|
||||
dispatchMethodNotAllowed(HttpMethod.PATCH, "$metadata", processor);
|
||||
dispatchMethodNotAllowed(HttpMethod.DELETE, "$metadata", processor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetadataDefault() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("$metadata");
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
|
||||
assertNotNull(response);
|
||||
public void metadataDefault() throws Exception {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", null);
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
|
||||
assertEquals(HttpContentType.APPLICATION_XML, response.getHeaders().get(HttpHeader.CONTENT_TYPE));
|
||||
|
||||
assertNotNull(response.getContent());
|
||||
String doc = IOUtils.toString(response.getContent());
|
||||
|
||||
assertTrue(doc.contains("<edmx:Edmx Version=\"4.0\""));
|
||||
assertThat(IOUtils.toString(response.getContent()),
|
||||
containsString("<edmx:Edmx Version=\"4.0\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxVersionNone() {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("$metadata");
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
|
||||
public void maxVersionNone() {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", null);
|
||||
assertEquals(ODataServiceVersion.V40.toString(), response.getHeaders().get(HttpHeader.ODATA_VERSION));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxVersionSupported() {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("$metadata");
|
||||
request.addHeader(HttpHeader.ODATA_MAX_VERSION, Arrays.asList(ODataServiceVersion.V40.toString()));
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
|
||||
public void maxVersionSupported() {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", null,
|
||||
HttpHeader.ODATA_MAX_VERSION, ODataServiceVersion.V40.toString(), null);
|
||||
assertEquals(ODataServiceVersion.V40.toString(), response.getHeaders().get(HttpHeader.ODATA_VERSION));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxVersionNotSupported() {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("$metadata");
|
||||
request.addHeader(HttpHeader.ODATA_MAX_VERSION, Arrays.asList(ODataServiceVersion.V30.toString()));
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
public void maxVersionNotSupported() {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", null,
|
||||
HttpHeader.ODATA_MAX_VERSION, ODataServiceVersion.V30.toString(), null);
|
||||
|
||||
assertEquals(ODataServiceVersion.V40.toString(), response.getHeaders().get(HttpHeader.ODATA_VERSION));
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContentNegotiationSupported() {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("$metadata");
|
||||
request.setRawQueryPath("$format=xml");
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
public void contentNegotiationSupported() {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", "$format=xml", null, null, null);
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContentNegotiationNotSupported() {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("$metadata");
|
||||
request.setRawQueryPath("$format=not/Supported");
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
public void contentNegotiationNotSupported() {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", "$format=not/Supported", null, null, null);
|
||||
assertEquals(HttpStatusCode.NOT_ACCEPTABLE.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContentNegotiationNotSupported2() {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("$metadata");
|
||||
request.setRawQueryPath("$format=notSupported");
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
public void contentNegotiationNotSupported2() {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", "$format=notSupported", null, null, null);
|
||||
assertEquals(HttpStatusCode.NOT_ACCEPTABLE.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnregisteredProcessor() {
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("ESAllPrim");
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
public void unregisteredProcessor() {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "ESAllPrim", null);
|
||||
assertEquals(HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCount() throws Exception {
|
||||
public void uriParserExceptionResultsInRightResponseNotFound() throws Exception {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "NotFound", null);
|
||||
assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uriParserExceptionResultsInRightResponseBadRequest() throws Exception {
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "ESAllPrim('122')", null);
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void applicationExceptionInProcessor() throws Exception {
|
||||
MetadataProcessor processor = mock(MetadataProcessor.class);
|
||||
doThrow(new ODataApplicationException("msg", 425, Locale.ENGLISH)).when(processor).readMetadata(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", processor);
|
||||
assertEquals(425, response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uriParserExceptionResultsInRightResponseEdmCause() throws Exception {
|
||||
final OData odata = OData.newInstance();
|
||||
final ServiceMetadata serviceMetadata = odata.createServiceMetadata(
|
||||
new EdmProvider() {
|
||||
public EntitySet getEntitySet(final FullQualifiedName entityContainer, final String entitySetName)
|
||||
throws ODataException {
|
||||
throw new ODataException("msg");
|
||||
}
|
||||
},
|
||||
Collections.<EdmxReference> emptyList());
|
||||
|
||||
ODataRequest request = new ODataRequest();
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("ESAllPrim/$count");
|
||||
request.setRawODataPath("EdmException");
|
||||
|
||||
EntitySetProcessor processor = mock(EntitySetProcessor.class);
|
||||
handler.register(processor);
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
final ODataResponse response = new ODataHandler(odata, serviceMetadata).process(request);
|
||||
assertNotNull(response);
|
||||
Mockito.verify(processor).countEntitySet(
|
||||
Mockito.eq(request),
|
||||
Mockito.any(ODataResponse.class),
|
||||
Mockito.any(UriInfo.class));
|
||||
assertEquals(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchEntitySet() throws Exception {
|
||||
final EntityCollectionProcessor processor = mock(EntityCollectionProcessor.class);
|
||||
dispatch(HttpMethod.GET, "ESAllPrim", processor);
|
||||
|
||||
verify(processor).readEntityCollection(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchEntitySetCount() throws Exception {
|
||||
final CountEntityCollectionProcessor processor = mock(CountEntityCollectionProcessor.class);
|
||||
dispatch(HttpMethod.GET, "ESAllPrim/$count", processor);
|
||||
|
||||
verify(processor).countEntityCollection(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), eq(ContentType.TEXT_PLAIN));
|
||||
|
||||
dispatchMethodNotAllowed(HttpMethod.POST, "ESAllPrim/$count", processor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchCountWithNavigation() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
final CountEntityCollectionProcessor processor = mock(CountEntityCollectionProcessor.class);
|
||||
dispatch(HttpMethod.GET, "ESAllPrim(0)/NavPropertyETTwoPrimMany/$count", processor);
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("ESAllPrim(0)/NavPropertyETTwoPrimMany/$count");
|
||||
|
||||
EntitySetProcessor processor = mock(EntitySetProcessor.class);
|
||||
handler.register(processor);
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
Mockito.verify(processor).countEntitySet(
|
||||
Mockito.eq(request),
|
||||
Mockito.any(ODataResponse.class),
|
||||
Mockito.any(UriInfo.class));
|
||||
verify(processor).countEntityCollection(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), eq(ContentType.TEXT_PLAIN));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchAddressPrimitiveProperty() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
public void dispatchEntity() throws Exception {
|
||||
final EntityProcessor processor = mock(EntityProcessor.class);
|
||||
dispatch(HttpMethod.GET, "ESAllPrim(0)", processor);
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("ESAllPrim(0)/PropertyInt16");
|
||||
|
||||
PropertyProcessor processor = mock(PropertyProcessor.class);
|
||||
handler.register(processor);
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
|
||||
Mockito.verify(processor).readProperty(
|
||||
Mockito.any(ODataRequest.class),
|
||||
Mockito.any(ODataResponse.class),
|
||||
Mockito.any(UriInfo.class),
|
||||
Mockito.any(ContentType.class));
|
||||
verify(processor).readEntity(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchAddressPrimitivePropertyValue() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
public void dispatchPrimitiveProperty() throws Exception {
|
||||
final PrimitiveProcessor processor = mock(PrimitiveProcessor.class);
|
||||
dispatch(HttpMethod.GET, "ESAllPrim(0)/PropertyInt16", processor);
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("ESAllPrim(0)/PropertyInt16/$value");
|
||||
|
||||
PropertyProcessor processor = mock(PropertyProcessor.class);
|
||||
handler.register(processor);
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
|
||||
Mockito.verify(processor).readPropertyValue(
|
||||
Mockito.any(ODataRequest.class),
|
||||
Mockito.any(ODataResponse.class),
|
||||
Mockito.any(UriInfo.class),
|
||||
Mockito.any(ContentType.class));
|
||||
verify(processor).readPrimitive(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchAddressComplexProperty() throws Exception {
|
||||
ODataRequest request = new ODataRequest();
|
||||
public void dispatchPrimitivePropertyValue() throws Exception {
|
||||
final PrimitiveProcessor processor = mock(PrimitiveProcessor.class);
|
||||
dispatch(HttpMethod.GET, "ESAllPrim(0)/PropertyInt16/$value", processor);
|
||||
|
||||
request.setMethod(HttpMethod.GET);
|
||||
request.setRawODataPath("ESMixPrimCollComp(7)/PropertyComp");
|
||||
|
||||
PropertyProcessor processor = mock(PropertyProcessor.class);
|
||||
handler.register(processor);
|
||||
|
||||
ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
|
||||
Mockito.verify(processor).readProperty(
|
||||
Mockito.any(ODataRequest.class),
|
||||
Mockito.any(ODataResponse.class),
|
||||
Mockito.any(UriInfo.class),
|
||||
Mockito.any(ContentType.class));
|
||||
verify(processor).readPrimitiveAsValue(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchPrimitiveCollectionProperty() throws Exception {
|
||||
final PrimitiveCollectionProcessor processor = mock(PrimitiveCollectionProcessor.class);
|
||||
dispatch(HttpMethod.GET, "ESMixPrimCollComp(7)/CollPropertyString", processor);
|
||||
|
||||
verify(processor).readPrimitiveCollection(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchComplexProperty() throws Exception {
|
||||
final ComplexProcessor processor = mock(ComplexProcessor.class);
|
||||
dispatch(HttpMethod.GET, "ESMixPrimCollComp(7)/PropertyComp", processor);
|
||||
|
||||
verify(processor).readComplex(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchComplexCollectionProperty() throws Exception {
|
||||
final ComplexCollectionProcessor processor = mock(ComplexCollectionProcessor.class);
|
||||
dispatch(HttpMethod.GET, "ESMixPrimCollComp(7)/CollPropertyComp", processor);
|
||||
|
||||
verify(processor).readComplexCollection(
|
||||
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
|
||||
}
|
||||
|
||||
private ODataResponse dispatch(final HttpMethod method, final String path, final String query,
|
||||
final String headerName, final String headerValue, final Processor processor) {
|
||||
ODataRequest request = new ODataRequest();
|
||||
request.setMethod(method);
|
||||
request.setRawBaseUri(BASE_URI);
|
||||
if (path.isEmpty()) {
|
||||
request.setRawRequestUri(BASE_URI);
|
||||
}
|
||||
request.setRawODataPath(path);
|
||||
request.setRawQueryPath(query);
|
||||
|
||||
if (headerName != null) {
|
||||
request.addHeader(headerName, Collections.singletonList(headerValue));
|
||||
}
|
||||
|
||||
final OData odata = OData.newInstance();
|
||||
final ServiceMetadata metadata = odata.createServiceMetadata(
|
||||
new EdmTechProvider(), Collections.<EdmxReference> emptyList());
|
||||
|
||||
ODataHandler handler = new ODataHandler(odata, metadata);
|
||||
|
||||
if (processor != null) {
|
||||
handler.register(processor);
|
||||
}
|
||||
|
||||
final ODataResponse response = handler.process(request);
|
||||
assertNotNull(response);
|
||||
return response;
|
||||
}
|
||||
|
||||
private ODataResponse dispatch(final HttpMethod method, final String path, final Processor processor) {
|
||||
return dispatch(method, path, null, null, null, processor);
|
||||
}
|
||||
|
||||
private void dispatchMethodNotAllowed(final HttpMethod method, final String path, final Processor processor) {
|
||||
final ODataResponse response = dispatch(method, path, processor);
|
||||
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
|
||||
assertNotNull(response.getContent());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,16 +31,22 @@ import org.apache.olingo.commons.api.data.EntitySet;
|
|||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.data.ValueType;
|
||||
import org.apache.olingo.commons.api.edm.Edm;
|
||||
import org.apache.olingo.commons.api.edm.EdmComplexType;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityContainer;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
||||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
import org.apache.olingo.commons.core.data.PropertyImpl;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.apache.olingo.server.api.edmx.EdmxReference;
|
||||
import org.apache.olingo.server.api.serializer.ComplexSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.queryoption.CountOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
|
||||
|
@ -58,7 +64,7 @@ import org.mockito.Mockito;
|
|||
public class ODataJsonSerializerTest {
|
||||
|
||||
private static final Edm edm = OData.newInstance().createServiceMetadata(
|
||||
new EdmTechProvider(), Collections.<EdmxReference>emptyList()).getEdm();
|
||||
new EdmTechProvider(), Collections.<EdmxReference> emptyList()).getEdm();
|
||||
private static final EdmEntityContainer entityContainer = edm.getEntityContainer(
|
||||
new FullQualifiedName("olingo.odata.test1", "Container"));
|
||||
private final DataProvider data = new DataProvider();
|
||||
|
@ -68,8 +74,8 @@ public class ODataJsonSerializerTest {
|
|||
public void entitySimple() throws Exception {
|
||||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
|
||||
final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||
InputStream result = serializer.entity(edmEntitySet, entity,
|
||||
ODataSerializerOptions.with()
|
||||
InputStream result = serializer.entity(edmEntitySet.getEntityType(), entity,
|
||||
EntitySerializerOptions.with()
|
||||
.contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
|
||||
.build());
|
||||
final String resultString = IOUtils.toString(result);
|
||||
|
@ -100,8 +106,8 @@ public class ODataJsonSerializerTest {
|
|||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
|
||||
Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||
entity.getProperties().retainAll(Arrays.asList(entity.getProperties().get(0)));
|
||||
final String resultString = IOUtils.toString(serializer.entity(edmEntitySet, entity,
|
||||
ODataSerializerOptions.with()
|
||||
final String resultString = IOUtils.toString(serializer.entity(edmEntitySet.getEntityType(), entity,
|
||||
EntitySerializerOptions.with()
|
||||
.contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
|
||||
.build()));
|
||||
final String expectedResult = "{\"@odata.context\":\"$metadata#ESAllPrim/$entity\","
|
||||
|
@ -121,8 +127,8 @@ public class ODataJsonSerializerTest {
|
|||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
|
||||
Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||
entity.getProperties().clear();
|
||||
serializer.entity(edmEntitySet, entity,
|
||||
ODataSerializerOptions.with()
|
||||
serializer.entity(edmEntitySet.getEntityType(), entity,
|
||||
EntitySerializerOptions.with()
|
||||
.contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
|
||||
.build());
|
||||
}
|
||||
|
@ -133,8 +139,8 @@ public class ODataJsonSerializerTest {
|
|||
Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||
entity.getProperties().get(0).setValue(ValueType.PRIMITIVE, false);
|
||||
try {
|
||||
serializer.entity(edmEntitySet, entity,
|
||||
ODataSerializerOptions.with()
|
||||
serializer.entity(edmEntitySet.getEntityType(), entity,
|
||||
EntitySerializerOptions.with()
|
||||
.contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
|
||||
.build());
|
||||
Assert.fail("Expected exception not thrown!");
|
||||
|
@ -154,8 +160,8 @@ public class ODataJsonSerializerTest {
|
|||
entitySet.setNext(URI.create("/next"));
|
||||
CountOption countOption = Mockito.mock(CountOption.class);
|
||||
Mockito.when(countOption.getValue()).thenReturn(true);
|
||||
InputStream result = serializer.entitySet(edmEntitySet, entitySet,
|
||||
ODataSerializerOptions.with()
|
||||
InputStream result = serializer.entityCollection(edmEntitySet.getEntityType(), entitySet,
|
||||
EntityCollectionSerializerOptions.with()
|
||||
.contextURL(ContextURL.with().entitySet(edmEntitySet).build())
|
||||
.count(countOption)
|
||||
.build());
|
||||
|
@ -179,8 +185,8 @@ public class ODataJsonSerializerTest {
|
|||
public void entityCollAllPrim() throws Exception {
|
||||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCollAllPrim");
|
||||
final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||
InputStream result = serializer.entity(edmEntitySet, entity,
|
||||
ODataSerializerOptions.with()
|
||||
InputStream result = serializer.entity(edmEntitySet.getEntityType(), entity,
|
||||
EntitySerializerOptions.with()
|
||||
.contextURL(ContextURL.with().serviceRoot(URI.create("http://host/service/"))
|
||||
.entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
|
||||
.build());
|
||||
|
@ -215,8 +221,8 @@ public class ODataJsonSerializerTest {
|
|||
public void entityCompAllPrim() throws Exception {
|
||||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCompAllPrim");
|
||||
final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||
InputStream result = serializer.entity(edmEntitySet, entity,
|
||||
ODataSerializerOptions.with()
|
||||
InputStream result = serializer.entity(edmEntitySet.getEntityType(), entity,
|
||||
EntitySerializerOptions.with()
|
||||
.contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
|
||||
.build());
|
||||
final String resultString = IOUtils.toString(result);
|
||||
|
@ -248,8 +254,8 @@ public class ODataJsonSerializerTest {
|
|||
public void entityMixPrimCollComp() throws Exception {
|
||||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMixPrimCollComp");
|
||||
final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||
InputStream result = serializer.entity(edmEntitySet, entity,
|
||||
ODataSerializerOptions.with()
|
||||
InputStream result = serializer.entity(edmEntitySet.getEntityType(), entity,
|
||||
EntitySerializerOptions.with()
|
||||
.contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
|
||||
.build());
|
||||
final String resultString = IOUtils.toString(result);
|
||||
|
@ -271,8 +277,8 @@ public class ODataJsonSerializerTest {
|
|||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMixPrimCollComp");
|
||||
Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||
entity.getProperties().retainAll(Arrays.asList(entity.getProperties().get(0)));
|
||||
final String resultString = IOUtils.toString(serializer.entity(edmEntitySet, entity,
|
||||
ODataSerializerOptions.with()
|
||||
final String resultString = IOUtils.toString(serializer.entity(edmEntitySet.getEntityType(), entity,
|
||||
EntitySerializerOptions.with()
|
||||
.contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
|
||||
.build()));
|
||||
final String expectedResult = "{\"@odata.context\":\"$metadata#ESMixPrimCollComp/$entity\","
|
||||
|
@ -286,7 +292,7 @@ public class ODataJsonSerializerTest {
|
|||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESTwoPrim");
|
||||
final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||
InputStream result = new ODataJsonSerializer(ODataFormat.JSON_NO_METADATA)
|
||||
.entity(edmEntitySet, entity, null);
|
||||
.entity(edmEntitySet.getEntityType(), entity, null);
|
||||
final String resultString = IOUtils.toString(result);
|
||||
final String expectedResult = "{\"PropertyInt16\":32766,\"PropertyString\":\"Test String1\"}";
|
||||
Assert.assertEquals(expectedResult, resultString);
|
||||
|
@ -297,8 +303,8 @@ public class ODataJsonSerializerTest {
|
|||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESTwoPrim");
|
||||
final EntitySet entitySet = data.readAll(edmEntitySet);
|
||||
InputStream result = new ODataJsonSerializer(ODataFormat.JSON_NO_METADATA)
|
||||
.entitySet(edmEntitySet, entitySet,
|
||||
ODataSerializerOptions.with()
|
||||
.entityCollection(edmEntitySet.getEntityType(), entitySet,
|
||||
EntityCollectionSerializerOptions.with()
|
||||
.contextURL(ContextURL.with().entitySet(edmEntitySet).build()).build());
|
||||
final String resultString = IOUtils.toString(result);
|
||||
final String expectedResult = "{\"value\":["
|
||||
|
@ -314,8 +320,8 @@ public class ODataJsonSerializerTest {
|
|||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMedia");
|
||||
Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||
entity.setMediaETag("theMediaETag");
|
||||
final String resultString = IOUtils.toString(serializer.entity(edmEntitySet, entity,
|
||||
ODataSerializerOptions.with()
|
||||
final String resultString = IOUtils.toString(serializer.entity(edmEntitySet.getEntityType(), entity,
|
||||
EntitySerializerOptions.with()
|
||||
.contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
|
||||
.build()));
|
||||
final String expectedResult = "{\"@odata.context\":\"$metadata#ESMedia/$entity\","
|
||||
|
@ -328,8 +334,8 @@ public class ODataJsonSerializerTest {
|
|||
public void entitySetMedia() throws Exception {
|
||||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMedia");
|
||||
final EntitySet entitySet = data.readAll(edmEntitySet);
|
||||
final String resultString = IOUtils.toString(serializer.entitySet(edmEntitySet, entitySet,
|
||||
ODataSerializerOptions.with()
|
||||
final String resultString = IOUtils.toString(serializer.entityCollection(edmEntitySet.getEntityType(), entitySet,
|
||||
EntityCollectionSerializerOptions.with()
|
||||
.contextURL(ContextURL.with().entitySet(edmEntitySet).build()).build()));
|
||||
final String expectedResult = "{\"@odata.context\":\"$metadata#ESMedia\",\"value\":["
|
||||
+ "{\"@odata.mediaContentType\":\"image/png\",\"PropertyInt16\":1},"
|
||||
|
@ -342,16 +348,17 @@ public class ODataJsonSerializerTest {
|
|||
@Test
|
||||
public void select() throws Exception {
|
||||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
|
||||
final EdmEntityType entityType = edmEntitySet.getEntityType();
|
||||
final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||
final SelectItem selectItem1 = ExpandSelectMock.mockSelectItem(edmEntitySet, "PropertyDate");
|
||||
final SelectItem selectItem2 = ExpandSelectMock.mockSelectItem(edmEntitySet, "PropertyBoolean");
|
||||
final SelectOption select = ExpandSelectMock.mockSelectOption(Arrays.asList(
|
||||
selectItem1, selectItem2, selectItem2));
|
||||
InputStream result = serializer
|
||||
.entity(edmEntitySet, entity,
|
||||
ODataSerializerOptions.with()
|
||||
.entity(entityType, entity,
|
||||
EntitySerializerOptions.with()
|
||||
.contextURL(ContextURL.with().entitySet(edmEntitySet)
|
||||
.selectList(serializer.buildContextURLSelectList(edmEntitySet, null, select))
|
||||
.selectList(serializer.buildContextURLSelectList(entityType, null, select))
|
||||
.suffix(Suffix.ENTITY).build())
|
||||
.select(select)
|
||||
.build());
|
||||
|
@ -370,8 +377,8 @@ public class ODataJsonSerializerTest {
|
|||
SelectItem selectItem2 = Mockito.mock(SelectItem.class);
|
||||
Mockito.when(selectItem2.isStar()).thenReturn(true);
|
||||
final SelectOption select = ExpandSelectMock.mockSelectOption(Arrays.asList(selectItem1, selectItem2));
|
||||
InputStream result = serializer.entity(edmEntitySet, entity,
|
||||
ODataSerializerOptions.with()
|
||||
InputStream result = serializer.entity(edmEntitySet.getEntityType(), entity,
|
||||
EntitySerializerOptions.with()
|
||||
.contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
|
||||
.select(select)
|
||||
.build());
|
||||
|
@ -384,14 +391,15 @@ public class ODataJsonSerializerTest {
|
|||
@Test
|
||||
public void selectComplex() throws Exception {
|
||||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCompComp");
|
||||
final EdmEntityType entityType = edmEntitySet.getEntityType();
|
||||
final EntitySet entitySet = data.readAll(edmEntitySet);
|
||||
final SelectOption select = ExpandSelectMock.mockSelectOption(Arrays.asList(
|
||||
ExpandSelectMock.mockSelectItem(edmEntitySet, "PropertyComp", "PropertyComp", "PropertyString")));
|
||||
InputStream result = serializer
|
||||
.entitySet(edmEntitySet, entitySet,
|
||||
ODataSerializerOptions.with()
|
||||
.entityCollection(entityType, entitySet,
|
||||
EntityCollectionSerializerOptions.with()
|
||||
.contextURL(ContextURL.with().entitySet(edmEntitySet)
|
||||
.selectList(serializer.buildContextURLSelectList(edmEntitySet, null, select))
|
||||
.selectList(serializer.buildContextURLSelectList(entityType, null, select))
|
||||
.build())
|
||||
.select(select)
|
||||
.build());
|
||||
|
@ -407,15 +415,16 @@ public class ODataJsonSerializerTest {
|
|||
@Test
|
||||
public void selectComplexTwice() throws Exception {
|
||||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCompComp");
|
||||
final EdmEntityType entityType = edmEntitySet.getEntityType();
|
||||
final EntitySet entitySet = data.readAll(edmEntitySet);
|
||||
final SelectOption select = ExpandSelectMock.mockSelectOption(Arrays.asList(
|
||||
ExpandSelectMock.mockSelectItem(edmEntitySet, "PropertyComp", "PropertyComp", "PropertyString"),
|
||||
ExpandSelectMock.mockSelectItem(edmEntitySet, "PropertyComp", "PropertyComp")));
|
||||
final String resultString = IOUtils.toString(serializer
|
||||
.entitySet(edmEntitySet, entitySet,
|
||||
ODataSerializerOptions.with()
|
||||
.entityCollection(entityType, entitySet,
|
||||
EntityCollectionSerializerOptions.with()
|
||||
.contextURL(ContextURL.with().entitySet(edmEntitySet)
|
||||
.selectList(serializer.buildContextURLSelectList(edmEntitySet, null, select))
|
||||
.selectList(serializer.buildContextURLSelectList(entityType, null, select))
|
||||
.build())
|
||||
.select(select)
|
||||
.build()));
|
||||
|
@ -433,8 +442,8 @@ public class ODataJsonSerializerTest {
|
|||
final Entity entity = data.readAll(edmEntitySet).getEntities().get(3);
|
||||
final ExpandOption expand = ExpandSelectMock.mockExpandOption(Arrays.asList(
|
||||
ExpandSelectMock.mockExpandItem(edmEntitySet, "NavPropertyETAllPrimOne")));
|
||||
InputStream result = serializer.entity(edmEntitySet, entity,
|
||||
ODataSerializerOptions.with()
|
||||
InputStream result = serializer.entity(edmEntitySet.getEntityType(), entity,
|
||||
EntitySerializerOptions.with()
|
||||
.contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
|
||||
.expand(expand)
|
||||
.build());
|
||||
|
@ -464,6 +473,7 @@ public class ODataJsonSerializerTest {
|
|||
@Test
|
||||
public void expandSelect() throws Exception {
|
||||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESTwoPrim");
|
||||
final EdmEntityType entityType = edmEntitySet.getEntityType();
|
||||
final Entity entity = data.readAll(edmEntitySet).getEntities().get(3);
|
||||
final SelectOption select = ExpandSelectMock.mockSelectOption(Arrays.asList(
|
||||
ExpandSelectMock.mockSelectItem(entityContainer.getEntitySet("ESAllPrim"), "PropertyDate")));
|
||||
|
@ -471,10 +481,10 @@ public class ODataJsonSerializerTest {
|
|||
Mockito.when(expandItem.getSelectOption()).thenReturn(select);
|
||||
final ExpandOption expand = ExpandSelectMock.mockExpandOption(Arrays.asList(expandItem));
|
||||
final String resultString = IOUtils.toString(serializer
|
||||
.entity(edmEntitySet, entity,
|
||||
ODataSerializerOptions.with()
|
||||
.entity(entityType, entity,
|
||||
EntitySerializerOptions.with()
|
||||
.contextURL(ContextURL.with().entitySet(edmEntitySet)
|
||||
.selectList(serializer.buildContextURLSelectList(edmEntitySet, expand, select))
|
||||
.selectList(serializer.buildContextURLSelectList(entityType, expand, select))
|
||||
.suffix(Suffix.ENTITY).build())
|
||||
.expand(expand)
|
||||
.build()));
|
||||
|
@ -488,6 +498,7 @@ public class ODataJsonSerializerTest {
|
|||
@Test
|
||||
public void expandAll() throws Exception {
|
||||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
|
||||
final EdmEntityType entityType = edmEntitySet.getEntityType();
|
||||
final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
|
||||
final ExpandItem expandItem = ExpandSelectMock.mockExpandItem(edmEntitySet, "NavPropertyETTwoPrimOne");
|
||||
ExpandItem expandItemAll = Mockito.mock(ExpandItem.class);
|
||||
|
@ -497,10 +508,10 @@ public class ODataJsonSerializerTest {
|
|||
final SelectOption select = ExpandSelectMock.mockSelectOption(Arrays.asList(
|
||||
ExpandSelectMock.mockSelectItem(edmEntitySet, "PropertySByte")));
|
||||
final String resultString = IOUtils.toString(serializer
|
||||
.entity(edmEntitySet, entity,
|
||||
ODataSerializerOptions.with()
|
||||
.entity(entityType, entity,
|
||||
EntitySerializerOptions.with()
|
||||
.contextURL(ContextURL.with().entitySet(edmEntitySet)
|
||||
.selectList(serializer.buildContextURLSelectList(edmEntitySet, expand, select))
|
||||
.selectList(serializer.buildContextURLSelectList(entityType, expand, select))
|
||||
.suffix(Suffix.ENTITY).build())
|
||||
.expand(expand)
|
||||
.select(select)
|
||||
|
@ -516,6 +527,7 @@ public class ODataJsonSerializerTest {
|
|||
@Test
|
||||
public void expandNoData() throws Exception {
|
||||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
|
||||
final EdmEntityType entityType = edmEntitySet.getEntityType();
|
||||
final Entity entity = data.readAll(edmEntitySet).getEntities().get(1);
|
||||
ExpandItem expandItemAll = Mockito.mock(ExpandItem.class);
|
||||
Mockito.when(expandItemAll.isStar()).thenReturn(true);
|
||||
|
@ -523,10 +535,10 @@ public class ODataJsonSerializerTest {
|
|||
final SelectOption select = ExpandSelectMock.mockSelectOption(Arrays.asList(
|
||||
ExpandSelectMock.mockSelectItem(edmEntitySet, "PropertyTimeOfDay")));
|
||||
final String resultString = IOUtils.toString(serializer
|
||||
.entity(edmEntitySet, entity,
|
||||
ODataSerializerOptions.with()
|
||||
.entity(entityType, entity,
|
||||
EntitySerializerOptions.with()
|
||||
.contextURL(ContextURL.with().entitySet(edmEntitySet)
|
||||
.selectList(serializer.buildContextURLSelectList(edmEntitySet, expand, select))
|
||||
.selectList(serializer.buildContextURLSelectList(entityType, expand, select))
|
||||
.suffix(Suffix.ENTITY).build())
|
||||
.expand(expand)
|
||||
.select(select)
|
||||
|
@ -541,6 +553,7 @@ public class ODataJsonSerializerTest {
|
|||
@Test
|
||||
public void expandTwoLevels() throws Exception {
|
||||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESTwoPrim");
|
||||
final EdmEntityType entityType = edmEntitySet.getEntityType();
|
||||
final EdmEntitySet innerEntitySet = entityContainer.getEntitySet("ESAllPrim");
|
||||
final Entity entity = data.readAll(edmEntitySet).getEntities().get(1);
|
||||
ExpandItem expandItemSecond = Mockito.mock(ExpandItem.class);
|
||||
|
@ -553,10 +566,10 @@ public class ODataJsonSerializerTest {
|
|||
Mockito.when(expandItemFirst.getSelectOption()).thenReturn(select);
|
||||
final ExpandOption expand = ExpandSelectMock.mockExpandOption(Arrays.asList(expandItemFirst));
|
||||
final String resultString = IOUtils.toString(serializer
|
||||
.entity(edmEntitySet, entity,
|
||||
ODataSerializerOptions.with()
|
||||
.entity(entityType, entity,
|
||||
EntitySerializerOptions.with()
|
||||
.contextURL(ContextURL.with().entitySet(edmEntitySet)
|
||||
.selectList(serializer.buildContextURLSelectList(edmEntitySet, expand, select))
|
||||
.selectList(serializer.buildContextURLSelectList(entityType, expand, select))
|
||||
.suffix(Suffix.ENTITY).build())
|
||||
.expand(expand)
|
||||
.build()));
|
||||
|
@ -579,8 +592,8 @@ public class ODataJsonSerializerTest {
|
|||
final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("PropertyString");
|
||||
final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty(edmProperty.getName());
|
||||
final String resultString = IOUtils.toString(serializer
|
||||
.entityProperty(edmProperty, property,
|
||||
ODataSerializerOptions.with()
|
||||
.primitive((EdmPrimitiveType) edmProperty.getType(), property,
|
||||
PrimitiveSerializerOptions.with()
|
||||
.contextURL(ContextURL.with()
|
||||
.entitySet(edmEntitySet).keyPath("32767").navOrPropertyPath(edmProperty.getName())
|
||||
.build())
|
||||
|
@ -596,8 +609,8 @@ public class ODataJsonSerializerTest {
|
|||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
|
||||
final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("PropertyString");
|
||||
final Property property = new PropertyImpl("Edm.String", edmProperty.getName(), ValueType.PRIMITIVE, null);
|
||||
serializer.entityProperty(edmProperty, property,
|
||||
ODataSerializerOptions.with()
|
||||
serializer.primitive((EdmPrimitiveType) edmProperty.getType(), property,
|
||||
PrimitiveSerializerOptions.with()
|
||||
.contextURL(ContextURL.with()
|
||||
.entitySet(edmEntitySet).keyPath("4242").navOrPropertyPath(edmProperty.getName())
|
||||
.build())
|
||||
|
@ -611,8 +624,8 @@ public class ODataJsonSerializerTest {
|
|||
final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty(edmProperty.getName());
|
||||
|
||||
final String resultString = IOUtils.toString(serializer
|
||||
.entityProperty(edmProperty, property,
|
||||
ODataSerializerOptions.with()
|
||||
.primitiveCollection((EdmPrimitiveType) edmProperty.getType(), property,
|
||||
PrimitiveSerializerOptions.with()
|
||||
.contextURL(ContextURL.with()
|
||||
.entitySet(edmEntitySet).keyPath("1").navOrPropertyPath(edmProperty.getName())
|
||||
.build())
|
||||
|
@ -630,8 +643,8 @@ public class ODataJsonSerializerTest {
|
|||
final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty("PropertyComp");
|
||||
|
||||
final String resultString = IOUtils.toString(serializer
|
||||
.entityProperty(edmProperty, property,
|
||||
ODataSerializerOptions.with()
|
||||
.complex((EdmComplexType) edmProperty.getType(), property,
|
||||
ComplexSerializerOptions.with()
|
||||
.contextURL(ContextURL.with()
|
||||
.entitySet(edmEntitySet).keyPath("32767").navOrPropertyPath(edmProperty.getName())
|
||||
.build())
|
||||
|
@ -641,4 +654,25 @@ public class ODataJsonSerializerTest {
|
|||
+ "\"PropertyInt16\":111,\"PropertyString\":\"TEST A\"}",
|
||||
resultString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void complexCollectionProperty() throws Exception {
|
||||
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMixPrimCollComp");
|
||||
final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("CollPropertyComp");
|
||||
final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty(edmProperty.getName());
|
||||
|
||||
final String resultString = IOUtils.toString(serializer
|
||||
.complexCollection((EdmComplexType) edmProperty.getType(), property,
|
||||
ComplexSerializerOptions.with()
|
||||
.contextURL(ContextURL.with()
|
||||
.entitySet(edmEntitySet).keyPath("32767").navOrPropertyPath(edmProperty.getName())
|
||||
.build())
|
||||
.build()));
|
||||
Assert.assertEquals("{"
|
||||
+ "\"@odata.context\":\"$metadata#ESMixPrimCollComp(32767)/CollPropertyComp\","
|
||||
+ "\"value\":[{\"PropertyInt16\":123,\"PropertyString\":\"TEST 1\"},"
|
||||
+ "{\"PropertyInt16\":456,\"PropertyString\":\"TEST 2\"},"
|
||||
+ "{\"PropertyInt16\":789,\"PropertyString\":\"TEST 3\"}]}",
|
||||
resultString);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -266,7 +266,6 @@ public class UriValidatorTest {
|
|||
validator.validate(uri, HttpMethod.PUT);
|
||||
validator.validate(uri, HttpMethod.DELETE);
|
||||
validator.validate(uri, HttpMethod.PATCH);
|
||||
validator.validate(uri, HttpMethod.MERGE);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -22,7 +22,6 @@ import java.util.ArrayList;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.olingo.commons.api.ODataException;
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
|
@ -41,8 +40,6 @@ import org.apache.olingo.server.api.uri.UriParameter;
|
|||
|
||||
public class DataProvider {
|
||||
|
||||
private static final UUID GUID = UUID.fromString("01234567-89ab-cdef-0123-456789abcdef");
|
||||
|
||||
private Map<String, EntitySet> data;
|
||||
|
||||
public DataProvider() {
|
||||
|
|
|
@ -27,7 +27,9 @@ import org.apache.olingo.commons.api.data.ContextURL.Suffix;
|
|||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.data.EntitySet;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.edm.EdmComplexType;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
||||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
|
@ -38,11 +40,15 @@ import org.apache.olingo.server.api.ODataApplicationException;
|
|||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
import org.apache.olingo.server.api.processor.ComplexProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntityProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntitySetProcessor;
|
||||
import org.apache.olingo.server.api.processor.PropertyProcessor;
|
||||
import org.apache.olingo.server.api.processor.PrimitiveProcessor;
|
||||
import org.apache.olingo.server.api.serializer.ComplexSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.SerializerException;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.api.uri.UriInfoResource;
|
||||
|
@ -59,7 +65,8 @@ import org.apache.olingo.server.sample.data.DataProvider.DataProviderException;
|
|||
* This is a very simple example which should give you a rough guideline on how to implement such an processor.
|
||||
* See the JavaDoc of the server.api interfaces for more information.
|
||||
*/
|
||||
public class CarsProcessor implements EntitySetProcessor, EntityProcessor, PropertyProcessor {
|
||||
public class CarsProcessor implements EntityCollectionProcessor, EntityProcessor,
|
||||
PrimitiveProcessor, ComplexProcessor {
|
||||
|
||||
private OData odata;
|
||||
private DataProvider dataProvider;
|
||||
|
@ -76,7 +83,7 @@ public class CarsProcessor implements EntitySetProcessor, EntityProcessor, Prope
|
|||
}
|
||||
|
||||
@Override
|
||||
public void readEntitySet(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
public void readEntityCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
|
||||
final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
|
||||
// First we have to figure out which entity set to use
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
|
||||
|
@ -93,8 +100,8 @@ public class CarsProcessor implements EntitySetProcessor, EntityProcessor, Prope
|
|||
// Now the content is serialized using the serializer.
|
||||
final ExpandOption expand = uriInfo.getExpandOption();
|
||||
final SelectOption select = uriInfo.getSelectOption();
|
||||
InputStream serializedContent = serializer.entitySet(edmEntitySet, entitySet,
|
||||
ODataSerializerOptions.with()
|
||||
InputStream serializedContent = serializer.entityCollection(edmEntitySet.getEntityType(), entitySet,
|
||||
EntityCollectionSerializerOptions.with()
|
||||
.contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
|
||||
getContextUrl(serializer, edmEntitySet, false, expand, select, null))
|
||||
.count(uriInfo.getCountOption())
|
||||
|
@ -131,11 +138,10 @@ public class CarsProcessor implements EntitySetProcessor, EntityProcessor, Prope
|
|||
ODataSerializer serializer = odata.createSerializer(format);
|
||||
final ExpandOption expand = uriInfo.getExpandOption();
|
||||
final SelectOption select = uriInfo.getSelectOption();
|
||||
InputStream serializedContent = serializer.entity(edmEntitySet, entity,
|
||||
ODataSerializerOptions.with()
|
||||
InputStream serializedContent = serializer.entity(edmEntitySet.getEntityType(), entity,
|
||||
EntitySerializerOptions.with()
|
||||
.contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
|
||||
getContextUrl(serializer, edmEntitySet, true, expand, select, null))
|
||||
.count(uriInfo.getCountOption())
|
||||
.expand(expand).select(select)
|
||||
.build());
|
||||
response.setContent(serializedContent);
|
||||
|
@ -144,9 +150,8 @@ public class CarsProcessor implements EntitySetProcessor, EntityProcessor, Prope
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readProperty(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType contentType)
|
||||
throws ODataApplicationException, SerializerException {
|
||||
private void readProperty(ODataResponse response, UriInfo uriInfo, ContentType contentType,
|
||||
boolean complex) throws ODataApplicationException, SerializerException {
|
||||
// To read a property we have to first get the entity out of the entity set
|
||||
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
|
||||
Entity entity;
|
||||
|
@ -175,11 +180,13 @@ public class CarsProcessor implements EntitySetProcessor, EntityProcessor, Prope
|
|||
} else {
|
||||
final ODataFormat format = ODataFormat.fromContentType(contentType);
|
||||
ODataSerializer serializer = odata.createSerializer(format);
|
||||
InputStream serializerContent = serializer.entityProperty(edmProperty, property,
|
||||
ODataSerializerOptions.with()
|
||||
.contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
|
||||
getContextUrl(serializer, edmEntitySet, true, null, null, edmProperty.getName()))
|
||||
.build());
|
||||
final ContextURL contextURL = format == ODataFormat.JSON_NO_METADATA ? null :
|
||||
getContextUrl(serializer, edmEntitySet, true, null, null, edmProperty.getName());
|
||||
InputStream serializerContent = complex ?
|
||||
serializer.complex((EdmComplexType) edmProperty.getType(), property,
|
||||
ComplexSerializerOptions.with().contextURL(contextURL).build()) :
|
||||
serializer.primitive((EdmPrimitiveType) edmProperty.getType(), property,
|
||||
PrimitiveSerializerOptions.with().contextURL(contextURL).build());
|
||||
response.setContent(serializerContent);
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
|
||||
|
@ -187,22 +194,7 @@ public class CarsProcessor implements EntitySetProcessor, EntityProcessor, Prope
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readPropertyValue(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType contentType)
|
||||
throws ODataApplicationException, SerializerException {
|
||||
throw new ODataApplicationException("Not implemented for this sample", HttpStatusCode.NOT_IMPLEMENTED
|
||||
.getStatusCode(), Locale.ENGLISH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void countEntitySet(ODataRequest request, ODataResponse response, UriInfo uriInfo)
|
||||
throws ODataApplicationException, SerializerException {
|
||||
// In this example we do not support the count system query option so we throw an exception
|
||||
throw new ODataApplicationException("Not implemented for this sample", HttpStatusCode.NOT_IMPLEMENTED
|
||||
.getStatusCode(), Locale.ENGLISH);
|
||||
}
|
||||
|
||||
|
||||
private Entity readEntityInternal(final UriInfoResource uriInfo, final EdmEntitySet entitySet)
|
||||
throws DataProvider.DataProviderException {
|
||||
// This method will extract the key values and pass them to the data provider
|
||||
|
@ -234,9 +226,28 @@ public class CarsProcessor implements EntitySetProcessor, EntityProcessor, Prope
|
|||
throws SerializerException {
|
||||
|
||||
return ContextURL.with().entitySet(entitySet)
|
||||
.selectList(serializer.buildContextURLSelectList(entitySet, expand, select))
|
||||
.selectList(serializer.buildContextURLSelectList(entitySet.getEntityType(), expand, select))
|
||||
.suffix(isSingleEntity ? Suffix.ENTITY : null)
|
||||
.navOrPropertyPath(navOrPropertyPath)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readPrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException {
|
||||
readProperty(response, uriInfo, format, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readComplex(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException {
|
||||
readProperty(response, uriInfo, format, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readPrimitiveAsValue(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
|
||||
throws ODataApplicationException, SerializerException {
|
||||
throw new ODataApplicationException("Not implemented for this sample",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue