All Downloads are FREE. Search and download functionalities are using the official Maven repository.

java.fedora.server.storage.FastBmechReader Maven / Gradle / Ivy

/*
 * -----------------------------------------------------------------------------
 *
 * 

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.storage; import java.io.InputStream; import java.sql.Connection; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.Date; import java.util.Enumeration; import java.util.Vector; import org.apache.log4j.Logger; import fedora.server.Context; import fedora.server.Server; import fedora.server.errors.GeneralException; import fedora.server.errors.ServerException; import fedora.server.storage.types.BMechDSBindSpec; import fedora.server.storage.types.MethodDef; import fedora.server.storage.types.MethodDefOperationBind; import fedora.server.storage.types.MethodParmDef; /** *

Title: FastBmechReader.java

*

Description: BMECH Object Reader that accesses objects located in the * "Fast" storage area. It mirros the functionality of SimpleBMechReader for * the "Definitive" storage aread. To enhance performance of disseminations, * there are two distinct storage areas for digital objects: *

    *
  1. * "Fast" storage area - The storage area containing a subset of digital * objects that is optimized for performance. Both the composition of the * subset of objects and storage area are implementation specific. For Phase 1, * this object subset consists of a partial replication of the most current * version of each object and is used as the primary source for resolving * dissemination requests. The replication is partial since only information * required to disseminate the object is replicated in the Fast storage area. * For Phase 1, the Fast storage area is implemented as a relational database * that is accessed via JDBC. Note that an appropriate definitve reader * should always be used to obtain the most complete information about a * specific object. A fast reader is used primarily for dissemination * requests.. *
  2. *
  3. * Definitive storage area - The storage area containing complete information on * all digital objects in the repository. This storage area is used as the * authoritative source for reading complete information about a digital object. * This storage area is used as a secondary source for resolving dissemination * requests when the specified object does not exist in the Fast storage area. *
  4. *
*

This reader is designed to read bmech objects from the "Fast" storage area * that is implemented as a relational database. If the object cannot be found * in the relational database, this reader will attempt to read the object * from the Definitive storage area using the appropriate definitive reader. * When the object exists in both storage areas, preference is given to the * Fast storage area since this reader is designed to read primarily from the * Fast Storage area. A SimpleBMechReader should always be used to * read the authoritative version of a bmech object.

*

Note that versioning is not implemented in Phase 1. Methods in * FastBmechReader that contain arguments related to versioning * date such as versDateTime or asOfDate will be * ignored in Phase 1.

* * @author [email protected] * @version $Id: FastBmechReader.java 5218 2006-11-20 05:10:11Z cwilper $ */ public class FastBmechReader extends FastDOReader implements BMechReader { /** Logger for this class. */ private static final Logger LOG = Logger.getLogger( FastBmechReader.class.getName()); /** Instance of BMechReader */ private BMechReader bMechReader = null; /** Persistent identifier of behavior mechanism object */ private String bMechPID = null; /** Label of behavior mechanism object */ private String bMechLabel = null; /** *

Constructs an instance of FastBmechReader.

* *

Constructs a new FastBmechReader for the specified bmech * object. If the object is found, this constructor initializes the class * variables for bMechPID and bMechLabel. * * @param context The context of this request. * @param objectPID The persistent identifier of the bmech object. * @throws ServerException If any type of error occurred fulfilling the * request. */ public FastBmechReader(Context context, String objectPID) throws ServerException { super(context, objectPID); // Override FastDOReader constructor. // In FastBmechReader, the object PID is assumed to always be a bmech PID. try { // Attempt to find bmech object in either Fast or Definitive store this.bMechLabel = locateBmechPID(objectPID); this.bMechPID = objectPID; } catch (ServerException se) { throw se; } catch (Throwable th) { LOG.error("Unable to construct FastBmechReader", th); throw new GeneralException("[FastBmechReader] An error has occurred. " + "The error was a \"" + th.getClass().getName() + "\" . " + "Reason: \"" + th.getMessage() + "\" ."); } } /** *

Gets default mechanism method parameters associated with the specified * method name. Default method parameters are defined by the Behavior * Mechanism object as mechanism default parameters and cannot be altered * by the user.

* * @param methodName The name of the method. * @param versDateTime The versioning datetime stamp. * @return An array of method parameter definitions. * @throws GeneralException If there was any misc exception that we want to * catch and re-throw as a Fedora exception. Extends ServerException. */ public MethodParmDef[] getServiceMethodParms(String methodName, Date versDateTime) throws GeneralException { MethodParmDef[] methodParms = null; MethodParmDef methodParm = null; Vector queryResults = new Vector(); Connection connection = null; Statement statement = null; ResultSet rs = null; if (isFoundInFastStore && versDateTime == null) { // Requested object exists in Fast storage area and is NOT versioned; // query relational database String query = "SELECT DISTINCT " + "defParmName," + "defParmDefaultValue," + "defParmDomainValues," + "defParmRequiredFlag," + "defParmLabel," + "defParmType " + " FROM " + "bDef," + "bMech," + "mechImpl," + "method," + "mechDefParm " + " WHERE " + "bMech.bMechDbID=mechDefParm.bMechDbID AND " + "method.methodDbID=mechDefParm.methodDbID AND " + "bMech.bDefDbID=method.bDefDbID AND " + "mechImpl.methodDbID=method.methodDbID AND " + "bMech.bDefDbID=bDef.bDefDbID AND " + "bMech.bMechPID='" + bMechPID + "' AND " + "method.methodName='" + methodName + "'"; LOG.debug("GetBmechDefaultMethodParmQuery=" + query); try { connection = connectionPool.getConnection(); LOG.debug("connectionPool = " + connectionPool); statement = connection.createStatement(); rs = statement.executeQuery(query); ResultSetMetaData rsMeta = rs.getMetaData(); int cols = rsMeta.getColumnCount(); // Note: a row is returned for each method parameter while (rs.next()) { methodParm = new MethodParmDef(); String[] results = new String[cols]; for (int i=1; i<=cols; i++) { results[i-1] = rs.getString(i); } methodParm.parmName = results[0]; methodParm.parmDefaultValue = results[1]; methodParm.parmDomainValues = results[2].split(","); Boolean B = new Boolean(results[3]); methodParm.parmRequired = B.booleanValue(); methodParm.parmLabel = results[4]; methodParm.parmType = results[5]; LOG.debug("methodParms: " + methodParm.parmName + "\nlabel: " + methodParm.parmLabel + "\ndefault: " + methodParm.parmDefaultValue + "\nrequired: " + methodParm.parmRequired + "\ntype: " + methodParm.parmType); for (int j=0; jGets all method defintiions associated with the specified Behavior * Mechanism. Note the PID of the associated Behavior Mechanism object is * determined via reflection based on the specified PID of the digital object * and the PID of its Behavior Definition object. This method retrieves the * list of available methods based on the assocaited Behavior Mechanism * object and NOT the Behavior Definition object. This is done to insure * that only methods that have been implemented in the mechanism are returned. * This distinction is only important when versioning is enabled * in a later release. When versioning is enabled, it is possible * that a versioned Behavior Definition may have methods that have not * yet been implemented by all of its associated Behavior Mechanisms. * In such a case, only those methods implemented in the mechanism * will be returned.

* * @param versDateTime The versioning datetime stamp. * @return An array of method definitions. * @throws ServerException If there was any misc exception that we want to * catch and re-throw as a Fedora exception. Extends ServerException. */ public MethodDef[] getServiceMethods(Date versDateTime) throws ServerException { MethodDef[] methodDefs = null; MethodDef methodDef = null; Vector queryResults = new Vector(); Connection connection = null; Statement statement = null; ResultSet rs = null; if (isFoundInFastStore && versDateTime == null) { // Requested object exists in Fast storage area and is NOT versioned; // query relational database String query = "SELECT DISTINCT " + "method.methodName," + "method.methodLabel " + "FROM " + "bDef," + "method," + "bMech," + "mechImpl " + "WHERE " + "bMech.bMechDbID = mechImpl.bMechDbID AND " + "bDef.bDefDbID = mechImpl.bDefDbID AND " + "method.methodDbID = mechImpl.methodDbID AND " + "method.bDefDbID = bDef.bDefDbID AND " + "bMech.bMechPID = \'" + bMechPID + "\'"; LOG.debug("getObjectMethodsQuery: " + query); String[] results = null; try { connection = connectionPool.getConnection(); statement = connection.createStatement(); rs = statement.executeQuery(query); ResultSetMetaData rsMeta = rs.getMetaData(); int cols = rsMeta.getColumnCount(); while (rs.next()) { results = new String[cols]; methodDef = new MethodDef(); for (int i=1; i<=cols; i++) { results[i-1] = rs.getString(i); } methodDef.methodName = results[0]; methodDef.methodLabel = results[1]; try { methodDef.methodParms = getServiceMethodParms(methodDef.methodName, versDateTime); } catch (Throwable th) { // Failed to get method paramters throw new GeneralException("[FastBmechReader] An error has occured. The " + "underlying error was a \"" + th.getClass().getName() + "\" . The message was \"" + th.getMessage() + "\" ."); } queryResults.add(methodDef); } methodDefs = new MethodDef[queryResults.size()]; int rowCount = 0; for (Enumeration e = queryResults.elements(); e.hasMoreElements();) { methodDefs[rowCount] = (MethodDef)e.nextElement(); rowCount++; } return methodDefs; } catch (Throwable th) { throw new GeneralException("[FastBmechReader] An error has occured. The " + "underlying error was a \"" + th.getClass().getName() + "\" . The message was \"" + th.getMessage() + "\" ."); } finally { try { if (rs != null) rs.close(); if (statement != null) statement.close(); if (connection!=null) connectionPool.free(connection); } catch (SQLException sqle) { throw new GeneralException("[FastBmechReader] Unexpected error " + "from SQL database. The error was \"" + sqle.getMessage() + "\" ."); } finally { rs=null; statement=null; } } } else if (isFoundInDefinitiveStore || versDateTime != null) { // Requested object exists in Definitive storage area or is versioned; // query Definitive storage area. try { if (bMechReader == null) { bMechReader = m_manager.getBMechReader(Server.USE_DEFINITIVE_STORE, m_context, PID); } return bMechReader.getServiceMethods(versDateTime); } catch (ServerException se) { throw se; } catch (Throwable th) { throw new GeneralException("[FastbMechReader] Definitive bMechReader returned " + "error. The underlying error was a \"" + th.getClass().getName() + "\" . The message was \"" + th.getMessage() + "\" ."); } } return null; } public MethodDefOperationBind[] getServiceMethodBindings(Date versDateTime) throws ServerException { try { if (bMechReader == null) { bMechReader = m_manager.getBMechReader(Server.GLOBAL_CHOICE, m_context, PID); } return bMechReader.getServiceMethodBindings(versDateTime); } catch (ServerException se) { throw se; } catch (Throwable th) { throw new GeneralException("[FastbMechReader] Definitive bMechReader returned " + "error. The underlying error was a \"" + th.getClass().getName() + "\" . The message was \"" + th.getMessage() + "\" ."); } } /** *

Gets XML containing method definitions. Since the XML representation * of digital objects is not stored in the Fast storage area, this method * uses a BMechReader to query the Definitive * storage area.

* * @param versDateTime The versioning datetime stamp. * @return A stream of bytes containing XML-encoded representation of * method definitions from XML in the Behavior Mechanism * object. * @throws ServerException If any type of error occurred fulfilling the * request. */ public InputStream getServiceMethodsXML(Date versDateTime) throws ServerException { try { if (bMechReader == null) { bMechReader = m_manager.getBMechReader(Server.GLOBAL_CHOICE, m_context, PID); } return bMechReader.getServiceMethodsXML(versDateTime); } catch (ServerException se) { throw se; } catch (Throwable th) { throw new GeneralException("[FastbMechReader] Definitive bMechReader returned " + "error. The underlying error was a \"" + th.getClass().getName() + "\" . The message was \"" + th.getMessage() + "\" ."); } } public BMechDSBindSpec getServiceDSInputSpec(Date versDateTime) throws ServerException { try { if (bMechReader == null) { bMechReader = m_manager.getBMechReader(Server.USE_DEFINITIVE_STORE, m_context, PID); } return bMechReader.getServiceDSInputSpec(versDateTime); } catch (ServerException se) { throw se; } catch (Throwable th) { throw new GeneralException("[FastbMechReader] Definitive bMechReader returned " + "error. The underlying error was a \"" + th.getClass().getName() + "\" . The message was \"" + th.getMessage() + "\" ."); } } /** *

Locates the specified bmech object using its persistent identifier. * This method will first attempt to locate the object in the Fast storage * area. If the the object cannot be located there, it will then try to find * it in the Definitive storage area. If the object is found, the object's * label is returned. Otherwise, it throws * GeneralException.

* * @param bMechPID persistent identifier of the digital object. * @return String containing label of the specified digital object. * @throws GeneralException If there was any misc exception that we want to * catch and re-throw as a Fedora exception. Extends ServerException. * @throws ServerException If any type of error occurred fulfilling the * request. */ public String locateBmechPID(String bMechPID) throws GeneralException, ServerException { Connection connection = null; Statement statement = null; ResultSet rs = null; String query = "SELECT " + "bMech.bMechLabel " + "FROM " + "bMech " + "WHERE " + "bMech.bMechPID=\'" + bMechPID + "\'"; LOG.debug("LocateBmechPIDQuery: " + query); try { connection = connectionPool.getConnection(); LOG.debug("LocateBmechPIDConnectionPool: " + connectionPool); statement = connection.createStatement(); rs = statement.executeQuery(query); while (rs.next()) { bMechLabel = rs.getString(1); } } catch (Throwable th) { LOG.error("Error locating BMech PID", th); throw new GeneralException("[FastBmechReader] An error has occurred. The " + "underlying error was a \"" + th.getClass().getName() + "\" . The message was \"" + th.getMessage() + "\" ."); } finally { try { if (rs != null) rs.close(); if (statement != null) statement.close(); if (connection!=null) connectionPool.free(connection); } catch (SQLException sqle) { throw new GeneralException("[FastBmechReader] Unexpected error " + "from SQL database. The error was \"" + sqle.getMessage() + "\" ."); } finally { rs=null; statement=null; } } if (bMechLabel == null || bMechLabel.equalsIgnoreCase("")) { // Empty result means that the bmech object could not be found in the // relational database. This could be due to incorrectly specified // parameter for PID OR the object is not in the relational database. // If not in the relational database, attempt to find the object in the // Definitive storage area. try { if (definitiveDOReader == null) { definitiveDOReader = m_manager.getReader(Server.USE_DEFINITIVE_STORE, m_context, bMechPID); } bMechLabel = definitiveDOReader.GetObjectLabel(); isFoundInDefinitiveStore = true; LOG.debug("BMech found in definitive store: " + bMechPID); } catch (ServerException se) { throw se; } catch (Throwable th) { LOG.error("BMech found in definitive store: " + bMechPID, th); throw new GeneralException("[FastBmechReader] Definitive doReader " + "returned error. The underlying error was a \"" + th.getClass().getName() + "\" . The message " + "was \"" + th.getMessage() + "\" ."); } } else { isFoundInFastStore = true; LOG.debug("BMech found in fast store: " + bMechPID); } return bMechLabel; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy