Package it.eng.qbe.statement.jpa

Source Code of it.eng.qbe.statement.jpa.JPQLBusinessViewUtility

/**
* SpagoBI - The Business Intelligence Free Platform
*
* Copyright (C) 2004 - 2008 Engineering Ingegneria Informatica S.p.A.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.

* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*
**/
package it.eng.qbe.statement.jpa;

import it.eng.spagobi.utilities.objects.Couple;
import it.eng.qbe.model.structure.IModelEntity;
import it.eng.qbe.model.structure.IModelField;
import it.eng.qbe.model.structure.ModelViewEntity;
import it.eng.qbe.model.structure.ModelViewEntity.ViewRelationship;
import it.eng.qbe.query.DataMartSelectField;
import it.eng.qbe.query.HavingField;
import it.eng.qbe.query.Operand;
import it.eng.qbe.query.Query;
import it.eng.qbe.query.WhereField;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* @authors Alberto Ghedin (alberto.ghedin@eng.it)
*
*/
public class JPQLBusinessViewUtility {

  private JPQLStatement statement;
 
  public JPQLBusinessViewUtility(JPQLStatement statement){
    this.statement = statement;
  }
 
  /**
   * Build the string with the join conditions between the views
   * and the entity in relation with the view
   * @param entityAliasesMaps
   * @param query the query
   * @param queryWhereClause the where clause of the query (used for add the strin WHERE or AND at
   * the beginning of the clause)
   * @return
   */
  public String buildViewsRelations(Map entityAliasesMaps, Query query, String queryWhereClause) {
    IModelField datamartField;
    Set<ViewRalationClause> viewRelations = new HashSet<ViewRalationClause>();
    StringBuffer whereClause = new StringBuffer("");
    Set<IModelEntity> concernedEntities = new HashSet<IModelEntity>();
    String clauseToReturn;
   
    //get all the fields
   
    //Get the select fields
    List<DataMartSelectField> selectFields = query.getSelectFields(false);
    if(selectFields!=null){
      for(int i=0; i<selectFields.size(); i++){
        datamartField = statement.getDataSource().getModelStructure().getField(selectFields.get(i).getUniqueName());
        concernedEntities.add(datamartField.getPathParent());
      }
    }

   
    //Get the where fields
    List<WhereField> whereFields = query.getWhereFields();
    if(whereFields!=null){
      for(int i=0; i<whereFields.size(); i++){
        WhereField whereField = whereFields.get(i);
        Operand leftOperand = whereField.getLeftOperand();
        if(statement.OPERAND_TYPE_FIELD.equalsIgnoreCase(leftOperand.type)){
          datamartField = statement.getDataSource().getModelStructure().getField( leftOperand.values[0] );
          concernedEntities.add(datamartField.getPathParent());
        }
        Operand rightOperand = whereField.getLeftOperand();
        if(statement.OPERAND_TYPE_FIELD.equalsIgnoreCase(rightOperand.type)){
          datamartField = statement.getDataSource().getModelStructure().getField( rightOperand.values[0] );
          concernedEntities.add(datamartField.getPathParent());
        }
      }
    }

   
    //Get the having fields
    List<HavingField> havingFields = query.getHavingFields();
    if(havingFields!=null){
      for(int i=0; i<havingFields.size(); i++){
        HavingField havingField = havingFields.get(i);
        Operand leftOperand = havingField.getLeftOperand();
        if(statement.OPERAND_TYPE_FIELD.equalsIgnoreCase(leftOperand.type)){
          datamartField = statement.getDataSource().getModelStructure().getField( leftOperand.values[0] );
          concernedEntities.add(datamartField.getPathParent());
        }
        Operand rightOperand = havingField.getLeftOperand();
        if(statement.OPERAND_TYPE_FIELD.equalsIgnoreCase(rightOperand.type)){
          datamartField = statement.getDataSource().getModelStructure().getField( rightOperand.values[0] );
          concernedEntities.add(datamartField.getPathParent());
        }
      }
    }

   
    //Get the order by fields
    List<DataMartSelectField> orderFields = query.getOrderByFields();
    if(orderFields!=null){
      for(int i=0; i<orderFields.size(); i++){
        datamartField = statement.getDataSource().getModelStructure().getField(orderFields.get(i).getUniqueName());
        concernedEntities.add(datamartField.getPathParent());
      }
    }

   
    //Get the group by fields
    List<DataMartSelectField> groupFields = query.getGroupByFields();
    if(groupFields!=null){
      for(int i=0; i<groupFields.size(); i++){
        datamartField = statement.getDataSource().getModelStructure().getField(groupFields.get(i).getUniqueName());
        concernedEntities.add(datamartField.getPathParent());
      }
    }

   
    Iterator<IModelEntity> concernedEntitiesIter = concernedEntities.iterator();
    while (concernedEntitiesIter.hasNext()) {
      buildViewsRelationsBackVistitPath((IModelEntity) concernedEntitiesIter.next(), null, viewRelations, entityAliasesMaps, query);     
    }
       
    Iterator<ViewRalationClause> iter = viewRelations.iterator();
    while (iter.hasNext()) {
      ViewRalationClause viewRalationClause = (ViewRalationClause) iter.next();
      whereClause.append(viewRalationClause.toString());
      if(iter.hasNext()){
        whereClause.append(" and ");
      }
    }
   
    clauseToReturn =whereClause.toString();
    if(clauseToReturn!=null && clauseToReturn.length()>1){
      if(queryWhereClause!=null && queryWhereClause.length()<4){
        clauseToReturn = " WHERE "+clauseToReturn;
      }else{
        clauseToReturn = " and "+clauseToReturn;
      }
    }
     
   
    return clauseToReturn;
  }
 
  /**
   * Visit backward the branch from the field to the root..
   * When it finds a view it add the join condition between the entity in the path
   *  in relation with the view 
   * @param entity
   * @param child
   * @param viewRelations the set of the join condition
   * @param entityAliases
   * @param query
   */
  private void buildViewsRelationsBackVistitPath(IModelEntity entity, IModelEntity child,  Set<ViewRalationClause> viewRelations,  Map entityAliases, Query query){
   
    if(entity==null){
      return;
    } else if(entity instanceof ModelViewEntity){
      addRelationForTheView(entity.getPathParent(), (ModelViewEntity)entity, child,viewRelations, entityAliases, query);
    }
    buildViewsRelationsBackVistitPath(entity.getPathParent(), entity, viewRelations, entityAliases, query);
   
  }
 
  /**
   * Takes the relation parent-->view and view-->child and builds
   * the join condition
   * @param parent the parent of the view
   * @param view the view
   * @param child the child entity of the view
   * @param viewRelations the set of the join condition
   * @param entityAliases
   * @param query the query
   */
  private void addRelationForTheView(IModelEntity parent, ModelViewEntity view, IModelEntity child, Set<ViewRalationClause> viewRelations, Map entityAliases, Query query){
    List<ViewRelationship> relations = view.getRelationships();
    IModelEntity inEntity,outEntity;
    ViewRelationship relation;
    for(int i=0; i<relations.size(); i++){
      relation = relations.get(i);
      outEntity = relation.getSourceEntity();
      inEntity = relation.getDestinationEntity();
      if( (view.getInnerEntities().contains(inEntity) && parent!=null && outEntity.getType().equals(parent.getType())) || //income relation
        (view.getInnerEntities().contains(outEntity) && child!=null && inEntity.getType().equals(child.getType()))){    //outcome relation
        //build the relation constraints
        viewRelations.addAll(buildRelationConditionString(relation.getSourceFileds(), relation.getDestinationFileds(), entityAliases, query));
      }
    }
  }
 
  /**
   * Takes the fields of the relation source and destination entity
   * and builds the join condition
   * @param sourceFields the list of the source entity in the relation
   * @param destFields the list of the destination entity in the relation
   * @param entityAliases
   * @param query
   * @return
   */
  private Set<ViewRalationClause> buildRelationConditionString(List<IModelField> sourceFields, List<IModelField> destFields, Map entityAliases, Query query){
    Set<ViewRalationClause> clauses = new HashSet<ViewRalationClause>();
    IModelField sourceField, destField;
    for(int i=0; i<sourceFields.size(); i++){
      sourceField = sourceFields.get(i);
      destField = destFields.get(i);
      clauses.add(new ViewRalationClause(getFieldString(sourceField, entityAliases,query),getFieldString(destField, entityAliases,query)));
    }
    return clauses;
   
  }
 
  /**
   * Builds the JPQL string of a field for the join condition..
   * @param datamartField the field
   * @param entityAliasesMaps
   * @param query
   * @return
   */
  private String getFieldString(IModelField datamartField, Map entityAliasesMaps, Query query){
    String queryName;
   
    IModelEntity rootEntity;
   
    Couple queryNameAndRoot = datamartField.getQueryName();
   
    queryName = (String) queryNameAndRoot.getFirst();
   
    if(queryNameAndRoot.getSecond()!=null){
      rootEntity = (IModelEntity)queryNameAndRoot.getSecond();  
    }else{
      rootEntity = datamartField.getParent().getRoot();  
    }
   
   
//    if(datamartField.getPathParent() instanceof ModelViewEntity){
//      rootEntity = (datamartField.getParent()).getRoot();
//    }else{
//      rootEntity = datamartField.getParent().getRoot();
//    }
 
    Map entityAliases = (Map)entityAliasesMaps.get(query.getId());
    String rootEntityAlias = (String)entityAliases.get(rootEntity.getUniqueName());
       
    if(rootEntityAlias == null) {
      rootEntityAlias = statement.getNextAlias(entityAliasesMaps);
      entityAliases.put(rootEntity.getUniqueName(), rootEntityAlias);
    }
       
    return rootEntityAlias + "." + queryName.substring(0,1).toLowerCase()+queryName.substring(1);
  }
 
  /**
   *
   * @authors Alberto Ghedin (alberto.ghedin@eng.it)
   *
   * A simple class that stay for a couple of
   * non ordered strings..
   * Note: (ViewRalationClause(a,b)).equals(ViewRalationClause(b,a)) = true..
   *
   */
  private class ViewRalationClause{
    private String field1;
    private String field2;
   
    public ViewRalationClause(String field1, String field2){
      this.field1 = field1;
      this.field2 = field2;
    }
   
    public String toString(){
      return "(" +this.field1 +" = "+ this.field2+ ")";
    }

    @Override
    public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result
          + ((field1 == null) ? 0 : field1.hashCode());
      result = prime * result
          + ((field2 == null) ? 0 : field2.hashCode());
      return result;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj)
        return true;
      if (obj == null)
        return false;
      if (getClass() != obj.getClass())
        return false;
      ViewRalationClause other = (ViewRalationClause) obj;
      if (field1 == null) {
        if (other.field1 != null)
          return false;
      }
      if (field2 == null) {
        if (other.field2 != null)
          return false;
      }
      if ((field1.equals(other.field2)) || (field2.equals(other.field1)) ){
        if(!(field1.equals(other.field2)) || !(field2.equals(other.field1))){
          return false;
        }
      }
      if ((field1.equals(other.field1)) && !(field2.equals(other.field2)) ){
        return false;
     
      if ((field2.equals(other.field2)) && !(field1.equals(other.field1)) ){
        return false;
      }
      return true;
    }
  }
 
}
TOP

Related Classes of it.eng.qbe.statement.jpa.JPQLBusinessViewUtility

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.