com.yahoo.sql4dclient.BeanGenUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.yahoo.sql4dclient.BeanGenUtil.java

Source

/**
 * Copyright 2014 Yahoo! Inc. 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.yahoo.sql4dclient;

import com.yahoo.sql4d.sql4ddriver.Util;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * To auto generate Bean java class for a SQL.
 * @author srikalyan
 */
public class BeanGenUtil {
    private static final Logger logger = LoggerFactory.getLogger(BeanGenUtil.class);

    //TODO: Extend the following to address join sqls as well.
    private static final Pattern joinSqlPattern = Pattern
            .compile("(?i)select (.*) from (.*) (join|right_join|left_join) \\((.*)\\) on \\((.*)\\)(;)?");
    private static final Pattern sqlPattern = Pattern.compile("(?i)select (.*) from (.*)(;)?");
    private static final Pattern fieldPattern = Pattern.compile("(.*) (AS|as) (.*)");

    //TODO: Extend to generate package structure as well.
    public static void generateBean(String cmd, String beanClassName) {
        Matcher joinSqlMatcher = joinSqlPattern.matcher(cmd);
        if (joinSqlMatcher.matches()) {
            Map<String, String> firstSet = getFields(joinSqlMatcher.group(1));
            Map<String, String> secondSet = null;
            Matcher sqlMatcher = sqlPattern.matcher(joinSqlMatcher.group(4));
            if (sqlMatcher.matches()) {
                secondSet = getFields(sqlMatcher.group(1));
                String joinField = joinSqlMatcher.group(5);
                secondSet.remove(joinField);
                firstSet.putAll(secondSet);
            }
            generate(firstSet, beanClassName);
        } else {
            Matcher sqlMatcher = sqlPattern.matcher(cmd);
            if (sqlMatcher.matches()) {
                generate(getFields(sqlMatcher.group(1)), beanClassName);
            }
        }
    }

    private static Map<String, String> getFields(String rawFields) {
        Map<String, String> fields = new HashMap<>();
        String[] args = rawFields.split(",");
        for (String arg : args) {
            Matcher fMatcher = fieldPattern.matcher(arg);
            if (fMatcher.matches()) {
                String actual = fMatcher.group(1).trim();
                String alias = fMatcher.group(3).trim();
                if (actual.matches("(COUNT|count)\\(\\*\\)(.*)")) {
                    fields.put(alias, "long");
                } else if (actual.matches("(LONG_SUM|long_sum)\\((.*)\\)(.*)")) {
                    fields.put(alias, "long");
                } else if (actual.matches("(DOUBLE_SUM|double_sum)\\((.*)\\)(.*)")) {
                    fields.put(alias, "double");
                } else {
                    fields.put(alias, "String");
                }
            } else {// Type cannot be inferred.
                fields.put(arg.trim(), "String");
            }
        }
        return fields;
    }

    private static void generate(Map<String, String> fields, String beanClassName) {
        fields.remove("timestamp");// Timestamp is derived from DruidBaseBean so do not create one for it.
        StringBuilder javaClass = new StringBuilder("/** AUTO-GENERATED **/ \n");
        javaClass.append("import com.yahoo.sql4d.sql4ddriver.rowmapper.DruidBaseBean;\n\n");
        javaClass.append(String.format("public class %s extends DruidBaseBean { \n", beanClassName));
        for (String field : fields.keySet()) {
            javaClass.append(String.format("    private %s %s ;\n", fields.get(field), field));
        }
        for (String field : fields.keySet()) {
            genGetter(field, fields.get(field), javaClass);
            genSetter(field, fields.get(field), javaClass);
        }
        javaClass.append("} \n");
        javaClass.append("/** AUTO-GENERATED **/ \n");
        try {
            FileUtils.write(new File(System.getenv("HOME") + File.separator + beanClassName + ".java"), javaClass);
        } catch (IOException ex) {
            logger.error("generate error {}", javaClass.toString(), ex);
        }
        logger.info(javaClass.toString());
    }

    private static void genGetter(String name, String type, StringBuilder buff) {
        buff.append(String.format("    public %s get%s() { \n", type, Util.capitalize(name)));
        buff.append(String.format("         return this.%s; \n", name));
        buff.append("    } \n");
    }

    private static void genSetter(String name, String type, StringBuilder buff) {
        buff.append(String.format("    public void set%s(%s %s) { \n", Util.capitalize(name), type, name));
        buff.append(String.format("         this.%s = %s; \n", name, name));
        buff.append("    } \n");
    }
}