You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by cm...@apache.org on 2002/08/22 15:57:30 UTC
cvs commit: jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms StandardRDBMSAdapter.java RDBMSAdapter.java AbstractRDBMSAdapter.java
cmlenz 2002/08/22 06:57:30
Added: src/stores/org/apache/slide/store/impl/rdbms
StandardRDBMSAdapter.java RDBMSAdapter.java
AbstractRDBMSAdapter.java
Log:
Initial implementation of database delegate: based on interface
RDBMSAdapter which simply duplicates the methods from all the stores
and adds a java.sql.Connection argument. I know this isn't elegant, but
it was the most elegant while simple solution I could think of :P
Revision Changes Path
1.1 jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms/StandardRDBMSAdapter.java
Index: StandardRDBMSAdapter.java
===================================================================
/*
* $Header$
* $Revision$
* $Date$
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.store.impl.rdbms;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import org.apache.slide.common.Service;
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.Uri;
import org.apache.slide.content.NodeProperty;
import org.apache.slide.content.NodeRevisionContent;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionDescriptors;
import org.apache.slide.content.NodeRevisionNumber;
import org.apache.slide.content.RevisionAlreadyExistException;
import org.apache.slide.content.RevisionDescriptorNotFoundException;
import org.apache.slide.content.RevisionNotFoundException;
import org.apache.slide.lock.LockTokenNotFoundException;
import org.apache.slide.lock.NodeLock;
import org.apache.slide.security.NodePermission;
import org.apache.slide.structure.LinkNode;
import org.apache.slide.structure.ObjectAlreadyExistsException;
import org.apache.slide.structure.ObjectNode;
import org.apache.slide.structure.ObjectNotFoundException;
/**
*
*
* @author <a href="mailto:cmlenz@apache.org">Christopher Lenz</a>
* @version $Revision$
*/
public class StandardRDBMSAdapter
extends AbstractRDBMSAdapter {
// -------------------------------------------------------------- Constants
/**
* Buffer size used whe copying content streams.
*/
public static final int BUFFER_SIZE = 2048;
/**
* Size limit for the caches.
*/
private static final int CACHE_SIZE = 200;
// ----------------------------------------------------- Instance Variables
/**
* Hashtable used to cache the mapping between URI IDs and the actual URIs.
*/
private static Hashtable uriIdLookup =
new Hashtable(CACHE_SIZE);
/**
* Hashtable used to cache the mapping between URIs and their IDs.
*/
private static Hashtable uriLookup =
new Hashtable(CACHE_SIZE);
// this is used to share an object between multiple methods, it should be
// replaced with some internal helper methods
private NodeRevisionDescriptor myRevisionDescriptor = null;
// ----------------------------------------------------------- Constructors
/**
*
*/
public StandardRDBMSAdapter(Service service) {
super(service);
}
// -------------------------------------------- RDBMSAdapter Implementation
/**
*
*/
public ObjectNode retrieveObject(Connection conn, Uri uri)
throws ServiceAccessException, ObjectNotFoundException {
ObjectNode result = null;
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
stmt = conn.createStatement();
long uriId = getUriId(conn, uri.toString());
if (uriId == 0) {
throw new ObjectNotFoundException(uri);
}
// retrieve class name
String className;
sql.setLength(0);
sql.append("SELECT CLASS_NAME FROM OBJECT WHERE URI_ID = ")
.append(uriId);
ResultSet rs = stmt.executeQuery(sql.toString());
if (rs.next()) {
className = rs.getString("CLASS_NAME");
} else {
throw new ObjectNotFoundException(uri);
}
// retrieve the children
Vector children = new Vector();
sql.setLength(0);
sql.append("SELECT A.URI_STRING FROM URI A, CHILDREN B ")
.append("WHERE A.URI_ID = B.CHILD_URI_ID ")
.append("AND B.URI_ID = ").append(uriId);
rs = stmt.executeQuery(sql.toString());
while (rs.next()) {
children.addElement(rs.getString("URI_STRING"));
}
// retrieve the inbound links
Vector links = new Vector();
sql.setLength(0);
sql.append("SELECT A.URI_STRING FROM URI A, LINKS B ")
.append("WHERE A.URI_ID = B.URI_ID ")
.append("AND B.LINK_TO_ID = ").append(uriId);
rs = stmt.executeQuery(sql.toString());
while (rs.next()) {
links.addElement(rs.getString("URI_STRING"));
}
// if the node is a link, retrieve the link target and instantiate
// the LinkNode
if (className.equals("org.apache.slide.structure.LinkNode")) {
String linkTarget = null;
sql.setLength(0);
sql.append("SELECT A.URI_STRING FROM URI A, LINKS B ")
.append("WHERE A.URI_ID = B.LINK_TO_ID ")
.append("AND B.URI_ID = ").append(uriId);
rs = stmt.executeQuery(sql.toString());
if (rs.next()) {
linkTarget = rs.getString("URI_STRING");
}
result = new LinkNode(uri.toString(), children, links,
linkTarget);
} else {
try {
Class objClass = Class.forName(className);
Class[] argClasses =
{ String.class, Vector.class, Vector.class };
Object[] arguments = { uri.toString(), children, links };
Constructor constructor =
objClass.getConstructor(argClasses);
result = (ObjectNode)constructor.newInstance(arguments);
} catch(Exception e) {
// introspection exceptions
throw new ServiceAccessException(service, e);
}
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
}
}
return result;
}
/**
*
*/
public void storeObject(Connection conn, Uri uri, ObjectNode object)
throws ServiceAccessException, ObjectNotFoundException {
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
stmt = conn.createStatement();
long uriId = getUriId(conn, uri.toString());
sql.setLength(0);
sql.append("SELECT CLASS_NAME FROM OBJECT WHERE URI_ID = ");
sql.append(uriId);
ResultSet rs = stmt.executeQuery(sql.toString());
if (!rs.next()) {
throw new ObjectNotFoundException(uri);
}
// TODO: check the class name?
// store the children
long parent = getUriId(conn, object.getUri());
// TODO: why not use the already calculated uriId ?
Enumeration children =
getNewChildren(conn, parent,object.enumerateChildren());
if (children != null) {
while (children.hasMoreElements()) {
sql.setLength(0);
sql.append("INSERT INTO CHILDREN (URI_ID,CHILD_URI_ID) ")
.append("VALUES (").append(parent).append(", ")
.append(getUriId(conn, (String)children.nextElement()))
.append(")");
stmt.executeUpdate(sql.toString());
}
}
// Updating link
// [not implemented]
// store the link target
if (object instanceof LinkNode) {
long linkTargetId =
getUriId(conn, ((LinkNode)object).getLinkedUri());
if (!isLinkExist(conn, parent, linkTargetId)) {
sql.setLength(0);
sql.append("INSERT INTO LINKS (URI_ID, LINK_TO_ID) ")
.append("VALUES (").append(parent).append(", ")
.append(linkTargetId).append(")");
stmt.executeUpdate(sql.toString());
}
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
}
}
}
/**
*
*/
public void createObject(Connection conn, Uri uri, ObjectNode object)
throws ServiceAccessException, ObjectAlreadyExistsException {
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
stmt = conn.createStatement();
setUriId(conn, uri.toString());
long uriId = getUriId(conn, uri.toString());
sql.setLength(0);
sql.append("SELECT CLASS_NAME FROM OBJECT WHERE URI_ID = ")
.append(uriId);
ResultSet rs = stmt.executeQuery(sql.toString());
if (rs.next()) {
throw new ObjectAlreadyExistsException(uri.toString());
}
// store the class name
sql.setLength(0);
sql.append("INSERT INTO OBJECT (URI_ID,CLASS_NAME) ")
.append("VALUES (").append(uriId).append(", '")
.append(object.getClass().getName()).append("')");
stmt.executeUpdate(sql.toString());
// store children
Enumeration children =
getNewChildren(conn, uriId, object.enumerateChildren());
if (children != null) {
while (children.hasMoreElements()) {
sql.setLength(0);
sql.append("INSERT INTO CHILDREN (URI_ID,CHILD_URI_ID) ")
.append("VALUES (").append(uriId).append(", ")
.append(getUriId(conn, (String)children.nextElement()))
.append(" )");
stmt.executeUpdate(sql.toString());
}
}
// if the object is a link, also store the link information
if (object instanceof LinkNode) {
long linkTargetId = getUriId(conn, ((LinkNode)object).getLinkedUri());
if (!isLinkExist(conn, uriId, linkTargetId)) {
sql.setLength(0);
sql.append("INSERT INTO LINKS (URI_ID, LINK_TO_ID) ")
.append("VALUES (").append(uriId).append(", ")
.append(linkTargetId).append(")");
stmt.executeUpdate(sql.toString());
}
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
}
}
}
/**
*
*/
public void removeObject(Connection conn, Uri uri, ObjectNode object)
throws ServiceAccessException, ObjectNotFoundException {
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
stmt = conn.createStatement();
long uriId = getUriId(conn, object.getUri());
if (uriId == 0) {
throw new ObjectNotFoundException(uri);
}
// remove related child associations
sql.setLength(0);
sql.append("DELETE FROM CHILDREN WHERE URI_ID = ")
.append(uriId).append(" OR CHILD_URI_ID = ").append(uriId);
stmt.executeUpdate(sql.toString());
// delete link target and/or inbound links
sql.setLength(0);
sql.append("DELETE FROM LINKS WHERE URI_ID = ").append(uriId);
stmt.executeUpdate(sql.toString());
// delete the object itself
sql.setLength(0);
sql.append("DELETE FROM OBJECT WHERE URI_ID = ").append(uriId);
stmt.executeUpdate(sql.toString());
// delete the URI
removeUri(conn, object.getUri());
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
}
}
}
/**
*
*/
public void grantPermission
(Connection conn, Uri uri, NodePermission permission)
throws ServiceAccessException {
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
stmt = conn.createStatement();
setUriId(conn, permission.getObjectUri());
setUriId(conn, permission.getSubjectUri());
setUriId(conn, permission.getActionUri());
long objectId = getUriId(conn, permission.getObjectUri());
long subjectId = getUriId(conn, permission.getSubjectUri());
long actionId = getUriId(conn, permission.getActionUri());
sql.setLength(0);
sql.append("SELECT 1 FROM PERMISSIONS ")
.append("WHERE OBJECT_ID = ").append(objectId)
.append(" AND SUBJECT_ID = ").append(subjectId)
.append(" AND ACTION_ID = " ).append(actionId);
ResultSet rs = stmt.executeQuery(sql.toString());
if (!rs.next()) {
NodeRevisionNumber nrn = permission.getRevisionNumber();
sql.setLength(0);
sql.append("INSERT INTO PERMISSIONS ")
.append("(OBJECT_ID, SUBJECT_ID, ACTION_ID, VERSION_NO, ")
.append("IS_INHERITABLE, IS_NEGATIVE) VALUES (")
.append(objectId).append(", ").append(subjectId)
.append(", ").append(actionId)
.append(", ").append((nrn == null) ? "NULL" : nrn.toString())
.append(", ").append(permission.isInheritable())
.append(", ").append(permission.isNegative())
.append(")");
stmt.executeUpdate(sql.toString());
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
}
}
}
/**
*
*/
public void revokePermission
(Connection conn, Uri uri, NodePermission permission)
throws ServiceAccessException {
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
stmt = conn.createStatement();
NodeRevisionNumber nrn = permission.getRevisionNumber();
sql.setLength(0);
sql.append("DELETE FROM PERMISSIONS ")
.append("WHERE OBJECT_ID = ")
.append(getUriId(conn, permission.getObjectUri()))
.append(" AND SUBJECT_ID = ")
.append(getUriId(conn, permission.getSubjectUri()))
.append(" AND ACTION_ID = ")
.append(getUriId(conn, permission.getActionUri()))
.append(" AND VERSION_NO ")
.append((nrn != null) ? "= '" + nrn + "'" : "IS NULL");
stmt.executeUpdate(sql.toString());
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
}
}
}
/**
*
*/
public void revokePermissions(Connection conn, Uri uri)
throws ServiceAccessException {
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
stmt = conn.createStatement();
sql.setLength(0);
sql.append("DELETE FROM PERMISSIONS WHERE OBJECT_ID = ")
.append(getUriId(conn, uri.toString()));
stmt.executeUpdate(sql.toString());
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
}
}
}
/**
*
*/
public Enumeration enumeratePermissions(Connection conn, Uri uri)
throws ServiceAccessException {
Vector result = new Vector();
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
stmt = conn.createStatement();
sql.setLength(0);
sql.append("SELECT * FROM PERMISSIONS ")
.append("WHERE OBJECT_ID = ")
.append(getUriId(conn, uri.toString()));
ResultSet rs = stmt.executeQuery(sql.toString());
while (rs.next()) {
String subject = getUri(conn, rs.getLong("SUBJECT_ID"));
String action = getUri(conn, rs.getLong("ACTION_ID"));
String revision = rs.getString("VERSION_NO");
boolean inheritable = rs.getBoolean("IS_INHERITABLE");
boolean negative = rs.getBoolean("IS_NEGATIVE");
NodePermission permission =
new NodePermission(uri.toString(), revision, subject,
action, inheritable, negative);
result.addElement(permission);
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
}
}
return result.elements();
}
/**
*
*/
public void putLock(Connection conn, Uri uri, NodeLock lock)
throws ServiceAccessException {
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
stmt = conn.createStatement();
long lockId = getUriId(conn, lock.getLockId());
if (lockId == 0 ) {
setUriId(conn, lock.getLockId());
lockId = getUriId(conn, lock.getLockId());
}
sql.setLength(0);
sql.append("INSERT INTO LOCKS (LOCK_ID, OBJECT_ID, SUBJECT_ID, ")
.append("TYPE_ID, EXPIRATION_DATE, IS_INHERITABLE, ")
.append("IS_EXCLUSIVE) VALUES (").append(lockId).append(", ")
.append(getUriId(conn, lock.getObjectUri())).append(", ")
.append(getUriId(conn, lock.getSubjectUri())).append(", ")
.append(getUriId(conn, lock.getTypeUri())).append(", ")
.append(lock.getExpirationDate().getTime()).append(", ")
.append(lock.isInheritable()).append(", ")
.append(lock.isExclusive()).append(")");
stmt.executeUpdate(sql.toString());
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
}
}
}
/**
*
*/
public void renewLock(Connection conn, Uri uri, NodeLock lock)
throws ServiceAccessException, LockTokenNotFoundException {
try {
if (!isLockExist(conn, getUriId(conn, lock.getLockId()))) {
putLock(conn, uri, lock);
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
}
}
/**
*
*/
public void removeLock(Connection conn, Uri uri, NodeLock lock)
throws ServiceAccessException, LockTokenNotFoundException {
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
stmt = conn.createStatement();
long lockId = getUriId(conn, lock.getLockId());
sql.setLength(0);
sql.append("DELETE FROM LOCKS WHERE LOCK_ID = ")
.append(lockId);
stmt.executeUpdate(sql.toString());
removeUri(conn, lock.getLockId());
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
}
}
}
/**
*
*/
public void killLock(Connection conn, Uri uri, NodeLock lock)
throws ServiceAccessException, LockTokenNotFoundException {
removeLock(conn, uri, lock);
}
/**
*
*/
public Enumeration enumerateLocks(Connection conn, Uri uri)
throws ServiceAccessException {
Vector result = new Vector();
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
stmt = conn.createStatement();
sql.setLength(0);
sql.append("SELECT * FROM LOCKS WHERE OBJECT_ID = ")
.append(getUriId(conn, uri.toString()));
ResultSet rs = stmt.executeQuery(sql.toString());
while (rs.next()) {
Date expirationDate = null;
try {
long timeValue = rs.getLong("EXPIRATION_DATE");
expirationDate = new Date(timeValue);
} catch (NumberFormatException e) {
expirationDate = new Date();
}
NodeLock lock =
new NodeLock(getUri(conn, rs.getLong("LOCK_ID")),
getUri(conn, rs.getLong("OBJECT_ID")),
getUri(conn, rs.getLong("SUBJECT_ID")),
getUri(conn, rs.getLong("TYPE_ID")),
expirationDate,
rs.getBoolean("IS_INHERITABLE"),
rs.getBoolean("IS_EXCLUSIVE"));
result.addElement(lock);
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
try {
stmt.close();
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
}
}
return result.elements();
}
/**
*
*/
public NodeRevisionDescriptors retrieveRevisionDescriptors
(Connection conn, Uri uri)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
NodeRevisionDescriptors result = null;
Statement stmt = null;
Statement stmt2 = null;
try {
StringBuffer sql = new StringBuffer();
ResultSet rs = null;
stmt = conn.createStatement();
stmt2 = conn.createStatement();
long uriId = getUriId(conn, uri.toString());
// find out whether the node is versioned
boolean isVersioned = false;
sql.setLength(0);
sql.append("SELECT IS_VERSIONED FROM VERSION ")
.append("WHERE URI_ID = ").append(uriId);
rs = stmt.executeQuery(sql.toString());
if (rs.next()) {
isVersioned = rs.getBoolean("IS_VERSIONED");
} else {
throw new RevisionDescriptorNotFoundException(uri.toString());
}
Hashtable branches = new Hashtable();
Hashtable latestRevisionNumbers = new Hashtable();
Hashtable workingRevisions = new Hashtable();
sql.setLength(0);
sql.append("SELECT A.VERSION_ID, A.REVISION_NO, B.BRANCH_STRING ")
.append("FROM VERSION_HISTORY A, BRANCH B ")
.append("WHERE A.URI_ID = ").append(uriId)
.append(" AND A.BRANCH_ID = B.BRANCH_ID");
rs = stmt.executeQuery(sql.toString());
while (rs.next()) {
String branch = rs.getString("BRANCH_STRING");
long versionId = rs.getLong("VERSION_ID");
NodeRevisionNumber nrn =
new NodeRevisionNumber(rs.getString("REVISION_NO"));
// We parse the revision list of the object
sql.setLength(0);
sql.append("SELECT PREDECESSOR_ID FROM VERSION_PREDS ")
.append("WHERE VERSION_ID = ").append(versionId);
ResultSet rs2 = stmt2.executeQuery(sql.toString());
Vector predecessors = new Vector();
while (rs2.next()) {
predecessors.addElement(
new NodeRevisionNumber(
getRevisionNumber(conn,
rs2.getLong("PREDECESSOR_ID"),
uriId, branch)));
}
branches.put(nrn, predecessors);
rs2.close();
}
result = new NodeRevisionDescriptors(uri.toString(),
new NodeRevisionNumber(),
workingRevisions,
latestRevisionNumbers,
branches, isVersioned);
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
try {
if (stmt != null) {
stmt.close();
}
if (stmt2 != null) {
stmt2.close();
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
}
}
return result;
}
/**
*
*/
public void createRevisionDescriptors
(Connection conn, Uri uri, NodeRevisionDescriptors revisionDescriptors)
throws ServiceAccessException {
// TODO : Here, we have the option of "cleaning up" before
// creating the new records in the database.
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
ResultSet rs = null;
stmt = conn.createStatement();
long uriId = getUriId(conn, uri.toString());
// Creating record in revisions tables
sql.setLength(0);
sql.append("SELECT 1 FROM VERSION WHERE URI_ID = ").append(uriId);
rs = stmt.executeQuery(sql.toString());
if (!rs.next()) {
sql.setLength(0);
sql.append("INSERT INTO VERSION (URI_ID, IS_VERSIONED) ")
.append("VALUES (").append(uriId).append(", ")
.append(revisionDescriptors.isVersioned()).append(")");
stmt.execute(sql.toString());
}
// for now, only the latest revision from the main branch is stored
long branchId =
getBranchId(conn, NodeRevisionDescriptors.MAIN_BRANCH);
NodeRevisionNumber nrn =
revisionDescriptors.getLatestRevision();
sql.setLength(0);
sql.append("SELECT 1 FROM VERSION_HISTORY ")
.append("WHERE URI_ID = ").append(uriId)
.append(" AND BRANCH_ID = ").append(branchId)
.append(" AND REVISION_NO ")
.append((nrn != null) ? ("= '" + nrn + "'") : " IS NULL");
rs = stmt.executeQuery(sql.toString());
if (!rs.next() && (nrn != null)) {
sql.setLength(0);
sql.append("INSERT INTO VERSION_HISTORY ")
.append("(URI_ID, BRANCH_ID, REVISION_NO) ")
.append("VALUES (").append(uriId).append(", ")
.append(branchId).append(", '").append(nrn).append("')");
stmt.execute(sql.toString());
}
// Creating records in the branches table
// TODO Retained from the old Slide Schema
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
}
}
}
/**
*
*/
public void storeRevisionDescriptors
(Connection conn, Uri uri, NodeRevisionDescriptors revisionDescriptors)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
removeRevisionDescriptors(conn, uri);
createRevisionDescriptors(conn, uri, revisionDescriptors);
}
/**
*
*/
public void removeRevisionDescriptors(Connection conn, Uri uri)
throws ServiceAccessException {
Statement stmt = null;
Statement stmt2 = null;
try {
StringBuffer sql = new StringBuffer();
ResultSet rs = null;
stmt = conn.createStatement();
long uriId = getUriId(conn, uri.toString());
sql.setLength(0);
sql.append("SELECT VERSION_ID FROM VERSION_HISTORY ")
.append("WHERE URI_ID = ").append(uriId);
rs = stmt.executeQuery(sql.toString());
stmt2 = conn.createStatement();
if (rs.next()) {
sql.setLength(0);
sql.append("DELETE FROM VERSION_PREDS WHERE VERSION_ID = ")
.append(rs.getLong("VERSION_ID"));
stmt2.execute(sql.toString());
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
try {
if (stmt != null) {
stmt.close();
}
if (stmt2 != null) {
stmt2.close();
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
}
}
}
/**
*
*/
public NodeRevisionDescriptor retrieveRevisionDescriptor
(Connection conn, Uri uri, NodeRevisionNumber nrn)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
if (nrn == null) {
// TODO: should throw a NullPointerException
throw new RevisionDescriptorNotFoundException(uri.toString());
}
NodeRevisionDescriptor result = null;
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
ResultSet rs = null;
stmt = conn.createStatement();
long uriId = getUriId(conn, uri.toString());
// retrieve branch name and version ID
String branchName = null;
long versionId = 0;
sql.setLength(0);
sql.append("SELECT A.VERSION_ID, B.BRANCH_STRING ")
.append("FROM VERSION_HISTORY A, BRANCH B ")
.append("WHERE A.URI_ID = ").append(uriId)
.append(" AND A.REVISION_NO = '").append(nrn.toString());
sql.append("' AND B.BRANCH_ID = A.BRANCH_ID");
rs = stmt.executeQuery(sql.toString());
if (rs.next()) {
branchName = rs.getString("BRANCH_STRING");
versionId = rs.getLong("VERSION_ID");
} else {
throw new RevisionDescriptorNotFoundException(uri.toString());
}
// retrieve labels
Vector labels = new Vector();
sql.setLength(0);
sql.append("SELECT LABEL_ID FROM VERSION_LABELS ")
.append("WHERE VERSION_ID = ").append(versionId);
rs = stmt.executeQuery(sql.toString());
while (rs.next()) {
labels.addElement(getLabelName(conn, rs.getLong("LABEL_ID")));
}
// Retrieve properties
Hashtable properties = new Hashtable();
sql.setLength(0);
sql.append("SELECT * FROM PROPERTIES WHERE VERSION_ID = ")
.append(versionId);
rs = stmt.executeQuery(sql.toString());
while (rs.next()) {
String propertyName = rs.getString("PROPERTY_NAME");
String propertyNamespace = rs.getString("PROPERTY_NAMESPACE");
NodeProperty property =
new NodeProperty(propertyName,
rs.getString("PROPERTY_VALUE"),
propertyNamespace,
rs.getString("PROPERTY_TYPE"),
rs.getBoolean("IS_PROTECTED"));
properties.put(propertyNamespace + propertyName, property);
}
result = new NodeRevisionDescriptor(nrn, branchName, labels,
properties);
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
}
}
return result;
}
/**
*
*/
public void createRevisionDescriptor
(Connection conn, Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException {
Statement stmt = null;
PreparedStatement pstmt = null;
try {
StringBuffer sql = new StringBuffer();
ResultSet rs = null;
stmt = conn.createStatement();
long uriId = getUriId(conn, uri.toString());
long branchId =
getBranchId(conn, revisionDescriptor.getBranchName());
if (branchId == 0) {
setBranchId(conn, revisionDescriptor.getBranchName());
branchId =
getBranchId(conn, revisionDescriptor.getBranchName());
}
// TODO: this automatically creates the corresponding
// NodeRevisionDescriptors if they do not exist...
// is that intended?
sql.setLength(0);
sql.append("SELECT 1 FROM VERSION WHERE URI_ID = ")
.append(uriId);
rs = stmt.executeQuery(sql.toString());
if (!rs.next()) {
sql.setLength(0);
sql.append("INSERT INTO VERSION (URI_ID, IS_VERSIONED) ")
.append("VALUES (").append(uriId).append(", ").append(0)
.append(")");
stmt.execute(sql.toString());
}
sql.setLength(0);
sql.append("SELECT 1 FROM VERSION_HISTORY WHERE URI_ID = ")
.append(uriId).append(" AND BRANCH_ID = ")
.append(branchId).append(" AND REVISION_NO = '" )
.append(revisionDescriptor.getRevisionNumber().toString())
.append("'");
rs = stmt.executeQuery(sql.toString());
if (!rs.next()) {
sql.setLength(0);
sql.append("INSERT INTO VERSION_HISTORY (URI_ID, BRANCH_ID, ")
.append("REVISION_NO) VALUES (")
.append(uriId).append(", ").append(branchId).append(", '")
.append(revisionDescriptor.getRevisionNumber().toString())
.append("')");
stmt.execute(sql.toString());
}
long versionId =
getRevisionId(conn, uriId, revisionDescriptor.getBranchName(),
revisionDescriptor.getRevisionNumber());
// create revision labels
Enumeration labels = revisionDescriptor.enumerateLabels();
while (labels.hasMoreElements()) {
String label =(String)labels.nextElement();
long labelId = getLabelId(conn, label);
if (labelId == 0) {
setLabelId(conn, label);
labelId = getLabelId(conn, label);
}
sql.setLength(0);
sql.append("INSERT INTO VERSION_LABELS (VERSION_ID,LABEL_ID) ")
.append("VALUES (").append(versionId).append(", ")
.append(labelId).append(")");
stmt.execute(sql.toString());
}
// create associated properties
Enumeration properties = revisionDescriptor.enumerateProperties();
sql.setLength(0);
sql.append("INSERT INTO PROPERTIES (VERSION_ID, ")
.append("PROPERTY_NAMESPACE, PROPERTY_NAME, PROPERTY_VALUE, ")
.append("PROPERTY_TYPE, IS_PROTECTED) ")
.append("VALUES (?, ?, ?, ?, ?, ?)");
pstmt = conn.prepareStatement(sql.toString());
while (properties.hasMoreElements()) {
NodeProperty property = (NodeProperty)properties.nextElement();
pstmt.setLong(1, versionId);
pstmt.setString(2, property.getNamespace());
pstmt.setString(3, property.getName());
pstmt.setString(4, property.getValue().toString());
pstmt.setString(5, property.getType());
pstmt.setBoolean(6, property.isProtected());
pstmt.execute();
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
try {
if (stmt != null) {
stmt.close();
}
if (pstmt != null) {
pstmt.close();
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
}
}
}
/**
*
*/
public void storeRevisionDescriptor
(Connection conn, Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
myRevisionDescriptor = revisionDescriptor;
removeRevisionDescriptor(conn, uri,
revisionDescriptor.getRevisionNumber());
createRevisionDescriptor(conn, uri, revisionDescriptor);
}
/**
*
*/
public void removeRevisionDescriptor
(Connection conn, Uri uri, NodeRevisionNumber nrn)
throws ServiceAccessException {
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
stmt = conn.createStatement();
long uriId = getUriId(conn, uri.toString());
String branchStr = null;
if (myRevisionDescriptor != null) {
branchStr = myRevisionDescriptor.getBranchName();
} else {
branchStr = "main";
}
long versionId = getRevisionId(conn, uriId, branchStr, nrn);
// remove revision labels
sql.setLength(0);
sql.append("DELETE FROM VERSION_LABELS WHERE VERSION_ID = ");
sql.append(versionId);
stmt.execute(sql.toString());
// remove associated properties
sql.setLength(0);
sql.append("DELETE FROM PROPERTIES WHERE VERSION_ID = ");
sql.append(versionId);
stmt.execute(sql.toString());
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
} finally {
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
}
}
}
/**
*
*/
public NodeRevisionContent retrieveRevisionContent
(Connection conn, Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException, RevisionNotFoundException {
NodeRevisionContent result = null;
NodeRevisionNumber nrn = revisionDescriptor.getRevisionNumber();
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
stmt = conn.createStatement();
long versionId = getRevisionId(conn, getUriId(conn, uri.toString()),
revisionDescriptor.getBranchName(),
nrn);
sql.setLength(0);
sql.append("SELECT CONTENT FROM VERSION_CONTENT ")
.append("WHERE VERSION_ID = ").append(versionId);
ResultSet rs = stmt.executeQuery(sql.toString());
if (!rs.next()) {
throw new RevisionNotFoundException
(uri.toString(),
revisionDescriptor.getRevisionNumber());
}
InputStream in = rs.getBinaryStream("CONTENT");
if (in == null) {
throw new RevisionNotFoundException
(uri.toString(),
revisionDescriptor.getRevisionNumber());
}
// Uncompress the retrieved data.
result = new NodeRevisionContent();
StoreContentZip zip = new StoreContentZip();
zip.UnZip(in);
revisionDescriptor.setContentLength(zip.getContentLength());
in = zip.getInputStream();
result.setContent(in);
// this input stream passes on the closure of itself onto the
// jdbc stmt and resultSet
result.setContent(new JDBCAwareInputStream(in, stmt));
} catch (SQLException e) {
throw new ServiceAccessException(service, e.getMessage());
} catch (RevisionNotFoundException e) {
throw e; // we do NOT want this caught by next clause.
} catch (Exception e) {
throw new ServiceAccessException(service, e.getMessage());
} finally {
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
}
}
return result;
}
/**
*
*/
public void createRevisionContent
(Connection conn, Uri uri, NodeRevisionDescriptor revisionDescriptor,
NodeRevisionContent revisionContent)
throws ServiceAccessException, RevisionAlreadyExistException {
String revisionUri = uri.toString();
NodeRevisionNumber nrn = revisionDescriptor.getRevisionNumber();
long contentLength = revisionDescriptor.getContentLength();
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
stmt = conn.createStatement();
long versionId = getRevisionId(conn, getUriId(conn, revisionUri),
revisionDescriptor.getBranchName(),
nrn);
sql.setLength(0);
sql.append("SELECT 1 FROM VERSION_CONTENT ")
.append("WHERE VERSION_ID = ").append(versionId);
ResultSet rs = stmt.executeQuery(sql.toString());
if (rs.next()) {
throw new RevisionAlreadyExistException
(uri.toString(),
revisionDescriptor.getRevisionNumber());
}
storeContent(conn, revisionUri, nrn.toString(), revisionDescriptor,
revisionContent);
} catch (SQLException e) {
throw new ServiceAccessException(service, e.getMessage());
} catch (IOException e) {
throw new ServiceAccessException(service, e.getMessage());
} catch(RevisionAlreadyExistException e) {
throw e;
} catch (Exception e) {
throw new ServiceAccessException(service, e.getMessage());
} finally {
try {
stmt.close();
} catch (SQLException e) {
throw new ServiceAccessException(service, e);
}
}
}
/**
*
*/
public void storeRevisionContent
(Connection conn, Uri uri, NodeRevisionDescriptor revisionDescriptor,
NodeRevisionContent revisionContent)
throws ServiceAccessException, RevisionNotFoundException {
String revisionUri = uri.toString();
NodeRevisionNumber nrn = revisionDescriptor.getRevisionNumber();
Statement stmt = null;
try {
long versionId = getRevisionId(conn, getUriId(conn, revisionUri),
revisionDescriptor.getBranchName(),
nrn);
stmt = conn.createStatement();
StringBuffer sql = new StringBuffer
("select 1 from VERSION_CONTENT where VERSION_ID = ");
sql.append(versionId);
ResultSet rs = stmt.executeQuery(sql.toString());
if (!rs.next()) {
throw new RevisionNotFoundException
(uri.toString(),
revisionDescriptor.getRevisionNumber());
}
removeRevisionContent(conn, uri, revisionDescriptor);
storeContent(conn, revisionUri, nrn.toString(), revisionDescriptor,
revisionContent);
} catch (SQLException e) {
throw new ServiceAccessException(service, e.getMessage());
} catch (IOException e) {
throw new ServiceAccessException(service, e.getMessage());
} catch(RevisionNotFoundException e) {
throw e;
} catch (Exception e) {
throw new ServiceAccessException(service, e.getMessage());
} finally {
try {
stmt.close();
} catch (SQLException e) { }
}
}
/**
*
*/
public void removeRevisionContent
(Connection conn, Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException {
try {
long versionId =
getRevisionId(conn, getUriId(conn, uri.toString()),
revisionDescriptor.getBranchName(),
revisionDescriptor.getRevisionNumber());
removeContent(conn, versionId);
} catch (Exception e) {
throw new ServiceAccessException(service, e.getMessage());
}
}
// ------------------------------------------------------ Protected Methods
/**
* Returns the URI ID corresponding to an URI.
*/
protected long getUriId(Connection conn, String uri)
throws SQLException {
Statement stmt = null;
try {
Long uriIdLong = (Long)uriIdLookup.get(uri);
if (uriIdLong == null) {
StringBuffer sql = new StringBuffer()
.append("SELECT URI_ID FROM URI WHERE URI_STRING = '")
.append(uri).append("'");
stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql.toString());
if (rs.next()) {
long uriId = rs.getLong("URI_ID");
if (uriIdLookup.size() == CACHE_SIZE) {
uriIdLookup.clear();
uriLookup.clear();
}
uriIdLong = new Long(uriId);
uriIdLookup.put(uri, uriIdLong);
uriLookup.put(uriIdLong, uri);
}
}
return (uriIdLong != null) ? uriIdLong.longValue() : 0;
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqle) { }
}
}
}
/**
* Retrieve the URI Name.
*/
protected String getUri(Connection conn, long uriId)
throws SQLException {
Statement stmt = null;
try {
Long uriIdLong = new Long(uriId);
String uri = (String)uriLookup.get(uriIdLong);
if (uri == null) {
StringBuffer sql = new StringBuffer()
.append("SELECT URI_STRING FROM URI WHERE URI_ID = ")
.append(uriId);
stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql.toString());
if (rs.next()) {
uri = rs.getString("URI_STRING");
if (uriLookup.size() == CACHE_SIZE) {
uriLookup.clear();
uriIdLookup.clear();
}
uriLookup.put(uriIdLong, uri);
uriIdLookup.put(uri, uriIdLong);
}
}
return uri;
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqle) { }
}
}
}
/**
* Adds the URI into the URI ID table.
*/
protected void setUriId(Connection conn, String uri)
throws SQLException {
Statement stmt = null;
try {
if (getUriId(conn, uri) == 0) {
StringBuffer sql = new StringBuffer()
.append("INSERT INTO URI (URI_STRING) VALUES ('")
.append(uri).append("')");
stmt = conn.createStatement();
stmt.executeUpdate(sql.toString());
}
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqle) { }
}
}
}
/**
*
*/
protected void removeUri(Connection conn, String uri)
throws SQLException {
Statement stmt = null;
try {
long uriId = getUriId(conn, uri);
if (uriId != 0) {
StringBuffer sql = new StringBuffer()
.append("DELETE FROM URI WHERE URI_ID = ").append(uriId);
stmt = conn.createStatement();
stmt.executeUpdate(sql.toString());
uriIdLookup.remove(uri);
uriLookup.remove(new Long(uriId));
}
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqle) { }
}
}
}
/**
* Retrieve the Branch ID For the given Branch.
*/
protected long getBranchId(Connection conn, String branchName)
throws SQLException {
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
sql.append("SELECT BRANCH_ID FROM BRANCH ")
.append("WHERE BRANCH_STRING = '").append(branchName)
.append("'");
stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql.toString());
if (rs.next()) {
return rs.getLong("BRANCH_ID");
} else {
return 0;
}
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqle) { }
}
}
}
/**
* Add the branchname and id
*/
protected void setBranchId(Connection conn, String branchName)
throws SQLException {
Statement stmt = null;
try {
if (getBranchId(conn, branchName) == 0 ) {
StringBuffer sql = new StringBuffer();
sql.append("INSERT INTO BRANCH (BRANCH_STRING) ")
.append("VALUES ('").append(branchName).append("')");
stmt = conn.createStatement();
stmt.execute(sql.toString());
}
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqle) { }
}
}
}
/**
* Retrieve the label ID For the labelName.
*/
protected long getLabelId(Connection conn, String label)
throws SQLException {
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
sql.append("SELECT LABEL_ID FROM LABEL ")
.append("WHERE LABEL_STRING = '").append(label).append("'");
stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql.toString());
if (rs.next()) {
return rs.getLong("LABEL_ID");
} else {
return 0;
}
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqle) { }
}
}
}
/**
* Retrieve the label name for the corresponding ID.
*/
protected String getLabelName(Connection conn, long labelID)
throws SQLException {
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
sql.append("SELECT LABEL_STRING FROM LABEL ")
.append("WHERE LABEL_ID = ").append(labelID);
stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql.toString());
if (rs.next()) {
return rs.getString("LABEL_STRING");
} else {
return null;
}
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqle) { }
}
}
}
/**
* Add the labelName and id
*/
protected void setLabelId(Connection conn, String labelName)
throws SQLException {
Statement stmt = null;
try {
if (getBranchId(conn, labelName) == 0) {
StringBuffer sql = new StringBuffer();
sql.append("INSERT INTO LABEL (LABEL_STRING) ")
.append("VALUES ('").append(labelName).append("')");
stmt = conn.createStatement();
stmt.executeUpdate(sql.toString());
}
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqle) { }
}
}
}
/**
* Filter for all the new children
*/
protected Enumeration getNewChildren
(Connection conn, long parent, Enumeration childlist)
throws SQLException {
Hashtable hshtempHash = new Hashtable();
Hashtable hshnewChild = new Hashtable();
Statement getStatement = conn.createStatement();
StringBuffer sql = new StringBuffer
("select A.URI_STRING FROM URI A, CHILDREN B WHERE A.URI_ID = ");
sql.append("B.CHILD_URI_ID AND B.URI_ID = ");
sql.append(parent);
ResultSet rslt = getStatement.executeQuery(sql.toString());
String s_child = null;
while (rslt.next()) {
s_child = rslt.getString("URI_STRING");
hshtempHash.put(s_child,s_child);
}
rslt.close();
while (childlist.hasMoreElements()) {
String temp_child = (String)childlist.nextElement();
if (hshtempHash.containsKey(temp_child)) {
} else {
hshnewChild.put(temp_child,temp_child);
}
}
hshtempHash.clear();
return hshnewChild.elements();
}
/**
* Check if the Link exist.
*/
protected boolean isLinkExist(Connection conn, long parent, long child)
throws SQLException {
Statement getStatement = conn.createStatement();
StringBuffer sql = new StringBuffer
("select 1 from LINKS where URI_ID = " );
sql.append(parent).append(" and LINK_TO_ID = ").append(child);
ResultSet rslt = getStatement.executeQuery(sql.toString());
return rslt.next();
}
/**
* Check if the Lock exist.
*/
protected boolean isLockExist(Connection conn, long parent)
throws SQLException {
Statement getStatement = conn.createStatement();
StringBuffer sql = new StringBuffer
("select 1 from LOCKS where LOCK_ID = " );
sql.append(parent);
ResultSet rslt = getStatement.executeQuery(sql.toString());
return rslt.next();
}
/**
* Get the VersionID for the current URI
*/
protected long getRevisionId
(Connection conn, long uriId, String branch, NodeRevisionNumber nrn)
throws SQLException {
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
stmt = conn.createStatement();
sql.setLength(0);
sql.append("SELECT A.VERSION_ID FROM VERSION_HISTORY A, BRANCH B ")
.append("WHERE A.URI_ID = " ).append(uriId)
.append(" AND A.BRANCH_ID = B.BRANCH_ID ")
.append(" AND B.BRANCH_STRING = '").append(branch)
.append("' AND A.REVISION_NO ")
.append((nrn != null) ? "= '" + nrn + "'" : "IS NULL");
ResultSet rs = stmt.executeQuery(sql.toString());
if (rs.next()) {
return rs.getLong("VERSION_ID");
} else {
return 0;
}
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqle) { }
}
}
}
/**
* Set the Version ID for the current URI
*/
protected void setRevisionId
(Connection conn, long uriId, long branchId, String sXNumber)
throws SQLException {
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
stmt = conn.createStatement();
sql.setLength(0);
sql.append("SELECT 1 FROM VERSION WHERE URI_ID = ").append(uriId);
ResultSet rs = stmt.executeQuery(sql.toString());
if (!rs.next()) {
sql.setLength(0);
sql.append("INSERT INTO VERSION (URI_ID, IS_VERSIONED) ")
.append("VALUES (").append(uriId).append(", ").append(0)
.append(")");
stmt.execute(sql.toString());
}
sql.setLength(0);
sql.append("INSERT INTO VERSION_HISTORY ")
.append("(URI_ID, BRANCH_ID, REVISION_NO) ")
.append("VALUES (").append(uriId).append(", ").append(branchId)
.append(", '").append(sXNumber).append("')");
stmt.execute(sql.toString());
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqle) { }
}
}
}
/**
* Get the revision number string for the current URI
*/
protected String getRevisionNumber
(Connection conn, long versionId, long uriId, String branch)
throws SQLException {
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
stmt = conn.createStatement();
sql.append("SELECT A.REVISION_NO ")
.append("FROM VERSION_HISTORY A, BRANCH B ")
.append("WHERE A.VERSION_ID = ").append(versionId)
.append(" AND A.URI_ID = ").append(uriId)
.append(" AND A.BRANCH_ID = B.BRANCH_ID")
.append(" AND B.BRANCH_STRING = '").append(branch).append("'");
ResultSet rs = stmt.executeQuery(sql.toString());
if (rs.next()) {
return rs.getString("REVISION_NO");
} else {
return null;
}
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqle) { }
}
}
}
/**
* Store a revision.
*/
protected void storeContent
(Connection conn, String revisionUri, String revisionNumber,
NodeRevisionDescriptor revisionDescriptor,
NodeRevisionContent revisionContent)
throws IOException, SQLException {
PreparedStatement pstmt = null;
try {
StringBuffer sql = new StringBuffer();
// find or add the version ID
long versionId = getRevisionId(conn, getUriId(conn, revisionUri),
revisionDescriptor.getBranchName(),
revisionDescriptor.getRevisionNumber());
if (versionId == 0) {
setRevisionId(conn, getUriId(conn, revisionUri),
getBranchId(conn,
revisionDescriptor.getBranchName()),
revisionNumber);
versionId =
getRevisionId(conn, getUriId(conn, revisionUri),
revisionDescriptor.getBranchName(),
revisionDescriptor.getRevisionNumber());
}
sql.append("INSERT INTO VERSION_CONTENT VALUES (?, ?)");
pstmt = conn.prepareStatement(sql.toString());
pstmt.setLong(1, versionId);
InputStream in = revisionContent.streamContent();
if (in != null) {
// Compress the received data.
long contentLength = 0;
StoreContentZip zip = new StoreContentZip();
zip.Zip(in);
in = zip.getInputStream();
contentLength = zip.getContentLength();
OutputStream os = null;
// We copy 8 ko with each read
byte[] buffer = new byte[BUFFER_SIZE];
long position = 0;
//long contentLength = revisionDescriptor.getContentLength();
File tempFile = null;
String tempFileName = null;
if (contentLength == -1) {
// If content length is unspecified, we have to buffer
// to a temp file.
tempFileName = revisionUri + "-" + revisionNumber;
tempFileName = tempFileName.replace('/', '.');
int tempFileNameLength = tempFileName.length();
if (tempFileNameLength > 200)
tempFileName = tempFileName.substring
(tempFileNameLength - 200, tempFileNameLength);
tempFile = File.createTempFile(tempFileName, null);
FileOutputStream fos = new FileOutputStream(tempFile);
while (true) {
int nChar = in.read(buffer);
if (nChar == -1) {
break;
}
fos.write(buffer, 0, nChar);
position = position + nChar;
}
fos.close();
in = new FileInputStream(tempFile);
contentLength = tempFile.length();
}
// FIXME ? Cast from long to int won't allow files > 4GB.
pstmt.setBinaryStream(2, in, (int)contentLength - 1);
pstmt.executeUpdate();
revisionDescriptor.setContentLength(contentLength);
if (tempFile != null) {
in.close();
tempFile.delete();
}
}
} finally {
if (pstmt != null) {
try {
pstmt.close();
} catch (SQLException sqle) { }
}
}
}
/**
* Remove content.
*/
protected void removeContent(Connection conn, long versionId)
throws SQLException {
Statement stmt = null;
try {
StringBuffer sql = new StringBuffer();
sql.append("DELETE FROM VERSION_CONTENT ")
.append("WHERE VERSION_ID = ").append(versionId);
stmt = conn.createStatement();
stmt.executeUpdate(sql.toString());
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqle) { }
}
}
}
}
1.1 jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms/RDBMSAdapter.java
Index: RDBMSAdapter.java
===================================================================
/*
* $Header$
* $Revision$
* $Date$
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.store.impl.rdbms;
import java.sql.Connection;
import java.util.Enumeration;
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.Uri;
import org.apache.slide.content.NodeRevisionContent;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionDescriptors;
import org.apache.slide.content.NodeRevisionNumber;
import org.apache.slide.content.RevisionAlreadyExistException;
import org.apache.slide.content.RevisionDescriptorNotFoundException;
import org.apache.slide.content.RevisionNotFoundException;
import org.apache.slide.lock.LockTokenNotFoundException;
import org.apache.slide.lock.NodeLock;
import org.apache.slide.security.NodePermission;
import org.apache.slide.structure.ObjectAlreadyExistsException;
import org.apache.slide.structure.ObjectNode;
import org.apache.slide.structure.ObjectNotFoundException;
/**
*
*
* @author <a href="mailto:cmlenz@apache.org">Christopher Lenz</a>
* @version $Revision$
*/
public interface RDBMSAdapter {
// ---------------------------------------------------------------- Methods
/**
*
*/
public ObjectNode retrieveObject(Connection conn, Uri uri)
throws ServiceAccessException, ObjectNotFoundException;
/**
*
*/
public void storeObject(Connection conn, Uri uri, ObjectNode object)
throws ServiceAccessException, ObjectNotFoundException;
/**
*
*/
public void createObject(Connection conn, Uri uri, ObjectNode object)
throws ServiceAccessException, ObjectAlreadyExistsException;
/**
*
*/
public void removeObject(Connection conn, Uri uri, ObjectNode object)
throws ServiceAccessException, ObjectNotFoundException;
/**
*
*/
public void grantPermission
(Connection conn, Uri uri, NodePermission permission)
throws ServiceAccessException;
/**
*
*/
public void revokePermission
(Connection conn, Uri uri, NodePermission permission)
throws ServiceAccessException;
/**
*
*/
public void revokePermissions(Connection conn, Uri uri)
throws ServiceAccessException;
/**
*
*/
public Enumeration enumeratePermissions(Connection conn, Uri uri)
throws ServiceAccessException;
/**
*
*/
public void putLock(Connection conn, Uri uri, NodeLock lock)
throws ServiceAccessException;
/**
*
*/
public void renewLock(Connection conn, Uri uri, NodeLock lock)
throws ServiceAccessException, LockTokenNotFoundException;
/**
*
*/
public void removeLock(Connection conn, Uri uri, NodeLock lock)
throws ServiceAccessException, LockTokenNotFoundException;
/**
*
*/
public void killLock(Connection conn, Uri uri, NodeLock lock)
throws ServiceAccessException, LockTokenNotFoundException;
/**
*
*/
public Enumeration enumerateLocks(Connection conn, Uri uri)
throws ServiceAccessException;
/**
*
*/
public NodeRevisionDescriptors retrieveRevisionDescriptors
(Connection conn, Uri uri)
throws ServiceAccessException, RevisionDescriptorNotFoundException;
/**
*
*/
public void createRevisionDescriptors
(Connection conn, Uri uri, NodeRevisionDescriptors revisionDescriptors)
throws ServiceAccessException;
/**
*
*/
public void storeRevisionDescriptors
(Connection conn, Uri uri, NodeRevisionDescriptors revisionDescriptors)
throws ServiceAccessException, RevisionDescriptorNotFoundException;
/**
*
*/
public void removeRevisionDescriptors(Connection conn, Uri uri)
throws ServiceAccessException;
/**
*
*/
public NodeRevisionDescriptor retrieveRevisionDescriptor
(Connection conn, Uri uri, NodeRevisionNumber nrn)
throws ServiceAccessException, RevisionDescriptorNotFoundException;
/**
*
*/
public void createRevisionDescriptor
(Connection conn, Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException;
/**
*
*/
public void storeRevisionDescriptor
(Connection conn, Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException, RevisionDescriptorNotFoundException;
/**
*
*/
public void removeRevisionDescriptor
(Connection conn, Uri uri, NodeRevisionNumber nrn)
throws ServiceAccessException;
/**
*
*/
public NodeRevisionContent retrieveRevisionContent
(Connection conn, Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException, RevisionNotFoundException;
/**
*
*/
public void createRevisionContent
(Connection conn, Uri uri, NodeRevisionDescriptor revisionDescriptor,
NodeRevisionContent revisionContent)
throws ServiceAccessException, RevisionAlreadyExistException;
/**
*
*/
public void storeRevisionContent
(Connection conn, Uri uri, NodeRevisionDescriptor revisionDescriptor,
NodeRevisionContent revisionContent)
throws ServiceAccessException, RevisionNotFoundException;
/**
*
*/
public void removeRevisionContent
(Connection conn, Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException;
}
1.1 jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms/AbstractRDBMSAdapter.java
Index: AbstractRDBMSAdapter.java
===================================================================
/*
* $Header$
* $Revision$
* $Date$
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.store.impl.rdbms;
import java.sql.Connection;
import java.util.Enumeration;
import org.apache.slide.common.Service;
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.Uri;
import org.apache.slide.content.NodeRevisionContent;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionDescriptors;
import org.apache.slide.content.NodeRevisionNumber;
import org.apache.slide.content.RevisionAlreadyExistException;
import org.apache.slide.content.RevisionDescriptorNotFoundException;
import org.apache.slide.content.RevisionNotFoundException;
import org.apache.slide.lock.LockTokenNotFoundException;
import org.apache.slide.lock.NodeLock;
import org.apache.slide.security.NodePermission;
import org.apache.slide.structure.ObjectAlreadyExistsException;
import org.apache.slide.structure.ObjectNode;
import org.apache.slide.structure.ObjectNotFoundException;
/**
*
*
* @author <a href="mailto:cmlenz@apache.org">Christopher Lenz</a>
* @version $Revision$
*/
public abstract class AbstractRDBMSAdapter
implements RDBMSAdapter {
// ----------------------------------------------------- Instance Variables
/**
*
*/
protected Service service;
// ----------------------------------------------------------- Constructors
/**
*
*/
public AbstractRDBMSAdapter(Service service) {
this.service = service;
}
// -------------------------------------------- RDBMSAdapter Implementation
/**
*
*/
public ObjectNode retrieveObject(Connection conn, Uri uri)
throws ServiceAccessException, ObjectNotFoundException {
throw new UnsupportedOperationException();
}
/**
*
*/
public void storeObject(Connection conn, Uri uri, ObjectNode object)
throws ServiceAccessException, ObjectNotFoundException {
throw new UnsupportedOperationException();
}
/**
*
*/
public void createObject(Connection conn, Uri uri, ObjectNode object)
throws ServiceAccessException, ObjectAlreadyExistsException {
throw new UnsupportedOperationException();
}
/**
*
*/
public void removeObject(Connection conn, Uri uri, ObjectNode object)
throws ServiceAccessException, ObjectNotFoundException {
throw new UnsupportedOperationException();
}
/**
*
*/
public void grantPermission
(Connection conn, Uri uri, NodePermission permission)
throws ServiceAccessException {
throw new UnsupportedOperationException();
}
/**
*
*/
public void revokePermission
(Connection conn, Uri uri, NodePermission permission)
throws ServiceAccessException {
throw new UnsupportedOperationException();
}
/**
*
*/
public void revokePermissions(Connection conn, Uri uri)
throws ServiceAccessException {
throw new UnsupportedOperationException();
}
/**
*
*/
public Enumeration enumeratePermissions(Connection conn, Uri uri)
throws ServiceAccessException {
throw new UnsupportedOperationException();
}
/**
*
*/
public void putLock(Connection conn, Uri uri, NodeLock lock)
throws ServiceAccessException {
throw new UnsupportedOperationException();
}
/**
*
*/
public void renewLock(Connection conn, Uri uri, NodeLock lock)
throws ServiceAccessException, LockTokenNotFoundException {
throw new UnsupportedOperationException();
}
/**
*
*/
public void removeLock(Connection conn, Uri uri, NodeLock lock)
throws ServiceAccessException, LockTokenNotFoundException {
throw new UnsupportedOperationException();
}
/**
*
*/
public void killLock(Connection conn, Uri uri, NodeLock lock)
throws ServiceAccessException, LockTokenNotFoundException {
throw new UnsupportedOperationException();
}
/**
*
*/
public Enumeration enumerateLocks(Connection conn, Uri uri)
throws ServiceAccessException {
throw new UnsupportedOperationException();
}
/**
*
*/
public NodeRevisionDescriptors retrieveRevisionDescriptors
(Connection conn, Uri uri)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
throw new UnsupportedOperationException();
}
/**
*
*/
public void createRevisionDescriptors
(Connection conn, Uri uri, NodeRevisionDescriptors revisionDescriptors)
throws ServiceAccessException {
throw new UnsupportedOperationException();
}
/**
*
*/
public void storeRevisionDescriptors
(Connection conn, Uri uri, NodeRevisionDescriptors revisionDescriptors)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
throw new UnsupportedOperationException();
}
/**
*
*/
public void removeRevisionDescriptors(Connection conn, Uri uri)
throws ServiceAccessException {
throw new UnsupportedOperationException();
}
/**
*
*/
public NodeRevisionDescriptor retrieveRevisionDescriptor
(Connection conn, Uri uri, NodeRevisionNumber nrn)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
throw new UnsupportedOperationException();
}
/**
*
*/
public void createRevisionDescriptor
(Connection conn, Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException {
throw new UnsupportedOperationException();
}
/**
*
*/
public void storeRevisionDescriptor
(Connection conn, Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
throw new UnsupportedOperationException();
}
/**
*
*/
public void removeRevisionDescriptor
(Connection conn, Uri uri, NodeRevisionNumber nrn)
throws ServiceAccessException {
throw new UnsupportedOperationException();
}
/**
*
*/
public NodeRevisionContent retrieveRevisionContent
(Connection conn, Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException, RevisionNotFoundException {
throw new UnsupportedOperationException();
}
/**
*
*/
public void createRevisionContent
(Connection conn, Uri uri, NodeRevisionDescriptor revisionDescriptor,
NodeRevisionContent revisionContent)
throws ServiceAccessException, RevisionAlreadyExistException {
throw new UnsupportedOperationException();
}
/**
*
*/
public void storeRevisionContent
(Connection conn, Uri uri, NodeRevisionDescriptor revisionDescriptor,
NodeRevisionContent revisionContent)
throws ServiceAccessException, RevisionNotFoundException {
throw new UnsupportedOperationException();
}
/**
*
*/
public void removeRevisionContent
(Connection conn, Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException {
throw new UnsupportedOperationException();
}
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>