com.gemstone.gemfire.cache.query.internal.PathUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gemfire-core Show documentation
Show all versions of gemfire-core Show documentation
SnappyData store based off Pivotal GemFireXD
The newest version!
/*
* Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
*
* 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. See accompanying
* LICENSE file.
*/
package com.gemstone.gemfire.cache.query.internal;
import java.lang.reflect.*;
import java.util.*;
import com.gemstone.gemfire.cache.query.AmbiguousNameException;
import com.gemstone.gemfire.cache.query.NameResolutionException;
import com.gemstone.gemfire.cache.query.QueryInvocationTargetException;
import com.gemstone.gemfire.cache.query.NameNotFoundException;
import com.gemstone.gemfire.cache.query.QueryService;
import com.gemstone.gemfire.cache.query.Struct;
import com.gemstone.gemfire.cache.query.TypeMismatchException;
import com.gemstone.gemfire.cache.query.types.*;
import com.gemstone.gemfire.cache.query.internal.types.*;
/**
* Class Description
*
* @version $Revision: 1.1 $
* @author ericz
*/
public class PathUtils {
public static String[] tokenizePath(String path) {
ArrayList alist = new ArrayList();
StringTokenizer tokenizer = new StringTokenizer(path, ".");
while (tokenizer.hasMoreTokens()) {
alist.add(tokenizer.nextToken());
}
return (String[])alist.toArray(new String[alist.size()]);
}
public static String buildPathString(String[] path) {
Support.assertArg(path != null && path.length > 0, "path should not be null or empty");
StringBuilder buf = new StringBuilder();
buf.append(path[0]);
for (int i = 1 ; i < path.length; i++) {
buf.append('.');
buf.append(path[i]);
}
return buf.toString();
}
public static Object evaluateAttribute(Object target, String attribute)
throws NameNotFoundException, QueryInvocationTargetException {
if(target instanceof Struct){
Struct struct = (Struct)target;
try{
return struct.get(attribute);
}catch(Exception e){
throw new NameNotFoundException(attribute);
}
}
try {
return new AttributeDescriptor(attribute).read(target);
} catch (NameNotFoundException nfe) {
if (DefaultQueryService.QUERY_HETEROGENEOUS_OBJECTS ||
DefaultQueryService.TEST_QUERY_HETEROGENEOUS_OBJECTS) {
return QueryService.UNDEFINED;
} else {
throw nfe;
}
}
}
/*
* This was added as part of CQ performance changes.
* The change is done to re-use the AttributeDescriptor object instead of creating
* it each time.
*/
/*
public static Object evaluateAttribute(Object target, String attribute, AttributeDescriptor attributeDescriptor)
throws NameNotFoundException, QueryInvocationTargetException {
if(target instanceof Struct){
Struct struct = (Struct)target;
try{
return struct.get(attribute);
}catch(Exception e){
throw new NameNotFoundException(attribute);
}
}
return attributeDescriptor.read(target);
}
*/
/**
* @param pathArray the path starting with an attribute on
* the initial type.
* @return array of types starting with the initialType and
* ending with the type of the last attribute in the path.
* @throws NameNotFoundException if could not find an attribute along path
*
*/
public static ObjectType[] calculateTypesAlongPath(ObjectType initialType,
String[] pathArray)
throws NameNotFoundException {
ObjectType[] types = new ObjectType[pathArray.length + 1];
// initialClass goes in front
types[0] = initialType;
for (int i = 1; i < types.length; i++) {
ObjectType currentType = types[i - 1];
Member member = new AttributeDescriptor(pathArray[i-1]).getReadMember(currentType);
if (member instanceof Field)
types[i] = TypeUtils.getObjectType(((Field)member).getType());
else if (member instanceof Method)
types[i] = TypeUtils.getObjectType(((Method)member).getReturnType());
}
return types;
}
public static ObjectType computeElementTypeOfExpression(
ExecutionContext context, CompiledValue expr)
throws AmbiguousNameException
{
try {
ObjectType type = TypeUtils.OBJECT_TYPE;
List exprSteps = new ArrayList();
while (true) {
if (expr instanceof CompiledPath) {
CompiledPath path = (CompiledPath)expr;
exprSteps.add(0, path.getTailID());
expr = path.getReceiver();
}
else if (expr instanceof CompiledOperation) {
CompiledOperation operation = (CompiledOperation)expr;
if (operation.getArguments().size() > 0) {
return TypeUtils.OBJECT_TYPE;
}
exprSteps.add(0, operation.getMethodName() + "()");
expr = operation.getReceiver(context);
if (expr == null) {
expr = context.resolveImplicitOperationName(operation
.getMethodName(), operation.getArguments().size(), true);
}
}
else if (expr instanceof CompiledID) {
expr = context.resolve(((CompiledID)expr).getId());
}
else if (expr instanceof CompiledRegion) {
QRegion qrgn = (QRegion)((CompiledRegion)expr).evaluate(context);
type = qrgn.getCollectionType();
break;
}
else if (expr instanceof RuntimeIterator) {
type = ((RuntimeIterator)expr).getElementType();
break;
}
else {
return TypeUtils.OBJECT_TYPE;
}
}
if (!TypeUtils.OBJECT_TYPE.equals(type)) {
Class clazz = type.resolveClass();
for (int i = 0; i < exprSteps.size(); i++) {
Member member;
String stepStr = (String)exprSteps.get(i);
// System.out.println("step = "+step);
if (stepStr.endsWith("()")) {
stepStr = stepStr.substring(0, stepStr.length() - 2);
member = clazz.getMethod(stepStr, (Class[])null);
}
else {
member = new AttributeDescriptor(stepStr).getReadMember(clazz);
}
if (member instanceof Field) {
clazz = ((Field)member).getType();
}
else if (member instanceof Method) {
clazz = ((Method)member).getReturnType();
}
type = TypeUtils.getObjectType(clazz);
}
return type;
}
}
catch (NoSuchMethodException e) {
}
catch (NameResolutionException e) {
}
catch (TypeMismatchException e) {
}
return TypeUtils.OBJECT_TYPE;
}
}