Package com.impetus.client.oraclenosql.index

Source Code of com.impetus.client.oraclenosql.index.OracleNoSQLInvertedIndexer

/**
* Copyright 2013 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.oraclenosql.index;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;

import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.EntityType;

import oracle.kv.Direction;
import oracle.kv.KVStore;
import oracle.kv.Key;
import oracle.kv.KeyRange;
import oracle.kv.KeyValueVersion;
import oracle.kv.Value;

import com.impetus.client.oraclenosql.OracleNOSQLConstants;
import com.impetus.client.oraclenosql.OracleNoSQLDataHandler;
import com.impetus.client.oraclenosql.query.OracleNoSQLQueryInterpreter;
import com.impetus.kundera.index.Indexer;
import com.impetus.kundera.metadata.model.EntityMetadata;
import com.impetus.kundera.metadata.model.MetamodelImpl;
import com.impetus.kundera.metadata.model.attributes.AbstractAttribute;
import com.impetus.kundera.property.PropertyAccessor;
import com.impetus.kundera.property.PropertyAccessorFactory;
import com.impetus.kundera.property.PropertyAccessorHelper;
import com.impetus.kundera.query.KunderaQuery.FilterClause;

/**
* Inverted Index implementation of {@link Indexer}
*
* @author amresh.singh
*/
public class OracleNoSQLInvertedIndexer implements Indexer
{

    private KVStore kvStore;

    private OracleNoSQLDataHandler handler;

    @Override
    public void index(Class entityClazz, EntityMetadata m, Map<String, Object> values, Object entityId, final Class parentClazz)
    {
        String idColumnName = ((AbstractAttribute) m.getIdAttribute()).getJPAColumnName();
        Object id = values.get(idColumnName);

        for (String column : values.keySet())
        {
            Object valueObject = values.get(column);

            List<String> majorKeyComponents = new ArrayList<String>();
            majorKeyComponents.add(getIndexTableName(m));
            majorKeyComponents.add(column);
            majorKeyComponents.add(PropertyAccessorHelper.getString(valueObject));

            String minorKey = PropertyAccessorHelper.getString(id);

            Key key = Key.createKey(majorKeyComponents, minorKey);
            byte[] valueByteArray = PropertyAccessorHelper.getBytes(id);

            kvStore.put(key, Value.createValue(valueByteArray));
        }
    }

    @Override
    public Map<String, Object> search(Class<?> clazz, EntityMetadata m, String luceneQuery, int start, int count)
    {
        throw new UnsupportedOperationException("This method is not supported for OracleNoSQL.");
    }

    @Override
    public Map<String, Object> search(String query, Class<?> parentClass,  EntityMetadata parentMetadata, Class<?> childClass, EntityMetadata childMetadata, Object entityId,
            int start, int count)
    {
        String secIndexName = getIndexTableName(childMetadata);
        String parentIdColumnName = ((AbstractAttribute) parentMetadata.getIdAttribute()).getJPAColumnName();
        String childIdColumnName = ((AbstractAttribute) childMetadata.getIdAttribute()).getJPAColumnName();
        String id = PropertyAccessorHelper.getString(entityId);

        List<String> majorComponents = new ArrayList<String>();
        majorComponents.add(secIndexName);
        majorComponents.add(parentIdColumnName);
        majorComponents.add(id);

        Key majorKeyToFind = Key.createKey(majorComponents);

        Iterator<KeyValueVersion> iterator = kvStore.multiGetIterator(Direction.FORWARD, 0, majorKeyToFind, null, null);

        Map<String, Object> results = new HashMap<String, Object>();

        while (iterator.hasNext())
        {
            KeyValueVersion keyValueVersion = iterator.next();
            String minorKey = keyValueVersion.getKey().getMinorPath().get(0);

            PropertyAccessor accessor = PropertyAccessorFactory.getPropertyAccessor(childMetadata.getIdAttribute()
                    .getBindableJavaType());

            byte[] idByteArr = keyValueVersion.getValue().getValue();
            Object keyObj = accessor.fromBytes(childMetadata.getIdAttribute().getBindableJavaType(), idByteArr);

            results.put(childIdColumnName + "|" + minorKey, keyObj);
        }

        return results;
    }

    public <E> Set<E> executeQuery(OracleNoSQLQueryInterpreter interpreter, Class<?> entityClass, EntityMetadata entityMetadata)
    {
        String idColumnName = ((AbstractAttribute) entityMetadata.getIdAttribute()).getJPAColumnName();
        String secIndexName = getIndexTableName(entityMetadata);

        Set<Object> results = new HashSet<Object>();
        Set<Object> foundKeys = new HashSet<Object>();
        String interClauseOperator = null;

        Queue filterClauseQueue = interpreter.getClauseQueue();

        for (Object clause : filterClauseQueue)
        {
            if (clause instanceof FilterClause)
            {
                foundKeys = new HashSet<Object>();

                String columnName = ((FilterClause) clause).getProperty();
                String condition = ((FilterClause) clause).getCondition();
                Object value = ((FilterClause) clause).getValue();

                if (columnName.equals(((AbstractAttribute) entityMetadata.getIdAttribute()).getJPAColumnName())
                        && condition.equals("="))
                {
                    Object idValue = PropertyAccessorHelper.fromSourceToTargetClass(entityMetadata.getIdAttribute()
                            .getJavaType(), String.class, value);
                    foundKeys.add(idValue);
                }
                else
                {
                    List<String> majorComponents = new ArrayList<String>();
                    majorComponents.add(secIndexName);
                    majorComponents.add(columnName);

                    KeyRange range = null;
                    Iterator<KeyValueVersion> iterator = null;

                    if (condition.equals("="))
                    {
                        majorComponents.add(PropertyAccessorHelper.getString(value));
                        Key majorKeyToFind = Key.createKey(majorComponents);
                        iterator = kvStore.multiGetIterator(Direction.FORWARD, 0, majorKeyToFind, range, null);
                    }
                    else if (condition.equals(">"))
                    {
                        range = new KeyRange(value.toString(), false, null, true);
                        Key majorKeyToFind = Key.createKey(majorComponents);
                        iterator = kvStore.storeIterator(Direction.UNORDERED, 0, majorKeyToFind, range, null);
                    }
                    else if (condition.equals("<"))
                    {
                        range = new KeyRange(null, true, value.toString(), false);
                        Key majorKeyToFind = Key.createKey(majorComponents);
                        iterator = kvStore.storeIterator(Direction.UNORDERED, 0, majorKeyToFind, range, null);
                    }
                    else if (condition.equals(">="))
                    {
                        range = new KeyRange(value.toString(), true, null, true);
                        Key majorKeyToFind = Key.createKey(majorComponents);
                        iterator = kvStore.storeIterator(Direction.UNORDERED, 0, majorKeyToFind, range, null);
                    }
                    else if (condition.equals("<="))
                    {
                        range = new KeyRange(null, true, value.toString(), true);
                        Key majorKeyToFind = Key.createKey(majorComponents);
                        iterator = kvStore.storeIterator(Direction.UNORDERED, 0, majorKeyToFind, range, null);
                    }

                    while (iterator.hasNext())
                    {
                        KeyValueVersion keyValueVersion = iterator.next();
                        String minorKey = keyValueVersion.getKey().getMinorPath().get(0);

                        PropertyAccessor accessor = PropertyAccessorFactory.getPropertyAccessor(entityMetadata
                                .getIdAttribute().getBindableJavaType());

                        byte[] idByteArr = keyValueVersion.getValue().getValue();
                        Object keyObj = accessor.fromBytes(entityMetadata.getIdAttribute().getBindableJavaType(),
                                idByteArr);

                        foundKeys.add(keyObj);
                    }

                }
            }
            else if (clause instanceof String)
            {
                interClauseOperator = clause.toString().trim();
            }

            addToResults(results, foundKeys, interClauseOperator);
        }

        return (Set<E>) results;

    }

    @Override
    public void unIndex(Class entityClazz, Object entity, EntityMetadata entityMetadata, MetamodelImpl metamodel)
    {
        String indexTableName = getIndexTableName(entityMetadata);

        // byte[] id = PropertyAccessorHelper.get(entity,
        // (Field)entityMetadata.getIdAttribute().getJavaMember());
        Object id = PropertyAccessorHelper.getId(entity, entityMetadata);
        EntityType entityType = metamodel.entity(entityMetadata.getEntityClazz());
        Set<Attribute> attributes = entityType.getSingularAttributes();

        for (Attribute attribute : attributes)
        {
            Class fieldJavaType = ((AbstractAttribute) attribute).getBindableJavaType();

            if (!attribute.isAssociation() && !metamodel.isEmbeddable(fieldJavaType))
            {
                String columnName = ((AbstractAttribute) attribute).getJPAColumnName();

                List<String> majorComponents = new ArrayList<String>();
                majorComponents.add(indexTableName);
                majorComponents.add(columnName);

                Key key = Key.createKey(majorComponents);
                Iterator<KeyValueVersion> iterator = kvStore.storeIterator(Direction.UNORDERED, 0, key, null, null);

                while (iterator.hasNext())
                {
                    KeyValueVersion keyValueVersion = iterator.next();
                    Key keytoDelete = keyValueVersion.getKey();
                    byte[] value = keyValueVersion.getValue().getValue();
                    Object valueObject = PropertyAccessorHelper.getObject(
                            ((AbstractAttribute) entityMetadata.getIdAttribute()).getBindableJavaType(), value);

                    if (valueObject.equals(id))
                    {
                        // Delete this key
                        kvStore.multiDelete(keytoDelete, null, null);
                    }
                }
            }
        }

    }

    @Override
    public void close()
    {
    }

    private void addToResults(Set results, Set resultsToAdd, String operation)
    {
        if (resultsToAdd == null || resultsToAdd.isEmpty())
        {
            return;
        }

        if (operation == null)
        {
            results.addAll(resultsToAdd);
        }
        else if (operation.equalsIgnoreCase("OR"))
        {
            results.addAll(resultsToAdd);
        }
        else if (operation.equalsIgnoreCase("AND"))
        {
            if (results.isEmpty())
            {
                results.addAll(resultsToAdd);
            }
            else
            {
                results.retainAll(resultsToAdd);
            }
        }

        resultsToAdd.clear();
    }

    /**
     * @return the kvStore
     */
    public KVStore getKvStore()
    {
        return kvStore;
    }

    /**
     * @param kvStore
     *            the kvStore to set
     */
    public void setKvStore(KVStore kvStore)
    {
        this.kvStore = kvStore;
    }

    /**
     * @param handler
     *            the handler to set
     */
    public void setHandler(OracleNoSQLDataHandler handler)
    {
        this.handler = handler;
    }

    /**
     * @param entityMetadata
     * @return
     */
    protected String getIndexTableName(EntityMetadata entityMetadata)
    {
        return entityMetadata.getIndexName() + OracleNOSQLConstants.SECONDARY_INDEX_SUFFIX;
    }
}
TOP

Related Classes of com.impetus.client.oraclenosql.index.OracleNoSQLInvertedIndexer

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.