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

org.cloudgraph.hbase.scan.ScanLiteralAssembler Maven / Gradle / Ivy

Go to download

CloudGraph(tm) is a suite of Service Data Object (SDO) 2.1 services designed for relational and big-table style "cloud" databases, such as HBase and others.

There is a newer version: 2.0.4
Show newest version
/**
 *        CloudGraph Community Edition (CE) License
 * 
 * This is a community release of CloudGraph, a dual-license suite of
 * Service Data Object (SDO) 2.1 services designed for relational and 
 * big-table style "cloud" databases, such as HBase and others. 
 * This particular copy of the software is released under the 
 * version 2 of the GNU General Public License. CloudGraph was developed by 
 * TerraMeta Software, Inc.
 * 
 * Copyright (c) 2013, TerraMeta Software, Inc. All rights reserved.
 * 
 * General License information can be found below.
 * 
 * This distribution may include materials developed by third
 * parties. For license and attribution notices for these
 * materials, please refer to the documentation that accompanies
 * this distribution (see the "Licenses for Third-Party Components"
 * appendix) or view the online documentation at 
 * . 
 */
package org.cloudgraph.hbase.scan;

import javax.xml.namespace.QName;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.cloudgraph.config.CloudGraphConfig;
import org.cloudgraph.config.DataGraphConfig;
import org.cloudgraph.config.TableConfig;
import org.cloudgraph.config.UserDefinedRowKeyFieldConfig;
import org.cloudgraph.store.service.GraphServiceException;
import org.plasma.query.model.AbstractPathElement;
import org.plasma.query.model.GroupOperator;
import org.plasma.query.model.Literal;
import org.plasma.query.model.LogicalOperator;
import org.plasma.query.model.NullLiteral;
import org.plasma.query.model.Path;
import org.plasma.query.model.PathElement;
import org.plasma.query.model.Property;
import org.plasma.query.model.RelationalOperator;
import org.plasma.query.model.RelationalOperatorValues;
import org.plasma.query.model.Where;
import org.plasma.query.model.WildcardOperator;
import org.plasma.query.model.WildcardPathElement;
import org.plasma.query.visitor.DefaultQueryVisitor;
import org.plasma.sdo.PlasmaProperty;
import org.plasma.sdo.PlasmaType;


/**
 * Assembles the set of data "flavor" and data type specific
 * scan literals used to construct composite partial row 
 * (start/stop) key pair.  
 * 
 * @see org.cloudgraph.config.DataGraphConfig
 * @see org.cloudgraph.config.TableConfig
 * @author Scott Cinnamond
 * @since 0.5
 */
public class ScanLiteralAssembler extends DefaultQueryVisitor 
{
    private static Log log = LogFactory.getLog(ScanLiteralAssembler.class);
	protected PlasmaType rootType;
	protected PlasmaType contextType;
	protected PlasmaProperty contextProperty;
	protected String contextPropertyPath;
	protected RelationalOperator contextRelationalOperator;
	protected LogicalOperator contextLogicalOperator;
	protected WildcardOperator contextWildcardOperator;
	protected DataGraphConfig graph;
	protected TableConfig table;
	protected ScanLiterals partialKeyScanLiterals = new ScanLiterals();
	protected ScanLiterals fuzzyKeyScanLiterals = new ScanLiterals();
	protected ScanLiteralFactory scanLiteralFactory = new ScanLiteralFactory();
	
	@SuppressWarnings("unused")
	private ScanLiteralAssembler() {}
	
	public ScanLiteralAssembler(PlasmaType rootType)
	{
    	this.rootType = rootType;
		this.contextType = this.rootType;
		QName rootTypeQname = this.rootType.getQualifiedName();
		this.graph = CloudGraphConfig.getInstance().getDataGraph(
				rootTypeQname);
		this.table = CloudGraphConfig.getInstance().getTable(rootTypeQname);
	}
	
    public ScanLiterals getPartialKeyScanResult() {    	
		return this.partialKeyScanLiterals;
	}
    
    public ScanLiterals getFuzzyKeyScanResult() {    	
		return this.fuzzyKeyScanLiterals;
	}

    /**
     * Assemble the set of data "flavor" and data type specific
     * scan literals used to construct composite partial row 
     * (start/stop) key pair. 
     * @param where the row predicate hierarchy
     * @param contextType the context type which may be the root type or another
     * type linked by one or more relations to the root
     */
	public void assemble(Where where, PlasmaType contextType) {
    	
		this.contextType = contextType;
		
		if (log.isDebugEnabled())
    		log.debug("begin traverse");
    	
    	where.accept(this); // traverse
    	
    	if (log.isDebugEnabled())
    		log.debug("end traverse");      	
    }
	
	/**
	 * Process the traversal start event for a query {@link org.plasma.query.model.Property property}
     * within an {@link org.plasma.query.model.Expression expression} just
     * traversing the property path if exists and capturing context information
     * for the current {@link org.plasma.query.model.Expression expression}.  
	 * @see org.plasma.query.visitor.DefaultQueryVisitor#start(org.plasma.query.model.Property)
	 */
	@Override
    public void start(Property property)
    {                
        Path path = property.getPath();
        PlasmaType targetType = (PlasmaType)this.rootType;                
        if (path != null)
        {
            for (int i = 0 ; i < path.getPathNodes().size(); i++)
            {    
            	AbstractPathElement pathElem = path.getPathNodes().get(i).getPathElement();
                if (pathElem instanceof WildcardPathElement)
                    throw new GraphServiceException("wildcard path elements applicable for 'Select' clause paths only, not 'Where' clause paths");
                String elem = ((PathElement)pathElem).getValue();
                PlasmaProperty prop = (PlasmaProperty)targetType.getProperty(elem);                
                targetType = (PlasmaType)prop.getType(); // traverse
            }
        }
        PlasmaProperty endpointProp = (PlasmaProperty)targetType.getProperty(property.getName());
        this.contextProperty = endpointProp;
        this.contextType = targetType;
        this.contextPropertyPath = property.asPathString();
        
        super.start(property);
    }     

    /**
     * Process the traversal start event for a query {@link org.plasma.query.model.Literal literal}
     * within an {@link org.plasma.query.model.Expression expression}.
     * @param literal the expression literal
     * @throws GraphServiceException if no user defined row-key token
     * is configured for the current literal context.
     */
	@Override
	public void start(Literal literal) {
		String content = literal.getValue();
		if (this.contextProperty == null)
			throw new IllegalStateException("expected context property for literal");
		if (this.contextType == null)
			throw new IllegalStateException("expected context type for literal");
		if (this.rootType == null)
			throw new IllegalStateException("expected context type for literal");

		// Match the current property to a user defined 
		// row key token, if found we can process
		UserDefinedRowKeyFieldConfig fieldConfig = this.graph.getUserDefinedRowKeyField(this.contextPropertyPath);
		if (fieldConfig != null) 
		{
			PlasmaProperty property = (PlasmaProperty)fieldConfig.getEndpointProperty();
			ScanLiteral scanLiteral = null;
			if (this.contextRelationalOperator != null) {
			    scanLiteral = this.scanLiteralFactory.createLiteral(
					content, property, 
					this.rootType, 
					this.contextRelationalOperator, 
					fieldConfig);
			    // partial scan does not accommodate 'not equals' as it scans for
			    // contiguous set of row keys
				if (this.contextRelationalOperator.getValue().ordinal() !=
						RelationalOperatorValues.NOT_EQUALS.ordinal())
				    this.partialKeyScanLiterals.addLiteral(scanLiteral);
				// fuzzy only does 'equals' and wildcards
				if (this.contextRelationalOperator.getValue().ordinal() ==
						RelationalOperatorValues.EQUALS.ordinal())
				    this.fuzzyKeyScanLiterals.addLiteral(scanLiteral);
			}
			else if (this.contextWildcardOperator != null) {
			    scanLiteral = this.scanLiteralFactory.createLiteral(
					content, property, 
					this.rootType, 
					this.contextWildcardOperator, 
					fieldConfig);
				this.fuzzyKeyScanLiterals.addLiteral(scanLiteral);
			}
			else
		        throw new GraphServiceException("expected relational or wildcard operator for query path '"
			    	+ this.contextPropertyPath + "'");				
		}
		else
	        log.warn("no user defined row-key field for query path '"
			    	+ this.contextPropertyPath + "' - deferring to graph recogniser post processor");
		
		super.start(literal);
	}

	/**
	 * (non-Javadoc)
	 * @see org.plasma.query.visitor.DefaultQueryVisitor#start(org.plasma.query.model.NullLiteral)
	 */
	@Override
	public void start(NullLiteral nullLiteral) {
        throw new GraphServiceException("null literals for row scans not yet supported");
	}
	
	/**
	 * Process a {@link org.plasma.query.model.LogicalOperator logical operator} query traversal
	 * start event. 
	 */
	public void start(LogicalOperator operator) {
		
		switch (operator.getValue()) {
		case AND:
		case OR:	
			this.contextLogicalOperator = operator;
		}
		super.start(operator);
	}
	
	public void start(WildcardOperator operator) {
		switch (operator.getValue()) {
		default:
			this.contextRelationalOperator = null;
			this.contextWildcardOperator = operator;
		}
	}		
    
	@Override
	public void start(RelationalOperator operator) {
		switch (operator.getValue()) {
		case EQUALS:
		case NOT_EQUALS:
		case GREATER_THAN:
		case GREATER_THAN_EQUALS:
		case LESS_THAN:
		case LESS_THAN_EQUALS:
			this.contextRelationalOperator = operator;
			this.contextWildcardOperator = null;
			break;
		default:
			throw new GraphServiceException("unknown relational operator '"
					+ operator.getValue().toString() + "'");
		}
		super.start(operator);
	}
	
	public void start(GroupOperator operator) {
		switch (operator.getValue()) {
		case RP_1:  		
	        break;
		case RP_2:  		
		    break;
		case RP_3:  			
			break;
		case LP_1:  
			break;
		case LP_2:  			
			break;
		case LP_3:  
			break;
		default:
			throw new GraphServiceException("unsupported group operator, "
						+ operator.getValue().name());
		}
		super.start(operator);
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy