Java tutorial
/** * Copyright 2011-2015 Asakusa Framework Team. * * 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. */ package com.asakusafw.dmdl.thundergate; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.text.MessageFormat; import java.util.Arrays; import java.util.List; import java.util.Properties; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import org.apache.commons.cli.BasicParser; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.asakusafw.dmdl.model.AstLiteral; import com.asakusafw.dmdl.parser.DmdlParser; import com.asakusafw.dmdl.parser.DmdlSyntaxException; /** * * @since 0.2.0 * @version 0.6.1 */ public final class Main { static final Logger LOG = LoggerFactory.getLogger(Main.class); private static final Option OPT_OUTPUT; private static final Option OPT_JDBC_CONFIG; private static final Option OPT_ENCODING; private static final Option OPT_INCLUDES; private static final Option OPT_EXCLUDES; private static final Option OPT_SID_COLUMN; private static final Option OPT_TIMESTAMP_COLUMN; private static final Option OPT_DELETE_FLAG_COLUMN; private static final Option OPT_DELETE_FLAG_VALUE; private static final Option OPT_RECORD_LOCK_DDL_OUTPUT; private static final Options OPTIONS; static { OPT_JDBC_CONFIG = new Option("jdbc", true, "??JDBC"); OPT_JDBC_CONFIG.setArgName("/path/to/jdbc-config.properties"); OPT_JDBC_CONFIG.setRequired(true); OPT_OUTPUT = new Option("output", true, "????"); OPT_OUTPUT.setArgName("/path/to/output"); OPT_OUTPUT.setRequired(true); OPT_ENCODING = new Option("encoding", true, "?"); OPT_ENCODING.setArgName("encoding"); OPT_ENCODING.setRequired(false); OPT_INCLUDES = new Option("includes", true, "??/?????"); OPT_INCLUDES.setArgName("inclusion-regex"); OPT_INCLUDES.setRequired(false); OPT_EXCLUDES = new Option("excludes", true, "??/?????"); OPT_EXCLUDES.setArgName("exclusion-regex"); OPT_EXCLUDES.setRequired(false); OPT_SID_COLUMN = new Option("sid_column", true, "System ID???"); OPT_SID_COLUMN.setArgName("SID"); OPT_SID_COLUMN.setRequired(false); OPT_TIMESTAMP_COLUMN = new Option("timestamp_column", true, "???"); OPT_TIMESTAMP_COLUMN.setArgName("LAST_UPDATED_DATETIME"); OPT_TIMESTAMP_COLUMN.setRequired(false); OPT_DELETE_FLAG_COLUMN = new Option("delete_flag_column", true, "????"); OPT_DELETE_FLAG_COLUMN.setArgName("LOGICAL_DELETE_FLAG"); OPT_DELETE_FLAG_COLUMN.setRequired(false); OPT_DELETE_FLAG_VALUE = new Option("delete_flag_value", true, "??(TRUE)?? (Java?)"); OPT_DELETE_FLAG_VALUE.setArgName("1"); OPT_DELETE_FLAG_VALUE.setRequired(false); OPT_RECORD_LOCK_DDL_OUTPUT = new Option("record_lock_ddl_output", true, "???DDL??"); OPT_RECORD_LOCK_DDL_OUTPUT.setArgName("/path/to/output.sql"); OPT_RECORD_LOCK_DDL_OUTPUT.setRequired(false); OPTIONS = new Options(); OPTIONS.addOption(OPT_OUTPUT); OPTIONS.addOption(OPT_JDBC_CONFIG); OPTIONS.addOption(OPT_ENCODING); OPTIONS.addOption(OPT_INCLUDES); OPTIONS.addOption(OPT_EXCLUDES); OPTIONS.addOption(OPT_SID_COLUMN); OPTIONS.addOption(OPT_TIMESTAMP_COLUMN); OPTIONS.addOption(OPT_DELETE_FLAG_COLUMN); OPTIONS.addOption(OPT_DELETE_FLAG_VALUE); OPTIONS.addOption(OPT_RECORD_LOCK_DDL_OUTPUT); } private Main() { return; } /** * ??? * @param args ??????????? */ public static void main(String... args) { GenerateTask task; try { Configuration conf = loadConfigurationFromArguments(args); task = new GenerateTask(conf); } catch (Exception e) { HelpFormatter formatter = new HelpFormatter(); formatter.setWidth(Integer.MAX_VALUE); formatter.printHelp(MessageFormat.format("java -classpath ... {0}", Main.class.getName()), OPTIONS, true); e.printStackTrace(System.out); System.exit(1); return; } try { task.call(); } catch (Exception e) { e.printStackTrace(System.out); System.exit(1); return; } } /** * ?? * @param args ? * @return ?? * @throws IllegalStateException ???? */ public static Configuration loadConfigurationFromArguments(String[] args) { assert args != null; CommandLineParser parser = new BasicParser(); CommandLine cmd; try { cmd = parser.parse(OPTIONS, args); } catch (ParseException e) { throw new IllegalStateException(e); } Configuration result = new Configuration(); String jdbc = getOption(cmd, OPT_JDBC_CONFIG, true); try { Properties jdbcProps = loadProperties(jdbc); result.setJdbcDriver(findProperty(jdbcProps, Constants.K_JDBC_DRIVER)); result.setJdbcUrl(findProperty(jdbcProps, Constants.K_JDBC_URL)); result.setJdbcUser(findProperty(jdbcProps, Constants.K_JDBC_USER)); result.setJdbcPassword(findProperty(jdbcProps, Constants.K_JDBC_PASSWORD)); result.setDatabaseName(findProperty(jdbcProps, Constants.K_DATABASE_NAME)); LOG.info("JDBC??????: {}", jdbcProps); } catch (IOException e) { throw new IllegalStateException( MessageFormat.format("JDBC?????????: -{0}={1}", OPT_JDBC_CONFIG.getOpt(), jdbc), e); } String output = getOption(cmd, OPT_OUTPUT, true); result.setOutput(new File(output)); LOG.info("Output: {}", output); String includes = getOption(cmd, OPT_INCLUDES, false); if (includes != null && includes.isEmpty() == false) { try { Pattern pattern = Pattern.compile(includes, Pattern.CASE_INSENSITIVE); result.setMatcher(new ModelMatcher.Regex(pattern)); LOG.info("Inclusion: {}", pattern); } catch (PatternSyntaxException e) { throw new IllegalArgumentException(MessageFormat .format("??????????: {0}", includes), e); } } else { result.setMatcher(ModelMatcher.ALL); } String excludes = getOption(cmd, OPT_EXCLUDES, false); if (excludes != null && excludes.isEmpty() == false) { try { Pattern pattern = Pattern.compile(excludes, Pattern.CASE_INSENSITIVE); result.setMatcher(new ModelMatcher.And(result.getMatcher(), new ModelMatcher.Not(new ModelMatcher.ConstantTable(Constants.SYSTEM_TABLE_NAMES)), new ModelMatcher.Not(new ModelMatcher.Regex(pattern)))); LOG.info("Exclusion: {}", pattern); } catch (PatternSyntaxException e) { throw new IllegalArgumentException(MessageFormat .format("??????????: {0}", excludes), e); } } else { result.setMatcher(new ModelMatcher.And(result.getMatcher(), new ModelMatcher.Not(new ModelMatcher.ConstantTable(Constants.SYSTEM_TABLE_NAMES)))); } String encoding = getOption(cmd, OPT_ENCODING, false); if (encoding != null) { try { Charset charset = Charset.forName(encoding); result.setEncoding(charset); LOG.info("Encoding: {}", charset); } catch (Exception e) { result.setEncoding(Constants.OUTPUT_ENCODING); } } else { result.setEncoding(Constants.OUTPUT_ENCODING); } checkIf(cmd, OPT_SID_COLUMN, OPT_TIMESTAMP_COLUMN); checkIf(cmd, OPT_TIMESTAMP_COLUMN, OPT_SID_COLUMN); checkIf(cmd, OPT_SID_COLUMN, OPT_DELETE_FLAG_COLUMN); checkIf(cmd, OPT_SID_COLUMN, OPT_DELETE_FLAG_VALUE); checkIf(cmd, OPT_DELETE_FLAG_COLUMN, OPT_DELETE_FLAG_VALUE); checkIf(cmd, OPT_DELETE_FLAG_VALUE, OPT_DELETE_FLAG_COLUMN); String sidColumn = trim(getOption(cmd, OPT_SID_COLUMN, false)); String timestampColumn = trim(getOption(cmd, OPT_TIMESTAMP_COLUMN, false)); String deleteFlagColumn = trim(getOption(cmd, OPT_DELETE_FLAG_COLUMN, false)); String deleteFlagValue = trim(getOption(cmd, OPT_DELETE_FLAG_VALUE, false)); if (deleteFlagValue != null) { // FIXME get "bare" string List<String> arguments = Arrays.asList(args); int index = arguments.indexOf('-' + OPT_DELETE_FLAG_VALUE.getOpt()); assert index >= 0; assert arguments.size() > index + 1; deleteFlagValue = trim(arguments.get(index + 1)); } result.setSidColumn(sidColumn); result.setTimestampColumn(timestampColumn); result.setDeleteFlagColumn(deleteFlagColumn); if (deleteFlagValue != null) { try { DmdlParser dmdl = new DmdlParser(); AstLiteral literal = dmdl.parseLiteral(deleteFlagValue); result.setDeleteFlagValue(literal); } catch (DmdlSyntaxException e) { throw new IllegalArgumentException(MessageFormat.format( "???Java???????????: {0}", deleteFlagValue), e); } } String recordLockDdlOutput = getOption(cmd, OPT_RECORD_LOCK_DDL_OUTPUT, false); if (recordLockDdlOutput != null) { result.setRecordLockDdlOutput(new File(recordLockDdlOutput)); } return result; } private static void checkIf(CommandLine cmd, Option target, Option condition) { String conditionValue = getOption(cmd, condition, false); if (trim(conditionValue) == null) { return; } String targetValue = getOption(cmd, target, false); if (trim(targetValue) == null) { throw new IllegalArgumentException(MessageFormat.format( " \"-{0}\" ?????? (\"-{1}\"?????)", target.getOpt(), condition.getOpt())); } } private static String trim(String string) { if (string == null) { return null; } String trimmed = string.trim(); if (trimmed.isEmpty()) { return null; } return trimmed; } private static String getOption(CommandLine cmd, Option option, boolean mandatory) { assert cmd != null; assert option != null; String value = cmd.getOptionValue(option.getOpt()); if (mandatory && value == null) { throw new IllegalStateException(MessageFormat .format("\"{0}\"??????", option.getOpt())); } LOG.debug("Option: {}={}", option.getOpt(), value); return value; } private static Properties loadProperties(String path) throws IOException { assert path != null; LOG.debug("Loading Properties: {}", path); InputStream in = new FileInputStream(path); try { Properties result = new Properties(); result.load(in); return result; } finally { in.close(); } } private static String findProperty(Properties properties, String key) { assert properties != null; assert key != null; LOG.debug("Finding Property: {}", key); String value = properties.getProperty(key); if (value == null) { throw new IllegalStateException( MessageFormat.format("\"{0}\"??????", key)); } return value; } }