java/sql-dk/src/info/globalcode/sql/dk/InfoLister.java
branchv_0
changeset 69 0befec5034c2
parent 67 10c9b9e54622
child 70 02c8eaa425e8
equal deleted inserted replaced
68:574cd7fbb5b2 69:0befec5034c2
    21 import info.globalcode.sql.dk.configuration.ConfigurationException;
    21 import info.globalcode.sql.dk.configuration.ConfigurationException;
    22 import info.globalcode.sql.dk.configuration.ConfigurationProvider;
    22 import info.globalcode.sql.dk.configuration.ConfigurationProvider;
    23 import info.globalcode.sql.dk.configuration.DatabaseDefinition;
    23 import info.globalcode.sql.dk.configuration.DatabaseDefinition;
    24 import info.globalcode.sql.dk.configuration.FormatterDefinition;
    24 import info.globalcode.sql.dk.configuration.FormatterDefinition;
    25 import static info.globalcode.sql.dk.Functions.rpad;
    25 import static info.globalcode.sql.dk.Functions.rpad;
       
    26 import info.globalcode.sql.dk.formatting.ColumnsHeader;
       
    27 import info.globalcode.sql.dk.formatting.Formatter;
       
    28 import info.globalcode.sql.dk.formatting.FormatterContext;
       
    29 import info.globalcode.sql.dk.formatting.FormatterException;
    26 import java.io.BufferedReader;
    30 import java.io.BufferedReader;
    27 import java.io.InputStreamReader;
    31 import java.io.InputStreamReader;
    28 import java.io.PrintStream;
    32 import java.io.PrintStream;
    29 import java.sql.SQLException;
    33 import java.sql.SQLException;
    30 import java.util.EnumSet;
       
    31 import java.util.List;
    34 import java.util.List;
    32 import java.util.logging.Level;
    35 import java.util.logging.Level;
    33 import java.util.logging.Logger;
    36 import java.util.logging.Logger;
       
    37 import javax.sql.rowset.RowSetMetaDataImpl;
    34 
    38 
    35 /**
    39 /**
    36  * Displays info like help, version etc.
    40  * Displays info like help, version etc.
    37  *
    41  *
    38  * @author Ing. František Kučera (frantovo.cz)
    42  * @author Ing. František Kučera (frantovo.cz)
    40 public class InfoLister {
    44 public class InfoLister {
    41 
    45 
    42 	private static final Logger log = Logger.getLogger(InfoLister.class.getName());
    46 	private static final Logger log = Logger.getLogger(InfoLister.class.getName());
    43 	private PrintStream out;
    47 	private PrintStream out;
    44 	private ConfigurationProvider configurationProvider;
    48 	private ConfigurationProvider configurationProvider;
    45 
    49 	private CLIOptions options;
    46 	public InfoLister(PrintStream out, ConfigurationProvider configurationProvider) {
    50 
       
    51 	public InfoLister(PrintStream out, ConfigurationProvider configurationProvider, CLIOptions options) {
    47 		this.out = out;
    52 		this.out = out;
    48 		this.configurationProvider = configurationProvider;
    53 		this.configurationProvider = configurationProvider;
    49 	}
    54 		this.options = options;
    50 
    55 	}
    51 	public void showInfo(CLIOptions options) throws ConfigurationException {
    56 
    52 		EnumSet<CLIOptions.INFO_TYPE> infoTypes = options.getShowInfo();
    57 	public void listFormatters() throws ConfigurationException {
    53 		for (CLIOptions.INFO_TYPE infoType : infoTypes) {
    58 		for (FormatterDefinition fd : configurationProvider.getConfiguration().getBuildInFormatters()) {
    54 			switch (infoType) {
    59 			log.log(Level.INFO, "Built-in formatter:   {0} implemented by class: {1}", new Object[]{rpad(fd.getName(), 16), fd.getClassName()});
    55 				/**
    60 		}
    56 				 * TODO: implement show info
    61 		List<FormatterDefinition> configuredFormatters = configurationProvider.getConfiguration().getFormatters();
    57 				 */
    62 		for (FormatterDefinition fd : configuredFormatters) {
    58 				case FORMATTERS:
    63 			log.log(Level.INFO, "Configured formatter: {0} implemented by class: {1}", new Object[]{rpad(fd.getName(), 16), fd.getClassName()});
    59 					for (FormatterDefinition fd : configurationProvider.getConfiguration().getBuildInFormatters()) {
    64 		}
    60 						log.log(Level.INFO, "Built-in formatter:   {0} implemented by class: {1}", new Object[]{rpad(fd.getName(), 16), fd.getClassName()});
    65 		if (configuredFormatters.isEmpty()) {
    61 					}
    66 			log.log(Level.INFO, "No other formatters are configured");
    62 
    67 		}
    63 					List<FormatterDefinition> configuredFormatters = configurationProvider.getConfiguration().getFormatters();
    68 		String configuredDefaultFormatter = configurationProvider.getConfiguration().getDefaultFormatter();
    64 					for (FormatterDefinition fd : configuredFormatters) {
    69 		if (configuredDefaultFormatter == null) {
    65 						log.log(Level.INFO, "Configured formatter: {0} implemented by class: {1}", new Object[]{rpad(fd.getName(), 16), fd.getClassName()});
    70 			log.log(Level.INFO, "Built-in default formatter: {0}", Configuration.DEFAULT_FORMATTER);
    66 					}
    71 		} else {
    67 					if (configuredFormatters.isEmpty()) {
    72 			log.log(Level.INFO, "Configured default formatter: {0}", configuredDefaultFormatter);
    68 						log.log(Level.INFO, "No other formatters are configured");
    73 		}
    69 					}
    74 	}
    70 
    75 
    71 					String configuredDefaultFormatter = configurationProvider.getConfiguration().getDefaultFormatter();
    76 	public void listTypes() throws FormatterException {
    72 					if (configuredDefaultFormatter == null) {
    77 	}
    73 						log.log(Level.INFO, "Built-in default formatter: {0}", Configuration.DEFAULT_FORMATTER);
    78 
    74 					} else {
    79 	public void listDatabases() throws ConfigurationException {
    75 						log.log(Level.INFO, "Configured default formatter: {0}", configuredDefaultFormatter);
    80 		final List<DatabaseDefinition> configuredDatabases = configurationProvider.getConfiguration().getDatabases();
    76 					}
    81 		if (configuredDatabases.isEmpty()) {
    77 					break;
    82 			log.log(Level.WARNING, "No databases are configured.");
    78 				case HELP:
    83 		} else {
    79 					printResource(Constants.HELP_FILE);
    84 			for (DatabaseDefinition dd : configuredDatabases) {
    80 					break;
    85 				log.log(Level.INFO, "Configured database: {0}", dd.getName());
    81 				case LICENSE:
    86 			}
    82 					printResource(Constants.LICENSE_FILE);
    87 		}
    83 					break;
    88 	}
    84 				case TYPES:
    89 
    85 					println("TODO: list supported types");
    90 	public void testConnection() {
    86 					break;
    91 		boolean connectionTestResult = false;
    87 				case VERSION:
    92 		String dbName = options.getDatabaseNameToTest();
    88 					printResource(Constants.VERSION_FILE);
    93 		log.log(Level.FINE, "Testing connection to database: {0}", dbName);
    89 					break;
    94 		try {
    90 				case DATABASES:
    95 			DatabaseDefinition dd = configurationProvider.getConfiguration().getDatabase(dbName);
    91 					final List<DatabaseDefinition> configuredDatabases = configurationProvider.getConfiguration().getDatabases();
    96 			if (dd == null) {
    92 					if (configuredDatabases.isEmpty()) {
    97 				log.log(Level.SEVERE, "No database with this name is configured: {0}", dbName);
    93 						log.log(Level.WARNING, "No databases are configured.");
    98 			} else {
    94 					} else {
    99 				log.log(Level.FINE, "Database definition was loaded from configuration");
    95 						for (DatabaseDefinition dd : configuredDatabases) {
   100 				DatabaseConnection dc = dd.connect();
    96 							log.log(Level.INFO, "Configured database: {0}", dd.getName());
   101 				connectionTestResult = dc.test();
    97 						}
   102 			}
    98 					}
   103 		} catch (ConfigurationException | SQLException e) {
    99 					break;
   104 			log.log(Level.SEVERE, "Error during testing connection", e);
   100 				case CONNECTION:
   105 		}
   101 					boolean connectionTestResult = false;
   106 		log.log(Level.INFO, "Connection test result: {0}", connectionTestResult ? "success" : "failure");
   102 					String dbName = options.getDatabaseNameToTest();
   107 	}
   103 					log.log(Level.FINE, "Testing connection to database: {0}", dbName);
   108 
   104 					try {
   109 	public void printResource(String fileName) {
   105 						DatabaseDefinition dd = configurationProvider.getConfiguration().getDatabase(dbName);
       
   106 						if (dd == null) {
       
   107 							log.log(Level.SEVERE, "No database with this name is configured: {0}", dbName);
       
   108 						} else {
       
   109 							log.log(Level.FINE, "Database definition was loaded from configuration");
       
   110 							DatabaseConnection dc = dd.connect();
       
   111 							connectionTestResult = dc.test();
       
   112 						}
       
   113 					} catch (ConfigurationException | SQLException e) {
       
   114 						log.log(Level.SEVERE, "Error during testing connection", e);
       
   115 					}
       
   116 					log.log(Level.INFO, "Connection test result: {0}", connectionTestResult ? "success" : "failure");
       
   117 					break;
       
   118 				default:
       
   119 					throw new IllegalArgumentException("Unsupported INFO_TYPE: " + infoType);
       
   120 			}
       
   121 		}
       
   122 	}
       
   123 
       
   124 	private void printResource(String fileName) {
       
   125 		try (BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getClassLoader().getResourceAsStream(fileName)))) {
   110 		try (BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getClassLoader().getResourceAsStream(fileName)))) {
   126 			while (true) {
   111 			while (true) {
   127 				String line = reader.readLine();
   112 				String line = reader.readLine();
   128 				if (line == null) {
   113 				if (line == null) {
   129 					break;
   114 					break;
   137 	}
   122 	}
   138 
   123 
   139 	private void println(String line) {
   124 	private void println(String line) {
   140 		out.println(line);
   125 		out.println(line);
   141 	}
   126 	}
       
   127 
       
   128 	private void printTable(Formatter formatter, ColumnsHeader header, List<Object[]> data) throws ConfigurationException, FormatterException {
       
   129 		formatter.writeStartResultSet();
       
   130 		formatter.writeColumnsHeader(header);
       
   131 
       
   132 		for (Object[] row : data) {
       
   133 			formatter.writeStartRow();
       
   134 			for (Object cell : row) {
       
   135 				formatter.writeColumnValue(cell);
       
   136 			}
       
   137 			formatter.writeEndRow();
       
   138 		}
       
   139 
       
   140 		formatter.writeEndResultSet();
       
   141 	}
       
   142 
       
   143 	private Formatter getFormatter() throws ConfigurationException, FormatterException {
       
   144 		FormatterDefinition fd = configurationProvider.getConfiguration().getFormatter(options.getFormatterName());
       
   145 		FormatterContext context = new FormatterContext(out);
       
   146 		return fd.getInstance(context);
       
   147 	}
       
   148 
       
   149 	private ColumnsHeader constructHeader(HeaderField... fields) throws FormatterException {
       
   150 		try {
       
   151 			RowSetMetaDataImpl metaData = new RowSetMetaDataImpl();
       
   152 			metaData.setColumnCount(fields.length);
       
   153 
       
   154 			for (int i = 0; i < fields.length; i++) {
       
   155 				HeaderField hf = fields[i];
       
   156 				int sqlIndex = i + 1;
       
   157 				metaData.setColumnName(sqlIndex, hf.name);
       
   158 				metaData.setColumnLabel(sqlIndex, hf.name);
       
   159 				metaData.setColumnType(sqlIndex, hf.type.getCode());
       
   160 				metaData.setColumnTypeName(sqlIndex, hf.type.name());
       
   161 			}
       
   162 
       
   163 			return new ColumnsHeader(metaData);
       
   164 		} catch (SQLException e) {
       
   165 			throw new FormatterException("Error while constructing table headers", e);
       
   166 		}
       
   167 	}
       
   168 
       
   169 	private static class HeaderField {
       
   170 
       
   171 		String name;
       
   172 		SQLType type;
       
   173 
       
   174 		public HeaderField(String name, SQLType type) {
       
   175 			this.name = name;
       
   176 			this.type = type;
       
   177 		}
       
   178 	}
       
   179 
       
   180 	public enum InfoType {
       
   181 
       
   182 		HELP {
       
   183 			@Override
       
   184 			public void showInfo(InfoLister infoLister) {
       
   185 				infoLister.printResource(Constants.HELP_FILE);
       
   186 			}
       
   187 		},
       
   188 		VERSION {
       
   189 			@Override
       
   190 			public void showInfo(InfoLister infoLister) {
       
   191 				infoLister.printResource(Constants.VERSION_FILE);
       
   192 			}
       
   193 		},
       
   194 		LICENSE {
       
   195 			@Override
       
   196 			public void showInfo(InfoLister infoLister) {
       
   197 				infoLister.printResource(Constants.LICENSE_FILE);
       
   198 			}
       
   199 		},
       
   200 		FORMATTERS {
       
   201 			@Override
       
   202 			public void showInfo(InfoLister infoLister) throws ConfigurationException {
       
   203 				infoLister.listFormatters();
       
   204 			}
       
   205 		},
       
   206 		TYPES {
       
   207 			@Override
       
   208 			public void showInfo(InfoLister infoLister) throws FormatterException {
       
   209 				infoLister.listTypes();
       
   210 			}
       
   211 		},
       
   212 		DATABASES {
       
   213 			@Override
       
   214 			public void showInfo(InfoLister infoLister) throws ConfigurationException {
       
   215 				infoLister.listDatabases();
       
   216 			}
       
   217 		},
       
   218 		CONNECTION {
       
   219 			@Override
       
   220 			public void showInfo(InfoLister infoLister) {
       
   221 				infoLister.testConnection();
       
   222 			}
       
   223 		};
       
   224 
       
   225 		public abstract void showInfo(InfoLister infoLister) throws ConfigurationException, FormatterException;
       
   226 	}
   142 }
   227 }