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

com.impetus.client.rdbms.query.RDBMSEntityReader Maven / Gradle / Ivy

There is a newer version: 2.9
Show newest version
/*******************************************************************************
 * * Copyright 2012 Impetus Infotech.
 *  *
 *  * Licensed 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 com.impetus.client.rdbms.query;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;

import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PersistenceException;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.EmbeddableType;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.Metamodel;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.impetus.client.rdbms.HibernateClient;
import com.impetus.kundera.client.Client;
import com.impetus.kundera.client.EnhanceEntity;
import com.impetus.kundera.metadata.MetadataUtils;
import com.impetus.kundera.metadata.model.ApplicationMetadata;
import com.impetus.kundera.metadata.model.EntityMetadata;
import com.impetus.kundera.metadata.model.KunderaMetadata;
import com.impetus.kundera.metadata.model.MetamodelImpl;
import com.impetus.kundera.metadata.model.Relation;
import com.impetus.kundera.metadata.model.attributes.AbstractAttribute;
import com.impetus.kundera.persistence.AbstractEntityReader;
import com.impetus.kundera.persistence.EntityReader;
import com.impetus.kundera.persistence.EntityReaderException;
import com.impetus.kundera.query.KunderaQuery.FilterClause;
import com.impetus.kundera.query.QueryHandlerException;

/**
 * The Class RDBMSEntityReader.
 * 
 * @author vivek.mishra
 */
public class RDBMSEntityReader extends AbstractEntityReader implements EntityReader
{

    /** the log used by this class. */
    private static Log log = LogFactory.getLog(RDBMSEntityReader.class);

    /** The conditions. */
    private Queue conditions;

    /** The filter. */
    private String filter;

    /** The jpa query. */
    private String jpaQuery;

    /**
     * Instantiates a new rDBMS entity reader.
     * 
     * @param luceneQuery
     *            the lucene query
     * @param query
     *            the query
     */
    public RDBMSEntityReader(String luceneQuery, String query)
    {
        this.luceneQueryFromJPAQuery = luceneQuery;
        this.jpaQuery = query;
    }

    /**
     * Instantiates a new rDBMS entity reader.
     */
    public RDBMSEntityReader()
    {

    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.impetus.kundera.persistence.EntityReader#populateRelation(com.impetus
     * .kundera.metadata.model.EntityMetadata, java.util.List, boolean,
     * com.impetus.kundera.client.Client)
     */
    @Override
    public List populateRelation(EntityMetadata m, Client client)
    {
        List ls = null;
        List relationNames = m.getRelationNames();
        boolean isParent = m.isParent();
        if (!isParent)
        {
            // if it is not a parent.
            String sqlQuery = null;
            if (MetadataUtils.useSecondryIndex(client.getPersistenceUnit()))
            {
                sqlQuery = getSqlQueryFromJPA(m, relationNames, null);
            }
            else
            {
                // prepare lucene query and find.
                Set rSet = fetchDataFromLucene(client);
                if (rSet != null && !rSet.isEmpty())
                {
                    filter = "WHERE";
                }
                sqlQuery = getSqlQueryFromJPA(m, relationNames, rSet);
            }
            // call client with relation name list and convert to sql query.

            ls = populateEnhanceEntities(m, relationNames, client, sqlQuery);

        }
        else
        {
            if (MetadataUtils.useSecondryIndex(client.getPersistenceUnit()))
            {
                try
                {
                    List entities = ((HibernateClient) client).find(getSqlQueryFromJPA(m, relationNames, null),
                            new ArrayList(), m);
                    ls = new ArrayList(entities.size());
                    ls = transform(m, ls, entities);
                }
                catch (Exception e)
                {
                    log.error("Error while executing handleAssociation for cassandra:" + e.getMessage());
                    throw new QueryHandlerException(e);
                }
            }
            else
            {
                ls = onAssociationUsingLucene(m, client, ls);
            }

        }

        return ls;
    }

    /**
     * Populate enhance entities.
     * 
     * @param m
     *            the m
     * @param relationNames
     *            the relation names
     * @param client
     *            the client
     * @param sqlQuery
     *            the sql query
     * @return the list
     */
    private List populateEnhanceEntities(EntityMetadata m, List relationNames, Client client,
            String sqlQuery)
    {
        List ls = null;
        List result = ((HibernateClient) client).find(sqlQuery, relationNames, m);

        try
        {
            if (!result.isEmpty())
            {
                ls = new ArrayList(result.size());
                for (Object o : result)
                {
                    Class clazz = m.getEntityClazz();
                    Object entity = clazz.newInstance();
                    boolean noRelationFound = true;
                    if (!o.getClass().isAssignableFrom(clazz))
                    {
                        entity = ((Object[]) o)[0];
                        noRelationFound = false;
                    }
                    else
                    {
                        entity = o;
                    }
                    EnhanceEntity e = new EnhanceEntity(entity, getId(entity, m), noRelationFound ? null
                            : populateRelations(relationNames, (Object[]) o));
                    ls.add(e);
                }
            }
        }
        catch (InstantiationException e)
        {
            log.error("Error during populating entities:" + e.getMessage());
            throw new EntityReaderException(e);
        }
        catch (IllegalAccessException e)
        {
            log.error("Error during populating entities:" + e.getMessage());
            throw new EntityReaderException(e);
        }
        return ls;

    }

    /**
     * Gets the sql query from jpa.
     * 
     * @param entityMetadata
     *            the entity metadata
     * @param relations
     *            the relations
     * @param primaryKeys
     *            the primary keys
     * @return the sql query from jpa
     */
    public String getSqlQueryFromJPA(EntityMetadata entityMetadata, List relations, Set primaryKeys)
    {
        ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata();
        Metamodel metaModel = appMetadata.getMetamodel(entityMetadata.getPersistenceUnit());
        if (appMetadata.isNative(jpaQuery))
        {
            return appMetadata.getQuery(jpaQuery);
        }

        String aliasName = "_" + entityMetadata.getTableName();

        StringBuilder queryBuilder = new StringBuilder("Select ");

        queryBuilder.append(aliasName);
        queryBuilder.append(".");
        queryBuilder.append(((AbstractAttribute) entityMetadata.getIdAttribute()).getJPAColumnName());

        EntityType entityType = metaModel.entity(entityMetadata.getEntityClazz());
        Set attributes = entityType.getAttributes();
        for (Attribute field : attributes)
        //
        // for (String column : entityMetadata.getColumnFieldNames())
        {
            if (!field.isAssociation()
                    && !field.isCollection()
                    && !((Field) field.getJavaMember()).isAnnotationPresent(ManyToMany.class)
                    && !((AbstractAttribute) field).getJPAColumnName().equals(
                            ((AbstractAttribute) entityMetadata.getIdAttribute()).getJPAColumnName())
                    && !((MetamodelImpl) metaModel).isEmbeddable(((AbstractAttribute) field).getBindableJavaType()))
            {
                queryBuilder.append(", ");
                queryBuilder.append(aliasName);
                queryBuilder.append(".");
                queryBuilder.append(((AbstractAttribute) field).getJPAColumnName());
            }
        }

        // Handle embedded columns, add them to list.
        // List embeddedColumns =
        // entityMetadata.getEmbeddedColumnsAsList();
        Map embeddedColumns = ((MetamodelImpl) metaModel).getEmbeddables(entityMetadata
                .getEntityClazz());
        for (EmbeddableType embeddedCol : embeddedColumns.values())
        {
            Set embeddedAttributes = embeddedCol.getAttributes();
            // for (Column column : embeddedCol.getColumns())
            for (Attribute column : embeddedAttributes)
            {
                queryBuilder.append(", ");
                queryBuilder.append(aliasName);
                queryBuilder.append(".");
                queryBuilder.append(((AbstractAttribute) column).getJPAColumnName());
            }
        }

        if (relations != null)
        {
            for (String relation : relations)
            {

                Relation rel = entityMetadata.getRelation(entityMetadata.getFieldName(relation));
                String r = MetadataUtils.getMappedName(entityMetadata, rel);
                if (!((AbstractAttribute) entityMetadata.getIdAttribute()).getJPAColumnName().equalsIgnoreCase(
                        r != null ? r : relation)
                        && rel != null
                        && !rel.getProperty().isAnnotationPresent(ManyToMany.class)
                        && !rel.getProperty().isAnnotationPresent(OneToMany.class)
                        && (rel.getProperty().isAnnotationPresent(OneToOne.class)
                                && StringUtils.isBlank(rel.getMappedBy()) || rel.getProperty().isAnnotationPresent(
                                ManyToOne.class)))
                {
                    queryBuilder.append(", ");
                    queryBuilder.append(aliasName);
                    queryBuilder.append(".");
                    queryBuilder.append(r != null ? r : relation);
                }
            }
        }
        for (Relation r : entityMetadata.getRelations())
        {
            if (r.getJoinColumnName() != null)
            {
                queryBuilder.append(", ");
                queryBuilder.append(aliasName);
                queryBuilder.append(".");
                queryBuilder.append(r.getJoinColumnName());
            }
        }

        queryBuilder.append(" From ");
        if (entityMetadata.getSchema() != null && !entityMetadata.getSchema().isEmpty())
        {
            queryBuilder.append(entityMetadata.getSchema() + ".");
        }
        queryBuilder.append(entityMetadata.getTableName());
        queryBuilder.append(" ");
        queryBuilder.append(aliasName);
        // add conditions
        if (filter != null)
        {
            queryBuilder.append(" Where ");
            // queryBuilder.append(filter);
        }

        if (primaryKeys == null)
        {
            for (Object o : conditions)
            {

                if (o instanceof FilterClause)
                {
                    FilterClause clause = ((FilterClause) o);
                    // String fieldName = getColumnName(clause.getProperty());
                    String fieldName = clause.getProperty();
                    boolean isString = isStringProperty(entityType, fieldName, entityMetadata);

                    // queryBuilder.append(StringUtils.replace(clause.getProperty(),
                    // clause.getProperty().substring(0,
                    // clause.getProperty().indexOf(".")), aliasName));
                    queryBuilder.append(StringUtils.replace(clause.getProperty(), aliasName, aliasName));
                    queryBuilder.append(" ");
                    queryBuilder.append(clause.getCondition());

                    if (clause.getCondition().equalsIgnoreCase("like"))
                    {
                        queryBuilder.append("%");
                    }
                    queryBuilder.append(" ");
                    appendStringPrefix(queryBuilder, isString);
                    queryBuilder.append(clause.getValue());
                    appendStringPrefix(queryBuilder, isString);
                }
                else
                {
                    queryBuilder.append(" ");
                    queryBuilder.append(o);
                    queryBuilder.append(" ");
                }

            }
        }
        else
        {

            queryBuilder.append(aliasName);
            queryBuilder.append(".");
            queryBuilder.append(((AbstractAttribute) entityMetadata.getIdAttribute()).getJPAColumnName());
            queryBuilder.append(" ");
            queryBuilder.append("IN(");
            int count = 0;
            Attribute col = entityMetadata.getIdAttribute();
            boolean isString = col.getJavaType().isAssignableFrom(String.class);
            for (String key : primaryKeys)
            {
                appendStringPrefix(queryBuilder, isString);
                queryBuilder.append(key);
                appendStringPrefix(queryBuilder, isString);
                if (++count != primaryKeys.size())
                {
                    queryBuilder.append(",");
                }
                else
                {
                    queryBuilder.append(")");
                }
            }

        }
        return queryBuilder.toString();
    }

    /**
     * Append string prefix.
     * 
     * @param queryBuilder
     *            the query builder
     * @param isString
     *            the is string
     */
    private void appendStringPrefix(StringBuilder queryBuilder, boolean isString)
    {
        if (isString)
        {
            queryBuilder.append("'");
        }
    }

    /**
     * Sets the conditions.
     * 
     * @param q
     *            the new conditions
     */
    public void setConditions(Queue q)
    {
        this.conditions = q;
    }

    /**
     * Sets the filter.
     * 
     * @param filter
     *            the new filter
     */
    public void setFilter(String filter)
    {
        this.filter = filter;
    }

    /**
     * Populate relations.
     * 
     * @param relations
     *            the relations
     * @param o
     *            the o
     * @return the map
     */
    private Map populateRelations(List relations, Object[] o)
    {
        Map relationVal = new HashMap(relations.size());
        int counter = 1;
        for (String r : relations)
        {
            relationVal.put(r, o[counter++]);
        }
        return relationVal;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.impetus.kundera.persistence.EntityReader#findById(java.lang.Object,
     * com.impetus.kundera.metadata.model.EntityMetadata, java.util.List,
     * com.impetus.kundera.client.Client)
     */
    @Override
    public EnhanceEntity findById(Object primaryKey, EntityMetadata m, Client client)
    {
        List relationNames = m.getRelationNames();
        if (relationNames != null && !relationNames.isEmpty())
        {
            Set keys = new HashSet(1);
            keys.add(primaryKey.toString());
            String query = getSqlQueryFromJPA(m, relationNames, keys);
            List results = populateEnhanceEntities(m, relationNames, client, query);
            return results != null && !results.isEmpty() ? results.get(0) : null;
        }
        else
        {
            Object o;
            try
            {
                o = client.find(m.getEntityClazz(), primaryKey);
            }
            catch (Exception e)
            {
                throw new PersistenceException(e);
            }
            return o != null ? new EnhanceEntity(o, getId(o, m), null) : null;
        }
    }

    /**
     * Checks if is string property.
     * 
     * @param m
     *            the m
     * @param fieldName
     *            the field name
     * @return true, if is string property
     */
    private boolean isStringProperty(EntityType entityType, String jpaColumnName, EntityMetadata m)
    {
        if (((AbstractAttribute) m.getIdAttribute()).getJPAColumnName().equals(jpaColumnName))
        {
            return ((AbstractAttribute) m.getIdAttribute()).getBindableJavaType().isAssignableFrom(String.class);
        }
        String fieldName = m.getFieldName(jpaColumnName);
        Attribute col = entityType.getAttribute(fieldName);
        // Column col = m.getColumn(fieldName);

        Field f = (Field) col.getJavaMember();
        return f != null ? ((AbstractAttribute) col).getBindableJavaType().isAssignableFrom(String.class) : false;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy