/******************************************************************************* * Copyright 2013 SAP AG * * Licensed 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 com.sap.core.odata.processor.core.jpa.access.data; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.sap.core.odata.api.ODataCallback; import com.sap.core.odata.api.edm.EdmEntitySet; import com.sap.core.odata.api.edm.EdmEntityType; import com.sap.core.odata.api.edm.EdmException; import com.sap.core.odata.api.edm.EdmNavigationProperty; import com.sap.core.odata.api.ep.EntityProviderWriteProperties; import com.sap.core.odata.api.ep.EntityProviderWriteProperties.ODataEntityProviderPropertiesBuilder; import com.sap.core.odata.api.ep.callback.OnWriteEntryContent; import com.sap.core.odata.api.ep.callback.OnWriteFeedContent; import com.sap.core.odata.api.ep.callback.WriteCallbackContext; import com.sap.core.odata.api.ep.callback.WriteEntryCallbackContext; import com.sap.core.odata.api.ep.callback.WriteEntryCallbackResult; import com.sap.core.odata.api.ep.callback.WriteFeedCallbackContext; import com.sap.core.odata.api.ep.callback.WriteFeedCallbackResult; import com.sap.core.odata.api.uri.ExpandSelectTreeNode; import com.sap.core.odata.api.uri.NavigationPropertySegment; import com.sap.core.odata.processor.api.jpa.exception.ODataJPARuntimeException; public class JPAExpandCallBack implements OnWriteFeedContent, OnWriteEntryContent, ODataCallback { private URI baseUri; private List<ArrayList<NavigationPropertySegment>> expandList; private EdmEntitySet nextEntitySet = null; private JPAExpandCallBack(final URI baseUri, final List<ArrayList<NavigationPropertySegment>> expandList) { super(); this.baseUri = baseUri; this.expandList = expandList; } @Override public WriteEntryCallbackResult retrieveEntryResult( final WriteEntryCallbackContext context) { WriteEntryCallbackResult result = new WriteEntryCallbackResult(); Map<String, Object> entry = context.getEntryData(); Map<String, Object> edmPropertyValueMap = null; List<EdmNavigationProperty> currentNavPropertyList = null; Map<String, ExpandSelectTreeNode> navigationLinks = null; JPAEntityParser jpaResultParser = new JPAEntityParser(); EdmNavigationProperty currentNavigationProperty = context.getNavigationProperty(); try { Object inlinedEntry = entry.get(currentNavigationProperty.getName()); if (nextEntitySet == null) { nextEntitySet = context.getSourceEntitySet().getRelatedEntitySet(currentNavigationProperty); } edmPropertyValueMap = jpaResultParser.parse2EdmPropertyValueMap(inlinedEntry, nextEntitySet.getEntityType()); result.setEntryData(edmPropertyValueMap); navigationLinks = context.getCurrentExpandSelectTreeNode().getLinks(); if (navigationLinks.size() > 0) { currentNavPropertyList = new ArrayList<EdmNavigationProperty>(); currentNavPropertyList.add(getNextNavigationProperty(context.getSourceEntitySet().getEntityType(), context.getNavigationProperty())); HashMap<String, Object> navigationMap = jpaResultParser.parse2EdmNavigationValueMap(inlinedEntry, currentNavPropertyList); edmPropertyValueMap.putAll(navigationMap); result.setEntryData(edmPropertyValueMap); } result.setInlineProperties(getInlineEntityProviderProperties(context)); } catch (EdmException e) { } catch (ODataJPARuntimeException e) { } return result; } @Override public WriteFeedCallbackResult retrieveFeedResult( final WriteFeedCallbackContext context) { WriteFeedCallbackResult result = new WriteFeedCallbackResult(); HashMap<String, Object> inlinedEntry = (HashMap<String, Object>) context.getEntryData(); List<Map<String, Object>> edmEntityList = new ArrayList<Map<String, Object>>(); Map<String, Object> edmPropertyValueMap = null; JPAEntityParser jpaResultParser = new JPAEntityParser(); List<EdmNavigationProperty> currentNavPropertyList = null; EdmNavigationProperty currentNavigationProperty = context.getNavigationProperty(); try { @SuppressWarnings({ "unchecked" }) List<Object> listOfItems = (List<Object>) inlinedEntry.get(context.getNavigationProperty().getName()); if (nextEntitySet == null) { nextEntitySet = context.getSourceEntitySet().getRelatedEntitySet(currentNavigationProperty); } for (Object object : listOfItems) { edmPropertyValueMap = jpaResultParser.parse2EdmPropertyValueMap(object, nextEntitySet.getEntityType()); edmEntityList.add(edmPropertyValueMap); } result.setFeedData(edmEntityList); if (context.getCurrentExpandSelectTreeNode().getLinks().size() > 0) { currentNavPropertyList = new ArrayList<EdmNavigationProperty>(); currentNavPropertyList.add(getNextNavigationProperty(context.getSourceEntitySet().getEntityType(), context.getNavigationProperty())); int count = 0; for (Object object : listOfItems) { HashMap<String, Object> navigationMap = jpaResultParser.parse2EdmNavigationValueMap(object, currentNavPropertyList); edmEntityList.get(count).putAll(navigationMap); count++; } result.setFeedData(edmEntityList); } result.setInlineProperties(getInlineEntityProviderProperties(context)); } catch (EdmException e) { } catch (ODataJPARuntimeException e) { } return result; } private EdmNavigationProperty getNextNavigationProperty( final EdmEntityType sourceEntityType, final EdmNavigationProperty navigationProperty) throws EdmException { int count; for (ArrayList<NavigationPropertySegment> navPropSegments : expandList) { count = 0; for (NavigationPropertySegment navPropSegment : navPropSegments) { EdmNavigationProperty navProperty = navPropSegment.getNavigationProperty(); if (navProperty.getFromRole().equalsIgnoreCase(sourceEntityType.getName()) && navProperty.getName().equals(navigationProperty.getName())) { return navPropSegments.get(count + 1).getNavigationProperty(); } else { count++; } } } return null; } public static <T> Map<String, ODataCallback> getCallbacks(final URI baseUri, final ExpandSelectTreeNode expandSelectTreeNode, final List<ArrayList<NavigationPropertySegment>> expandList) throws EdmException { Map<String, ODataCallback> callbacks = new HashMap<String, ODataCallback>(); for (String navigationPropertyName : expandSelectTreeNode.getLinks().keySet()) { callbacks.put(navigationPropertyName, new JPAExpandCallBack(baseUri, expandList)); } return callbacks; } private EntityProviderWriteProperties getInlineEntityProviderProperties(final WriteCallbackContext context) throws EdmException { ODataEntityProviderPropertiesBuilder propertiesBuilder = EntityProviderWriteProperties.serviceRoot(baseUri); propertiesBuilder.callbacks(getCallbacks(baseUri, context.getCurrentExpandSelectTreeNode(), expandList)); propertiesBuilder.expandSelectTree(context.getCurrentExpandSelectTreeNode()); return propertiesBuilder.build(); } }