org.cloudgraph.hbase.scan.ScanLiteralAssembler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cloudgraph-hbase Show documentation
Show all versions of cloudgraph-hbase Show documentation
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.
/**
* 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