Java tutorial
/******************************************************************************* * Copyright (c) 2010-2011 VIVO Harvester Team. For full list of contributors, please see the AUTHORS file provided. * All rights reserved. * This program and the accompanying materials are made available under the terms of the new BSD license which accompanies this distribution, and is available at http://www.opensource.org/licenses/bsd-license.html ******************************************************************************/ package org.vivoweb.harvester.fetch; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.vivoweb.harvester.util.InitLog; import org.vivoweb.harvester.util.SpecialEntities; import org.vivoweb.harvester.util.args.ArgDef; import org.vivoweb.harvester.util.args.ArgList; import org.vivoweb.harvester.util.args.ArgParser; import org.vivoweb.harvester.util.args.UsageException; import org.vivoweb.harvester.util.repo.RecordHandler; /** * Fetches rdf data from a JDBC database placing the data in the supplied record handler. * @author Christopher Haines (hainesc@ctrip.ufl.edu) */ public class JDBCFetch { /** * SLF4J Logger */ private static Logger log = LoggerFactory.getLogger(JDBCFetch.class); /** * Record Handler to write records to */ private RecordHandler rh; /** * Statement processor for the database */ private Statement cursor; /** * Mapping of tablename to idField name */ private Map<String, List<String>> idFields = null; /** * Mapping of tablename to mapping of fieldname to tablename */ private Map<String, Map<String, String>> fkRelations = null; /** * Mapping of tablename to list of datafields */ private Map<String, List<String>> dataFields = null; /** * Set of table names */ private Set<String> tableNames = null; /** * List of conditions */ private Map<String, List<String>> whereClauses; /** * Mapping of extra tables for the from section */ private Map<String, String> fromClauses; /** * Namespace for RDF made from this database */ private String uriNS; /** * Prefix each field in query with this */ private String queryPre; /** * Suffix each field in query with this */ private String querySuf; /** * The user defined SQL Query string */ private Map<String, String> queryStrings; /** * accepted table types */ private String[] tableTypes; /** * Constructor * @param dbConn connection to the database * @param output RecordHandler to write data to * @param uriNameSpace namespace base for rdf records * @throws IOException error talking with database */ public JDBCFetch(Connection dbConn, RecordHandler output, String uriNameSpace) throws IOException { this(dbConn, output, uriNameSpace, null, null, null, null, null, null, null, null, null); } /** * Constructor * @param driverClass the jdbc driver * @param connLine the jdbc connection line * @param username the username * @param password the password * @param output RecordHandler to write data to * @param uriNameSpace namespace base for rdf records * @throws IOException error talking with database */ public JDBCFetch(String driverClass, String connLine, String username, String password, RecordHandler output, String uriNameSpace) throws IOException { this(driverClass, connLine, username, password, output, uriNameSpace, null, null, null, null, null, null, null, null, null); } /** * Command line Constructor * @param args commandline arguments * @throws IOException error creating task * @throws UsageException user requested usage message */ private JDBCFetch(String[] args) throws IOException, UsageException { this(getParser().parse(args)); } /** * Arglist Constructor * @param args option set of parsed args * @throws IOException error creating task */ private JDBCFetch(ArgList args) throws IOException { this(args.get("d"), args.get("c"), args.get("u"), args.get("p"), RecordHandler.parseConfig(args.get("o"), args.getValueMap("O")), (args.has("n") ? args.get("n") : (args.get("c") + "/")), args.get("delimiterPrefix"), args.get("delimiterSuffix"), new TreeSet<String>(args.getAll("t")), (args.has("T") ? args.getValueMap("T") : null), (args.has("F") ? splitCommaList(args.getValueMap("F")) : null), (args.has("I") ? splitCommaList(args.getValueMap("I")) : null), (args.has("W") ? splitCommaList(args.getValueMap("W")) : null), (args.has("R") ? splitTildeMap(args.getValueMap("R")) : null), (args.has("Q") ? args.getValueMap("Q") : null), args.getAll("v").toArray(new String[] {})); } /** * Library style Constructor * @param dbConn The database Connection * @param rh Record Handler to write records to * @param uriNS the uri namespace to use * @param queryPre Query prefix often "[" * @param querySuf Query suffix often "]" * @param tableNames set of the table names * @param fromClauses Mapping of extra tables for the from section * @param dataFields Mapping of tablename to list of datafields * @param idFields Mapping of tablename to idField name * @param whereClauses List of conditions * @param relations Mapping of tablename to mapping of fieldname to tablename * @param queryStrings Mapping of tablename to query * @param tableTypes accepted table types * @throws IOException error accessing database */ public JDBCFetch(Connection dbConn, RecordHandler rh, String uriNS, String queryPre, String querySuf, Set<String> tableNames, Map<String, String> fromClauses, Map<String, List<String>> dataFields, Map<String, List<String>> idFields, Map<String, List<String>> whereClauses, Map<String, Map<String, String>> relations, Map<String, String> queryStrings, String... tableTypes) throws IOException { try { this.cursor = dbConn.createStatement(); } catch (SQLException e) { throw new IOException(e); } this.rh = rh; Set<String> argTables = tableNames; this.fromClauses = fromClauses; this.dataFields = dataFields; this.idFields = idFields; this.whereClauses = whereClauses; this.fkRelations = relations; this.uriNS = uriNS; this.queryPre = queryPre; this.querySuf = querySuf; this.queryStrings = queryStrings; if (tableTypes.length > 0 && tableTypes[0] != null) { this.tableTypes = tableTypes; for (int x = 0; x < this.tableTypes.length; x++) { this.tableTypes[x] = this.tableTypes[x].toUpperCase(); } } else { this.tableTypes = new String[] { "TABLE" }; } if (this.rh == null) { throw new IllegalArgumentException("Must provide output recordhandler!"); } if (argTables == null) { argTables = new TreeSet<String>(); } if (this.fromClauses != null) { argTables.addAll(this.fromClauses.keySet()); } if (this.dataFields != null) { argTables.addAll(this.dataFields.keySet()); } if (this.idFields != null) { argTables.addAll(this.idFields.keySet()); } if (this.whereClauses != null) { argTables.addAll(this.whereClauses.keySet()); } if (this.fkRelations != null) { argTables.addAll(this.fkRelations.keySet()); } if (this.queryStrings != null) { // tablenames for queries are arbitrary argTables.removeAll(this.queryStrings.keySet()); } this.tableNames = new TreeSet<String>(); try { this.tableNames = getTableNames(); } catch (SQLException e) { throw new IOException(e); } Set<String> realDBTables = this.tableNames; this.tableNames = new TreeSet<String>(); //TODO: this is required as getTableNames loads data in and we want this to be a fresh start // there should be a nicer way to do all of this, as this is very hacky at the moment for (String argTable : argTables) { boolean found = false; for (String realTableName : realDBTables) { realTableName = realTableName.trim(); if (argTable.trim().equalsIgnoreCase(realTableName)) { this.tableNames.add(realTableName); // fix the tablename in all the other structures >.> if (this.fromClauses != null) { Map<String, String> tempMap = new HashMap<String, String>(); for (String fromClausesTable : this.fromClauses.keySet()) { if (fromClausesTable.trim().equalsIgnoreCase(realTableName)) { tempMap.put(realTableName, this.fromClauses.get(fromClausesTable)); } else { tempMap.put(fromClausesTable, this.fromClauses.get(fromClausesTable)); } } this.fromClauses = tempMap; } if (this.dataFields != null) { Map<String, List<String>> tempMap = this.dataFields; for (String dataFieldsTable : this.dataFields.keySet()) { if (dataFieldsTable.trim().equalsIgnoreCase(realTableName)) { tempMap.put(realTableName, this.dataFields.get(dataFieldsTable)); } else { tempMap.put(dataFieldsTable, this.dataFields.get(dataFieldsTable)); } } this.dataFields = tempMap; } if (this.idFields != null) { Map<String, List<String>> tempMap = this.idFields; for (String idFieldsTable : this.idFields.keySet()) { if (idFieldsTable.trim().equalsIgnoreCase(realTableName)) { tempMap.put(realTableName, this.idFields.get(idFieldsTable)); } else { tempMap.put(idFieldsTable, this.idFields.get(idFieldsTable)); } } this.idFields = tempMap; } if (this.whereClauses != null) { Map<String, List<String>> tempMap = this.whereClauses; for (String whereClausesTable : this.whereClauses.keySet()) { if (whereClausesTable.trim().equalsIgnoreCase(realTableName)) { tempMap.put(realTableName, this.whereClauses.get(whereClausesTable)); } else { tempMap.put(whereClausesTable, this.whereClauses.get(whereClausesTable)); } } this.whereClauses = tempMap; } if (this.fkRelations != null) { Map<String, Map<String, String>> tempMap = this.fkRelations; for (String fkRelationsTable : this.fkRelations.keySet()) { if (fkRelationsTable.trim().equalsIgnoreCase(realTableName)) { tempMap.put(realTableName, this.fkRelations.get(fkRelationsTable)); } else { tempMap.put(fkRelationsTable, this.fkRelations.get(fkRelationsTable)); } } this.fkRelations = tempMap; } found = true; break; } } if (!found) { throw new IllegalArgumentException("Database Does Not Contain A Table Named '" + argTable + "'"); } } if (this.queryStrings != null) { this.tableNames.addAll(this.queryStrings.keySet()); } } /** * Library style Constructor * @param driverClass the jdbc driver * @param connLine the jdbc connection line * @param username the username * @param password the password * @param rh Record Handler to write records to * @param uriNS the uri namespace to use * @param queryPre Query prefix often "[" * @param querySuf Query suffix often "]" * @param tableNames set of the table names * @param fromClauses Mapping of extra tables for the from section * @param dataFields Mapping of tablename to list of datafields * @param idFields Mapping of tablename to idField name * @param whereClauses List of conditions * @param relations Mapping of tablename to mapping of fieldname to tablename * @param queryStrings Mapping of tablename to query * @param tableTypes accepted table types * @throws IOException error accessing database */ public JDBCFetch(String driverClass, String connLine, String username, String password, RecordHandler rh, String uriNS, String queryPre, String querySuf, Set<String> tableNames, Map<String, String> fromClauses, Map<String, List<String>> dataFields, Map<String, List<String>> idFields, Map<String, List<String>> whereClauses, Map<String, Map<String, String>> relations, Map<String, String> queryStrings, String... tableTypes) throws IOException { this(createConnection(driverClass, connLine, username, password), rh, uriNS, queryPre, querySuf, tableNames, fromClauses, dataFields, idFields, whereClauses, relations, queryStrings, tableTypes); } /** * Split the values of a comma separated list mapping * @param list the original mapping * @return the split mapping */ private static Map<String, List<String>> splitCommaList(Map<String, String> list) { Map<String, List<String>> splitList = new HashMap<String, List<String>>(); for (String tableName : list.keySet()) { splitList.put(tableName, Arrays.asList(list.get(tableName).split("\\s?,\\s?"))); } return splitList; } /** * Split the values of comma separated ~ maps mapping * @param list the original mapping * @return the split mappings */ private static Map<String, Map<String, String>> splitTildeMap(Map<String, String> list) { Map<String, List<String>> splitList = splitCommaList(list); Map<String, Map<String, String>> splitMaps = new HashMap<String, Map<String, String>>(); for (String tableName : splitList.keySet()) { if (!splitMaps.containsKey(tableName)) { splitMaps.put(tableName, new HashMap<String, String>()); } for (String relLine : splitList.get(tableName)) { String[] relPair = relLine.split("\\s?~\\s?", 2); if (relPair.length != 2) { throw new IllegalArgumentException("Bad Relation Line: " + relLine); } splitMaps.get(tableName).put(relPair[0], relPair[1]); } } return splitMaps; } /** * Create a connection * @param driverClass the jdbc driver * @param connLine the jdbc connection line * @param username the username * @param password the password * @return the connection * @throws IOException error connecting or loading driver */ private static Connection createConnection(String driverClass, String connLine, String username, String password) throws IOException { try { Class.forName(driverClass); return DriverManager.getConnection(connLine, username, password); } catch (SQLException e) { throw new IOException(e); } catch (ClassNotFoundException e) { throw new IOException(e); } } /** * Get the field prefix * @return the field prefix */ private String getFieldPrefix() { if (this.queryPre == null) { this.queryPre = getParser().getOptMap().get("delimiterPrefix").getDefaultValue(); } return this.queryPre; } /** * Set the field prefix * @param fieldPrefix the field prefix to use */ public void setFieldPrefix(String fieldPrefix) { this.queryPre = fieldPrefix; } /** * Get the field suffix * @return the field suffix */ private String getFieldSuffix() { if (this.querySuf == null) { this.querySuf = getParser().getOptMap().get("delimiterSuffix").getDefaultValue(); } return this.querySuf; } /** * Set the field suffix * @param fieldSuffix the field suffix to use */ public void setFieldSuffix(String fieldSuffix) { this.querySuf = fieldSuffix; } /** * Get the data field information for a table from the database * @param tableName the table to get the data field information for * @return the data field list * @throws SQLException error connecting to DB */ private List<String> getDataFields(String tableName) throws SQLException { // TODO: the part after the OR looks like it should be on the next if statement, look into this if ((this.dataFields == null) || ((this.queryStrings != null) && this.queryStrings.containsKey(tableName))) { this.dataFields = new HashMap<String, List<String>>(); } if (!this.dataFields.containsKey(tableName)) { log.debug("Finding data column names for table: " + tableName); this.dataFields.put(tableName, new LinkedList<String>()); if ((this.queryStrings == null) || !this.queryStrings.containsKey(tableName)) { ResultSet columnData = this.cursor.getConnection().getMetaData() .getColumns(this.cursor.getConnection().getCatalog(), null, tableName, "%"); while (columnData.next()) { String colName = columnData.getString("COLUMN_NAME"); log.trace("Found data column: " + colName); if (!getFkRelationFields(tableName).containsKey(colName)) { this.dataFields.get(tableName).add(colName); } } } } return this.dataFields.get(tableName); } /** * Get the relation field information for a table from the database * @param tableName the table to get the relation field information for * @return the relation field mapping * @throws SQLException error connecting to DB */ private Map<String, String> getFkRelationFields(String tableName) throws SQLException { // TODO: the part after the OR looks like it should be on the next if statement, look into this if (this.fkRelations == null) { this.fkRelations = new HashMap<String, Map<String, String>>(); } if (!this.fkRelations.containsKey(tableName)) { this.fkRelations.put(tableName, new HashMap<String, String>()); } if ((this.queryStrings == null || !this.queryStrings.containsKey(tableName)) && this.fkRelations.get(tableName).isEmpty()) { log.debug("Finding relation column names for table: " + tableName); if ((this.queryStrings == null) || !this.queryStrings.containsKey(tableName)) { ResultSet foreignKeys = this.cursor.getConnection().getMetaData() .getImportedKeys(this.cursor.getConnection().getCatalog(), null, tableName); while (foreignKeys.next()) { String colName = foreignKeys.getString("FKCOLUMN_NAME"); String foreignTable = foreignKeys.getString("PKTABLE_NAME"); log.trace("Found relation column: " + colName); log.trace("links to table: " + foreignTable); this.fkRelations.get(tableName).put(colName, foreignTable); } } } return this.fkRelations.get(tableName); } /** * Get the where clauses for a table from the database * @param tableName the table to get the where clauses for * @return the where clauses */ private List<String> getWhereClauses(String tableName) { if (this.whereClauses == null) { this.whereClauses = new HashMap<String, List<String>>(); } if (!this.whereClauses.containsKey(tableName)) { this.whereClauses.put(tableName, new LinkedList<String>()); } return this.whereClauses.get(tableName); } /** * Get the id field list for a table from the database * @param tableName the table to get the id field list for * @return the id field list * @throws SQLException error connecting to DB */ private List<String> getIDFields(String tableName) throws SQLException { if (this.idFields == null) { this.idFields = new HashMap<String, List<String>>(); } if (!this.idFields.containsKey(tableName)) { log.debug("Finding id column names for table: " + tableName); this.idFields.put(tableName, new LinkedList<String>()); ResultSet primaryKeys = this.cursor.getConnection().getMetaData() .getPrimaryKeys(this.cursor.getConnection().getCatalog(), null, tableName); while (primaryKeys.next()) { String colName = primaryKeys.getString("COLUMN_NAME"); log.trace("Found id column: " + colName); this.idFields.get(tableName).add(colName); } } if (this.idFields.get(tableName).isEmpty()) { throw new IllegalArgumentException("ID fields for table '" + tableName + "' were not provided and no primary keys are present... please provide an ID field set for this table"); } return this.idFields.get(tableName); } /** * Gets the tablenames in database * @return set of tablenames * @throws SQLException error connecting to DB */ private Set<String> getTableNames() throws SQLException { if (this.tableNames.isEmpty()) { ResultSet tableData = this.cursor.getConnection().getMetaData() .getTables(this.cursor.getConnection().getCatalog(), null, "%", this.tableTypes); while (tableData.next()) { this.tableNames.add(tableData.getString("TABLE_NAME")); } } return this.tableNames; } /** * Builds a select statement against the table using configured fields * @param tableName the table to build the select statement for * @return the select statement * @throws SQLException error connecting to db */ private String buildSelect(String tableName) throws SQLException { if ((this.queryStrings != null) && this.queryStrings.containsKey(tableName)) { String query = this.queryStrings.get(tableName); log.trace("User defined SQL Query:\n" + query); return query; } boolean multiTable = (this.fromClauses != null) && this.fromClauses.containsKey(tableName); StringBuilder sb = new StringBuilder(); sb.append("SELECT "); for (String dataField : getDataFields(tableName)) { sb.append(getFieldPrefix()); if (multiTable && (dataField.split("\\.").length <= 1)) { sb.append(tableName); sb.append("."); } sb.append(dataField); sb.append(getFieldSuffix()); sb.append(", "); } for (String relField : getFkRelationFields(tableName).keySet()) { sb.append(getFieldPrefix()); if (multiTable && (relField.split("\\.").length <= 1)) { sb.append(tableName); sb.append("."); } sb.append(relField); sb.append(getFieldSuffix()); sb.append(", "); } for (String idField : getIDFields(tableName)) { sb.append(getFieldPrefix()); if (multiTable && (idField.split("\\.").length <= 1)) { sb.append(tableName); sb.append("."); } sb.append(idField); sb.append(getFieldSuffix()); sb.append(", "); } sb.delete(sb.lastIndexOf(", "), sb.length()); sb.append(" FROM "); sb.append(tableName); if (multiTable) { sb.append(", "); sb.append(this.fromClauses.get(tableName)); } if (getWhereClauses(tableName).size() > 0) { sb.append(" WHERE "); sb.append(StringUtils.join(getWhereClauses(tableName), " AND ")); } log.trace("Generated SQL Query:\n" + sb.toString()); return sb.toString(); } /** * Builds a table's record namespace * @param tableName the table to build the namespace for * @return the namespace */ private String buildTableRecordNS(String tableName) { return this.uriNS + tableName; } /** * Builds a table's field description namespace * @param tableName the table to build the namespace for * @return the namespace */ private String buildTableFieldNS(String tableName) { return this.uriNS + "fields/" + tableName + "/"; } /** * Builds a table's type description namespace * @param tableName the table to build the namespace for * @return the namespace */ private String buildTableType(String tableName) { return this.uriNS + "types#" + tableName; } /** * Get the fields from a result set * @param rs the resultset * @return the list of fields * @throws SQLException error reading resultset */ private List<String> getResultSetFields(ResultSet rs) throws SQLException { ResultSetMetaData rsmd = rs.getMetaData(); int count = rsmd.getColumnCount(); List<String> fields = new ArrayList<String>(count); for (int x = 1; x <= count; x++) { fields.add(rsmd.getColumnLabel(x)); } return fields; } /** * Executes the task * @throws IOException error processing record handler or jdbc connection */ public void execute() throws IOException { int count = 0; // For each Table try { for (String tableName : getTableNames()) { StringBuilder sb = new StringBuilder(); // For each Record ResultSet rs = this.cursor.executeQuery(buildSelect(tableName)); // ResultSetMetaData rsmd = rs.getMetaData(); // int ColumnCount = rsmd.getColumnCount(); // Map<String,String> columnData = new HashMap<String,String>(); while (rs.next()) { StringBuilder recID = new StringBuilder(); recID.append("id"); for (String idField : getIDFields(tableName)) { recID.append("_-_"); String id = rs.getString(idField); if (id != null) { id = id.trim(); } id = SpecialEntities.xmlEncode(id); recID.append(id); } // log.trace("Creating RDF for "+tableName+": "+recID); // Build RDF BEGIN // Header info String tableNS = "db-" + tableName; sb = new StringBuilder(); sb.append("<?xml version=\"1.0\"?>\n"); sb.append("<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n"); sb.append(" xmlns:"); sb.append(tableNS); sb.append("=\""); sb.append(buildTableFieldNS(tableName)); sb.append("\"\n"); sb.append(" xml:base=\""); sb.append(buildTableRecordNS(tableName)); sb.append("\">\n"); // Record info BEGIN sb.append(" <rdf:Description rdf:ID=\""); sb.append(recID); sb.append("\">\n"); // insert type value sb.append(" <rdf:type rdf:resource=\""); sb.append(buildTableType(tableName)); sb.append("\"/>\n"); // DataFields List<String> dataFieldList; if ((this.queryStrings != null) && this.queryStrings.containsKey(tableName)) { dataFieldList = getResultSetFields(rs); } else { dataFieldList = getDataFields(tableName); } for (String dataField : dataFieldList) { // Field BEGIN String field = tableNS + ":" + dataField.replaceAll(" ", "_"); sb.append(" <"); sb.append(SpecialEntities.xmlEncode(field)); sb.append(">"); // insert field value if (rs.getString(dataField) != null) { sb.append(SpecialEntities.xmlEncode(rs.getString(dataField).trim())); } // Field END sb.append("</"); sb.append(SpecialEntities.xmlEncode(field)); sb.append(">\n"); } // Relation Fields for (String relationField : getFkRelationFields(tableName).keySet()) { // Field BEGIN String field = tableNS + ":" + relationField.replaceAll(" ", "_"); sb.append(" <"); sb.append(SpecialEntities.xmlEncode(field)); sb.append(" rdf:resource=\""); sb.append(buildTableRecordNS(getFkRelationFields(tableName).get(relationField))); // insert field value sb.append("#id_-_" + rs.getString(relationField).trim()); // Field END sb.append("\"/>\n"); } // Record info END sb.append(" </rdf:Description>\n"); // Footer info sb.append("</rdf:RDF>"); // Build RDF END // Write RDF to RecordHandler log.trace("Adding record: " + tableName + "_" + recID); this.rh.addRecord(tableName + "_" + recID, sb.toString(), this.getClass()); count++; } } } catch (SQLException e) { throw new IOException(e); } log.info("Added " + count + " Records"); } /** * Get the ArgParser for this task * @return the ArgParser */ private static ArgParser getParser() { ArgParser parser = new ArgParser("JDBCFetch"); parser.addArgument(new ArgDef().setShortOption('d').setLongOpt("driver").withParameter(true, "JDBC_DRIVER") .setDescription("jdbc driver class").setRequired(true)); parser.addArgument(new ArgDef().setShortOption('c').setLongOpt("connection") .withParameter(true, "JDBC_CONN").setDescription("jdbc connection string").setRequired(true)); parser.addArgument(new ArgDef().setShortOption('u').setLongOpt("username").withParameter(true, "USERNAME") .setDescription("database username").setRequired(true)); parser.addArgument(new ArgDef().setShortOption('p').setLongOpt("password").withParameter(true, "PASSWORD") .setDescription("database password").setRequired(true)); parser.addArgument(new ArgDef().setShortOption('o').setLongOpt("output").withParameter(true, "CONFIG_FILE") .setDescription("RecordHandler config file path").setRequired(false)); parser.addArgument( new ArgDef().setShortOption('t').setLongOpt("tableName").withParameters(true, "TABLE_NAME") .setDescription("a single database table name [have multiple -t for more table names]") .setRequired(false)); parser.addArgument(new ArgDef().setShortOption('v').setLongOpt("validTableType") .withParameters(true, "TABLE_TYPE") .setDescription("a single table type (TABLE, VIEW, etc) [have multiple -v for more table types]") .setRequired(false)); parser.addArgument(new ArgDef().setShortOption('Q').setLongOpt("query") .withParameterValueMap("TABLE_NAME", "SQL_QUERY") .setDescription("use SQL_QUERY to select from TABLE_NAME").setRequired(false)); parser.addArgument(new ArgDef().setShortOption('I').setLongOpt("id") .withParameterValueMap("TABLE_NAME", "ID_FIELD_LIST") .setDescription("use columns in ID_FIELD_LIST[comma separated] as identifier for TABLE_NAME") .setRequired(false)); parser.addArgument(new ArgDef().setShortOption('F').setLongOpt("fields") .withParameterValueMap("TABLE_NAME", "FIELD_LIST") .setDescription("fetch columns in FIELD_LIST[comma separated] for TABLE_NAME").setRequired(false)); parser.addArgument(new ArgDef().setShortOption('R').setLongOpt("relations") .withParameterValueMap("TABLE_NAME", "RELATION_PAIR_LIST") .setDescription("fetch columns in RELATION_PAIR_LIST[comma separated] for TABLE_NAME") .setRequired(false)); parser.addArgument(new ArgDef().setShortOption('W').setLongOpt("whereClause") .withParameterValueMap("TABLE_NAME", "CLAUSE_LIST") .setDescription("filter TABLE_NAME records based on conditions in CLAUSE_LIST[comma separated]") .setRequired(false)); parser.addArgument(new ArgDef().setShortOption('T').setLongOpt("tableFromClause") .withParameterValueMap("TABLE_NAME", "TABLE_LIST") .setDescription("add tables to use in from clauses for TABLE_NAME").setRequired(false)); parser.addArgument(new ArgDef().setShortOption('O').setLongOpt("outputOverride") .withParameterValueMap("RH_PARAM", "VALUE") .setDescription("override the RH_PARAM of output recordhandler using VALUE").setRequired(false)); parser.addArgument( new ArgDef().setShortOption('n').setLongOpt("namespaceBase").withParameter(true, "NAMESPACE_BASE") .setDescription("the base namespace to use for each node created").setRequired(false)); parser.addArgument(new ArgDef().setLongOpt("delimiterPrefix").withParameter(true, "DELIMITER") .setDescription("Prefix each field in the query with this character").setDefaultValue("") .setRequired(false)); parser.addArgument(new ArgDef().setLongOpt("delimiterSuffix").withParameter(true, "DELIMITER") .setDescription("Suffix each field in the query with this character").setDefaultValue("") .setRequired(false)); return parser; } /** * Main method * @param args commandline arguments */ public static void main(String... args) { Exception error = null; try { InitLog.initLogger(args, getParser()); log.info(getParser().getAppName() + ": Start"); new JDBCFetch(args).execute(); } catch (IllegalArgumentException e) { log.error(e.getMessage()); log.debug("Stacktrace:", e); System.out.println(getParser().getUsage()); error = e; } catch (UsageException e) { log.info("Printing Usage:"); System.out.println(getParser().getUsage()); error = e; } catch (Exception e) { log.error(e.getMessage()); log.debug("Stacktrace:", e); error = e; } finally { log.info(getParser().getAppName() + ": End"); if (error != null) { System.exit(1); } } } }