
java.fedora.server.utilities.rebuild.SQLRebuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fcrepo-client Show documentation
Show all versions of fcrepo-client Show documentation
The Fedora Client is a Java Library that allows API access to a Fedora Repository. The client is typically one part of a full Fedora installation.
The newest version!
/*
* -----------------------------------------------------------------------------
*
* License and Copyright: The contents of this file are subject to the
* Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of
* the License at
* http://www.fedora-commons.org/licenses.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
*
* The entire file consists of original code.
* Copyright © 2008 Fedora Commons, Inc.
*
Copyright © 2002-2007 The Rector and Visitors of the University of
* Virginia and Cornell University
* All rights reserved.
*
* -----------------------------------------------------------------------------
*/
package fedora.server.utilities.rebuild;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import fedora.common.Constants;
import fedora.server.Context;
import fedora.server.ReadOnlyContext;
import fedora.server.Server;
import fedora.server.config.DatastoreConfiguration;
import fedora.server.config.ModuleConfiguration;
import fedora.server.config.ServerConfiguration;
import fedora.server.errors.ConnectionPoolNotFoundException;
import fedora.server.errors.InitializationException;
import fedora.server.errors.LowlevelStorageException;
import fedora.server.errors.ModuleInitializationException;
import fedora.server.errors.ObjectNotFoundException;
import fedora.server.errors.ServerException;
import fedora.server.errors.StorageDeviceException;
import fedora.server.management.PIDGenerator;
import fedora.server.search.FieldSearch;
import fedora.server.storage.BDefReader;
import fedora.server.storage.BMechReader;
import fedora.server.storage.ConnectionPool;
import fedora.server.storage.ConnectionPoolManager;
import fedora.server.storage.DOManager;
import fedora.server.storage.DOReader;
import fedora.server.storage.DOWriter;
import fedora.server.storage.lowlevel.ILowlevelStorage;
import fedora.server.storage.replication.DOReplicator;
import fedora.server.storage.types.Datastream;
import fedora.server.storage.types.DigitalObject;
import fedora.server.storage.types.Disseminator;
import fedora.server.utilities.SQLUtility;
import fedora.server.utilities.TableSpec;
/**
* A Rebuilder for the SQL database.
*
* @@version $Id: SQLRebuilder.java 6095 2007-08-31 19:14:55Z cwilper $
*/
public class SQLRebuilder implements Rebuilder {
/** Logger for this class. */
private static final Logger LOG = Logger.getLogger(
Rebuilder.class.getName());
private File m_serverDir;
private ServerConfiguration m_serverConfig;
private static Server s_server;
private ConnectionPool m_connectionPool;
private Connection m_connection;
private Context m_context;
private String m_echoString = "Added PID";
/**
* Get a short phrase describing what the user can do with this rebuilder.
*/
public String getAction() {
return "Rebuild SQL database.";
}
/**
* Returns true is the server _must_ be shut down for this
* rebuilder to safely operate.
*/
public boolean shouldStopServer()
{
return(true);
}
/**
* Initialize the rebuilder, given the server configuration.
*
* @@returns a map of option names to plaintext descriptions.
*/
public Map init(File serverDir,
ServerConfiguration serverConfig) {
m_serverDir = serverDir;
m_serverConfig = serverConfig;
Map m = new HashMap();
return m;
}
/**
* Validate the provided options and perform any necessary startup tasks.
*/
public void start(Map options) throws Exception
{
// This must be done before starting "RebuildServer"
// rather than after, so any application caches
// (in particular the hash map held by PIDGenerator)
// don't get out of sync with the database.
blankExistingTables( );
try {
s_server = RebuildServer.getRebuildInstance(
new File(Constants.FEDORA_HOME));
// now get the connectionpool
ConnectionPoolManager cpm=(ConnectionPoolManager) s_server.
getModule("fedora.server.storage.ConnectionPoolManager");
if (cpm==null)
{
throw new ModuleInitializationException(
"ConnectionPoolManager not loaded.", "ConnectionPoolManager");
}
m_connectionPool = cpm.getPool();
m_context = ReadOnlyContext.getContext("utility", "fedoraAdmin", "", /*null, */ReadOnlyContext.DO_OP);
String registryClassTemp = s_server.getParameter("registry");
String reason = "registry";
ILowlevelStorage llstore = (ILowlevelStorage) s_server.
getModule("fedora.server.storage.lowlevel.ILowlevelStorage");
try
{
llstore.rebuildObject();
llstore.rebuildDatastream();
}
catch (LowlevelStorageException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
catch (InitializationException ie)
{
LOG.error("Error initializing", ie);
throw ie;
}
}
public static List getExistingTables( Connection conn )
throws SQLException
{
ArrayList existing=new ArrayList();
DatabaseMetaData dbMeta=conn.getMetaData();
ResultSet r = null;
// Get a list of tables that don't exist, if any
try
{
r = dbMeta.getTables(null, null, "%", null);
HashSet existingTableSet=new HashSet();
while (r.next())
{
existing.add(r.getString("TABLE_NAME"));
}
r.close();
r = null;
}
catch (SQLException sqle)
{
throw new SQLException(sqle.getMessage());
}
finally
{
try {
if (r != null) r.close();
}
catch (SQLException sqle2)
{
throw sqle2;
}
finally
{
r=null;
}
}
return existing;
}
/**
* Delete all rows from all Fedora-related tables (except the resource index
* ones) that exist in the database.
*/
private void blankExistingTables( )
{
Connection connection = null;
try {
connection = getDefaultConnection();
List existingTables = getExistingTables(connection);
List fedoraTables = getFedoraTables();
for (int i = 0; i < existingTables.size(); i++)
{
String origTableName = existingTables.get(i).toString();
String tableName = origTableName.toUpperCase();
if (fedoraTables.contains(tableName) && !tableName.startsWith("RI"))
{
System.out.println("Cleaning up table: " + origTableName);
try {
executeSql(connection, "DELETE FROM " + origTableName);
}
catch (LowlevelStorageException lle)
{
System.err.println(lle.getMessage());
System.err.flush();
}
}
}
}
catch (SQLException e)
{
throw new RuntimeException("DB error while blanking existing tables", e);
}
finally
{
try { connection.close(); } catch (Exception e) { }
}
}
/**
* Get the names of all Fedora tables listed in the server's dbSpec file.
*
* Names will be returned in ALL CAPS so that case-insensitive comparisons
* can be done.
*/
private List getFedoraTables() {
try {
String dbSpecLocation = "fedora/server/storage/resources/DefaultDOManager.dbspec";
InputStream in = getClass().getClassLoader().getResourceAsStream(dbSpecLocation);
List specs = TableSpec.getTableSpecs(in);
ArrayList names = new ArrayList();
for (int i = 0; i < specs.size(); i++) {
TableSpec spec = (TableSpec) specs.get(i);
names.add(spec.getName().toUpperCase());
}
return names;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Unexpected error reading dbspec file", e);
}
}
public void executeSql(Connection connection, String sql )
throws LowlevelStorageException
{
Statement statement = null;
try {
statement = connection.createStatement();
if (statement.execute(sql))
{
throw new LowlevelStorageException(true, "sql returned query results for a nonquery");
}
int updateCount = statement.getUpdateCount();
}
catch (SQLException e1)
{
throw new LowlevelStorageException(true, "sql failurex (exec)", e1);
}
finally
{
try {
if (statement != null) statement.close();
}
catch (Exception e2)
{ // purposely general to include uninstantiated statement, connection
throw new LowlevelStorageException(true,"sql failure closing statement, connection, pool (exec)", e2);
}
finally
{
statement=null;
}
}
}
/**
* Add the data of interest for the given object.
*/
public void addObject(DigitalObject obj)
{
// CURRENT TIME:
// Get the current time to use for created dates on object
// and object components (if they are not already there).
Date nowUTC=new Date();
DOReplicator replicator=(DOReplicator) s_server.getModule("fedora.server.storage.replication.DOReplicator");
DOManager manager=(DOManager) s_server.getModule("fedora.server.storage.DOManager");
FieldSearch fieldSearch=(FieldSearch) s_server.getModule("fedora.server.search.FieldSearch");
PIDGenerator pidGenerator=(PIDGenerator) s_server.getModule("fedora.server.management.PIDGenerator");
// SET OBJECT PROPERTIES:
LOG.debug("Rebuild: Setting object/component states and create dates if unset...");
// set object state to "A" (Active) if not already set
if (obj.getState()==null || obj.getState().equals("")) {
obj.setState("A");
}
// set object create date to UTC if not already set
if (obj.getCreateDate()==null || obj.getCreateDate().equals("")) {
obj.setCreateDate(nowUTC);
}
// set object last modified date to UTC
obj.setLastModDate(nowUTC);
// SET OBJECT PROPERTIES:
LOG.debug("Rebuild: Setting object/component states and create dates if unset...");
// set object state to "A" (Active) if not already set
if (obj.getState()==null || obj.getState().equals("")) {
obj.setState("A");
}
// set object create date to UTC if not already set
if (obj.getCreateDate()==null || obj.getCreateDate().equals("")) {
obj.setCreateDate(nowUTC);
}
// set object last modified date to UTC
obj.setLastModDate(nowUTC);
// SET DATASTREAM PROPERTIES...
Iterator dsIter=obj.datastreamIdIterator();
while (dsIter.hasNext()) {
List dsList=(List) obj.datastreams((String) dsIter.next());
for (int i=0; i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy