Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package de.aeb.sqlscriptformater; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.io.FileUtils; /** * (!) depends on correct sql syntax in file * * @author Eugen * */ public class SqlScriptFormater { private static final Logger log = Logger.getLogger(SqlScriptFormater.class.getName()); private static final String USAGE = getUsageString(); private static final String HEADER = getHeaderString(); private static final String PREFIX = "generated_"; private static String getUsageString() { return "-------------------------------------------------------------------------------\n" + "Usage: java -jar sqlsf.jar OPERATION OPSTRING FILE/PATH [OPTIONALS]\n" + "\t\tOPERATION:\t-r/-remove | -a/-add | -e/-exists\n" + "\t\tOPSTRING:\tex. \"_lut\"\n" + "\t\tFILE/PATH:\tex.\"create.sql\" or \"C:\\scripts\\create.sql\"\n" + "\t\t[OPTIONALS]:\t-h (add HEADER) | -f (replace Generated Files)\n" + "-------------------------------------------------------------------------------\n"; } private static String getHeaderString() { return "--##############################################\n" + "--### File is generated by SQLScriptFormater ###\n" + "--##############################################\n \n"; } // OP-Parmeters --- START private File _opFile; private OperationsEnum _op; private String _opStr; public File getOpFile() { return _opFile; } public void setOpFile(File _opFile) { this._opFile = _opFile; checkParameters(); } public OperationsEnum getOp() { return _op; } public void setOp(OperationsEnum _op) { this._op = _op; checkParameters(); } public String getOpStr() { return _opStr; } public void setOpStr(String _opStr) { this._opStr = _opStr; checkParameters(); } // OP-Parmeters --- END // // Internals -- START private final ArrayList<String> _errors = new ArrayList<>(); private boolean _success = false; private boolean _parametersSet = false; private boolean _buildWithHeader = false; private boolean _replace = false; private boolean isParametersSet() { return _parametersSet; } public boolean isSuccess() { return _success; } public ArrayList<String> getErrors() { return _errors; } /** * Set before run() to skip Header in file. */ public void buildWithoutHeader() { _buildWithHeader = false; } /** * Set to replace generated Files. */ public void replaceFiles() { _replace = true; } // Internals -- END //------------------------ // Constructors //------------------------ /** * Default Constructor; use set-Methods to set parameters */ public SqlScriptFormater() { } /** * Constructor for parametric use. * * @param args String array containing the parameters in the right order. * @param verbose turns logging on or off. */ public SqlScriptFormater(String[] args, boolean verbose) { // for debugging if (verbose) { log.setLevel(Level.ALL); } else { log.setLevel(Level.OFF); } _parametersSet = extractArgs(args); } //------------------------ // Methods //------------------------ public static void printUsage() { System.out.println(USAGE); } public void printErrors() { if (_errors.size() > 0) { for (String _error : _errors) { System.out.println(_error); } } else { System.out.println("No Errors to print out!"); } } public void printStatus() { if (_success) { System.out.println("Last Operation: success"); } else { System.out.println("Last Operation: unsuccessful"); } } @Deprecated public boolean old_printFile() { boolean bOk = true; try { BufferedReader in = new BufferedReader(new FileReader(_opFile)); String line = null; int i = 1; System.out.println("Selected File " + _opFile.getName() + ":"); while ((line = in.readLine()) != null) { String formatedStr = "Line " + (i++) + ": " + line; System.out.println(formatedStr); } } catch (FileNotFoundException ex) { _errors.add("File not found: " + ex.getMessage()); return false; } catch (IOException ex) { _errors.add("IOExeption: " + ex.getMessage()); return false; } return bOk; } public boolean printFile() { boolean bOk = true; // load lines from file List<String> lines = readLinesFromFile(_opFile, "UTF-8"); if (lines != null) { int start = 0; int end = lines.size() - 1; //loop through the lines for (int index = start; index <= end; index++) { // actual line String line = lines.get(index); // Printout formated int lineNumber = index + 1; System.out.println("Line " + lineNumber + " :" + line); } } else { //lines == null bOk = false; } return bOk; } private void checkParameters() { _parametersSet = (_opFile != null && _op != null && _opStr != null); } // Methods for Parameter Extraction --- START /** * Extracts the Arguments from String[] and sets the parameters accordingly. * * @param args String[]. Valid are 3,4 or 5 Arguments. * @return Returns true if extraction was succsessful, else false. */ public boolean extractArgs(String[] args) { boolean bOk = true; // Check args length min 3 required if (args.length == 3) { bOk = extract3Args(args); } else if (args.length == 4) { bOk = extract4Args(args); } else if (args.length == 5) { bOk = extract5Args(args); } else { _errors.add("Arguments are not Vaild!"); bOk = false; } return bOk; } private OperationsEnum checkAndGetOpArg(String arg) { String op = arg.trim(); log.info("op String after trim:" + op); OperationsEnum rOp = OperationsEnum.UNSUPPORTED; if (op != "" && op != " ") { if (op.startsWith("-")) { op = op.substring(1); log.info("op shorted String:" + op); String firstLetter = ""; if (op.length() > 1) { firstLetter = op.substring(0, 1); log.info("op String first Letter:" + firstLetter); } else { firstLetter = op; } switch (firstLetter) { // op = remove case "r": { if (op.contains("remove") || op.startsWith("r")) { rOp = OperationsEnum.REMOVE; } break; } // op = add case "a": { if (op.contains("add") || op.startsWith("a")) { rOp = OperationsEnum.ADD; } break; } // op = exits case "e": { if (op.contains("exists") || op.startsWith("e")) { rOp = OperationsEnum.EXISTS; } break; } // nothing from above = false default: rOp = OperationsEnum.UNSUPPORTED; } } else { // not an operation argument _errors.add("First Argument is not an Operation, \"-\" missing."); } } else { // not a valid argument _errors.add("First Argument is empty."); } return rOp; } private boolean extract3Args(String[] args) { boolean bOk = true; // null checks if (args[0] != null && args[1] != null && args[2] != null) { // Check first argument OperationsEnum op = checkAndGetOpArg(args[0]); if (op == OperationsEnum.UNSUPPORTED) { //Return if OperationsEnum is Unsupported, no need to check the other arguments _errors.add("Unsupported Operation in first argument!"); return bOk = false; } else { _op = op; } log.info("first arg extracted. bOk=" + bOk); // Check second arg if (checkOpStrArg(args[1])) { _opStr = args[1]; } else { //Return if check failed, no need to check the other arguments _errors.add("Checks failed in second argument!"); return bOk = false; } log.info("second arg extracted. bOk=" + bOk); // Check third arg File file = checkAndGetFileArg(args[2]); if (file != null) { _opFile = file; } else { _errors.add("Checks failed in third argument!"); bOk = false; } log.info("third arg extracted. bOk=" + bOk); } else { _errors.add("Some Arguments are not Valid or null!"); bOk = false; } return bOk; } private boolean extract4Args(String[] args) { boolean bOk = true; if (args.length == 4) { if (args[3] != null) { String[] args3 = { args[0], args[1], args[2] }; bOk = extract3Args(args3); String firstOptionalArg = args[3]; setOptionalArg(firstOptionalArg); } else { bOk = false; } } else { bOk = false; } return bOk; } private boolean extract5Args(String[] args) { boolean bOk = true; if (args.length == 5) { if (args[4] != null) { String[] args4 = { args[0], args[1], args[2], args[3] }; bOk = extract4Args(args4); String secondOptionalArg = args[4]; setOptionalArg(secondOptionalArg); } else { bOk = false; } } else { bOk = false; } return bOk; } private boolean checkOpStrArg(String arg) { // Checks for second argument boolean bOk = true; String tArg = arg.trim(); // empty or blank if (tArg == "" || tArg == " ") { _errors.add("Second Argument is empty or has blanks"); bOk = false; } return bOk; } private File checkAndGetFileArg(String arg) { File sqlFile = new File(arg); try { if (sqlFile.isFile()) { if (sqlFile.exists()) { if (sqlFile.canRead()) { return sqlFile; } } } } catch (Exception e) { _errors.add("File Error: " + e.getMessage()); return null; } return null; } private void setOptionalArg(String OptionalArg) { if (OptionalArg.contains("-h") || OptionalArg.contains("-header")) { // set buildWtihHeader _buildWithHeader = true; } else if (OptionalArg.contains("-f") || OptionalArg.contains("-file")) { // set replace Generated Files _replace = true; } } // Methods for Parameter Extraction --- END @Deprecated private boolean old_runRemove() { boolean bOk = true; try { BufferedReader in = new BufferedReader(new FileReader(_opFile)); String line = null; String outStr = ""; if (_buildWithHeader) { outStr = HEADER + ""; } int i = 1; while ((line = in.readLine()) != null) { String formatedStr = "Line " + (i++) + ": " + line; log.info(formatedStr); // remove line if (line.contains(_opStr)) { // Skip that line } else { // append to Output String and add newline feed outStr += line + "\n"; } } log.info(outStr); // save generated outStr to new File bOk = saveToNewFile(outStr); if (!bOk) { _errors.add("Failed to Save to File."); } } catch (FileNotFoundException ex) { _errors.add("File Not Found!" + ex.getMessage()); return false; } catch (IOException ex) { _errors.add("IOExceptin: " + ex.getMessage()); return false; } return bOk; } /** * Runs the Remove Operation. With some Case checks. * * @return true if succssesful, false if not */ private boolean runRemove() { boolean bOk = true; // load lines from file List<String> lines = readLinesFromFile(_opFile, "UTF-8"); // Format lines if (lines != null) { // apply Case Checks runRemoveCaseChecks(lines); // add header if (_buildWithHeader) { lines.addAll(0, Arrays.asList(HEADER.split("\n"))); } // save lines to file bOk = saveToNewFile(lines); if (!bOk) { _errors.add("Failed to Save to File."); } } else { //lines == null bOk = false; } return bOk; } private boolean runAdd() { _errors.add("Add Operation not implemented"); return false; } private boolean runExists() { _errors.add("Exists Operation not implemented"); return false; } /** * Run an Operation on a file. For non parametic use. * * @param opFile File object (*.sql) * @param op Operation to run. * @param opStr String needed for that Operation. * @return true if succssesful, false if not */ public boolean runOnFile(File opFile, OperationsEnum op, String opStr) { boolean bOk = true; if (opFile != null && op != null && opStr != null) { _opFile = opFile; _opStr = opStr; switch (op) { case ADD: bOk = runAdd(); break; case REMOVE: bOk = runRemove(); break; case EXISTS: bOk = runExists(); break; case UNSUPPORTED: _errors.add("Unsupported Operation detected. Can not run!"); bOk = false; break; default: bOk = false; } } else { _errors.add("Parameters invalid, some are probably null!"); bOk = false; } // set succsess if operation was succsessful (bOk is true) if (bOk) { _success = true; } return bOk; } /** * Runs the Operation set in the parameters. * * @return true if succssesful, false if not */ public boolean run() { if (isParametersSet()) { return runOnFile(_opFile, _op, _opStr); } else { _errors.add("No Parameters set!"); return false; } } private boolean saveToNewFile(String outStr) { boolean bOk = true; // new prefixed File File newFile = new File(buildPrefixedFilepath()); try { if (_replace) { if (newFile.exists()) { newFile.delete(); } } if (newFile.createNewFile()) { if (newFile.isFile()) { bOk = writeStringToFile(newFile, outStr); } else { bOk = false; } } else { _errors.add("A generated file already exists! Delete that and run again."); bOk = false; } } catch (IOException ex) { _errors.add("Failed to create new File: " + ex.getMessage()); return false; } return bOk; } private boolean saveToNewFile(List<String> lines) { boolean bOk = true; // new prefixed File File newFile = new File(buildPrefixedFilepath()); try { if (_replace) { if (newFile.exists()) { newFile.delete(); } } if (newFile.createNewFile()) { if (newFile.isFile()) { bOk = writeListToFile(newFile, lines); } else { bOk = false; } } else { _errors.add("A generated file already exists! Delete that and run again."); bOk = false; } } catch (IOException ex) { _errors.add("Failed to create new File: " + ex.getMessage()); return false; } return bOk; } private String buildPrefixedFilepath() { String filepath = _opFile.getAbsolutePath(); String oldname = _opFile.getName(); //add prefix String newname = PREFIX + _opFile.getName(); return filepath.replace(oldname, newname); } private List<String> readLinesFromFile(File file, String charset) { if (file != null) { List<String> lines = null; if (charset == null) { charset = "UTF-8"; } try { lines = FileUtils.readLines(file, charset); } catch (IOException ex) { _errors.add("IOExceptin: " + ex.getMessage()); return null; } return lines; } else { return null; } } private boolean writeStringToFile(File newFile, String outStr) { boolean bOk = true; if (newFile != null) { try { FileUtils.writeStringToFile(newFile, outStr, "UTF-8"); } catch (IOException ex) { _errors.add("Failed to write to File: " + ex.getMessage()); return false; } } else { bOk = false; } return bOk; } private boolean writeListToFile(File newFile, List<String> lines) { boolean bOk = true; if (newFile != null) { try { FileUtils.writeLines(newFile, lines); } catch (IOException ex) { _errors.add("Failed to write to File: " + ex.getMessage()); return false; } } else { bOk = false; } return bOk; } private void runRemoveCaseChecks(List<String> lines) { int start = 0; int end = lines.size() - 1; // Contains check for lower and upper Cases String opUpper = _opStr.toUpperCase(); String opLower = _opStr.toLowerCase(); //loop through the lines for (int index = start; index <= end; index++) { // actual line String line = lines.get(index); if (!line.isEmpty()) { if (line.contains(opUpper) || line.contains(opLower)) { // line contains opStr and needs formating // one liner? if (index > start) { // not in first line? -> check comma String previousLine = lines.get(index - 1); if (previousLine.contains(",")) { if (previousLine.endsWith(",")) { // index = last line? if (index == end) { // last line // case: ....., // ...opStr... ); // remove everything before LAST ")", line can contain multiple ")" int lastCloser = line.lastIndexOf(")"); if (lastCloser < line.length()) { String newLine = line.substring(lastCloser, line.length()); lines.set(index, newLine); } // remove , from previous line String newLine = previousLine.substring(0, previousLine.length() - 1); lines.set(index - 1, newLine); } else if (index == end - 1) { // on second last line // case: ......., // ...opStr.., // ); // remove , from previous line String newLine = previousLine.substring(0, previousLine.length() - 1); lines.set(index - 1, newLine); // now save to remove index line lines.remove(index); end = lines.size() - 1; } else { // index != lastLine && != secondlastLine // case: ....., // ...opStr.., // ...... // save to remove index line lines.remove(index); end = lines.size() - 1; } } else { // previousLine does not end with , // Case: ... , ... // ...opStr... // -> syntax error? // TODO add code } } else if (previousLine.endsWith("(")) { // previousLine has no comma, ends with ( // case : ... ( // ...opStr.. // save to remove index line lines.remove(index); end = lines.size() - 1; } else if (line.startsWith("(")) { // Case : ..... // ( ...opStr ... // remove "...opStr..." but leave "(" lines.set(index, line.substring(0, 1)); } else if (line.contains("(")) { // Case : "... ( ...opStr ..." on same line int firstOpener = line.indexOf("("); if (firstOpener < line.length()) { //remove everything behind "(" String newLine = line.substring(0, firstOpener + 1); lines.set(index, newLine); } } else { } } else if (line.contains("(")) { // first line (index = 0) -> one liner or opStr in first line //----------------------------------------------------------- if (line.startsWith("(")) { // Case : "( ...opStr ..." // remove "...opStr..." but leave "(" lines.set(index, line.substring(0, 1)); } else { // Case : "... ( ...opStr ..." on same line int firstOpener = line.indexOf("("); if (firstOpener < line.length()) { //remove everything behind "(" String newLine = line.substring(0, firstOpener + 1); lines.set(index, newLine); } } } else { // one liner that contains ...opStr... and no opener // this case cant be -> syntax error // add empty line, just in case lines.set(index, " "); } } else { // line does not contain opStr // do nothing } } else { // line is empty // remove empty lines // lines.remove(index); // end = lines.size() - 1; } } } }