private void getParameterName(CommonTree tree) { Tree parameterNameTree = tree.getFirstChildWithType(CSharpParser.IDENTIFIER); if (parameterNameTree != null) { this.declareName = parameterNameTree.getText(); if ((this.declareName != null) && (!this.declareName.trim().equals(""))) { this.nameFound = true; } } }
/** @param preparedSql */ private Executor createSQLExecutor(String preparedSql) { if (logger.isDetailEnabled()) logger.detail(preparedSql); Executor result = null; // parse the sql CommonTree root = parse(preparedSql); // get the root of the tree int tokenType = root.getType(); // perform command-specific actions String tableName = ""; CommonTree tableNode; WhereNode whereNode; String whereType = "empty"; List<String> columnNames = new ArrayList<String>(); Dictionary dictionary; DomainTypeHandlerImpl<?> domainTypeHandler; QueryDomainTypeImpl<?> queryDomainType = null; int numberOfParameters = 0; switch (tokenType) { case MySQL51Parser.INSERT: tableNode = (CommonTree) root.getFirstChildWithType(MySQL51Parser.TABLE); tableName = getTableName(tableNode); getSession(); dictionary = session.getDictionary(); domainTypeHandler = getDomainTypeHandler(tableName, dictionary); CommonTree insertValuesNode = (CommonTree) root.getFirstChildWithType(MySQL51Parser.INSERT_VALUES); CommonTree columnsNode = (CommonTree) insertValuesNode.getFirstChildWithType(MySQL51Parser.COLUMNS); List<CommonTree> fields = columnsNode.getChildren(); for (CommonTree field : fields) { columnNames.add(getColumnName(field)); } if (logger.isDetailEnabled()) logger.detail( "StatementInterceptorImpl.preProcess parse result INSERT INTO " + tableName + " COLUMNS " + columnNames); result = new SQLExecutor.Insert(domainTypeHandler, columnNames); break; case MySQL51Parser.SELECT: CommonTree fromNode = (CommonTree) root.getFirstChildWithType(MySQL51Parser.FROM); if (fromNode == null) { // no from clause; cannot handle this case so return a do-nothing ParsedSQL result = new SQLExecutor.Noop(); break; } try { // this currently handles only FROM clauses with a single table tableNode = (CommonTree) fromNode.getFirstChildWithType(MySQL51Parser.TABLE); tableName = getTableName(tableNode); } catch (Exception e) { // trouble with the FROM clause; log the SQL statement and the parser output logger.info("Problem with FROM clause in SQL statement: " + preparedSql); logger.info(walk(root)); result = new SQLExecutor.Noop(); break; } boolean forUpdate = null != (CommonTree) root.getFirstChildWithType(MySQL51Parser.FOR); boolean lockShared = null != (CommonTree) root.getFirstChildWithType(MySQL51Parser.LOCK); LockMode lockMode = LockMode.READ_COMMITTED; if (forUpdate) { lockMode = LockMode.EXCLUSIVE; } else if (lockShared) { lockMode = LockMode.SHARED; } getSession(); dictionary = session.getDictionary(); domainTypeHandler = getDomainTypeHandler(tableName, dictionary); columnsNode = (CommonTree) root.getFirstChildWithType(MySQL51Parser.COLUMNS); List<CommonTree> selectExprNodes = columnsNode.getChildren(); for (CommonTree selectExprNode : selectExprNodes) { columnNames.add(getColumnName(getFieldNode(selectExprNode))); } if (logger.isDetailEnabled()) logger.detail("SELECT FROM " + tableName + " COLUMNS " + columnNames); // we need to distinguish three cases: // - no where clause (select all rows) // - where clause that cannot be executed by clusterj // - where clause that can be executed by clusterj whereNode = ((SelectNode) root).getWhereNode(); queryDomainType = (QueryDomainTypeImpl<?>) session.createQueryDomainType(domainTypeHandler); if (whereNode == null) { // no where clause (select all rows) result = new SQLExecutor.Select(domainTypeHandler, columnNames, queryDomainType, lockMode); } else { // create a predicate from the tree Predicate predicate = whereNode.getPredicate(queryDomainType); if (predicate != null) { // where clause that can be executed by clusterj queryDomainType.where(predicate); numberOfParameters = whereNode.getNumberOfParameters(); result = new SQLExecutor.Select( domainTypeHandler, columnNames, queryDomainType, lockMode, numberOfParameters); whereType = "clusterj"; } else { // where clause that cannot be executed by clusterj result = new SQLExecutor.Noop(); whereType = "non-clusterj"; } if (logger.isDetailEnabled()) logger.detail(walk(root)); } if (logger.isDetailEnabled()) { logger.detail( "SELECT FROM " + tableName + " COLUMNS " + columnNames + " whereType " + whereType); logger.detail(walk(root)); } logger.info(preparedSql + ": " + whereType); break; case MySQL51Parser.DELETE: tableNode = (CommonTree) root.getFirstChildWithType(MySQL51Parser.TABLE); tableName = getTableName(tableNode); getSession(); dictionary = session.getDictionary(); domainTypeHandler = getDomainTypeHandler(tableName, dictionary); whereNode = ((WhereNode) root.getFirstChildWithType(MySQL51Parser.WHERE)); if (whereNode == null) { // no where clause (delete all rows) result = new SQLExecutor.Delete(domainTypeHandler); whereType = "empty"; } else { // create a predicate from the tree queryDomainType = (QueryDomainTypeImpl<?>) session.createQueryDomainType(domainTypeHandler); Predicate predicate = whereNode.getPredicate(queryDomainType); if (predicate != null) { // where clause that can be executed by clusterj queryDomainType.where(predicate); numberOfParameters = whereNode.getNumberOfParameters(); result = new SQLExecutor.Delete(domainTypeHandler, queryDomainType, numberOfParameters); whereType = "clusterj"; } else { // where clause that cannot be executed by clusterj result = new SQLExecutor.Noop(); whereType = "non-clusterj"; } if (logger.isDetailEnabled()) logger.detail(walk(root)); } if (logger.isDetailEnabled()) logger.detail( "DELETE FROM " + tableName + " whereType " + whereType + " number of parameters " + numberOfParameters); logger.info(preparedSql + ": " + whereType); break; case MySQL51Parser.UPDATE: // UPDATE table SET column = value, column = value WHERE where-clause tableNode = (CommonTree) root.getFirstChildWithType(MySQL51Parser.TABLE); tableName = getTableName(tableNode); getSession(); dictionary = session.getDictionary(); domainTypeHandler = getDomainTypeHandler(tableName, dictionary); CommonTree setNode = (CommonTree) root.getFirstChildWithType(MySQL51Parser.SET); // create list of columns to update // SET node has one child for each <field> = <value List<CommonTree> equalNodes = setNode.getChildren(); List<Integer> parameterNumbers = new ArrayList<Integer>(); for (CommonTree equalNode : equalNodes) { // each equalNode has a FIELD node and a parameter node columnNames.add(getColumnName(getFieldNode(equalNode))); PlaceholderNode parameterNode = (PlaceholderNode) equalNode.getChild(1); parameterNumbers.add(parameterNode.getId()); } if (logger.isDetailEnabled()) logger.detail("Update " + columnNames + " values " + parameterNumbers); whereNode = ((WhereNode) root.getFirstChildWithType(MySQL51Parser.WHERE)); if (whereNode == null) { // no where clause (update all rows) whereType = "non-clusterj"; // return a do-nothing ParsedSQL if (logger.isDetailEnabled()) logger.detail( "ClusterJ cannot process this SQL statement: " + "unsupported statement type (UPDATE without WHERE clause."); result = new SQLExecutor.Noop(); } else { // create a predicate from the tree queryDomainType = (QueryDomainTypeImpl<?>) session.createQueryDomainType(domainTypeHandler); PredicateImpl predicate = (PredicateImpl) whereNode.getPredicate(queryDomainType); if (predicate != null) { // where clause that can be executed by clusterj queryDomainType.where(predicate); List<String> whereColumnNames = predicate.getTopLevelPropertyNames(); numberOfParameters = equalNodes.size() + whereColumnNames.size(); result = new SQLExecutor.Update( domainTypeHandler, queryDomainType, numberOfParameters, columnNames, whereColumnNames); whereType = "clusterj"; } else { // where clause that cannot be executed by clusterj result = new SQLExecutor.Noop(); whereType = "non-clusterj"; } if (logger.isDetailEnabled()) logger.detail(walk(root)); } if (logger.isDetailEnabled()) logger.detail( "UPDATE " + tableName + " whereType " + whereType + " number of parameters " + numberOfParameters); logger.info(preparedSql + ": " + whereType); break; default: // return a do-nothing ParsedSQL if (logger.isDetailEnabled()) logger.detail("ClusterJ cannot process this SQL statement: unsupported statement type."); result = new SQLExecutor.Noop(); } return result; }
@SuppressWarnings("unchecked") private Object walk(final Tree node, final DatatypeInfo parent) { // an optional node that is not present in the current context, is null if (node == null) { return null; } DatatypeInfo newParent = parent; CommonTree commonTreeNode = (CommonTree) node; Tree modifiers; switch (node.getType()) { // case CsRewriteRulesParser.ATTRIBUTE: // System.out.println("ATTRIBUTE"); // break; case CSharp4AST.NAMESPACE: CommonTree qid = (CommonTree) commonTreeNode.getFirstChildWithType(CSharp4AST.QUALIFIED_IDENTIFIER); Collection<String> namespaces = TreeHelper.treeListToStringList(qid.getChildren()); namespaceStack.addAll(namespaces); walk( commonTreeNode.getFirstChildWithType(CSharp4AST.NAMESPACE_MEMBER_DECLARATIONS), parent); for (int i = 0; i < qid.getChildren().size(); i++) namespaceStack.removeLast(); return null; case CSharp4AST.QUALIFIED_IDENTIFIER: case CSharp4AST.EXTERN_ALIAS_DIRECTIVES: case CSharp4AST.USING_DIRECTIVES: case CSharp4AST.NAMESPACE_MEMBER_DECLARATIONS: case CSharp4AST.ATTRIBUTES: case CSharp4AST.CLASS_MEMBER_DECLARATIONS: case CSharp4AST.INTERFACE_MEMBER_DECLARATIONS: case CSharp4AST.ENUM_MEMBER_DECLARATIONS: case CSharp4AST.STRUCT_MEMBER_DECLARATIONS: case CSharp4AST.CONST: for (int i = 0; i < commonTreeNode.getChildCount(); i++) { walk(commonTreeNode.getChild(i), parent); } return null; case CSharp4AST.CLASS: newParent = new DatatypeInfo("class"); newParent.setNamespace(namespaceStack); datatypeInfos.add(newParent); String className = walk( commonTreeNode.getFirstChildWithType(CSharp4AST.IDENTIFIER), newParent, String.class); newParent.setName(className); LOGGER.fine("class: " + className); // modifiers modifiers = commonTreeNode.getFirstChildWithType(CSharp4AST.MODIFIERS); if (modifiers != null) { List<String> modifierNames = TreeHelper.treeListToStringList(((CommonTree) modifiers).getChildren()); if (modifierNames.contains(ABSTRACT)) { newParent.setIsAbstract(Boolean.TRUE); } } setFullPath(parent, newParent); // must be invoked after setFullPath walk(commonTreeNode.getFirstChildWithType(CSharp4AST.CLASS_MEMBER_DECLARATIONS), newParent); addToReferences(newParent); return newParent; case CSharp4AST.INTERFACE: newParent = new DatatypeInfo("interface"); newParent.setNamespace(namespaceStack); datatypeInfos.add(newParent); String interfaceName = walk( commonTreeNode.getFirstChildWithType(CSharp4AST.IDENTIFIER), newParent, String.class); newParent.setName(interfaceName); LOGGER.fine("interface: " + interfaceName); // transform(commonTreeNode.getFirstChildWithType(CSharp4AST.IMPLEMENTS), // newParent, // false); // modifiers modifiers = commonTreeNode.getFirstChildWithType(CSharp4AST.MODIFIERS); if (modifiers != null) { List<String> modifierNames = TreeHelper.treeListToStringList(((CommonTree) modifiers).getChildren()); if (modifierNames.contains(ABSTRACT)) { newParent.setIsAbstract(Boolean.TRUE); } } setFullPath(parent, newParent); // must be invoked after setFullPath walk( commonTreeNode.getFirstChildWithType(CSharp4AST.INTERFACE_MEMBER_DECLARATIONS), newParent); addToReferences(newParent); return newParent; case CSharp4AST.ENUM: newParent = new DatatypeInfo("enum"); newParent.setNamespace(namespaceStack); datatypeInfos.add(newParent); String enumName = walk( commonTreeNode.getFirstChildWithType(CSharp4AST.IDENTIFIER), newParent, String.class); newParent.setName(enumName); LOGGER.fine("enum: " + enumName); // modifiers modifiers = commonTreeNode.getFirstChildWithType(CSharp4AST.MODIFIERS); if (modifiers != null) { for (int i = 0; i < modifiers.getChildCount(); i++) { Tree modTree = modifiers.getChild(i); String modName = modTree.getText(); if (ABSTRACT.equals(modName)) { newParent.setIsAbstract(Boolean.TRUE); } } } setFullPath(parent, newParent); // must be invoked after setFullPath walk(commonTreeNode.getFirstChildWithType(CSharp4AST.ENUM_MEMBER_DECLARATIONS), newParent); addToReferences(newParent); return newParent; case CSharp4AST.STRUCT: newParent = new DatatypeInfo("struct"); newParent.setNamespace(namespaceStack); datatypeInfos.add(newParent); String structName = walk( commonTreeNode.getFirstChildWithType(CSharp4AST.IDENTIFIER), newParent, String.class); newParent.setName(structName); // IMPLEMENTS setFullPath(parent, newParent); walk( commonTreeNode.getFirstChildWithType(CSharp4AST.STRUCT_MEMBER_DECLARATIONS), newParent); addToReferences(newParent); LOGGER.fine("struct: " + newParent); return newParent; case CSharp4AST.DELEGATE: // see http://msdn.microsoft.com/de-de/library/900fyy8e%28v=vs.80%29.aspx newParent = new DatatypeInfo("delegate"); newParent.setNamespace(namespaceStack); String delegateName = walk( commonTreeNode.getFirstChildWithType(CSharp4AST.IDENTIFIER), newParent, String.class); newParent.setName(delegateName); // TODO handle signature and generics setFullPath(parent, newParent); addToReferences(newParent); LOGGER.fine("delegate: " + newParent); break; case CSharp4AST.METHOD_DECL: MethodInfo methodInfo = new MethodInfo(parent); String returnType = walk(commonTreeNode.getFirstChildWithType(CSharp4AST.TYPE), parent, String.class); String methodName = walk( commonTreeNode.getFirstChildWithType(CSharp4AST.MEMBER_NAME), parent, String.class); List<ParameterInfo> formalParameters = walk( commonTreeNode.getFirstChildWithType(CSharp4AST.FORMAL_PARAMETER_LIST), parent, List.class); LOGGER.fine("method: " + methodName); methodInfo.setName(methodName); methodInfo.setReturnType(returnType); if (formalParameters != null) methodInfo.getParameters().addAll(formalParameters); parent.addMethodInfo(methodInfo); addToReferences(methodInfo); return methodInfo; case CSharp4AST.MEMBER_NAME: String typeName = walk( commonTreeNode.getFirstChildWithType(CSharp4AST.NAMESPACE_OR_TYPE_NAME), parent, String.class); return typeName; case CSharp4AST.FORMAL_PARAMETER_LIST: List<ParameterInfo> parameters = new LinkedList<ParameterInfo>(); for (int i = 0; i < commonTreeNode.getChildCount(); i++) { Tree child = commonTreeNode.getChild(i); ParameterInfo parameter = walk(child, parent, ParameterInfo.class); parameters.add(parameter); } return parameters; case CSharp4AST.FIXED_PARAMETER: String fixedParamName = walk(commonTreeNode.getFirstChildWithType(CSharp4AST.IDENTIFIER), parent, String.class); String fixedParamType = walk(commonTreeNode.getFirstChildWithType(CSharp4AST.TYPE), parent, String.class); if (fixedParamType != null) { // if not __arglist fixedParamType = KeyStringHelper.normalize(fixedParamType); } else { fixedParamType = fixedParamName; } return new ParameterInfo(fixedParamType, fixedParamName); case CSharp4AST.PARAMETER_ARRAY: String paramArrayName = walk(commonTreeNode.getFirstChildWithType(CSharp4AST.IDENTIFIER), parent, String.class); String paramArrayType = walk(commonTreeNode.getFirstChildWithType(CSharp4AST.TYPE), parent, String.class); paramArrayType = KeyStringHelper.normalize(paramArrayType); return new ParameterInfo(paramArrayType, paramArrayName); case CSharp4AST.FIELD_DECL: // do not process children of type TYPE for (int i = 0; i < commonTreeNode.getChildCount(); i++) { Tree child = commonTreeNode.getChild(i); if (child.getType() == CSharp4AST.VARIABLE_DECLARATOR) { walk(child, parent); } } break; case CSharp4AST.PROPERTY_DECL: FieldInfo propertyInfo = new FieldInfo(parent); String propertyName = walk( commonTreeNode.getFirstChildWithType(CSharp4AST.MEMBER_NAME), parent, String.class); if (propertyName != null) propertyInfo.setName(propertyName); String propertyType = walk(commonTreeNode.getFirstChildWithType(CSharp4AST.TYPE), parent, String.class); propertyInfo.setType(propertyType); parent.addFieldInfo(propertyInfo); addToReferences(propertyInfo); LOGGER.fine("LOAD PROPERTY: " + propertyInfo.getName()); return propertyInfo; case CSharp4AST.VARIABLE_DECLARATOR: FieldInfo fieldInfo = new FieldInfo(parent); String fieldName = walk(commonTreeNode.getFirstChildWithType(CSharp4AST.IDENTIFIER), parent, String.class); if (fieldName != null) fieldInfo.setName(fieldName); String variableType = walk(commonTreeNode.getFirstChildWithType(CSharp4AST.TYPE), parent, String.class); fieldInfo.setType(variableType); parent.addFieldInfo(fieldInfo); addToReferences(fieldInfo); return fieldInfo; case CSharp4AST.ENUM_MEMBER_DECLARATION: LOGGER.warning("UNSUPPORTED: enum member declarations are not yet supported."); break; case CSharp4AST.TYPE: StringBuilder builder = new StringBuilder(); Tree baseTypeNode = commonTreeNode.getChild(0); switch (baseTypeNode.getType()) { case CSharp4AST.NAMESPACE_OR_TYPE_NAME: String qualifiedBaseType = walk(baseTypeNode, parent, String.class); builder.append(qualifiedBaseType); break; default: // OBJECT, STRING, VOID, IDENTIFIER(dynamic), and primitive // types builder.append(baseTypeNode.getText()); break; } for (int i = 1; i < commonTreeNode.getChildCount(); i++) { Tree typeExtension = commonTreeNode.getChild(i); // INTERR, rank_specifier, STAR switch (typeExtension.getType()) { case CSharp4AST.INTERR: LOGGER.warning("UNSUPPORTED: INTERR is not yet supported"); break; case CSharp4AST.RANK_SPECIFIER: builder.append("["); int numCommas = typeExtension.getChildCount(); do { builder.append(","); } while (numCommas-- > 0); builder.append("]"); break; case CSharp4AST.STAR: builder.append("*"); break; default: break; } } return builder.toString(); case CSharp4AST.NAMESPACE_OR_TYPE_NAME: builder = new StringBuilder(); String nsIdentifier = walk(commonTreeNode.getFirstChildWithType(CSharp4AST.IDENTIFIER), parent, String.class); if (nsIdentifier != null) builder.append(nsIdentifier); List<String> qualified_alias_member = walk( commonTreeNode.getFirstChildWithType(CSharp4AST.QUALIFIED_ALIAS_MEMBER), parent, List.class); if (qualified_alias_member != null) { for (String qam : qualified_alias_member) { builder.append("."); builder.append(qam); } } for (int i = 1; i < node.getChildCount(); i++) { CommonTree child = (CommonTree) node.getChild(i); if (child.getType() == CSharp4AST.NAMESPACE_OR_TYPE_PART) { String nsPart = walk(child.getFirstChildWithType(CSharp4AST.IDENTIFIER), parent, String.class); builder.append("."); builder.append(nsPart); } } return builder.toString(); case CSharp4AST.IDENTIFIER: return node.getText(); default: return null; } return null; }