001/* 002 * #%L 003 * Netarchivesuite - common 004 * %% 005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library, 006 * the National Library of France and the Austrian National Library. 007 * %% 008 * This program is free software: you can redistribute it and/or modify 009 * it under the terms of the GNU Lesser General Public License as 010 * published by the Free Software Foundation, either version 2.1 of the 011 * License, or (at your option) any later version. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Lesser Public License for more details. 017 * 018 * You should have received a copy of the GNU General Lesser Public 019 * License along with this program. If not, see 020 * <http://www.gnu.org/licenses/lgpl-2.1.html>. 021 * #L% 022 */ 023 024package dk.netarkivet.common.tools; 025 026import dk.netarkivet.common.utils.ExceptionUtils; 027 028/** 029 * A simple class that manages and runs an implementation of SimpleCmdlineTool. The class contains an abstract factory 030 * method, which will create the actual implementation when specialized. This could also have been done with generics, 031 * but this is the traditional implementation. 032 */ 033public abstract class ToolRunnerBase { 034 035 /** 036 * Factory method. Creates and returns the intended specific implementation of a command line tool. 037 * 038 * @return An implementation of the SimpleCmdlineTool interface. 039 */ 040 protected abstract SimpleCmdlineTool makeMyTool(); 041 042 /** 043 * Consolidates that behavior on error is System.exit(1) (exit with failure). 044 */ 045 private void exitWithFailure() { 046 System.exit(1); 047 } 048 049 /** 050 * A template method implementing default behaviour for showing a message (send to stderr). Can be overridden to 051 * ensure logging. 052 * 053 * @param msg The message to display 054 */ 055 protected void showMessage(String msg) { 056 System.err.println(msg); 057 } 058 059 /** 060 * Passes (command line) parameters to the tool. If an error occured (internalRunTool returned false), exit with 061 * failure. 062 * 063 * @param args Usually a straight passing of the command line parameters from a "main" method. 064 */ 065 public void runTheTool(String... args) { 066 if (!internalRunTheTool(args)) { 067 exitWithFailure(); 068 } 069 System.exit(0); 070 } 071 072 // Private methods follow for doing setup, run and teardown with rudimentary 073 // handling of exceptions. Split up in several methods for clarity. 074 075 private boolean runIt(SimpleCmdlineTool tool, String... args) { 076 try { 077 tool.run(args); 078 } catch (Exception e) { 079 exceptionMessage("An error occurred during processing.", e); 080 return false; 081 } 082 return true; 083 } 084 085 private boolean setupAndRunIt(SimpleCmdlineTool tool, String... args) { 086 try { 087 tool.setUp(args); 088 runIt(tool, args); 089 return true; 090 } catch (Exception e) { 091 exceptionMessage("An error occurred during setup of tool.", e); 092 return false; 093 } finally { 094 tool.tearDown(); 095 } 096 } 097 098 private boolean checkArgsSetupAndRun(SimpleCmdlineTool tool, String... args) { 099 try { 100 if (!tool.checkArgs(args)) { 101 usage(tool); 102 return false; 103 } 104 return setupAndRunIt(tool, args); 105 } catch (Exception e) { 106 exceptionMessage("Couldn't check parameters for tool.", e); 107 return false; 108 } 109 } 110 111 private boolean internalRunTheTool(String... args) { 112 try { 113 SimpleCmdlineTool tool = makeMyTool(); 114 return checkArgsSetupAndRun(tool, args); 115 } catch (Exception e) { 116 exceptionMessage("Couldn't create the tool to run!", e); 117 return false; 118 } 119 } 120 121 /** 122 * Prints usage, delegating the actual parameter description to the tool. 123 * 124 * @param tool The tool that we have specialized this class to. Know how to run and how to describe itself. 125 */ 126 private void usage(SimpleCmdlineTool tool) { 127 showMessage("Usage: java " + this.getClass().getName() + " " + tool.listParameters()); 128 exitWithFailure(); 129 } 130 131 /** 132 * Centralized, rudimentary exception handling. Only option is to print a message, and a stack trace. 133 * 134 * @param msg A message from the tool manager (this class), notifying the user about where the exception occurred. 135 * @param e The exception that occurred. 136 */ 137 private void exceptionMessage(String msg, Exception e) { 138 showMessage(msg); 139 showMessage("Output (if any) is not OK"); 140 showMessage("Exception message is:"); 141 showMessage(e.getMessage()); 142 showMessage("Stack trace:"); 143 showMessage(ExceptionUtils.getStackTrace(e)); 144 exitWithFailure(); 145 } 146 147}