edu.ucsb.adl.bucket99
Class GenericQueryMetadataSubdriver

java.lang.Object
  |
  +--edu.ucsb.adl.bucket99.GenericQueryMetadataSubdriver
All Implemented Interfaces:
MetadataSubdriver

public final class GenericQueryMetadataSubdriver
extends java.lang.Object
implements MetadataSubdriver

Metadata subdriver that generates ADL metadata reports by querying a database and inserting the returned values into a template.

This class reads the following properties from Bucket99 configuration files when creating a subdriver for property prefix V. Property values may be indirectly specified using the notation @P where P is the name of another property (see ExtendedProperties for more information).

V.name
The name of the view, e.g., "adl:access".
V.template
The filename of a report template. If the filename is not absolute, it is interpreted relative to the directory containing the Bucket99 configuration file.
V.queries
The names of zero or more queries to execute separated by commas, e.g., "MAIN,DATES,TYPES".
Q.query
For query Q, an SQL query of the form "select columns from table where holding_id = ?". The question mark ("?") will be replaced by a holding identifier.
Q.prefix
For query Q, the name the template uses to refer to the query, e.g., "main".
Q.columns
For query Q, the names the template uses to refer to the query's returned columns separated by commas, e.g., "foo,bar,baz". The names should be listed in the order in which they are returned by the query.
Q.num_rows_expected
For query Q, the number of rows the query is expected to return. Acceptable values are: "1", indicating exactly one row; "1?", indicating zero rows or one row; "1+", indicating one or more rows; and "0+", indicating zero or more rows.
metadata.identifier_datatype
The datatype of holding identifiers; must be "integer" or "string".
The contents of the template are included in the report verbatim with the exception of dollar-sign-delimited operators, which are interpreted and processed as follows.
$$
Literal dollar sign. Inserts "$". The XML/Unicode numeric encodings "$" and "$" can also be used.
$!V$
Variable insertion. Inserts the value of variable V. The currently supported variables are collection (the collection name, e.g., "adl_catalog"), holding (the holding identifier, e.g., "1001652"), and view (the view name, e.g, "adl:access").
$Q.C$
Value insertion. Inserts the value of column C from query Q. If this operator appears within a loop on Q (see below), the row that the value is drawn from is determined by the loop. Otherwise, Q must have returned exactly one row (if zero rows were returned, a BadRequestException is thrown; if more than one row was returned, an InternalErrorException is thrown). In any case, the value must not be null.
$[Q$ ... $]$
Query-based conditional inclusion. The block of text and operators between the $[Q$ and $]$ operators is included if query Q returned at least one row.
$[Q.C$ ... $]$
Column-based conditional inclusion. The block of text and operators between the $[Q.C$ and $]$ operators is included if the value of column C from query Q is non-null. If this operator appears within a loop on Q (see below), the row that the value is drawn from is determined by the loop. Otherwise, Q must have returned exactly one row (if zero rows were returned, a BadRequestException is thrown; if more than one row was returned, an InternalErrorException is thrown).
${Q$ ... $}$
Loop. The block of text and operators between the ${Q$ and $}$ operators is repeatedly included, once for each row returned by query Q. Value insertion and conditional inclusion operators within the scope of this operator that refer to columns of Q reference the rows returned by Q in the obvious way.

For example, consider source database tables

CREATE TABLE master (
    holding_id INTEGER NOT NULL,
    ...,
    PRIMARY KEY (holding_id)
);

CREATE TABLE image (
    holding_id INTEGER NOT NULL,
    filename VARCHAR(255) NOT NULL,
    width INTEGER,
    height INTEGER,
    FOREIGN KEY (holding_id) REFERENCES master
);
in which there is one row per holding in table master and zero or more rows per holding in table image, and in which width and height are either both null or both non-null. And consider a target XML document type
<!DOCTYPE sample-report [
    <!ELEMENT sample-report (identifier, image*)>
    <!ELEMENT identifier (#PCDATA)>
    <!ELEMENT image (filename, (width, height)?)>
    <!ELEMENT filename (#PCDATA)>
    <!ELEMENT width (#PCDATA)>
    <!ELEMENT height (#PCDATA)>
]>
Then, given the configuration (using "V" as the property name prefix):
V.name: sample-report
V.class: edu.ucsb.adl.bucket99.GenericQueryMetadataSubdriver
V.template: ...
V.queries: V-QUERY
V-QUERY.prefix: image
V-QUERY.query: SELECT filename, width, height FROM image WHERE holding_id = ?
V-QUERY.columns: filename,width,height
V-QUERY.num_rows_expected: 0+
the following template will generate an appropriate report:
<?xml version="1.0"?>
<!DOCTYPE sample-report SYSTEM "...">
<sample-report>
<identifier>$!collection$:$!holding$</identifier>
${image$<image>
<filename>$image.filename$</filename>
$[image.width$<width>$image.width$</width>
<height>$image.height$</height>
$]$</image>
$}$</sample-report>

Version:
$Header: /export/home/gjanee/bucket99/edu/ucsb/adl/bucket99/RCS/GenericQueryMetadataSubdriver.java,v 1.10 2004/09/23 17:08:09 gjanee Exp $

$Log: GenericQueryMetadataSubdriver.java,v $ Revision 1.10 2004/09/23 17:08:09 gjanee
Rewrite to use classes edu.ucsb.adl.middleware.ExtendedProperties and edu.ucsb.adl.middleware.XmlUtils.

Revision 1.9 2004/09/13 17:38:10 gjanee
Added the query-based conditional inclusion operator. Improved several error messages.

Revision 1.8 2004/03/17 21:35:19 gjanee
Added the variable insertion operator. Spiffed up the documentation a little.

Revision 1.7 2003/06/13 17:32:24 gjanee
Improved the error messages by adding the name of the view.

Revision 1.6 2003/06/12 04:46:09 gjanee
Added support for arbitrary, per-collection and per-holding metadata views. Specifically, the createSubdriver method is now passed a property name prefix. The subdriver-specific properties are now (for prefix P) P.template and P.queries.

Revision 1.5 2002/09/28 21:12:09 gjanee
Configuration file renames. Renamed the Bucket99 configuration file to bucket99.conf.

Revision 1.4 2001/11/16 06:22:12 gjanee
Internationalization support. We now use FileLoader.loadXMLFile to load the template.

Revision 1.3 2001/10/09 18:18:35 gjanee
Added support for relative filenames.

Revision 1.2 2001/08/24 03:40:34 gjanee
Added support for string holding identifiers. Added property metadata.identifier_datatype.

Revision 1.1 2000/08/05 23:29:12 gjanee
Initial revision

Author:
Greg Janée
Alexandria Digital Library

Method Summary
static edu.ucsb.adl.bucket99.GenericQueryMetadataSubdriver createSubdriver(edu.ucsb.adl.middleware.ExtendedProperties propertyList, java.lang.String prefix)
          Creates a GenericQueryMetadataSubdriver.
 void destroy()
          Frees all resources held by the subdriver.
 void disuseConnection()
          For use by MetadataDriver only.
 java.lang.String generateReport(java.lang.String view, java.lang.String collection, java.lang.String holding)
          Generates an ADL metadata report.
 void useConnection(java.sql.Connection connection)
          For use by MetadataDriver only.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Method Detail

createSubdriver

public static edu.ucsb.adl.bucket99.GenericQueryMetadataSubdriver createSubdriver(edu.ucsb.adl.middleware.ExtendedProperties propertyList,
                                                                                  java.lang.String prefix)
                                                                           throws InternalErrorException
Creates a GenericQueryMetadataSubdriver.

Parameters:
propertyList - The source for the above-mentioned properties.
prefix - The property name prefix corresponding to the metadata view the subdriver is to support, e.g., "ACCESS".
Returns:
A GenericQueryMetadataSubdriver.
Throws:
InternalErrorException - If any error occurs.

useConnection

public void useConnection(java.sql.Connection connection)
                   throws java.sql.SQLException
For use by MetadataDriver only.

Specified by:
useConnection in interface MetadataSubdriver
Parameters:
connection - The connection.
Throws:
java.sql.SQLException - If any error occurs.

disuseConnection

public void disuseConnection()
For use by MetadataDriver only.

Specified by:
disuseConnection in interface MetadataSubdriver

generateReport

public java.lang.String generateReport(java.lang.String view,
                                       java.lang.String collection,
                                       java.lang.String holding)
                                throws java.sql.SQLException,
                                       MiddlewareException
Generates an ADL metadata report.

Specified by:
generateReport in interface MetadataSubdriver
Parameters:
view - The metadata view, e.g., "adl:bucket".
collection - The collection name, e.g., "adl_catalog".
holding - The holding identifier.
Returns:
An XML document that is well-formed and valid according to the appropriate DTD.
Throws:
java.sql.SQLException - If a database-related error occurs.
BadRequestException - If holding is invalid.
InternalErrorException - If any other error occurs.
MiddlewareException

destroy

public void destroy()
Frees all resources held by the subdriver.

Specified by:
destroy in interface MetadataSubdriver