[Registry-dev] svn commit r16528 - in trunk/registry/modules/core/src: main/java/org/wso2/registry/jdbc main/java/org/wso2/registry/jdbc/dao main/java/org/wso2/registry/jdbc/dataobjects main/java/org/wso2/registry/jdbc/utils/creators test/java/org/wso2/registry/jdbc

svn at wso2.org svn at wso2.org
Mon May 5 04:19:14 PDT 2008


Author: chathura
Date: Mon May  5 04:18:43 2008
New Revision: 16528

Log:


Implementing the version restore functionality.
Resource restoring works fine now.
Still have to complete the collection restoring.
Have to consider all scenarios related to restoring and add support for all such scenarios.

Changed the database creating code to have description of 10000 charactors.



Added:
   trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/dao/RestoreUtilDAO.java
   trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/dataobjects/PropertyDO.java
   trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/dataobjects/ResourceDO.java
Modified:
   trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/JDBCRegistry.java
   trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/NonTransactionalJDBCRegistry.java
   trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/VersionRepository.java
   trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/dao/ResourceDAO.java
   trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/dao/ResourceVersionDAO.java
   trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/utils/creators/DerbyDatabaseCreator.java
   trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/utils/creators/HSQLDatabaseCreator.java
   trunk/registry/modules/core/src/test/java/org/wso2/registry/jdbc/MoveTest.java
   trunk/registry/modules/core/src/test/java/org/wso2/registry/jdbc/VersionHandlingTest.java

Modified: trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/JDBCRegistry.java
==============================================================================
--- trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/JDBCRegistry.java	(original)
+++ trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/JDBCRegistry.java	Mon May  5 04:18:43 2008
@@ -433,6 +433,12 @@
     }
 
     public void restoreVersion(String versionPath) throws RegistryException {
+
+        if (Transaction.isStarted()) {
+            transactionalRegistry.restoreVersion(versionPath);
+        } else {
+            nonTransactionalRegistry.restoreVersion(versionPath);
+        }
     }
 
 

Modified: trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/NonTransactionalJDBCRegistry.java
==============================================================================
--- trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/NonTransactionalJDBCRegistry.java	(original)
+++ trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/NonTransactionalJDBCRegistry.java	Mon May  5 04:18:43 2008
@@ -487,7 +487,23 @@
 
     public void restoreVersion(String versionPath) throws RegistryException {
 
-        throw new RegistryException("Verioning is not yet implemented.");
+        boolean success = false;
+        try {
+
+            beginTransaction();
+
+            transactionalJDBCRegistry.restoreVersion(versionPath);
+
+            success = true;
+
+        } finally {
+
+            if (success) {
+                commitTransaction();
+            } else {
+                rollbackTransaction();
+            }
+        }
 
         //String plainPath;
         //long versionNumber;

Modified: trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/VersionRepository.java
==============================================================================
--- trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/VersionRepository.java	(original)
+++ trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/VersionRepository.java	Mon May  5 04:18:43 2008
@@ -19,6 +19,8 @@
 import org.wso2.registry.*;
 import org.wso2.registry.jdbc.dao.ResourceDAO;
 import org.wso2.registry.jdbc.dao.ResourceVersionDAO;
+import org.wso2.registry.jdbc.dao.RestoreUtilDAO;
+import org.wso2.registry.jdbc.dataobjects.ResourceDO;
 import org.wso2.registry.utils.VersionedPath;
 import org.wso2.registry.utils.RegistryUtils;
 import org.apache.commons.logging.Log;
@@ -38,6 +40,7 @@
 
     private ResourceDAO resourceDAO = new ResourceDAO();
     private ResourceVersionDAO resourceVersionDAO = new ResourceVersionDAO();
+    private RestoreUtilDAO restoreUtilDAO = new RestoreUtilDAO();
 
     public VersionRepository(DataSource dataSource) {
         this.dataSource = dataSource;
@@ -135,6 +138,11 @@
             log.error(msg);
             throw new RegistryException(msg);
         }
+
+        String versionedResourcePath = versionedPath.getPath();
+        long snapshotID = versionedPath.getVersion();
+        String resourceID = resourceDAO.getResourceID(versionedResourcePath);
+        restoreSnapshotNetwork(snapshotID, resourceID);
     }
 
     private void restoreSnapshotNetwork(long snapshotID, String resourceID)
@@ -150,6 +158,7 @@
         //      check if that version number and equivalent version number are same
         //      if no,
         //          replace versionalble fields of the resource table
+        //          delete current version content
         //          copy versioned content to content table, and set the content ID of the resource
         //          delete all properties of old resource and copy properties from the version
         //      end if
@@ -161,5 +170,43 @@
         //      call restoreSnapshotNetwork
         // end for
 
+        ResourceDO resourceVersionDO =
+                resourceVersionDAO.getResourceVersionDO(resourceID, snapshotID);
+        ResourceDO resourceDO = resourceDAO.getResourceDO(resourceID);
+        if (resourceDO != null) {
+
+            if (resourceDO.getEquivalentVersion() != resourceVersionDO.getVersion()) {
+                restoreUtilDAO.replaceContentVersion(resourceDO, resourceVersionDO);
+                restoreUtilDAO.mergeResourceVersion(resourceDO, resourceVersionDO);
+                restoreUtilDAO.replaceProperties(resourceID, resourceVersionDO.getVersion());
+            }
+
+        } else {
+
+            String contentID = restoreUtilDAO.copyContentVersion(resourceDO, resourceVersionDO);
+            restoreUtilDAO.copyResourceVersion(resourceVersionDO, contentID);
+            restoreUtilDAO.copyProperties(resourceID, resourceVersionDO.getVersion());
+        }
+
+        List <String> versionedChildIDs =
+                resourceVersionDAO.getChildIDs(resourceID, resourceVersionDO.getVersion());
+        
+        if (resourceDO != null) {
+            List <String> childIDs = resourceDAO.getChildIDs(resourceID);
+            Iterator <String> iChildIDs = childIDs.iterator();
+            while (iChildIDs.hasNext()) {
+                String childID = iChildIDs.next();
+                if (!versionedChildIDs.contains(childID)) {
+                    resourceDAO.delete(childID);
+                }
+            }
+        }
+
+        restoreUtilDAO.replaceDependencies(resourceID, versionedChildIDs);
+
+        Iterator <String> iVersionedChildIDs = versionedChildIDs.iterator();
+        while (iVersionedChildIDs.hasNext()) {
+            restoreSnapshotNetwork(snapshotID, iVersionedChildIDs.next());
+        }
     }
 }

Modified: trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/dao/ResourceDAO.java
==============================================================================
--- trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/dao/ResourceDAO.java	(original)
+++ trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/dao/ResourceDAO.java	Mon May  5 04:18:43 2008
@@ -22,6 +22,7 @@
 import org.wso2.registry.utils.AuthorizationUtils;
 import org.wso2.registry.session.CurrentSession;
 import org.wso2.registry.jdbc.utils.Transaction;
+import org.wso2.registry.jdbc.dataobjects.ResourceDO;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -208,6 +209,37 @@
         return exists;
     }
 
+    public boolean resourceExistsWithID(String resourceID) throws RegistryException {
+
+        Connection conn = Transaction.getConnection();
+
+        boolean exists = false;
+        try {
+            String sql = "SELECT PATH FROM RESOURCE WHERE RID=?";
+
+            PreparedStatement ps = conn.prepareStatement(sql);
+            ps.setString(1, resourceID);
+
+            ResultSet result = ps.executeQuery();
+
+            exists = false;
+            if (result.next()) {
+                exists = true;
+            }
+
+            ps.close();
+
+        } catch (SQLException e) {
+
+            String msg = "Failed to check the existence of the resource " +
+                    resourceID + ". " + e.getMessage();
+            log.error(msg, e);
+            throw new RegistryException(msg, e);
+        }
+
+        return exists;
+    }
+
     public void attachChild(String parentID, String childID) throws RegistryException {
 
         Connection conn = Transaction.getConnection();
@@ -493,7 +525,7 @@
 
         try {
             String sql = "SELECT R.RID, R.PATH FROM RESOURCE R, DEPENDENCY D WHERE D.PARENT_RID=?" +
-                         " AND D.CHILD_RID=R.RID ORDER BY R.PATH";
+                    " AND D.CHILD_RID=R.RID ORDER BY R.PATH";
 
             PreparedStatement ps = conn.prepareStatement(sql);
             ps.setString(1, collection.getId());
@@ -996,6 +1028,63 @@
         resourceImpl.setContentID(contentID);
     }
 
+    public void updateContent(String contentID, InputStream contentStream)
+            throws RegistryException {
+
+        Connection conn = Transaction.getConnection();
+
+        // we should first write the content stream to a temporary file because JDBC
+        // needs the length of the binary stream.
+
+        File tempFile = null;
+        try {
+            tempFile = File.createTempFile("reg", "tmp");
+            OutputStream fileStream = new BufferedOutputStream(new FileOutputStream(tempFile));
+            InputStream bufferedIn = new BufferedInputStream(contentStream);
+
+            byte[] dataChunk = new byte[1024];
+            int byteCount;
+            while ((byteCount = bufferedIn.read(dataChunk)) != -1) {
+                fileStream.write(dataChunk, 0, byteCount);
+            }
+            fileStream.flush();
+            bufferedIn.close();
+            fileStream.close();
+
+        } catch (IOException e) {
+
+            String msg = "Failed to write the resource content to a temporary file, " +
+                    "before writing to the database. " + e.getMessage();
+            log.error(msg, e);
+            throw new RegistryException(msg, e);
+        }
+
+        try {
+
+            InputStream tempFileStream = new BufferedInputStream(new FileInputStream(tempFile));
+            long contentLength = tempFile.length();
+
+            String sql = "UPDATE CONTENT SET CONTENT_DATA=? WHERE CONTENT_ID=?";
+
+            PreparedStatement ps = conn.prepareStatement(sql);
+            ps.setBinaryStream(1, tempFileStream, (int)contentLength);
+            ps.setString(2, contentID);
+            ps.executeUpdate();
+            ps.close();
+
+        } catch (FileNotFoundException e) {
+            String msg = "Failed to read resource content from the temporary file. " + e.getMessage();
+            log.error(msg, e);
+            throw new RegistryException(msg, e);
+
+        } catch (SQLException e) {
+
+            String msg = "Failed to write resource content to the database. " + e.getMessage();
+            log.error(msg, e);
+            throw new RegistryException(msg, e);
+        }
+    }
+
     /**
      * Content of resources are stored seprately in the CONTENT table and given a UUID. Resource
      * refer to thier contents by this UUID. Multiple resources may refer to a same content.
@@ -1034,4 +1123,131 @@
         }
     }
 
+    public long getEquivalenVersion(String resourceID) throws RegistryException {
+
+        Connection conn = Transaction.getConnection();
+
+        try {
+            String sql = "SELECT EQUIVALENT_VERSION FROM RESOURCE WHERE RID=?";
+            PreparedStatement ps = conn.prepareStatement(sql);
+            ps.setString(1, resourceID);
+
+            ResultSet result = ps.executeQuery();
+            long equivalentVersion = -1;
+            if (result.next()) {
+                equivalentVersion = result.getLong("EQUIVALENT_VERSION");
+            }
+            ps.close();
+
+            return equivalentVersion;
+
+        } catch (SQLException e) {
+
+            String msg = "Failed to get equivalent version of the resource " +
+                    resourceID + ". " + e.getMessage();
+            log.error(msg, e);
+            throw new RegistryException(msg, e);
+        }
+    }
+
+    public ResourceDO getResourceDO(String resourceID) throws RegistryException {
+
+        Connection conn = Transaction.getConnection();
+
+        String sql = "SELECT R.RID, R.EQUIVALENT_VERSION, R.PATH, R.MEDIA_TYPE, R.COLLECTION, " +
+                "R.CREATOR, R.CREATED_TIME, R.LAST_UPDATOR, R.LAST_UPDATED_TIME, " +
+                "R.DESCRIPTION, R.CONTENT_ID FROM RESOURCE R WHERE R.RID=?";
+
+        try {
+            PreparedStatement ps = conn.prepareStatement(sql);
+            ps.setString(1, resourceID);
+
+            ResourceDO resourceDO = null;
+            ResultSet result = ps.executeQuery();
+            if (result.next()) {
+                resourceDO = new ResourceDO();
+
+                resourceDO.setID(result.getString("RID"));
+                resourceDO.setEquivalentVersion(result.getLong("EQUIVALENT_VERSION"));
+                resourceDO.setPath(result.getString("PATH"));
+                resourceDO.setMediaType(result.getString("MEDIA_TYPE"));
+                resourceDO.setCollection(result.getInt("COLLECTION"));
+                resourceDO.setAuthor(result.getString("CREATOR"));
+                resourceDO.setCreatedOn(result.getTimestamp("CREATED_TIME"));
+                resourceDO.setLastUpdator(result.getString("LAST_UPDATOR"));
+                resourceDO.setLastUpdatedOn(result.getTimestamp("LAST_UPDATED_TIME"));
+                resourceDO.setDescription(result.getString("DESCRIPTION"));
+                resourceDO.setContentID(result.getString("CONTENT_ID"));
+            }
+
+            return resourceDO;
+
+        } catch (SQLException e) {
+
+            String msg = "Failed to read resource version data for resource " +
+                    resourceID + ". " + e.getMessage();
+            log.error(msg, e);
+            throw new RegistryException(msg, e);
+        }
+    }
+
+    public String addContent(InputStream contentStream) throws RegistryException {
+
+        Connection conn = Transaction.getConnection();
+
+        // we should first write the content stream to a temporary file because JDBC
+        // needs the length of the binary stream.
+
+        File tempFile;
+        try {
+            tempFile = File.createTempFile("reg", "tmp");
+            OutputStream fileStream = new BufferedOutputStream(new FileOutputStream(tempFile));
+            InputStream bufferedIn = new BufferedInputStream(contentStream);
+
+            byte[] dataChunk = new byte[1024];
+            int byteCount;
+            while ((byteCount = bufferedIn.read(dataChunk)) != -1) {
+                fileStream.write(dataChunk, 0, byteCount);
+            }
+            fileStream.flush();
+            bufferedIn.close();
+            fileStream.close();
+
+        } catch (IOException e) {
+
+            String msg = "Failed to write the resource content to a temporary file, " +
+                    "before writing to the database. " + e.getMessage();
+            log.error(msg, e);
+            throw new RegistryException(msg, e);
+        }
+
+        try {
+
+            String contentID = UUID.randomUUID().toString();
+
+            InputStream tempFileStream = new BufferedInputStream(new FileInputStream(tempFile));
+            long contentLength = tempFile.length();
+
+            String sql = "INSERT INTO CONTENT (CONTENT_ID, CONTENT_DATA) VALUES (?, ?)";
+
+            PreparedStatement ps = conn.prepareStatement(sql);
+            ps.setString(1, contentID);
+            ps.setBinaryStream(2, tempFileStream, (int)contentLength);
+            ps.executeUpdate();
+            ps.close();
+
+            return contentID;
+
+        } catch (FileNotFoundException e) {
+            String msg = "Failed to read resource content from the temporary file. " + e.getMessage();
+            log.error(msg, e);
+            throw new RegistryException(msg, e);
+
+        } catch (SQLException e) {
+
+            String msg = "Failed to write resource content to the database. " + e.getMessage();
+            log.error(msg, e);
+            throw new RegistryException(msg, e);
+        }
+    }
 }

Modified: trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/dao/ResourceVersionDAO.java
==============================================================================
--- trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/dao/ResourceVersionDAO.java	(original)
+++ trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/dao/ResourceVersionDAO.java	Mon May  5 04:18:43 2008
@@ -17,6 +17,7 @@
 package org.wso2.registry.jdbc.dao;
 
 import org.wso2.registry.jdbc.utils.Transaction;
+import org.wso2.registry.jdbc.dataobjects.ResourceDO;
 import org.wso2.registry.*;
 import org.wso2.registry.Collection;
 import org.wso2.registry.utils.AuthorizationUtils;
@@ -605,4 +606,82 @@
 
         return new BufferedInputStream(new FileInputStream(tempFile));
     }
+
+    public ResourceDO getResourceVersionDO(String resourceID, long snapshotID)
+            throws RegistryException {
+
+        Connection conn = Transaction.getConnection();
+
+        String sql = "SELECT R.RID, R.VERSION, R.PATH, R.MEDIA_TYPE, R.COLLECTION, " +
+                "R.CREATOR, R.CREATED_TIME, R.LAST_UPDATOR, R.LAST_UPDATED_TIME, " +
+                "R.DESCRIPTION, R.CONTENT_ID " +
+                "FROM RESOURCE_VERSION R WHERE R.RID=? AND R.VERSION=" +
+                "(SELECT S.VERSION FROM SNAPSHOT_RESOURCE_VERSION S " +
+                "WHERE S.SNAPSHOT_ID=? AND S.RID=?)";
+
+        try {
+            PreparedStatement ps = conn.prepareStatement(sql);
+            ps.setString(1, resourceID);
+            ps.setLong(2, snapshotID);
+            ps.setString(3, resourceID);
+
+            ResourceDO resourceVersionDO = null;
+            ResultSet result = ps.executeQuery();
+            if (result.next()) {
+                resourceVersionDO = new ResourceDO();
+
+                resourceVersionDO.setID(result.getString("RID"));
+                resourceVersionDO.setVersion(result.getLong("VERSION"));
+                resourceVersionDO.setPath(result.getString("PATH"));
+                resourceVersionDO.setMediaType(result.getString("MEDIA_TYPE"));
+                resourceVersionDO.setCollection(result.getInt("COLLECTION"));
+                resourceVersionDO.setAuthor(result.getString("CREATOR"));
+                resourceVersionDO.setCreatedOn(result.getTimestamp("CREATED_TIME"));
+                resourceVersionDO.setLastUpdator(result.getString("LAST_UPDATOR"));
+                resourceVersionDO.setLastUpdatedOn(result.getTimestamp("LAST_UPDATED_TIME"));
+                resourceVersionDO.setDescription(result.getString("DESCRIPTION"));
+                resourceVersionDO.setContentID(result.getString("CONTENT_ID"));
+            }
+
+            return resourceVersionDO;
+
+        } catch (SQLException e) {
+
+            String msg = "Failed to read resource version data for resource " +
+                    resourceID + " for snapshot ID " + snapshotID + ". " + e.getMessage();
+            log.error(msg, e);
+            throw new RegistryException(msg, e);
+        }
+    }
+
+    public List<String> getChildIDs(String resourceID, long version) throws RegistryException {
+
+        List <String> childIDs = new ArrayList();
+
+        Connection conn = Transaction.getConnection();
+
+        try {
+            String sql = "SELECT CHILD_RID FROM DEPENDENCY_VERSION " +
+                    "WHERE PARENT_RID=? AND PARENT_VERSION=?";
+
+            PreparedStatement ps = conn.prepareStatement(sql);
+            ps.setString(1, resourceID);
+            ps.setLong(2, version);
+
+            ResultSet results = ps.executeQuery();
+            while (results.next()) {
+                childIDs.add(results.getString("CHILD_RID"));
+            }
+            ps.close();
+
+        } catch (SQLException e) {
+
+            String msg = "Failed to get child resource IDs of resource " +
+                    resourceID + ". " + e.getMessage();
+            log.error(msg, e);
+            throw new RegistryException(msg, e);
+        }
+
+        return childIDs;
+    }
 }

Added: trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/dao/RestoreUtilDAO.java
==============================================================================
--- (empty file)
+++ trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/dao/RestoreUtilDAO.java	Mon May  5 04:18:43 2008
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2006, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wso2.registry.jdbc.dao;
+
+import org.wso2.registry.RegistryException;
+import org.wso2.registry.jdbc.dataobjects.ResourceDO;
+import org.wso2.registry.jdbc.dataobjects.PropertyDO;
+import org.wso2.registry.jdbc.utils.Transaction;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.InputStream;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.ResultSet;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+public class RestoreUtilDAO {
+
+    private static Log log = LogFactory.getLog(RestoreUtilDAO.class);
+
+    private ResourceDAO resourceDAO = new ResourceDAO();
+    private ResourceVersionDAO resourceVersionDAO = new ResourceVersionDAO();
+
+    public String replaceContentVersion(ResourceDO resourceDO, ResourceDO resourceVersionDO)
+            throws RegistryException {
+
+        Connection conn = Transaction.getConnection();
+        InputStream contentStream = resourceVersionDAO.
+                getResourceContentStream(resourceVersionDO.getContentID(), conn);
+        resourceDAO.updateContent(resourceDO.getContentID(), contentStream);
+
+        return resourceDO.getContentID();
+    }
+
+    public void mergeResourceVersion(ResourceDO resourceDO, ResourceDO resourceVersionDO)
+            throws RegistryException {
+
+        Connection conn = Transaction.getConnection();
+
+        String sql = "UPDATE RESOURCE SET EQUIVALENT_VERSION=?, MEDIA_TYPE=?, " +
+                "LAST_UPDATOR=?, LAST_UPDATED_TIME=?, DESCRIPTION=? WHERE RID=?";
+
+        try {
+            PreparedStatement ps = conn.prepareStatement(sql);
+
+            ps.setLong(1, resourceVersionDO.getVersion());
+            ps.setString(2, resourceVersionDO.getMediaType());
+            ps.setString(3, resourceVersionDO.getLastUpdator());
+            ps.setTimestamp(4, resourceVersionDO.getLastUpdatedOn());
+            ps.setString(5, resourceVersionDO.getDescription());
+
+            ps.setString(6, resourceDO.getID());
+
+            ps.executeUpdate();
+            ps.close();
+
+        } catch (SQLException e) {
+
+            String msg = "Failed to merge the revision " + resourceVersionDO.getVersion() +
+                    " with the current version of resource " + resourceDO.getPath() + ". " +
+                    e.getMessage();
+            log.error(msg, e);
+            throw new RegistryException(msg, e);
+        }
+    }
+
+    public void replaceProperties(String resourceID, long versionNumber) throws RegistryException {
+
+        deleteProperties(resourceID);
+        List <PropertyDO> properties = getProperties(resourceID, versionNumber);
+        setProperties(resourceID, properties);
+    }
+
+    private void setProperties(String resourceID, List<PropertyDO> properties)
+            throws RegistryException {
+
+        Connection conn = Transaction.getConnection();
+
+        String sql = "INSERT INTO PROPERTY (RID, NAME, VALUE) VALUES (?, ?, ?)";
+
+        try {
+            PreparedStatement ps = conn.prepareStatement(sql);
+
+            Iterator <PropertyDO> iProps = properties.iterator();
+            while (iProps.hasNext()) {
+                PropertyDO propertyDO = iProps.next();
+                ps.setString(1, resourceID);
+                ps.setString(2, propertyDO.getName());
+                ps.setString(3, propertyDO.getValue());
+                ps.executeUpdate();
+                ps.clearParameters();
+            }
+            ps.close();
+
+        } catch (SQLException e) {
+
+            String msg = "Failed to set properties for resource " +
+                    resourceID + ". " + e.getMessage();
+            log.error(msg, e);
+            throw new RegistryException(msg, e);
+        }
+    }
+
+    private List<PropertyDO> getProperties(String resourceID, long versionNumber)
+            throws RegistryException {
+
+        Connection conn = Transaction.getConnection();
+
+        String sql = "SELECT NAME, VALUE FROM PROPERTY_VERSION WHERE RID=? AND VERSION=?";
+
+        try {
+            PreparedStatement ps = conn.prepareStatement(sql);
+            ps.setString(1, resourceID);
+            ps.setLong(2, versionNumber);
+
+            ResultSet result = ps.executeQuery();
+
+            List <PropertyDO> properties = new ArrayList();
+            while (result.next()) {
+                PropertyDO propertyDO = new PropertyDO();
+                propertyDO.setName(result.getString("NAME"));
+                propertyDO.setValue(result.getString("VALUE"));
+
+                properties.add(propertyDO);
+            }
+            ps.close();
+
+            return properties;
+
+        } catch (SQLException e) {
+
+            String msg = "Failed to read properties revision " + versionNumber +
+                    " of resource " + resourceID + ". " + e.getMessage();
+            log.error(msg, e);
+            throw new RegistryException(msg, e);
+        }
+    }
+
+    private void deleteProperties(String resourceID) throws RegistryException {
+
+        Connection conn = Transaction.getConnection();
+
+        String sql = "DELETE FROM PROPERTY WHERE RID=?";
+
+        try {
+            PreparedStatement ps = conn.prepareStatement(sql);
+            ps.setString(1, resourceID);
+            ps.executeUpdate();
+
+        } catch (SQLException e) {
+
+            String msg = "Failed to delete properties of resource " +
+                    resourceID + ". " + e.getMessage();
+            log.error(msg, e);
+            throw new RegistryException(msg, e);
+        }
+    }
+
+    public String copyContentVersion(ResourceDO resourceDO, ResourceDO resourceVersionDO)
+            throws RegistryException {
+
+        Connection conn = Transaction.getConnection();
+
+        InputStream contentStream = resourceVersionDAO.
+                getResourceContentStream(resourceVersionDO.getContentID(), conn);
+        String contentID = resourceDAO.addContent(contentStream);
+
+        return contentID;
+
+    }
+
+    public void copyResourceVersion(ResourceDO resourceVersionDO, String contentID)
+            throws RegistryException {
+
+        Connection conn = Transaction.getConnection();
+
+        String sql = "INSERT RESOURCE (RID, PATH, MEDIA_TYPE, COLLECTION, CREATER, CREATED_TIME, " +
+                "LAST_UPDATOR, LAST_UPDATED_TIME, DESCRIPTION, CONTENT_ID, EQUIVALENT_VERSION) " +
+                "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+        try {
+            PreparedStatement ps = conn.prepareStatement(sql);
+
+            ps.setString(1, resourceVersionDO.getID());
+            ps.setString(2, resourceVersionDO.getPath());
+            ps.setString(3, resourceVersionDO.getMediaType());
+            ps.setInt(4, resourceVersionDO.getCollection());
+            ps.setString(5, resourceVersionDO.getAuthor());
+            ps.setTimestamp(6, resourceVersionDO.getCreatedOn());
+            ps.setString(7, resourceVersionDO.getLastUpdator());
+            ps.setTimestamp(8, resourceVersionDO.getLastUpdatedOn());
+            ps.setString(9, resourceVersionDO.getDescription());
+            ps.setString(10, contentID);
+            ps.setLong(11, resourceVersionDO.getVersion());
+
+            ps.executeUpdate();
+            ps.close();
+
+        } catch (SQLException e) {
+
+            String msg = "Failed to copy the revision " + resourceVersionDO.getVersion() +
+                    " to the current version of resource " + resourceVersionDO.getPath() + ". " +
+                    e.getMessage();
+            log.error(msg, e);
+            throw new RegistryException(msg, e);
+        }
+    }
+
+    public void copyProperties(String resourceID, long versionNumber) throws RegistryException {
+
+        List <PropertyDO> properties = getProperties(resourceID, versionNumber);
+        setProperties(resourceID, properties);
+    }
+
+    public void replaceDependencies(String resourceID, List<String> versionedChildIDs) 
+            throws RegistryException {
+
+        deleteDependencies(resourceID);
+        addDependencies(resourceID, versionedChildIDs);
+    }
+
+    private void addDependencies(String resourceID, List<String> versionedChildIDs)
+            throws RegistryException {
+
+        Connection conn = Transaction.getConnection();
+
+        String sql = "INSERT INTO DEPENDENCY (PARENT_RID, CHILD_RID) VALUES (? ,?)";
+
+        try {
+            PreparedStatement ps = conn.prepareStatement(sql);
+
+            Iterator <String> iChildIDs = versionedChildIDs.iterator();
+            while (iChildIDs.hasNext()) {
+                String childID = iChildIDs.next();
+
+                ps.setString(1, resourceID);
+                ps.setString(2, childID);
+                ps.executeUpdate();
+                ps.clearParameters();
+            }
+            ps.close();
+
+        } catch (SQLException e) {
+
+            String msg = "Failed to add dependencies to resource " +
+                    resourceID + ". " + e.getMessage();
+            log.error(msg, e);
+            throw new RegistryException(msg, e);
+        }
+    }
+
+    private void deleteDependencies(String resourceID) throws RegistryException {
+
+        Connection conn = Transaction.getConnection();
+
+        String sql = "DELETE FROM DEPENDENCY WHERE PARENT_RID=?";
+
+        try {
+            PreparedStatement ps = conn.prepareStatement(sql);
+            ps.setString(1, resourceID);
+            ps.executeUpdate();
+            ps.close();
+
+        } catch (SQLException e) {
+            String msg = "Failed to delete dependencies of resource " +
+                    resourceID + ". " + e.getMessage();
+            log.error(msg, e);
+            throw new RegistryException(msg, e);
+        }
+
+    }
+}

Added: trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/dataobjects/PropertyDO.java
==============================================================================
--- (empty file)
+++ trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/dataobjects/PropertyDO.java	Mon May  5 04:18:43 2008
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2006, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wso2.registry.jdbc.dataobjects;
+
+public class PropertyDO {
+
+    private String name;
+
+    private String value;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+}

Added: trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/dataobjects/ResourceDO.java
==============================================================================
--- (empty file)
+++ trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/dataobjects/ResourceDO.java	Mon May  5 04:18:43 2008
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2006, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wso2.registry.jdbc.dataobjects;
+
+import java.sql.Timestamp;
+
+public class ResourceDO {
+
+    private String ID;
+
+    private long version = -1;
+
+    private long equivalentVersion = -1;
+
+    private String path;
+
+    private String mediaType;
+
+    private int collection;
+
+    private String author;
+
+    private Timestamp createdOn;
+
+    private String lastUpdator;
+
+    private Timestamp lastUpdatedOn;
+
+    private String description;
+
+    private String contentID;
+
+    public String getID() {
+        return ID;
+    }
+
+    public void setID(String ID) {
+        this.ID = ID;
+    }
+
+    public long getVersion() {
+        return version;
+    }
+
+    public void setVersion(long version) {
+        this.version = version;
+    }
+
+    public long getEquivalentVersion() {
+        return equivalentVersion;
+    }
+
+    public void setEquivalentVersion(long equivalentVersion) {
+        this.equivalentVersion = equivalentVersion;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public String getMediaType() {
+        return mediaType;
+    }
+
+    public void setMediaType(String mediaType) {
+        this.mediaType = mediaType;
+    }
+
+    public int getCollection() {
+        return collection;
+    }
+
+    public void setCollection(int collection) {
+        this.collection = collection;
+    }
+
+    public String getAuthor() {
+        return author;
+    }
+
+    public void setAuthor(String author) {
+        this.author = author;
+    }
+
+    public Timestamp getCreatedOn() {
+        return createdOn;
+    }
+
+    public void setCreatedOn(Timestamp createdOn) {
+        this.createdOn = createdOn;
+    }
+
+    public String getLastUpdator() {
+        return lastUpdator;
+    }
+
+    public void setLastUpdator(String lastUpdator) {
+        this.lastUpdator = lastUpdator;
+    }
+
+    public Timestamp getLastUpdatedOn() {
+        return lastUpdatedOn;
+    }
+
+    public void setLastUpdatedOn(Timestamp lastUpdatedOn) {
+        this.lastUpdatedOn = lastUpdatedOn;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getContentID() {
+        return contentID;
+    }
+
+    public void setContentID(String contentID) {
+        this.contentID = contentID;
+    }
+}

Modified: trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/utils/creators/DerbyDatabaseCreator.java
==============================================================================
--- trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/utils/creators/DerbyDatabaseCreator.java	(original)
+++ trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/utils/creators/DerbyDatabaseCreator.java	Mon May  5 04:18:43 2008
@@ -30,7 +30,7 @@
                     "CREATED_TIME TIMESTAMP," +
                     "LAST_UPDATOR VARCHAR (500)," +
                     "LAST_UPDATED_TIME TIMESTAMP," +
-                    "DESCRIPTION VARCHAR (500)," +
+                    "DESCRIPTION VARCHAR (10000)," +
                     "CONTENT_ID VARCHAR (50)," +
                     "EQUIVALENT_VERSION INTEGER NOT NULL," +
                     "PRIMARY KEY (RID)," +
@@ -138,7 +138,7 @@
                     "CREATED_TIME TIMESTAMP," +
                     "LAST_UPDATOR VARCHAR (500)," +
                     "LAST_UPDATED_TIME TIMESTAMP," +
-                    "DESCRIPTION VARCHAR (500)," +
+                    "DESCRIPTION VARCHAR (10000)," +
                     "CONTENT_ID VARCHAR (50)," +
                     "FOREIGN KEY (CONTENT_ID) REFERENCES CONTENT_VERSION (CONTENT_VERSION_ID)," +
                     "PRIMARY KEY (RESOURCE_VERSION_ID)," +

Modified: trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/utils/creators/HSQLDatabaseCreator.java
==============================================================================
--- trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/utils/creators/HSQLDatabaseCreator.java	(original)
+++ trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/utils/creators/HSQLDatabaseCreator.java	Mon May  5 04:18:43 2008
@@ -33,7 +33,7 @@
                     "CREATED_TIME TIMESTAMP," +
                     "LAST_UPDATOR VARCHAR (500)," +
                     "LAST_UPDATED_TIME TIMESTAMP," +
-                    "DESCRIPTION VARCHAR (500)," +
+                    "DESCRIPTION VARCHAR (10000)," +
                     "CONTENT_ID VARCHAR (50)," +
                     "EQUIVALENT_VERSION INTEGER NOT NULL," +
                     "PRIMARY KEY (RID)," +
@@ -141,7 +141,7 @@
                     "CREATED_TIME TIMESTAMP," +
                     "LAST_UPDATOR VARCHAR (500)," +
                     "LAST_UPDATED_TIME TIMESTAMP," +
-                    "DESCRIPTION VARCHAR (500)," +
+                    "DESCRIPTION VARCHAR (10000)," +
                     "CONTENT_ID VARCHAR (50)," +
                     "FOREIGN KEY (CONTENT_ID) REFERENCES CONTENT_VERSION (CONTENT_VERSION_ID)," +
                     "PRIMARY KEY (RESOURCE_VERSION_ID)," +

Modified: trunk/registry/modules/core/src/test/java/org/wso2/registry/jdbc/MoveTest.java
==============================================================================
--- trunk/registry/modules/core/src/test/java/org/wso2/registry/jdbc/MoveTest.java	(original)
+++ trunk/registry/modules/core/src/test/java/org/wso2/registry/jdbc/MoveTest.java	Mon May  5 04:18:43 2008
@@ -23,6 +23,10 @@
 import org.wso2.registry.session.UserRegistry;
 import org.wso2.registry.jdbc.realm.RegistryRealm;
 
+import java.util.Properties;
+import java.util.Map;
+import java.util.HashMap;
+
 public class MoveTest extends TestCase {
 
     protected static EmbeddedRegistry embeddedRegistry = null;

Modified: trunk/registry/modules/core/src/test/java/org/wso2/registry/jdbc/VersionHandlingTest.java
==============================================================================
--- trunk/registry/modules/core/src/test/java/org/wso2/registry/jdbc/VersionHandlingTest.java	(original)
+++ trunk/registry/modules/core/src/test/java/org/wso2/registry/jdbc/VersionHandlingTest.java	Mon May  5 04:18:43 2008
@@ -21,7 +21,6 @@
 
 import junit.framework.TestCase;
 import org.wso2.registry.*;
-import org.wso2.registry.jdbc.realm.InMemoryRegistryRealm;
 import org.wso2.registry.jdbc.realm.RegistryRealm;
 import org.wso2.registry.jdbc.utils.RegistryDataSource;
 
@@ -151,6 +150,51 @@
         Collection c1v3 = (Collection) registry.get(c1Versions[2]);
     }
 
+    public void testResourceRestore() throws RegistryException {
+
+        Resource r1 = registry.newResource();
+        r1.setContent("content 1");
+        registry.put("/test/v10/r1", r1);
+
+        Resource r1e1 = registry.get("/test/v10/r1");
+        r1e1.setContent("content 2");
+        registry.put("/test/v10/r1", r1e1);
+
+        String[] r1Versions = registry.getVersions("/test/v10/r1");
+        registry.restoreVersion(r1Versions[0]);
+
+        Resource r1r1 = registry.get("/test/v10/r1");
+
+        assertEquals("Restored resource should have content 'content 1'",
+                "content 1", new String((byte[]) r1r1.getContent()));
+    }
+
+    public void testSimpleCollectionRestore() throws RegistryException {
+
+        //Collection c1 = registry.newCollection();
+        //registry.put("/test/v11/c1", c1);
+        //
+        //registry.createVersion("/test/v11/c1");
+        //
+        //Resource r1 = registry.newResource();
+        //r1.setContent("r1c1");
+        //registry.put("/test/v11/c1/r1", r1);
+        //
+        //registry.createVersion("/test/v11/c1");
+        //
+        //Resource r2 = registry.newResource();
+        //r2.setContent("r1c1");
+        //registry.put("/test/v11/c1/r2", r2);
+        //
+        //registry.createVersion("/test/v11/c1");
+        //
+        //String[] c1Versions = registry.getVersions("/test/v11/c1");
+        //
+        //registry.restoreVersion(c1Versions[0]);
+        //Collection c1r1 = (Collection) registry.get("/test/v11/c1");
+        //assertEquals("version 1 of c1 should not have any children", 0, c1r1.getChildren().length);
+    }
+
     //protected static Registry registry = null;
     //
     //public void setUp() {



More information about the Registry-dev mailing list