[
https://issues.apache.org/jira/browse/APEXMALHAR-2010?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15203843#comment-15203843
]
ASF GitHub Bot commented on APEXMALHAR-2010:
--------------------------------------------
Github user tushargosavi commented on a diff in the pull request:
https://github.com/apache/incubator-apex-malhar/pull/209#discussion_r56787178
--- Diff:
library/src/main/java/com/datatorrent/lib/expression/JavaExpressionParser.java
---
@@ -0,0 +1,179 @@
+/**
+ * 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 com.datatorrent.lib.expression;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.datatorrent.lib.util.KeyValPair;
+
+/**
+ * Defines how quasi-Java Expression should be parsed.
+ */
+public class JavaExpressionParser implements Expression.ExpressionParser
+{
+ private static final Logger logger =
LoggerFactory.getLogger(JavaExpressionParser.class);
+
+ private static final String GET = "get";
+ private static final String IS = "is";
+
+ private String variablePlaceholderPattern = "\\{(.*?)\\}";
+
+ private String exprObjPlaceholder;
+ private String codeObjPlaceholder;
+
+ public JavaExpressionParser()
+ {
+ // Fro kryo serialization.
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override public String convertToCompilableExpression(String expression,
Class<?> objectType, Class<?> returnType)
+ {
+ if (expression.startsWith(".")) {
+ expression = expression.substring(1);
+ }
+
+ if (expression.isEmpty()) {
+ throw new IllegalArgumentException("The getter expression: \"" +
expression + "\" is invalid.");
+ }
+
+ Pattern entry = Pattern.compile(variablePlaceholderPattern);
+ Matcher matcher = entry.matcher(expression);
+ StringBuffer sb = new StringBuffer();
+
+ while (matcher.find()) {
+ if (matcher.groupCount() == 1) {
+ try {
+ matcher.appendReplacement(sb,
getObjectJavaExpression(matcher.group(1), objectType));
+ } catch (NoSuchFieldException e) {
+ throw new RuntimeException("Failed to parse the operand: " +
matcher.group(1), e);
+ }
+ } else {
+ throw new RuntimeException("Invalid expression: " +
matcher.group());
+ }
+ }
+
+ matcher.appendTail(sb);
+
+ if (sb.toString().equals(expression)) {
+ // This is a simple expression. No object placeholder. create proper
expression.
+ if (!expression.startsWith("$.")) {
+ expression = "$." + expression;
+ }
+ try {
+ String tempExpr = getObjectJavaExpression(expression, objectType);
+ sb.setLength(0);
+ sb.append(tempExpr.replace("\\$", "$"));
+ } catch (NoSuchFieldException e) {
+ throw new RuntimeException("Failed to create expression.", e);
+ }
+ }
+
+ return "return ((" + returnType.getName().replace("$", "\\$") + ")" +
sb.toString() + ");";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override public void setInputObjectPlaceholder(String
exprObjPlaceholder, String codeObjPlaceholder)
+ {
+ this.exprObjPlaceholder = exprObjPlaceholder;
+ this.codeObjPlaceholder = codeObjPlaceholder;
+ }
+
+ private String getObjectJavaExpression(String exp, Class objectType)
throws NoSuchFieldException
+ {
+ StringBuilder sb = new StringBuilder();
+
+ String[] split = exp.split("\\.");
+ Class<?> currentClassType = objectType;
+
+ boolean first = true;
+ for (String field : split) {
+ if (first) {
+ first = false;
+ } else {
+ sb.append(".");
+ }
+ if (field.equals(exprObjPlaceholder)) {
+ // Replace with object type
+ sb.append("((").append(objectType.getName().replace("$",
"\\$")).append(")").append("(")
+ .append(codeObjPlaceholder).append("))");
+ currentClassType = objectType;
+ } else {
+ KeyValPair<String, ? extends Class<?>> getter =
getGetterForVariable(field, currentClassType);
+ sb.append(getter.getKey());
+ currentClassType = getter.getValue();
+ }
+ }
+
+ return sb.toString();
+ }
+
+ private KeyValPair<String, ? extends Class<?>>
getGetterForVariable(String var, Class<?> inputClassType)
+ {
+ try {
+ final Field field = inputClassType.getField(var);
+ if (Modifier.isPublic(field.getModifiers())) {
+ return new KeyValPair<>(var, field.getType());
+ }
+ logger.debug("Field {} is not publicly accessible. Proceeding to
locate a getter method.", var);
+ } catch (NoSuchFieldException | SecurityException ex) {
+ logger.debug("{} does not have field {}. Proceeding to locate a
getter method.", inputClassType.getName(), var);
+ }
+
+ String methodName = GET + var.substring(0, 1).toUpperCase() +
var.substring(1);
+ try {
+ Method method = inputClassType.getMethod(methodName);
+ if (Modifier.isPublic(method.getModifiers())) {
+ return new KeyValPair<>(methodName + "()", method.getReturnType());
+ }
+ logger.debug("Method {} of {} is not accessible. Proceeding to
locate another getter method.", methodName,
+ inputClassType.getName());
+ } catch (NoSuchMethodException | SecurityException ex) {
+ logger.debug("{} does not have method {}. Proceeding to locate
another getter method", inputClassType.getName(),
+ methodName);
+ }
+
+ methodName = IS + var.substring(0, 1).toUpperCase() + var.substring(1);
+ try {
+ Method method = inputClassType.getMethod(methodName);
+ if (Modifier.isPublic(method.getModifiers())) {
+ return new KeyValPair<>(methodName + "()", method.getReturnType());
+ }
+ logger.debug("Method {} of {} is not accessible. Proceeding to
locate another getter method.", methodName,
+ inputClassType.getName());
+ } catch (NoSuchMethodException | SecurityException ex) {
+ logger.debug("{} does not have method {}. Proceeding to locate
another getter method", inputClassType.getName(),
+ methodName);
+ }
--- End diff --
duplicate code same as above can you take it out as a private function in
same class.
> Add transform operator
> ----------------------
>
> Key: APEXMALHAR-2010
> URL: https://issues.apache.org/jira/browse/APEXMALHAR-2010
> Project: Apache Apex Malhar
> Issue Type: New Feature
> Components: algorithms
> Affects Versions: 3.4.0
> Reporter: Chinmay Kolhatkar
> Assignee: Chinmay Kolhatkar
>
> Add transform operator
> Details to be added soon once the mailing thread reaching conclusion:
> http://mail-archives.apache.org/mod_mbox/incubator-apex-dev/201603.mbox/%3CCABAipVZUdRGx5dS35bYPN46koLQU5gSLgbCeRH8aM_y9ANRU2w%40mail.gmail.com%3E
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)