/******************************************************************************* * 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.model; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import org.apache.olingo.odata2.api.edm.provider.Association; import org.apache.olingo.odata2.api.edm.provider.ComplexType; import org.apache.olingo.odata2.api.edm.provider.EntityType; import org.apache.olingo.odata2.api.edm.provider.NavigationProperty; import org.apache.olingo.odata2.api.edm.provider.Schema; import org.apache.olingo.odata2.jpa.processor.api.access.JPAEdmBuilder; import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException; import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException; import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmAssociationView; import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmComplexTypeView; import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmEntityContainerView; import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmEntitySetView; import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmEntityTypeView; import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmExtension; import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmFunctionImportView; import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmModelView; import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmSchemaView; import org.apache.olingo.odata2.jpa.processor.core.access.model.JPAEdmNameBuilder; public class JPAEdmSchema extends JPAEdmBaseViewImpl implements JPAEdmSchemaView { private Schema schema; private JPAEdmComplexTypeView complexTypeView; private JPAEdmEntityContainerView entityContainerView; private JPAEdmAssociationView associationView = null; private LinkedHashMap<Class<?>, String[]> customOperations = null; public JPAEdmSchema(final JPAEdmModelView modelView) { super(modelView); } @Override public Schema getEdmSchema() { return schema; } @Override public JPAEdmEntityContainerView getJPAEdmEntityContainerView() { return entityContainerView; } @Override public JPAEdmComplexTypeView getJPAEdmComplexTypeView() { return complexTypeView; } @Override public JPAEdmBuilder getBuilder() { if (builder == null) { builder = new JPAEdmSchemaBuilder(); } return builder; } @Override public void clean() { super.clean(); schema = null; } private class JPAEdmSchemaBuilder implements JPAEdmBuilder { /* * * Each call to build method creates a new EDM Schema. The newly created * schema is built with Entity Containers, associations, Complex Types * and Entity Types. * * ************************************************************ Build * EDM Schema - STEPS * ************************************************************ 1) Build * Name for EDM Schema 2) Build EDM Complex Types from JPA Embeddable * Types 3) Add EDM Complex Types to EDM Schema 4) Build EDM Entity * Container 5) Add EDM Entity Container to EDM Schema 6) Fetch Built * EDM Entity Types from EDM Entity Container 7) Add EDM Entity Types to * EDM Schema 8) Fetch Built EDM Association Sets from EDM Entity * Container 9) Fetch Built EDM Associations from EDM Association Set * 10) Add EDM Association to EDM Schema * ************************************************************ Build * EDM Schema - STEPS * ************************************************************ */ @Override public void build() throws ODataJPAModelException, ODataJPARuntimeException { schema = new Schema(); JPAEdmNameBuilder.build(JPAEdmSchema.this); associationView = new JPAEdmAssociation(JPAEdmSchema.this); complexTypeView = new JPAEdmComplexType(JPAEdmSchema.this); complexTypeView.getBuilder().build(); entityContainerView = new JPAEdmEntityContainer(JPAEdmSchema.this); entityContainerView.getBuilder().build(); schema.setEntityContainers(entityContainerView.getConsistentEdmEntityContainerList()); JPAEdmEntitySetView entitySetView = entityContainerView.getJPAEdmEntitySetView(); if (entitySetView.isConsistent() && entitySetView.getJPAEdmEntityTypeView() != null) { JPAEdmEntityTypeView entityTypeView = entitySetView.getJPAEdmEntityTypeView(); if (entityTypeView.isConsistent() && !entityTypeView.getConsistentEdmEntityTypes().isEmpty()) { schema.setEntityTypes(entityTypeView.getConsistentEdmEntityTypes()); } } if (complexTypeView.isConsistent()) { List<ComplexType> complexTypes = complexTypeView.getConsistentEdmComplexTypes(); List<ComplexType> existingComplexTypes = new ArrayList<ComplexType>(); for (ComplexType complexType : complexTypes) { if (complexType != null && complexTypeView.isReferencedInKey(complexType.getName())) {// null check for // exclude existingComplexTypes.add(complexType); } } if (!existingComplexTypes.isEmpty()) { schema.setComplexTypes(existingComplexTypes); } } List<String> existingAssociationList = new ArrayList<String>(); if (associationView.isConsistent() && !associationView.getConsistentEdmAssociationList().isEmpty()) { List<Association> consistentAssociationList = associationView.getConsistentEdmAssociationList(); schema.setAssociations(consistentAssociationList); for (Association association : consistentAssociationList) { existingAssociationList.add(association.getName()); } } List<EntityType> entityTypes = entityContainerView.getJPAEdmEntitySetView().getJPAEdmEntityTypeView().getConsistentEdmEntityTypes(); List<NavigationProperty> navigationProperties; if (entityTypes != null && !entityTypes.isEmpty()) { for (EntityType entityType : entityTypes) { List<NavigationProperty> consistentNavigationProperties = null; navigationProperties = entityType.getNavigationProperties(); if (navigationProperties != null) { consistentNavigationProperties = new ArrayList<NavigationProperty>(); for (NavigationProperty navigationProperty : navigationProperties) { if (existingAssociationList.contains(navigationProperty.getRelationship().getName())) { consistentNavigationProperties.add(navigationProperty); } } if (consistentNavigationProperties.isEmpty()) { entityType.setNavigationProperties(null); } else { entityType.setNavigationProperties(consistentNavigationProperties); } } } } JPAEdmExtension edmExtension = getJPAEdmExtension(); if (edmExtension != null) { edmExtension.extendJPAEdmSchema(JPAEdmSchema.this); edmExtension.extendWithOperation(JPAEdmSchema.this); JPAEdmFunctionImportView functionImportView = new JPAEdmFunctionImport(JPAEdmSchema.this); functionImportView.getBuilder().build(); if (functionImportView.getConsistentFunctionImportList() != null) { entityContainerView.getEdmEntityContainer().setFunctionImports( functionImportView.getConsistentFunctionImportList()); } } } } @Override public final JPAEdmAssociationView getJPAEdmAssociationView() { return associationView; } @Override public void registerOperations(final Class<?> customClass, final String[] methodNames) { if (customOperations == null) { customOperations = new LinkedHashMap<Class<?>, String[]>(); } customOperations.put(customClass, methodNames); } @Override public HashMap<Class<?>, String[]> getRegisteredOperations() { return customOperations; } }