All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sap.gateway.v4.rt.jdbc.hana.ODataToHANAProcessor Maven / Gradle / Ivy

/*package com.sap.gateway.v4.rt.jdbc.hana;

import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;

import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.data.ValueType;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmFunctionImport;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriInfoResource;
import org.apache.olingo.server.api.uri.UriParameter;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
import org.apache.olingo.server.api.uri.UriResourceFunction;
import org.apache.olingo.server.api.uri.UriResourceNavigation;
import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
import org.apache.olingo.server.api.uri.queryoption.FilterOption;
import org.apache.olingo.server.api.uri.queryoption.OrderByOption;
import org.apache.olingo.server.api.uri.queryoption.SkipOption;
import org.apache.olingo.server.api.uri.queryoption.TopOption;
import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sap.gateway.v4.rt.jdbc.core.ODataToJDBCProcessor;
import com.sap.gateway.v4.rt.jdbc.hana.util.HANAODataArtifact;
import com.sap.gateway.v4.rt.jdbc.util.DBODataArtifact;

public class ODataToHANAProcessor extends ODataToJDBCProcessor{
	
	String schema = "";
	int rId = 0;
	Connection conn = null;
	private List artifacts;
	HashMap entitySetToHOA;
	
	final static Logger logger=LoggerFactory.getLogger(ODataToHANAProcessor.class);

	public ODataToHANAProcessor() {

	}
	
	@Override
	public void initialize(String schema,Connection conn,List artifacts) {
		
		this.schema = schema;
		this.conn = conn;
		this.artifacts = artifacts;
		this.entitySetToHOA = new HashMap();	
		
		for (DBODataArtifact doa : artifacts) {
		     this.entitySetToHOA.put(doa.getEntitySetName(), (HANAODataArtifact) doa);
		}

	}

	@Override
	public List formExpandSQLQueries(String sql,ExpandOption expandOption) throws ODataApplicationException {
		
		List selectTmp = new ArrayList();
		selectTmp .add(sql);
		if(expandOption != null) {			
			checkForUnimplementedFeaturesWithinExpand(expandOption.getExpandItems());
			selectTmp.addAll(getExpandSQLQueriesRecursive(expandOption.getExpandItems(),extractTableNameFromSQL(sql).replace("\"", "")));		
		}
		return selectTmp;
	}

	@Override
	public String formSQLQueryForMasterTable(UriInfo uriInfo) throws ODataApplicationException {
		
		checkForUnimplementedFeatures(uriInfo);
		
		String targetODataArtifactName;
		List uriResourceParts = uriInfo.asUriInfoResource().getUriResourceParts();
		UriResource firstUriResource = uriResourceParts.get(0);
		
		EdmEntityType targetEntityType;
		EdmEntitySet targetEntitySet;
		EdmFunctionImport functionImport;
		if(uriResourceParts.size() == 1) {
			
			if(firstUriResource instanceof UriResourceEntitySet) {
				targetEntitySet = ((UriResourceEntitySet) firstUriResource).getEntitySet();
				targetODataArtifactName = targetEntitySet.getName();
				targetEntityType = targetEntitySet.getEntityType();
			}
			else {
				functionImport = ((UriResourceFunction)firstUriResource).getFunctionImport();
				targetODataArtifactName = functionImport.getName();
				targetEntityType = (EdmEntityType) functionImport.getUnboundFunctions().get(0).getReturnType().getType();
			}
		}
		else {
			targetEntityType = ((UriResourceNavigation)uriResourceParts.get(uriResourceParts.size() - 1)).getProperty().getType();
			targetODataArtifactName = targetEntityType.getName().substring(0, targetEntityType.getName().length() - 5);//This is done because entitySetName = entityTypeName - "_type";
		}
		DBODataArtifact currentDOA = entitySetToHOA.get(targetODataArtifactName);
		String sql = simpleSelectJoins(uriResourceParts,uriResourceParts.size() - 1);

		if(uriInfo.getExpandOption() != null) {
			String temporaryTableName = getTempTableNameFromRId();
			String createTmpSQL = "CREATE LOCAL TEMPORARY TABLE " + "\"" + temporaryTableName + "\"" + " ( " + HanaSqlHelper.getTemporaryTableDefinition(targetEntityType,currentDOA.getTableDef()) + ",\"1row\" BIGINT" + ')';
			String insertTmpSQL = "INSERT INTO " + "\"" + temporaryTableName + "\"" + " ( SELECT * ,row_number() over() \"1row\"" + " FROM ( " + sql + " ) )";
			sql = "SELECT * FROM " + "\"" + temporaryTableName + "\"" + " ORDER BY \"1row\"";
			
			createAndPopulateTempTable(createTmpSQL, insertTmpSQL);
			
		}
		return sql;

	}

	@Override
	public String modifySQLForTopSkip(String sql, TopOption topOption, SkipOption skipOption) {
		String sqlToappend="";
		if(topOption!=null && skipOption!=null){
			sqlToappend=" LIMIT "+topOption.getValue() +" OFFSET "+skipOption.getValue();
		}else if (skipOption!=null){
			sqlToappend=" LIMIT null OFFSET "+skipOption.getValue();
		}else if (topOption!=null){
			sqlToappend=" LIMIT "+topOption.getValue();
		}
		return sql+sqlToappend;
	}

	@Override
	public String modifySQLForFilter(String sql, FilterOption filterOption)throws ODataApplicationException {
		StringBuffer tempWhere=new StringBuffer("");
		if(filterOption!=null){
			String filterExp = null;
			Expression expression=filterOption.getExpression();
			try {
				filterExp=expression.accept(new HanaExpressionVisitor()).toString();
			} catch (ExpressionVisitException e) {
				logger.error(e.getMessage(),e);
				throw new ODataApplicationException(e.getMessage(), HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ENGLISH,e);

			}
			if(filterExp!=null&&!filterExp.contains("/")){
				logger.debug("Filter Expression after parsing"+filterExp);
				tempWhere = appendTableName(filterExp, sql, sql.contains("WHERE"));			
			}
			else{
				logger.error(HttpStatusCode.NOT_IMPLEMENTED.getStatusCode()+"Filter on Navigation not implemented");
				throw new ODataApplicationException("Filter on Navigation not implemented",
				          HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH,"501");
			}
				//tempWhere = appendNavigationTableName(filterExp, sourceEntity);	
		}
		return appendWheretoSql(sql,tempWhere.toString());
	}

	private List getExpandSQLQueriesRecursive(List expandItems,String previousTempTable) throws ODataApplicationException {
		
		List select = new ArrayList();
		
		for(ExpandItem currentExpandItem : expandItems) {
			
			String createTmpSQL,insertTmpSQL,selectTmpSQL;
			UriResourceNavigation uriResourceNav = (UriResourceNavigation) currentExpandItem.getResourcePath().getUriResourceParts().get(0);
			EdmNavigationProperty np = uriResourceNav.getProperty();
			EdmEntityType entityType = np.getType();
			DBODataArtifact currentJOA = entitySetToHOA.get(entityType.getName().substring(0, entityType.getName().length() - 5));
			String currentHanaArtifact = currentJOA.getArtifactName();
			String currentQuery = "SELECT " + "\"" + previousTempTable + "\"" + ".\"1row\" \"0row\",";
			
			List orderByForOver = new ArrayList();
			orderByForOver.add('"' + previousTempTable + '"' + '.' + "\"1row\"");
			orderByForOver.addAll(HanaSqlHelper.getKeyPropertyNamesFromEntityType(entityType, "ALIAS"));
			currentQuery += HanaSqlHelper.constructOverInSQL(orderByForOver) + ',';
			currentQuery += '"' + "ALIAS" + '"' + ".*";
			
			String joinSubQuery = "(SELECT " + HanaSqlHelper.getSQLQueryWith0123AliasedKeysForSelect(entityType,currentHanaArtifact,schema) + ',' + '"' + schema + '"' + '.' + '"' + currentHanaArtifact + '"' + ".* FROM " +
			'"' + schema + '"' + '.' + '"' + currentHanaArtifact + '"' +") as \"ALIAS\"";
			
			currentQuery += " FROM " + '"' + previousTempTable + '"' + " join " + joinSubQuery + " on " + HanaSqlHelper.getJoinConditionsFromNavigationPropery(previousTempTable,"ALIAS", np,null);
			currentQuery += " ORDER BY \"1row\"";
			
			if(currentExpandItem.getExpandOption() != null) {
				
				String temporaryTableName = getTempTableNameFromRId();
				createTmpSQL = "CREATE LOCAL TEMPORARY TABLE " + "\"" + temporaryTableName + "\"" + " ( \"0row\" BIGINT,\"1row\" BIGINT," + HanaSqlHelper.getTemporaryTableDefinition(entityType, currentJOA.getTableDef()) + ')';
				insertTmpSQL = "INSERT INTO " + '"' + temporaryTableName + '"' + " (" + currentQuery + ")";
				selectTmpSQL = "SELECT * FROM " + "\"" + temporaryTableName + "\"" + " ORDER BY \"1row\"";			
				select.add(selectTmpSQL);
				
				createAndPopulateTempTable(createTmpSQL, insertTmpSQL);
				
				select.addAll(getExpandSQLQueriesRecursive(currentExpandItem.getExpandOption().getExpandItems(),temporaryTableName));	
				
			}
			else {
				select.add(currentQuery);
			}

		}
		return select;
	}
	
	@Override
	public EntityCollection processResultSet(List results, UriInfo uriInfo) throws ODataApplicationException {

		ArrayList>> dataSet = new ArrayList>>();
		
		for(ResultSet rs : results) {
			try {
				dataSet.add(HanaSqlHelper.extractResultSetData(rs));
			} catch (SQLException e) {
				throw new ODataApplicationException(e.getMessage(), HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ENGLISH,e);
			} catch (IOException e) {
				throw new ODataApplicationException(e.getMessage(), HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ENGLISH,e);
			}
		}
		EdmEntityType targetEntityType;
		UriInfoResource uriInfoResource = uriInfo.asUriInfoResource();                                 
		List uriResourceParts = uriInfoResource.getUriResourceParts();                                                                
		UriResource targetUriResource = uriResourceParts.get(uriResourceParts.size() - 1);   
		
		if(targetUriResource instanceof UriResourceEntitySet)
			targetEntityType = ((UriResourceEntitySet)targetUriResource).getEntityType();
		else if(targetUriResource instanceof UriResourceNavigation)
			targetEntityType = ((UriResourceNavigation)targetUriResource).getProperty().getType();
		else
			targetEntityType = (EdmEntityType) ((UriResourceFunction)targetUriResource).getFunction().getReturnType().getType();
		
		EntityCollection ec = new EntityCollection();
		Iterator>> dataSetIterator = dataSet.listIterator();

		List> resultEntityMaps = getResultListRecursive(uriInfo.getExpandOption(),dataSetIterator);

		List resultEntities = new ArrayList();
		
		for(Map targetEntityMap : resultEntityMaps)
			resultEntities.add(convertMapToEntity(targetEntityMap,targetEntityType));
		
		ec.getEntities().addAll(resultEntities);
		
		return ec;
	}
	
	private List> getResultListRecursive(ExpandOption expandOption,Iterator>> dataSetIterator) {
		
		List expandItems = new ArrayList();
		List> currentDataSet = dataSetIterator.next();
		if(expandOption != null && !expandOption.getExpandItems().isEmpty())
			expandItems = expandOption.getExpandItems();
		else 
			return currentDataSet;
		
		for(ExpandItem currentExpandItem : expandItems) {
			EdmNavigationProperty np = ((UriResourceNavigation) currentExpandItem.getResourcePath().getUriResourceParts().get(0)).getProperty();
			EdmEntityType child = np.getType();
			List> childEntityList = getResultListRecursive(currentExpandItem.getExpandOption(), dataSetIterator);
			List entities;
			ListIterator> iter = childEntityList.listIterator();
			for(Map currentEntityMap : currentDataSet) {
				entities = new ArrayList();
				Long parentId = (Long) currentEntityMap.get("1row");
				while(iter.hasNext()) {
					Map currentChildEntityMap = iter.next();
					if(parentId.equals(currentChildEntityMap.get("0row"))) {
						entities.add(convertMapToEntity(currentChildEntityMap,child));			
					}
					else {
						iter.previous();
						break;
					}
				
				}
				if(np.isCollection())
					currentEntityMap.put(np.getName(), entities);
				else if(entities.size() > 0)
					currentEntityMap.put(np.getName(), entities.get(0));
			}
			
		}
		return currentDataSet;
	}
	

	@SuppressWarnings("unchecked")
	private Entity convertMapToEntity(Map targetEntityMap, EdmEntityType targetEntityType) {
		
		Entity e = new Entity();
		List propertyNames = targetEntityType.getPropertyNames();
		for(Map.Entry entry : targetEntityMap.entrySet()) {
			String key = entry.getKey();
			Object value = entry.getValue();
			if(propertyNames.contains(key)) {
				if(targetEntityType.getStructuralProperty(key).getType().getFullQualifiedName().equals(EdmPrimitiveTypeKind.Boolean.getFullQualifiedName()))
					e.addProperty(new Property(null, key, ValueType.PRIMITIVE, value.toString().equals("1")));	
				else
					e.addProperty(new Property(null, key, ValueType.PRIMITIVE, value));
			}
			else if(value instanceof Entity) {
				Link link = new Link();
				link.setTitle(key);
				link.setInlineEntity((Entity) value);
				e.getNavigationLinks().add(link);
			}
			else if(value instanceof List) {
				Link link = new Link();
				link.setTitle(key);
				EntityCollection ec = new EntityCollection();
				ec.getEntities().addAll((List)value);
				link.setInlineEntitySet(ec);
				e.getNavigationLinks().add(link);
			}
		}
		
		return e;
		
	}
	
	public String modifySQLForOrderBy(String sql, OrderByOption orderByOption) {
		// TODO Auto-generated method stub
		return sql;
	}
	
	
	public String simpleSelectJoins(List uriResourceParts, int currentIndex) {
		
		UriResourceEntitySet uriResourceEntitySet;
		EdmEntityType currentEntityType;
		EdmEntityType previousEntityType;
		UriResourceNavigation uriResourceNavigation;
		List keyPredicates;
		UriResource uriResourcePartCurrent = uriResourceParts.get(currentIndex);
		UriResource uriResourcePartPrevious = currentIndex > 0 ? uriResourceParts.get(currentIndex-1):null;
		List parameters = new ArrayList();
		if(currentIndex == 0) {
			if(uriResourcePartCurrent instanceof UriResourceEntitySet) {
				uriResourceEntitySet = ((UriResourceEntitySet)uriResourcePartCurrent);
				keyPredicates = uriResourceEntitySet.getKeyPredicates();
				currentEntityType = uriResourceEntitySet.getEntityType();
			}
			else{
				UriResourceFunction uriResourceFunction = ((UriResourceFunction)uriResourcePartCurrent);
				keyPredicates = uriResourceFunction.getKeyPredicates();
				parameters = uriResourceFunction.getParameters();
				currentEntityType = (EdmEntityType) uriResourceFunction.getFunction().getReturnType().getType();
			}
		}
		else {
			uriResourceNavigation = ((UriResourceNavigation)uriResourcePartCurrent);
			keyPredicates = uriResourceNavigation.getKeyPredicates();
			currentEntityType = uriResourceNavigation.getProperty().getType();
		}
		String currentDBArtifact = entitySetToHOA.get(currentEntityType.getName().substring(0, currentEntityType.getName().length()-5)).getArtifactName();

		String inner = "";
		if(currentIndex > 0) {
			inner = simpleSelectJoins(uriResourceParts,currentIndex - 1);
			if(uriResourcePartPrevious != null) {
				String previousEntitySetName;
				String previousDBArtifact = "";
				UriResourceNavigation currentNavigationProperty = (UriResourceNavigation)uriResourcePartCurrent;
					if(uriResourcePartPrevious instanceof UriResourceEntitySet) {
						uriResourceEntitySet = ((UriResourceEntitySet)uriResourcePartPrevious);
						previousEntitySetName = uriResourceEntitySet.getEntitySet().getName();
					}
					else {
						uriResourceNavigation = ((UriResourceNavigation)uriResourcePartPrevious);
						previousEntityType = uriResourceNavigation.getProperty().getType();
						previousEntitySetName = previousEntityType.getName().substring(0,previousEntityType.getName().length() - 5);
					}
					
					previousDBArtifact = entitySetToHOA.get(previousEntitySetName).getArtifactName();
			inner += " AND " + HanaSqlHelper.getJoinConditionsFromNavigationPropery(previousDBArtifact, currentDBArtifact, currentNavigationProperty.getProperty(),schema);
			}
			
		}
		String sel = "SELECT ";
		if(currentIndex < uriResourceParts.size()-1)
		   sel += '1';
		else
			sel += HanaSqlHelper.getSQLQueryWith0123AliasedKeysForSelect(currentEntityType,currentDBArtifact,schema) + ',' + '"' + schema + '"' + '.' + '"' + currentDBArtifact + '"' + ".*";
			
		String from = " FROM " + '"' + schema + '"' + '.' + '"' + currentDBArtifact + '"';
		String placeHolderDetails = "";
		for(UriParameter uriParam : parameters) {
			if(!placeHolderDetails.isEmpty())
				placeHolderDetails += ',';
			placeHolderDetails = "'PLACEHOLDER' = " + "('$$" + uriParam.getName() + "$$'," + uriParam.getText() + ")";
		}
		if(placeHolderDetails != "")
		from += " (" + placeHolderDetails + ")";
				
		String where = "";
		
		if(!inner.equals("")) {
			where = " WHERE EXISTS(" + inner + ")";
		}
		if(!keyPredicates.isEmpty()) {
			if(where == "")
				where = " WHERE ";
			else
				where += " AND ";
			where += HanaSqlHelper.getWhereStringFromKeyPredicates(keyPredicates, currentDBArtifact,schema);
		}
		
		return sel + from + where;	
		
		
	}
	
	private String getTempTableNameFromRId() {
		
		return "#r" + '_' + rId++;
	}
	
	public List execute(List sqlQueries) throws ODataApplicationException {

		List resultSetList = new ArrayList();
		try {
			for(int i = 0;i expandItems) throws ODataApplicationException {

		for(ExpandItem expandItem : expandItems) {
			
		if((expandItem).getCountOption() != null)
			throw new ODataApplicationException("$count system query option not implemented.",
			          HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH,"501");
		if(expandItem.getFilterOption() != null)
			throw new ODataApplicationException("$filter within $expand is not implemented.",
			          HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH,"501");
		if(expandItem.getSearchOption() != null)
				throw new ODataApplicationException("$search option is not implemented.",
				          HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH,"501");	
		if(expandItem.getLevelsOption() != null)
			throw new ODataApplicationException("$levels option is not implemented.",
			          HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH,"501");
		if(expandItem.getOrderByOption() != null)
			throw new ODataApplicationException("$orderby option is not implemented.",
			          HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH,"501");
		if(expandItem.getSkipOption() != null)
			throw new ODataApplicationException("$skip option within $expand is not implemented.",
			          HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH,"501");
		if(expandItem.getTopOption() != null)
			throw new ODataApplicationException("$top option not implemented within $expand.",
			          HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH,"501");
		if(expandItem.isStar())
			throw new ODataApplicationException("$expand=* functionality is not implemented.",
			          HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH,"501");
		if(expandItem.isRef())
			throw new ODataApplicationException("$ref functionality is not implemented.",
			          HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH,"501");
		if(expandItem.getOrderByOption() != null)
			throw new ODataApplicationException("$orderby option not implemented",
					HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH,"501");
		if(expandItem.getSelectOption() != null)
			throw new ODataApplicationException("$select option not implemented",
					HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH,"501");
	}
		
	}
	


	
}*/




© 2015 - 2025 Weber Informatics LLC | Privacy Policy