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/07 20:49:49 UTC
cvs commit: jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms J2EEDescriptorsStore.java StoreContentZip.java J2EEStore.java HSQLDBSchema.sql SQLServerSchema.sql J2EEContentStore.java
cmlenz 2002/08/07 11:49:49
Added: src/stores/org/apache/slide/store/impl/rdbms
J2EEDescriptorsStore.java StoreContentZip.java
J2EEStore.java HSQLDBSchema.sql SQLServerSchema.sql
J2EEContentStore.java
Log:
Initial commit of the J2EE Store classes based on the new database
schema by Ashok Kumar (akumar at metatomix.com).
NOTICE: I have not yet tested the schema or the store implementation,
but it does seem to be a big improvement over the "old" code.
Revision Changes Path
1.1 jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms/J2EEDescriptorsStore.java
Index: J2EEDescriptorsStore.java
===================================================================
/*
* $Header: /home/cvspublic/jakarta-slide/src/stores/slidestore/j2ee/J2EEDescriptorsStore2.java,v 1.0 2002/04/11 00:16:52 akumar Exp $
* $Revision: 1.0 $
* $Date: 2002/04/11 00:16:52 $
*
* ====================================================================
*
* 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.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.ServiceAccessException;
import org.apache.slide.common.Uri;
import org.apache.slide.content.NodeProperty;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionDescriptors;
import org.apache.slide.content.NodeRevisionNumber;
import org.apache.slide.content.RevisionDescriptorNotFoundException;
import org.apache.slide.lock.LockTokenNotFoundException;
import org.apache.slide.lock.NodeLock;
import org.apache.slide.security.NodePermission;
import org.apache.slide.store.LockStore;
import org.apache.slide.store.NodeStore;
import org.apache.slide.store.RevisionDescriptorStore;
import org.apache.slide.store.RevisionDescriptorsStore;
import org.apache.slide.store.SecurityStore;
import org.apache.slide.structure.LinkNode;
import org.apache.slide.structure.ObjectAlreadyExistsException;
import org.apache.slide.structure.ObjectNode;
import org.apache.slide.structure.ObjectNotFoundException;
import org.apache.slide.util.logger.Logger;
/**
* J2EE Descriptors store implementation for the new Indexed DB Schema..
*
*
* @author <a href="mailto:akumar@metatomix.com">Ashok Kumar</a>
* @version $Revision: 1.0 $
*/
public class J2EEDescriptorsStore
extends J2EEStore
implements LockStore, NodeStore, RevisionDescriptorsStore,
RevisionDescriptorStore, SecurityStore {
protected NodeRevisionDescriptor myRevisionDescriptor= null;
// ----------------------------------------------- DescriptorsStore Methods
/**
* Retrive an object.
*
* @param uri Uri of the object we want to retrieve
* @exception ServiceAccessException Error accessing the Service
* @exception ObjectNotFoundException The object to retrieve was not found
*/
public ObjectNode retrieveObject(Uri uri)
throws ServiceAccessException, ObjectNotFoundException {
ObjectNode result = null;
Statement statement = null;
Connection connection = getCurrentConnection();
try {
long currentUriID = this.getURIID(uri.toString());
statement = connection.createStatement();
if (currentUriID == 0) {
throw new ObjectNotFoundException(uri);
}
StringBuffer theSQL = new StringBuffer
("select CLASS_NAME from OBJECT where URI_ID= ");
theSQL.append(currentUriID);
ResultSet res = statement.executeQuery(theSQL.toString());
// Parsing result set
String className;
if (res.next()) {
// Retrieving and loading the object
className = res.getString("CLASS_NAME");
} else {
// Object was not found ...
throw new ObjectNotFoundException(uri);
}
// Then, retrieve the children
theSQL = new StringBuffer
("select URI_STRING from URI where URI_ID IN ");
theSQL.append("(SELECT CHILD_URI_ID FROM CHILDREN WHERE URI_ID = ");
theSQL.append(currentUriID).append(")");
res = statement.executeQuery(theSQL.toString());
Vector childrenVector = new Vector();
// Parse result set
while (res.next()) {
// Load each permission
String sts = res.getString("URI_STRING");
childrenVector.addElement(sts);
}
theSQL = new StringBuffer
("select URI_STRING from URI where URI_ID IN ");
theSQL.append("(select URI_ID from LINKS where LINK_TO_ID= ");
theSQL.append(currentUriID).append(")");
res = statement.executeQuery(theSQL.toString());
Vector linksVector = new Vector();
// Parse result set
while (res.next()) {
// Load each permission
linksVector.addElement(res.getString("URI_STRING"));
}
if (className.equals("org.apache.slide.structure.LinkNode")) {
String linkTo = new String();
theSQL = new StringBuffer("select URI_STRING from URI ");
theSQL.append(" where URI_ID IN (select LINK_TO_ID from ");
theSQL.append("LINKS where URI_ID= ");
theSQL.append(currentUriID).append(")");
res = statement.executeQuery(theSQL.toString());
if(res.next())
linkTo = res.getString("URI_STRING");
result = new LinkNode(uri.toString(), childrenVector,
linksVector, linkTo);
} else {
try {
Class objclass = Class.forName(className);
Class[] argClasses = { Class.forName("java.lang.String"),
Class.forName("java.util.Vector"),
Class.forName("java.util.Vector") };
Object[] arguments = { uri.toString(),
childrenVector,
linksVector };
Constructor constructor =
objclass.getConstructor(argClasses);
result = (ObjectNode)constructor.newInstance(arguments);
} catch(Exception e) {
// ClassNotFoundException, NoSuchMethodException, etc.
throw new ServiceAccessException(this, e);
}
}
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
} finally {
try {
statement.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
}
}
return result;
}
/**
* Update an object.
*
* @param object Object to update
* @exception ServiceAccessException Error accessing the Service
* @exception ObjectNotFoundException The object to update was not found
*/
public void storeObject(Uri uri, ObjectNode object)
throws ServiceAccessException, ObjectNotFoundException {
Statement statement = null;
Connection connection = getCurrentConnection();
try {
long uriid = this.getURIID( uri.toString());
statement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("select 1 from OBJECT where URI_ID= ");
theSQL.append(uriid);
ResultSet res = statement.executeQuery(theSQL.toString());
// Parsing result set
if (!res.next()) {
throw new ObjectNotFoundException(uri);
}
long parent = this.getURIID(object.getUri());
Enumeration children =
getNewChildren(parent,object.enumerateChildren());
if (children != null) {
while (children.hasMoreElements()) {
theSQL = new StringBuffer("insert into CHILDREN ");
theSQL.append("(URI_ID,CHILD_URI_ID) values( ");
theSQL.append(parent).append(" , ")
.append(this.getURIID((String)children.nextElement()))
.append(")");
statement.execute(theSQL.toString());
}
}
// Updating link
if (object instanceof LinkNode) {
long link_to = this.getURIID
(((LinkNode) object).getLinkedUri());
if (! this.isLinkExist(parent,link_to)) {
theSQL = new StringBuffer("insert into LINKS (URI_ID,");
theSQL.append("LINK_TO_ID) values( ");
theSQL.append(parent).append(" , ").
append(link_to).append(")");
statement.execute(theSQL.toString());
}
}
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
} finally {
try {
statement.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
}
}
}
/**
* Create a new object.
*
* @param object ObjectNode
* @param uri Uri of the object we want to create
* @exception ServiceAccessException Error accessing the Service
* @exception ObjectAlreadyExistsException An object already exists
* at this Uri
*/
public void createObject(Uri uri, ObjectNode object)
throws ServiceAccessException, ObjectAlreadyExistsException {
Statement statement = null;
Connection connection = getCurrentConnection();
try {
this.setURIID(uri.toString());
long uriid = this.getURIID( uri.toString());
String className = object.getClass().getName();
statement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("select 1 from OBJECT where URI_ID= ");
theSQL.append(uriid);
ResultSet res = statement.executeQuery(theSQL.toString());
// Parsing result set
if (res.next()) {
throw new ObjectAlreadyExistsException(uri.toString());
}
theSQL = new StringBuffer
("insert into OBJECT (URI_ID,CLASS_NAME) values ( ");
theSQL.append(uriid).append(" , '")
.append(className).append("' )");
statement.execute(theSQL.toString());
Enumeration children = getNewChildren
(uriid,object.enumerateChildren());
if (children != null) {
while (children.hasMoreElements()) {
theSQL = new StringBuffer("insert into CHILDREN ");
theSQL.append("(URI_ID,CHILD_URI_ID) values( ");
theSQL.append(uriid).append(" , ")
.append(this.getURIID((String)children.nextElement()))
.append(" )");
statement.execute(theSQL.toString());
}
}
// If the object is a link, also store the link information
if (object instanceof LinkNode) {
long link_to = this.getURIID
(((LinkNode) object).getLinkedUri());
if (! this.isLinkExist(uriid,link_to)) {
theSQL = new StringBuffer("insert into LINKS (URI_ID,");
theSQL.append("LINK_TO_ID) values( ");
theSQL.append(uriid).append(" , '")
.append(link_to).append("' )");
statement.execute(theSQL.toString());
}
}
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
} finally {
try {
statement.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
}
}
}
/**
* Remove an object.
*
* @param object Object to remove
* @exception ServiceAccessException Error accessing the Service
* @exception ObjectNotFoundException The object to remove was not found
*/
public void removeObject(Uri uri, ObjectNode object)
throws ServiceAccessException, ObjectNotFoundException {
try {
long uriid = this.getURIID(object.getUri());
Statement statement = null;
Connection connection = getCurrentConnection();
statement = connection.createStatement();
// Removing children
StringBuffer theSQL = new StringBuffer
("delete from CHILDREN where URI_ID = ");
theSQL.append(uriid).append(" OR CHILD_URI_ID = ")
.append(uriid);
statement.execute(theSQL.toString());
// Removing REST
theSQL = new StringBuffer
("delete from LINKS where URI_ID = ");
theSQL.append(uriid);
statement.execute(theSQL.toString());
theSQL = new StringBuffer
("delete from VERSION_HISTORY where URI_ID = ");
theSQL.append(uriid);
statement.execute(theSQL.toString());
theSQL = new StringBuffer
("delete from VERSION where URI_ID = ");
theSQL.append(uriid);
statement.execute(theSQL.toString());
// Removing object
theSQL = new StringBuffer
("delete from OBJECT where URI_ID = ");
theSQL.append(uriid);
statement.execute(theSQL.toString());
theSQL = new StringBuffer
("delete from URI where URI_ID = ");
theSQL.append(uriid);
statement.execute(theSQL.toString());
super.uriIdLookup.remove(object.getUri());
super.uriLookup.remove(new Long(uriid));
statement.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
}
}
/**
* Grant a new permission.
*
* @param permission Permission we want to create
* @exception ServiceAccessException Error accessing the Service
*/
public void grantPermission(Uri uri, NodePermission permission)
throws ServiceAccessException {
Statement statement = null;
Connection connection = getCurrentConnection();
try {
int inheritable = 0;
if (permission.isInheritable()) {
inheritable = 1;
}
int negative = 0;
if (permission.isNegative()) {
negative = 1;
}
statement = connection.createStatement();
NodeRevisionNumber revisionNumber = permission.getRevisionNumber();
String revisionNumberStr =
(revisionNumber == null) ? "NULL" : revisionNumber.toString();
this.setURIID(permission.getObjectUri());
this.setURIID(permission.getSubjectUri());
this.setURIID(permission.getActionUri());
long objid = this.getURIID(permission.getObjectUri());
long subid = this.getURIID(permission.getSubjectUri());
long actid = this.getURIID(permission.getActionUri());
StringBuffer theSQL = new StringBuffer("select 1 from PERMISSIONS");
theSQL.append(" where OBJECT_ID = ");
theSQL.append(objid).append(" and SUBJECT_ID= ")
.append(subid).append(" and ACTION_ID = " )
.append(actid);
ResultSet res = statement.executeQuery(theSQL.toString());
if (! res.next()) {
theSQL = new StringBuffer("insert into PERMISSIONS ");
theSQL.append("(OBJECT_ID,SUBJECT_ID,ACTION_ID,VERSION_NO,");
theSQL.append("IS_INHERITABLE,IS_NEGATIVE) values( ");
theSQL.append(objid).append(", ").append(subid)
.append(", ").append(actid)
.append(", ").append(revisionNumberStr)
.append(", ").append(inheritable)
.append(", ").append(negative).append(")");
statement.execute(theSQL.toString());
}
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
} finally {
try {
statement.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
}
}
}
/**
* Revoke a permission.
*
* @param permission Permission we want to create
* @exception ServiceAccessException Error accessing the Service
*/
public void revokePermission(Uri uri, NodePermission permission)
throws ServiceAccessException {
Statement statement = null;
Connection connection = getCurrentConnection();
try {
statement = connection.createStatement();
NodeRevisionNumber revisionNumber = permission.getRevisionNumber();
StringBuffer theSQL = new StringBuffer("delete from PERMISSIONS ");
theSQL.append("where OBJECT_ID= ");
theSQL.append(this.getURIID(permission.getObjectUri()))
.append(" and SUBJECT_ID = ")
.append(this.getURIID(permission.getSubjectUri()))
.append(" and ACTION_ID = " )
.append(this.getURIID(permission.getActionUri()));
if(revisionNumber != null) {
statement.execute(theSQL.append(" and VERSION_NO = ")
.append(revisionNumber.toString()).toString());
}
else {
statement.execute(
theSQL.append(" and VERSION_NO = NULL").toString());
}
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
} finally {
try {
statement.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
}
}
}
/**
* Revoke all the permissions on an object.
*
* @param permission Permission we want to create
* @exception ServiceAccessException Error accessing the Service
*/
public void revokePermissions(Uri uri)
throws ServiceAccessException {
Statement statement = null;
Connection connection = getCurrentConnection();
try {
statement = connection.createStatement();
StringBuffer theSQL = new StringBuffer("delete from PERMISSIONS");
theSQL.append(" where OBJECT_ID= ");
theSQL.append(this.getURIID(uri.toString()));
statement.execute(theSQL.toString());
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
} finally {
try {
statement.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
}
}
}
/**
* Enumerate permissions on an object.
*
* @param permission Permission we want to create
* @exception ServiceAccessException Error accessing the Service
*/
public Enumeration enumeratePermissions(Uri uri)
throws ServiceAccessException {
Vector permissionVector = new Vector();
Statement statement = null;
Connection connection = getCurrentConnection();
try {
statement = connection.createStatement();
StringBuffer theSQL = new StringBuffer("select * from PERMISSIONS ");
theSQL.append("where OBJECT_ID = ");
theSQL.append(this.getURIID(uri.toString()));
statement.execute(theSQL.toString());
ResultSet res = statement.executeQuery(theSQL.toString());
String object = null;
while (res.next()) {
if (object == null) {
object = this.getURIString(res.getLong("OBJECT_ID"));
}
String revision = res.getString("VERSION_NO");
String subject = this.getURIString(res.getLong("SUBJECT_ID"));
String action = this.getURIString(res.getLong("ACTION_ID"));
boolean inheritable = false;
if (res.getInt("IS_INHERITABLE") == 1) {
inheritable = true;
}
boolean negative = false;
if (res.getInt("IS_NEGATIVE") == 1) {
negative = true;
}
NodePermission permission =
new NodePermission(object,revision,subject,
action,inheritable,negative);
permissionVector.addElement(permission);
}
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
} finally {
try {
statement.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
}
}
return permissionVector.elements();
}
/**
* Create a new lock.
*
* @param lock Lock token
* @exception ServiceAccessException Service access error
*/
public void putLock(Uri uri, NodeLock lock)
throws ServiceAccessException {
Statement statement = null;
Connection connection = getCurrentConnection();
try {
int inheritable = 0;
if (lock.isInheritable()) {
inheritable = 1;
}
int exclusive = 0;
if (lock.isExclusive()) {
exclusive = 1;
}
statement = connection.createStatement();
StringBuffer theSQL =
new StringBuffer("insert into LOCKS (LOCK_ID,OBJECT_ID,");
theSQL.append("SUBJECT_ID,TYPE_ID,EXPIRATION_DATE,");
theSQL.append("IS_INHERITABLE,IS_EXCLUSIVE) values( ");
long in_lockid = this.getURIID(lock.getLockId());
if (in_lockid == 0 ) {
this.setURIID(lock.getLockId());
in_lockid = this.getURIID(lock.getLockId());
}
theSQL.append(in_lockid).append(", ");
theSQL.append(this.getURIID(lock.getObjectUri())).append(", ");
theSQL.append(this.getURIID(lock.getSubjectUri())).append(", ");
theSQL.append(this.getURIID(lock.getTypeUri())).append(", ");
theSQL.append(lock.getExpirationDate().getTime()).append(", ");
theSQL.append(inheritable).append(", ");
theSQL.append(exclusive).append(" ) ");
statement.execute(theSQL.toString());
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
} finally {
try {
statement.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
}
}
}
/**
* Renew a lock.
*
* @param lock Token to renew
* @exception ServiceAccessException Service access error
* @exception LockTokenNotFoundException Lock token was not found
*/
public void renewLock(Uri uri, NodeLock lock)
throws ServiceAccessException, LockTokenNotFoundException {
try {
if (! isLockExist(this.getURIID(lock.getLockId())) ) {
this.putLock(uri,lock);
}
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
}
}
/**
* Unlock.
*
* @param lock Token to remove
* @exception ServiceAccessException Service access error
* @exception LockTokenNotFoundException Lock token was not found
*/
public void removeLock(Uri uri, NodeLock lock)
throws ServiceAccessException, LockTokenNotFoundException {
Statement statement = null;
Connection connection = getCurrentConnection();
try {
statement = connection.createStatement();
int inheritable = 0;
if (lock.isInheritable()) {
inheritable = 1;
}
StringBuffer theSQL =
new StringBuffer("delete from LOCKS where LOCK_ID= '");
long in_lock = this.getURIID(lock.getLockId());
theSQL.append(in_lock).append("'");
statement.execute(theSQL.toString());
statement.execute("delete from URI where URI_ID = " + in_lock);
super.uriIdLookup.remove(lock.getLockId());
super.uriLookup.remove(new Long(in_lock));
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
} finally {
try {
statement.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
}
}
}
/**
* Kill a lock.
*
* @param lock Token to remove
* @exception ServiceAccessException Service access error
* @exception LockTokenNotFoundException Lock token was not found
*/
public void killLock(Uri uri, NodeLock lock)
throws ServiceAccessException, LockTokenNotFoundException {
removeLock(uri, lock);
}
/**
* Enumerate locks on an object.
*
* @param subject Subject
* @return Enumeration List of locks which have been put on the subject
* @exception ServiceAccessException Service access error
*/
public Enumeration enumerateLocks(Uri uri)
throws ServiceAccessException {
Vector lockVector = new Vector();
Statement statement = null;
Connection connection = getCurrentConnection();
try {
statement = connection.createStatement();
StringBuffer theSQL =
new StringBuffer("select * from LOCKS where OBJECT_ID= ");
theSQL.append(this.getURIID(uri.toString()));
ResultSet res = statement.executeQuery(theSQL.toString());
while (res.next()) {
Date expirationDate = null;
try {
Long timeValue = new Long(res.getLong
("EXPIRATION_DATE"));
expirationDate = new Date(timeValue.longValue());
} catch (NumberFormatException e) {
expirationDate = new Date();
}
NodeLock lock =
new NodeLock(this.getURIString(res.getLong("LOCK_ID")),
this.getURIString(res.getLong("OBJECT_ID")),
this.getURIString(res.getLong("SUBJECT_ID")),
this.getURIString(res.getLong("TYPE_ID")),
expirationDate,
(res.getInt("IS_INHERITABLE") == 1),
(res.getInt("IS_EXCLUSIVE") == 1));
lockVector.addElement(lock);
}
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
} finally {
try {
statement.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
}
}
return lockVector.elements();
}
/**
* Retrieve the revisions informations of an object.
*
* @param uri Uri
* @exception ServiceAccessException Service access error
* @exception RevisionDescriptorNotFoundException Revision descriptor
* was not found
*/
public NodeRevisionDescriptors retrieveRevisionDescriptors(Uri uri)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
NodeRevisionDescriptors revisionDescriptors = null;
Statement statement = null;
Statement statement2 = null;
Connection connection = getCurrentConnection();
try {
ResultSet res = null;
NodeRevisionNumber initialRevision = new NodeRevisionNumber();
Hashtable workingRevisions = new Hashtable();
Hashtable latestRevisionNumbers = new Hashtable();
Hashtable branches = new Hashtable();
boolean isVersioned = false;
long uriid = this.getURIID( uri.toString());
statement = connection.createStatement();
statement2 = connection.createStatement();
StringBuffer theSQL =
new StringBuffer("select IS_VERSIONED from VERSION");
theSQL.append(" where URI_ID= ");
theSQL.append(uriid);
res = statement.executeQuery(theSQL.toString());
if (res.next()) {
int isVersionedInt = res.getInt("IS_VERSIONED");
if (isVersionedInt == 1) {
isVersioned = true;
}
} else {
throw new RevisionDescriptorNotFoundException(uri.toString());
}
theSQL = new StringBuffer("select VERSION_ID,REVISION_NO, ");
theSQL.append("B.BRANCH_STRING from VERSION_HISTORY A , ");
theSQL.append("BRANCH B where A.URI_ID= ");
theSQL.append(uriid).append(" and A.BRANCH_ID = B.BRANCH_ID");
res = statement.executeQuery(theSQL.toString());
while(res.next()) {
String branchid = res.getString("BRANCH_STRING");
long versionid = res.getLong("VERSION_ID");
String currentRevisionNumber = res.getString("REVISION_NO");
latestRevisionNumbers
.put(branchid,
new NodeRevisionNumber(currentRevisionNumber));
// We parse the revision list of the object
theSQL = new StringBuffer("select PREDECESSOR_ID from ");
theSQL.append("VERSION_PREDS where VERSION_ID = ");
theSQL.append(versionid);
ResultSet res2 = statement2.executeQuery(theSQL.toString());
Vector childList = new Vector();
while (res2.next()) {
childList.addElement(new NodeRevisionNumber
(this.getXNumber(res2.getLong("PREDECESSOR_ID"),
uriid,
branchid)));
}
branches.put(new NodeRevisionNumber(currentRevisionNumber),
childList);
res2.close();
}
revisionDescriptors = new NodeRevisionDescriptors
(uri.toString(), initialRevision, workingRevisions,
latestRevisionNumbers, branches, isVersioned);
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
} finally {
try {
statement.close();
statement2.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
}
}
return revisionDescriptors;
}
/**
* Create a new revision information object.
*
* @param uri Uri
* @param revisionDescriptors Node revision descriptors
* @exception ServiceAccessException Service access error
*/
public void createRevisionDescriptors
(Uri uri, NodeRevisionDescriptors revisionDescriptors)
throws ServiceAccessException {
// TODO : Here, we have the option of "cleaning up" before
// creating the new records in the database.
Statement statement = null;
Connection connection = getCurrentConnection();
try {
ResultSet res = null;
// Creating record in revisions tables
int isVersioned = 0;
if (revisionDescriptors.isVersioned()) {
isVersioned = 1;
}
long urid = this.getURIID(uri.toString());
statement = connection.createStatement();
StringBuffer theSQL =
new StringBuffer("SELECT 1 FROM VERSION WHERE URI_ID =");
theSQL.append(urid);
res = statement.executeQuery(theSQL.toString());
if (!res.next()) {
theSQL = new StringBuffer("insert into VERSION ");
theSQL.append("(URI_ID,IS_VERSIONED) values( ");
theSQL.append(urid).append(", ").append(isVersioned)
.append(")");
statement.execute(theSQL.toString());
}
// For now, only the latest revision from the main branch is stored
long brid = this.getBranchID( NodeRevisionDescriptors.
MAIN_BRANCH.toString());
theSQL = new StringBuffer
("SELECT 1 FROM VERSION_HISTORY WHERE URI_ID =");
theSQL.append(urid).append(" and BRANCH_ID = ").append(brid);
if (revisionDescriptors.getLatestRevision() == null) {
theSQL.append(" and REVISION_NO = ").append("NULL");
} else {
theSQL.append(" and REVISION_NO = '").
append(revisionDescriptors.getLatestRevision().toString())
.append("'");
}
res = statement.executeQuery(theSQL.toString());
if (!res.next()) {
if (revisionDescriptors.getLatestRevision() != null) {
theSQL = new StringBuffer("insert into VERSION_HISTORY ");
theSQL.append("(URI_ID,BRANCH_ID,REVISION_NO) values(");
theSQL.append(urid).append(", ").append(brid);
theSQL.append(", '").append(
revisionDescriptors.getLatestRevision().toString())
.append("')");
statement.execute(theSQL.toString());
}
}
// Creating records in the branches table
// TODO Retained from the old Slide Schema
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
} finally {
try {
statement.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
}
}
}
/**
* Update revision information.
*
* @param uri Uri
* @param revisionDescriptors Node revision descriptors
* @exception ServiceAccessException Service access error
* @exception RevisionDescriptorNotFoundException Revision descriptor
* was not found
*/
public void storeRevisionDescriptors
(Uri uri, NodeRevisionDescriptors revisionDescriptors)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
removeRevisionDescriptors(uri);
createRevisionDescriptors(uri, revisionDescriptors);
}
/**
* Remove revision information.
*
* @param uri Uri
* @exception ServiceAccessException Service access error
*/
public void removeRevisionDescriptors(Uri uri)
throws ServiceAccessException {
Statement statement = null;
Connection connection = getCurrentConnection();
try {
long uriid = this.getURIID(uri.toString());
statement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("delete from VERSION_PREDS where VERSION_ID IN ");
theSQL.append("(SELECT VERSION_ID FROM VERSION_HISTORY");
theSQL.append(" where URI_ID = ");
theSQL.append(uriid).append(")");
statement.execute(theSQL.toString());
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
} finally {
try {
statement.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
}
}
}
/**
* Retrieve an individual object's revision descriptor.
*
* @param Uri uri
* @param revisionNumber Node revision number
*/
public NodeRevisionDescriptor retrieveRevisionDescriptor
(Uri uri, NodeRevisionNumber revisionNumber)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
NodeRevisionDescriptor revisionDescriptor = null;
Statement statement = null;
Connection connection = getCurrentConnection();
if(revisionNumber == null)
throw new RevisionDescriptorNotFoundException(uri.toString());
try {
ResultSet res = null;
long uriid = this.getURIID(uri.toString());
String branchName = null;
Vector labels = new Vector();
Hashtable properties = new Hashtable();
// Retrieving branch name (and also check that revision
// does indeed exist)
statement = connection.createStatement();
StringBuffer theSQL = new StringBuffer("select A.VERSION_ID, ");
theSQL.append("B.BRANCH_STRING from VERSION_HISTORY A, BRANCH B");
theSQL.append(" where A.URI_ID = ");
theSQL.append(uriid).append(" and A.REVISION_NO = '");
theSQL.append(revisionNumber.toString());
theSQL.append("' and B.BRANCH_ID = A.BRANCH_ID");
res = statement.executeQuery(theSQL.toString());
long Version_ID = 0;
if (res.next()) {
branchName = res.getString("BRANCH_STRING");
Version_ID = res.getLong("VERSION_ID");
} else {
throw new RevisionDescriptorNotFoundException(uri.toString());
}
// Retrieve labels
theSQL = new StringBuffer
("select LABEL_ID from VERSION_LABELS where VERSION_ID = ");
theSQL.append(Version_ID);
res = statement.executeQuery(theSQL.toString());
while (res.next()) {
labels.addElement(this.getLabelName(res.getLong("LABEL_ID")));
}
// Retrieve properties
theSQL = new StringBuffer
("select * from PROPERTIES where VERSION_ID = ");
theSQL.append(Version_ID);
res = statement.executeQuery(theSQL.toString());
while (res.next()) {
String propertyName = res.getString("PROPERTY_NAME");
String propertyNamespace = res.getString("PROPERTY_NAMESPACE");
NodeProperty property =
new NodeProperty(propertyName,
res.getString("PROPERTY_VALUE"),
propertyNamespace,
res.getString("PROPERTY_TYPE"),
(res.getInt("IS_PROTECTED") == 1));
properties.put(propertyNamespace + propertyName, property);
}
revisionDescriptor =
new NodeRevisionDescriptor(revisionNumber, branchName,
labels, properties);
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
} finally {
try {
statement.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
}
}
return revisionDescriptor;
}
/**
* Create a new revision descriptor.
*
* @param uri Uri
* @param revisionDescriptor Node revision descriptor
* @exception ServiceAccessException Service access error
*/
public void createRevisionDescriptor
(Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException {
Statement statement = null;
Connection connection = getCurrentConnection();
try {
ResultSet res = null;
long uriid = this.getURIID(uri.toString());
long brid = this.getBranchID(revisionDescriptor.getBranchName());
if (brid == 0 ) {
this.setBranchID(revisionDescriptor.getBranchName());
brid = this.getBranchID(revisionDescriptor.getBranchName());
}
statement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("SELECT 1 FROM VERSION WHERE URI_ID =");
theSQL.append(uriid);
res = statement.executeQuery(theSQL.toString());
if (!res.next()) {
theSQL = new StringBuffer
("insert into VERSION (URI_ID,IS_VERSIONED) values( ");
theSQL.append(uriid).append(", ").append(0).append(")");
statement.execute(theSQL.toString());
}
theSQL = new StringBuffer
("SELECT 1 FROM VERSION_HISTORY WHERE URI_ID =");
theSQL.append(uriid).append(" and BRANCH_ID = ");
theSQL.append(brid).append(" and REVISION_NO = '" );
theSQL.append(revisionDescriptor.getRevisionNumber().toString());
theSQL.append("'");
res = statement.executeQuery(theSQL.toString());
if (!res.next()) {
theSQL = new StringBuffer
("insert into VERSION_HISTORY (URI_ID,BRANCH_ID,");
theSQL.append("REVISION_NO) values(");
theSQL.append(uriid).append(", ").append(brid);
theSQL.append(", '").append
(revisionDescriptor.getRevisionNumber().toString());
theSQL.append("')");
statement.execute(theSQL.toString());
}
long Version_ID = this.getVersionID(uriid,
revisionDescriptor.getBranchName(),
revisionDescriptor.getRevisionNumber().toString());
// Creating revision labels
Enumeration labels = revisionDescriptor.enumerateLabels();
while (labels.hasMoreElements()) {
String sLabel =(String)labels.nextElement();
long label= this.getLabelID(sLabel);
if (label == 0) {
this.setLabelID(sLabel);
label= this.getLabelID(sLabel);
}
theSQL = new StringBuffer("insert into VERSION_LABELS ");
theSQL.append("(VERSION_ID,LABEL_ID) values( ");
theSQL.append(Version_ID).append(", ");
theSQL.append(label).append(")");
statement.execute(theSQL.toString());
}
// Creating associated properties
Enumeration properties = revisionDescriptor.enumerateProperties();
PreparedStatement pstmt = connection.prepareStatement
("insert into PROPERTIES (VERSION_ID,PROPERTY_NAMESPACE,"
+"PROPERTY_NAME,PROPERTY_VALUE,PROPERTY_TYPE,IS_PROTECTED)"
+" values(?,?,?,?,?,? )");
while (properties.hasMoreElements()) {
NodeProperty property =
(NodeProperty) properties.nextElement();
int protectedProperty = 0;
if (property.isProtected()) {
protectedProperty = 1;
}
pstmt.setLong(1,Version_ID);
pstmt.setString(2,property.getNamespace());
pstmt.setString(3,property.getName());
pstmt.setString(4,property.getValue().toString());
pstmt.setString(5,property.getType());
pstmt.setInt(6,protectedProperty);
pstmt.addBatch();
}
pstmt.executeBatch();
pstmt.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
} finally {
try {
statement.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
}
}
}
/**
* Update a revision descriptor.
*
* @param uri Uri
* @param revisionDescriptors Node revision descriptor
* @exception ServiceAccessException Service access error
* @exception RevisionDescriptorNotFoundException Revision descriptor
* was not found
*/
public void storeRevisionDescriptor
(Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
myRevisionDescriptor = revisionDescriptor;
removeRevisionDescriptor(uri, revisionDescriptor.getRevisionNumber());
createRevisionDescriptor(uri, revisionDescriptor);
}
/**
* Remove a revision descriptor.
*
* @param uri Uri
* @param revisionNumber Revision number
* @exception ServiceAccessException Service access error
*/
public void removeRevisionDescriptor(Uri uri,
NodeRevisionNumber revisionNumber)
throws ServiceAccessException {
Statement statement = null;
Connection connection = getCurrentConnection();
try {
statement = connection.createStatement();
long uriid = this.getURIID(uri.toString());
String revisionNumberStr =
(revisionNumber == null) ? "NULL" : revisionNumber.toString();
String branchStr = null;
try {
branchStr = myRevisionDescriptor.getBranchName();
} catch (NullPointerException npex) {
branchStr = "main";
}
long Version_ID =
this.getVersionID(uriid,branchStr,revisionNumberStr);
// Removing revision labels
StringBuffer theSQL = new StringBuffer
("delete from VERSION_LABELS where VERSION_ID= ");
theSQL.append(Version_ID);
statement.execute(theSQL.toString());
// Removing associated properties
theSQL = new StringBuffer
("delete from PROPERTIES where VERSION_ID= ");
theSQL.append(Version_ID);
statement.execute(theSQL.toString());
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
} finally {
try {
statement.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
}
}
}
// ------------------------------------------------------ Protected Methods
/**
* Retrieve the URI ID For the URI.
*/
protected long getURIID(String revisionUri)
throws SQLException {
Long urivalue = (Long)super.uriIdLookup.get(revisionUri);
if (urivalue == null) {
Connection connection = getCurrentConnection();
Statement getStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer("select URI_ID from URI");
theSQL.append(" where URI_STRING = '");
theSQL.append(revisionUri).append("'");
ResultSet rslt = getStatement.executeQuery(theSQL.toString());
if (rslt.next()) {
long uriid = rslt.getLong("URI_ID");
if (super.uriIdLookup.size() == 2000) {
super.uriIdLookup.clear();
super.uriLookup.clear();
}
rslt.close();
super.uriIdLookup.put(revisionUri,new Long(uriid));
super.uriLookup.put(new Long(uriid),revisionUri);
return uriid;
} else {
return 0;
}
} else {
return urivalue.longValue();
}
}
/**
* Retrieve the URI Name.
*/
protected String getURIString(long revisionUriID)
throws SQLException {
Long uri_key = new Long(revisionUriID);
String URI_String = (String)super.uriLookup.get(uri_key);
if (URI_String == null) {
Connection connection = getCurrentConnection();
Statement getStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("select URI_STRING from URI where URI_ID = ");
theSQL.append(revisionUriID);
ResultSet rslt = getStatement.executeQuery(theSQL.toString());
if (rslt.next()) {
URI_String = rslt.getString("URI_STRING");
if (super.uriLookup.size() == 2000) {
super.uriLookup.clear();
super.uriIdLookup.clear();
}
rslt.close();
super.uriLookup.put(uri_key,URI_String);
super.uriIdLookup.put(URI_String,uri_key);
} else {
return null;
}
}
return URI_String;
}
/**
* Add the URI.
*/
protected void setURIID(String revisionUri)
throws SQLException {
if (this.getURIID(revisionUri) == 0 ) {
Connection connection = getCurrentConnection();
Statement addStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("insert into URI (URI_STRING) values ('");
theSQL.append(revisionUri).append("')");
addStatement.execute(theSQL.toString());
addStatement.close();
}
}
/**
* Retrieve the Branch ID For the given Branch.
*/
protected long getBranchID(String branchName)
throws SQLException {
Connection connection = getCurrentConnection();
Statement getStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("select BRANCH_ID from BRANCH where BRANCH_STRING = '");
theSQL.append(branchName).append("'");
ResultSet rslt = getStatement.executeQuery(theSQL.toString());
if (rslt.next()) {
return rslt.getLong("BRANCH_ID");
} else {
return 0;
}
}
/**
* Add the branchname and id
*/
protected void setBranchID(String branchName)
throws SQLException {
if (this.getBranchID(branchName) == 0 ) {
Connection connection = getCurrentConnection();
Statement addStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("insert into BRANCH (BRANCH_STRING) values ('");
theSQL.append(branchName).append("')");
addStatement.execute(theSQL.toString());
addStatement.close();
}
}
/**
* Retrieve the label ID For the labelName.
*/
protected long getLabelID(String labelName)
throws SQLException {
Connection connection = getCurrentConnection();
Statement getStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("select LABEL_ID from LABEL where LABEL_STRING = '");
theSQL.append(labelName).append("'");
ResultSet rslt = getStatement.executeQuery(theSQL.toString());
if (rslt.next()) {
return rslt.getLong("LABEL_ID");
} else {
return 0;
}
}
/**
* Retrieve the label NAME For the labelid.
*/
protected String getLabelName(long labelID)
throws SQLException {
Connection connection = getCurrentConnection();
Statement getStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("select LABEL_STRING from LABEL where LABEL_ID= ");
theSQL.append(labelID);
ResultSet rslt = getStatement.executeQuery(theSQL.toString());
if (rslt.next()) {
return rslt.getString("LABEL_STRING");
} else {
return null;
}
}
/**
* Add the labelName and id
*/
protected void setLabelID(String labelName)
throws SQLException {
if (this.getBranchID(labelName) == 0 ) {
Connection connection = getCurrentConnection();
Statement addStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("insert into LABEL (LABEL_STRING) values ('");
theSQL.append(labelName).append("')");
addStatement.execute(theSQL.toString());
addStatement.close();
}
}
/**
* Filter for all the new children
*/
protected Enumeration getNewChildren( long parent, Enumeration childlist)
throws SQLException {
Hashtable hshtempHash = new Hashtable();
Hashtable hshnewChild = new Hashtable();
Connection connection = getCurrentConnection();
Statement getStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("select URI_STRING FROM URI WHERE URI_ID IN ");
theSQL.append("(SELECT CHILD_URI_ID from CHILDREN where URI_ID = ");
theSQL.append(parent).append(")");
ResultSet rslt = getStatement.executeQuery(theSQL.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(long parent, long child)
throws SQLException {
Connection connection = getCurrentConnection();
Statement getStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("select 1 from LINKS where URI_ID = " );
theSQL.append(parent).append(" and LINK_TO_ID = ").append(child);
ResultSet rslt = getStatement.executeQuery(theSQL.toString());
return rslt.next();
}
/**
* Check if the Lock exist.
*/
protected boolean isLockExist(long parent)
throws SQLException {
Connection connection = getCurrentConnection();
Statement getStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("select 1 from LOCKS where LOCK_ID = " );
theSQL.append(parent);
ResultSet rslt = getStatement.executeQuery(theSQL.toString());
return rslt.next();
}
/**
* Get the VersionID for the current URI
*/
protected long getVersionID(long uri_id,
String branch_name,
String sXNumber)
throws SQLException {
Connection connection = getCurrentConnection();
Statement getStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("select A.VERSION_ID from VERSION_HISTORY A, BRANCH B ");
theSQL.append("where A.URI_ID= " );
theSQL.append(uri_id).append(" and A.BRANCH_ID = B.BRANCH_ID and");
theSQL.append(" B.BRANCH_STRING = '").append(branch_name);
theSQL.append("' and A.REVISION_NO= '").append(sXNumber).append("'");
ResultSet rslt = getStatement.executeQuery(theSQL.toString());
if (rslt.next()) {
return rslt.getLong("VERSION_ID");
} else {
return 0;
}
}
/**
* Get the XNUMBER for the current URI
*/
protected String getXNumber(long version_id,
long uri_id,
String branch_name)
throws SQLException {
Connection connection = getCurrentConnection();
Statement getStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("select A.REVISION_NO from VERSION_HISTORY A, ");
theSQL.append("BRANCH B where A.VERSION_ID = " );
theSQL.append(version_id).append(" and A.URI_ID= ");
theSQL.append(uri_id).append(" and A.BRANCH_ID = B.BRANCH_ID");
theSQL.append(" and B.BRANCH_STRING = '");
theSQL.append(branch_name).append("'");
ResultSet rslt = getStatement.executeQuery(theSQL.toString());
if (rslt.next()) {
return rslt.getString("REVISION_NO");
} else {
return null;
}
}
}
1.1 jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms/StoreContentZip.java
Index: StoreContentZip.java
===================================================================
/*
* $Header: /home/cvspublic/jakarta-slide/src/stores/slidestore/j2ee/J2EEContentStore.java,v 1.0 2002/08/01 00:16:52 akumar Exp $
* $Revision: 1.0 $
* $Date: 2002/08/01 00:16:52 $
*
* ====================================================================
*
* 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.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
/**
* Title: StoreContentZip
*
* This util class can generally be used to zip/unzip an inputstream
* Returns the zip/unzip data as both output/input streams. This is used
* in the J2EEContentStore
* @author <a href="mailto:akumar@metatomix.com">Ashok Kumar</a>
* @version $Revision: 1.0 $
*/
public class StoreContentZip {
protected static final int ZIP_BUFFER = 2048;
private long contentLength = 0;
private OutputStream theOS = null;
/**
* Constructor for StoreContentZip.
*/
public StoreContentZip() {
super();
contentLength = 0;
}
/**
* This method compress the input stream and returns the outputstream
* @param InputStream inIPS
* @exception IOException,ZipException
* @return the compressed OutputStream
*/
public void Zip(InputStream inIPS)
throws IOException, ZipException{
int byteCount = 0;
contentLength = 0;
byte data[] = new byte[ZIP_BUFFER];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zoutp = new ZipOutputStream(baos);
zoutp.putNextEntry(new ZipEntry("zippedfile"));
while((byteCount = inIPS.read(data,0,ZIP_BUFFER)) != -1 ) {
zoutp.write(data,0,byteCount);
}
zoutp.finish();
zoutp.flush();
zoutp.close();
baos.flush();
baos.close();
contentLength = (long)baos.size();
theOS = baos;
}
/**
* This method decompress the input stream and returns the outputstream
* @param InputStream inIPS
* @exception IOException,ZipException
* @return the decompressed OutputStream
*/
public void UnZip(InputStream inIPS)
throws IOException, ZipException{
int byteCount = 0;
contentLength = 0;
byte indata[] = new byte[ZIP_BUFFER];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipInputStream zinp = new ZipInputStream(inIPS);
while (zinp.getNextEntry() != null) {
while ((byteCount = zinp.read(indata,0,ZIP_BUFFER)) != -1 ) {
baos.write(indata,0,byteCount);
}
}
contentLength = (long)baos.size();
baos.flush();
baos.close();
zinp.close();
theOS = baos;
}
/**
* This method returns the compressed/decompressed stream as InputStream
* @param void
* @exception IOException,ZipException
* @return the processed InputStream
*/
public InputStream getInputStream()
throws IOException, ZipException{
return new ByteArrayInputStream(
((ByteArrayOutputStream)theOS).toByteArray());
}
/**
* This method returns the compressed/decompressed stream as O/PStream
* @param void
* @exception IOException,ZipException
* @return the processed InputStream
*/
public OutputStream getOutputStream()
throws IOException, ZipException{
return theOS;
}
/**
* Gets the length.
* @return return the length of the un/compressed Stream
*/
public long getContentLength() {
return contentLength;
}
}
1.1 jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms/J2EEStore.java
Index: J2EEStore.java
===================================================================
/*
* $Header: /home/cvspublic/jakarta-slide/src/stores/slidestore/j2ee/J2EEStore.java,v 1.1 2002/04/11 00:16:52 akumar Exp $
* $Revision: 1.1 $
* $Date: 2002/04/11 00:16:52 $
*
* ====================================================================
*
* 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.sql.SQLException;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import org.apache.slide.common.AbstractXAService;
import org.apache.slide.common.NamespaceAccessToken;
import org.apache.slide.common.ServiceConnectionFailedException;
import org.apache.slide.common.ServiceDisconnectionFailedException;
import org.apache.slide.common.ServiceInitializationFailedException;
import org.apache.slide.common.ServiceParameterErrorException;
import org.apache.slide.common.ServiceParameterMissingException;
import org.apache.slide.common.ServiceResetFailedException;
import org.apache.slide.util.logger.Logger;
/**
* J2EE store implementation - implements the shared parts of
* the two (content, descriptors) J2EE stores for the new Indexed DB Schema.
*
* @author <a href="mailto:msmith@apache.org">Michael Smith</a>
* @author <a href="mailto:akumar@metatomix.com">Ashok Kumar</a>
* @version $Revision: 1.1 $
*/
public abstract class J2EEStore
extends AbstractXAService {
// -------------------------------------------------------------- Constants
public static final int TX_IDLE = 0;
public static final int TX_PREPARED = 1;
public static final int TX_SUSPENDED = 1;
// ----------------------------------------------------- Instance Variables
/**
* Database connection source.
*/
protected DataSource ds;
protected String datasource;
protected Hashtable connectionMap = new Hashtable();
// New DB Schema lookup cache
protected static Hashtable uriIdLookup = new Hashtable(2000); //if u change the numbers change them
protected static Hashtable uriLookup = new Hashtable(2000); //also in J2EE*2.java
/* A connection used when we aren't associated with a transaction correctly. */
protected static Connection globalConnection;
// -------------------------------------------------------- Service Methods
/**
* Initializes the data source with a set of parameters.
*
* @param parameters Hashtable containing the parameters' name
* and associated value
* @exception ServiceParameterErrorException Incorrect service parameter
* @exception ServiceParameterMissingException Service parameter missing
*/
public void setParameters(Hashtable parameters)
throws ServiceParameterErrorException,
ServiceParameterMissingException {
// Get the datsource lookup name
datasource = (String) parameters.get("datasource");
}
/**
* Connects to JDBC and creates the basic table structure.
*
* @exception ServiceConnectionFailedException Connection to the
* database failed
*/
public synchronized void connect()
throws ServiceConnectionFailedException {
getLogger().log("Trying connect to database", LOG_CHANNEL,
Logger.DEBUG);
try {
globalConnection = ds.getConnection();
} catch(SQLException e) {
getLogger().log("Couldn't get global transaction.", LOG_CHANNEL,
Logger.ERROR);
}
getLogger().log("Done connecting to database. globalConnection is "+
globalConnection, LOG_CHANNEL, Logger.DEBUG);
}
/**
* Returns connection status
*/
public boolean isConnected() {
try {
return ds!=null && globalConnection != null && !globalConnection.isClosed();
} catch(SQLException e) {
return false;
}
}
/**
* Disconnects from data source.
*
* @exception ServiceDisconnectionFailedException Disconnection
* from database failed
*/
public void disconnect()
throws ServiceDisconnectionFailedException {
// This doesn't need to do anything any more.
try {
globalConnection.close();
} catch(SQLException e) {
getLogger().log("Failed to close special global connection: "+
e.getMessage(), LOG_CHANNEL, Logger.ERROR);
}
}
/**
* Initializes data source.
* <p/>
* Occurs in two steps :
* <li>Datasource is looked up from the pool</li>
* <li>Creation of the basic tables, if they didn't exist before</li>
*
* @exception ServiceInitializationFailedException Throws an exception
* if the data source has already been initialized before
*/
public synchronized void initialize(NamespaceAccessToken token)
throws ServiceInitializationFailedException {
try {
// Loading and registering driver
token.getLogger().log("Loading and registering datasource " + datasource ,LOG_CHANNEL,Logger.INFO);
// Initialize database
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
ds = (DataSource) envCtx.lookup(datasource);
} catch (ClassCastException e) {
token.getLogger().log("Loading and registering datasource " + datasource + " failed",LOG_CHANNEL,Logger.ERROR);
token.getLogger().log(e.toString(),LOG_CHANNEL,Logger.ERROR);
throw new ServiceInitializationFailedException(this, e.getMessage());
} catch (NamingException e) {
token.getLogger().log("Loading and registering datasource " + datasource + " failed",LOG_CHANNEL,Logger.ERROR);
token.getLogger().log(e.toString(),LOG_CHANNEL,Logger.ERROR);
throw new ServiceInitializationFailedException(this, e.getMessage());
} catch (Exception e) {
token.getLogger().log("Loading and registering datasource " + datasource+ " failed",LOG_CHANNEL,Logger.ERROR);
token.getLogger().log(e.toString(),LOG_CHANNEL,Logger.ERROR);
throw new ServiceInitializationFailedException(this, e.getMessage());
}
if(ds == null) {
token.getLogger().log("Datasource is null, can't initialise store");
throw new ServiceInitializationFailedException(this, "Null datasource from context");
}
}
/**
* Deletes data source. Should remove stored data if possible.
*
* @exception ServiceResetFailedException Reset failed
*/
public synchronized void reset()
throws ServiceResetFailedException {
}
// ----------------------------------------------------- XAResource Methods
/**
* Get the transaction timeout value for this XAResource.
* Just returns 0, we don't have a way of doing transaction timeouts
* with the connection.
*/
public int getTransactionTimeout() throws XAException {
return 0;
}
/**
* Set transaction timeout, not implemented (returns false).
*/
public boolean setTransactionTimeout(int timeout) throws XAException {
return false;
}
public Xid[] recover(int flag)
throws XAException {
getLogger().log("recover() for thread: "+Thread.currentThread(), LOG_CHANNEL, Logger.DEBUG);
TransactionId id = (TransactionId)connectionMap.get(
Thread.currentThread());
if(id != null && id.status == TX_PREPARED) {
Xid[] xids = new Xid[1];
xids[0] = id.xid;
return xids;
}
else
return new Xid[0];
}
public int prepare(Xid xid)
throws XAException {
getLogger().log("prepare() for thread: "+Thread.currentThread(), LOG_CHANNEL, Logger.DEBUG);
TransactionId id = (TransactionId)connectionMap.get(
Thread.currentThread());
if(id == null)
throw new XAException(XAException.XAER_NOTA);
if(xid == null)
throw new XAException(XAException.XAER_INVAL);
if(id.status != TX_IDLE && id.status != TX_SUSPENDED)
throw new XAException(XAException.XAER_PROTO);
if(id.rollbackOnly)
throw new XAException(XAException.XA_RBROLLBACK);
id.status = TX_PREPARED;
return XAResource.XA_OK;
}
public boolean isSameRM(XAResource xares) throws XAException {
if(xares == null)
return false;
else
return this == xares;
}
public void forget(Xid xid) throws XAException {
getLogger().log("forget() for thread: "+Thread.currentThread(), LOG_CHANNEL, Logger.DEBUG);
TransactionId id = (TransactionId)connectionMap.get(
Thread.currentThread());
if(id == null || id.xid == null)
throw new XAException(XAException.XAER_NOTA);
if(xid == null)
throw new XAException(XAException.XAER_INVAL);
try {
id.connection.close();
} catch(SQLException e) {
getLogger().log("Couldn't close connection.", LOG_CHANNEL, Logger.ERROR);
}
getLogger().log("forget(): removing from map: "+Thread.currentThread(), LOG_CHANNEL, Logger.DEBUG);
connectionMap.remove(Thread.currentThread());
}
public void end(Xid xid, int flags) throws XAException {
getLogger().log("end() for thread: "+Thread.currentThread(), LOG_CHANNEL, Logger.DEBUG);
TransactionId id = (TransactionId)connectionMap.get(Thread.currentThread());
if(id == null || id.xid == null)
throw new XAException(XAException.XAER_NOTA);
if(xid == null)
throw new XAException(XAException.XAER_INVAL);
if(flags == XAResource.TMSUSPEND)
id.status = TX_SUSPENDED;
if(flags == XAResource.TMFAIL)
id.rollbackOnly = true;
}
/**
* Commit the global transaction specified by xid.
*/
public void commit(Xid xid, boolean onePhase)
throws XAException {
getLogger().log("commit() for thread "+Thread.currentThread()+", removing from map",
LOG_CHANNEL, Logger.DEBUG);
TransactionId id = (TransactionId)connectionMap.remove(
Thread.currentThread());
if(id == null) {
getLogger().log("Error committing: no transaction associated with current thread", LOG_CHANNEL, Logger.ERROR);
throw new XAException(XAException.XAER_NOTA);
}
if(xid == null)
throw new XAException(XAException.XAER_INVAL);
if(!onePhase && id.status != TX_PREPARED)
throw new XAException(XAException.XAER_PROTO);
if(onePhase && (!(id.status == TX_IDLE || id.status == TX_SUSPENDED)))
throw new XAException(XAException.XAER_PROTO);
Connection conn = id.connection;
if(conn == null) {
getLogger().log("commit(): No connection in connectionMap for id \""+id+"\"", LOG_CHANNEL, Logger.ERROR);
throw new XAException(XAException.XAER_NOTA);
}
// Not neeeded as transactional
/* try {
if(id.rollbackOnly)
conn.rollback();
else
conn.commit();
} catch(Exception e) {
throw new XAException(XAException.XA_RBCOMMFAIL);
} finally {
*/ try {
conn.close(); /* We must always return connections to the pool,
or we'd eventually run out. */
} catch(SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
}
// }
}
/**
* Inform the resource manager to roll back work done on behalf of a
* transaction branch.
*/
public void rollback(Xid xid)
throws XAException {
getLogger().log("rollback() for thread "+Thread.currentThread()+", removing from map",
LOG_CHANNEL, Logger.DEBUG);
TransactionId id = (TransactionId)connectionMap.remove(
Thread.currentThread());
if(id == null) {
getLogger().log("No transaction associated with current thread, can't rollback", LOG_CHANNEL, Logger.ERROR);
throw new XAException(XAException.XAER_NOTA);
}
Connection conn = id.connection;
if(conn == null) {
getLogger().log("rollback(): No connection in connectionMap for id \""+id+"\"", LOG_CHANNEL, Logger.ERROR);
throw new XAException(XAException.XAER_NOTA);
}
// Not neeeded as transactional
/* try {
//conn.rollback();
} catch (SQLException e) {
throw new XAException(XAException.XA_HEURCOM);
} finally {
*/ try {
conn.close(); /* We must always return connections to the pool,
or we'd eventually run out. */
} catch(SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
}
// }
}
/**
* Start work on behalf of a transaction branch specified in xid.
*/
public void start(Xid xid, int flags)
throws XAException {
getLogger().log("start(): beginning transaction with xid "+xid, LOG_CHANNEL, Logger.DEBUG);
TransactionId id = (TransactionId)connectionMap.get(Thread.currentThread());
switch(flags) {
case XAResource.TMNOFLAGS:
if(id != null)
throw new XAException(XAException.XAER_INVAL);
id = new TransactionId(xid, TX_IDLE);
getLogger().log("start(): adding to map for "+Thread.currentThread(),
LOG_CHANNEL, Logger.DEBUG);
connectionMap.put(Thread.currentThread(), id);
break;
case XAResource.TMJOIN:
getLogger().log("TMJOIN for transaction in thread: "+Thread.currentThread(), LOG_CHANNEL, Logger.DEBUG);
if(id == null)
throw new XAException(XAException.XAER_NOTA);
break;
case XAResource.TMRESUME:
getLogger().log("TMRESUME for transaction in thread: "+Thread.currentThread(), LOG_CHANNEL, Logger.DEBUG);
if(id == null)
throw new XAException(XAException.XAER_NOTA);
if(id.status != TX_SUSPENDED)
throw new XAException(XAException.XAER_INVAL);
id.status = TX_IDLE;
break;
}
}
// ------------------------------------------------------ Protected Methods
/**
* Get the Connection object associated with the current transaction.
*/
protected Connection getCurrentConnection() {
getLogger().log("Getting current connection for thread "+
Thread.currentThread(), LOG_CHANNEL, Logger.DEBUG);
TransactionId id = (TransactionId)connectionMap.get(Thread.currentThread());
if(id == null) {
getLogger().log("No id for current thread - called outside transaction?", LOG_CHANNEL, Logger.DEBUG);
return globalConnection;
}
Connection conn = id.connection;
if(conn == null) {
getLogger().log("No connection for current id - shouldn't be possible", LOG_CHANNEL, Logger.ERROR);
return globalConnection;
}
getLogger().log("Returning current valid connection from map", LOG_CHANNEL, Logger.DEBUG);
return conn;
}
protected class TransactionId // made to static protected
{
public Xid xid;
public int status;
public boolean rollbackOnly;
Connection connection;
public TransactionId(Xid xid, int status) {
this.xid = xid;
this.status = status;
rollbackOnly = false;
/* Now, fetch a connection from the DataSource */
try {
connection = ds.getConnection();
if(connection == null) {
// System.out.println("CONNDEBUG: Got null connection from datasource");
connection = globalConnection;
return;
}
if (connection.getAutoCommit()) {
connection.setAutoCommit(false);
}
} catch(SQLException e) {
System.out.println("CONNDEBUG: Couldn't get connection: "+e.getMessage());
connection = globalConnection;
e.printStackTrace();
}
}
}
}
1.1 jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms/HSQLDBSchema.sql
Index: HSQLDBSchema.sql
===================================================================
/**********************************************************************/
/****** CREATE SLIDE TABLES FOR HYPERSONIC DB ******/
/**********************************************************************/
CREATE TABLE URI (
URI_ID INT NOT NULL IDENTITY PRIMARY KEY,
URI_STRING varchar(800) NOT NULL,
UNIQUE (URI_ID)
);
CREATE TABLE OBJECT (
URI_ID INT PRIMARY KEY,
CLASS_NAME varchar(255) NOT NULL,
CONSTRAINT FK_OBJECT_URI_ID
FOREIGN KEY (URI_ID)
REFERENCES URI (URI_ID)
);
CREATE TABLE CHILDREN (
URI_ID BIGINT NOT NULL,
CHILD_URI_ID BIGINT NOT NULL,
CONSTRAINT FK_CHILD_URI_ID
FOREIGN KEY (URI_ID) REFERENCES URI (URI_ID),
FOREIGN KEY (CHILD_URI_ID) REFERENCES URI (URI_ID),
UNIQUE (URI_ID, CHILD_URI_ID)
);
CREATE TABLE LINKS (
URI_ID bigint NOT NULL,
LINK_TO_ID bigint NOT NULL,
CONSTRAINT FK_URI_ID
FOREIGN KEY (URI_ID) REFERENCES URI (URI_ID),
FOREIGN KEY (LINK_TO_ID) REFERENCES URI (URI_ID),
UNIQUE (URI_ID, LINK_TO_ID)
);
CREATE TABLE LOCKS (
LOCK_ID bigint PRIMARY KEY,
OBJECT_ID bigint NOT NULL,
SUBJECT_ID bigint NOT NULL,
TYPE_ID bigint NOT NULL,
EXPIRATION_DATE numeric(14, 0) NOT NULL,
IS_INHERITABLE bit NOT NULL,
IS_EXCLUSIVE bit NOT NULL,
CONSTRAINT FK_LOCKS_LOCK_ID
FOREIGN KEY (LOCK_ID) REFERENCES URI (URI_ID),
FOREIGN KEY (OBJECT_ID) REFERENCES URI (URI_ID),
FOREIGN KEY (SUBJECT_ID) REFERENCES URI (URI_ID),
FOREIGN KEY (TYPE_ID) REFERENCES URI (URI_ID)
);
CREATE TABLE BRANCH (
BRANCH_ID int NOT NULL IDENTITY PRIMARY KEY,
BRANCH_STRING varchar(255) NOT NULL,
UNIQUE (BRANCH_ID)
);
CREATE TABLE LABEL (
LABEL_ID int NOT NULL IDENTITY PRIMARY KEY,
LABEL_STRING varchar(255) NOT NULL,
UNIQUE (LABEL_ID)
);
CREATE TABLE VERSION (
URI_ID bigint PRIMARY KEY,
IS_VERSIONED bit NOT NULL,
CONSTRAINT FK_VERSION_URI_ID
FOREIGN KEY (URI_ID)
REFERENCES URI (URI_ID)
);
CREATE TABLE VERSION_HISTORY (
VERSION_ID int IDENTITY PRIMARY KEY,
URI_ID bigint NOT NULL,
BRANCH_ID bigint NOT NULL,
REVISION_NO VARCHAR(20) NOT NULL,
CONSTRAINT FK_VERSION_ID
FOREIGN KEY (URI_ID) REFERENCES VERSION (URI_ID),
FOREIGN KEY (BRANCH_ID) REFERENCES BRANCH (BRANCH_ID),
UNIQUE (URI_ID, BRANCH_ID, REVISION_NO)
);
CREATE TABLE VERSION_PREDS (
VERSION_ID bigint NOT NULL,
PREDECESSOR_ID bigint NOT NULL,
CONSTRAINT FK_VERSION_ID
FOREIGN KEY (VERSION_ID) REFERENCES VERSION_HISTORY (VERSION_ID),
FOREIGN KEY (PREDECESSOR_ID) REFERENCES VERSION_HISTORY (VERSION_ID),
UNIQUE (VERSION_ID, PREDECESSOR_ID)
);
CREATE TABLE VERSION_LABELS (
VERSION_ID bigint NOT NULL,
LABEL_ID bigint NOT NULL,
CONSTRAINT FK_VERSION_ID
FOREIGN KEY (VERSION_ID) REFERENCES VERSION_HISTORY (VERSION_ID),
FOREIGN KEY (LABEL_ID) REFERENCES LABEL (LABEL_ID),
UNIQUE (VERSION_ID, LABEL_ID)
);
CREATE TABLE VERSION_CONTENT (
VERSION_ID bigint PRIMARY KEY,
CONTENT longvarbinary NOT NULL,
CONSTRAINT FK_VC_VERSION_ID
FOREIGN KEY (VERSION_ID)
REFERENCES VERSION_HISTORY (VERSION_ID)
);
CREATE TABLE PROPERTIES (
VERSION_ID bigint NOT NULL,
PROPERTY_NAMESPACE varchar(50) NOT NULL,
PROPERTY_NAME varchar(50) NOT NULL,
PROPERTY_VALUE varchar(255) NOT NULL,
PROPERTY_TYPE varchar(50) NOT NULL,
IS_PROTECTED bit NOT NULL,
CONSTRAINT FK_VC_VERSION_ID
FOREIGN KEY (VERSION_ID)
REFERENCES VERSION_HISTORY (VERSION_ID),
UNIQUE (VERSION_ID, PROPERTY_NAMESPACE, PROPERTY_NAME)
);
CREATE TABLE PERMISSIONS (
OBJECT_ID bigint NOT NULL,
SUBJECT_ID bigint NOT NULL,
ACTION_ID bigint NOT NULL,
VERSION_NO VARCHAR(20),
IS_INHERITABLE bit NOT NULL,
IS_NEGATIVE bit NOT NULL,
CONSTRAINT FK_VC_VERSION_ID
FOREIGN KEY (OBJECT_ID) REFERENCES URI (URI_ID),
FOREIGN KEY (SUBJECT_ID) REFERENCES URI (URI_ID),
FOREIGN KEY (ACTION_ID) REFERENCES URI (URI_ID),
UNIQUE (OBJECT_ID, SUBJECT_ID, ACTION_ID)
);
1.1 jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms/SQLServerSchema.sql
Index: SQLServerSchema.sql
===================================================================
/**********************************************************************/
/****** NEW SLIDE DATABASE SCHEMA Date: 8/02/02 ******/
/**********************************************************************/
/**********************************************************************/
/****** DROP SLIDE TABLES ******/
/**********************************************************************/
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[OBJECT]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
DROP TABLE [dbo].[OBJECT]
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[CHILDREN]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
DROP TABLE [dbo].[CHILDREN]
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[LINKS]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
DROP TABLE [dbo].[LINKS]
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[LOCKS]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
DROP TABLE [dbo].[LOCKS]
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[VERSION_CONTENT]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
DROP TABLE [dbo].[VERSION_CONTENT]
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[PROPERTIES]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
DROP TABLE [dbo].[PROPERTIES]
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[PERMISSIONS]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
DROP TABLE [dbo].[PERMISSIONS]
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[VERSION_PREDS]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
DROP TABLE [dbo].[VERSION_PREDS]
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[VERSION_LABELS]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
DROP TABLE [dbo].[VERSION_LABELS]
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[VERSION_HISTORY]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
DROP TABLE [dbo].[VERSION_HISTORY]
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[VERSION]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
DROP TABLE [dbo].[VERSION]
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[BRANCH]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
DROP TABLE [dbo].[BRANCH]
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[LABEL]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
DROP TABLE [dbo].[LABEL]
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[URI]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
DROP TABLE [dbo].[URI]
GO
/**********************************************************************/
/****** DROP EXISTING USER DEFINED DATA TYPES ******/
/**********************************************************************/
sp_droptype id_type
GO
sp_droptype uri_str_type
GO
/**********************************************************************/
/****** ADD USER DEFINED DATA TYPES ******/
/**********************************************************************/
sp_addtype id_type, bigint
GO
sp_addtype uri_str_type, "varchar(800)"
GO
/***********************************************/
/** Sybase **/
/***********************************************/
/** sp_addtype id_type, "numeric(18,0)" **/
/** GO **/
/** sp_addtype uri_str_type, "varchar(255)" **/
/** GO **/
/***********************************************/
/**********************************************************************/
/****** CREATE SLIDE TABLES ******/
/**********************************************************************/
CREATE TABLE URI (
URI_ID id_type IDENTITY UNIQUE NOT NULL,
URI_STRING uri_str_type NOT NULL,
UNIQUE NONCLUSTERED (URI_ID)
)
GO
CREATE TABLE OBJECT (
URI_ID id_type PRIMARY KEY,
CLASS_NAME varchar(255) NOT NULL,
CONSTRAINT FK_OBJECT_URI_ID
FOREIGN KEY (URI_ID)
REFERENCES URI (URI_ID)
)
GO
CREATE TABLE CHILDREN (
URI_ID id_type NOT NULL FOREIGN KEY
REFERENCES URI (URI_ID),
CHILD_URI_ID id_type NOT NULL FOREIGN KEY
REFERENCES URI (URI_ID),
UNIQUE CLUSTERED (URI_ID, CHILD_URI_ID)
)
GO
CREATE TABLE LINKS (
URI_ID id_type NOT NULL FOREIGN KEY
REFERENCES URI (URI_ID),
LINK_TO_ID id_type NOT NULL FOREIGN KEY
REFERENCES URI (URI_ID),
UNIQUE CLUSTERED (URI_ID, LINK_TO_ID)
)
GO
CREATE TABLE LOCKS (
LOCK_ID id_type PRIMARY KEY,
OBJECT_ID id_type NOT NULL FOREIGN KEY
REFERENCES URI (URI_ID),
SUBJECT_ID id_type NOT NULL FOREIGN KEY
REFERENCES URI (URI_ID),
TYPE_ID id_type NOT NULL FOREIGN KEY
REFERENCES URI (URI_ID),
EXPIRATION_DATE numeric(14, 0) NOT NULL,
IS_INHERITABLE bit NOT NULL,
IS_EXCLUSIVE bit NOT NULL,
CONSTRAINT FK_LOCKS_LOCK_ID
FOREIGN KEY (LOCK_ID)
REFERENCES URI (URI_ID)
)
GO
CREATE TABLE BRANCH (
BRANCH_ID id_type IDENTITY UNIQUE NOT NULL,
BRANCH_STRING varchar(255) NOT NULL,
UNIQUE NONCLUSTERED (BRANCH_ID)
)
GO
CREATE TABLE LABEL (
LABEL_ID id_type IDENTITY UNIQUE NOT NULL,
LABEL_STRING varchar(255) NOT NULL,
UNIQUE NONCLUSTERED (LABEL_ID)
)
GO
CREATE TABLE VERSION (
URI_ID id_type PRIMARY KEY,
IS_VERSIONED bit NOT NULL,
CONSTRAINT FK_VERSION_URI_ID
FOREIGN KEY (URI_ID)
REFERENCES URI (URI_ID)
)
GO
CREATE TABLE VERSION_HISTORY (
VERSION_ID id_type IDENTITY UNIQUE NOT NULL,
URI_ID id_type NOT NULL FOREIGN KEY
REFERENCES VERSION (URI_ID),
BRANCH_ID id_type NOT NULL FOREIGN KEY
REFERENCES BRANCH (BRANCH_ID),
REVISION_NO VARCHAR(20) NOT NULL,
UNIQUE NONCLUSTERED (URI_ID, BRANCH_ID, REVISION_NO)
)
GO
CREATE TABLE VERSION_PREDS (
VERSION_ID id_type NOT NULL FOREIGN KEY
REFERENCES VERSION_HISTORY (VERSION_ID),
PREDECESSOR_ID id_type NOT NULL FOREIGN KEY
REFERENCES VERSION_HISTORY (VERSION_ID),
UNIQUE CLUSTERED (VERSION_ID, PREDECESSOR_ID)
)
GO
CREATE TABLE VERSION_LABELS (
VERSION_ID id_type NOT NULL FOREIGN KEY
REFERENCES VERSION_HISTORY (VERSION_ID),
LABEL_ID id_type NOT NULL FOREIGN KEY
REFERENCES LABEL (LABEL_ID),
UNIQUE CLUSTERED (VERSION_ID, LABEL_ID)
)
GO
CREATE TABLE VERSION_CONTENT (
VERSION_ID id_type PRIMARY KEY,
CONTENT image NOT NULL,
CONSTRAINT FK_VC_VERSION_ID
FOREIGN KEY (VERSION_ID)
REFERENCES VERSION_HISTORY (VERSION_ID),
)
GO
CREATE TABLE PROPERTIES (
VERSION_ID id_type NOT NULL FOREIGN KEY
REFERENCES VERSION_HISTORY (VERSION_ID),
PROPERTY_NAMESPACE varchar(50) NOT NULL,
PROPERTY_NAME varchar(50) NOT NULL,
PROPERTY_VALUE varchar(255) NOT NULL,
PROPERTY_TYPE varchar(50) NOT NULL,
IS_PROTECTED bit NOT NULL,
UNIQUE CLUSTERED (VERSION_ID, PROPERTY_NAMESPACE, PROPERTY_NAME)
)
GO
CREATE TABLE PERMISSIONS (
OBJECT_ID id_type NOT NULL FOREIGN KEY
REFERENCES URI (URI_ID),
SUBJECT_ID id_type NOT NULL FOREIGN KEY
REFERENCES URI (URI_ID),
ACTION_ID id_type NOT NULL FOREIGN KEY
REFERENCES URI (URI_ID),
VERSION_NO VARCHAR(20),
IS_INHERITABLE bit NOT NULL,
IS_NEGATIVE bit NOT NULL,
UNIQUE CLUSTERED (OBJECT_ID, SUBJECT_ID, ACTION_ID)
)
GO
1.1 jakarta-slide/src/stores/org/apache/slide/store/impl/rdbms/J2EEContentStore.java
Index: J2EEContentStore.java
===================================================================
/*
* $Header: /home/cvspublic/jakarta-slide/src/stores/slidestore/j2ee/J2EEContentStore.java,v 1.0 2002/08/01 00:16:52 akumar Exp $
* $Revision: 1.0 $
* $Date: 2002/08/01 00:16:52 $
*
* ====================================================================
*
* 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.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Hashtable;
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.ServiceParameterErrorException;
import org.apache.slide.common.ServiceParameterMissingException;
import org.apache.slide.common.Uri;
import org.apache.slide.content.NodeRevisionContent;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.RevisionAlreadyExistException;
import org.apache.slide.content.RevisionNotFoundException;
import org.apache.slide.store.ContentStore;
import org.apache.slide.util.logger.Logger;
import slidestore.reference.util.JDBCAwareInputStream;
/**
* J2EE 2.0 compliant implementation of ContentStore for the new Indexed DB Schema.
*
* @author <a href="mailto:akumar@metatomix.com">Ashok Kumar</a>
* @version $Revision: 1.0 $
*/
public class J2EEContentStore extends J2EEStore
implements ContentStore {
// -------------------------------------------------------------- Constants
private boolean bcompress = false;
public static final int BUFFER_SIZE = 2048;
/** @deprecated */ // FIXME: remove this
public static final String CHARACTER_ENCODING = "8859_1";
// --------------------------------------------------- ContentStore Methods
//Overidden method with a call to the parent method.
//Added behaviour for passing additional parameters.
public synchronized void setParameters(Hashtable parameters)
throws ServiceParameterErrorException,
ServiceParameterMissingException {
try {
bcompress = (((String)parameters.get("compress")
).equals("true"))? true:false;
super.setParameters(parameters);
}catch (Exception e){
getLogger().log(e.toString(),LOG_CHANNEL,Logger.ERROR);
}
}
/**
* Retrive revision content.
*
* @param uri Uri
* @param revisionNumber Node revision number
*/
public NodeRevisionContent retrieveRevisionContent
(Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException, RevisionNotFoundException {
Connection connection = getCurrentConnection();
NodeRevisionContent result = null;
String revisionUri = uri.toString();
String revisionNumber =
(revisionDescriptor.getRevisionNumber() == null)
? "NULL" : revisionDescriptor.getRevisionNumber().toString();
Statement selectStatement=null;
try {
long versionid = this.getVersionID(
this.getURIID(revisionUri),
revisionDescriptor.getBranchName(),
revisionNumber);
selectStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("select CONTENT from VERSION_CONTENT where VERSION_ID = ");
theSQL.append(versionid);
ResultSet rs = selectStatement.executeQuery(theSQL.toString());
if (!rs.next()) {
rs.close();
selectStatement.close();
throw new RevisionNotFoundException
(uri.toString(),
revisionDescriptor.getRevisionNumber());
}
InputStream is = rs.getBinaryStream("CONTENT");
if (is == null) {
rs.close();
selectStatement.close();
throw new RevisionNotFoundException
(uri.toString(),
revisionDescriptor.getRevisionNumber());
}
// Uncompress the retrieved data.
result = new NodeRevisionContent();
if (bcompress) {
getLogger().log
("DeCompressing the data",LOG_CHANNEL,Logger.INFO);
StoreContentZip ziputil = new StoreContentZip();
ziputil.UnZip(is);
revisionDescriptor.setContentLength(ziputil.getContentLength());
is = ziputil.getInputStream();
}
result.setContent(is);
// this input stream passes on the closure of itself onto the
// jdbc statement and resultSet
result.setContent( new JDBCAwareInputStream(is,selectStatement) );
selectStatement.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e.getMessage());
} catch (RevisionNotFoundException e) {
getLogger().log("RevisionNotFoundException encountered for " +
revisionUri + " revision " + revisionNumber,
LOG_CHANNEL,Logger.WARNING);
throw e; // we do NOT want this caught by next clause.
} catch (Exception e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e.getMessage());
}
return result;
}
/**
* Create a new revision
*
* @param uri Uri
* @param revisionDescriptor Node revision descriptor
* @param revisionContent Node revision content
*/
public void createRevisionContent
(Uri uri, NodeRevisionDescriptor revisionDescriptor,
NodeRevisionContent revisionContent)
throws ServiceAccessException, RevisionAlreadyExistException {
Connection connection = getCurrentConnection();
String revisionUri = uri.toString();
String revisionNumber =
revisionDescriptor.getRevisionNumber().toString();
long contentLength = revisionDescriptor.getContentLength();
Statement selectStatement = null;
try {
long versionid = this.getVersionID(
this.getURIID(revisionUri),
revisionDescriptor.getBranchName(),
revisionNumber);
selectStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("select 1 from VERSION_CONTENT where VERSION_ID = ");
theSQL.append(versionid);
ResultSet rs = selectStatement.executeQuery(theSQL.toString());
if (rs.next()) {
rs.close();
throw new RevisionAlreadyExistException
(uri.toString(),
revisionDescriptor.getRevisionNumber());
}
rs.close();
storeContent(revisionUri, revisionNumber, revisionDescriptor,
revisionContent);
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e.getMessage());
} catch (IOException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e.getMessage());
} catch(RevisionAlreadyExistException e) {
getLogger().log("RevisionAlreadyExistException encountered for " +
revisionUri + " revision " + revisionNumber,
LOG_CHANNEL,Logger.WARNING);
throw e;
} catch (Exception e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e.getMessage());
} finally {
try {
selectStatement.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
}
}
}
/**
* Modify the latest revision of an object.
*
* @param uri Uri
* @param revisionDescriptor Node revision descriptor
* @param revisionContent Node revision content
*/
public void storeRevisionContent
(Uri uri, NodeRevisionDescriptor revisionDescriptor,
NodeRevisionContent revisionContent)
throws ServiceAccessException, RevisionNotFoundException {
Connection connection = getCurrentConnection();
String revisionUri = uri.toString();
String revisionNumber =
revisionDescriptor.getRevisionNumber().toString();
Statement selectStatement = null;
try {
long versionid = this.getVersionID(
this.getURIID(revisionUri),
revisionDescriptor.getBranchName(),
revisionNumber);
selectStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("select 1 from VERSION_CONTENT where VERSION_ID = ");
theSQL.append(versionid);
ResultSet rs = selectStatement.executeQuery(theSQL.toString());
if (!rs.next()) {
rs.close();
throw new RevisionNotFoundException
(uri.toString(),
revisionDescriptor.getRevisionNumber());
}
rs.close();
removeRevisionContent(uri, revisionDescriptor);
storeContent(revisionUri, revisionNumber, revisionDescriptor,
revisionContent);
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e.getMessage());
} catch (IOException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e.getMessage());
} catch(RevisionNotFoundException e) {
getLogger().log("RevisionNotFoundException encountered for "+
revisionUri + " revision " + revisionNumber,
LOG_CHANNEL,Logger.WARNING);
throw e;
} catch (Exception e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e.getMessage());
} finally {
try {
selectStatement.close();
} catch (SQLException e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e);
}
}
}
/**
* Remove revision.
*
* @param uri Uri
* @param revisionNumber Node revision number
*/
public void removeRevisionContent
(Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException {
String revisionUri = uri.toString();
String revisionNumber =
revisionDescriptor.getRevisionNumber().toString();
try {
long versionid = this.getVersionID(
this.getURIID(revisionUri),
revisionDescriptor.getBranchName(),
revisionNumber);
removeContent(versionid);
} catch (Exception e) {
getLogger().log(e,LOG_CHANNEL,Logger.ERROR);
throw new ServiceAccessException(this, e.getMessage());
}
}
// ------------------------------------------------------ Protected Methods
/**
* Store a revision.
*/
protected void storeContent(String revisionUri, String revisionNumber,
NodeRevisionDescriptor revisionDescriptor,
NodeRevisionContent revisionContent)
throws IOException, SQLException {
Connection connection = getCurrentConnection();
long versionid = this.getVersionID(
this.getURIID(revisionUri),
revisionDescriptor.getBranchName(),
revisionNumber);
if (versionid == 0 ) {
this.setVersionID(
this.getURIID(revisionUri),
this.getBranchID(revisionDescriptor.getBranchName()),
revisionNumber);
versionid = this.getVersionID(
this.getURIID(revisionUri),
revisionDescriptor.getBranchName(),
revisionNumber);
}
PreparedStatement insertStatement = connection.prepareStatement
("insert into VERSION_CONTENT values(?, ?)");
insertStatement.setLong(1, versionid);
InputStream is = revisionContent.streamContent();
if (is != null) {
// Compress the recieved data.
long contentLength = 0;
if (bcompress) {
getLogger().log("Compressing the data",LOG_CHANNEL,Logger.INFO);
StoreContentZip ziputil = new StoreContentZip();
ziputil.Zip(is);
is = ziputil.getInputStream();
contentLength = ziputil.getContentLength();
} else {
contentLength = revisionDescriptor.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.
try {
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 = is.read(buffer);
if (nChar == -1) {
break;
}
fos.write(buffer, 0, nChar);
position = position + nChar;
}
fos.close();
is = new FileInputStream(tempFile);
contentLength = tempFile.length();
}
catch (IOException ex) {
getLogger().log
(ex.toString()
+ " during the calculation of the content length.",
LOG_CHANNEL,Logger.ERROR);
getLogger().log
("tempFileName: "
+ tempFileName,
LOG_CHANNEL,Logger.ERROR);
getLogger().log
("tempFile: "
+ tempFile.getAbsolutePath(),
LOG_CHANNEL,Logger.ERROR);
throw ex;
}
}
// FIXME ? Cast from long to int won't allow files > 4GB.
//ORIGINAL SLIDE COMMENT
insertStatement.setBinaryStream(2, is, (int) contentLength - 1);
insertStatement.executeUpdate();
revisionDescriptor.setContentLength(contentLength);
if (tempFile != null) {
is.close();
tempFile.delete();
}
}
insertStatement.close();
}
/**
* Remove content.
*/
protected void removeContent(long version_id)
throws SQLException {
Connection connection = getCurrentConnection();
Statement deleteStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("delete from VERSION_CONTENT where VERSION_ID = ");
theSQL.append(version_id);
deleteStatement.execute(theSQL.toString());
deleteStatement.close();
}
/**
* Retrieve the URI ID For the URI.
*/
protected long getURIID(String revisionUri)
throws SQLException {
Long urivalue = (Long)super.uriIdLookup.get(revisionUri);
if (urivalue == null) {
Connection connection = getCurrentConnection();
Statement getStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("select URI_ID from URI where URI_STRING = '");
theSQL.append(revisionUri).append("'");
ResultSet rslt = getStatement.executeQuery(theSQL.toString());
if (rslt.next()) {
long uriid = rslt.getLong("URI_ID");
// A limit predecided wrt J2EEStore hashmap based cache
if (super.uriIdLookup.size() == 2000) {
super.uriIdLookup.clear();
super.uriLookup.clear();
}
rslt.close();
super.uriIdLookup.put(revisionUri,new Long(uriid));
super.uriLookup.put(new Long(uriid),revisionUri);
return uriid;
} else {
return 0;
}
} else {
return urivalue.longValue();
}
}
/**
* Get the VersionID for the current URI
*/
protected long getVersionID(long uri_id, String branch_name, String sXNumber)
throws SQLException {
Connection connection = getCurrentConnection();
Statement getStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("select A.VERSION_ID from VERSION_HISTORY A, BRANCH B ");
theSQL.append("where A.URI_ID= ");
theSQL.append(uri_id).append
(" and A.BRANCH_ID = B.BRANCH_ID and B.BRANCH_STRING = '")
.append(branch_name).append("' and A.REVISION_NO= '")
.append(sXNumber).append("'");
ResultSet rslt = getStatement.executeQuery(theSQL.toString());
if (rslt.next()) {
return rslt.getLong("VERSION_ID");
} else {
return 0;
}
}
/**
* Set the VersionID for the current URI
*/
protected void setVersionID(long uri_id, long branch_id, String sXNumber)
throws SQLException {
//getLogger().log("Inside VersionID",LOG_CHANNEL,Logger.DEBUG);
Connection connection = getCurrentConnection();
Statement insStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("SELECT 1 FROM VERSION WHERE URI_ID =");
theSQL.append(uri_id);
getLogger().log
("Inside VersionID =="
+ theSQL.toString(),
LOG_CHANNEL,Logger.DEBUG);
ResultSet res = insStatement.executeQuery(theSQL.toString());
if (!res.next()) {
theSQL = new StringBuffer
("insert into VERSION (URI_ID,IS_VERSIONED) values( ");
theSQL.append(uri_id).append(", ").append(0).append(")");
insStatement.execute(theSQL.toString());
}
theSQL = new StringBuffer
("insert into VERSION_HISTORY (URI_ID,BRANCH_ID,REVISION_NO)");
theSQL.append("values(");
theSQL.append(uri_id).append(", ")
.append(branch_id).append(", '")
.append(sXNumber).append("')");
insStatement.execute(theSQL.toString());
insStatement.close();
}
/**
* Retrieve the Branch ID For the given Branch.
*/
protected long getBranchID(String branchName)
throws SQLException {
Connection connection = getCurrentConnection();
Statement getStatement = connection.createStatement();
StringBuffer theSQL = new StringBuffer
("select BRANCH_ID from BRANCH where BRANCH_STRING = '");
theSQL.append(branchName).append("'");
ResultSet rslt = getStatement.executeQuery(theSQL.toString());
if (rslt.next()) {
return rslt.getLong("BRANCH_ID");
} else {
return 0;
}
}
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>