CVE-2026-48114
Description
Unauthenticated SQL injection in Metacat 2.x harvesterRegistration endpoint allows full database compromise; fixed in 3.0.0.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Unauthenticated SQL injection in Metacat 2.x harvesterRegistration endpoint allows full database compromise; fixed in 3.0.0.
Vulnerability
Metacat versions 2.0.0 through 2.19.1 contain an unauthenticated SQL injection in the /harvesterRegistration endpoint. The HarvesterRegistration.dbInsert() method builds an INSERT statement against HARVEST_SITE_SCHEDULE via string concatenation, using a quoteString() helper that performs raw single-quote wrapping without escaping. Three request parameters reach the sink: unit, contactEmail, and documentListURL. The servlet does not verify LDAP identity, allowing the vulnerable insert to proceed. [1]
Exploitation
An attacker can send a crafted HTTP request to the /harvesterRegistration endpoint with malicious payloads in any of the three parameters. Because the PostgreSQL backend permits stacked queries via Statement.executeUpdate(), the attacker can execute arbitrary SQL statements. Additionally, a second-order SQL injection exists: an attacker-controlled documentListURL is fetched by the scheduled harvester, and the parsed `` element flows unsanitized. [1]
Impact
Successful exploitation allows full read/write/execute access in the Metacat database context, including credentials, session material, and the xml_documents corpus. This can lead to complete compromise of the Metacat instance and its data. [1]
Mitigation
The vulnerability was remediated in Metacat 3.0.0 (commit 820d595) via removal of the harvesterClient package. [2] The 2.x branch remains vulnerable and will not be backported. Users should upgrade to Metacat 3.0.0 or later (preferably the current release >= 3.4.0). As a workaround, restrict access to the old 1.x API endpoints. [1]
AI Insight generated on Jun 15, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
2Patches
1820d595309b3Removed the harvester client for LTER.
16 files changed · +0 −6471
src/edu/ucsb/nceas/metacat/harvesterClient/HarvestDetailLog.java+0 −125 removed@@ -1,125 +0,0 @@ -/** - * '$RCSfile$' - * Copyright: 2004 University of New Mexico and the - * Regents of the University of California - * - * '$Author$' - * '$Date$' - * '$Revision$' - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package edu.ucsb.nceas.metacat.harvesterClient; - -import java.io.PrintStream; -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; - -/** - * HarvestDetailLog manages data and operations corresponding to the - * HARVEST_DETAIL_LOG table. It records errors encountered while attempting - * to harvest a particular EML document. - * - * @author costa - */ -public class HarvestDetailLog { - - private Connection conn; - private Harvester harvester; // The parent Harvester object - private int detailLogID; - private int harvestLogID; - private HarvestDocument harvestDocument; // The associated HarvestDocument - private String errorMessage; - - - /** - * Creates a new instance of HarvestDetailLog and inserts the data into - * the HARVEST_DETAIL_LOG table. - * - * @param harvester the Harvester parent object - * @param conn the database connection - * @param detailLogID primary key in the HARVEST_LOG table - * @param harvestLogID foreign key value matching the HARVEST_LOG table - * @param harvestDocument HarvestDocument object that generated an error - * @param errorMessage text of the error message - */ - public HarvestDetailLog(Harvester harvester, - Connection conn, - int detailLogID, - int harvestLogID, - HarvestDocument harvestDocument, - String errorMessage - ) { - this.harvester = harvester; - this.conn = conn; - this.detailLogID = detailLogID; - this.harvestLogID = harvestLogID; - this.harvestDocument = harvestDocument; - this.errorMessage = errorMessage; - } - - - /** - * Inserts a new entry into the HARVEST_DETAIL_LOG table, based on the - * contents of this HarvestDetailLog object. - */ - void dbInsertHarvestDetailLogEntry() { - String dequotedMessage; - String insertString; - Statement stmt; - - dequotedMessage = harvester.dequoteText(errorMessage); - - // Set the value of the HARVEST_LOG_ID to the current time in UTC seconds - insertString = "INSERT INTO HARVEST_DETAIL_LOG " + - "(DETAIL_LOG_ID, HARVEST_LOG_ID, SCOPE," + - " IDENTIFIER, REVISION," + - " DOCUMENT_URL, ERROR_MESSAGE, DOCUMENT_TYPE) " + - "values(" + - detailLogID + ", " + - harvestLogID + ", " + - "'" + harvestDocument.scope + "', " + - harvestDocument.identifier + ", " + - harvestDocument.revision + ", " + - "'" + harvestDocument.documentURL + "', " + - "'" + dequotedMessage + "'," + - "'" + harvestDocument.documentType + "'" + - ")"; - - try { - stmt = conn.createStatement(); - stmt.executeUpdate(insertString); - stmt.close(); - } - catch(SQLException e) { - System.out.println("SQLException: " + e.getMessage()); - } - } - - - /** - * Prints the contents of this HarvestLog object. Used in generating reports. - * - * @param out the PrintStream to write to - */ - public void printOutput(PrintStream out) { - out.println("* detailLogID: " + detailLogID); - out.println("* errorMessage: " + errorMessage); - harvestDocument.printOutput(out); - } - -}
src/edu/ucsb/nceas/metacat/harvesterClient/HarvestDocument.java+0 −402 removed@@ -1,402 +0,0 @@ -/** - * '$RCSfile$' - * Copyright: 2004 University of New Mexico and the - * Regents of the University of California - * - * '$Author$' - * '$Date$' - * '$Revision$' - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package edu.ucsb.nceas.metacat.harvesterClient; - -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.IOException; -import java.io.PrintStream; -import java.io.StringReader; -import java.net.MalformedURLException; -import java.net.URL; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import edu.ucsb.nceas.metacat.client.InsufficientKarmaException; -import edu.ucsb.nceas.metacat.client.Metacat; -import edu.ucsb.nceas.metacat.client.MetacatException; -import edu.ucsb.nceas.metacat.client.MetacatInaccessibleException; -import edu.ucsb.nceas.utilities.IOUtil; - - -/** - * HarvestDocument manages operations and data for a single document to be - * harvested. - * - * @author costa - */ -public class HarvestDocument { - - - private String docid; // scope + identifier - private String docidFull; // scope + identifier + revision - String documentType; - String documentURL; - private Harvester harvester; - private HarvestSiteSchedule harvestSiteSchedule; - int identifier; - int revision; - String scope; - - /* These booleans keep track of status information. They are used when - * generating email reports. - */ - boolean accessError = false; - boolean inserted = false; - boolean metacatHasIt = false; - boolean updated = false; - boolean uploadError = false; - - - /** - * Creates a new instance of HarvestDocument. Initialized with the data - * that was read from a single <document> element in site document list. - * - * @param harvester the parent Harvester object - * @param harvestSiteSchedule the parent HarvestSiteSchedule object - * @param scope the value of the <scope> element - * @param identifier the value of the <identifier> element - * @param revision the value of the <revision> element - * @param documentType the value of the <documentType> element - * @param documentURL the value of the <documentURL> element - */ - public HarvestDocument ( - Harvester harvester, - HarvestSiteSchedule harvestSiteSchedule, - String scope, - int identifier, - int revision, - String documentType, - String documentURL - ) { - this.harvester = harvester; - this.harvestSiteSchedule = harvestSiteSchedule; - this.documentType = documentType; - this.documentURL = documentURL; - this.scope = scope; - this.identifier = identifier; - this.revision = revision; - - this.docid = scope + "." + identifier; - this.docidFull = this.docid + "." + revision; - } - - - /** - * Retrieve the document from the site using its <documentURL> value. - * - * @return A StringReader containing the document string. - */ - public StringReader getSiteDocument() { - String documentString; - InputStream inputStream; - InputStreamReader inputStreamReader; - StringReader stringReader = null; - URL url; - - try { - url = new URL(documentURL); - inputStream = url.openStream(); - inputStreamReader = new InputStreamReader(inputStream); - documentString = IOUtil.getAsString(inputStreamReader, true); - stringReader = new StringReader(documentString); - harvester.addLogEntry(0, - "Retrieved: " + documentURL, - "harvester.GetDocSuccess", - harvestSiteSchedule.siteScheduleID, - null, - ""); - } - catch (MalformedURLException e) { - accessError = true; - harvester.addLogEntry(1, "MalformedURLException", "harvester.GetDocError", - harvestSiteSchedule.siteScheduleID, this, - "MalformedURLException: " + e.getMessage()); - } - catch (IOException e) { - accessError = true; - harvester.addLogEntry(1, "IOException", "harvester.GetDocError", - harvestSiteSchedule.siteScheduleID, this, - "IOException: " + e.getMessage()); - } - - return stringReader; - } - - - /** - * Harvest the document from the site. Unless Metacat already has the - * document, retrieve the document from the site and put (insert or - * update) it to Metacat. If Metacat already has the document, determine - * the highest revision stored in Metacat so that this can be reported - * back to the user. - */ - public void harvestDocument() { - int highestRevision; - boolean insert = false; - String metacatReturnString; - StringReader stringReader; - boolean update = false; - - /* If metacat already has this document, determine the highest revision in - * metacat and report it to the user; else, insert or delete the document - * into metacat. - */ - highestRevision = metacatHighestRevision(); - - if (highestRevision == -1) { - insert = true; - } - else if (revision > highestRevision) { - update = true; - } - else { - metacatHasIt = true; - harvester.addLogEntry(0, - "Attempting to update " + docid + " to revision " + - revision + ". Metacat has document revision " + - highestRevision + ".", - "harvester.MetacatHasDoc", - harvestSiteSchedule.siteScheduleID, - null, - ""); - } - - if (insert || update) { - stringReader = getSiteDocument(); - if (stringReader != null) { - if (validateDocument()) { - putMetacatDocument(insert, update, stringReader); - } - } - } - } - - - /** - * Boolean to determine whether the string returned by the Metacat client for - * an insert or update operation indicates that the operation succeeded. - * - * @param metacatReturnString The string returned by the Metacat client. - * @return true if the return string indicates success, else false - */ - private boolean isMetacatSuccessString(String metacatReturnString) { - boolean isMetacatSuccessString = false; - - if ((metacatReturnString != null) && - (metacatReturnString.contains("<success>")) - ) { - isMetacatSuccessString = true; - } - - return isMetacatSuccessString; - } - - - /** - * Logs a metacat document error to the harvest detail log. - * - * @param insert true if insert operation, false is update - * @param metacatReturnString string returned from the insert or update - * @param exceptionName name of the exception class - * @param e the exception object - */ - private void logMetacatError (boolean insert, - String metacatReturnString, - String exceptionName, - Exception e - ) { - uploadError = true; - - if (insert) { - harvester.addLogEntry(1, - metacatReturnString, - "harvester.InsertDocError", - harvestSiteSchedule.siteScheduleID, - this, - exceptionName + ": " + e.getMessage()); - } - else { - harvester.addLogEntry(1, - metacatReturnString, - "harvester.UpdateDocError", - harvestSiteSchedule.siteScheduleID, - this, - exceptionName + ": " + e.getMessage()); - } - } - - - /** - * Determines the highest revision that Metacat has for this document. - * - * @return int representing the highest revision for this document in - * Metacat. Returns -1 if Metacat does not currently hold the - * document. - */ - public int metacatHighestRevision() { - Connection conn = harvester.getConnection(); - int highestRevision = -1; - String query = "SELECT REV FROM XML_DOCUMENTS WHERE DOCID = " + - "'" + docid + "'"; - Statement stmt; - - try { - stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery(query); - - while (rs.next()) { - highestRevision = rs.getInt("REV"); - } - - stmt.close(); - } - catch(SQLException e) { - System.out.println("SQLException: " + e.getMessage()); - } - - return highestRevision; - } - - - /** - * Print the data fields and values in this HarvestDocument object. - * - * @param out the PrintStream to write to - */ - public void printOutput(PrintStream out) { - out.println("* scope: " + scope); - out.println("* identifier: " + identifier); - out.println("* revision: " + revision); - out.println("* documentType: " + documentType); - out.println("* documentURL: " + documentURL); - } - - - /** - * Print the document URL following by its scope.identifier.revision. - * Used for report generation. - * - * @param out the PrintStream to write to - */ - public void prettyPrint(PrintStream out) { - out.println("* " + docidFull + " (" + documentURL + ")"); - } - - - /** - * Insert or update this document to Metacat. If revision equals 1, do an - * insert; otherwise, do an update. - * - * @param insert true if this is an insert operation - * @param update true if this is an update operation - * @param stringReader the StringReader object holding the document text - */ - private void putMetacatDocument(boolean insert, - boolean update, - StringReader stringReader) { - Metacat metacat = harvester.metacat; - String metacatReturnString = ""; - - if (harvester.connectToMetacat()) { - try { - String harvestOperationCode = ""; - - if (insert) { - harvestOperationCode = "harvester.InsertDocSuccess"; - metacatReturnString = metacat.insert(docidFull, stringReader, null); - this.inserted = true; - } - else if (update) { - harvestOperationCode = "harvester.UpdateDocSuccess"; - metacatReturnString = metacat.update(docidFull, stringReader, null); - this.updated = true; - } - - if (isMetacatSuccessString(metacatReturnString)) { - String message = docidFull + " : " + metacatReturnString; - harvester.addLogEntry(0, message, harvestOperationCode, - harvestSiteSchedule.siteScheduleID, null, ""); - } - else { - this.inserted = false; - this.updated = false; - final String exceptionName = "UnreportedMetacatException"; - final String exceptionMessage = - "Metacat insert/update failed without reporting an exception"; - Exception e = new Exception(exceptionMessage); - logMetacatError(insert, metacatReturnString, exceptionName, e); - } - } - catch (MetacatInaccessibleException e) { - logMetacatError(insert, metacatReturnString, - "MetacatInaccessibleException", e); - } - catch (InsufficientKarmaException e) { - logMetacatError(insert, metacatReturnString, - "InsufficientKarmaException", e); - } - catch (MetacatException e) { - logMetacatError(insert, metacatReturnString, "MetacatException", e); - } - catch (IOException e) { - logMetacatError(insert, metacatReturnString, "IOException", e); - } - catch (Exception e) { - logMetacatError(insert, metacatReturnString, "Exception", e); - } - } - } - - - /** - * Validate the document to determine whether it is valid EML prior to - * inserting or updating it to Metacat. This is QA/QC measure. - * Not yet implemented. - * - * @return true if the document is valid EML, otherwise false - */ - private boolean validateDocument () { - boolean success = true; - - /*if (success) { - harvester.addLogEntry(0, - "Validated: " + documentURL, - "harvester.ValidateDocSuccess", - harvestSiteSchedule.siteScheduleID, - null, - ""); - } - else { - harvester.addLogEntry(1, "Error validating document", "harvester.ValidateDocError", - harvestSiteSchedule.siteScheduleID, this, ""); - }*/ - - return success; - } - -}
src/edu/ucsb/nceas/metacat/harvesterClient/Harvester.java+0 −1042 removed@@ -1,1042 +0,0 @@ -/** - * '$RCSfile$' - * Copyright: 2004 University of New Mexico and the - * Regents of the University of California - * - * '$Author$' - * '$Date$' - * '$Revision$' - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package edu.ucsb.nceas.metacat.harvesterClient; - -import com.oreilly.servlet.MailMessage; -import java.io.IOException; -import java.io.PrintStream; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.SQLWarning; -import java.sql.Statement; -import java.util.ArrayList; -import java.text.SimpleDateFormat; -import java.util.Date; - -import edu.ucsb.nceas.metacat.client.Metacat; -import edu.ucsb.nceas.metacat.client.MetacatFactory; -import edu.ucsb.nceas.metacat.client.MetacatInaccessibleException; -import edu.ucsb.nceas.metacat.properties.PropertyService; -import edu.ucsb.nceas.metacat.util.SystemUtil; -import edu.ucsb.nceas.utilities.PropertyNotFoundException; - -/** - * Harvester is the main class for the Harvester application. The main - * method creates a single Harvester object which drives the application. - * - * @author costa - * - */ -public class Harvester { - - /* - * Class fields - */ - - public static final String filler = "*"; - private static boolean keepRunning = true; - public static final String marker = -"*****************************************************************************"; -// public static PropertyService propertyService = null; - private static String schemaLocation = null; - - - /* - * Class methods - */ - - - /** - * Constructor. Creates a new instance of Harvester. - */ - public Harvester() { - } - - - /** - * Loads Harvester options from a configuration file. - */ - public static void loadProperties(String metacatContextDir) { - - try { - PropertyService.getInstance(metacatContextDir + "/WEB-INF"); - } - catch (Exception e) { - System.out.println("Error in loading properties: " + e.getMessage()); - System.exit(1); - } - } - - - /** - * Harvester main method. - * - * @param args the command line arguments - * - * args[0] if "false", then this is not command-line mode, - * Command-line mode is true by default. - * - * args[1] if present, represents the path to the harvest list schema file. - * Specifying it overrides the default path to the schema file. - * - * @throws SAXException - * @throws IOException - * @throws ParserConfigurationException - */ - public static void main(String[] args) { - - Integer delayDefault = new Integer(0); // Default number of hours delay - int delay = delayDefault.intValue(); // Delay in hours before first - // harvest - Integer d; // Used for determining delay - long delta; // endTime - startTime - long endTime; // time that a harvest completes - Harvester harvester; // object for a single harvest run - Integer maxHarvestsDefault = new Integer(0); // Default max harvests - int maxHarvests = maxHarvestsDefault.intValue(); // Max number of - // harvests - Integer mh; // used in determining max harvests - int nHarvests = 0; // counts the number of harvest runs - final long oneHour = (60 * 60 * 1000); // milliseconds in one hour - Integer periodDefault = new Integer(24); // Default hours between - // harvests - int period = periodDefault.intValue(); // Hours between harvests - Integer p; // Used in determining the period - long startTime; // time that a harvest run starts - - String metacatContextDir = null; - - if ((args.length > 0) && (args[0] != null)) { - metacatContextDir = args[0]; - } - - /* - * If there is a second argument, it is the schemaLocation value - */ - if (args.length > 1) { - schemaLocation = args[1]; - System.err.println("schemaLocation: " + schemaLocation); - - try { - Thread.sleep(10000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - System.out.println(marker); - System.out.println("Starting Harvester"); - Harvester.loadProperties(metacatContextDir); - - // Parse the delay property. Use default if necessary. - try { - d = Integer.valueOf(PropertyService.getProperty("harvester.delay")); - delay = d.intValue(); - } catch (NumberFormatException e) { - System.out.println("NumberFormatException: Error parsing delay: " - + e.getMessage()); - System.out.println("Defaulting to delay=" + delayDefault); - delay = delayDefault.intValue(); - } catch (PropertyNotFoundException pnfe) { - System.out.println("PropertyNotFoundException: Error finding delay: " - + pnfe.getMessage()); - System.out.println("Defaulting to delay=" + delayDefault); - delay = delayDefault.intValue(); - } - - // Parse the maxHarvests property. Use default if necessary. - try { - mh = Integer.valueOf(PropertyService.getProperty("harvester.maxHarvests")); - maxHarvests = mh.intValue(); - } catch (NumberFormatException e) { - System.out.println("NumberFormatException: Error parsing maxHarvests: " - + e.getMessage()); - System.out.println("Defaulting to maxHarvests=" + maxHarvestsDefault); - maxHarvests = maxHarvestsDefault.intValue(); - } catch (PropertyNotFoundException pnfe) { - System.out.println("PropertyNotFoundException: Error finding maxHarvests: " - + pnfe.getMessage()); - System.out.println("Defaulting to maxHarvests=" + maxHarvestsDefault); - maxHarvests = maxHarvestsDefault.intValue(); - } - - // Parse the period property. Use default if necessary. - try { - p = Integer.valueOf(PropertyService.getProperty("harvester.period")); - period = p.intValue(); - } catch (NumberFormatException e) { - System.out.println("NumberFormatException: Error parsing period: " - + e.getMessage()); - System.out.println("Defaulting to period=" + periodDefault); - period = periodDefault.intValue(); - } catch (PropertyNotFoundException pnfe) { - System.out.println("PropertyNotFoundException: Error finding period: " - + pnfe.getMessage()); - System.out.println("Defaulting to period=" + periodDefault); - period = periodDefault.intValue(); - } - - // Sleep for delay number of hours prior to starting first harvest - if (delay > 0) { - try { - System.out.print("First harvest will begin in " + delay); - if (delay == 1) { - System.out.println(" hour."); - } else { - System.out.println(" hours."); - } - Thread.sleep(delay * oneHour); - } catch (InterruptedException e) { - System.err.println("InterruptedException: " + e.getMessage()); - System.exit(1); - } - } - - // Repeat a new harvest once every period number of hours, until we reach - // the maximum number of harvests, or indefinitely if maxHarvests <= 0. - // Subtract delta from the time period so - // that each harvest will start at a fixed interval. - // - while (keepRunning && ((nHarvests < maxHarvests) || (maxHarvests <= 0))) { - nHarvests++; - startTime = System.currentTimeMillis(); - harvester = new Harvester(); // New object for this - // harvest - harvester.startup(nHarvests, maxHarvests); // Start up Harvester - harvester.readHarvestSiteSchedule(); // Read the database table - harvester.harvest(); // Harvest the documents - harvester.shutdown(); // Shut down Harvester - endTime = System.currentTimeMillis(); - delta = endTime - startTime; - - if ((nHarvests < maxHarvests) || (maxHarvests <= 0)) { - try { - System.out.println("Next harvest will begin in " + - period + " hours."); - Thread.sleep((period * oneHour) - delta); - } - catch (InterruptedException e) { - System.err.println("InterruptedException: " + e.getMessage()); - System.exit(1); - } - } - } - } - - - /** - * Set the keepRunning flag. If set to false, the main program will end - * the while loop that keeps harvester running every period number of hours. - * The static method is intended to be called from the HarvesterServlet class - * which creates a thread to run Harvester. When the thread is destroyed, the - * thread's destroy() method calls Harvester.setKeepRunning(false). - * - * @param keepRunning - */ - static void setKeepRunning(boolean keepRunning) { - Harvester.keepRunning = keepRunning; - } - - - /* - * Object fields - */ - - /** Database connection */ - private Connection conn = null; - - /** Used during development to determine whether to connect to metacat - * Sometimes it's useful to test parts of the code without actually - * connecting to Metacat. - */ - private boolean connectToMetacat; - - /** Highest DETAIL_LOG_ID primary key in the HARVEST_DETAIL_LOG table */ - private int detailLogID; - - /** Email address of the Harvester Administrator */ - String harvesterAdministrator; - - /** Highest HARVEST_LOG_ID primary key in the HARVEST_LOG table */ - private int harvestLogID; - - /** End time of this harvest session */ - private Date harvestEndTime; - - /** List of HarvestLog objects. Stores log entries for report generation. */ - private ArrayList harvestLogList = new ArrayList(); - - /** List of HarvestSiteSchedule objects */ - private ArrayList harvestSiteScheduleList = new ArrayList(); - - /** Start time of this harvest session */ - private Date harvestStartTime; - - /** Number of days to save log records. Any that are older are purged. */ - int logPeriod; - - /** Metacat client object */ - Metacat metacat; - - /** SMTP server for sending mail messages */ - String smtpServer; - - /** The timestamp for this harvest run. Used for output only. */ - String timestamp; - - - /* - * Object methods - */ - - /** - * Creates a new HarvestLog object and adds it to the harvestLogList. - * - * @param status the status of the harvest operation - * @param message the message text of the harvest operation - * @param harvestOperationCode the harvest operation code - * @param siteScheduleID the siteScheduleID for which this operation was - * performed. 0 indicates that the operation did not - * involve a particular harvest site. - * @param harvestDocument the associated HarvestDocument object. May be null. - * @param errorMessage additional error message pertaining to document - * error. - */ - void addLogEntry(int status, - String message, - String harvestOperationCode, - int siteScheduleID, - HarvestDocument harvestDocument, - String errorMessage - ) { - HarvestLog harvestLog; - int harvestLogID = getHarvestLogID(); - int detailLogID; - - /* If there is no associated harvest document, call the basic constructor; - * else call the extended constructor. - */ - if (harvestDocument == null) { - harvestLog = new HarvestLog(this, conn, harvestLogID, harvestStartTime, - status, message, harvestOperationCode, - siteScheduleID); - } - else { - detailLogID = getDetailLogID(); - harvestLog = new HarvestLog(this, conn, harvestLogID, detailLogID, - harvestStartTime, status, message, - harvestOperationCode, siteScheduleID, - harvestDocument, errorMessage); - } - - harvestLogList.add(harvestLog); - } - - - public void closeConnection() { - try { - // Close the database connection - System.out.println("Closing the database connection."); - conn.close(); - } - catch (SQLException e) { - System.out.println("Database access failed " + e); - } - } - - - /** - * Determines whether Harvester should attempt to connect to Metacat. - * Used during development and testing. - * - * @return true if Harvester should connect, otherwise false - */ - boolean connectToMetacat () { - return connectToMetacat; - } - - - /** - * Normalizes text prior to insertion into the HARVEST_LOG or - * HARVEST_DETAIL_LOG tables. In particular, replaces the single quote - * character with the double quote character. This prevents SQL errors - * involving words that contain single quotes. Also removes \n and \r - * characters from the text. - * - * @param text the original string - * @return a string containing the normalized text - */ - public String dequoteText(String text) { - char c; - StringBuffer stringBuffer = new StringBuffer(); - - for (int i = 0; i < text.length(); i++) { - c = text.charAt(i); - switch (c) { - case '\'': - stringBuffer.append('\"'); - break; - case '\r': - case '\n': - break; - default: - stringBuffer.append(c); - break; - } - } - - return stringBuffer.toString(); - } - - /** - * Returns a connection to the database. Opens the connection if a connection - * has not already been made previously. - * - * @return conn the database Connection object - */ - public Connection getConnection() { - String dbDriver = ""; - String defaultDB = null; - String password = null; - String user = null; - SQLWarning warn; - - if (conn == null) { - try { - dbDriver = PropertyService.getProperty("database.driver"); - defaultDB = PropertyService.getProperty("database.connectionURI"); - password = PropertyService.getProperty("database.password"); - user = PropertyService.getProperty("database.user"); - } catch (PropertyNotFoundException pnfe) { - System.out.println("Can't find property " + pnfe); - System.exit(1); - } - - // Load the jdbc driver - try { - Class.forName(dbDriver); - } - catch (ClassNotFoundException e) { - System.out.println("Can't load driver " + e); - System.exit(1); - } - - // Make the database connection - try { - System.out.println("Getting connection to Harvester tables"); - conn = DriverManager.getConnection(defaultDB, user, password); - - // If a SQLWarning object is available, print its warning(s). - // There may be multiple warnings chained. - warn = conn.getWarnings(); - - if (warn != null) { - while (warn != null) { - System.out.println("SQLState: " + warn.getSQLState()); - System.out.println("Message: " + warn.getMessage()); - System.out.println("Vendor: " + warn.getErrorCode()); - System.out.println(""); - warn = warn.getNextWarning(); - } - } - } - catch (SQLException e) { - System.out.println("Database access failed " + e); - System.exit(1); - } - } - - return conn; - } - - - /** - * Gets the current value of the detailLogID for storage as a primary key in - * the DETAIL_LOG_ID field of the HARVEST_DETAIL_LOG table. - * - * @return the current value of the detailLogID - */ - public int getDetailLogID() { - int currentValue = detailLogID; - - detailLogID++; - return currentValue; - } - - - /** - * Gets the current value of the harvestLogID for storage as a primary key in - * the HARVEST_LOG_ID field of the HARVEST_LOG table. - * - * @return the current value of the detailLogID - */ - public int getHarvestLogID() { - int currentValue = harvestLogID; - - harvestLogID++; - return currentValue; - } - - - /** - * Gets the maximum value of an integer field from a table. - * - * @param tableName the database table name - * @param fieldName the field name of the integer field in the table - * @return the maximum integer stored in the fieldName field of tableName - */ - private int getMaxValue(String tableName, String fieldName) { - int maxValue = 0; - int fieldValue; - String query = "SELECT " + fieldName + " FROM " + tableName; - Statement stmt; - - try { - stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery(query); - - while (rs.next()) { - fieldValue = rs.getInt(fieldName); - maxValue = Math.max(maxValue, fieldValue); - } - - stmt.close(); - } - catch(SQLException ex) { - System.out.println("SQLException: " + ex.getMessage()); - } - - return maxValue; - } - - - /** - * Gets the minimum value of an integer field from a table. - * - * @param tableName the database table name - * @param fieldName the field name of the integer field in the table - * @return the minimum integer stored in the fieldName field of tableName - */ - private int getMinValue(String tableName, String fieldName) { - int minValue = 0; - int fieldValue; - String query = "SELECT " + fieldName + " FROM " + tableName; - Statement stmt; - - try { - stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery(query); - - while (rs.next()) { - fieldValue = rs.getInt(fieldName); - - if (minValue == 0) { - minValue = fieldValue; - } - else { - minValue = Math.min(minValue, fieldValue); - } - } - - stmt.close(); - } - catch(SQLException ex) { - System.out.println("SQLException: " + ex.getMessage()); - } - - return minValue; - } - - - /** - * For every Harvest site schedule in the database, harvest the - * documents for that site if they are due to be harvested. - * - * @throws SAXException - * @throws IOException - * @throws ParserConfigurationException - */ - private void harvest() { - HarvestSiteSchedule harvestSiteSchedule; - - for (int i = 0; i < harvestSiteScheduleList.size(); i++) { - harvestSiteSchedule = (HarvestSiteSchedule)harvestSiteScheduleList.get(i); - - if (Harvester.schemaLocation != null) { - harvestSiteSchedule.setSchemaLocation(Harvester.schemaLocation); - } - - harvestSiteSchedule.harvestDocumentList(); - } - } - - - /** - * Initializes the detailLogID and harvestLogID values to their current - * maximums + 1. - */ - public void initLogIDs() { - detailLogID = getMaxValue("HARVEST_DETAIL_LOG", "DETAIL_LOG_ID") + 1; - harvestLogID = getMaxValue("HARVEST_LOG", "HARVEST_LOG_ID") + 1; - } - - - /** - * Prints the header of the harvest report. - * - * @param out the PrintStream object to print to - * @param siteScheduleID the siteScheduleId of the HarvestSiteSchedule. Will - * have a value of 0 if no particular site is involved, - * which indicates that the report is being prepared - * for the Harvester Administrator rather than for a - * particular Site Contact. - */ - void printHarvestHeader(PrintStream out, int siteScheduleID) { - HarvestLog harvestLog; - int logSiteScheduleID; - int nErrors = 0; - String phrase; - - for (int i = 0; i < harvestLogList.size(); i++) { - harvestLog = (HarvestLog) harvestLogList.get(i); - logSiteScheduleID = harvestLog.getSiteScheduleID(); - - if ((siteScheduleID == 0) || (siteScheduleID == logSiteScheduleID)) { - if (harvestLog.isErrorEntry()) { - nErrors++; - } - } - } - - out.println(marker); - out.println(filler); - out.println("* METACAT HARVESTER REPORT: " + timestamp); - out.println(filler); - - if (nErrors > 0) { - phrase = (nErrors == 1) ? " ERROR WAS " : " ERRORS WERE "; - out.println("* A TOTAL OF " + nErrors + phrase + "DETECTED."); - out.println("* Please see the log entries below for additonal details."); - } - else { - out.println("* NO ERRORS WERE DETECTED DURING THIS HARVEST."); - } - - out.println(filler); - out.println(marker); - } - - - /** - * Prints harvest log entries for this harvest run. Entries may be filtered - * for a particular site, or all entries may be printed. - * - * @param out the PrintStream object to write to - * @param maxCodeLevel the maximum code level that should be printed, - * e.g. "warning". Any log entries higher than this - * level will not be printed. - * @param siteScheduleID if greater than 0, indicates that the log - * entry should only be printed for a particular site - * as identified by its siteScheduleID. if 0, then - * print output for all sites. - */ - void printHarvestLog(PrintStream out, String maxCodeLevel, int siteScheduleID - ) { - HarvestLog harvestLog; - int logSiteScheduleID; - int nErrors = 0; - String phrase; - - out.println(""); - out.println(marker); - out.println(filler); - out.println("* LOG ENTRIES"); - out.println(filler); - out.println(marker); - - for (int i = 0; i < harvestLogList.size(); i++) { - harvestLog = (HarvestLog) harvestLogList.get(i); - logSiteScheduleID = harvestLog.getSiteScheduleID(); - if ((siteScheduleID == 0) || (siteScheduleID == logSiteScheduleID)) { - harvestLog.printOutput(out, maxCodeLevel); - } - } - } - - - /** - * Prints the site schedule data for a given site. - * - * @param out the PrintStream to write to - * @param siteScheduleID the primary key in the HARVEST_SITE_SCHEDULE table - */ - void printHarvestSiteSchedule(PrintStream out, int siteScheduleID) { - HarvestSiteSchedule harvestSiteSchedule; - - for (int i = 0; i < harvestSiteScheduleList.size(); i++) { - harvestSiteSchedule = (HarvestSiteSchedule)harvestSiteScheduleList.get(i); - if (harvestSiteSchedule.siteScheduleID == siteScheduleID) { - harvestSiteSchedule.printOutput(out); - } - } - } - - - /** - * Prunes old records from the HARVEST_LOG table. Records are removed if - * their HARVEST_DATE is older than a given number of days, as stored in the - * logPeriod object field. First deletes records from the HARVEST_DETAIL_LOG - * table that reference the to-be-pruned entries in the HARVEST_LOG table. - */ - private void pruneHarvestLog() { - long currentTime = harvestStartTime.getTime(); // time in milliseconds - Date dateLastLog; // Prune everything prior to this date - String deleteString; - String deleteStringDetailLog; - long delta; - final long millisecondsPerDay = (1000 * 60 * 60 * 24); - int recordsDeleted; - int recordsDeletedDetail = 0; - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MMM-yyyy"); - String dateString; - ResultSet rs; - String selectString; - Statement stmt; - long timeLastLog = 0; - SQLWarning warn; - - delta = logPeriod * millisecondsPerDay; - deleteString = "DELETE FROM HARVEST_LOG WHERE HARVEST_DATE < "; - selectString="SELECT HARVEST_LOG_ID FROM HARVEST_LOG WHERE HARVEST_DATE < "; - deleteStringDetailLog = - "DELETE FROM HARVEST_DETAIL_LOG WHERE HARVEST_LOG_ID = "; - timeLastLog = currentTime - delta; - dateLastLog = new Date(timeLastLog); - dateString = "'" + simpleDateFormat.format(dateLastLog) + "'"; - deleteString += dateString; - selectString += dateString; - - try { - System.out.println( - "Pruning log entries from HARVEST_DETAIL_LOG and HARVEST_LOG:"); - - /* Get the list of entries that need to be pruned from the HARVEST_LOG - * table. - */ - stmt = conn.createStatement(); - rs = stmt.executeQuery(selectString); - warn = rs.getWarnings(); - - if (warn != null) { - System.out.println("\n---Warning---\n"); - - while (warn != null) { - System.out.println("Message: " + warn.getMessage()); - System.out.println("SQLState: " + warn.getSQLState()); - System.out.print("Vendor error code: "); - System.out.println(warn.getErrorCode()); - System.out.println(""); - warn = warn.getNextWarning(); - } - } - - /* Delete any entries from the HARVEST_DETAIL_LOG which reference - * HARVEST_LOG_IDs that are about to be pruned. HARVEST_DETAIL_LOG must - * be pruned first because its records have a child relationship to those - * in HARVEST_LOG. - */ - while (rs.next()) { - harvestLogID = rs.getInt("HARVEST_LOG_ID"); - stmt = conn.createStatement(); - recordsDeleted = stmt.executeUpdate(deleteStringDetailLog + - harvestLogID); - recordsDeletedDetail += recordsDeleted; - stmt.close(); - } - - /* Now prune entries from the HARVEST_LOG table using a single update. - */ - stmt = conn.createStatement(); - recordsDeleted = stmt.executeUpdate(deleteString); - stmt.close(); - - System.out.println(" " + recordsDeletedDetail + - " records deleted from HARVEST_DETAIL_LOG"); - System.out.println(" " + recordsDeleted + - " records deleted from HARVEST_LOG"); - } - catch (SQLException e) { - System.out.println("SQLException: " + e.getMessage()); - } - } - - - /** - * Reads the HARVEST_SITE_SCHEDULE table in the database, creating - * a HarvestSiteSchedule object for each row in the table. - */ - private void readHarvestSiteSchedule() { - HarvestSiteSchedule harvestSiteSchedule; - ResultSet rs; - SQLWarning warn; - Statement stmt; - - String contactEmail; - String dateLastHarvest; - String dateNextHarvest; - String documentListURL; - String ldapDN; - String ldapPwd; - int siteScheduleID; - String unit; - int updateFrequency; - - try { - // Read the HARVEST_SITE_SCHEDULE table - stmt = conn.createStatement(); - rs = stmt.executeQuery("SELECT * FROM HARVEST_SITE_SCHEDULE"); - warn = rs.getWarnings(); - - if (warn != null) { - System.out.println("\n---Warning---\n"); - - while (warn != null) { - System.out.println("Message: " + warn.getMessage()); - System.out.println("SQLState: " + warn.getSQLState()); - System.out.print("Vendor error code: "); - System.out.println(warn.getErrorCode()); - System.out.println(""); - warn = warn.getNextWarning(); - } - } - - while (rs.next()) { - siteScheduleID = rs.getInt("SITE_SCHEDULE_ID"); - documentListURL = rs.getString("DOCUMENTLISTURL"); - ldapDN = rs.getString("LDAPDN"); - ldapPwd = rs.getString("LDAPPWD"); - dateNextHarvest = rs.getString("DATENEXTHARVEST"); - dateLastHarvest = rs.getString("DATELASTHARVEST"); - updateFrequency = rs.getInt("UPDATEFREQUENCY"); - unit = rs.getString("UNIT"); - contactEmail = rs.getString("CONTACT_EMAIL"); - - warn = rs.getWarnings(); - - if (warn != null) { - System.out.println("\n---Warning---\n"); - - while (warn != null) { - System.out.println("Message: " + warn.getMessage()); - System.out.println("SQLState: " + warn.getSQLState()); - System.out.print("Vendor error code: "); - System.out.println(warn.getErrorCode()); - System.out.println(""); - warn = warn.getNextWarning(); - } - } - - harvestSiteSchedule = new HarvestSiteSchedule(this, - siteScheduleID, - documentListURL, - ldapDN, - ldapPwd, - dateNextHarvest, - dateLastHarvest, - updateFrequency, - unit, - contactEmail - ); - harvestSiteScheduleList.add(harvestSiteSchedule); - } - - rs.close(); - stmt.close(); - } - catch (SQLException e) { - System.out.println("Database access failed " + e); - System.exit(1); - } - - } - - - /** - * Sends a report to the Harvester Administrator. The report prints each log - * entry pertaining to this harvest run. - * - * @param maxCodeLevel the maximum code level that should be printed, - * e.g. "warning". Any log entries higher than this - * level will not be printed. - */ - void reportToAdministrator(String maxCodeLevel) { - PrintStream body; - String from = harvesterAdministrator; - String[] fromArray; - MailMessage msg; - int siteScheduleID = 0; - String subject = "Report from Metacat Harvester: " + timestamp; - String to = harvesterAdministrator; - - if (!to.equals("")) { - System.out.println("Sending report to Harvester Administrator at address " - + harvesterAdministrator); - - try { - msg = new MailMessage(smtpServer); - - if (from.indexOf(',') > 0) { - fromArray = from.split(","); - - for (int i = 0; i < fromArray.length; i++) { - if (i == 0) { - msg.from(fromArray[i]); - } - - msg.to(fromArray[i]); - } - } - else if (from.indexOf(';') > 0) { - fromArray = from.split(";"); - - for (int i = 0; i < fromArray.length; i++) { - if (i == 0) { - msg.from(fromArray[i]); - } - - msg.to(fromArray[i]); - } - } - else { - msg.from(from); - msg.to(to); - } - - msg.setSubject(subject); - body = msg.getPrintStream(); - printHarvestHeader(body, siteScheduleID); - printHarvestLog(body, maxCodeLevel, siteScheduleID); - msg.sendAndClose(); - } - catch (IOException e) { - System.out.println("There was a problem sending email to " + to); - System.out.println("IOException: " + e.getMessage()); - } - } - } - - - /** - * Sets the harvest start time for this harvest run. - * - * @param date - */ - public void setHarvestStartTime(Date date) { - harvestStartTime = date; - } - - - /** - * Shuts down Harvester. Performs cleanup operations such as logging out - * of Metacat and disconnecting from the database. - */ - private void shutdown() { - String maxCodeLevel = "debug"; // Print all log entries from level 1 - // ("error") to level 5 ("debug") - int siteScheduleID = 0; - - // Log shutdown operation - System.out.println("Shutting Down Harvester"); - addLogEntry(0, "Shutting Down Harvester", "harvester.HarvesterShutdown", 0, null, ""); - pruneHarvestLog(); - closeConnection(); - // Print log to standard output and then email the Harvester administrator - printHarvestLog(System.out, maxCodeLevel, siteScheduleID); - reportToAdministrator(maxCodeLevel); // Send a copy to harvester admin - } - - - /** - * Initializes Harvester at startup. Connects to the database and to Metacat. - * - * @param nHarvests the nth harvest - * @param maxHarvests the maximum number of harvests that this process - * can run - */ - private void startup(int nHarvests, int maxHarvests) { - Boolean ctm; - Integer lp; - String metacatURL; - Date now = new Date(); - - timestamp = now.toString(); - System.out.println(Harvester.marker); - System.out.print(timestamp + ": Starting Next Harvest"); - if (maxHarvests > 0) { - System.out.print(" (" + nHarvests + "/" + maxHarvests + ")"); - } - System.out.print("\n"); - try { - ctm = Boolean.valueOf(PropertyService.getProperty("harvester.connectToMetacat")); - connectToMetacat = ctm.booleanValue(); - harvesterAdministrator = PropertyService - .getProperty("harvester.administrator"); - smtpServer = PropertyService.getProperty("harvester.smtpServer"); - - lp = Integer.valueOf(PropertyService.getProperty("harvester.logPeriod")); - logPeriod = lp.intValue(); - } catch (NumberFormatException e) { - System.err.println("NumberFormatException: Error parsing logPeriod " - + logPeriod + e.getMessage()); - System.err.println("Defaulting to logPeriod of 90 days"); - logPeriod = 90; - } catch (PropertyNotFoundException pnfe) { - System.out.println("PropertyNotFoundException: Error getting property: " - + pnfe.getMessage()); - return; - } - - conn = getConnection(); - initLogIDs(); - setHarvestStartTime(now); - // Log startup operation - addLogEntry(0, "Starting Up Harvester", "harvester.HarvesterStartup", 0, null, ""); - - if (connectToMetacat()) { - try { - metacatURL = SystemUtil.getServletURL(); - System.out.println("Connecting to Metacat: " + metacatURL); - metacat = MetacatFactory.createMetacatConnection(metacatURL); - } catch (MetacatInaccessibleException e) { - System.out.println("Metacat connection failed." + e.getMessage()); - } catch (Exception e) { - System.out.println("Metacat connection failed." + e.getMessage()); - } - } - } - -}
src/edu/ucsb/nceas/metacat/harvesterClient/HarvesterRegistration.java+0 −808 removed@@ -1,808 +0,0 @@ -/** - * '$RCSfile$' - * Copyright: 2004 University of New Mexico and the - * Regents of the University of California - * - * '$Author$' - * '$Date$' - * '$Revision$' - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package edu.ucsb.nceas.metacat.harvesterClient; - -import com.oreilly.servlet.ParameterParser; -import java.io.IOException; -import java.io.PrintWriter; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.SQLWarning; -import java.sql.Statement; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import edu.ucsb.nceas.metacat.properties.PropertyService; -import edu.ucsb.nceas.metacat.shared.ServiceException; -import edu.ucsb.nceas.utilities.PropertyNotFoundException; - -/** - * HarvesterRegistration is a servlet that implements harvester registration. - * The servlet reads parameters that were entered in a harvester registration - * form, checks the validity of the values, stores the values in the database - * by either inserting, updating, or removing a record in the - * HARVEST_SITE_SCHEDULE table. - * - * @author costa - * - */ -public class HarvesterRegistration extends HttpServlet { - - /* - * Class fields - */ - private static final String CONFIG_DIR = "WEB-INF"; - - private static final long serialVersionUID = 7390084694699704362L; - - /* - * Object fields - */ - private ServletConfig config = null; - private ServletContext context = null; - private String defaultDB; // database connection, from properties file - final private long millisecondsPerDay = (1000 * 60 * 60 * 24); - private String password; // database password, from properties file - private String user; // database user, from properties file - - - /* - * Object methods - */ - - - /** - * Checks validity of user input values. - * - * @param out the PrintWriter output object - * @param documentListURL the Harvest List URL specified by the user - * @param updateFrequency the Harvest Frequency specified by the user - * @return validValues true if all values are valid, else false - */ - private boolean checkValues(PrintWriter out, - String documentListURL, - int updateFrequency - ) { - boolean validValues = true; - - // Check validity of the Harvest List URL field - if (documentListURL.equals("")) { - out.println("A value must be specified in the Harvest List URL field"); - validValues = false; - } - - // Check validity of the Harvest Frequency field - if ((updateFrequency < 0) || (updateFrequency > 99)) { - out.println("Harvest Frequency should be in the range 1 to 99"); - validValues = false; - } - - return validValues; - } - - - /** - * Closes the database connection. - * - * @param conn The connection. - */ - private void closeConnection(Connection conn) { - try { - if (conn != null) { - conn.close(); - } - } - catch (SQLException e) { - // ignored - } - } - - - /** - * Inserts a record to the HARVEST_SITE_SCHEDULE table. - * - * @param out the PrintWriter output object - * @param conn the Connection - * @param siteScheduleID the primary key for the table - * @param contactEmail contact email address of the site user - * @param documentListURL the URL of the harvest list at the site - * @param ldapDN the site user's LDAP DN - * @param ldapPwd the site user's LDAP password - * @param unit the update frequency unit, e.g. "days", "weeks" - * @param updateFrequency the update frequency, an integer in range 1-99 - */ - private void dbInsert(PrintWriter out, - Connection conn, - int siteScheduleID, - String contactEmail, - String documentListURL, - String ldapDN, - String ldapPwd, - String unit, - int updateFrequency - ) { - String dateNextHarvest; - long delta; - Date dnh; // Date of next harvest - Date now; // Today's date - String query; - Statement stmt; - long timeNextHarvest; - SimpleDateFormat writeFormat = new SimpleDateFormat("dd-MMM-yyyy"); - - // Calculate the value of delta, the number of milliseconds between the - // last harvest date and the next harvest date. - delta = updateFrequency * millisecondsPerDay; - - if (unit.equals("weeks")) { - delta *= 7; - } - else if (unit.equals("months")) { - delta *= 30; - } - - now = new Date(); - timeNextHarvest = now.getTime(); - dnh = new Date(timeNextHarvest); - dateNextHarvest = writeFormat.format(dnh); - - try { - stmt = conn.createStatement(); - query = "insert into HARVEST_SITE_SCHEDULE " + - "(SITE_SCHEDULE_ID, CONTACT_EMAIL, DOCUMENTLISTURL, LDAPDN, LDAPPWD, " + - "UNIT, UPDATEFREQUENCY, DATENEXTHARVEST) " + - "values(" + siteScheduleID + "," + - quoteString(contactEmail) + "," + - quoteString(documentListURL) + "," + - quoteString(ldapDN) + "," + - quoteString(ldapPwd) + "," + - quoteString(unit) + "," + - updateFrequency + "," + - quoteString(dateNextHarvest) + ")"; - - System.out.println(query); - stmt.executeUpdate(query); - stmt.close(); - reportResults(out, ldapDN, contactEmail, documentListURL, updateFrequency, - unit, dateNextHarvest); - } - catch(SQLException e) { - System.out.println("SQLException: " + e.getMessage()); - } - } - - - /** - * Removes a record from the HARVEST_SITE_SCHEDULE table. - * - * @param out the PrintWriter output object - * @param conn the Connection - * @param siteScheduleID the primary key for the table - * @param ldapDN the site user's LDAP DN - */ - private void dbRemove(PrintWriter out, - Connection conn, - int siteScheduleID, - String ldapDN - ) { - String query = "DELETE FROM HARVEST_SITE_SCHEDULE WHERE " + - "SITE_SCHEDULE_ID=" + siteScheduleID; - int nRecords = 0; - Statement stmt; - - try { - stmt = conn.createStatement(); - System.out.println(query); - nRecords = stmt.executeUpdate(query); - stmt.close(); - System.out.println(nRecords + " record(s) removed."); - - if (nRecords > 0) { - out.println("Harvester registration removed for user " + ldapDN); - } - else { - out.println("A problem was encountered removing registration for user " - + ldapDN); - } - } - catch(SQLException e) { - System.out.println("SQLException: " + e.getMessage()); - } - } - - - /** - * Updates a record in the HARVEST_SITE_SCHEDULE table. - * - * @param out the PrintWriter output object - * @param conn the Connection - * @param siteScheduleID the primary key for the table - * @param contactEmail contact email address of the site user - * @param documentListURL the URL of the harvest list at the site - * @param ldapDN the site user's LDAP DN - * @param ldapPwd the site user's LDAP password - * @param unit the update frequency unit, e.g. "days", "weeks" - * @param updateFrequency the update frequency, an integer in range 1-99 - * @param dateLastHarvest the date of last harvest, - * e.g. "2004-04-30 00:00:00.0" or "" - */ - private void dbUpdate(PrintWriter out, - Connection conn, - int siteScheduleID, - String contactEmail, - String documentListURL, - String ldapDN, - String ldapPwd, - String unit, - int updateFrequency, - String dateLastHarvest - ) { - String dateNextHarvest; - long delta; - Date dlh; // Date of last harvest - Date dnh; // Date of next harvest - Date now = new Date(); // Today's date -// SimpleDateFormat readFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S"); - SimpleDateFormat readFormat = new SimpleDateFormat("yyyy-MM-dd"); - SimpleDateFormat writeFormat = new SimpleDateFormat("dd-MMM-yyyy"); - Statement stmt; - long timeLastHarvest; - long timeNextHarvest; - long timeNow = now.getTime(); - - // Calculate the value of delta, the number of milliseconds between the - // last harvest date and the next harvest date. - delta = updateFrequency * millisecondsPerDay; - - if (unit.equals("weeks")) { - delta *= 7; - } - else if (unit.equals("months")) { - delta *= 30; - } - - if (dateLastHarvest.equals("")) { - timeNextHarvest = timeNow; - } - else { - try { - dlh = readFormat.parse(dateLastHarvest); - timeLastHarvest = dlh.getTime(); - timeNextHarvest = timeLastHarvest + delta; - timeNextHarvest = Math.max(timeNextHarvest, timeNow); - } - catch (ParseException e) { - System.out.println("Error parsing date: " + dateLastHarvest + - " " + e.getMessage()); - timeNextHarvest = timeNow; - } - } - - dnh = new Date(timeNextHarvest); - dateNextHarvest = writeFormat.format(dnh); - - try { - stmt = conn.createStatement(); - stmt.executeUpdate("UPDATE HARVEST_SITE_SCHEDULE SET CONTACT_EMAIL=" + - quoteString(contactEmail) + - " WHERE SITE_SCHEDULE_ID = " + siteScheduleID); - stmt.executeUpdate("UPDATE HARVEST_SITE_SCHEDULE SET DOCUMENTLISTURL=" + - quoteString(documentListURL) + - " WHERE SITE_SCHEDULE_ID = " + siteScheduleID); - stmt.executeUpdate("UPDATE HARVEST_SITE_SCHEDULE SET LDAPPWD=" + - quoteString(ldapPwd) + - " WHERE SITE_SCHEDULE_ID = " + siteScheduleID); - stmt.executeUpdate("UPDATE HARVEST_SITE_SCHEDULE SET UNIT=" + - quoteString(unit) + - " WHERE SITE_SCHEDULE_ID = " + siteScheduleID); - stmt.executeUpdate("UPDATE HARVEST_SITE_SCHEDULE SET UPDATEFREQUENCY=" + - updateFrequency + - " WHERE SITE_SCHEDULE_ID = " + siteScheduleID); - stmt.executeUpdate("UPDATE HARVEST_SITE_SCHEDULE SET DATENEXTHARVEST=" + - quoteString(dateNextHarvest) + - " WHERE SITE_SCHEDULE_ID = " + siteScheduleID); - stmt.close(); - reportResults(out, ldapDN, contactEmail, documentListURL, updateFrequency, - unit, dateNextHarvest); - } - catch(SQLException e) { - System.out.println("SQLException: " + e.getMessage()); - } - - } - - - /** - * Handles GET method requests. Displays the current registration info for - * this user (if any), then allows the user to make changes and register or - * unregister. - * - * @param req the request - * @param res the response - * @throws ServletException - * @throws IOException - */ - public void doGet(HttpServletRequest req, HttpServletResponse res) - throws ServletException, IOException { - Connection conn = getConnection(); - String contactEmail = ""; - String documentListURL = "http://"; - HttpSession httpSession; - String ldapDN; - String ldapPwd; - String query; - int siteScheduleID; - Statement stmt; - String unit = "days"; - int updateFrequency = 1; - - httpSession = req.getSession(false); - - if (httpSession == null) { - System.out.println("User did not log in."); - return; - } - - // The user name and password are stored as session attributes by the - // HarvesterRegistrationLogin servlet. - ldapDN = (String) httpSession.getAttribute("username"); - ldapPwd = (String) httpSession.getAttribute("password"); - - siteScheduleID = getSiteScheduleID(conn, ldapDN); - - // If the user is already registered, query the existing values and - // initialize the form with them. - if (siteScheduleID != 0) { - query = "SELECT * FROM HARVEST_SITE_SCHEDULE WHERE SITE_SCHEDULE_ID=" + - siteScheduleID; - - try { - stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery(query); - - while (rs.next()) { - contactEmail = rs.getString("CONTACT_EMAIL"); - documentListURL = rs.getString("DOCUMENTLISTURL"); - updateFrequency = rs.getInt("UPDATEFREQUENCY"); - unit = rs.getString("UNIT"); - } - - stmt.close(); - } - catch (SQLException ex) { - System.out.println("SQLException: " + ex.getMessage()); - } - } - - res.setContentType("text/html"); - PrintWriter out = res.getWriter(); - - // Print the registration form - out.println("<HTML>"); - out.println("<HEAD>"); - out.println("<TITLE>Metacat Harvester Registration</TITLE>"); - out.println("</HEAD>"); - out.println("<BODY>"); - out.println("<H2><B>Metacat Harvester Registration</B></H2>"); - out.println("<FORM METHOD=POST>"); // posts to itself - out.println("Fill out the form below to schedule regular harvests of EML "); - out.println("documents from your site.<BR>"); - out.println("To register or changes values, enter all values "); - out.println("below and click <B>Register</B>. "); - out.println("To unregister, simply click <B>Unregister</B>.<BR>"); - out.println("<table>"); - out.println("<tr>"); - out.println("<td>"); - out.println("Email address:"); - out.println("</td>"); - out.println("<td>"); - out.println("<INPUT TYPE=TEXT NAME=contactEmail SIZE=30 VALUE="); - out.println(contactEmail + ">"); - out.println("</td>"); - out.println("</tr>"); - out.println("<tr>"); - out.println("<td>"); - out.println("Harvest List URL:"); - out.println("</td>"); - out.println("<td>"); - out.println("<INPUT TYPE=TEXT NAME=documentListURL SIZE=50 VALUE="); - out.println(documentListURL + ">"); - out.println("</td>"); - out.println("</tr>"); - out.println("<tr>"); - out.println("<td>"); - out.println("Harvest Frequency"); - out.println("</td>"); - out.println("<td>"); - out.println("</td>"); - out.println("</tr>"); - out.println("<tr>"); - out.println("<td>"); - out.println(" Once every (1-99):"); - out.println("</td>"); - out.println("<td>"); - out.println("<INPUT TYPE=TEXT NAME=updateFrequency "); - out.println("MAXLENGTH=2 SIZE=2 VALUE="); - out.println(updateFrequency + ">"); - out.println("</td>"); - out.println("</tr>"); - out.println("<tr>"); - out.println("<td>"); - //out.println("Unit:"); - out.println("</td>"); - out.println("<td>"); - out.println("<INPUT TYPE=RADIO "); - if (unit.equals("days")) out.println("CHECKED "); - out.println("NAME=unit VALUE=days>day(s)"); - out.println("<INPUT TYPE=RADIO "); - if (unit.equals("weeks")) out.println("CHECKED "); - out.println("NAME=unit VALUE=weeks>week(s)"); - out.println("<INPUT TYPE=RADIO "); - if (unit.equals("months")) out.println("CHECKED "); - out.println("NAME=unit VALUE=months>month(s)"); - out.println("</td>"); - out.println("</tr>"); - out.println("<tr></tr>"); - out.println("<tr>"); - out.println("<td>"); - out.println("<INPUT TYPE=SUBMIT NAME=register VALUE=Register>"); - out.println("<INPUT TYPE=SUBMIT NAME=unregister VALUE=Unregister>"); - out.println("</td>"); - out.println("<td>"); - out.println("</td>"); - out.println("</tr>"); - out.println("</table>"); - out.println("</BODY>"); - out.println("</HTML>"); - } - - - /** - * Handles POST method requests. Reads values as entered by the user in the - * harvester registration form and checks them for validity. Then either - * inserts, updates, or removes a record in the HARVEST_SITE_SCHEDULE table. - * - * @param req the request - * @param res the response - * @throws ServletException - * @throws IOException - */ - public void doPost(HttpServletRequest req, HttpServletResponse res) - throws ServletException, IOException { - Connection conn = getConnection(); - int maxValue; - boolean remove = false; // if true, remove record - int siteScheduleID; - String contactEmail; - String dateLastHarvest; - String dateNextHarvest; - String documentListURL; - HttpSession httpSession; - String ldapDN; - String ldapPwd; - PrintWriter out; - ParameterParser parameterParser = new ParameterParser(req); - String register; - String unit; - String unregister; - int updateFrequency; - boolean validValues; - - httpSession = req.getSession(false); - - if (httpSession == null) { - System.out.println("User did not log in."); - return; - } - - // The user name and password are stored as session attributes by the - // HarvesterRegistrationLogin servlet - ldapDN = (String) httpSession.getAttribute("username"); - ldapPwd = (String) httpSession.getAttribute("password"); - - contactEmail = parameterParser.getStringParameter("contactEmail", "None"); - documentListURL = parameterParser.getStringParameter("documentListURL", ""); - unit = parameterParser.getStringParameter("unit", "days"); - updateFrequency = parameterParser.getIntParameter("updateFrequency", 1); - register = parameterParser.getStringParameter("register", ""); - unregister = parameterParser.getStringParameter("unregister", ""); - remove = (unregister.equalsIgnoreCase("Unregister")); - siteScheduleID = getSiteScheduleID(conn, ldapDN); - dateLastHarvest = getDateLastHarvest(conn, siteScheduleID); - - res.setContentType("text/plain"); - out = res.getWriter(); - - if (!remove) { - validValues = checkValues(out, documentListURL, updateFrequency); - - if (!validValues) { - return; - } - } - - if (siteScheduleID == 0) { - if (remove) { - // The user clicked Unregister, but no existing record was found - System.out.println("Unable to remove record for user " + ldapDN); - System.out.println("No matching record found in HARVEST_SITE_SCHEDULE"); - out.println("No record found for user " + ldapDN + "."); - out.println("Since you were not registered, no action was taken."); - } - else { - maxValue = getMaxValue(conn, - "HARVEST_SITE_SCHEDULE", - "SITE_SCHEDULE_ID"); - siteScheduleID = maxValue + 1; - dbInsert(out, conn, siteScheduleID, contactEmail, documentListURL, - ldapDN, ldapPwd, unit, updateFrequency); - } - } - else { - // Either update or remove an existing record - if (remove) { - dbRemove(out, conn, siteScheduleID, ldapDN); - } - else { - dbUpdate(out, conn, siteScheduleID, contactEmail, documentListURL, - ldapDN, ldapPwd, unit, updateFrequency, dateLastHarvest); - } - } - - closeConnection(conn); - } - - - /** - * Gets a database connection. - * - * @return conn, the Connection object - */ - private Connection getConnection() { - Connection conn = null; - SQLWarning warn; - - // Make the database connection - try { - System.out.println("Getting connection to Harvester tables"); - conn = DriverManager.getConnection(defaultDB, user, password); - - // If a SQLWarning object is available, print its warning(s). - // There may be multiple warnings chained. - warn = conn.getWarnings(); - - if (warn != null) { - while (warn != null) { - System.out.println("SQLState: " + warn.getSQLState()); - System.out.println("Message: " + warn.getMessage()); - System.out.println("Vendor: " + warn.getErrorCode()); - System.out.println(""); - warn = warn.getNextWarning(); - } - } - } - catch (SQLException e) { - System.out.println("Database access failed " + e); - } - - return conn; - } - - - /** - * Gets the date of last harvest value from the HARVEST_SITE_SCHEDULE table, - * given a siteScheduleID value (the primary key). - * - * @param conn the connection - * @param siteScheduleID the primary key - * @return dateLastHarvest the string stored in the table, e.g. - * "2004-04-30 00:00:00.0" or "" - */ - private String getDateLastHarvest(Connection conn, int siteScheduleID) { - String dateLastHarvest = ""; - String query = "SELECT DATELASTHARVEST FROM HARVEST_SITE_SCHEDULE " + - "WHERE SITE_SCHEDULE_ID=" + siteScheduleID; - Statement stmt; - - try { - stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery(query); - - while (rs.next()) { - dateLastHarvest = rs.getString("DATELASTHARVEST"); - if (rs.wasNull()) { - dateLastHarvest = ""; // Convert null value to empty string - } - } - - stmt.close(); - } - catch (SQLException ex) { - System.out.println("SQLException: " + ex.getMessage()); - } - - return dateLastHarvest; - } - - - /** - * Gets the maximum value of an integer field from a table, given the table - * name and the field name. - * - * @param tableName the database table name - * @param fieldName the field name of the integer field in the table - * @return the maximum integer stored in the fieldName field of tableName - */ - private int getMaxValue(Connection conn, String tableName, String fieldName) { - int maxValue = 0; - int fieldValue; - String query = "SELECT " + fieldName + " FROM " + tableName; - Statement stmt; - - try { - stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery(query); - - while (rs.next()) { - fieldValue = rs.getInt(fieldName); - maxValue = Math.max(maxValue, fieldValue); - } - - stmt.close(); - } - catch (SQLException ex) { - System.out.println("SQLException: " + ex.getMessage()); - } - - return maxValue; - } - - - /** - * Gets the siteScheduleID value from the HARVEST_SITE_SCHEDULE table, given - * the value of the ldapDN field. - * - * @param conn the database connection - * @param ldapDN the ldap DN string - * @return siteScheduleID, an integer, the primary key - */ - private int getSiteScheduleID(Connection conn, String ldapDN) { - String ldapDNValue; // value of LDAPDN field - String query = "SELECT * FROM HARVEST_SITE_SCHEDULE"; - int siteScheduleID = 0; - Statement stmt; - - - try { - stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery(query); - - while (rs.next()) { - ldapDNValue = rs.getString("LDAPDN"); - - if (ldapDNValue.equalsIgnoreCase(ldapDN)) { - siteScheduleID = rs.getInt("SITE_SCHEDULE_ID"); - } - } - - stmt.close(); - } - catch (SQLException ex) { - System.out.println("SQLException: " + ex.getMessage()); - } - - return siteScheduleID; - } - - - /** - * Initializes the servlet. Reads properties and initializes object fields. - * - * @throws ServletException - */ - public void init(ServletConfig config) throws ServletException { - String database; - String dbDriver = ""; - String dirPath; - - super.init(config); - this.config = config; - this.context = config.getServletContext(); - dirPath = context.getRealPath(CONFIG_DIR); - - try { - ServletContext context = config.getServletContext(); - PropertyService.getInstance(context); - - dbDriver = PropertyService.getProperty("database.driver"); - defaultDB = PropertyService.getProperty("database.connectionURI"); - password = PropertyService.getProperty("database.password"); - user = PropertyService.getProperty("database.user"); - } catch (ServiceException se) { - System.out.println("Error initializing PropertyService: " + se.getMessage()); - } catch (PropertyNotFoundException pnfe) { - System.out.println("Error reading property: " + pnfe.getMessage()); - } - - // Load the jdbc driver - try { - Class.forName(dbDriver); - } catch (ClassNotFoundException e) { - System.out.println("Can't load driver " + e); - } - } - - - /** - * Surrounds a string with single quotes. - * - * @param str - * the original string - * @return the quoted string - */ - private String quoteString(String str) { - return "'" + str + "'"; - } - - - /** - * Reports the results of an insert or update to the client. - * - * @param out the PrintWriter - * @param ldapDN the LDAP DN string - * @param contactEmail the email address of the site contact - * @param documentListURL the URL of the harvester document list at the site - * @param updateFrequency the harvest update frequency - * @param unit the unit (e.g. "days", "weeks", "months" - * @param dateNextHarvest the date of the next scheduled harvest - */ - private void reportResults(PrintWriter out, - String ldapDN, - String contactEmail, - String documentListURL, - int updateFrequency, - String unit, - String dateNextHarvest - ) { - out.println("Harvester registration updated for " + ldapDN); - out.println(" Email Address: " + contactEmail); - out.println(" Harvest List URL: " + documentListURL); - out.println(" Harvest Frequency: " + updateFrequency); - out.println(" Unit: " + unit); - out.println(""); - out.println("Next scheduled harvest date: " + dateNextHarvest); - } - -}
src/edu/ucsb/nceas/metacat/harvesterClient/HarvesterRegistrationLogin.java+0 −135 removed@@ -1,135 +0,0 @@ -/** - * '$RCSfile$' - * Copyright: 2004 University of New Mexico and the - * Regents of the University of California - * - * '$Author$' - * '$Date$' - * '$Revision$' - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package edu.ucsb.nceas.metacat.harvesterClient; - -import java.io.PrintWriter; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import edu.ucsb.nceas.metacat.AuthSession; -import edu.ucsb.nceas.metacat.properties.PropertyService; -import edu.ucsb.nceas.metacat.util.SystemUtil; - - -/** - * HarvesterRegistrationLogin implements a servlet to login to the Harvester - * Registration servlet. - */ -public class HarvesterRegistrationLogin extends HttpServlet { - - final String LDAP_DOMAIN = ",dc=ecoinformatics,dc=org"; - - /** - * Handle "GET" method requests from HTTP clients - * - * @param req The request - * @param res The response - * @throws ServletException, java.io.IOException - */ - public void doGet(HttpServletRequest req, HttpServletResponse res) - throws ServletException, java.io.IOException { - handleGetOrPost(req, res); - } - - - /** - * Handle "POST" method requests from HTTP clients - * - * @param req The request - * @param res The response - * @throws ServletException, java.io.IOException - */ - public void doPost(HttpServletRequest req, HttpServletResponse res) - throws ServletException, java.io.IOException { - handleGetOrPost(req, res); - } - - - /** - * Handle "GET" or "POST" method requests from HTTP clients - * - * @param req The request - * @param res The response - * @throws ServletException, java.io.IOException - */ - private void handleGetOrPost(HttpServletRequest req, - HttpServletResponse res) - throws ServletException, java.io.IOException { - AuthSession authSession; - String authSessionMessage; - HttpSession httpSession; - boolean isValid; - String o = req.getParameter("o"); - String organization; - String passwd = req.getParameter("passwd"); - PrintWriter out = res.getWriter(); - String uid = req.getParameter("uid"); - String user; - - if ((uid == null) || (uid.equals(""))) { - out.println("Invalid login: no Username specified."); - return; - } - else if ((o == null) || (o.equals(""))) { - out.println("Invalid login: no Organization selected."); - return; - } - else if ((passwd == null) || (passwd.equals(""))) { - out.println("Invalid login: no Password specified."); - return; - } - else { - user = "uid=" + uid + ",o=" + o + LDAP_DOMAIN; - } - - res.setContentType("text/plain"); - - try { - authSession = new AuthSession(); - isValid = authSession.authenticate(req, user, passwd); - authSessionMessage = authSession.getMessage(); - System.out.println("authSession.authenticate(): "+authSessionMessage); - out.println("authSession.authenticate(): " + authSessionMessage); - - if (isValid) { - httpSession = req.getSession(true); - httpSession.setAttribute("username", user); - httpSession.setAttribute("password", passwd); - String context = PropertyService.getProperty("application.context"); - res.sendRedirect("/" + context + "/harvesterRegistration"); - } - else { - out.println("Invalid login"); - } - } - catch (Exception e) { - System.out.println("Error in AuthSession()" + e.getMessage()); - } - } -}
src/edu/ucsb/nceas/metacat/harvesterClient/HarvesterServlet.java+0 −100 removed@@ -1,100 +0,0 @@ -/** - * '$RCSfile$' - * Copyright: 2004 University of New Mexico and the - * Regents of the University of California - * - * '$Author$' - * '$Date$' - * '$Revision$' - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package edu.ucsb.nceas.metacat.harvesterClient; - -import javax.servlet.*; -import javax.servlet.http.*; -/** - * HarvesterServlet class allows Harvester to be run as a background - * process. This eliminates the need to run Harvester in a terminal window. - * To activate this servlet, uncomment the HarvesterServlet entry in the - * appropriate 'lib/web.xml.tomcat*' file. - * - * @author costa - */ -public class HarvesterServlet extends HttpServlet implements Runnable { - - /* - * Class fields - */ - private static final String SCHEMA_DIR = "harvester"; - private static String SCHEMA_LOCATION; - private static final String SCHEMA_NAME = "harvestList.xsd"; - static final long serialVersionUID = 0; // Needed for Eclipse warning. - - /* - * Object fields - */ - Thread harvesterThread; // background Harvester thread - - - /** - * When the thread is destroyed, sets the Harvester.keepRunning flag to false. - */ - public void destroy() { - Harvester.setKeepRunning(false); - } - - - /** - * Initializes the servlet. Reads properties and initializes object fields. - * - * @throws ServletException - */ - public void init(ServletConfig config) throws ServletException { - ServletContext context = null; - String fileSeparator = System.getProperty("file.separator"); - String schemaPath; - - super.init(config); - context = config.getServletContext(); - schemaPath = context.getRealPath(SCHEMA_DIR) + fileSeparator + SCHEMA_NAME; - SCHEMA_LOCATION = "eml://ecoinformatics.org/harvestList " + schemaPath; - harvesterThread = new Thread(this); - harvesterThread.setPriority(Thread.MIN_PRIORITY); // be a good citizen - harvesterThread.start(); - } - - - /** - * Runs the Harvester main program in a separate thread. First sleeps for - * 30 seconds to give Metacat a chance to fully initialize. - */ - public void run() { - String[] args = new String[2]; - args[0] = "false"; // Set to true if in command line mode or test mode - args[1] = SCHEMA_LOCATION; - - try { - Thread.sleep(30000); // Sleep 30 seconds before starting Harvester - } - catch (InterruptedException e) { - System.err.println("InterruptedException: " + e.getMessage()); - } - - Harvester.main(args); - } - -}
src/edu/ucsb/nceas/metacat/harvesterClient/HarvestListEditor.java+0 −1199 removed@@ -1,1199 +0,0 @@ -/** - * '$RCSfile$' - * Copyright: 2004 University of New Mexico and the - * Regents of the University of California - * - * '$Author$' - * '$Date$' - * '$Revision$' - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package edu.ucsb.nceas.metacat.harvesterClient; - -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.io.Reader; -import java.util.Properties; -import javax.swing.JButton; -import javax.swing.JFileChooser; -import javax.swing.JFrame; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTable; -import javax.swing.KeyStroke; -import javax.swing.ListSelectionModel; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; -import javax.swing.table.AbstractTableModel; -import javax.swing.table.TableColumn; -import javax.swing.table.TableModel; -import javax.swing.text.Document; -import javax.xml.parsers.ParserConfigurationException; -import org.xml.sax.Attributes; -import org.xml.sax.ContentHandler; -import org.xml.sax.ErrorHandler; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.DefaultHandler; -import org.xml.sax.helpers.XMLReaderFactory; - -/** - * The Harvest List Editor reads a Harvest List XML file and displays it as a - * JTable. Allows user to add, modify, or delete <Document> elements in the - * Harvest List, and save changes back to the disk. - * - */ -public class HarvestListEditor extends JFrame implements ActionListener { - - String clipboardDocumentType = ""; - String clipboardDocumentURL = ""; - String clipboardIdentifier = ""; - String clipboardRevision = ""; - String clipboardScope = ""; - JButton copyButton; - JButton cutButton; - String defaultDocumentType = "eml://ecoinformatics.org/eml-2.0.1"; - String defaultDocumentURL = "http://"; - String defaultHarvestList = ""; - String defaultIdentifier = "1"; - String defaultRevision = "1"; - String defaultScope = "dataset"; - Document doc; - JScrollPane docPane; - JFileChooser fileChooser = new JFileChooser(); - File harvestListFile; - boolean harvestListHasChanged = false; - JMenuBar menuBar; - final int numColumns = 6; - final int numRows = 1200; - JButton pasteButton; - JButton pasteDefaultsButton; - Properties properties; - private String schemaLocation = - "eml://ecoinformatics.org/harvestList harvestList.xsd"; - int selectedRow = -1; - final JTable table; - TableModel tableModel; - File tempFile; - String title = "Harvest List Editor"; - - // Menu items - JMenuItem exitMenuItem = new JMenuItem("Exit"); - JMenuItem newMenuItem = new JMenuItem("New"); - JMenuItem openMenuItem = new JMenuItem("Open..."); - JMenuItem saveMenuItem = new JMenuItem("Save"); - JMenuItem saveAsMenuItem = new JMenuItem("Save As..."); - JMenuItem validateMenuItem = new JMenuItem("Validate"); - - - /** - * The main program. Instantiate the main frame, a HarvestListEditor object. - * - * @param args - */ - public static void main(String[] args) { - HarvestListEditor harvestListEditor = new HarvestListEditor(); - } - - - /** - * Constructor for HarvestListEditor class. - */ - public HarvestListEditor() { - super("Harvest List Editor"); - - JPanel buttonPanel = new JPanel(); - String[] fileItems = - new String[] {"New", "Open...", "Save", "Save As...", "Exit"}; - JMenu fileMenu = new JMenu("File"); - char[] fileShortCuts = {'N', 'O', 'S', 'A', 'X'}; - TableColumn tableColumn; - - loadProperties(); - setSize(1000, 400); - setDefaultCloseOperation(EXIT_ON_CLOSE); - menuBar = new JMenuBar(); - - /* - * Add menu items to the File menu - */ - newMenuItem.setAccelerator(KeyStroke.getKeyStroke('N', - java.awt.Event.CTRL_MASK, - false)); - newMenuItem.addActionListener(this); - fileMenu.add(newMenuItem); - - openMenuItem.setAccelerator(KeyStroke.getKeyStroke('O', - java.awt.Event.CTRL_MASK, - false)); - openMenuItem.addActionListener(this); - fileMenu.add(openMenuItem); - - saveMenuItem.setAccelerator(KeyStroke.getKeyStroke('S', - java.awt.Event.CTRL_MASK, - false)); - saveMenuItem.addActionListener(this); - saveMenuItem.setEnabled(false); - fileMenu.add(saveMenuItem); - - saveAsMenuItem.setAccelerator(KeyStroke.getKeyStroke('A', - java.awt.Event.CTRL_MASK, - false)); - saveAsMenuItem.addActionListener(this); - fileMenu.add(saveAsMenuItem); - - validateMenuItem.setAccelerator(KeyStroke.getKeyStroke('V', - java.awt.Event.CTRL_MASK, - false)); - validateMenuItem.addActionListener(this); - fileMenu.add(validateMenuItem); - - exitMenuItem.setAccelerator(KeyStroke.getKeyStroke('X', - java.awt.Event.CTRL_MASK, - false)); - exitMenuItem.addActionListener(this); - fileMenu.add(exitMenuItem); - - menuBar.add(fileMenu); // Add the File menu to the menu bar - setJMenuBar(menuBar); // Set the frame's menu bar to this menu bar - - //table = new JTable(numRows, numColumns); - table = new JTable(new HarvestListTableModel()); - table.setPreferredScrollableViewportSize(new Dimension(900, 300)); - tableColumn = table.getColumnModel().getColumn(0); - tableColumn.setPreferredWidth(30); - tableColumn = table.getColumnModel().getColumn(1); - tableColumn.setPreferredWidth(200); - tableColumn = table.getColumnModel().getColumn(2); - tableColumn.setPreferredWidth(50); - tableColumn = table.getColumnModel().getColumn(3); - tableColumn.setPreferredWidth(50); - tableColumn = table.getColumnModel().getColumn(4); - tableColumn.setPreferredWidth(250); - tableColumn = table.getColumnModel().getColumn(5); - tableColumn.setPreferredWidth(320); - - table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - tableModel = table.getModel(); - initHarvestList(); - - //Ask to be notified of selection changes. - ListSelectionModel rowSM = table.getSelectionModel(); - - rowSM.addListSelectionListener(new ListSelectionListener() { - public void valueChanged(ListSelectionEvent e) { - ListSelectionModel lsm; - - //Ignore extra messages. - if (e.getValueIsAdjusting()) return; - - lsm = (ListSelectionModel)e.getSource(); - - // If now row is selected, disable all buttons. - if (lsm.isSelectionEmpty()) { - selectedRow = -1; - cutButton.setEnabled(false); - copyButton.setEnabled(false); - pasteButton.setEnabled(false); - pasteDefaultsButton.setEnabled(false); - } - // If a row is selected, manage the buttons based on the selected row - // and the current clipboard values. - else { - selectedRow = lsm.getMinSelectionIndex(); - manageButtons(selectedRow); - } - } - }); - - docPane = new JScrollPane(table); - getContentPane().add(docPane, BorderLayout.CENTER); - - cutButton = new JButton("Cut"); - copyButton = new JButton("Copy"); - pasteButton = new JButton("Paste"); - pasteDefaultsButton = new JButton("Paste Defaults"); - - // Action listener for the Copy button. - copyButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent ae) { - copyRow(selectedRow); - manageButtons(selectedRow); - harvestListHasChanged = true; - } - } - ); - - // Action listener for the Cut button. - cutButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent ae) { - cutRow(selectedRow); - manageButtons(selectedRow); - harvestListHasChanged = true; - } - } - ); - - // Action listener for the Paste button. - pasteButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent ae) { - pasteRow(selectedRow); - manageButtons(selectedRow); - harvestListHasChanged = true; - } - } - ); - - // Action listener for the Paste Defaults button. - pasteDefaultsButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent ae) { - pasteDefaultValues(selectedRow); - manageButtons(selectedRow); - harvestListHasChanged = true; - } - } - ); - - cutButton.setEnabled(false); - copyButton.setEnabled(false); - pasteButton.setEnabled(false); - pasteDefaultsButton.setEnabled(false); - buttonPanel.add(cutButton); - buttonPanel.add(copyButton); - buttonPanel.add(pasteButton); - buttonPanel.add(pasteDefaultsButton); - buttonPanel.setOpaque(true); - getContentPane().add(buttonPanel, BorderLayout.SOUTH); - - // If the default Harvest List option has a value, and the file exists, - // loads its contents. - // - if ((defaultHarvestList != null) && (!defaultHarvestList.equals(""))) { - harvestListFile = new File(defaultHarvestList); - if (harvestListFile.exists()) { - try { - loadHarvestList(harvestListFile); - saveMenuItem.setEnabled(true); - } - catch (ParserConfigurationException e) { - System.out.println("Error parsing Harvest List: " + e.getMessage()); - } - } - else { - System.out.println( - "Warning: the default harvest list file that was specified in the " + - ".harvestListEditor configuration file does not exist:\n" + - harvestListFile - ); - fileNew(); - } - } - else { - fileNew(); - } - - try { - tempFile = File.createTempFile("harvestListTemp", ".xml"); - } - catch (IOException ioe) { - System.out.println("Error creating temporary file: " + ioe.getMessage()); - } - - setVisible(true); - } - - - /** - * Implements action listeners for menu items. - * - * @param e An ActionEvent object, determines the menu item that was - * selected. - */ - public void actionPerformed(ActionEvent e) { - if ((e.getActionCommand()).equals("New")) { - fileNew(); - } - else if ((e.getActionCommand()).equals("Open...")) { - fileOpen(); - } - else if ((e.getActionCommand()).equals("Save")) { - fileSave(); - } - else if ((e.getActionCommand()).equals("Save As...")) { - fileSaveAs(); - } - else if ((e.getActionCommand()).equals("Validate")) { - fileValidate(); - } - else if ((e.getActionCommand()).equals("Exit")) { - fileExit(); - } - } - - - /** - * Adds a new row to the table, setting values for each of the five columns - * in the row. - * - * @param rowIndex the row index - * @param scope the scope string - * @param identifier the identifier string - * @param revision the revision string - * @param documentType the document type - * @param documentURL the document URL - */ - void addRow(int rowIndex, String scope, String identifier, String revision, - String documentType, String documentURL) { - tableModel.setValueAt(scope, rowIndex, 1); - tableModel.setValueAt(identifier, rowIndex, 2); - tableModel.setValueAt(revision, rowIndex, 3); - tableModel.setValueAt(documentType, rowIndex, 4); - tableModel.setValueAt(documentURL, rowIndex, 5); - } - - - /** - * Composes a single tag line to be written in the Harvest List. - * - * @param indentLevel the number of spaces to begin the line with - * @param tag the tag name - * @param text the text to insert within the begin and end tags - * @return line the composed line - */ - String composeLine(int indentLevel, String tag, String text) { - String line = ""; - - for (int i = 0; i < indentLevel; i++) { - line += " "; - } - - line += "<" + tag + ">"; - line += text; - line += "</" + tag + ">"; - - return line; - } - - - /** - * Clears all rows in the table, setting all values to null. - */ - void clearHarvestList() { - for (int rowIndex = 0; rowIndex < numRows; rowIndex++) { - clearRow(rowIndex); - } - } - - - /** - * Clears a single row in the tables, setting all five fields to null. - * - * @param rowIndex the index to the table row to be cleared - */ - void clearRow(int rowIndex) { - final String nil = ""; - - tableModel.setValueAt(nil, rowIndex, 1); - tableModel.setValueAt(nil, rowIndex, 2); - tableModel.setValueAt(nil, rowIndex, 3); - tableModel.setValueAt(nil, rowIndex, 4); - tableModel.setValueAt(nil, rowIndex, 5); - } - - - /** - * Copies the values in a given table row to the clipboard. - * - * @param rowIndex the index of the table row to be copied - */ - void copyRow(int rowIndex) { - clipboardScope = (String) tableModel.getValueAt(rowIndex, 1); - clipboardIdentifier = (String) tableModel.getValueAt(rowIndex, 2); - clipboardRevision = (String) tableModel.getValueAt(rowIndex, 3); - clipboardDocumentType = (String) tableModel.getValueAt(rowIndex, 4); - clipboardDocumentURL = (String) tableModel.getValueAt(rowIndex, 5); - } - - - /** - * Cuts a row from the table. The row is copied to the clipboard and then - * cleared. - * - * @param rowIndex the index of the table row to be copied - */ - void cutRow(int rowIndex) { - copyRow(rowIndex); - clearRow(rowIndex); - } - - - /** - * Exit from the Harvest List Editor. Prompt to save changes if appropriate. - */ - void fileExit() { - int value; - - if (harvestListHasChanged) { - value = saveChangesDialog(); - - if (value == JOptionPane.YES_OPTION) { - try { - // Save the changes then exit - // - fileSave(); - System.exit(0); - } - catch (Exception exception) { - exception.printStackTrace(); - } - } - else if (value == JOptionPane.NO_OPTION) { - // Exit without saving changes - System.exit(0); - } - } - else { - System.exit(0); - } - } - - - /** - * Replace the current Harvest List with an empty Harvest List. Prompt to save - * changes if appropriate. - */ - void fileNew() { - int value; - - if (harvestListHasChanged) { - value = saveChangesDialog(); - - if (value == JOptionPane.YES_OPTION) { - try { - fileSave(); - } - catch (Exception exception) { - exception.printStackTrace(); - } - } - else if (value == JOptionPane.CANCEL_OPTION) { - return; - } - } - - clearHarvestList(); - harvestListFile = null; - setTitle(title + ": (Untitled)"); - saveMenuItem.setEnabled(false); - harvestListHasChanged = false; - } - - - /** - * Opens a file dialog to load a Harvest List. Prompts to save changes to the - * current Harvest List if appropriate. - */ - void fileOpen() { - int value; - - if (harvestListHasChanged) { - value = saveChangesDialog(); - - if (value == JOptionPane.YES_OPTION) { - try { - fileSave(); - } - catch (Exception exception) { - exception.printStackTrace(); - } - } - else if (value == JOptionPane.CANCEL_OPTION) { - return; - } - } - - value = fileChooser.showOpenDialog(HarvestListEditor.this); - - if (value == JFileChooser.APPROVE_OPTION) { - harvestListFile = fileChooser.getSelectedFile(); - try { - clearHarvestList(); - loadHarvestList(harvestListFile); - } - catch (ParserConfigurationException e) { - System.out.println("Error parsing Harvest List: " + e.getMessage()); - } - harvestListHasChanged = false; - saveMenuItem.setEnabled(true); - } - } - - - /** - * Save the current Harvest List to disk. - */ - void fileSave() { - if (harvestListFile != null) { - writeFile(harvestListFile); - harvestListHasChanged = false; - } - else { - System.out.println("No action taken"); - } - } - - - /** - * Save the current Harvest List as a potentially different file name. - */ - void fileSaveAs() { - int returnVal; - - returnVal = fileChooser.showOpenDialog(HarvestListEditor.this); - - if (returnVal == JFileChooser.APPROVE_OPTION) { - harvestListFile = fileChooser.getSelectedFile(); - writeFile(harvestListFile); - setTitle(title + ": " + harvestListFile.getName()); - saveMenuItem.setEnabled(true); - harvestListHasChanged = false; - } - } - - - /** - * Validate the Harvest List that is currently stored in the table. This is - * implemented by writing the Harvest List to a temporary file and then - * running the SAX parser on the temporary file. - */ - void fileValidate() { - FileInputStream fis; - HarvestListHandler harvestListHandler = new HarvestListHandler(); - InputStreamReader inputStreamReader; - boolean loadHarvestList = false; - boolean validateHarvestList = true; - - writeFile(tempFile); - - try { - fis = new FileInputStream(tempFile); - inputStreamReader = new InputStreamReader(fis); - harvestListHandler.runParser(this, inputStreamReader, schemaLocation, - loadHarvestList, validateHarvestList); - fis.close(); - tempFile.delete(); - harvestListMessage("Harvest List is valid"); - } - catch (SAXException e) { - harvestListMessage("Validation error: " + e.getMessage()); - } - catch (ClassNotFoundException e) { - System.out.println("ClassNotFoundException: " + e.getMessage()); - } - catch (IOException ioe) { - System.out.println("Error opening file: " + ioe.getMessage()); - } - } - - - /** - * Displays a short message in a dialog box. - * - * @param message the message text - */ - void harvestListMessage(String message) { - JOptionPane.showMessageDialog(this, message); - } - - - /** - * Initializes the Harvest List table, filling column 0 with row numbers. - * This is a non-editable column, so its values should never change after - * this point. - */ - void initHarvestList() { - for (int rowIndex = 0; rowIndex < numRows; rowIndex++) { - tableModel.setValueAt(new Integer(rowIndex + 1).toString(), rowIndex, 0); - } - } - - - /** - * Determines whether the clipboard is currently empty. The clipboard is - * empty if all five of the fields are empty. - * - * @return true if the clipboard is empty, else false - */ - boolean isEmptyClipboard() { - boolean isEmpty = true; - - isEmpty = isEmpty && (clipboardScope.equals("")); - isEmpty = isEmpty && (clipboardIdentifier.equals("")); - isEmpty = isEmpty && (clipboardRevision.equals("")); - isEmpty = isEmpty && (clipboardDocumentType.equals("")); - isEmpty = isEmpty && (clipboardDocumentURL.equals("")); - - return isEmpty; - } - - - /** - * Determines whether a given row in the table is empty. A row is empty if - * all five of its fields contain either null or "". - * - * @param rowIndex the index to the row in the table that is being checked - * @return true if the row is empty, else false - */ - boolean isEmptyRow(int rowIndex) { - boolean isEmpty = true; - String scope = (String) tableModel.getValueAt(rowIndex, 1); - String identifier = (String) tableModel.getValueAt(rowIndex, 2); - String revision = (String) tableModel.getValueAt(rowIndex, 3); - String documentType = (String) tableModel.getValueAt(rowIndex, 4); - String documentURL = (String) tableModel.getValueAt(rowIndex, 5); - - isEmpty = isEmpty && ((scope == null) || (scope.equals(""))); - isEmpty = isEmpty && ((identifier == null) || (identifier.equals(""))); - isEmpty = isEmpty && ((revision == null) || (revision.equals(""))); - isEmpty = isEmpty && ((documentType == null) || (documentType.equals(""))); - isEmpty = isEmpty && ((documentURL == null) || (documentURL.equals(""))); - - return isEmpty; - } - - - /** - * Loads the Harvest List from a file. Parses the file using the inner class, - * HarvestListHandler, a SAX parser. - * - * @param harvestList the File to be loaded - * @throws ParserConfigurationException - */ - void loadHarvestList(File harvestList) throws ParserConfigurationException { - HarvestListHandler harvestListHandler = new HarvestListHandler(); - FileInputStream fis; - InputStreamReader inputStreamReader; - boolean loadHarvestList = true; - boolean validateHarvestList = false; - - try { - fis = new FileInputStream(harvestList); - inputStreamReader = new InputStreamReader(fis); - //System.out.println("Opened file successfully."); - harvestListHandler.runParser(this, inputStreamReader, schemaLocation, - loadHarvestList, validateHarvestList); - fis.close(); - setTitle(title + ": " + harvestListFile.getName()); - } - catch (SAXException e) { - System.out.println("Error parsing Harvest List: " + e.getMessage()); - } - catch (ClassNotFoundException e) { - System.out.println("ClassNotFoundException: " + e.getMessage()); - } - catch (IOException ioe) { - System.out.println("Error opening file: " + ioe.getMessage()); - } - } - - - /** - * Loads properties from the .harvestListEditor file in the user's home - * directory. - */ - void loadProperties () { - String homedir = System.getProperty("user.home"); - File propertiesFile = new File(homedir, ".harvestListEditor"); - - properties = new Properties(); - - if (propertiesFile.exists()) { - try { - properties.load(new FileInputStream(propertiesFile)); - defaultHarvestList = properties.getProperty("defaultHarvestList"); - defaultDocumentType = properties.getProperty("defaultDocumentType"); - defaultDocumentURL = properties.getProperty("defaultDocumentURL"); - defaultIdentifier = properties.getProperty("defaultIdentifier"); - defaultRevision = properties.getProperty("defaultRevision"); - defaultScope = properties.getProperty("defaultScope"); - } - catch (IOException ioe) { - System.out.println("Error loading properties file: " + - ioe.getMessage()); - } - } - } - - - /** - * Enables or disables buttons depending on the state of the currently - * selected row and the state of the clipboard. - * - * @param rowIndex the index of the currently selected row - */ - void manageButtons(int rowIndex) { - - if (isEmptyRow(rowIndex)) { - // Selected row is empty, so disable cut and copy - cutButton.setEnabled(false); - copyButton.setEnabled(false); - } - else { - // Selected row is not empty, so enable cut and copy - cutButton.setEnabled(true); - copyButton.setEnabled(true); - } - - if (isEmptyClipboard()) { - // Clipboard is empty, so disable paste - pasteButton.setEnabled(false); - } - else { - // Clipboard is not empty, so enable paste - pasteButton.setEnabled(true); - } - - // Paste Defaults button is enabled whenever a row is selected - pasteDefaultsButton.setEnabled(true); - } - - - /** - * Pastes the clipboard values into the specified row. - * - * @param rowIndex the index of the row that is being pasted to - */ - void pasteRow(int rowIndex) { - tableModel.setValueAt(clipboardScope, rowIndex, 1); - tableModel.setValueAt(clipboardIdentifier, rowIndex, 2); - tableModel.setValueAt(clipboardRevision, rowIndex, 3); - tableModel.setValueAt(clipboardDocumentType, rowIndex, 4); - tableModel.setValueAt(clipboardDocumentURL, rowIndex, 5); - } - - - /** - * Pastes the default values into the specified row. - * - * @param rowIndex the index of the row that is being pasted to - */ - void pasteDefaultValues(int rowIndex) { - tableModel.setValueAt(defaultScope, rowIndex, 1); - tableModel.setValueAt(defaultIdentifier, rowIndex, 2); - tableModel.setValueAt(defaultRevision, rowIndex, 3); - tableModel.setValueAt(defaultDocumentType, rowIndex, 4); - tableModel.setValueAt(defaultDocumentURL, rowIndex, 5); - } - - - /** - * Dialog to determine whether user wants to save changes before proceeding. - * - * @return integer value that determines whether the user responded with - * "Yes", "No", or "Cancel" - */ - int saveChangesDialog () { - Object[] options = {"Yes", "No", "Cancel"}; - int value; - - value = JOptionPane.showOptionDialog(null, - "Save Changes?", - "Warning", - JOptionPane.DEFAULT_OPTION, - JOptionPane.WARNING_MESSAGE, - null, - options, - options[0]); // default option - return value; - } - - - /** - * Writes the contents of the table to file as XML. - * - * @param harvestList the File object to write to - */ - void writeFile(File harvestList) { - try { - PrintWriter out = new PrintWriter(new FileWriter(harvestList)); - writeHarvestList(out); - } - catch (IOException ioe) { - System.out.println("IOException: " + ioe.getMessage()); - } - } - - - /** - * Writes the contents of the table to a PrintWriter. - * - * @param out the PrintWriter to write the Harvest List to - */ - void writeHarvestList(PrintWriter out) { - out.println("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); - out.println(""); - out.println( - "<hrv:harvestList xmlns:hrv=\"eml://ecoinformatics.org/harvestList\" >"); - - for (int i = 0; i < numRows; i++) { - if (!isEmptyRow(i)) { - writeRow(out, i); - } - } - - out.println(""); - out.println("</hrv:harvestList>"); - out.close(); - } - - - /** - * Writes a row of the table to file. A row corresponds to a single - * <Document> element in the Harvest List. - * - * @param out the PrintWriter object for the file - * @param rowIndex the index of the table row that is being written to file - */ - void writeRow(PrintWriter out, int rowIndex) { - int indentLevel = 6; - String scope = (String) tableModel.getValueAt(rowIndex, 1); - String identifier = (String) tableModel.getValueAt(rowIndex, 2); - String revision = (String) tableModel.getValueAt(rowIndex, 3); - String documentType = (String) tableModel.getValueAt(rowIndex, 4); - String documentURL = (String) tableModel.getValueAt(rowIndex, 5); - - out.println(""); - out.println(" <document>"); - out.println(" <docid>"); - out.println(composeLine(indentLevel, "scope", scope)); - out.println(composeLine(indentLevel, "identifier", identifier)); - out.println(composeLine(indentLevel, "revision", revision)); - out.println(" </docid>"); - indentLevel = 4; - out.println(composeLine(indentLevel, "documentType", documentType)); - out.println(composeLine(indentLevel, "documentURL", documentURL)); - out.println(" </document>"); - } - - - /* - * Inner class: HarvestListTableModel - */ - class HarvestListTableModel extends AbstractTableModel { - final boolean DEBUG = false; - // Column names for the JTable - private String[] columnNames = { - "Row #", - "Scope", - "Identifier", - "Revision", - "Document Type", - "Document URL" - }; - - private Object[][] data = new Object[numRows][numColumns]; - - public int getColumnCount() { - return columnNames.length; - } - - public int getRowCount() { - return data.length; - } - - public String getColumnName(int col) { - return columnNames[col]; - } - - public Object getValueAt(int row, int col) { - return data[row][col]; - } - - /* - * JTable uses this method to determine the default renderer/ - * editor for each cell. If we didn't implement this method, - * then the last column would contain text ("true"/"false"), - * rather than a check box. - */ - public Class getColumnClass(int c) { - return getValueAt(0, c).getClass(); - } - - /* - * Don't need to implement this method unless your table's - * editable. - */ - public boolean isCellEditable(int row, int col) { - //Note that the data/cell address is constant, - //no matter where the cell appears onscreen. - if (col < 1) { - return false; - } else { - return true; - } - } - - /* - * Don't need to implement this method unless your table's - * data can change. - */ - public void setValueAt(Object value, int row, int col) { - if (DEBUG) { - System.out.println("Setting value at " + row + "," + col - + " to " + value - + " (an instance of " - + value.getClass() + ")"); - } - - data[row][col] = value; - fireTableCellUpdated(row, col); - - if (DEBUG) { - System.out.println("New value of data:"); - printDebugData(); - } - } - - private void printDebugData() { - int numRows = getRowCount(); - int numCols = getColumnCount(); - - for (int i=0; i < numRows; i++) { - System.out.print(" row " + i + ":"); - for (int j=0; j < numCols; j++) { - System.out.print(" " + data[i][j]); - } - System.out.println(); - } - System.out.println("--------------------------"); - } - } - - /** - * This inner class extends DefaultHandler. It parses the Harvest List file, - * writing a new row to the table every time it encounters a </Document> - * end tag. - */ - class HarvestListHandler extends DefaultHandler implements ErrorHandler { - - public String scope; - public int identifier; - public String identifierString; - public String documentType; - private HarvestListEditor harvestListEditor; - boolean loadHarvestList; - public int revision; - public String revisionString; - private int rowIndex = 0; - public String documentURL; - private String currentQname; - public final static String DEFAULT_PARSER = - "org.apache.xerces.parsers.SAXParser"; - private boolean schemaValidate = true; - private boolean validateHarvestList; - - - /** - * This method is called for any plain text within an element. - * It parses the value for any of the following elements: - * <scope>, <identifier>, <revision>, <documentType>, <documentURL> - * - * @param ch the character array holding the parsed text - * @param start the start index - * @param length the text length - * - */ - public void characters (char ch[], int start, int length) { - String s = new String(ch, start, length); - - if (length > 0) { - if (currentQname.equals("scope")) { - scope += s; - } - else if (currentQname.equals("identifier")) { - identifierString += s; - } - else if (currentQname.equals("revision")) { - revisionString += s; - } - else if (currentQname.equals("documentType")) { - documentType += s; - } - else if (currentQname.equals("documentURL")) { - documentURL += s; - } - } - } - - - /** - * Handles an end-of-document event. - */ - public void endDocument () { - } - - - /** - * Handles an end-of-element event. If the end tag is </Document>, then - * creates a new HarvestDocument object and pushes it to the document - * list. - * - * @param uri - * @param localname - * @param qname - */ - public void endElement(String uri, - String localname, - String qname) { - - HarvestDocument harvestDocument; - - if (qname.equals("identifier")) { - identifier = Integer.parseInt(identifierString); - } - else if (qname.equals("revision")) { - revision = Integer.parseInt(revisionString); - } - else if (qname.equals("document")) { - if (loadHarvestList) { - harvestListEditor.addRow(rowIndex, scope, identifierString, - revisionString, documentType, documentURL); - } - - rowIndex++; - } - - currentQname = ""; - } - - - /** - * Method for handling errors during a parse - * - * @param exception The parsing error - * @exception SAXException Description of Exception - */ - public void error(SAXParseException e) throws SAXParseException { - System.out.println("SAXParseException: " + e.getMessage()); - throw e; - } - - - /** - * Run the validating parser - * - * @param xml the xml stream to be validated - * @schemaLocation relative path the to XML Schema file, e.g. "." - * @exception IOException thrown when test files can't be opened - * @exception ClassNotFoundException thrown when SAX Parser class not found - * @exception SAXException - * @exception SAXParserException - */ - public void runParser(HarvestListEditor harvestListEditor, - Reader xml, - String schemaLocation, - boolean loadHarvestList, - boolean validateHarvestList) - throws IOException, ClassNotFoundException, - SAXException, SAXParseException { - - // Get an instance of the parser - XMLReader parser; - - this.harvestListEditor = harvestListEditor; - this.loadHarvestList = loadHarvestList; - this.validateHarvestList = validateHarvestList; - this.rowIndex = 0; - - parser = XMLReaderFactory.createXMLReader(DEFAULT_PARSER); - // Set Handlers in the parser - parser.setContentHandler((ContentHandler)this); - parser.setErrorHandler((ErrorHandler)this); - parser.setFeature("http://xml.org/sax/features/namespaces", true); - parser.setFeature("http://xml.org/sax/features/namespace-prefixes", true); - parser.setFeature("http://xml.org/sax/features/validation", true); - parser.setProperty( - "http://apache.org/xml/properties/schema/external-schemaLocation", - schemaLocation); - - if (schemaValidate) { - parser.setFeature("http://apache.org/xml/features/validation/schema", - true); - } - - // Parse the document - parser.parse(new InputSource(xml)); - } - - - /** - * Handles a start-of-document event. - */ - public void startDocument () { - //System.out.println("Started parsing Harvest List"); - } - - - /** - * Handles a start-of-element event. - * - * @param uri - * @param localname - * @param qname - * @param attributes - */ - public void startElement(String uri, - String localname, - String qname, - Attributes attributes) { - - currentQname = qname; - - if (qname.equals("scope")) { - scope = ""; - } - else if (qname.equals("identifier")) { - identifierString = ""; - } - else if (qname.equals("revision")) { - revisionString = ""; - } - else if (qname.equals("documentType")) { - documentType = ""; - } - else if (qname.equals("documentURL")) { - documentURL = ""; - } - } - } -} \ No newline at end of file
src/edu/ucsb/nceas/metacat/harvesterClient/HarvestLog.java+0 −368 removed@@ -1,368 +0,0 @@ -/** - * '$RCSfile$' - * Copyright: 2004 University of New Mexico and the - * Regents of the University of California - * - * '$Author$' - * '$Date$' - * '$Revision$' - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package edu.ucsb.nceas.metacat.harvesterClient; - -import java.io.PrintStream; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.SQLWarning; -import java.sql.Statement; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.StringTokenizer; - -import edu.ucsb.nceas.metacat.properties.PropertyService; -import edu.ucsb.nceas.utilities.PropertyNotFoundException; - -/** - * Manages log entries to be inserted to the HARVEST_LOG table. - * - * @author costa - */ -public class HarvestLog { - - private Connection conn; - private Harvester harvester; // The parent Harvester object - private int harvestLogID; - private Date harvestDate; - private int status; - private final String marker = -"*****************************************************************************"; - private String message; - private String harvestOperationCode; - private int siteScheduleID; - private String explanation; - private String harvestOperationCodeLevel; - private String timestamp; - private HarvestDetailLog harvestDetailLog; // Associated detail log, if any - - - /** - * Creates a new instance of HarvestLog. This constructor is used when - * creating log entries that do not involve an error on a harvest document. - * (For that type of log entry, use the alternate constructor below.) - * - * @param harvester the parent Harvester object - * @param conn the database connection - * @param harvestLogID the primary key in the HARVEST_LOG table - * @param harvestDate the date of this harvest - * @param status the status of the harvest operation - * @param message the message text of the harvest operation - * @param harvestOperationCode the harvest operation code - * @param siteScheduleID the siteScheduleID for which this operation was - * performed. 0 indicates that the operation did not - * involve a particular harvest site. - */ - public HarvestLog(Harvester harvester, - Connection conn, - int harvestLogID, - Date harvestDate, - int status, - String message, - String harvestOperationCode, - int siteScheduleID - ) { - Date now = new Date(); - timestamp = now.toString(); - - this.harvester = harvester; - this.conn = conn; - this.harvestLogID = harvestLogID; - this.harvestDate = harvestDate; - this.status = status; - this.message = message; - this.harvestOperationCode = harvestOperationCode; - this.siteScheduleID = siteScheduleID; - - harvestOperationCodeLevel = - getHarvestOperationCodeLevel(harvestOperationCode); - explanation = getExplanation(harvestOperationCode); - dbInsertHarvestLogEntry(); // Insert this entry to the HARVEST_LOG table - } - - - /** - * Creates a new instance of HarvestLog and inserts this entry to the - * HARVEST_LOG table. This version of the constructor also instantiates a - * HarvestDetailLog object and inserts it to the HARVEST_DETAIL_LOG table. - * - * @param harvester the parent Harvester object - * @param conn the database connection - * @param harvestLogID the primary key in the HARVEST_LOG table - * @param detailLogID the primary key in the HARVEST_DETAIL_LOG table - * @param harvestDate the date of this harvest - * @param status the status of the harvest operation - * @param message the message text of the harvest operation - * @param harvestOperationCode the harvest operation code - * @param siteScheduleID the siteScheduleID for which this operation was - * performed. 0 indicates that the operation did not - * involve a particular harvest site. - * @param harvestDocument the HarvestDocument involved in this operation - * @param errorMessage the error message generated by this operation - */ - public HarvestLog(Harvester harvester, - Connection conn, - int harvestLogID, - int detailLogID, - Date harvestDate, - int status, - String message, - String harvestOperationCode, - int siteScheduleID, - HarvestDocument harvestDocument, - String errorMessage - ) { - Date now = new Date(); - timestamp = now.toString(); - - this.harvester = harvester; - this.conn = conn; - this.harvestLogID = harvestLogID; - this.harvestDate = harvestDate; - this.status = status; - this.message = message; - this.harvestOperationCode = harvestOperationCode; - this.siteScheduleID = siteScheduleID; - this.harvestDetailLog = new HarvestDetailLog(harvester, conn, detailLogID, - harvestLogID, harvestDocument, - errorMessage); - harvestOperationCodeLevel = - getHarvestOperationCodeLevel(harvestOperationCode); - explanation = getExplanation(harvestOperationCode); - dbInsertHarvestLogEntry(); // Insert to the HARVEST_LOG table - harvestDetailLog.dbInsertHarvestDetailLogEntry(); // HARVEST_DETAIL_LOG - } - - - /** - * Inserts a new entry into the HARVEST_LOG table, based on the contents of - * this HarvestLog object. Not yet implemented. - */ - void dbInsertHarvestLogEntry() { - String dequotedMessage = harvester.dequoteText(message); - String insertString; - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MMM-yyyy"); - Statement stmt; - - insertString = "INSERT INTO HARVEST_LOG " + - "(HARVEST_LOG_ID, HARVEST_DATE, STATUS, MESSAGE," + - " HARVEST_OPERATION_CODE, SITE_SCHEDULE_ID) " + - "values(" + - harvestLogID + ", " + - "'" + simpleDateFormat.format(harvestDate) + "', " + - status + ", " + - "'" + timestamp + ": " + dequotedMessage + "', " + - "'" + harvestOperationCode + "', " + - siteScheduleID + - ")"; - try { - stmt = conn.createStatement(); - stmt.executeUpdate(insertString); - stmt.close(); - } - catch(SQLException e) { - System.out.println("SQLException: " + e.getMessage()); - } - } - - - /** - * Maps each code level to an integer value. - * - * @param codeLevel the code level: "error", "warning", "notice", - * "info", or "debug" - * @return codeLevelValue the corresponding code level value - */ - public int getCodeLevelValue(String codeLevel) { - int codeLevelValue = 0; - - if (codeLevel.equalsIgnoreCase("error")) { - codeLevelValue = 1; - } - else if (codeLevel.equalsIgnoreCase("warning")) { - codeLevelValue = 2; - } - else if (codeLevel.equalsIgnoreCase("notice")) { - codeLevelValue = 3; - } - else if (codeLevel.equalsIgnoreCase("info")) { - codeLevelValue = 4; - } - else if (codeLevel.equalsIgnoreCase("debug")) { - codeLevelValue = 5; - } - - return codeLevelValue; - } - - - /** - * Returns an explanation string based on the value of a - * harvestOperationCode string. The explanation string is a description - * of the harvest operation specified by the harvestOperationCode. - * - * @param harvestOperationCode string value of the harvest operation code - * @return the explanation for this harvest operation, a String - */ - public String getExplanation(String harvestOperationCode) { - String explanation; - String fieldName = "EXPLANATION"; - - explanation = getHarvestOperation(fieldName, harvestOperationCode); - - return explanation; - } - - - /** - * Returns either an explanation string or a harvest operation code level - * string based on the value of a harvest operation code property. The - * explanation and the code level are stored as comma-separated strings in - * the metacat.properties file. For example, the HarvesterStartup - * harvest operation code stores its explanation and code level like so: - * - * HarvesterStartup=Harvester start up,Info - * - * @param fieldName the field name to match, e.g. "EXPLANATION" - * @param harvestOperationCode string value of the harvest operation code - * @return the explanation string or the harvestOperationCodeLevel string - */ - String getHarvestOperation(String fieldName, String harvestOperationCode) { - String explanation = "No explanation available"; - String harvestOperationCodeLevel = "debug"; - String propertyValue = null; - String returnString = ""; - StringTokenizer stringTokenizer; - - try { - propertyValue = PropertyService.getProperty(harvestOperationCode); - } catch (PropertyNotFoundException pnfe) { - System.out.println("Error trying to get property: " + harvestOperationCode - + " : " + pnfe.getMessage()); - } - stringTokenizer = new StringTokenizer(propertyValue, ","); - - explanation = (String) stringTokenizer.nextElement(); - harvestOperationCodeLevel = (String) stringTokenizer.nextElement(); - - if (fieldName.equals("EXPLANATION")) { - returnString = explanation; - } - else if (fieldName.equals("HARVEST_OPERATION_CODE_LEVEL")) { - returnString = harvestOperationCodeLevel; - } - - return returnString; - } - - - /** - * Returns a code level string based on a harvestOperationCode string. - * The code level string is one of a set of possible code levels: - * "error", "warning", "notice", "info", or "debug". - * - * @param harvestOperationCode string value of the harvest operation code - * @return the code level value, a String, one of the following: - * "error", "warning", "notice", "info", or "debug" - */ - public String getHarvestOperationCodeLevel(String harvestOperationCode) { - String harvestOperationCodeLevel; - String fieldName = "HARVEST_OPERATION_CODE_LEVEL"; - - harvestOperationCodeLevel = - getHarvestOperation(fieldName, harvestOperationCode); - - return harvestOperationCodeLevel; - } - - - /** - * Access function for the siteScheduleID field. - * - * @return siteScheduleID, an int. If 0, indicates that this log entry does - * not pertain to a particular site. - */ - int getSiteScheduleID() { - return siteScheduleID; - } - - - /** - * Determines whether this log entry had an error status. - * - * @return isError true if this log entry had an error status, else false - */ - boolean isErrorEntry () { - boolean isError; - - isError = (status != 0); - - return isError; - } - - - /** - * Prints the contents of this HarvestLog object. Used in generating reports. - * - * @param out the PrintStream to write to - * @param maxLevel the maximum code level to output. If this log entry has a - * higher code level than the maxLevel, no output - * is issued. For example, if the maxLevel is "error" - * (level 1), then anything lower ("warning", "notice", etc.) - * will not generate any output. - */ - public void printOutput(PrintStream out, String maxLevel) { - int codeLevelValue = getCodeLevelValue(harvestOperationCodeLevel); - int maxLevelValue = getCodeLevelValue(maxLevel); - - if (codeLevelValue <= maxLevelValue) { - out.println(""); - out.println(marker); - out.println("*"); - out.println("* harvestLogID: " + harvestLogID); - out.println("* harvestDate: " + harvestDate); - out.println("* status: " + status); - out.println("* message: " + message); - out.println("* harvestOperationCode: " + harvestOperationCode); - out.println("* description: " + explanation); - - if (harvestOperationCode.equals("harvester.GetHarvestListSuccess") || - harvestOperationCode.equals("harvester.GetHarvestListError")) { - if (siteScheduleID != 0) { - harvester.printHarvestSiteSchedule(out, siteScheduleID); - } - } - - if (harvestDetailLog != null) { - harvestDetailLog.printOutput(out); - } - - out.println("*"); - out.println(marker); - } - } - -}
src/edu/ucsb/nceas/metacat/harvesterClient/HarvestSiteSchedule.java+0 −814 removed@@ -1,814 +0,0 @@ -/** - * '$RCSfile$' - * Copyright: 2004 University of New Mexico and the - * Regents of the University of California - * - * '$Author$' - * '$Date$' - * '$Revision$' - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package edu.ucsb.nceas.metacat.harvesterClient; - -import com.oreilly.servlet.MailMessage; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintStream; -import java.io.Reader; -import java.net.MalformedURLException; -import java.net.URL; -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import javax.xml.parsers.ParserConfigurationException; -import org.xml.sax.Attributes; -import org.xml.sax.ContentHandler; -import org.xml.sax.ErrorHandler; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.DefaultHandler; -import org.xml.sax.helpers.XMLReaderFactory; - -import edu.ucsb.nceas.metacat.client.Metacat; -import edu.ucsb.nceas.metacat.client.MetacatException; -import edu.ucsb.nceas.metacat.client.MetacatInaccessibleException; - - -/** - * HarvestSiteSchedule manages a single entry in the HARVEST_SITE_SCHEDULE - * table, determining when and how to harvest the documents for a given site. - * - * @author costa - */ -public class HarvestSiteSchedule { - - private String contactEmail; - private String dateLastHarvest; - private String dateNextHarvest; - private long delta; - private String documentListURL; - private Harvester harvester; - private ArrayList harvestDocumentList = new ArrayList(); - private String harvestSiteEndTime; - private String harvestSiteStartTime; - private String ldapDN; - private String ldapPwd; - final private long millisecondsPerDay = (1000 * 60 * 60 * 24); - private String schemaLocation = - "eml://ecoinformatics.org/harvestList ../../lib/harvester/harvestList.xsd"; - int siteScheduleID; - private String unit; - private int updateFrequency; - - /** - * Creates a new instance of HarvestSiteSchedule. Initialized with the data - * that was read from a single row in the HARVEST_SITE_SCHEDULE table. - * - * @param harvester the parent Harvester object - * @param siteScheduleID the value of the SITE_SCHEDULE_ID field - * @param documentListURL the value of the DOCUMENTLISTURL field - * @param ldapDN the value of the LDAPDN field - * @param ldapPwd the value of the LDAPPASSWORD field - * @param dateNextHarvest the value of the DATENEXTHARVEST field - * @param dateLastHarvest the value of the DATELASTHARVEST field - * @param updateFrequency the value of the UPDATEFREQUENCY field - * @param unit the value of the UNIT field - * @param contactEmail the value of the CONTACT_EMAIL field - */ - public HarvestSiteSchedule( - Harvester harvester, - int siteScheduleID, - String documentListURL, - String ldapDN, - String ldapPwd, - String dateNextHarvest, - String dateLastHarvest, - int updateFrequency, - String unit, - String contactEmail - ) - { - this.harvester = harvester; - this.siteScheduleID = siteScheduleID; - this.documentListURL = documentListURL; - this.ldapDN = ldapDN; - this.ldapPwd = ldapPwd; - this.dateNextHarvest = dateNextHarvest; - this.dateLastHarvest = dateLastHarvest; - this.updateFrequency = updateFrequency; - this.unit = unit; - this.contactEmail = contactEmail; - - // Calculate the value of delta, the number of milliseconds between the - // last harvest date and the next harvest date. - delta = updateFrequency * millisecondsPerDay; - - if (unit.equals("weeks")) { - delta *= 7; - } - else if (unit.equals("months")) { - delta *= 30; - } - } - - - /** - * Updates the DATELASTHARVEST and DATENEXTHARVEST values of the - * HARVEST_SITE_SCHEDULE table after a harvest operation has completed. - * Calculates the date of the next harvest based on today's date and the - * update frequency. - */ - private void dbUpdateHarvestDates() { - Connection conn; - long currentTime; // Current time in milliseconds - Date dateNextHarvest; // Date of next harvest - String lastHarvest; - String nextHarvest; - Date now = new Date(); - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MMM-yyyy"); - Statement stmt; - long timeNextHarvest; - - conn = harvester.getConnection(); - now = new Date(); - currentTime = now.getTime(); - timeNextHarvest = currentTime + delta; - dateNextHarvest = new Date(timeNextHarvest); - nextHarvest = "'" + simpleDateFormat.format(dateNextHarvest) + "'"; - lastHarvest = "'" + simpleDateFormat.format(now) + "'"; - - try { - stmt = conn.createStatement(); - stmt.executeUpdate( - "UPDATE HARVEST_SITE_SCHEDULE SET DATENEXTHARVEST = " + - nextHarvest + - " WHERE SITE_SCHEDULE_ID = " + - siteScheduleID); - stmt.executeUpdate( - "UPDATE HARVEST_SITE_SCHEDULE SET DATELASTHARVEST = " + - lastHarvest + - " WHERE SITE_SCHEDULE_ID = " + - siteScheduleID); - stmt.close(); - } - catch(SQLException e) { - System.out.println("SQLException: " + e.getMessage()); - } - } - - - /** - * Boolean to determine whether this site is currently due for its next - * harvest. - * - * @retrun true if due for harvest, otherwise false - */ - public boolean dueForHarvest() { - boolean dueForHarvest = false; -// DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S"); - DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); - Date now = new Date(); - Date dnh; // Date of next harvest - long currentTime = now.getTime(); // Current time in milliseconds - long timeNextHarvest = 0; - - try { - dnh = dateFormat.parse(dateNextHarvest); - timeNextHarvest = dnh.getTime(); - - if (timeNextHarvest < currentTime) { - dueForHarvest = true; - System.out.println("Due for harvest: " + documentListURL); - } - else { - System.out.println("Not due for harvest: " + documentListURL); - } - } - catch (ParseException e) { - System.out.println("Error parsing date: " + e.getMessage()); - } - - return dueForHarvest; - } - - - /** - * Accessor method for the schemaLocation field. - * - * @return schemaLocation the schema location string - */ - public String getSchemaLocation() { - return schemaLocation; - } - - - /** - * Harvests each document in the site document list. - * - * @throws SAXException - * @throws IOException - * @throws ParserConfigurationException - */ - public void harvestDocumentList() { - HarvestDocument harvestDocument; - boolean success; - - if (dueForHarvest()) { - try { - success = parseHarvestList(); - - /* If the document list was validated, then proceed with harvesting - * the documents - */ - if (success) { - metacatLogin(); - - for (int i = 0; i < harvestDocumentList.size(); i++) { - harvestDocument = (HarvestDocument) harvestDocumentList.get(i); - - if (harvestDocument != null) { - harvestDocument.harvestDocument(); - } - } - - metacatLogout(); - dbUpdateHarvestDates(); // Update the schedule - } - } - catch (ParserConfigurationException e) { - System.out.println("ParserConfigurationException: " + e.getMessage()); - } - - reportToSiteContact(); - } - } - - - /** - * Login to Metacat using the ldapDN and ldapPwd - */ - public void metacatLogin() { - Metacat metacat = harvester.metacat; - String response; - - if (harvester.connectToMetacat()) { - try { - System.out.println("Logging in to Metacat: " + ldapDN); - response = metacat.login(ldapDN, ldapPwd); - //System.out.println("Metacat login response: " + response); - } - catch (MetacatInaccessibleException e) { - System.out.println("Metacat login failed." + e.getMessage()); - } - catch (Exception e) { - System.out.println("Metacat login failed." + e.getMessage()); - } - } - } - - - /** - * Logout from Metacat - */ - private void metacatLogout() { - Metacat metacat = harvester.metacat; - - if (harvester.connectToMetacat()) { - try { - // Log out from the Metacat session - System.out.println("Logging out from Metacat"); - metacat.logout(); - } - catch (MetacatInaccessibleException e) { - System.out.println("Metacat inaccessible: " + e.getMessage()); - } - catch (MetacatException e) { - System.out.println("Metacat exception: " + e.getMessage()); - } - } - } - - - /** - * Parses the site harvest list XML file to find out which documents to - * harvest. - * - * @return true if successful, otherwise false - */ - public boolean parseHarvestList() - throws ParserConfigurationException { - DocumentListHandler documentListHandler = new DocumentListHandler(); - InputStream inputStream; - InputStreamReader inputStreamReader; - String schemaLocation = getSchemaLocation(); - boolean success = false; - URL url; - - try { - url = new URL(documentListURL); - inputStream = url.openStream(); - harvester.addLogEntry(0, - "Retrieved: " + documentListURL, - "harvester.GetHarvestListSuccess", - siteScheduleID, - null, - ""); - inputStreamReader = new InputStreamReader(inputStream); -// char[] harvestListChars = new char[1024]; -// inputStreamReader.read(harvestListChars, 0, 1024); -// System.out.println("documentListURL: " + documentListURL); -// String encoding = inputStreamReader.getEncoding(); -// System.out.println("encoding: " + encoding); -// String harvestListStr = new String(harvestListChars); -// System.out.println("harvestListStr:\n" + harvestListStr); - documentListHandler.runParser(inputStreamReader, schemaLocation); - harvester.addLogEntry(0, - "Validated: " + documentListURL, - "harvester.ValidateHarvestListSuccess", - siteScheduleID, - null, - ""); - success = true; - } - catch (MalformedURLException e){ - harvester.addLogEntry(1, "MalformedURLException: " + e.getMessage(), - "harvester.GetHarvestListError", siteScheduleID, null, ""); - } - catch (FileNotFoundException e) { - harvester.addLogEntry(1, "FileNotFoundException: " + e.getMessage(), - "harvester.GetHarvestListError", siteScheduleID, null, ""); - } - catch (SAXException e) { - harvester.addLogEntry(1, "SAXException: " + e.getMessage(), - "harvester.ValidateHarvestListError", siteScheduleID, null, ""); - } - catch (ClassNotFoundException e) { - harvester.addLogEntry(1, "ClassNotFoundException: " + e.getMessage(), - "harvester.ValidateHarvestListError", siteScheduleID, null, ""); - } - catch (IOException e) { - harvester.addLogEntry(1, "IOException: " + e.getMessage(), - "harvester.GetHarvestListError", siteScheduleID, null, ""); - } - - return success; - } - - - /** - * Prints the data that is stored in this HarvestSiteSchedule object. - * - * @param out the PrintStream to write to - */ - public void printOutput(PrintStream out) { - out.println("* siteScheduleID: " + siteScheduleID); - out.println("* documentListURL: " + documentListURL); - out.println("* ldapDN: " + ldapDN); - out.println("* dateNextHarvest: " + dateNextHarvest); - out.println("* dateLastHarvest: " + dateLastHarvest); - out.println("* updateFrequency: " + updateFrequency); - out.println("* unit: " + unit); - out.println("* contactEmail: " + contactEmail); - } - - /** - * Reports a summary of the site harvest. Includes the following: - * A list of documents that were successfully inserted. - * A list of documents that were successfully updated. - * A list of documents that could not be accessed at the site. - * A list of documents that could not be uploaded to Metacat. - * A list of documents that were already found in Metacat. - * - * @param out the PrintStream to write to - */ - void printSiteSummary(PrintStream out) { - HarvestDocument harvestDocument; - int nAccessError = 0; - int nInserted = 0; - int nMetacatHasIt = 0; - int nUpdated = 0; - int nUploadError = 0; - - for (int i = 0; i < harvestDocumentList.size(); i++) { - harvestDocument = (HarvestDocument) harvestDocumentList.get(i); - - if (harvestDocument != null) { - if (harvestDocument.accessError) { nAccessError++; } - if (harvestDocument.inserted) { nInserted++; } - if (harvestDocument.metacatHasIt) { nMetacatHasIt++; } - if (harvestDocument.updated) { nUpdated++; } - if (harvestDocument.uploadError) { nUploadError++; } - } - } - - if (nInserted > 0) { - printSiteSummaryHeader(out); - out.println("* The following document(s) were successfully inserted:"); - for (int i = 0; i < harvestDocumentList.size(); i++) { - harvestDocument = (HarvestDocument) harvestDocumentList.get(i); - if (harvestDocument != null) { - if (harvestDocument.inserted) { - harvestDocument.prettyPrint(out); - } - } - } - printSiteSummaryTrailer(out); - } - - if (nUpdated > 0) { - printSiteSummaryHeader(out); - out.println("* The following document(s) were successfully updated:"); - for (int i = 0; i < harvestDocumentList.size(); i++) { - harvestDocument = (HarvestDocument) harvestDocumentList.get(i); - if (harvestDocument != null) { - if (harvestDocument.updated) { - harvestDocument.prettyPrint(out); - } - } - } - printSiteSummaryTrailer(out); - } - - if (nAccessError > 0) { - printSiteSummaryHeader(out); - out.println("* The following document(s) could not be accessed"); - out.println("* at the site. Please check the URL to ensure that it is"); - out.println("* accessible at the site."); - for (int i = 0; i < harvestDocumentList.size(); i++) { - harvestDocument = (HarvestDocument) harvestDocumentList.get(i); - if (harvestDocument != null) { - if (harvestDocument.accessError) { - harvestDocument.prettyPrint(out); - } - } - } - printSiteSummaryTrailer(out); - } - - if (nUploadError > 0) { - printSiteSummaryHeader(out); - out.println("* The following document(s) could not be uploaded to"); - out.println("* Metacat because an error of some kind occurred."); - out.println("* (See log entries below for additional details.) :"); - for (int i = 0; i < harvestDocumentList.size(); i++) { - harvestDocument = (HarvestDocument) harvestDocumentList.get(i); - if (harvestDocument != null) { - if (harvestDocument.uploadError) { - harvestDocument.prettyPrint(out); - } - } - } - printSiteSummaryTrailer(out); - } - - if (nMetacatHasIt > 0) { - printSiteSummaryHeader(out); - out.println("* The following document(s) were already found in Metacat:"); - - for (int i = 0; i < harvestDocumentList.size(); i++) { - harvestDocument = (HarvestDocument) harvestDocumentList.get(i); - if (harvestDocument != null) { - if (harvestDocument.metacatHasIt) { - harvestDocument.prettyPrint(out); - } - } - } - printSiteSummaryTrailer(out); - } - - } - - - /** - * Prints the header lines of a site summary entry. - * - * @param out the PrintStream to write to - */ - void printSiteSummaryHeader(PrintStream out) { - final String filler = Harvester.filler; - final String marker = Harvester.marker; - - out.println(""); - out.println(marker); - out.println(filler); - } - - - /** - * Prints the trailing lines of a site summary entry. - * - * @param out the PrintStream to write to - */ - void printSiteSummaryTrailer(PrintStream out) { - final String filler = Harvester.filler; - final String marker = Harvester.marker; - - out.println(filler); - out.println(marker); - } - - - /** - * Sends a report to the Site Contact summarizing the results of the harvest - * at that site. - */ - void reportToSiteContact() { - PrintStream body; - String from = harvester.harvesterAdministrator; - String[] fromArray; - String maxCodeLevel = "notice"; - MailMessage msg; - int nErrors = 0; - String subject = "Report from Metacat Harvester: " + harvester.timestamp; - String to = contactEmail; - String[] toArray; - - if (!to.equals("")) { - System.out.println("Sending report to siteScheduleID=" + siteScheduleID + - " at address: " + contactEmail); - try { - msg = new MailMessage(harvester.smtpServer); - - if (from.indexOf(',') > 0) { - fromArray = from.split(","); - - for (int i = 0; i < fromArray.length; i++) { - if (i == 0) { - msg.from(fromArray[i]); - } - - msg.cc(fromArray[i]); - - } - } - else if (from.indexOf(';') > 0) { - fromArray = from.split(";"); - - for (int i = 0; i < fromArray.length; i++) { - if (i == 0) { - msg.from(fromArray[i]); - } - - msg.cc(fromArray[i]); - - } - } - else { - msg.from(from); - msg.cc(from); - } - - if (to.indexOf(',') > 0) { - toArray = to.split(","); - - for (int i = 0; i < toArray.length; i++) { - msg.to(toArray[i]); - } - } - else if (to.indexOf(';') > 0) { - toArray = to.split(";"); - - for (int i = 0; i < toArray.length; i++) { - msg.to(toArray[i]); - } - } - else { - msg.to(to); - } - - msg.setSubject(subject); - body = msg.getPrintStream(); - harvester.printHarvestHeader(body, siteScheduleID); - printSiteSummary(body); - harvester.printHarvestLog(body, maxCodeLevel, siteScheduleID); - msg.sendAndClose(); - } - catch (IOException e) { - System.out.println("There was a problem sending email to " + to); - System.out.println("IOException: " + e.getMessage()); - } - } - } - - - /** - * Accessor method for setting the value of the schemaLocation field. - * - * @param schemaLocation the new value of the schemaLocation field - */ - public void setSchemaLocation(String schemaLocation) { - this.schemaLocation = schemaLocation; - } - - - /** - * This inner class extends DefaultHandler. It parses the document list, - * creating a new HarvestDocument object every time it finds a </Document> - * end tag. - */ - class DocumentListHandler extends DefaultHandler implements ErrorHandler { - - public String scope; - public int identifier; - public String identifierString; - public String documentType; - public int revision; - public String revisionString; - public String documentURL; - private String currentQname; - public final static String DEFAULT_PARSER = - "org.apache.xerces.parsers.SAXParser"; - private boolean schemaValidate = true; - - - /** - * This method is called for any plain text within an element. - * It parses the value for any of the following elements: - * <scope>, <identifier>, <revision>, <documentType>, <documentURL> - * - * @param ch the character array holding the parsed text - * @param start the start index - * @param length the text length - * - */ - public void characters (char ch[], int start, int length) { - String s = new String(ch, start, length); - - if (length > 0) { - if (currentQname.equals("scope")) { - scope += s; - } - else if (currentQname.equals("identifier")) { - identifierString += s; - } - else if (currentQname.equals("revision")) { - revisionString += s; - } - else if (currentQname.equals("documentType")) { - documentType += s; - } - else if (currentQname.equals("documentURL")) { - documentURL += s; - } - } - } - - - /** - * Handles an end-of-document event. - */ - public void endDocument () { - System.out.println("Finished parsing " + documentListURL); - } - - - /** - * Handles an end-of-element event. If the end tag is </Document>, then - * creates a new HarvestDocument object and pushes it to the document - * list. - * - * @param uri - * @param localname - * @param qname - */ - public void endElement(String uri, - String localname, - String qname) { - - HarvestDocument harvestDocument; - - if (qname.equals("identifier")) { - identifier = Integer.parseInt(identifierString); - } - else if (qname.equals("revision")) { - revision = Integer.parseInt(revisionString); - } - else if (qname.equals("document")) { - harvestDocument = new HarvestDocument( - harvester, - HarvestSiteSchedule.this, - scope, - identifier, - revision, - documentType, - documentURL - ); - harvestDocumentList.add(harvestDocument); - } - - currentQname = ""; - } - - - /** - * Method for handling errors during a parse - * - * @param exception The parsing error - * @exception SAXException Description of Exception - */ - public void error(SAXParseException e) throws SAXParseException { - System.out.println("SAXParseException: " + e.getMessage()); - throw e; - } - - - /** - * Run the validating parser - * - * @param xml the xml stream to be validated - * @schemaLocation relative path the to XML Schema file, e.g. "." - * @exception IOException thrown when test files can't be opened - * @exception ClassNotFoundException thrown when SAX Parser class not found - * @exception SAXException - * @exception SAXParserException - */ - public void runParser(Reader xml, String schemaLocation) - throws IOException, ClassNotFoundException, - SAXException, SAXParseException { - - // Get an instance of the parser - XMLReader parser; - - parser = XMLReaderFactory.createXMLReader(DEFAULT_PARSER); - // Set Handlers in the parser - parser.setContentHandler((ContentHandler)this); - parser.setErrorHandler((ErrorHandler)this); - parser.setFeature("http://xml.org/sax/features/namespaces", true); - parser.setFeature("http://xml.org/sax/features/namespace-prefixes", true); - parser.setFeature("http://xml.org/sax/features/validation", true); - parser.setProperty( - "http://apache.org/xml/properties/schema/external-schemaLocation", - schemaLocation); - - if (schemaValidate) { - parser.setFeature("http://apache.org/xml/features/validation/schema", - true); - } - - // Parse the document - parser.parse(new InputSource(xml)); - } - /** - * Handles a start-of-document event. - */ - public void startDocument () { - System.out.println("Started parsing " + documentListURL); - } - - - /** - * Handles a start-of-element event. - * - * @param uri - * @param localname - * @param qname - * @param attributes - */ - public void startElement(String uri, - String localname, - String qname, - Attributes attributes) { - - currentQname = qname; - - if (qname.equals("scope")) { - scope = ""; - } - else if (qname.equals("identifier")) { - identifierString = ""; - } - else if (qname.equals("revision")) { - revisionString = ""; - } - else if (qname.equals("documentType")) { - documentType = ""; - } - else if (qname.equals("documentURL")) { - documentURL = ""; - } - } - } -}
src/edu/ucsb/nceas/metacat/harvesterClient/LoginServlet.java+0 −117 removed@@ -1,117 +0,0 @@ -/** - * '$RCSfile$' - * Copyright: 2004 University of New Mexico and the - * Regents of the University of California - * - * '$Author$' - * '$Date$' - * '$Revision$' - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package edu.ucsb.nceas.metacat.harvesterClient; - -import java.io.PrintWriter; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletInputStream; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpUtils; -import javax.servlet.ServletOutputStream; -import edu.ucsb.nceas.metacat.AuthSession; - -/** - * LoginServlet implements a Harvester servlet to login to Metacat - */ -public class LoginServlet extends HttpServlet { - - public void destroy() { - // Close all connections - System.out.println("Destroying LoginServlet"); - } - - /** - * Handle "GET" method requests from HTTP clients - * - * @param request The request - * @param response The response - * @throws ServletException, java.io.IOException - */ - public void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, java.io.IOException { - // Process the data and send back the response - handleGetOrPost(request, response); - } - - /** - * Handle "POST" method requests from HTTP clients - * - * @param request The request - * @param response The response - * @throws ServletException, java.io.IOException - */ - public void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, java.io.IOException { - // Process the data and send back the response - handleGetOrPost(request, response); - } - - /** - * Handle "GET" or "POST" method requests from HTTP clients - * - * @param request The request - * @param response The response - * @throws ServletException, java.io.IOException - */ - private void handleGetOrPost(HttpServletRequest request, - HttpServletResponse response) - throws ServletException, java.io.IOException { - AuthSession authSession = null; - HttpSession httpSession; - boolean isValid; - PrintWriter out = response.getWriter(); - String passwd = request.getParameter("passwd"); - String user = request.getParameter("user"); - - response.setContentType("text/plain"); - - try { - authSession = new AuthSession(); - } - catch (Exception e) { - out.println("Error creating AuthSession: " + e.getMessage()); - return; - } - - isValid = authSession.authenticate(request, user, passwd); - - if (isValid) { - System.out.println(authSession.getMessage()); - httpSession = request.getSession(true); - httpSession.setAttribute("username", user); - httpSession.setAttribute("password", passwd); - response.sendRedirect("../style/skins/dev/harvesterUpload.html"); - } - else { - out.println("Error authenticating Metacat login: " + - authSession.getMessage()); - } - } -}
src/edu/ucsb/nceas/metacat/harvesterClient/MetUpload.java+0 −347 removed@@ -1,347 +0,0 @@ -/** - * '$RCSfile$' - * Copyright: 2004 University of New Mexico and the - * Regents of the University of California - * - * '$Author$' - * '$Date$' - * '$Revision$' - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package edu.ucsb.nceas.metacat.harvesterClient; - -import java.io.*; -import java.util.*; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletInputStream; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpUtils; -import javax.servlet.ServletOutputStream; -import com.oreilly.servlet.multipart.FilePart; -import com.oreilly.servlet.multipart.MultipartParser; -import com.oreilly.servlet.multipart.ParamPart; -import com.oreilly.servlet.multipart.Part; - -import edu.ucsb.nceas.metacat.client.*; -import edu.ucsb.nceas.metacat.properties.PropertyService; -import edu.ucsb.nceas.metacat.shared.ServiceException; -import edu.ucsb.nceas.metacat.util.SystemUtil; -import edu.ucsb.nceas.utilities.GeneralPropertyException; -import edu.ucsb.nceas.utilities.IOUtil; - -/** - * MetUpload implements a Harvester servlet to insert, update, or delete - * a single file to Metacat. - */ -public class MetUpload extends HttpServlet { - - /* - * Class fields - */ - private static final String CONFIG_DIR = "WEB-INF"; - private static final String CONFIG_NAME = "metacat.properties"; - - /* Object fields */ - private ServletConfig config = null; - private ServletContext context = null; - private String metacatURL; - - /** - * Handle POST requests made to the Harvester MetUpload servlet. - * - * @param req The request - * @param res The response - * @throws IOException - */ - public void doPost(HttpServletRequest req, HttpServletResponse res) - throws IOException { - Part aPart; - boolean delete = false; - String docid = ""; - String fieldName; - String fieldValue; - String fileName = ""; - FilePart fPart = null; - PrintWriter out = res.getWriter(); - MultipartParser parser = new MultipartParser(req, 1024 * 1024); - ParamPart pPart; - HttpSession sess = req.getSession(true); - String password = (String) sess.getAttribute("password"); - StringReader sr = null; - boolean upload = false; - String username = (String) sess.getAttribute("username"); - - res.setContentType("text/plain"); - - try { - while ((aPart = parser.readNextPart()) != null) { - - if (aPart.isParam() == true) { - pPart = (ParamPart) aPart; - fieldName = pPart.getName(); - - if (fieldName != null) { - if (fieldName.equals("docid")) { - docid = pPart.getStringValue(); - } - else if (fieldName.equals("Upload")) { - upload = true; - } - else if (fieldName.equals("Delete")) { - delete = true; - } - } - } - else if (aPart.isFile() == true) { - fPart = (FilePart) aPart; - fieldName = fPart.getName(); - fileName = fPart.getFileName(); - sr = writeTempFile(fPart, out, docid, fileName); - } - - } - } - catch (Exception e) { - System.out.println("Error parsing parameters: " + e.getMessage()); - } - - if (upload) { - upload(out, docid, sr, username, password); - } - if (delete) { - delete(out, docid, username, password); - } - } - - - /** - * Deletes a file from Metacat based on its docid. - * - * @param out the PrintWriter output stream - * @param docid the Metacat document id, e.g. document.1.1 - * @param username the Metacat username - * @param password the Metacat password - */ - private void delete(PrintWriter out, - String docid, - String username, - String password - ) { - Metacat metacat; - String metacatResponse; - - if (docid.equals("")) { - out.println("Error deleting document: No DocID specified"); - return; - } - - try { - metacat = MetacatFactory.createMetacatConnection(metacatURL); - metacat.login(username, password); - metacatResponse = metacat.delete(docid); - out.println(metacatResponse); - } - catch (MetacatAuthException e) { - out.println("Metacat delete failed: MetacatAuthException:" + - e.getMessage()); - } - catch (MetacatInaccessibleException e) { - out.println("Metacat delete failed: MetacatInaccessibleException:" + - e.getMessage()); - } - catch (InsufficientKarmaException e) { - out.println("Metacat delete failed: InsufficientKarmaException:" + - e.getMessage()); - } - catch (MetacatException e) { - out.println("Metacat delete failed: MetacatException:" + - e.getMessage()); - } - - } - - /** - * Initializes the servlet. Reads properties and initializes object fields. - * - * @throws ServletException - */ - public void init(ServletConfig config) throws ServletException { - String dirPath; - - super.init(config); - this.config = config; - this.context = config.getServletContext(); - dirPath = context.getRealPath(CONFIG_DIR); - - try { - PropertyService.getInstance(); - metacatURL = SystemUtil.getServletURL(); - } catch (ServiceException se) { - System.out.println("Service problem while initializing MetUpload: " + se.getMessage()); - } catch (GeneralPropertyException gpe) { - System.out.println("Error initializing properties utility: " + gpe.getMessage()); - } - - System.out.println("metacatURL: " + metacatURL); - } - - - /** - * Uploads a file to Metacat for insertion or updating. This implementation - * is limited by the fact that all ".1" documents are inserted while all - * other revisions are updated. This logic can be improved after the Metacat - * interface is extended with additional methods to query information about - * revisions, for example, hasDocument() and highestRevision(). - * - * @param out - * the PrintWriter output stream - * @param docid - * the docid, e.g. "document.1.1" - * @param sr - * the StringReader containing the contents of the document - * @param username - * the Metacat username - * @param password - * the Metacat password - */ - private void upload(PrintWriter out, - String docid, - StringReader sr, - String username, - String password - ) { - FileReader fr; - Metacat metacat; - String metacatResponse; - String revision; - int strLen; - - if (docid.equals("")) { - out.println("Error uploading: No docid specified"); - return; - } - - if (sr == null) { - out.println("Error uploading: No EML file specified"); - return; - } - - try { - metacat = MetacatFactory.createMetacatConnection(metacatURL); - metacat.login(username, password); - strLen = docid.length(); - revision = docid.substring((strLen - 2), strLen); - - if (revision.equals(".1")) { - metacatResponse = metacat.insert(docid, sr, null); - } - else { - metacatResponse = metacat.update(docid, sr, null); - } - - out.println(metacatResponse); - } - catch (MetacatAuthException e) { - out.println("Metacat upload failed: MetacatAuthException:" + - e.getMessage()); - } - catch (MetacatInaccessibleException e) { - out.println("Metacat upload failed: MetacatInaccessibleException:" + - e.getMessage()); - } - catch (InsufficientKarmaException e) { - out.println("Metacat upload failed: InsufficientKarmaException:" + - e.getMessage()); - } - catch (MetacatException e) { - out.println("Metacat upload failed: MetacatException:" + - e.getMessage()); - } - catch (IOException e) { - out.println("Metacat upload failed: IOException:" + - e.getMessage()); - } - - } - - - /** - * Writes the uploaded file to disk and then reads it into a StringReader for - * subsequent upload to Metacat. - * - * @param fPart the FilePart object containing the file form parameter - * @param out the PrintWriter output stream - * @param docid the document id, e.g. "document.1.1" - * @param fileName the name of the file to be written to disk - * @return sr a StringReader containing the contents of the file - */ - private StringReader writeTempFile(FilePart fPart, - PrintWriter out, - String docid, - String fileName - ) { - FileReader fr; - String metacatResponse; - StringReader sr = null; - File tmpDir; - String tmpDirPath; - File tmpFile; - String tmpFilePath = ""; - String xmlString = ""; - - if ((fileName == null) || fileName.equals("")) { - return sr; - } - - tmpDirPath = System.getProperties().getProperty("java.io.tmpdir"); - tmpDir = new File(tmpDirPath); - - // Create the temporary directory if it doesn't exist - try { - if (!tmpDir.exists()) { - tmpDir.mkdirs(); - } - } - catch (SecurityException e) { - out.println("Can't create directory: " + tmpDir.getPath()); - out.println(e.getMessage()); - } - - // Write the image to a file - try { - tmpFile = new File(tmpDirPath, fileName); - fPart.writeTo(tmpFile); - tmpFilePath = tmpDirPath + File.separator + fileName; - fr = new FileReader(tmpFilePath); - xmlString = IOUtil.getAsString(fr, true); - sr = new StringReader(xmlString); - tmpFile.delete(); // Clean up the temporary file from disk - } - catch (IOException e) { - out.println("IOException: " + tmpFilePath + e.getMessage()); - } - - return sr; - } - - -}
test/edu/ucsb/nceas/metacattest/harvesterClient/HarvestDetailLogTest.java+0 −182 removed@@ -1,182 +0,0 @@ -/** - * '$RCSfile$' - * Copyright: 2004 Regents of the University of California and the - * National Center for Ecological Analysis and Synthesis, - * and the University of New Mexico - * - * Purpose: To test the HarvestDetailLog class by using JUnit - * - * '$Author$' - * '$Date$' - * '$Revision$' - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package edu.ucsb.nceas.metacattest.harvesterClient; - -import edu.ucsb.nceas.MCTestCase; -import edu.ucsb.nceas.metacat.harvesterClient.Harvester; -import edu.ucsb.nceas.metacat.harvesterClient.HarvestDetailLog; -import edu.ucsb.nceas.metacat.harvesterClient.HarvestDocument; -import edu.ucsb.nceas.metacat.harvesterClient.HarvestSiteSchedule; -import edu.ucsb.nceas.metacat.properties.PropertyService; -import edu.ucsb.nceas.metacat.util.MetacatUtil; - -import java.sql.Connection; -import junit.framework.Test; -import junit.framework.TestSuite; - -/** - * Tests HarvestDetailLog code using JUnit. - * - * @author costa - */ -public class HarvestDetailLogTest extends MCTestCase { - - private Harvester harvester; - private HarvestDetailLog harvestDetailLog; - private HarvestDocument harvestDocument; - private HarvestSiteSchedule harvestSiteSchedule; - /* Initialize Properties*/ - static - { - try - { - PropertyService.getInstance(); - } - catch(Exception e) - { - System.err.println("Exception in initialize option in MetacatServletNetTest "+e.getMessage()); - } - } - - /** - * Constructor for this test. - * - * @param name name of the test case - */ - public HarvestDetailLogTest(String name) { - super(name); - } - - - /** - * Sets up the test by instantiating HarvestSiteSchedule, HarvestDocument, - * and HarvestDetailLog objects. - */ - protected void setUp() { - Connection conn; - boolean commandLineMode = true; - String contactEmail = "jdoe@institution.edu"; - String dateLastHarvest = "2004-04-01 00:00:00.0"; - String dateNextHarvest = "2004-05-01 00:00:00.0"; - int detailLogID; - String documentListURL = - "http://www.institution.edu/~jdoe/public_html/harvestList.xml"; - String documentType = "eml://ecoinformatics.org/eml-2.0.0"; - String documentURL = - "http://www.institution.edu/~jdoe/public_html/document1.xml"; - String errorMessage = "JUnit testing"; - int harvestLogID; - int identifier = 1; - String ldapDN = "uid=jdoe,o=lter,dc=ecoinformatics,dc=org"; - String ldapPwd = "secretpassword"; - int revision = 1; - String scope = "docname"; - int siteScheduleID = 1; - boolean test = true; - String unit = "months"; - int updateFrequency = 1; - - harvester = new Harvester(); - Harvester.loadProperties(metacatContextDir); - conn = harvester.getConnection(); // initializes the database connection - harvester.initLogIDs(); - harvestLogID = harvester.getHarvestLogID(); - detailLogID = harvester.getDetailLogID(); - - harvestSiteSchedule = new HarvestSiteSchedule(harvester, - siteScheduleID, - documentListURL, - ldapDN, - ldapPwd, - dateNextHarvest, - dateLastHarvest, - updateFrequency, - unit, - contactEmail - ); - - harvestDocument = new HarvestDocument(harvester, - harvestSiteSchedule, - scope, - identifier, - revision, - documentType, - documentURL - ); - - harvestDetailLog = new HarvestDetailLog(harvester, conn, harvestLogID, - detailLogID, harvestDocument, - errorMessage); - } - - - /** - * Closes the database connection when the test completes. - */ - protected void tearDown() { - harvester.closeConnection(); - } - - - /** - * Tests that the harvestDetailLog object was constructed. - */ - public void testHarvestDetailLogObject() { - assertTrue(harvestDetailLog != null); - } - - - /** - * Tests the printOutput() method. - */ - public void testPrintOutput() { - harvestDetailLog.printOutput(System.out); - } - - - /** - * Returns the test suite. The test suite consists of all methods in this - * class whose names start with "test". - * - * @return a TestSuite object - */ - public static Test suite() { - return new TestSuite(HarvestDetailLogTest.class); - } - - - /** - * The main program. Runs the test suite. - * - * @param args command line argument array. - */ - public static void main(String args[]) { - junit.textui.TestRunner.run(suite()); - } - -}
test/edu/ucsb/nceas/metacattest/harvesterClient/HarvestDocumentTest.java+0 −202 removed@@ -1,202 +0,0 @@ -/** - * '$RCSfile$' - * Copyright: 2004 Regents of the University of California and the - * National Center for Ecological Analysis and Synthesis, - * and the University of New Mexico - * - * Purpose: To test the HarvestDocument class by using JUnit - * - * '$Author$' - * '$Date$' - * '$Revision$' - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package edu.ucsb.nceas.metacattest.harvesterClient; - -import edu.ucsb.nceas.MCTestCase; -import edu.ucsb.nceas.metacat.harvesterClient.HarvestDocument; -import edu.ucsb.nceas.metacat.harvesterClient.HarvestSiteSchedule; -import edu.ucsb.nceas.metacat.harvesterClient.Harvester; -import edu.ucsb.nceas.metacat.properties.PropertyService; -import edu.ucsb.nceas.metacat.util.MetacatUtil; - -import java.io.StringReader; -import java.util.Date; -import junit.framework.Test; -import junit.framework.TestSuite; - -/** - * Tests HarvestDocument code using JUnit. - * - * @author costa - */ -public class HarvestDocumentTest extends MCTestCase { - - private Harvester harvester; - private HarvestDocument harvestDocument; - private HarvestSiteSchedule harvestSiteSchedule; - /* Initialize Properties*/ - static - { - try - { - PropertyService.getInstance(); - } - catch(Exception e) - { - System.err.println("Exception in initialize option in MetacatServletNetTest "+e.getMessage()); - } - } - - /** - * Constructor for this test. - * - * @param name name of the test case - */ - public HarvestDocumentTest(String name) { - super(name); - } - - - /** - * Sets up the test by instantiating HarvestSiteSchedule and HarvestDocument - * objects. - */ - protected void setUp() { - boolean commandLineMode = true; - String contactEmail = "jdoe@institution.edu"; - String dateLastHarvest = "2004-04-01 00:00:00.0"; - String dateNextHarvest = "2004-05-01 00:00:00.0"; - int detailLogID; - String documentListURL = - "https://code.ecoinformatics.org/code/metacat/branches/METACAT_1_9_4_BRANCH/test/harvester/sampleHarvestList.xml"; - String documentType = "eml://ecoinformatics.org/eml-2.0.0"; - String documentURL = - "https://code.ecoinformatics.org/code/metacat/branches/METACAT_1_9_4_BRANCH/test/eml-sample.xml"; - String errorMessage = "JUnit Testing"; - int harvestLogID; - String harvestOperationCode = "harvester.HarvesterStartup"; - Date harvestStartTime = new Date(); - int identifier = 1; - String ldapDN = "uid=jdoe,o=lter,dc=ecoinformatics,dc=org"; - String ldapPwd = "secretpassword"; - String message = "JUnit Testing"; - int revision = 1; - String scope = "docname"; - int siteScheduleID = 1; - int status = 0; - boolean test = true; - String unit = "months"; - int updateFrequency = 1; - - harvester = new Harvester(); - Harvester.loadProperties(metacatContextDir); - harvester.getConnection(); // initializes the database connection - harvester.initLogIDs(); - harvester.setHarvestStartTime(new Date()); - - harvestSiteSchedule = new HarvestSiteSchedule(harvester, - siteScheduleID, - documentListURL, - ldapDN, - ldapPwd, - dateNextHarvest, - dateLastHarvest, - updateFrequency, - unit, - contactEmail - ); - - harvestDocument = new HarvestDocument(harvester, - harvestSiteSchedule, - scope, - identifier, - revision, - documentType, - documentURL - ); - } - - - /** - * Closes the database connection after the test completes. - */ - protected void tearDown() { - harvester.closeConnection(); - } - - - /** - * Tests the getSiteDocument() method. The test succeeds if a non-null - * StringReader is returned. - */ - public void testGetSiteDocument() { - StringReader stringReader = null; - stringReader = harvestDocument.getSiteDocument(); - assertTrue(stringReader != null); - } - - - /** - * Tests that the harvesterDocument object was created successfully. - */ - public void testHarvestDocumentObject() { - assertTrue(harvestDocument != null); - } - - - /** - * Tests the metacatHighestRevision() method. This test ensures that -1 - * is returned for a non-existent document. - */ - public void testMetacatHighestRevision() { - int highestRevision; - - highestRevision = harvestDocument.metacatHighestRevision(); - assertTrue(highestRevision == -1); - } - - - /** - * Tests the printOutput() method. - */ - public void testPrintOutput() { - harvestDocument.printOutput(System.out); - } - - - /** - * Returns the test suite. The test suite consists of all methods in this - * class whose names start with "test". - * - * @return a TestSuite object - */ - public static Test suite() { - return new TestSuite(HarvestDocumentTest.class); - } - - - /** - * The main program. Runs the test suite. - * - * @param args command line argument array. - */ - public static void main(String args[]) { - junit.textui.TestRunner.run(suite()); - } - -}
test/edu/ucsb/nceas/metacattest/harvesterClient/HarvesterTest.java+0 −158 removed@@ -1,158 +0,0 @@ -/** - * '$RCSfile$' - * Copyright: 2004 Regents of the University of California and the - * National Center for Ecological Analysis and Synthesis, - * and the University of New Mexico - * - * Purpose: To test the Harvester class by using JUnit - * - * '$Author$' - * '$Date$' - * '$Revision$' - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package edu.ucsb.nceas.metacattest.harvesterClient; - -import edu.ucsb.nceas.MCTestCase; -import edu.ucsb.nceas.metacat.harvesterClient.Harvester; -import edu.ucsb.nceas.metacat.properties.PropertyService; -import edu.ucsb.nceas.metacat.util.MetacatUtil; -import edu.ucsb.nceas.utilities.PropertyNotFoundException; - -import junit.framework.Test; -import junit.framework.TestSuite; - -/** - * Tests Harvester code using JUnit. - * - * @author costa - */ -public class HarvesterTest extends MCTestCase { - - private Harvester harvester; - /* Initialize Properties */ - static { - try { - PropertyService.getInstance(); - } catch (Exception e) { - System.err.println("Exception in initialize option in MetacatServletNetTest " - + e.getMessage()); - } - } - - /** - * Constructor for this test. - * - * @param name - * name of the test case - */ - public HarvesterTest(String name) { - super(name); - } - - - /** - * Sets up the test by instantiating a Harvester object. - */ - protected void setUp() { - harvester = new Harvester(); - } - - - /** - * No clean-up actions necessary for these tests. - */ - protected void tearDown() { - } - - - /** - * Tests the dequoteText() string function. It converts single quotes to - * double quotes. - */ - public void testDequoteText() { - String singleQuoteString = "I can't see how it's done!\n"; - String compareString = "I can\"t see how it\"s done!"; - String dequotedString = ""; - - dequotedString = harvester.dequoteText(singleQuoteString); - assertTrue(dequotedString.equals(compareString)); - System.out.println("Dequoted string: " + dequotedString); - } - - - /** - * Tests that the Harvester object was created successfully. - */ - public void testHarvesterObject() { - assertTrue(harvester != null); - } - - - /** - * Tests loading of Harvester properties from a configuration file. - */ - public void testLoadProperties() { - boolean commandLineMode = true; - String ctm = null; - boolean test = true; - - Harvester.loadProperties(metacatContextDir); - try { - ctm = PropertyService.getProperty("harvester.connectToMetacat"); - } catch (PropertyNotFoundException pnfe) { - fail("Could not get connectToMetacat property: "+ pnfe.getMessage()); - } - assertTrue(ctm.equals("true") || ctm.equals("false")); - } - - - /** - * Prints the files in the current working directory. This may be useful for - * determining which directory all other tests are running in. - */ - public void testWorkingDirectory() { - String[] dir = new java.io.File(".").list(); // Get files in current dir - - java.util.Arrays.sort(dir); // Sort the directory listing - - for (int i=0; i<dir.length; i++) - System.out.println(dir[i]); // Print the list - } - - - /** - * Returns the test suite. The test suite consists of all methods in this - * class whose names start with "test". - * - * @return a TestSuite object - */ - public static Test suite() { - return new TestSuite(HarvesterTest.class); - } - - - /** - * The main program. Runs the test suite. - * - * @param args command line argument array. - */ - public static void main(String args[]) { - junit.textui.TestRunner.run(suite()); - } - -}
test/edu/ucsb/nceas/metacattest/harvesterClient/HarvestLogTest.java+0 −253 removed@@ -1,253 +0,0 @@ -/** - * '$RCSfile$' - * Copyright: 2004 Regents of the University of California and the - * National Center for Ecological Analysis and Synthesis, - * and the University of New Mexico - * - * Purpose: To test the HarvestLog class by using JUnit - * - * '$Author$' - * '$Date$' - * '$Revision$' - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package edu.ucsb.nceas.metacattest.harvesterClient; - -import edu.ucsb.nceas.metacat.harvesterClient.HarvestSiteSchedule; -import java.sql.Connection; -import java.util.Date; - -import edu.ucsb.nceas.MCTestCase; -import edu.ucsb.nceas.metacat.harvesterClient.Harvester; -import edu.ucsb.nceas.metacat.harvesterClient.HarvestDocument; -import edu.ucsb.nceas.metacat.harvesterClient.HarvestLog; -import edu.ucsb.nceas.metacat.properties.PropertyService; -import edu.ucsb.nceas.metacat.util.MetacatUtil; - -import junit.framework.Test; -import junit.framework.TestSuite; - -/** - * Tests HarvestLog code using JUnit. - * - * @author costa - */ -public class HarvestLogTest extends MCTestCase { - - private Connection conn; - private Harvester harvester; - private HarvestLog harvestLogShallow; - private HarvestLog harvestLogDeep; - private HarvestSiteSchedule harvestSiteSchedule; - /* Initialize Properties*/ - static - { - try - { - PropertyService.getInstance(); - } - catch(Exception e) - { - System.err.println("Exception in initialize option in MetacatServletNetTest "+e.getMessage()); - } - } - - /** - * Constructor for this test. - * - * @param name name of the test case - */ - public HarvestLogTest(String name) { - super(name); - } - - - /** - * Sets up the test by instantiating a HarvestSiteSchedule, HarvestDocument, - * and two HarvestLog objects. The harvestLogShallow is a HarvestLog that - * does not have an associated HarvestDetailLog. The harvestLogDeep is a - * HarvestLog that does have an associated HarvestDetailLog. - */ - protected void setUp() { - boolean commandLineMode = true; - String contactEmail = "jdoe@institution.edu"; - String dateLastHarvest = "2004-04-01 00:00:00.0"; - String dateNextHarvest = "2004-05-01 00:00:00.0"; - int detailLogID; - String documentListURL = - "http://www.institution.edu/~jdoe/public_html/harvestList.xml"; - String documentType = "eml://ecoinformatics.org/eml-2.0.0"; - String documentURL = - "http://www.institution.edu/~jdoe/public_html/document1.xml"; - String errorMessage = "JUnit Testing"; - HarvestDocument harvestDocument = null; - int harvestLogID; - String harvestOperationCode = "harvester.HarvesterStartup"; - Date harvestStartTime = new Date(); - int identifier = 1; - String ldapDN = "uid=jdoe,o=lter,dc=ecoinformatics,dc=org"; - String ldapPwd = "secretpassword"; - String message = "JUnit Testing"; - int revision = 1; - String scope = "docname"; - int siteScheduleID = 1; - int status = 0; - boolean test = true; - String unit = "months"; - int updateFrequency = 1; - - harvester = new Harvester(); - Harvester.loadProperties(metacatContextDir); - conn = harvester.getConnection(); // initializes the database connection - harvester.initLogIDs(); - harvestLogID = harvester.getHarvestLogID(); - harvestLogShallow = new HarvestLog(harvester, conn, harvestLogID, - harvestStartTime, status, - message, harvestOperationCode, - siteScheduleID); - - harvestLogID = harvester.getHarvestLogID(); - detailLogID = harvester.getDetailLogID(); - harvestSiteSchedule = new HarvestSiteSchedule(harvester, - siteScheduleID, - documentListURL, - ldapDN, - ldapPwd, - dateNextHarvest, - dateLastHarvest, - updateFrequency, - unit, - contactEmail - ); - - harvestDocument = new HarvestDocument(harvester, - harvestSiteSchedule, - scope, - identifier, - revision, - documentType, - documentURL - ); - - - harvestLogDeep = new HarvestLog(harvester, conn, harvestLogID, detailLogID, - harvestStartTime, status, message, - harvestOperationCode, siteScheduleID, - harvestDocument, errorMessage); - } - - - /** - * Closes the database connection after the test completes. - */ - protected void tearDown() { - harvester.closeConnection(); - } - - - /** - * Tests the getCodeLevelValue() method by comparing the value returned for - * "error" (lowest level) to the value returned for "debug" (highest level). - */ - public void testGetCodeLevelValue() { - int lowLevel = harvestLogShallow.getCodeLevelValue("error"); - int highLevel = harvestLogShallow.getCodeLevelValue("debug"); - - assertTrue(lowLevel < highLevel); - } - - - /** - * Tests the getExplanation() method. Check that a harvest operation code is - * associated with an appropriate explanation string. - */ - public void testGetExplanation() { - String harvestOperationCode = "harvester.HarvesterStartup"; - String explanation; - - explanation = harvestLogShallow.getExplanation(harvestOperationCode); - assertTrue(explanation.equals("Harvester start up")); - } - - - /** - * Tests the getHarvestOperationCodeLevel() method. Check that the method - * returns an appropriate code level for a given harvest operation code. - */ - public void testGetHarvestOperationCodeLevel() { - String harvestOperationCode = "harvester.HarvesterStartup"; - String harvestOperationCodeLevel; - - harvestOperationCodeLevel = - harvestLogShallow.getHarvestOperationCodeLevel(harvestOperationCode); - assertTrue(harvestOperationCodeLevel.equalsIgnoreCase("Info")); - } - - - /** - * Tests the construction of HarvestLog object, and a HarvestLog object - * that contains a HarvestDetailLog object. - */ - public void testHarvestLogObject() { - assertTrue(harvestLogShallow != null); - assertTrue(harvestLogDeep != null); - } - - - /** - * Tests the printOutput() method when the code level of this operation is - * greater than the maximum level we wish to print. This means that the output - * should not be printed. - */ - public void testPrintOutputExceedsMax() { - System.out.println("No output should be printed:"); - harvestLogDeep.printOutput(System.out, "Error"); - } - - - /** - * Tests the printOutput() method when the code level of this operation is - * less than the maximum level we wish to print. This means that the output - * should be printed. - */ - public void testPrintOutputWithinMax() { - System.out.println("The log output should be printed:"); - harvestLogDeep.printOutput(System.out, "Debug"); - } - - - /** - * Returns the test suite. The test suite consists of all methods in this - * class whose names start with "test". - * - * @return a TestSuite object - */ - public static Test suite() { - return new TestSuite(HarvestLogTest.class); - } - - - /** - * The main program. Runs the test suite. - * - * @param args command line argument array. - */ - public static void main(String args[]) { - junit.textui.TestRunner.run(suite()); - } - -}
test/edu/ucsb/nceas/metacattest/harvesterClient/HarvestSiteScheduleTest.java+0 −219 removed@@ -1,219 +0,0 @@ -/** - * '$RCSfile$' - * Copyright: 2004 Regents of the University of California and the - * National Center for Ecological Analysis and Synthesis, - * and the University of New Mexico - * - * Purpose: To test the HarvestSiteSchedule class by using JUnit - * - * '$Author$' - * '$Date$' - * '$Revision$' - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -package edu.ucsb.nceas.metacattest.harvesterClient; - -import edu.ucsb.nceas.MCTestCase; -import edu.ucsb.nceas.metacat.harvesterClient.Harvester; -import edu.ucsb.nceas.metacat.harvesterClient.HarvestSiteSchedule; -import edu.ucsb.nceas.metacat.properties.PropertyService; -import edu.ucsb.nceas.metacat.util.MetacatUtil; - -import java.util.Date; -import javax.xml.parsers.ParserConfigurationException; -import junit.framework.Test; -import junit.framework.TestSuite; - -/** - * Tests HarvestSiteSchedule code using JUnit. - * - * @author costa - */ -public class HarvestSiteScheduleTest extends MCTestCase { - - private Harvester harvester; - private HarvestSiteSchedule harvestSiteScheduleFuture; // future date next har - private HarvestSiteSchedule harvestSiteSchedulePast; // past date next harvest - /* Initialize Properties*/ - static - { - try - { - PropertyService.getInstance(); - } - catch(Exception e) - { - System.err.println("Exception in initialize option in MetacatServletNetTest "+e.getMessage()); - } - } - - /** - * Constructor for this test. - * - * @param name name of the test case - */ - public HarvestSiteScheduleTest(String name) { - super(name); - } - - - /** - * Sets up the HarvestSiteScheduleTest by creating a pair of - * HarvestSiteSchedule objects. The harvestSiteScheduleFuture object - * is used for a site with a future date of next harvest (not due for - * harvest now), while the harvestSiteSchedulePast object is used for a site - * with a past date of next harvest (is due for harvest now). - */ - protected void setUp() { - boolean commandLineMode = true; - String contactEmail = "jdoe@institution.edu"; - String dateLastHarvest = "2004-04-01 00:00:00.0"; - String dateNextHarvestFuture = "2056-01-01 00:00:00.0"; - String dateNextHarvestPast = "2000-01-01 00:00:00.0"; - String documentListURL = - "https://code.ecoinformatics.org/code/metacat/branches/METACAT_1_9_4_BRANCH/test/harvester/sampleHarvestList.xml"; - String errorMessage = "JUnit Testing"; - String ldapDN = "uid=jdoe,o=lter,dc=ecoinformatics,dc=org"; - String ldapPwd = "secretpassword"; - int siteScheduleID = 1; - boolean test = true; - String unit = "months"; - int updateFrequency = 1; - - harvester = new Harvester(); - Harvester.loadProperties(metacatContextDir); - harvester.getConnection(); // initializes the database connection - harvester.initLogIDs(); - harvester.setHarvestStartTime(new Date()); - - harvestSiteScheduleFuture = new HarvestSiteSchedule(harvester, - siteScheduleID, - documentListURL, - ldapDN, - ldapPwd, - dateNextHarvestFuture, - dateLastHarvest, - updateFrequency, - unit, - contactEmail - ); - - harvestSiteSchedulePast = new HarvestSiteSchedule(harvester, - siteScheduleID, - documentListURL, - ldapDN, - ldapPwd, - dateNextHarvestPast, - dateLastHarvest, - updateFrequency, - unit, - contactEmail - ); - - } - - - /** - * Closes the database connection after the test completes. - */ - protected void tearDown() { - harvester.closeConnection(); - } - - - /** - * Tests the dueForHarvest() method in the case where a site is not due for - * a harvest. - */ - public void testDueForHarvestFalse() { - boolean dueForHarvest; - - dueForHarvest = harvestSiteScheduleFuture.dueForHarvest(); - assertTrue(dueForHarvest == false); - } - - - /** - * Tests the dueForHarvest() method in the case where a site is due for - * a harvest. - */ - public void testDueForHarvestTrue() { - boolean dueForHarvest; - - dueForHarvest = harvestSiteSchedulePast.dueForHarvest(); - assertTrue(dueForHarvest == true); - } - - - /** - * Tests the parseHarvestList() method. - */ - public void testParseHarvestList() { - boolean success = false; - String schemaLocation = - "eml://ecoinformatics.org/harvestList ./lib/harvester/harvestList.xsd"; - - harvestSiteScheduleFuture.setSchemaLocation(schemaLocation); - - try { - success = harvestSiteScheduleFuture.parseHarvestList(); - assertTrue(success == true); - } - catch (ParserConfigurationException e) { - fail("ParserConfigurationException: " + e.getMessage()); - } - } - - - /** - * Tests the printOutput() method. - */ - public void testPrintOutput() { - harvestSiteScheduleFuture.printOutput(System.out); - } - - - /** - * Tests that the harvesterDocument object was created successfully. - */ - public void testHarvestSiteScheduleObject() { - assertTrue(harvestSiteScheduleFuture != null); - assertTrue(harvestSiteSchedulePast != null); - } - - - /** - * Returns the test suite. The test suite consists of all methods in this - * class whose names start with "test". - * - * @return a TestSuite object - */ - public static Test suite() { - return new TestSuite(HarvestSiteScheduleTest.class); - } - - - /** - * The main program. Runs the test suite. - * - * @param args command line argument array. - */ - public static void main(String args[]) { - junit.textui.TestRunner.run(suite()); - } - -}
Vulnerability mechanics
Root cause
"Missing input sanitization in `HarvesterRegistration.dbInsert()` — the `quoteString()` helper wraps user-supplied values in single quotes without escaping, enabling SQL injection via string concatenation."
Attack vector
An unauthenticated attacker sends a crafted HTTP request to the `/harvesterRegistration` endpoint with malicious payloads in the `unit`, `contactEmail`, or `documentListURL` parameters. The servlet does not verify a real LDAP identity, so the vulnerable `INSERT` proceeds without authentication. Because the PostgreSQL backend supports stacked queries via `Statement.executeUpdate()`, the attacker can inject arbitrary SQL commands, achieving full read/write/execute access in the Metacat database context.
Affected code
The vulnerable code resides in the `HarvesterRegistration` servlet, specifically the `dbInsert()` method which builds an SQL `INSERT` statement against the `HARVEST_SITE_SCHEDULE` table using string concatenation. The `quoteString()` helper wraps values in single quotes without any escaping, and the three request parameters `unit`, `contactEmail`, and `documentListURL` reach this sink. The entire `harvesterClient` package, including `HarvesterRegistration.java`, was removed in commit [patch_id=6110799].
What the fix does
The patch [patch_id=6110799] removes the entire `harvesterClient` package (16 files, 6471 lines), including `HarvesterRegistration.java` which contained the SQL injection vulnerability. By deleting the vulnerable endpoint entirely, the attack surface is eliminated. The advisory states this was remediated in Metacat 3.0.0.
Preconditions
- networkThe `/harvesterRegistration` endpoint must be exposed and reachable over the network.
- authNo authentication or LDAP identity verification is required; the servlet allows the insert to proceed without checking credentials.
- inputThe attacker must supply values for `unit`, `contactEmail`, or `documentListURL` parameters containing SQL metacharacters.
Generated on Jun 15, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
2News mentions
0No linked articles in our index yet.