001/* 002 * #%L 003 * Netarchivesuite - harvester 004 * %% 005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library, 006 * the National Library of France and the Austrian National Library. 007 * %% 008 * This program is free software: you can redistribute it and/or modify 009 * it under the terms of the GNU Lesser General Public License as 010 * published by the Free Software Foundation, either version 2.1 of the 011 * License, or (at your option) any later version. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Lesser Public License for more details. 017 * 018 * You should have received a copy of the GNU General Lesser Public 019 * License along with this program. If not, see 020 * <http://www.gnu.org/licenses/lgpl-2.1.html>. 021 * #L% 022 */ 023 024package dk.netarkivet.harvester.datamodel; 025 026import java.io.Reader; 027import java.io.StringReader; 028import java.sql.Clob; 029import java.sql.Connection; 030import java.sql.PreparedStatement; 031import java.sql.ResultSet; 032import java.sql.SQLException; 033import java.util.Iterator; 034import java.util.List; 035 036import org.slf4j.Logger; 037import org.slf4j.LoggerFactory; 038 039import dk.netarkivet.common.exceptions.ArgumentNotValid; 040import dk.netarkivet.common.exceptions.IOFailure; 041import dk.netarkivet.common.exceptions.PermissionDenied; 042import dk.netarkivet.common.exceptions.UnknownID; 043import dk.netarkivet.common.utils.DBUtils; 044import dk.netarkivet.common.utils.ExceptionUtils; 045 046/** 047 * Implements the TemplateDAO with databases. 048 * <p> 049 * The statements to create the tables are now in scripts/sql/createfullhddb.sql 050 */ 051 052public class TemplateDBDAO extends TemplateDAO { 053 054 /** the log. */ 055 private static final Logger log = LoggerFactory.getLogger(TemplateDBDAO.class); 056 057 /** 058 * Default constructor. Only used by TemplateDAO,getInstance(). 059 */ 060 TemplateDBDAO() { 061 Connection connection = HarvestDBConnection.get(); 062 try { 063 HarvesterDatabaseTables.checkVersion(connection, HarvesterDatabaseTables.ORDERTEMPLATES); 064 } finally { 065 HarvestDBConnection.release(connection); 066 } 067 } 068 069 /** 070 * Read an XML order file for the named order XML. 071 * 072 * @param orderXmlName The name of the order.xml document 073 * @return The contents of this order.xml document 074 */ 075 public synchronized HeritrixTemplate read(String orderXmlName) { 076 ArgumentNotValid.checkNotNullOrEmpty(orderXmlName, "String orderXmlName"); 077 Connection c = HarvestDBConnection.get(); 078 PreparedStatement s = null; 079 try { 080 s = c.prepareStatement("SELECT orderxml FROM ordertemplates WHERE name = ?"); 081 s.setString(1, orderXmlName); 082 ResultSet res = s.executeQuery(); 083 if (!res.next()) { 084 throw new UnknownID("Can't find template " + orderXmlName); 085 } 086 Reader orderTemplateReader = null; 087 if (DBSpecifics.getInstance().supportsClob()) { 088 Clob clob = res.getClob(1); 089 090 orderTemplateReader = clob.getCharacterStream(); 091 } else { 092 String string = res.getString(1); 093 // log.debug("clob=" + string); 094 orderTemplateReader = new StringReader(string); 095 } 096 System.out.println("Calling HeritrixTemplate.read() w/ arg:" + orderTemplateReader); 097 return HeritrixTemplate.read(orderTemplateReader); 098 } catch (SQLException e) { 099 final String message = "SQL error finding order.xml for " + orderXmlName + "\n" 100 + ExceptionUtils.getSQLExceptionCause(e); 101 log.warn(message, e); 102 throw new IOFailure(message, e); 103 /* 104 } catch (DocumentException e) { 105 final String message = "Error parsing order.xml string for " + orderXmlName; 106 log.warn(message, e); 107 throw new IOFailure(message, e); 108 */ 109 } 110 finally { 111 DBUtils.closeStatementIfOpen(s); 112 HarvestDBConnection.release(c); 113 } 114 } 115 116 /** 117 * Returns an iterator with all names of order.xml-templates. 118 * 119 * @return Iterator<String> with all names of templates (without .xml). 120 */ 121 public synchronized Iterator<String> getAll() { 122 Connection c = HarvestDBConnection.get(); 123 try { 124 List<String> names = DBUtils.selectStringList(c, "SELECT name FROM ordertemplates ORDER BY name"); 125 return names.iterator(); 126 } finally { 127 HarvestDBConnection.release(c); 128 } 129 } 130 131 /** 132 * Return true if the database contains a template with the given name. 133 * 134 * @param orderXmlName Name of an order.xml template (without .xml). 135 * @return True if such a template exists. 136 * @throws ArgumentNotValid If the orderXmlName is null or an empty String 137 */ 138 public synchronized boolean exists(String orderXmlName) { 139 ArgumentNotValid.checkNotNullOrEmpty(orderXmlName, "String orderXmlName"); 140 141 Connection c = HarvestDBConnection.get(); 142 try { 143 return exists(c, orderXmlName); 144 } finally { 145 HarvestDBConnection.release(c); 146 } 147 } 148 149 /** 150 * Return true if the database contains a template with the given name. 151 * 152 * @param orderXmlName Name of an order.xml template (without .xml). 153 * @return True if such a template exists. 154 * @throws ArgumentNotValid If the orderXmlName is null or an empty String 155 */ 156 private synchronized boolean exists(Connection c, String orderXmlName) { 157 int count = DBUtils.selectIntValue(c, "SELECT COUNT(*) FROM ordertemplates WHERE name = ?", orderXmlName); 158 return count == 1; 159 } 160 161 /** 162 * Create a template. The template must not already exist. 163 * 164 * @param orderXmlName Name of the template. 165 * @param orderXml XML documents that is a Heritrix order.xml template. 166 * @throws ArgumentNotValid If the orderXmlName is null or an empty String, or the orderXml is null. 167 */ 168 public synchronized void create(String orderXmlName, HeritrixTemplate orderXml) { 169 ArgumentNotValid.checkNotNullOrEmpty(orderXmlName, "String orderXmlName"); 170 ArgumentNotValid.checkNotNull(orderXml, "HeritrixTemplate orderXml"); 171 172 Connection c = HarvestDBConnection.get(); 173 PreparedStatement s = null; 174 try { 175 if (exists(c, orderXmlName)) { 176 throw new PermissionDenied("An order template called " + orderXmlName + " already exists"); 177 } 178 179 s = c.prepareStatement("INSERT INTO ordertemplates " + "( name, orderxml ) VALUES ( ?, ? )"); 180 DBUtils.setStringMaxLength(s, 1, orderXmlName, Constants.MAX_NAME_SIZE, orderXmlName, "length"); 181 DBUtils.setClobMaxLength(s, 2, orderXml.getXML(), Constants.MAX_ORDERXML_SIZE, "size", orderXmlName); 182 s.executeUpdate(); 183 } catch (SQLException e) { 184 throw new IOFailure("SQL error creating template " + orderXmlName + "\n" 185 + ExceptionUtils.getSQLExceptionCause(e), e); 186 } finally { 187 HarvestDBConnection.release(c); 188 } 189 } 190 191 /** 192 * Update a template. The template must already exist. 193 * 194 * @param orderXmlName Name of the template. 195 * @param orderXml XML document that is a Heritrix order.xml template. 196 * @throws PermissionDenied If the template does not exist 197 * @throws IOFailure If the template could not be 198 * @throws ArgumentNotValid If the orderXmlName is null or an empty String, or the orderXml is null. 199 */ 200 public synchronized void update(String orderXmlName, HeritrixTemplate orderXml) { 201 ArgumentNotValid.checkNotNullOrEmpty(orderXmlName, "String orderXmlName"); 202 ArgumentNotValid.checkNotNull(orderXml, "HeritrixTemplate orderXml"); 203 204 Connection c = HarvestDBConnection.get(); 205 PreparedStatement s = null; 206 try { 207 if (!exists(c, orderXmlName)) { 208 throw new PermissionDenied("No order template called " + orderXmlName + " exists"); 209 } 210 211 s = c.prepareStatement("UPDATE ordertemplates SET orderxml = ? WHERE name = ?"); 212 DBUtils.setClobMaxLength(s, 1, orderXml.getXML(), Constants.MAX_ORDERXML_SIZE, "size", orderXmlName); 213 s.setString(2, orderXmlName); 214 s.executeUpdate(); 215 } catch (SQLException e) { 216 throw new IOFailure("SQL error updating template " + orderXmlName + "\n" 217 + ExceptionUtils.getSQLExceptionCause(e), e); 218 } finally { 219 HarvestDBConnection.release(c); 220 } 221 } 222 223}