/*
(non-Javadoc)

@see
com.impetus.client.cassandra.query.ResultIterator#populateEntities(com
.impetus.kundera.metadata.model.EntityMetadata,
com.impetus.kundera.client.Client)
180782
@Override
    protected List<E> populateEntities(EntityMetadata m, Client client) throws Exception
    {
        int count = 0;
        List results = new ArrayList();
        MetamodelImpl metaModel = (MetamodelImpl) kunderaMetadata.getApplicationMetadata().getMetamodel(
                m.getPersistenceUnit());
        EntityType entityType = metaModel.entity(entityMetadata.getEntityClazz());
        Map<String, Object> relationalValues = new HashMap<String, Object>();
        if (rSet == null)
        {
            String parsedQuery = query.onQueryOverCQL3(m, client, metaModel, null);
            Statement statement = new SimpleStatement(parsedQuery);
            statement.setFetchSize(fetchSize);
            rSet = ((DSClient) client).executeStatement(statement);
            rowIter = rSet.iterator();
        }
        while (rowIter.hasNext() && count++ < fetchSize)
        {
            Object entity = null;
            Row row = rowIter.next();
            ((DSClient) client).populateObjectFromRow(entityMetadata, metaModel, entityType, results, relationalValues,
                    entity, row);
        }
        return results;
    }
307336
private void populateRelations(EntityMetadata m, Object entity, Map<String, Object> relationMap, Node node,
            Map<Long, Object> nodeIdToEntityMap)
    {
        // Populate all relationship entities that are in Neo4J
        for (Relation relation : m.getRelations())
        {
            if (relation != null)
            {
                Class<?> targetEntityClass = relation.getTargetEntity();
                EntityMetadata targetEntityMetadata = KunderaMetadataManager.getEntityMetadata(kunderaMetadata,
                        targetEntityClass);
                Field property = relation.getProperty();
                if (relation.getPropertyType().isAssignableFrom(Map.class))
                {
                    Map<Object, Object> targetEntitiesMap = new HashMap<Object, Object>();

                    // If relationship entity is stored into Neo4J, fetch it
                    // immediately
                    if (isEntityForNeo4J(targetEntityMetadata))
                    {

                        for (Relationship relationship : node.getRelationships(Direction.OUTGOING,
                                DynamicRelationshipType.withName(relation.getJoinColumnName(kunderaMetadata))))
                        {
                            if (relationship == null)
                            {
                                continue;
                            }

                            // Target Entity
                            Node endNode = relationship.getEndNode();
                            if (endNode == null)
                            {
                                continue;
                            }
                            Object targetEntity = nodeIdToEntityMap.get(endNode.getId());
                            if (targetEntity == null)
                            {
                                targetEntity = mapper.getEntityFromNode(endNode, targetEntityMetadata);
                            }

                            // Relationship Entity
                            Object relationshipEntity = mapper.getEntityFromRelationship(relationship, m, relation);

                            // If this relationship is bidirectional, put source
                            // entity into Map field for target entity
                            Field bidirectionalField = relation.getBiDirectionalField();
                            Map<Object, Object> sourceEntitiesMap = new HashMap<Object, Object>();
                            if (bidirectionalField != null)
                            {
                                for (Relationship incomingRelationship : endNode.getRelationships(Direction.INCOMING,
                                        DynamicRelationshipType.withName(relation.getJoinColumnName(kunderaMetadata))))
                                {
                                    Node startNode = incomingRelationship.getStartNode();
                                    Object sourceEntity = nodeIdToEntityMap.get(startNode.getId());
                                    if (sourceEntity == null)
                                    {
                                        sourceEntity = mapper.getEntityFromNode(startNode, m);
                                        nodeIdToEntityMap.put(startNode.getId(), sourceEntity);
                                    }
                                    sourceEntitiesMap.put(relationshipEntity, sourceEntity);
                                }
                                PropertyAccessorHelper.set(targetEntity, bidirectionalField, sourceEntitiesMap);
                            }

                            // Set references to Target and owning entity in
                            // relationship entity
                            Class<?> relationshipClass = relation.getMapKeyJoinClass();
                            for (Field f : relationshipClass.getDeclaredFields())
                            {
                                if (!ReflectUtils.isTransientOrStatic(f))
                                {

                                    if (f.getType().equals(m.getEntityClazz()))
                                    {
                                        PropertyAccessorHelper.set(relationshipEntity, f, entity);
                                    }
                                    else if (f.getType().equals(targetEntityClass))
                                    {
                                        PropertyAccessorHelper.set(relationshipEntity, f, targetEntity);
                                    }
                                }
                            }
                            targetEntitiesMap.put(relationshipEntity, targetEntity);
                        }

                        PropertyAccessorHelper.set(entity, property, targetEntitiesMap);
                    }

                    /**
                     * If relationship entity is stored in a database other than
                     * Neo4J foreign keys are stored in "Proxy Nodes", retrieve
                     * these foreign keys and set into EnhanceEntity
                     */
                    else
                    {

                        for (Relationship relationship : node.getRelationships(Direction.OUTGOING,
                                DynamicRelationshipType.withName(relation.getJoinColumnName(kunderaMetadata))))
                        {
                            Node proxyNode = relationship.getEndNode();

                            String targetEntityIdColumnName = ((AbstractAttribute) targetEntityMetadata
                                    .getIdAttribute()).getJPAColumnName();
                            Object targetObjectId = proxyNode.getProperty(targetEntityIdColumnName);
                            Object relationshipEntity = mapper.getEntityFromRelationship(relationship, m, relation);

                            targetEntitiesMap.put(targetObjectId, relationshipEntity);
                        }

                        relationMap.put(relation.getJoinColumnName(kunderaMetadata), targetEntitiesMap);
                    }
                }
            }
        }
    }
865458
private <X extends Class, T extends Object> void populateMetadata(EntityMetadata metadata, Class<X> clazz,
            Map puProperties)
    {
        // process for metamodelImpl

        if (metadata.getPersistenceUnit() != null)
        {
            MetaModelBuilder<X, T> metaModelBuilder = kunderaMetadata.getApplicationMetadata().getMetaModelBuilder(
                    metadata.getPersistenceUnit());

            onBuildMetaModelSuperClass(clazz.getSuperclass(), metaModelBuilder);

            metaModelBuilder.process(clazz);

            for (Field f : clazz.getDeclaredFields())
            {
                if (f != null && !Modifier.isStatic(f.getModifiers()) && !Modifier.isTransient(f.getModifiers())
                        && !f.isAnnotationPresent(Transient.class))
                {
                    // construct metamodel.
                    metaModelBuilder.construct(clazz, f);

                    // on id attribute.
                    onIdAttribute(metaModelBuilder, metadata, clazz, f);

                    // determine if it is a column family or super column
                    // family.
                    onFamilyType(metadata, clazz, f);
                }
            }

            EntityType entityType = (EntityType) metaModelBuilder.getManagedTypes().get(metadata.getEntityClazz());

            validateAndSetId(metadata, clazz, metaModelBuilder);
            validateandSetEntityType(metadata, clazz, metaModelBuilder);
            MetadataUtils.onJPAColumnMapping(entityType, metadata);

            /* Scan for Relationship field */
            populateRelationMetaData(entityType, clazz, metadata);
        }
    }
255523
public void populateEntity(Object entity, RowResult result, EntityType entityType, MetamodelImpl metaModel)
    {
        Set<Attribute> attributes = entityType.getAttributes();
        Iterator<Attribute> iterator = attributes.iterator();
        iterateAndPopulateEntity(entity, result, metaModel, iterator);
    }
149349
protected List fetch()
    {
        EntityMetadata metadata = getEntityMetadata();
        Client client = persistenceDelegeator.getClient(metadata);
        List results = isRelational(metadata) ? recursivelyPopulateEntities(metadata, client) : populateEntities(
                metadata, client);
        return results;
    }
642703
private void populateCollectionFromJoinTable(Object entity, EntityMetadata entityMetadata,
            PersistenceDelegator delegator, Relation relation)
    {
        JoinTableMetadata jtMetadata = relation.getJoinTableMetadata();
        Client pClient = delegator.getClient(entityMetadata);

        String schema = entityMetadata.getSchema();

        EntityMetadata owningEntityMetadata = KunderaMetadataManager.getEntityMetadata(delegator.getKunderaMetadata(),
                relation.getTargetEntity());
        Class columnJavaType = owningEntityMetadata.getIdAttribute().getJavaType();
        if (jtMetadata == null)
        {
            columnJavaType = entityMetadata.getIdAttribute().getJavaType();
            Relation owningEntityMetadataRelation = owningEntityMetadata.getRelation(relation.getMappedBy());
            jtMetadata = owningEntityMetadataRelation.getJoinTableMetadata();
            pClient = delegator.getClient(owningEntityMetadata);
            schema = owningEntityMetadata.getSchema();
        }

        String joinTableName = jtMetadata.getJoinTableName();

        Set<String> joinColumns = jtMetadata.getJoinColumns();
        Set<String> inverseJoinColumns = jtMetadata.getInverseJoinColumns();

        String joinColumnName = (String) joinColumns.toArray()[0];
        String inverseJoinColumnName = (String) inverseJoinColumns.toArray()[0];

        Object entityId = PropertyAccessorHelper.getId(entity, entityMetadata);
        List<?> foreignKeys = pClient.getColumnsById(schema, joinTableName, joinColumnName, inverseJoinColumnName,
                entityId, columnJavaType);

        List childrenEntities = new ArrayList();

        if (foreignKeys != null)
        {
            for (Object foreignKey : foreignKeys)
            {
                EntityMetadata childMetadata = KunderaMetadataManager.getEntityMetadata(delegator.getKunderaMetadata(),
                        relation.getTargetEntity());

                Object child = delegator.find(relation.getTargetEntity(), foreignKey);
                Object obj = child instanceof EnhanceEntity && child != null ? ((EnhanceEntity) child).getEntity()
                        : child;

                // If child has any bidirectional relationship, process them
                // here
                Field biDirectionalField = relation.getBiDirectionalField();
                boolean isBidirectionalRelation = (biDirectionalField != null);

                if (isBidirectionalRelation && obj != null)
                {
                    Object columnValue = PropertyAccessorHelper.getId(obj, childMetadata);
                    Object[] pKeys = pClient.findIdsByColumn(entityMetadata.getSchema(), joinTableName, joinColumnName,
                            inverseJoinColumnName, columnValue, entityMetadata.getEntityClazz());
                    List parents = delegator.find(entity.getClass(), pKeys);
                    PropertyAccessorHelper.set(obj, biDirectionalField,
                            ObjectUtils.getFieldInstance(parents, biDirectionalField));
                    PersistenceCacheManager.addEntityToPersistenceCache(obj, delegator, columnValue);
                }

                childrenEntities.add(obj);
            }
        }
        Field childField = relation.getProperty();

        try
        {
            PropertyAccessorHelper.set(
                    entity,
                    childField,
                    PropertyAccessorHelper.isCollection(childField.getType()) ? ObjectUtils.getFieldInstance(
                            childrenEntities, childField) : childrenEntities.get(0));
            PersistenceCacheManager.addEntityToPersistenceCache(entity, delegator, entityId);
        }
        catch (PropertyAccessException ex)
        {
            throw new EntityReaderException(ex);
        }
    }
812433
private void populateGroupByResponse(Map<String, Object> aggregations, Iterable<Expression> resultOrderIterable,
            List<Object> results, Client client, EntityMetadata m)
    {
        List temp;
        Object entity = null;
        for (String entry : aggregations.keySet())
        {
            entity = null;
            Object obj = aggregations.get(entry);
            temp = new ArrayList<>();
            Iterator<Expression> resultOrder = resultOrderIterable.iterator();
            while (resultOrder.hasNext())
            {
                Expression expression = (Expression) resultOrder.next();

                if (AggregateFunction.class.isAssignableFrom(expression.getClass()))
                {
                    if (((Map) obj).get(expression.toParsedText()) != null)
                    {
                        temp.add(((Map) obj).get(expression.toParsedText()));
                    }
                }
                else
                {
                    if (entity == null)
                    {
                        entity = findUsingLucene(m, client, new Object[] { entry }).get(0);
                    }
                    temp.add(getEntityFieldValue(m, entity, expression.toParsedText()));
                }
            }
            results.add(temp.size() == 1 ? temp.get(0) : temp);
        }
    }
651575
private List populateData(EntityMetadata m, Map<Bytes, List<Column>> qResults, List<Object> entities,
            boolean isRelational, List<String> relationNames, CassandraDataHandler dataHandler)
    {
        if (m.getType().isSuperColumnFamilyMetadata())
        {
            Set<Bytes> primaryKeys = qResults.keySet();

            if (primaryKeys != null && !primaryKeys.isEmpty())
            {
                Object[] rowIds = new Object[primaryKeys.size()];
                int i = 0;
                for (Bytes b : primaryKeys)
                {
                    rowIds[i] = PropertyAccessorHelper.getObject(b, (Field) m.getIdAttribute().getJavaMember());
                    i++;
                }
                entities.addAll(findAll(m.getEntityClazz(), null, rowIds));
            }

        }
        else
        {
            Iterator<Bytes> rowIter = qResults.keySet().iterator();
            while (rowIter.hasNext())
            {
                Bytes rowKey = rowIter.next();
                List<Column> columns = qResults.get(rowKey);
                try
                {
                    Object id = PropertyAccessorHelper
                            .getObject(m.getIdAttribute().getJavaType(), rowKey.toByteArray());
                    Object e = null;
                    e = dataHandler.populateEntity(new ThriftRow(id, m.getTableName(), columns,
                            new ArrayList<SuperColumn>(0), new ArrayList<CounterColumn>(0),
                            new ArrayList<CounterSuperColumn>(0)), m, KunderaCoreUtils.getEntity(e), relationNames,
                            isRelational);
                    if (e != null)
                    {
                        entities.add(e);
                    }
                }
                catch (IllegalStateException e)
                {
                    log.error("Error while returning entities for {}, Caused by: .", m.getEntityClazz(), e);
                    throw new KunderaException(e);
                }
                catch (Exception e)
                {
                    log.error("Error while returning entities for {}, Caused by: .", m.getEntityClazz(), e);
                    throw new KunderaException(e);
                }
            }
        }
        return entities;
    }
101878
@Override
    public Set<EntityType<?>> getEntities()
    {
        Set<EntityType<?>> entities = null;
        if (entityTypes != null)
        {
            entities = new HashSet<EntityType<?>>(entityTypes.values());
        }
        return entities;
    }
141929
private void populateGFSEntity(EntityMetadata entityMetadata, List entities, GridFSDBFile gfsDBFile)
    {
        Object entity = instantiateEntity(entityMetadata.getEntityClazz(), null);
        handler.getEntityFromGFSDBFile(entityMetadata.getEntityClazz(), entity, entityMetadata, gfsDBFile,
                kunderaMetadata);
        entities.add(entity);
    }
1205861
@Override
    protected List<Object> populateEntities(EntityMetadata m, Client client)
    {
        MetamodelImpl metaModel = (MetamodelImpl) kunderaMetadata.getApplicationMetadata().getMetamodel(
                m.getPersistenceUnit());
        EntityType entity = metaModel.entity(m.getEntityClazz());
        Expression whereExpression = KunderaQueryUtils.getWhereClause(kunderaQuery.getJpqlExpression());

        QueryBuilder filter = whereExpression == null || whereExpression instanceof NullExpression ? null
                : esFilterBuilder.populateFilterBuilder(((WhereClause) whereExpression).getConditionalExpression(), m);

        return ((ESClient) client).executeQuery(filter, buildAggregation(kunderaQuery, m, filter), m,
                getKunderaQuery(),this.firstResult, this.maxResult);
    }
1069887
@Override
    protected List<Object> recursivelyPopulateEntities(EntityMetadata m, Client client)
    {
        List result = populateEntities(m, client);
        return setRelationEntities(result, client, m);
    }
1215069
private void onCheckRelation()
    {
        try
        {
            results = populateEntities(entityMetadata, client);

            if (entityMetadata.isRelationViaJoinTable()
                    || (entityMetadata.getRelationNames() != null && !(entityMetadata.getRelationNames().isEmpty())))
            {
                query.setRelationalEntities(results, client, entityMetadata);
            }
        }
        catch (Exception e)
        {
            throw new PersistenceException("Error while scrolling over results, Caused by :.", e);
        }
    }
516927
private ResourceIterator<Node> multiPropertiesIdFindEntities(GraphDatabaseService executionEngine, EntityKey[] keys) {
		String query = getMultiGetQueryCacheQuery( keys );
		Map<String, Object> params = multiGetParams( keys );
		Result result = executionEngine.execute( query, params );
		return result.columnAs( ENTITY_ALIAS );
	}
1051807
@Override
    protected List<Object> recursivelyPopulateEntities(EntityMetadata m, Client client)
    {
        List<EnhanceEntity> ls = new ArrayList<EnhanceEntity>();
        RedisQueryInterpreter interpreter = onTranslation(getKunderaQuery().getFilterClauseQueue(), m);
        ls = ((RedisClient) client).onExecuteQuery(interpreter, m.getEntityClazz());
        return setRelationEntities(ls, client, m);
    }
395402
private List onQuery(EntityMetadata m, Client client)
    {
        boolean useLuceneOrES = !MetadataUtils.useSecondryIndex(((ClientBase) client).getClientMetadata());
        QueryTranslator translator = new QueryTranslator();
        List<Map<String, Object>> columnsToOutput = translator.getColumnsToOutput(m, getKunderaQuery(), useLuceneOrES);
        translator.translate(getKunderaQuery(), m, useLuceneOrES);
        Filter filters = translator.getFilters();
        if (!translator.isWhereOrAggregationQuery() || !useLuceneOrES)
        {
            return ((HBaseClient) client).findData(m, null, translator.getStartRow(), translator.getEndRow(),
                    columnsToOutput, filters);
        }
        else
        {
            return populateUsingLucene(m, client, null, null);
        }
    }
994853
private void populatePartialRow(PartialRow row, EntityMetadata entityMetadata, Object entity)
    {
        MetamodelImpl metaModel = (MetamodelImpl) kunderaMetadata.getApplicationMetadata()
                .getMetamodel(entityMetadata.getPersistenceUnit());
        Class entityClazz = entityMetadata.getEntityClazz();
        EntityType entityType = metaModel.entity(entityClazz);
        Set<Attribute> attributes = entityType.getAttributes();
        Iterator<Attribute> iterator = attributes.iterator();
        iterateAndPopulateRow(row, entity, metaModel, iterator);
    }