Package org.apache.olingo.odata2.processor.core.jpa.model

Source Code of org.apache.olingo.odata2.processor.core.jpa.model.JPAEdmFunctionImport

/*******************************************************************************
* 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.processor.core.jpa.model;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.olingo.odata2.api.annotation.edm.FunctionImport.Multiplicity;
import org.apache.olingo.odata2.api.annotation.edm.FunctionImport.ReturnType;
import org.apache.olingo.odata2.api.annotation.edm.Parameter;
import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
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.Facets;
import org.apache.olingo.odata2.api.edm.provider.FunctionImport;
import org.apache.olingo.odata2.api.edm.provider.FunctionImportParameter;
import org.apache.olingo.odata2.api.edm.provider.Mapping;
import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmBuilder;
import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmComplexTypeView;
import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmEntityTypeView;
import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmFunctionImportView;
import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmMapping;
import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmSchemaView;
import org.apache.olingo.odata2.processor.core.jpa.access.model.JPAEdmNameBuilder;
import org.apache.olingo.odata2.processor.core.jpa.access.model.JPATypeConvertor;

public class JPAEdmFunctionImport extends JPAEdmBaseViewImpl implements JPAEdmFunctionImportView {

  private List<FunctionImport> consistentFunctionImportList = new ArrayList<FunctionImport>();
  private JPAEdmBuilder builder = null;
  private JPAEdmSchemaView schemaView;

  public JPAEdmFunctionImport(final JPAEdmSchemaView view) {
    super(view);
    schemaView = view;
  }

  @Override
  public JPAEdmBuilder getBuilder() {
    if (builder == null) {
      builder = new JPAEdmFunctionImportBuilder();
    }
    return builder;
  }

  @Override
  public List<FunctionImport> getConsistentFunctionImportList() {
    return consistentFunctionImportList;
  }

  protected class JPAEdmFunctionImportBuilder implements JPAEdmBuilder {

    private JPAEdmEntityTypeView jpaEdmEntityTypeView = null;
    private JPAEdmComplexTypeView jpaEdmComplexTypeView = null;

    @Override
    public void build() throws ODataJPAModelException, ODataJPARuntimeException {

      HashMap<Class<?>, String[]> customOperations = schemaView.getRegisteredOperations();

      jpaEdmEntityTypeView =
          schemaView.getJPAEdmEntityContainerView().getJPAEdmEntitySetView().getJPAEdmEntityTypeView();
      jpaEdmComplexTypeView = schemaView.getJPAEdmComplexTypeView();

      if (customOperations != null) {

        for (Class<?> clazz : customOperations.keySet()) {

          String[] operationNames = customOperations.get(clazz);
          Method[] methods = clazz.getMethods();
          Method method = null;

          int length = 0;
          if (operationNames != null) {
            length = operationNames.length;
          } else {
            length = methods.length;
          }

          boolean found = false;
          for (int i = 0; i < length; i++) {

            try {
              if (operationNames != null) {
                for (Method method2 : methods) {
                  if (method2.getName().equals(operationNames[i])) {
                    found = true;
                    method = method2;
                    break;
                  }
                }
                if (found == true) {
                  found = false;
                } else {
                  continue;
                }
              } else {
                method = methods[i];
              }

              FunctionImport functionImport = buildFunctionImport(method);
              if (functionImport != null) {
                consistentFunctionImportList.add(functionImport);
              }

            } catch (SecurityException e) {
              throw ODataJPAModelException.throwException(ODataJPAModelException.GENERAL, e);
            }
          }
        }
      }
    }

    private FunctionImport buildFunctionImport(final Method method) throws ODataJPAModelException {

      org.apache.olingo.odata2.api.annotation.edm.FunctionImport annotation =
          method.getAnnotation(org.apache.olingo.odata2.api.annotation.edm.FunctionImport.class);
      if (annotation != null && annotation.returnType() != ReturnType.NONE) {
        FunctionImport functionImport = new FunctionImport();

        if (annotation.name().equals("")) {
          functionImport.setName(method.getName());
        } else {
          functionImport.setName(annotation.name());
        }

        JPAEdmMapping mapping = new JPAEdmMappingImpl();
        ((Mapping) mapping).setInternalName(method.getName());
        mapping.setJPAType(method.getDeclaringClass());
        functionImport.setMapping((Mapping) mapping);

        functionImport.setHttpMethod(annotation.httpMethod().name().toString());

        buildReturnType(functionImport, method, annotation);
        buildParameter(functionImport, method);

        return functionImport;
      }
      return null;
    }

    private void buildParameter(final FunctionImport functionImport, final Method method)
        throws ODataJPAModelException {

      Annotation[][] annotations = method.getParameterAnnotations();
      Class<?>[] parameterTypes = method.getParameterTypes();
      List<FunctionImportParameter> funcImpList = new ArrayList<FunctionImportParameter>();
      JPAEdmMapping mapping = null;
      int j = 0;
      for (Annotation[] annotationArr : annotations) {
        Class<?> parameterType = parameterTypes[j++];

        for (Annotation element : annotationArr) {
          if (element instanceof Parameter) {
            Parameter annotation = (Parameter) element;
            FunctionImportParameter functionImportParameter = new FunctionImportParameter();
            if (annotation.name().equals("")) {
              throw ODataJPAModelException.throwException(ODataJPAModelException.FUNC_PARAM_NAME_EXP.addContent(method
                  .getDeclaringClass().getName(), method.getName()), null);
            } else {
              functionImportParameter.setName(annotation.name());
            }

            functionImportParameter.setType(JPATypeConvertor.convertToEdmSimpleType(parameterType, null));
            functionImportParameter.setMode(annotation.mode().toString());

            Facets facets = new Facets();
            if (annotation.facets().maxLength() > 0) {
              facets.setMaxLength(annotation.facets().maxLength());
            }
            if (annotation.facets().nullable() == false) {
              facets.setNullable(false);
            } else {
              facets.setNullable(true);
            }

            if (annotation.facets().precision() > 0) {
              facets.setPrecision(annotation.facets().precision());
            }
            if (annotation.facets().scale() >= 0) {
              facets.setScale(annotation.facets().scale());
            }

            functionImportParameter.setFacets(facets);
            mapping = new JPAEdmMappingImpl();
            mapping.setJPAType(parameterType);
            functionImportParameter.setMapping((Mapping) mapping);
            funcImpList.add(functionImportParameter);
          }
        }
      }
      if (!funcImpList.isEmpty()) {
        functionImport.setParameters(funcImpList);
      }
    }

    private void buildReturnType(final FunctionImport functionImport, final Method method,
        final org.apache.olingo.odata2.api.annotation.edm.FunctionImport annotation) throws ODataJPAModelException {
      ReturnType returnType = annotation.returnType();
      Multiplicity multiplicity = null;

      if (returnType != ReturnType.NONE) {
        org.apache.olingo.odata2.api.edm.provider.ReturnType functionReturnType =
            new org.apache.olingo.odata2.api.edm.provider.ReturnType();
        multiplicity = annotation.multiplicity();

        if (multiplicity == Multiplicity.MANY) {
          functionReturnType.setMultiplicity(EdmMultiplicity.MANY);
        } else {
          functionReturnType.setMultiplicity(EdmMultiplicity.ONE);
        }

        if (returnType == ReturnType.ENTITY_TYPE) {
          String entitySet = annotation.entitySet();
          if (entitySet.equals("")) {
            throw ODataJPAModelException.throwException(ODataJPAModelException.FUNC_ENTITYSET_EXP, null);
          }
          functionImport.setEntitySet(entitySet);
        }

        Class<?> methodReturnType = method.getReturnType();
        if (methodReturnType == null || methodReturnType.getName().equals("void")) {
          throw ODataJPAModelException.throwException(ODataJPAModelException.FUNC_RETURN_TYPE_EXP.addContent(method
              .getDeclaringClass(), method.getName()), null);
        }
        switch (returnType) {
        case ENTITY_TYPE:
          EntityType edmEntityType = null;
          if (multiplicity == Multiplicity.ONE) {
            edmEntityType = jpaEdmEntityTypeView.searchEdmEntityType(methodReturnType.getSimpleName());
          } else if (multiplicity == Multiplicity.MANY) {
            edmEntityType = jpaEdmEntityTypeView.searchEdmEntityType(getReturnTypeSimpleName(method));
          }

          if (edmEntityType == null) {
            throw ODataJPAModelException.throwException(ODataJPAModelException.FUNC_RETURN_TYPE_ENTITY_NOT_FOUND
                .addContent(method.getDeclaringClass(), method.getName(), methodReturnType.getSimpleName()), null);
          }
          functionReturnType.setTypeName(JPAEdmNameBuilder.build(schemaView, edmEntityType.getName()));
          break;
        case SCALAR:

          EdmSimpleTypeKind edmSimpleTypeKind = JPATypeConvertor.convertToEdmSimpleType(methodReturnType, null);
          functionReturnType.setTypeName(edmSimpleTypeKind.getFullQualifiedName());

          break;
        case COMPLEX_TYPE:
          ComplexType complexType = null;
          if (multiplicity == Multiplicity.ONE) {
            complexType = jpaEdmComplexTypeView.searchEdmComplexType(methodReturnType.getName());
          } else if (multiplicity == Multiplicity.MANY) {
            complexType = jpaEdmComplexTypeView.searchEdmComplexType(getReturnTypeName(method));
          }
          if (complexType == null) {
            throw ODataJPAModelException.throwException(ODataJPAModelException.FUNC_RETURN_TYPE_ENTITY_NOT_FOUND
                .addContent(method.getDeclaringClass(), method.getName(), methodReturnType.getSimpleName()), null);
          }
          functionReturnType.setTypeName(JPAEdmNameBuilder.build(schemaView, complexType.getName()));
          break;
        default:
          break;
        }
        functionImport.setReturnType(functionReturnType);
      }
    }

    private String getReturnTypeName(final Method method) {
      try {
        ParameterizedType pt = (ParameterizedType) method.getGenericReturnType();
        Type t = pt.getActualTypeArguments()[0];
        return ((Class<?>) t).getName();
      } catch (ClassCastException e) {
        return method.getReturnType().getName();
      }
    }

    private String getReturnTypeSimpleName(final Method method) {
      try {
        ParameterizedType pt = (ParameterizedType) method.getGenericReturnType();
        Type t = pt.getActualTypeArguments()[0];
        return ((Class<?>) t).getSimpleName();
      } catch (ClassCastException e) {
        return method.getReturnType().getSimpleName();
      }
    }
  }
}
TOP

Related Classes of org.apache.olingo.odata2.processor.core.jpa.model.JPAEdmFunctionImport

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.