/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.cassandra.cql;
import java.nio.ByteBuffer;
import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.db.marshal.AsciiType;
import org.apache.cassandra.db.marshal.FloatType;
import org.apache.cassandra.db.marshal.IntegerType;
import org.apache.cassandra.db.marshal.LexicalUUIDType;
import org.apache.cassandra.db.marshal.MarshalException;
import org.apache.cassandra.thrift.InvalidRequestException;
/** A term parsed from a CQL statement. */
public class Term
{
private final String text;
private final TermType type;
/**
* Create new Term instance from a string, and an integer that corresponds
* with the token ID from CQLParser.
*
* @param text the text representation of the term.
* @param type the term's type as an integer token ID.
*/
public Term(String text, int type)
{
this.text = text == null ? "" : text;
this.type = TermType.forInt(type);
}
public Term(String text, TermType type)
{
this.text = text == null ? "" : text;
this.type = type;
}
protected Term()
{
this.text = "";
this.type = TermType.STRING;
}
/**
* Returns the text parsed to create this term.
*
* @return the string term acquired from a CQL statement.
*/
public String getText()
{
return text;
}
/**
* Returns the typed value, serialized to a ByteBuffer according to a
* comparator/validator.
*
* @return a ByteBuffer of the value.
* @throws InvalidRequestException if unable to coerce the string to its type.
*/
public ByteBuffer getByteBuffer(AbstractType<?> validator) throws InvalidRequestException
{
try
{
return validator.fromString(text);
}
catch (MarshalException e)
{
throw new InvalidRequestException(e.getMessage());
}
}
/**
* Returns the typed value, serialized to a ByteBuffer.
*
* @return a ByteBuffer of the value.
* @throws InvalidRequestException if unable to coerce the string to its type.
*/
public ByteBuffer getByteBuffer() throws InvalidRequestException
{
switch (type)
{
case STRING:
return AsciiType.instance.fromString(text);
case INTEGER:
return IntegerType.instance.fromString(text);
case UUID:
// we specifically want the Lexical class here, not "UUIDType," because we're supposed to have
// a uuid-shaped string here, and UUIDType also accepts integer or date strings (and turns them into version 1 uuids).
return LexicalUUIDType.instance.fromString(text);
case FLOAT:
return FloatType.instance.fromString(text);
}
// FIXME: handle scenario that should never happen
return null;
}
/**
* Obtain the term's type.
*
* @return the type
*/
public TermType getType()
{
return type;
}
public String toString()
{
return String.format("Term(%s, type=%s)", getText(), type);
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((text == null) ? 0 : text.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Term other = (Term) obj;
if (text == null)
{
if (other.text != null)
return false;
} else if (!text.equals(other.text))
return false;
if (type != other.type)
return false;
return true;
}
}
enum TermType
{
STRING, INTEGER, UUID, FLOAT;
static TermType forInt(int type)
{
if ((type == CqlParser.STRING_LITERAL) || (type == CqlParser.IDENT))
return STRING;
else if (type == CqlParser.INTEGER)
return INTEGER;
else if (type == CqlParser.UUID)
return UUID;
else if (type == CqlParser.FLOAT)
return FLOAT;
// FIXME: handled scenario that should never occur.
return null;
}
}