| /* |
| * 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 java.util.ArrayList; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.concurrent.ConcurrentHashMap; |
| |
| import org.apache.olingo.commons.api.edm.FullQualifiedName; |
| import org.apache.olingo.commons.api.edm.provider.CsdlAction; |
| import org.apache.olingo.commons.api.edm.provider.CsdlActionImport; |
| import org.apache.olingo.commons.api.edm.provider.CsdlAliasInfo; |
| import org.apache.olingo.commons.api.edm.provider.CsdlAnnotations; |
| import org.apache.olingo.commons.api.edm.provider.CsdlComplexType; |
| import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider; |
| import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer; |
| import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainerInfo; |
| import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet; |
| import org.apache.olingo.commons.api.edm.provider.CsdlEntityType; |
| import org.apache.olingo.commons.api.edm.provider.CsdlEnumType; |
| import org.apache.olingo.commons.api.edm.provider.CsdlFunction; |
| import org.apache.olingo.commons.api.edm.provider.CsdlFunctionImport; |
| import org.apache.olingo.commons.api.edm.provider.CsdlSchema; |
| import org.apache.olingo.commons.api.edm.provider.CsdlSingleton; |
| import org.apache.olingo.commons.api.edm.provider.CsdlTerm; |
| import org.apache.olingo.commons.api.edm.provider.CsdlTypeDefinition; |
| import org.apache.olingo.commons.api.edmx.EdmxReference; |
| import org.apache.olingo.commons.api.edmx.EdmxReferenceInclude; |
| import org.apache.olingo.commons.api.ex.ODataException; |
| |
| public class SchemaBasedEdmProvider implements CsdlEdmProvider { |
| private final List<CsdlSchema> edmSchemas = new ArrayList<>(); |
| private final Map<String, EdmxReference> references = new ConcurrentHashMap<>(); |
| private final Map<String, SchemaBasedEdmProvider> referenceSchemas = |
| new ConcurrentHashMap<>(); |
| private final Map<String, SchemaBasedEdmProvider> coreVocabularySchemas = |
| new ConcurrentHashMap<>(); |
| |
| protected void addSchema(CsdlSchema schema) { |
| this.edmSchemas.add(schema); |
| } |
| |
| public List<EdmxReference> getReferences(){ |
| return new ArrayList<>(references.values()); |
| } |
| |
| protected void addReferenceSchema(String ns, SchemaBasedEdmProvider provider) { |
| this.referenceSchemas.put(ns, provider); |
| } |
| |
| protected void addVocabularySchema(String ns, SchemaBasedEdmProvider provider) { |
| this.coreVocabularySchemas.put(ns, provider); |
| } |
| |
| protected void addReference(EdmxReference reference) { |
| for (EdmxReferenceInclude include : reference.getIncludes()) { |
| this.references.put(include.getNamespace(), reference); |
| } |
| } |
| |
| CsdlSchema getVocabularySchema(String ns) { |
| SchemaBasedEdmProvider provider = this.coreVocabularySchemas.get(ns); |
| if (provider != null) { |
| return provider.getSchema(ns, false); |
| } |
| return null; |
| } |
| |
| CsdlSchema getSchema(String ns) { |
| return getSchema(ns, true); |
| } |
| |
| CsdlSchema getSchema(String ns, boolean checkReferences) { |
| if (checkReferences) { |
| return getSchemaRecursively(ns, new HashSet<String>()); |
| } else { |
| return getSchemaDirectly(ns); |
| } |
| } |
| |
| CsdlSchema getSchemaDirectly(String ns) { |
| for (CsdlSchema s : this.edmSchemas) { |
| if (s.getNamespace().equals(ns)) { |
| return s; |
| } |
| } |
| return null; |
| } |
| |
| CsdlSchema getSchemaRecursively(String ns, Set<String> parsedPath) { |
| // find the schema by namespace in current provider |
| CsdlSchema schema = getSchemaDirectly(ns); |
| if (schema != null) { |
| return schema; |
| } |
| |
| // find the schema by namespace in the reference schema provider |
| for (Map.Entry<String, SchemaBasedEdmProvider> entry : this.referenceSchemas.entrySet()) { |
| String namespace = entry.getKey(); |
| if (parsedPath.contains(namespace)) { |
| continue; |
| } |
| SchemaBasedEdmProvider provider = entry.getValue(); |
| parsedPath.add(namespace); |
| schema = provider.getSchemaRecursively(ns, parsedPath); |
| if (schema != null) { |
| return schema; |
| } |
| } |
| |
| return getVocabularySchema(ns); |
| } |
| |
| @Override |
| public CsdlEnumType getEnumType(FullQualifiedName fqn) throws ODataException { |
| CsdlSchema schema = getSchema(fqn.getNamespace()); |
| if (schema != null) { |
| List<CsdlEnumType> types = schema.getEnumTypes(); |
| if (types != null) { |
| for (CsdlEnumType type : types) { |
| if (type.getName().equals(fqn.getName())) { |
| return type; |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public CsdlTypeDefinition getTypeDefinition(FullQualifiedName fqn) throws ODataException { |
| CsdlSchema schema = getSchema(fqn.getNamespace()); |
| if (schema != null) { |
| List<CsdlTypeDefinition> types = schema.getTypeDefinitions(); |
| if (types != null) { |
| for (CsdlTypeDefinition type : types) { |
| if (type.getName().equals(fqn.getName())) { |
| return type; |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public List<CsdlFunction> getFunctions(FullQualifiedName fqn) throws ODataException { |
| ArrayList<CsdlFunction> foundFuncs = new ArrayList<>(); |
| CsdlSchema schema = getSchema(fqn.getNamespace()); |
| if (schema != null) { |
| List<CsdlFunction> functions = schema.getFunctions(); |
| if (functions != null) { |
| for (CsdlFunction func : functions) { |
| if (func.getName().equals(fqn.getName())) { |
| foundFuncs.add(func); |
| } |
| } |
| } |
| } |
| return foundFuncs; |
| } |
| |
| @Override |
| public CsdlTerm getTerm(FullQualifiedName fqn) throws ODataException { |
| CsdlSchema schema = getSchema(fqn.getNamespace()); |
| if (schema != null) { |
| List<CsdlTerm> terms = schema.getTerms(); |
| if (terms != null) { |
| for (CsdlTerm term : terms) { |
| if (term.getName().equals(fqn.getName())) { |
| return term; |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public CsdlEntitySet getEntitySet(FullQualifiedName fqn, String entitySetName) throws ODataException { |
| CsdlSchema schema = getSchema(fqn.getNamespace()); |
| if (schema != null) { |
| CsdlEntityContainer ec = schema.getEntityContainer(); |
| if (ec != null && ec.getEntitySets() != null) { |
| for (CsdlEntitySet es : ec.getEntitySets()) { |
| if (es.getName().equals(entitySetName)) { |
| return es; |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public CsdlSingleton getSingleton(FullQualifiedName fqn, String singletonName) throws ODataException { |
| CsdlSchema schema = getSchema(fqn.getNamespace()); |
| if (schema != null) { |
| CsdlEntityContainer ec = schema.getEntityContainer(); |
| if (ec != null && ec.getSingletons() != null) { |
| for (CsdlSingleton es : ec.getSingletons()) { |
| if (es.getName().equals(singletonName)) { |
| return es; |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public CsdlActionImport getActionImport(FullQualifiedName fqn, String actionImportName) |
| throws ODataException { |
| CsdlSchema schema = getSchema(fqn.getNamespace()); |
| if (schema != null) { |
| CsdlEntityContainer ec = schema.getEntityContainer(); |
| if (ec != null && ec.getActionImports() != null) { |
| for (CsdlActionImport es : ec.getActionImports()) { |
| if (es.getName().equals(actionImportName)) { |
| return es; |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public CsdlFunctionImport getFunctionImport(FullQualifiedName fqn, String functionImportName) |
| throws ODataException { |
| CsdlSchema schema = getSchema(fqn.getNamespace()); |
| if (schema != null) { |
| CsdlEntityContainer ec = schema.getEntityContainer(); |
| if (ec != null && ec.getFunctionImports() != null) { |
| for (CsdlFunctionImport es : ec.getFunctionImports()) { |
| if (es.getName().equals(functionImportName)) { |
| return es; |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName fqn) throws ODataException { |
| CsdlSchema schema = null; |
| |
| if (fqn == null) { |
| for (CsdlSchema s : this.edmSchemas) { |
| if (s.getEntityContainer() != null) { |
| schema = s; |
| break; |
| } |
| } |
| } else { |
| schema = getSchema(fqn.getNamespace()); |
| } |
| |
| if (schema != null) { |
| CsdlEntityContainer ec = schema.getEntityContainer(); |
| if (ec != null) { |
| CsdlEntityContainerInfo info = new CsdlEntityContainerInfo(); |
| info.setContainerName(new FullQualifiedName(schema.getNamespace(), ec.getName())); |
| if (schema.getEntityContainer().getExtendsContainer() != null) { |
| info.setExtendsContainer(new FullQualifiedName(schema.getEntityContainer().getExtendsContainer())); |
| } |
| return info; |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public List<CsdlAliasInfo> getAliasInfos() throws ODataException { |
| ArrayList<CsdlAliasInfo> list = new ArrayList<>(); |
| for (CsdlSchema s : this.edmSchemas) { |
| if (s.getAlias() != null) { |
| CsdlAliasInfo ai = new CsdlAliasInfo(); |
| ai.setAlias(s.getAlias()); |
| ai.setNamespace(s.getNamespace()); |
| list.add(ai); |
| } |
| } |
| for(EdmxReference reference:this.references.values()) { |
| for(EdmxReferenceInclude include:reference.getIncludes()) { |
| if (include.getAlias() != null) { |
| CsdlAliasInfo ai = new CsdlAliasInfo(); |
| ai.setAlias(include.getAlias()); |
| ai.setNamespace(include.getNamespace()); |
| list.add(ai); |
| } |
| } |
| } |
| for (SchemaBasedEdmProvider p:this.coreVocabularySchemas.values()) { |
| for (CsdlSchema s:p.getSchemas()) { |
| if (s.getAlias() != null) { |
| CsdlAliasInfo ai = new CsdlAliasInfo(); |
| ai.setAlias(s.getAlias()); |
| ai.setNamespace(s.getNamespace()); |
| list.add(ai); |
| } |
| } |
| } |
| return list; |
| } |
| |
| @Override |
| public CsdlEntityContainer getEntityContainer() throws ODataException { |
| // note that there can be many schemas, but only one needs to contain the |
| // entity container in a given metadata document. |
| for (CsdlSchema s : this.edmSchemas) { |
| if (s.getEntityContainer() != null) { |
| return s.getEntityContainer(); |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public List<CsdlSchema> getSchemas() throws ODataException { |
| return new ArrayList<>(this.edmSchemas); |
| } |
| |
| @Override |
| public CsdlEntityType getEntityType(final FullQualifiedName fqn) throws ODataException { |
| CsdlSchema schema = getSchema(fqn.getNamespace()); |
| if (schema != null && schema.getEntityTypes() != null) { |
| for (CsdlEntityType type : schema.getEntityTypes()) { |
| if (type.getName().equals(fqn.getName())) { |
| return type; |
| } |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public CsdlComplexType getComplexType(final FullQualifiedName fqn) throws ODataException { |
| CsdlSchema schema = getSchema(fqn.getNamespace()); |
| if (schema != null && schema.getComplexTypes() != null) { |
| for (CsdlComplexType type : schema.getComplexTypes()) { |
| if (type.getName().equals(fqn.getName())) { |
| return type; |
| } |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public List<CsdlAction> getActions(final FullQualifiedName fqn) throws ODataException { |
| ArrayList<CsdlAction> actions = new ArrayList<>(); |
| CsdlSchema schema = getSchema(fqn.getNamespace()); |
| if (schema != null) { |
| List<CsdlAction> types = schema.getActions(); |
| if (types != null) { |
| for (CsdlAction type : types) { |
| if (type.getName().equals(fqn.getName())) { |
| actions.add(type); |
| } |
| } |
| } |
| } |
| return actions; |
| } |
| |
| @Override |
| public CsdlAnnotations getAnnotationsGroup(FullQualifiedName targetName, String qualifier) throws ODataException { |
| CsdlSchema schema = getSchema(targetName.getNamespace()); |
| if (schema != null) { |
| return schema.getAnnotationGroup(targetName.getFullQualifiedNameAsString(), qualifier); |
| } |
| return null; |
| } |
| } |