| /******************************************************************************* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| ******************************************************************************/ |
| package org.apache.olingo.odata2.jpa.processor.core; |
| |
| import java.net.URI; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.apache.olingo.odata2.api.ODataCallback; |
| import org.apache.olingo.odata2.api.commons.HttpStatusCodes; |
| import org.apache.olingo.odata2.api.commons.InlineCount; |
| import org.apache.olingo.odata2.api.edm.EdmEntitySet; |
| import org.apache.olingo.odata2.api.edm.EdmEntityType; |
| import org.apache.olingo.odata2.api.edm.EdmException; |
| import org.apache.olingo.odata2.api.edm.EdmFunctionImport; |
| import org.apache.olingo.odata2.api.edm.EdmLiteralKind; |
| import org.apache.olingo.odata2.api.edm.EdmMultiplicity; |
| import org.apache.olingo.odata2.api.edm.EdmNavigationProperty; |
| import org.apache.olingo.odata2.api.edm.EdmProperty; |
| import org.apache.olingo.odata2.api.edm.EdmSimpleType; |
| import org.apache.olingo.odata2.api.edm.EdmStructuralType; |
| import org.apache.olingo.odata2.api.edm.EdmType; |
| import org.apache.olingo.odata2.api.edm.EdmTypeKind; |
| import org.apache.olingo.odata2.api.ep.EntityProvider; |
| import org.apache.olingo.odata2.api.ep.EntityProviderException; |
| import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties; |
| import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties.ODataEntityProviderPropertiesBuilder; |
| import org.apache.olingo.odata2.api.ep.callback.TombstoneCallback; |
| import org.apache.olingo.odata2.api.exception.ODataException; |
| import org.apache.olingo.odata2.api.exception.ODataHttpException; |
| import org.apache.olingo.odata2.api.exception.ODataNotFoundException; |
| import org.apache.olingo.odata2.api.processor.ODataContext; |
| import org.apache.olingo.odata2.api.processor.ODataResponse; |
| import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode; |
| import org.apache.olingo.odata2.api.uri.NavigationPropertySegment; |
| import org.apache.olingo.odata2.api.uri.PathInfo; |
| import org.apache.olingo.odata2.api.uri.SelectItem; |
| import org.apache.olingo.odata2.api.uri.UriParser; |
| import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo; |
| import org.apache.olingo.odata2.api.uri.info.GetEntityLinkUriInfo; |
| import org.apache.olingo.odata2.api.uri.info.GetEntitySetLinksUriInfo; |
| import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo; |
| import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo; |
| import org.apache.olingo.odata2.api.uri.info.GetFunctionImportUriInfo; |
| import org.apache.olingo.odata2.api.uri.info.PostUriInfo; |
| import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo; |
| import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext; |
| import org.apache.olingo.odata2.jpa.processor.api.ODataJPAResponseBuilder; |
| import org.apache.olingo.odata2.jpa.processor.api.ODataJPATombstoneContext; |
| import org.apache.olingo.odata2.jpa.processor.api.access.JPAPaging; |
| import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException; |
| import org.apache.olingo.odata2.jpa.processor.core.access.data.JPAEntityParser; |
| import org.apache.olingo.odata2.jpa.processor.core.callback.JPAExpandCallBack; |
| import org.apache.olingo.odata2.jpa.processor.core.callback.JPATombstoneCallBack; |
| |
| public final class ODataJPAResponseBuilderDefault implements ODataJPAResponseBuilder { |
| |
| private final ODataJPAContext oDataJPAContext; |
| |
| public ODataJPAResponseBuilderDefault(final ODataJPAContext context) { |
| oDataJPAContext = context; |
| } |
| |
| /* Response for Read Entity Set */ |
| @Override |
| public ODataResponse build(final GetEntitySetUriInfo resultsView, final List<Object> jpaEntities, |
| final String contentType) throws ODataJPARuntimeException { |
| |
| EdmEntityType edmEntityType = null; |
| ODataResponse odataResponse = null; |
| List<ArrayList<NavigationPropertySegment>> expandList = null; |
| |
| try { |
| edmEntityType = resultsView.getTargetEntitySet().getEntityType(); |
| List<Map<String, Object>> edmEntityList = null; |
| JPAEntityParser jpaResultParser = new JPAEntityParser(); |
| final List<SelectItem> selectedItems = resultsView.getSelect(); |
| if (selectedItems != null && selectedItems.size() > 0) { |
| edmEntityList = |
| jpaResultParser.parse2EdmEntityList(jpaEntities, buildSelectItemList(selectedItems, edmEntityType)); |
| } else { |
| edmEntityList = jpaResultParser.parse2EdmEntityList(jpaEntities, edmEntityType); |
| } |
| expandList = resultsView.getExpand(); |
| if (expandList != null && expandList.size() != 0) { |
| int count = 0; |
| List<EdmNavigationProperty> edmNavPropertyList = constructListofNavProperty(expandList); |
| for (Object jpaEntity : jpaEntities) { |
| Map<String, Object> relationShipMap = edmEntityList.get(count); |
| HashMap<String, Object> navigationMap = |
| jpaResultParser.parse2EdmNavigationValueMap(jpaEntity, edmNavPropertyList); |
| relationShipMap.putAll(navigationMap); |
| count++; |
| } |
| } |
| |
| EntityProviderWriteProperties feedProperties = null; |
| |
| feedProperties = getEntityProviderProperties(oDataJPAContext, resultsView, edmEntityList); |
| odataResponse = |
| EntityProvider.writeFeed(contentType, resultsView.getTargetEntitySet(), edmEntityList, feedProperties); |
| odataResponse = ODataResponse.fromResponse(odataResponse).status(HttpStatusCodes.OK).build(); |
| |
| } catch (EntityProviderException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e); |
| } catch (EdmException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e); |
| } |
| |
| return odataResponse; |
| } |
| |
| /* Response for Read Entity */ |
| @Override |
| public ODataResponse build(final GetEntityUriInfo resultsView, final Object jpaEntity, |
| final String contentType) throws ODataJPARuntimeException, |
| ODataNotFoundException { |
| |
| List<ArrayList<NavigationPropertySegment>> expandList = null; |
| if (jpaEntity == null) { |
| throw new ODataNotFoundException(ODataNotFoundException.ENTITY); |
| } |
| EdmEntityType edmEntityType = null; |
| ODataResponse odataResponse = null; |
| |
| try { |
| |
| edmEntityType = resultsView.getTargetEntitySet().getEntityType(); |
| Map<String, Object> edmPropertyValueMap = null; |
| |
| JPAEntityParser jpaResultParser = new JPAEntityParser(); |
| final List<SelectItem> selectedItems = resultsView.getSelect(); |
| if (selectedItems != null && selectedItems.size() > 0) { |
| edmPropertyValueMap = |
| jpaResultParser.parse2EdmPropertyValueMap(jpaEntity, buildSelectItemList(selectedItems, resultsView |
| .getTargetEntitySet().getEntityType())); |
| } else { |
| edmPropertyValueMap = jpaResultParser.parse2EdmPropertyValueMap(jpaEntity, edmEntityType); |
| } |
| |
| expandList = resultsView.getExpand(); |
| if (expandList != null && expandList.size() != 0) { |
| HashMap<String, Object> navigationMap = |
| jpaResultParser.parse2EdmNavigationValueMap(jpaEntity, constructListofNavProperty(expandList)); |
| edmPropertyValueMap.putAll(navigationMap); |
| } |
| EntityProviderWriteProperties feedProperties = null; |
| feedProperties = getEntityProviderProperties(oDataJPAContext, resultsView); |
| odataResponse = |
| EntityProvider.writeEntry(contentType, resultsView.getTargetEntitySet(), edmPropertyValueMap, feedProperties); |
| |
| odataResponse = ODataResponse.fromResponse(odataResponse).status(HttpStatusCodes.OK).build(); |
| |
| } catch (EntityProviderException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e); |
| } catch (EdmException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e); |
| } |
| |
| return odataResponse; |
| } |
| |
| /* Response for $count */ |
| @Override |
| public ODataResponse build(final long jpaEntityCount) |
| throws ODataJPARuntimeException { |
| |
| ODataResponse odataResponse = null; |
| try { |
| odataResponse = EntityProvider.writeText(String.valueOf(jpaEntityCount)); |
| odataResponse = ODataResponse.fromResponse(odataResponse).build(); |
| } catch (EntityProviderException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e); |
| } |
| return odataResponse; |
| } |
| |
| /* Response for Create Entity */ |
| @Override |
| public ODataResponse build(final PostUriInfo uriInfo, final Object createdObject, |
| final String contentType) throws ODataJPARuntimeException, |
| ODataNotFoundException { |
| |
| if (createdObject == null) { |
| throw new ODataNotFoundException(ODataNotFoundException.ENTITY); |
| } |
| |
| EdmEntityType edmEntityType = null; |
| ODataResponse odataResponse = null; |
| |
| try { |
| |
| edmEntityType = uriInfo.getTargetEntitySet().getEntityType(); |
| Map<String, Object> edmPropertyValueMap = null; |
| |
| JPAEntityParser jpaResultParser = new JPAEntityParser(); |
| edmPropertyValueMap = jpaResultParser.parse2EdmPropertyValueMap(createdObject, edmEntityType); |
| |
| EntityProviderWriteProperties feedProperties = null; |
| try { |
| feedProperties = getEntityProviderPropertiesforPost(oDataJPAContext, uriInfo); |
| } catch (ODataException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e); |
| } |
| |
| odataResponse = |
| EntityProvider.writeEntry(contentType, uriInfo.getTargetEntitySet(), edmPropertyValueMap, feedProperties); |
| |
| odataResponse = ODataResponse.fromResponse(odataResponse).status(HttpStatusCodes.CREATED).build(); |
| |
| } catch (EntityProviderException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e); |
| } catch (EdmException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e); |
| } |
| |
| return odataResponse; |
| } |
| |
| /* Response for Update Entity */ |
| @Override |
| public ODataResponse build(final PutMergePatchUriInfo putUriInfo, final Object updatedObject) |
| throws ODataJPARuntimeException, ODataNotFoundException { |
| if (updatedObject == null) { |
| throw new ODataNotFoundException(ODataNotFoundException.ENTITY); |
| } |
| return ODataResponse.status(HttpStatusCodes.NO_CONTENT).build(); |
| } |
| |
| /* Response for Delete Entity */ |
| @Override |
| public ODataResponse build(final DeleteUriInfo deleteUriInfo, final Object deletedObject) |
| throws ODataJPARuntimeException, ODataNotFoundException { |
| |
| if (deletedObject == null) { |
| throw new ODataNotFoundException(ODataNotFoundException.ENTITY); |
| } |
| return ODataResponse.status(HttpStatusCodes.NO_CONTENT).build(); |
| } |
| |
| /* Response for Function Import Single Result */ |
| @Override |
| public ODataResponse build(final GetFunctionImportUriInfo resultsView, final Object result) |
| throws ODataJPARuntimeException { |
| |
| try { |
| final EdmFunctionImport functionImport = resultsView.getFunctionImport(); |
| final EdmSimpleType type = (EdmSimpleType) functionImport.getReturnType().getType(); |
| |
| if (result != null) { |
| ODataResponse response = null; |
| if (type.getDefaultType().equals(byte[].class)) { |
| response = EntityProvider.writeBinary("application/octet-stream", (byte[]) result); |
| } else { |
| final String value = type.valueToString(result, EdmLiteralKind.DEFAULT, null); |
| response = EntityProvider.writeText(value); |
| } |
| |
| return ODataResponse.fromResponse(response).build(); |
| } else { |
| throw new ODataNotFoundException(ODataHttpException.COMMON); |
| } |
| } catch (EdmException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e); |
| } catch (EntityProviderException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e); |
| } catch (ODataException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e); |
| } |
| } |
| |
| /* Response for Function Import Multiple Result */ |
| @Override |
| public ODataResponse build(final GetFunctionImportUriInfo resultsView, final List<Object> resultList, |
| final String contentType) throws ODataJPARuntimeException, |
| ODataNotFoundException { |
| |
| ODataResponse odataResponse = null; |
| |
| if (resultList != null) { |
| JPAEntityParser jpaResultParser = new JPAEntityParser(); |
| EdmType edmType = null; |
| EdmFunctionImport functionImport = null; |
| Map<String, Object> edmPropertyValueMap = null; |
| List<Map<String, Object>> edmEntityList = null; |
| Object result = null; |
| try { |
| EntityProviderWriteProperties feedProperties = |
| EntityProviderWriteProperties.serviceRoot(oDataJPAContext.getODataContext().getPathInfo().getServiceRoot()) |
| .build(); |
| |
| functionImport = resultsView.getFunctionImport(); |
| edmType = functionImport.getReturnType().getType(); |
| |
| if (edmType.getKind().equals(EdmTypeKind.ENTITY) || edmType.getKind().equals(EdmTypeKind.COMPLEX)) { |
| if (functionImport.getReturnType().getMultiplicity().equals(EdmMultiplicity.MANY)) { |
| edmEntityList = new ArrayList<Map<String, Object>>(); |
| for (Object jpaEntity : resultList) { |
| edmPropertyValueMap = jpaResultParser.parse2EdmPropertyValueMap(jpaEntity, (EdmStructuralType) edmType); |
| edmEntityList.add(edmPropertyValueMap); |
| } |
| result = edmEntityList; |
| } else { |
| |
| Object resultObject = resultList.get(0); |
| edmPropertyValueMap = jpaResultParser.parse2EdmPropertyValueMap(resultObject, (EdmStructuralType) edmType); |
| |
| result = edmPropertyValueMap; |
| } |
| |
| } else if (edmType.getKind().equals(EdmTypeKind.SIMPLE)) { |
| result = resultList.get(0); |
| } |
| |
| odataResponse = |
| EntityProvider.writeFunctionImport(contentType, resultsView.getFunctionImport(), result, feedProperties); |
| odataResponse = ODataResponse.fromResponse(odataResponse).status(HttpStatusCodes.OK).build(); |
| |
| } catch (EdmException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e); |
| } catch (EntityProviderException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e); |
| } catch (ODataException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e); |
| } |
| |
| } else { |
| throw new ODataNotFoundException(ODataHttpException.COMMON); |
| } |
| |
| return odataResponse; |
| } |
| |
| /* Response for Read Entity Link */ |
| @Override |
| public ODataResponse build(final GetEntityLinkUriInfo resultsView, final Object jpaEntity, |
| final String contentType) throws ODataNotFoundException, |
| ODataJPARuntimeException { |
| |
| if (jpaEntity == null) { |
| throw new ODataNotFoundException(ODataNotFoundException.ENTITY); |
| } |
| EdmEntityType edmEntityType = null; |
| ODataResponse odataResponse = null; |
| |
| try { |
| |
| EdmEntitySet entitySet = resultsView.getTargetEntitySet(); |
| edmEntityType = entitySet.getEntityType(); |
| Map<String, Object> edmPropertyValueMap = null; |
| |
| JPAEntityParser jpaResultParser = new JPAEntityParser(); |
| edmPropertyValueMap = jpaResultParser.parse2EdmPropertyValueMap(jpaEntity, edmEntityType.getKeyProperties()); |
| |
| EntityProviderWriteProperties entryProperties = |
| EntityProviderWriteProperties.serviceRoot(oDataJPAContext.getODataContext().getPathInfo().getServiceRoot()) |
| .build(); |
| |
| ODataResponse response = EntityProvider.writeLink(contentType, entitySet, edmPropertyValueMap, entryProperties); |
| |
| odataResponse = ODataResponse.fromResponse(response).build(); |
| |
| } catch (ODataException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e); |
| |
| } |
| |
| return odataResponse; |
| } |
| |
| /* Response for Read Entity Links */ |
| @Override |
| public ODataResponse build(final GetEntitySetLinksUriInfo resultsView, final List<Object> jpaEntities, |
| final String contentType) throws ODataJPARuntimeException { |
| EdmEntityType edmEntityType = null; |
| ODataResponse odataResponse = null; |
| |
| try { |
| |
| EdmEntitySet entitySet = resultsView.getTargetEntitySet(); |
| edmEntityType = entitySet.getEntityType(); |
| List<EdmProperty> keyProperties = edmEntityType.getKeyProperties(); |
| |
| List<Map<String, Object>> edmEntityList = new ArrayList<Map<String, Object>>(); |
| Map<String, Object> edmPropertyValueMap = null; |
| JPAEntityParser jpaResultParser = new JPAEntityParser(); |
| |
| for (Object jpaEntity : jpaEntities) { |
| edmPropertyValueMap = jpaResultParser.parse2EdmPropertyValueMap(jpaEntity, keyProperties); |
| edmEntityList.add(edmPropertyValueMap); |
| } |
| |
| Integer count = null; |
| if (resultsView.getInlineCount() != null) { |
| if ((resultsView.getSkip() != null || resultsView.getTop() != null)) { |
| // when $skip and/or $top is present with $inlinecount |
| count = getInlineCountForNonFilterQueryLinks(edmEntityList, resultsView); |
| } else { |
| // In all other cases |
| count = resultsView.getInlineCount() == InlineCount.ALLPAGES ? edmEntityList.size() : null; |
| } |
| } |
| |
| ODataContext context = oDataJPAContext.getODataContext(); |
| EntityProviderWriteProperties entryProperties = |
| EntityProviderWriteProperties.serviceRoot(context.getPathInfo().getServiceRoot()).inlineCountType( |
| resultsView.getInlineCount()).inlineCount(count).build(); |
| |
| odataResponse = EntityProvider.writeLinks(contentType, entitySet, edmEntityList, entryProperties); |
| |
| odataResponse = ODataResponse.fromResponse(odataResponse).build(); |
| |
| } catch (ODataException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e); |
| } |
| |
| return odataResponse; |
| |
| } |
| |
| /* |
| * This method handles $inlinecount request. It also modifies the list of results in case of |
| * $inlinecount and $top/$skip combinations. Specific to LinksUriInfo. |
| * |
| * @param edmEntityList |
| * |
| * @param resultsView |
| * |
| * @return |
| */ |
| private static Integer getInlineCountForNonFilterQueryLinks(final List<Map<String, Object>> edmEntityList, |
| final GetEntitySetLinksUriInfo resultsView) { |
| // when $skip and/or $top is present with $inlinecount, first get the total count |
| Integer count = null; |
| if (resultsView.getInlineCount() == InlineCount.ALLPAGES) { |
| if (resultsView.getSkip() != null || resultsView.getTop() != null) { |
| count = edmEntityList.size(); |
| // Now update the list |
| if (resultsView.getSkip() != null) { |
| // Index checks to avoid IndexOutOfBoundsException |
| if (resultsView.getSkip() > edmEntityList.size()) { |
| edmEntityList.clear(); |
| return count; |
| } |
| edmEntityList.subList(0, resultsView.getSkip()).clear(); |
| } |
| if (resultsView.getTop() != null && resultsView.getTop() >= 0 && resultsView.getTop() < edmEntityList.size()) { |
| edmEntityList.subList(0, resultsView.getTop()); |
| } |
| } |
| }// Inlinecount of None is handled by default - null |
| return count; |
| } |
| |
| /* |
| * Method to build the entity provider Property.Callbacks for $expand would |
| * be registered here |
| */ |
| private static EntityProviderWriteProperties getEntityProviderProperties(final ODataJPAContext odataJPAContext, |
| final GetEntitySetUriInfo resultsView, final List<Map<String, Object>> edmEntityList) |
| throws ODataJPARuntimeException { |
| ODataEntityProviderPropertiesBuilder entityFeedPropertiesBuilder = null; |
| ODataContext context = odataJPAContext.getODataContext(); |
| |
| Integer count = null; |
| if (resultsView.getInlineCount() != null) { |
| if ((resultsView.getSkip() != null || resultsView.getTop() != null)) { |
| // when $skip and/or $top is present with $inlinecount |
| count = getInlineCountForNonFilterQueryEntitySet(edmEntityList, resultsView); |
| } else { |
| // In all other cases |
| count = resultsView.getInlineCount() == InlineCount.ALLPAGES ? edmEntityList.size() : null; |
| } |
| } |
| |
| try { |
| PathInfo pathInfo = context.getPathInfo(); |
| URI serviceRoot = pathInfo.getServiceRoot(); |
| |
| entityFeedPropertiesBuilder = |
| EntityProviderWriteProperties.serviceRoot(pathInfo.getServiceRoot()); |
| JPAPaging paging = odataJPAContext.getPaging(); |
| if (odataJPAContext.getPageSize() > 0 && paging != null && paging.getNextPage() > 0) { |
| String nextLink = |
| serviceRoot.relativize(pathInfo.getRequestUri()).toString(); |
| nextLink = percentEncodeNextLink(nextLink); |
| nextLink += (nextLink.contains("?") ? "&" : "?") |
| + "$skiptoken=" + odataJPAContext.getPaging().getNextPage(); |
| entityFeedPropertiesBuilder.nextLink(nextLink); |
| } |
| entityFeedPropertiesBuilder.inlineCount(count); |
| entityFeedPropertiesBuilder.inlineCountType(resultsView.getInlineCount()); |
| ExpandSelectTreeNode expandSelectTree = |
| UriParser.createExpandSelectTree(resultsView.getSelect(), resultsView.getExpand()); |
| |
| Map<String, ODataCallback> expandCallBack = |
| JPAExpandCallBack.getCallbacks(serviceRoot, expandSelectTree, resultsView.getExpand()); |
| |
| Map<String, ODataCallback> callBackMap = new HashMap<String, ODataCallback>(); |
| callBackMap.putAll(expandCallBack); |
| |
| String deltaToken = ODataJPATombstoneContext.getDeltaToken(); |
| if (deltaToken != null) { |
| callBackMap.put(TombstoneCallback.CALLBACK_KEY_TOMBSTONE, new JPATombstoneCallBack(serviceRoot.toString(), |
| resultsView, deltaToken)); |
| } |
| |
| entityFeedPropertiesBuilder.callbacks(callBackMap); |
| entityFeedPropertiesBuilder.expandSelectTree(expandSelectTree); |
| |
| } catch (ODataException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e); |
| } |
| |
| return entityFeedPropertiesBuilder.build(); |
| } |
| |
| private static String percentEncodeNextLink(final String link) { |
| if (link == null) { |
| return null; |
| } |
| |
| return link.replaceAll("\\$skiptoken=.+?(?:&|$)", "") |
| .replaceAll("\\$skip=.+?(?:&|$)", "") |
| .replaceFirst("(?:\\?|&)$", ""); // Remove potentially trailing "?" or "&" left over from remove actions |
| } |
| |
| /* |
| * This method handles $inlinecount request. It also modifies the list of results in case of |
| * $inlinecount and $top/$skip combinations. Specific to Entity Set. |
| */ |
| private static Integer getInlineCountForNonFilterQueryEntitySet(final List<Map<String, Object>> edmEntityList, |
| final GetEntitySetUriInfo resultsView) { |
| // when $skip and/or $top is present with $inlinecount, first get the total count |
| Integer count = null; |
| if (resultsView.getInlineCount() == InlineCount.ALLPAGES) { |
| if (resultsView.getSkip() != null || resultsView.getTop() != null) { |
| count = edmEntityList.size(); |
| // Now update the list |
| if (resultsView.getSkip() != null) { |
| // Index checks to avoid IndexOutOfBoundsException |
| if (resultsView.getSkip() > edmEntityList.size()) { |
| edmEntityList.clear(); |
| return count; |
| } |
| edmEntityList.subList(0, resultsView.getSkip()).clear(); |
| } |
| if (resultsView.getTop() != null && resultsView.getTop() >= 0 && resultsView.getTop() < edmEntityList.size()) { |
| final List<Map<String, Object>> edmEntitySubList = |
| new ArrayList<Map<String, Object>>(edmEntityList.subList(0, resultsView.getTop())); |
| edmEntityList.retainAll(edmEntitySubList); |
| } |
| } |
| }// Inlinecount of None is handled by default - null |
| return count; |
| } |
| |
| private static EntityProviderWriteProperties getEntityProviderProperties(final ODataJPAContext odataJPAContext, |
| final GetEntityUriInfo resultsView) throws ODataJPARuntimeException { |
| ODataEntityProviderPropertiesBuilder entityFeedPropertiesBuilder = null; |
| ExpandSelectTreeNode expandSelectTree = null; |
| try { |
| entityFeedPropertiesBuilder = |
| EntityProviderWriteProperties.serviceRoot(odataJPAContext.getODataContext().getPathInfo().getServiceRoot()); |
| expandSelectTree = UriParser.createExpandSelectTree(resultsView.getSelect(), resultsView.getExpand()); |
| entityFeedPropertiesBuilder.expandSelectTree(expandSelectTree); |
| entityFeedPropertiesBuilder.callbacks(JPAExpandCallBack.getCallbacks(odataJPAContext.getODataContext() |
| .getPathInfo().getServiceRoot(), expandSelectTree, resultsView.getExpand())); |
| } catch (ODataException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e); |
| } |
| |
| return entityFeedPropertiesBuilder.build(); |
| } |
| |
| private static EntityProviderWriteProperties getEntityProviderPropertiesforPost( |
| final ODataJPAContext odataJPAContext, final PostUriInfo resultsView) throws ODataJPARuntimeException { |
| ODataEntityProviderPropertiesBuilder entityFeedPropertiesBuilder = null; |
| try { |
| entityFeedPropertiesBuilder = |
| EntityProviderWriteProperties.serviceRoot(odataJPAContext.getODataContext().getPathInfo().getServiceRoot()); |
| } catch (ODataException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e); |
| } |
| |
| return entityFeedPropertiesBuilder.build(); |
| } |
| |
| private static List<EdmProperty> buildSelectItemList(final List<SelectItem> selectItems, final EdmEntityType entity) |
| throws ODataJPARuntimeException { |
| boolean flag = false; |
| List<EdmProperty> selectPropertyList = new ArrayList<EdmProperty>(); |
| try { |
| for (SelectItem selectItem : selectItems) { |
| if (selectItem.getNavigationPropertySegments().size() <= 0) { |
| if (selectItem.isStar()) { |
| selectPropertyList.addAll(getEdmProperties(entity)); |
| return selectPropertyList; |
| } else { |
| selectPropertyList.add(selectItem.getProperty()); |
| } |
| } |
| } |
| for (EdmProperty keyProperty : entity.getKeyProperties()) { |
| flag = true; |
| for (SelectItem selectedItem : selectItems) { |
| if (selectedItem.isStar() == false && selectedItem.getProperty().equals(keyProperty)) { |
| flag = false; |
| break; |
| } |
| } |
| if (flag == true) { |
| selectPropertyList.add(keyProperty); |
| } |
| } |
| |
| } catch (EdmException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e); |
| } |
| return selectPropertyList; |
| } |
| |
| private static List<EdmNavigationProperty> constructListofNavProperty( |
| final List<ArrayList<NavigationPropertySegment>> expandList) { |
| List<EdmNavigationProperty> navigationPropertyList = new ArrayList<EdmNavigationProperty>(); |
| for (ArrayList<NavigationPropertySegment> navpropSegment : expandList) { |
| navigationPropertyList.add(navpropSegment.get(0).getNavigationProperty()); |
| } |
| return navigationPropertyList; |
| } |
| |
| private static List<EdmProperty> getEdmProperties(final EdmStructuralType structuralType) |
| throws ODataJPARuntimeException { |
| List<EdmProperty> edmProperties = new ArrayList<EdmProperty>(); |
| try { |
| for (String propertyName : structuralType.getPropertyNames()) { |
| edmProperties.add((EdmProperty) structuralType.getProperty(propertyName)); |
| } |
| } catch (EdmException e) { |
| throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e); |
| } |
| return edmProperties; |
| } |
| |
| } |