Java tutorial
/* * 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.hadoop.chukwa.database; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.HashMap; import java.util.Iterator; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.chukwa.util.DatabaseWriter; public class Macro { private static Log log = LogFactory.getLog(Macro.class); private boolean forCharting = false; private long current = 0; private long start = 0; private long end = 0; private static DatabaseConfig dbc = new DatabaseConfig(); private static DatabaseWriter db = null; private String query = null; private HttpServletRequest request = null; public Macro(long timestamp, String query) { this.current = timestamp; this.start = timestamp; this.end = timestamp; this.query = query; } public Macro(long startTime, long endTime, String query) { this.current = endTime; this.start = startTime; this.end = endTime; forCharting = true; this.query = query; } public Macro(long startTime, long endTime, String query, HttpServletRequest request) { this.request = request; this.current = endTime; this.start = startTime; this.end = endTime; forCharting = true; this.query = query; } public HashMap<String, String> findMacros(String query) throws SQLException { boolean add = false; HashMap<String, String> macroList = new HashMap<String, String>(); String macro = ""; for (int i = 0; i < query.length(); i++) { if (query.charAt(i) == ']') { add = false; if (!macroList.containsKey(macro)) { String subString = computeMacro(macro); macroList.put(macro, subString); } macro = ""; } if (add) { macro = macro + query.charAt(i); } if (query.charAt(i) == '[') { add = true; } } return macroList; } public String computeMacro(String macro) throws SQLException { Pattern p = Pattern.compile("past_(.*)_minutes"); Matcher matcher = p.matcher(macro); if (macro.indexOf("avg(") == 0 || macro.indexOf("group_avg(") == 0 || macro.indexOf("sum(") == 0) { String meta = ""; String[] table = null; if (forCharting) { table = dbc.findTableNameForCharts(macro.substring(macro.indexOf("(") + 1, macro.indexOf(")")), start, end); } else { table = dbc.findTableName(macro.substring(macro.indexOf("(") + 1, macro.indexOf(")")), start, end); } try { String cluster = System.getProperty("CLUSTER"); if (cluster == null) { cluster = "unknown"; } db = new DatabaseWriter(cluster); DatabaseMetaData dbMetaData = db.getConnection().getMetaData(); ResultSet rs = dbMetaData.getColumns(null, null, table[0], null); boolean first = true; while (rs.next()) { if (!first) { meta = meta + ","; } String name = rs.getString(4); int type = rs.getInt(5); if (type == java.sql.Types.VARCHAR) { if (macro.indexOf("group_avg(") < 0) { meta = meta + "count(" + name + ") as " + name; } else { meta = meta + name; } first = false; } else if (type == java.sql.Types.DOUBLE || type == java.sql.Types.FLOAT || type == java.sql.Types.INTEGER) { if (macro.indexOf("sum(") == 0) { meta = meta + "sum(" + name + ")"; } else { meta = meta + "avg(" + name + ")"; } first = false; } else if (type == java.sql.Types.TIMESTAMP) { meta = meta + name; first = false; } else { if (macro.indexOf("sum(") == 0) { meta = meta + "SUM(" + name + ")"; } else { meta = meta + "AVG(" + name + ")"; } first = false; } } db.close(); if (first) { throw new SQLException("Table is undefined."); } } catch (SQLException ex) { throw new SQLException("Table does not exist:" + table[0]); } return meta; } else if (macro.indexOf("now") == 0) { SimpleDateFormat sdf = new SimpleDateFormat(); return DatabaseWriter.formatTimeStamp(current); } else if (macro.intern() == "start".intern()) { return DatabaseWriter.formatTimeStamp(start); } else if (macro.intern() == "end".intern()) { return DatabaseWriter.formatTimeStamp(end); } else if (matcher.find()) { int period = Integer.parseInt(matcher.group(1)); long timestamp = current - (current % (period * 60 * 1000L)) - (period * 60 * 1000L); return DatabaseWriter.formatTimeStamp(timestamp); } else if (macro.indexOf("past_hour") == 0) { return DatabaseWriter.formatTimeStamp(current - 3600 * 1000L); } else if (macro.endsWith("_week")) { long partition = current / DatabaseConfig.WEEK; if (partition <= 0) { partition = 1; } String[] buffers = macro.split("_"); StringBuffer tableName = new StringBuffer(); for (int i = 0; i < buffers.length - 1; i++) { tableName.append(buffers[i]); tableName.append("_"); } tableName.append(partition); tableName.append("_week"); return tableName.toString(); } else if (macro.endsWith("_month")) { long partition = current / DatabaseConfig.MONTH; if (partition <= 0) { partition = 1; } String[] buffers = macro.split("_"); StringBuffer tableName = new StringBuffer(); for (int i = 0; i < buffers.length - 1; i++) { tableName.append(buffers[i]); tableName.append("_"); } tableName.append(partition); tableName.append("_month"); return tableName.toString(); } else if (macro.endsWith("_quarter")) { long partition = current / DatabaseConfig.QUARTER; if (partition <= 0) { partition = 1; } String[] buffers = macro.split("_"); StringBuffer tableName = new StringBuffer(); for (int i = 0; i < buffers.length - 1; i++) { tableName.append(buffers[i]); tableName.append("_"); } tableName.append(partition); tableName.append("_quarter"); return tableName.toString(); } else if (macro.endsWith("_year")) { long partition = current / DatabaseConfig.YEAR; if (partition <= 0) { partition = 1; } String[] buffers = macro.split("_"); StringBuffer tableName = new StringBuffer(); for (int i = 0; i < buffers.length - 1; i++) { tableName.append(buffers[i]); tableName.append("_"); } tableName.append(partition); tableName.append("_year"); return tableName.toString(); } else if (macro.endsWith("_decade")) { long partition = current / DatabaseConfig.DECADE; if (partition <= 0) { partition = 1; } String[] buffers = macro.split("_"); StringBuffer tableName = new StringBuffer(); for (int i = 0; i < buffers.length - 1; i++) { tableName.append(buffers[i]); tableName.append("_"); } tableName.append(partition); tableName.append("_decade"); return tableName.toString(); } if (forCharting) { if (macro.startsWith("session(") && request != null) { String keyword = macro.substring(macro.indexOf("(") + 1, macro.indexOf(")")); String[] objects = null; if (request.getSession().getAttribute(keyword) != null) { objects = ((String) request.getSession().getAttribute(keyword)).split(","); } StringBuffer buf = new StringBuffer(); boolean first = true; if (objects != null) { for (String object : objects) { if (!first) { buf.append(" or "); } first = false; buf.append( macro.substring(macro.indexOf("(") + 1, macro.indexOf(")")) + "='" + object + "'"); } return buf.toString(); } return ""; } else { String[] tableList = dbc.findTableNameForCharts(macro, start, end); StringBuffer buf = new StringBuffer(); boolean first = true; for (String table : tableList) { if (!first) { buf.append("|"); } first = false; buf.append(table); } return buf.toString(); } } String[] tableList = dbc.findTableName(macro, current, current); return tableList[0]; } public String toString() { try { HashMap<String, String> macroList = findMacros(query); Iterator<String> macroKeys = macroList.keySet().iterator(); while (macroKeys.hasNext()) { String mkey = macroKeys.next(); if (macroList.get(mkey).contains("|")) { StringBuffer buf = new StringBuffer(); String[] tableList = macroList.get(mkey).split("\\|"); boolean first = true; for (String table : tableList) { String newQuery = query.replace("[" + mkey + "]", table); if (!first) { buf.append(" union "); } buf.append("("); buf.append(newQuery); buf.append(")"); first = false; } query = buf.toString(); } else { log.debug("replacing:" + mkey + " with " + macroList.get(mkey)); query = query.replace("[" + mkey + "]", macroList.get(mkey)); } } } catch (SQLException ex) { log.error(query); log.error(ex.getMessage()); } return query; } }