Author: adamw
Date: 2005-09-26 16:56:01 -0400 (Mon, 26 Sep 2005)
New Revision: 1215
Added:
trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/
trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/NodeReadOnly.java
trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/RepositoryException.java
trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/ResourceAlreadyExists.java
trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/ResourceDoesNotExist.java
trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceLocal.java
trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceManagement.java
trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHeadNode.java
trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHistoricNode.java
trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnNewDirectory.java
trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnNewNode.java
trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnOperationFailed.java
trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/Tools.java
trunk/forge/portal-extensions/shotoku/shotoku-test/
trunk/forge/portal-extensions/shotoku/shotoku-test/maven.xml
trunk/forge/portal-extensions/shotoku/shotoku-test/project.properties
trunk/forge/portal-extensions/shotoku/shotoku-test/project.xml
trunk/forge/portal-extensions/shotoku/shotoku-test/src/
trunk/forge/portal-extensions/shotoku/shotoku-test/src/java/
trunk/forge/portal-extensions/shotoku/shotoku-test/src/java/org/
trunk/forge/portal-extensions/shotoku/shotoku-test/src/java/org/jboss/
trunk/forge/portal-extensions/shotoku/shotoku-test/src/java/org/jboss/shotoku/
trunk/forge/portal-extensions/shotoku/shotoku-test/src/java/org/jboss/shotoku/test/
trunk/forge/portal-extensions/shotoku/shotoku-test/src/java/org/jboss/shotoku/test/ShotokuTest.java
trunk/forge/portal-extensions/shotoku/shotoku-test/src/web/
trunk/forge/portal-extensions/shotoku/shotoku-test/src/web/WEB-INF/
trunk/forge/portal-extensions/shotoku/shotoku-test/src/web/WEB-INF/web.xml
Modified:
trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/AbstractResource.java
trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/ContentManager.java
trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/Directory.java
trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/History.java
trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/Node.java
trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/NodeList.java
trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnRepository.java
trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceImpl.java
trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceTimer.java
trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/AbstractSvnResource.java
trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnContentManager.java
trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnDirectory.java
trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnService.java
Log:
Further implementation, comments
Modified: trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/AbstractResource.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/AbstractResource.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/AbstractResource.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -1,5 +1,7 @@
package org.jboss.shotoku;
+import org.jboss.shotoku.exceptions.RepositoryException;
+
/**
* @author adamw
* Common parts of nodes and directories interface.
@@ -9,8 +11,9 @@
* Gets the value of a given property.
* @param propertyName Name of the property to get.
* @return Value of the given property.
+ * @throws RepositoryException
*/
- public String getProperty(String propertyName);
+ public String getProperty(String propertyName) throws RepositoryException;
/**
* Sets the value of a given property.
* @param propertyName Name of the property to set.
@@ -22,19 +25,23 @@
* @return A directory to which this node/ directory belongs. Null
* if this directory is already the root directory.
*/
- public Directory getParent();
+ public Directory getParent() throws RepositoryException;
/**
* Saves modified properties and possibly content (in case of nodes).
* @param logMessage Log message for saving this node/ directory.
+ * @throws RepositoryException
*/
- public void save(String logMessage);
+ public void save(String logMessage) throws RepositoryException;
/**
* Gets a log message with which this node/ directory was saved.
* @return Log message with which this node/ directory was saved.
+ * @throws RepositoryException
*/
- public String getLogMessage();
+ public String getLogMessage() throws RepositoryException;
/**
- * Deletes this node or directory.
+ * Deletes this node or directory. This node should not be used after
+ * performing this operation.
+ * @throws RepositoryException
*/
- public void delete();
+ public void delete() throws RepositoryException;
}
Modified: trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/ContentManager.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/ContentManager.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/ContentManager.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -6,144 +6,169 @@
import org.apache.log4j.Logger;
import org.apache.xerces.parsers.DOMParser;
+import org.jboss.shotoku.exceptions.ResourceDoesNotExist;
+import org.jboss.shotoku.exceptions.RepositoryException;
import org.jboss.shotoku.search.SearchParameters;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
/**
- * @author adamw
- * A base class which provides access to nodes and directories.
+ * @author adamw A base class which provides access to nodes and directories.
*/
public abstract class ContentManager {
/**
* Gets a root directory that is represented by this content manager.
- * @return A directory that is the root directory of this content
- * manager.
+ *
+ * @return A directory that is the root directory of this content manager.
+ * @throws RepositoryException
*/
- public abstract Directory getRootDirectory();
+ public abstract Directory getRootDirectory() throws RepositoryException;
+
/**
- * Gets a node which can be found under the given path.
- * @param Path for which to get the node.
+ * Gets a head version of a node which can be found under the given path.
+ *
+ * @param path
+ * for which to get the node.
* @return A node corresponding to the gien path.
+ * @throws ResourceDoesNotExist
+ * @throws RepositoryException
*/
- public abstract Node getNode(String path);
+ public abstract Node getNode(String path) throws ResourceDoesNotExist,
+ RepositoryException;
+
/**
* Gets a directory which can be found under the given path.
- * @param Path for which to get the directory.
+ *
+ * @param path
+ * for which to get the directory.
* @return A directory corresponding to the gien path.
+ * @throws ResourceDoesNotExist
+ * @throws RepositoryException
*/
- public abstract Directory getDirectory(String path);
+ public abstract Directory getDirectory(String path)
+ throws ResourceDoesNotExist, RepositoryException;
+
/**
* Performs a search with the given parameters.
- * @param parameters Parameters for the search.
+ *
+ * @param parameters
+ * Parameters for the search.
* @return A list of found nodes.
+ * @throws RepositoryException
*/
- public abstract NodeList search(SearchParameters parameters);
-
+ public abstract NodeList search(SearchParameters parameters)
+ throws RepositoryException;
+
protected ContentManager(String id, String prefix) {
-
+
}
-
+
/*
* Content manager loading.
*/
-
+
private static final Logger log = Logger.getLogger(ContentManager.class);
-
+
/**
- * <code>defaultId</code> - id of the default content manager. May
- * be overriden by a setting in the xml configuration file.
+ * <code>defaultId</code> - id of the default content manager. May be
+ * overriden by a setting in the xml configuration file.
*/
private static String defaultId = "default";
+
/**
- * <code>contentManagers</code> - map (content manager id ->
- * content manager constructor).
+ * <code>contentManagers</code> - map (content manager id -> content
+ * manager constructor).
*/
private static Map<String, Constructor> contentManagers;
-
+
static {
contentManagers = new HashMap<String, Constructor>();
-
+
// Loading configuration file.
try {
DOMParser parser = new DOMParser();
- parser.parse(new InputSource(
- ContentManager.class.getResourceAsStream("/shotoku.xml")));
+ parser.parse(new InputSource(ContentManager.class
+ .getResourceAsStream("/shotoku.xml")));
Document doc = parser.getDocument();
-
+
org.w3c.dom.Node node = doc.getDocumentElement();
org.w3c.dom.NodeList nodes = node.getChildNodes();
org.w3c.dom.Node n;
-
+
for (int i = 0; i < nodes.getLength(); i++) {
n = nodes.item(i);
-
+
if (n.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
if ("default-id".equals(n.getNodeName())) {
// Overriding the default content manager id.
defaultId = Tools.getAttributeValue(n, "id");
-
+
log.info("Set default id to: " + defaultId);
} else if ("content-manager".equals(n.getNodeName())) {
// Creating a new content manager (getting its
// constructor).
String id = Tools.getAttributeValue(n, "id");
- String implementation =
- Tools.getAttributeValue(n, "implementation");
-
- contentManagers.put(id,
- Class.forName(implementation).getConstructor(
- new Class[] { String.class,
+ String implementation = Tools.getAttributeValue(n,
+ "implementation");
+
+ contentManagers.put(id, Class.forName(implementation)
+ .getConstructor(
+ new Class[] { String.class,
String.class }));
-
- log.info("Added content manager: " + id + ", " +
- implementation);
+
+ log.info("Added content manager: " + id + ", "
+ + implementation);
}
}
- }
+ }
} catch (Exception e) {
- log.warn("Error while loading content manager configuration: " +
- e);
+ log.warn("Error while loading content manager configuration: " + e);
}
}
-
+
/**
* Gets a content manager with a default id and an empty prefix.
+ *
* @return A ""-prefixed, default content manager, or null, if a default
- * content manager is not registered.
+ * content manager is not registered.
*/
public static ContentManager getContentManager() {
return getContentManager("");
}
-
+
/**
* Gets a content manager with a default id and the given prefix.
- * @param prefix Prefix for the new content manager (all paths will
- * have this prepended).
+ *
+ * @param prefix
+ * Prefix for the new content manager (all paths will have this
+ * prepended).
* @return A prefixed, default content manager, or null, if a default
- * content manager is not registered.
+ * content manager is not registered.
*/
public static ContentManager getContentManager(String prefix) {
return getContentManager(defaultId, prefix);
}
-
+
/**
* Gets a content manager with the given id and prefix.
- * @param id Id of the content manager.
- * @param prefix Prefix for the new content manager (all paths will
- * have this prepended).
+ *
+ * @param id
+ * Id of the content manager.
+ * @param prefix
+ * Prefix for the new content manager (all paths will have this
+ * prepended).
* @return A prefixed content manager with the given id or null, if a
- * content manager with the given id registers.
+ * content manager with the given id registers.
*/
public static ContentManager getContentManager(String id, String prefix) {
Constructor constructor = contentManagers.get(id);
-
+
if (constructor == null)
return null;
-
+
try {
- return (ContentManager)
- constructor.newInstance(new Object[] { id, prefix });
+ return (ContentManager) constructor.newInstance(new Object[] { id,
+ prefix });
} catch (Exception e) {
return null;
}
Modified: trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/Directory.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/Directory.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/Directory.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -2,51 +2,78 @@
import java.util.List;
+import org.jboss.shotoku.exceptions.RepositoryException;
+import org.jboss.shotoku.exceptions.ResourceAlreadyExists;
+
/**
- * @author adamw
- * Interface that must be implemented by classes which represent
- * directories, that is resources, which can contain other
- * directories and nodes.
+ * @author adamw Interface that must be implemented by classes which represent
+ * directories, that is resources, which can contain other directories
+ * and nodes.
*/
public interface Directory extends AbstractResource {
/**
* Gets a list of nodes that are contained in this directory.
+ *
* @return A list of nodes that are contained in this directory.
+ * @throws RepositoryException
*/
- public NodeList getNodes();
+ public NodeList getNodes() throws RepositoryException;
+
/**
* Gets a list of directories that are contained in this directory.
+ *
* @return A list of directories that are contained in this directory.
+ * @throws RepositoryException
*/
- public List<Directory> getDirectories();
+ public List<Directory> getDirectories() throws RepositoryException;
+
/**
- * Creates and returns a new node in this directory. Only after saving,
- * this node will be visible by other functions.
- * @param name Name of the new node.
+ * Creates and returns a new node in this directory. Only after saving, this
+ * node will be visible by other functions.
+ *
+ * @param name
+ * Name of the new node.
* @return A new node with the given name.
+ * @throws ResourceAlreadyExists
+ * @throws RepositoryException
*/
- public Node newNode(String name);
+ public Node newNode(String name) throws ResourceAlreadyExists,
+ RepositoryException;
+
/**
* Creates a new directory in this directory. Only after saving this
* directory, it will be visible by other functions. Also, new nodes/
* directories in it will be possible to create only after saving.
- * @param name Name of the directory to create.
+ *
+ * @param name
+ * Name of the directory to create.
* @return A new directory with the given name.
+ * @throws ResourceAlreadyExists
+ * @throws RepositoryException
*/
- public Directory newDirectory(String name);
+ public Directory newDirectory(String name) throws ResourceAlreadyExists,
+ RepositoryException;
+
/**
* Checks if an index is created on the given property.
- * @param propertyName Name of the property for which to check the
- * index.
+ *
+ * @param propertyName
+ * Name of the property for which to check the index.
* @return True iff an index is created for the given property.
+ * @throws RepositoryException
*/
- public boolean hasIndex(String propertyName);
+ public boolean hasIndex(String propertyName) throws RepositoryException;
+
/**
* Creates or deletes an index on a property.
- * @param propertyName Name of the property for which to create/ delete
- * an index.
- * @param index True if and index should be created, false in an index
- * should be deleted.
+ *
+ * @param propertyName
+ * Name of the property for which to create/ delete an index.
+ * @param index
+ * True if and index should be created, false in an index should
+ * be deleted.
+ * @throws RepositoryException
*/
- public void setIndex(String propertyName, boolean index);
+ public void setIndex(String propertyName, boolean index)
+ throws RepositoryException;
}
Modified: trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/History.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/History.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/History.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -1,25 +1,38 @@
package org.jboss.shotoku;
+import org.jboss.shotoku.exceptions.RepositoryException;
+import org.jboss.shotoku.exceptions.ResourceDoesNotExist;
+
/**
- * @author adamw
- * An interface that should be implemented by classes which represent
- * a node's history.
+ * @author adamw An interface that should be implemented by classes which
+ * represent a node's history.
*/
public interface History {
/**
- * Gets the number of revisions for this node's history.
- * @return
+ * Gets the number of revisions of this node's history.
+ *
+ * @return Number of revisions of this node's history.
+ * @throws RepositoryException
*/
- public int getRevisionsCount();
+ public int getRevisionsCount() throws RepositoryException;
+
/**
* Gets a node with a given revision.
- * @param revision Revision number to get.
+ *
+ * @param revision
+ * Revision number to get.
* @return A node at the given revision.
+ * @throws ResourceDoesNotExist
+ * @throws RepositoryException
*/
- public Node getNodeAtRevision(int revision);
+ public Node getNodeAtRevision(int revision) throws ResourceDoesNotExist,
+ RepositoryException;
+
/**
* Gets a list of all nodes in this history.
+ *
* @return A list of all nodes in this history.
+ * @throws RepositoryException
*/
- public NodeList getAllRevisions();
+ public NodeList getAllRevisions() throws RepositoryException;
}
Modified: trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/Node.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/Node.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/Node.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -2,50 +2,76 @@
import java.io.InputStream;
+import org.jboss.shotoku.exceptions.RepositoryException;
+
/**
- * @author adamw
- * An interface which should be implemented by classes representing a node,
- * that is a resource, which is versionable and has some text content.
+ * @author adamw An interface which should be implemented by classes
+ * representing a node, that is a resource, which is versionable and has
+ * some text content.
*/
public interface Node extends AbstractResource {
/**
* Gets the content of this node.
+ *
* @return Content of this node.
+ * @throws RepositoryException
*/
- public String getContent();
+ public String getContent() throws RepositoryException;
+
/**
* Sets the content of this node.
- * @param content New content of this node.
+ *
+ * @param content
+ * New content of this node.
*/
public void setContent(String content);
+
/**
* Gets a history of this node.
+ *
* @return A history of this node.
+ * @throws RepositoryException
*/
- public History getHistory();
+ public History getHistory() throws RepositoryException;
+
/**
* Gets the revision number of this node.
+ *
* @return Revision number of this node.
+ * @throws RepositoryException
*/
- public int getRevisionNumber();
+ public int getRevisionNumber() throws RepositoryException;
+
/**
* Copies this node's content to the given file.
- * @param filename Name of the file to which to copy this node's content.
+ *
+ * @param filename
+ * Name of the file to which to copy this node's content.
+ * @throws RepositoryException
*/
- public void copyToFile(String filename);
+ public void copyToFile(String filename) throws RepositoryException;
+
/**
* Gets the content of this node as an input stream.
+ *
* @return Content of this node as an input stream.
+ * @throws RepositoryException
*/
- public InputStream getContentInputStream();
+ public InputStream getContentInputStream() throws RepositoryException;
+
/**
* Gets the length of this node's content.
+ *
* @return Length of this node's content.
+ * @throws RepositoryException
*/
- public long getLength();
+ public long getLength() throws RepositoryException;
+
/**
* Gets the last modification time of this node.
+ *
* @return Last modification time of this node.
+ * @throws RepositoryException
*/
- public long getLastModfication();
+ public long getLastModfication() throws RepositoryException;
}
Modified: trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/NodeList.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/NodeList.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/NodeList.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -5,7 +5,8 @@
/**
* @author adamw
- * TODO
+ * A class representing a list of nodes and providing the possibility to
+ * manipulate these nodes.
*/
public class NodeList {
private List<Node> nodeList;
@@ -18,10 +19,18 @@
this.nodeList = nodeList;
}
+ /**
+ * Adds the given node to the node list.
+ * @param node Node to add.
+ */
public void add(Node node) {
nodeList.add(node);
}
+ /**
+ * Gets a <code>java.util.List</code> representation of this node list.
+ * @return A <code>java.util.List</code> representation of this node list.
+ */
public List toList() {
return nodeList;
}
Added: trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/NodeReadOnly.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/NodeReadOnly.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/NodeReadOnly.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -0,0 +1,5 @@
+package org.jboss.shotoku.exceptions;
+
+public class NodeReadOnly extends RuntimeException {
+
+}
Added: trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/RepositoryException.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/RepositoryException.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/RepositoryException.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -0,0 +1,7 @@
+package org.jboss.shotoku.exceptions;
+
+public class RepositoryException extends RuntimeException {
+ public RepositoryException(Exception e) {
+ super(e);
+ }
+}
Added: trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/ResourceAlreadyExists.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/ResourceAlreadyExists.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/ResourceAlreadyExists.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -0,0 +1,5 @@
+package org.jboss.shotoku.exceptions;
+
+public class ResourceAlreadyExists extends RuntimeException {
+
+}
Added: trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/ResourceDoesNotExist.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/ResourceDoesNotExist.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/ResourceDoesNotExist.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -0,0 +1,5 @@
+package org.jboss.shotoku.exceptions;
+
+public class ResourceDoesNotExist extends RuntimeException {
+
+}
Modified: trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/AbstractSvnResource.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/AbstractSvnResource.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/AbstractSvnResource.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -5,8 +5,13 @@
import java.util.Map;
import org.jboss.shotoku.AbstractResource;
+import org.jboss.shotoku.exceptions.RepositoryException;
public abstract class AbstractSvnResource implements AbstractResource {
+ /**
+ * <code>modifiedProperties</code> - a map of properties that have been
+ * modified for this resource and have to be written upon save.
+ */
private Map<String, String> modifiedProperties;
protected SvnService service;
@@ -25,19 +30,45 @@
}
public String getProperty(String name) {
- return service.getProperty(id, fullPath, name);
+ // First trying to get the properties from the ones that have been
+ // already modified, only if it hasn't been written, getting it
+ // from svn.
+ if (modifiedProperties.containsKey(name))
+ return modifiedProperties.get(name);
+
+ try {
+ return service.getProperty(id, fullPath, name);
+ } catch (SvnOperationFailed e) {
+ throw new RepositoryException(e);
+ }
}
public void setProperty(String name, String value) {
modifiedProperties.put(name, value);
}
- protected boolean save() {
+ /**
+ * Checks if there are any changes to properties in this resource.
+ * @return True if there are any changes in properties.
+ */
+ protected boolean checkForChanges() {
+ return modifiedProperties.size() > 1;
+ }
+
+ /**
+ * Saves modified properties, if any, and clears the modified
+ * properties map.
+ */
+ protected void save() {
for (String name : modifiedProperties.keySet()) {
- service.setProperty(id, fullPath, name,
- modifiedProperties.get(name));
+ try {
+ service.setProperty(id, fullPath, name,
+ modifiedProperties.get(name));
+ } catch (SvnOperationFailed e) {
+ throw new RepositoryException(e);
+ }
}
- return modifiedProperties.size() > 1;
+ modifiedProperties.clear();
}
}
Modified: trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnContentManager.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnContentManager.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnContentManager.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -6,12 +6,26 @@
import org.jboss.shotoku.Directory;
import org.jboss.shotoku.Node;
import org.jboss.shotoku.NodeList;
-import org.jboss.shotoku.exceptions.NodeDoesNotExist;
+import org.jboss.shotoku.exceptions.RepositoryException;
+import org.jboss.shotoku.exceptions.ResourceDoesNotExist;
import org.jboss.shotoku.search.SearchParameters;
+/**
+ * @author adamw
+ * An implementation of the content manager based on subversion.
+ */
public class SvnContentManager extends ContentManager {
+ /**
+ * <code>prefix</code> - prefix of this content manager.
+ */
private String prefix;
+ /**
+ * <code>id</code> - id of a corresponding repository.
+ */
private String id;
+ /**
+ * <code>service</code> - service interface binding.
+ */
private SvnService service;
public SvnContentManager(String id, String prefix) {
@@ -23,13 +37,29 @@
service = Tools.getService();
}
+ /**
+ * Gets a full repository path for the given path - that is, adds a prefix
+ * this content manager's prefix.
+ * @param path Path to this resource.
+ * @return A prefixed path to the given resource.
+ */
private String getPrefixedPath(String path) {
return prefix + '/' + path;
}
+ /**
+ * Gets a <code>java.io.File</code> object that corresponds to a resource
+ * that, in the repository, can be found under the given path.
+ * @param path Path to the resource in the repository.
+ * @return A <code>java.io.File</code> object for the given path.
+ */
private File getFileForPath(String path) {
- return new File(
- service.getFileSystemPath(id, getPrefixedPath(path)));
+ try {
+ return new File(
+ service.getFileSystemPath(id, getPrefixedPath(path)));
+ } catch (SvnOperationFailed e) {
+ throw new RepositoryException(e);
+ }
}
@Override
@@ -42,7 +72,7 @@
File file = getFileForPath(path);
if (!file.isFile())
- throw new NodeDoesNotExist();
+ throw new ResourceDoesNotExist();
return new SvnHeadNode(id, getPrefixedPath(path), file);
}
@@ -52,7 +82,7 @@
File file = getFileForPath(path);
if (!file.isFile())
- throw new NodeDoesNotExist();
+ throw new ResourceDoesNotExist();
return new SvnDirectory(id, getPrefixedPath(path), file);
}
Modified: trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnDirectory.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnDirectory.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnDirectory.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -1,31 +1,90 @@
package org.jboss.shotoku.svn;
import java.io.File;
+import java.io.FilenameFilter;
+import java.util.ArrayList;
import java.util.List;
import org.jboss.shotoku.Directory;
import org.jboss.shotoku.Node;
import org.jboss.shotoku.NodeList;
+import org.jboss.shotoku.exceptions.RepositoryException;
public class SvnDirectory extends AbstractSvnResource implements Directory {
public SvnDirectory(String id, String fullPath, File file) {
super(id, fullPath, file);
}
-
+
public NodeList getNodes() {
- throw new RuntimeException("Operation not yet implemented");
+ List<Node> ret = new ArrayList<Node>();
+
+ try {
+ // Filtering files from this directory and adding them.
+ for (String directory : new File(service.getFileSystemPath(id,
+ fullPath)).list(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ if (new File(dir.getAbsolutePath() + File.separator + name)
+ .isDirectory())
+ return false;
+ return true;
+ }
+ })) {
+ String childFullPath = fullPath + '/' + directory;
+ ret.add(new SvnHeadNode(id, childFullPath, new File(service
+ .getFileSystemPath(id, childFullPath))));
+ }
+ } catch (SvnOperationFailed e) {
+ throw new RepositoryException(e);
+ }
+
+ return new NodeList(ret);
}
public List<Directory> getDirectories() {
- throw new RuntimeException("Operation not yet implemented");
+ List<Directory> ret = new ArrayList<Directory>();
+
+ try {
+ // Filtering directories from this directory and adding them.
+ for (String directory : new File(service.getFileSystemPath(id,
+ fullPath)).list(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ if (name.equals(".svn"))
+ return false;
+ if (new File(dir.getAbsolutePath() + File.separator + name)
+ .isDirectory())
+ return true;
+ return false;
+ }
+ })) {
+ String childFullPath = fullPath + '/' + directory;
+ ret.add(new SvnDirectory(id, childFullPath, new File(service
+ .getFileSystemPath(id, childFullPath))));
+ }
+ } catch (SvnOperationFailed e) {
+ throw new RepositoryException(e);
+ }
+
+ return ret;
}
public Node newNode(String name) {
- throw new RuntimeException("Operation not yet implemented");
+ String childFullPath = fullPath + '/' + name;
+ try {
+ return new SvnNewNode(id, childFullPath, new File(service
+ .getFileSystemPath(id, childFullPath)));
+ } catch (SvnOperationFailed e) {
+ throw new RepositoryException(e);
+ }
}
public Directory newDirectory(String name) {
- throw new RuntimeException("Operation not yet implemented");
+ String childFullPath = fullPath + '/' + name;
+ try {
+ return new SvnNewDirectory(id, childFullPath, new File(service
+ .getFileSystemPath(id, childFullPath)));
+ } catch (SvnOperationFailed e) {
+ throw new RepositoryException(e);
+ }
}
public boolean hasIndex(String propertyName) {
Added: trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHeadNode.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHeadNode.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHeadNode.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -0,0 +1,128 @@
+package org.jboss.shotoku.svn;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+
+import org.jboss.shotoku.Directory;
+import org.jboss.shotoku.History;
+import org.jboss.shotoku.exceptions.RepositoryException;
+
+public class SvnHeadNode extends SvnNode {
+ private String newContent;
+ private String oldContent;
+
+ public SvnHeadNode(String id, String fullPath, File file) {
+ super(id, fullPath, file);
+ newContent = null;
+ }
+
+ public String getContent() {
+ if (newContent != null) return newContent;
+
+ if (oldContent == null) {
+ try {
+ BufferedReader bf = new BufferedReader(new FileReader(file));
+
+ StringBuffer sf = new StringBuffer();
+ while (true) {
+ String line = bf.readLine();
+ if (line == null)
+ break;
+ sf.append(line);
+ sf.append('\n');
+ }
+
+ oldContent = sf.toString();
+ bf.close();
+ } catch (IOException e) {
+ throw new RepositoryException(e);
+ }
+ }
+
+ return oldContent;
+ }
+
+ public void setContent(String content) {
+ newContent = content;
+ }
+
+ public History getHistory() {
+ throw new RuntimeException("Operation not yet implemented");
+ }
+
+ public int getRevisionNumber() {
+ throw new RuntimeException("Operation not yet implemented");
+ }
+
+ public InputStream getContentInputStream() {
+ try {
+ return new FileInputStream(file);
+ } catch (FileNotFoundException e) {
+ throw new RepositoryException(e);
+ }
+ }
+
+ public long getLength() {
+ return file.length();
+ }
+
+ public long getLastModfication() {
+ return file.lastModified();
+ }
+
+ public Directory getParent() {
+ throw new RuntimeException("Operation not yet implemented");
+ }
+
+ protected boolean checkForChanges() {
+ return newContent != null || super.checkForChanges();
+ }
+
+ public void save(String logMessage) {
+ // Checking if there is anything to save.
+ if (!checkForChanges()) return;
+
+ try {
+ service.getWriteLock(id, fullPath);
+
+ // Saving modified properties.
+ save();
+
+ // Saving modified content.
+ if (newContent != null) {
+ PrintWriter pw;
+
+ try {
+ pw = new PrintWriter(file);
+ } catch (FileNotFoundException e) {
+ service.putWriteLock(id, fullPath);
+ throw new RepositoryException(e);
+ }
+
+ pw.println(newContent);
+ pw.close();
+
+ oldContent = newContent;
+ newContent = null;
+ }
+
+ service.commit(id, fullPath, logMessage);
+ } catch (SvnOperationFailed e) {
+ throw new RepositoryException(e);
+ }
+ }
+
+ public String getLogMessage() {
+ throw new RuntimeException("Operation not yet implemented");
+ }
+
+ public void delete() {
+ throw new RuntimeException("Operation not yet implemented");
+ }
+}
Added: trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHistoricNode.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHistoricNode.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHistoricNode.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -0,0 +1,66 @@
+package org.jboss.shotoku.svn;
+
+import java.io.File;
+import java.io.InputStream;
+
+import org.jboss.shotoku.Directory;
+import org.jboss.shotoku.History;
+import org.jboss.shotoku.exceptions.NodeReadOnly;
+
+public class SvnHistoricNode extends SvnNode {
+ public SvnHistoricNode(String id, String fullPath, File file) {
+ super(id, fullPath, file);
+ }
+
+ public String getContent() {
+ throw new RuntimeException("Operation not yet implemented");
+ }
+
+ public History getHistory() {
+ throw new RuntimeException("Operation not yet implemented");
+ }
+
+ public int getRevisionNumber() {
+ throw new RuntimeException("Operation not yet implemented");
+ }
+
+ public InputStream getContentInputStream() {
+ throw new RuntimeException("Operation not yet implemented");
+ }
+
+ public long getLength() {
+ throw new RuntimeException("Operation not yet implemented");
+ }
+
+ public long getLastModfication() {
+ throw new RuntimeException("Operation not yet implemented");
+ }
+
+ public String getProperty(String arg0) {
+ throw new RuntimeException("Operation not yet implemented");
+ }
+
+ public Directory getParent() {
+ throw new RuntimeException("Operation not yet implemented");
+ }
+
+ public String getLogMessage() {
+ throw new RuntimeException("Operation not yet implemented");
+ }
+
+ public void setContent(String content) {
+ throw new NodeReadOnly();
+ }
+
+ public void setProperty(String name, String value) {
+ throw new NodeReadOnly();
+ }
+
+ public void save(String logMessage) {
+ throw new NodeReadOnly();
+ }
+
+ public void delete() {
+ throw new NodeReadOnly();
+ }
+}
Added: trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnNewDirectory.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnNewDirectory.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnNewDirectory.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -0,0 +1,97 @@
+package org.jboss.shotoku.svn;
+
+import java.io.File;
+import java.util.List;
+
+import org.jboss.shotoku.Directory;
+import org.jboss.shotoku.Node;
+import org.jboss.shotoku.NodeList;
+import org.jboss.shotoku.exceptions.RepositoryException;
+
+public class SvnNewDirectory extends SvnDirectory {
+ private boolean saved;
+
+ public SvnNewDirectory(String id, String fullPath, File file) {
+ super(id, fullPath, file);
+
+ saved = false;
+ }
+
+ @Override
+ public void delete() {
+ // We only have to delete a corresponding directory if this directory
+ // has been saved already.
+ if (saved)
+ super.delete();
+ }
+
+ @Override
+ public List<Directory> getDirectories() {
+ if (saved)
+ return super.getDirectories();
+ else
+ return null;
+ }
+
+ @Override
+ public String getLogMessage() {
+ if (saved)
+ return super.getLogMessage();
+ else
+ return null;
+ }
+
+ @Override
+ public NodeList getNodes() {
+ if (saved)
+ return super.getNodes();
+ else
+ return null;
+ }
+
+ @Override
+ public boolean hasIndex(String propertyName) {
+ if (saved)
+ return super.hasIndex(propertyName);
+ else
+ return false;
+ }
+
+ @Override
+ public Directory newDirectory(String name) {
+ if (saved)
+ return super.newDirectory(name);
+ else
+ return null;
+ }
+
+ @Override
+ public Node newNode(String name) {
+ if (saved)
+ return super.newNode(name);
+ else
+ return null;
+ }
+
+ @Override
+ public void save(String logMessage) {
+ if (!saved) {
+ file.mkdir();
+
+ try {
+ service.add(id, fullPath);
+ } catch (SvnOperationFailed e) {
+ throw new RepositoryException(e);
+ }
+ saved = true;
+ }
+
+ super.save(logMessage);
+ }
+
+ @Override
+ public void setIndex(String propertyName, boolean index) {
+ if (saved)
+ super.setIndex(propertyName, index);
+ }
+}
Added: trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnNewNode.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnNewNode.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnNewNode.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -0,0 +1,113 @@
+package org.jboss.shotoku.svn;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Calendar;
+
+import org.jboss.shotoku.History;
+import org.jboss.shotoku.exceptions.RepositoryException;
+
+public class SvnNewNode extends SvnHeadNode {
+ private String content;
+ private boolean saved;
+
+ public SvnNewNode(String id, String fullPath, File file) {
+ super(id, fullPath, file);
+
+ content = null;
+ saved = false;
+ }
+
+ @Override
+ public void delete() {
+ // We only have to delete a corresponding file if this node has
+ // been saved already.
+ if (saved)
+ super.delete();
+ }
+
+ @Override
+ public String getContent() {
+ if (saved)
+ return super.getContent();
+ else
+ return content;
+ }
+
+ @Override
+ public InputStream getContentInputStream() {
+ if (saved)
+ return super.getContentInputStream();
+ else
+ // TODO
+ return null;
+ }
+
+ @Override
+ public History getHistory() {
+ if (saved)
+ return super.getHistory();
+ else
+ return null;
+ }
+
+ @Override
+ public long getLastModfication() {
+ if (saved)
+ return super.getLastModfication();
+ else
+ return Calendar.getInstance().getTimeInMillis();
+ }
+
+ @Override
+ public long getLength() {
+ if (saved)
+ return super.getLength();
+ else
+ return content.length();
+ }
+
+ @Override
+ public String getLogMessage() {
+ if (saved)
+ return super.getLogMessage();
+ else
+ return null;
+ }
+
+ @Override
+ public int getRevisionNumber() {
+ if (saved)
+ return super.getRevisionNumber();
+ else
+ return -1;
+ }
+
+ @Override
+ public void save(String logMessage) {
+ if (!saved) {
+ try {
+ file.createNewFile();
+ service.add(id, fullPath);
+ } catch (IOException e) {
+ throw new RepositoryException(e);
+ } catch (SvnOperationFailed e) {
+ throw new RepositoryException(e);
+ }
+
+ saved = true;
+ }
+
+ super.save(logMessage);
+ }
+
+ @Override
+ public void setContent(String content) {
+ if (saved)
+ super.setContent(content);
+ else
+ this.content = content;
+ }
+
+}
Added: trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnOperationFailed.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnOperationFailed.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnOperationFailed.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -0,0 +1,11 @@
+package org.jboss.shotoku.svn;
+
+public class SvnOperationFailed extends Exception {
+ public SvnOperationFailed(Exception e) {
+ super(e);
+ }
+
+ public SvnOperationFailed(String msg) {
+ super(msg);
+ }
+}
Modified: trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnService.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnService.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnService.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -1,17 +1,118 @@
package org.jboss.shotoku.svn;
public abstract interface SvnService {
- public abstract void commit(String id, String path, String logMessage);
+ /**
+ * Gets an exclusive write lock for a given path. The lock should be
+ * requiered before making any changes to the file. Later, the file
+ * must be added for a commit, unless an exception is thrown. After
+ * commiting the file, the lock is released.
+ * @param id Id of the repository.
+ * @param path Path to lock.
+ */
+ public abstract void getWriteLock(String id, String path);
+ /**
+ * Puts an earlier acquiered exclusive write lock for a given path.
+ * This should be called only in case of an internal node-implementation
+ * execption that occures while saving.
+ * @param id Id of the repository.
+ * @param path Path to release the lock for.
+ */
+ public abstract void putWriteLock(String id, String path);
+ /**
+ * Adds the given path to a commite quese of a repository with the
+ * given id.
+ * @param id Id of the repository.
+ * @param path Path to commit.
+ * @param logMessage Log message to commit with.
+ * @throws SvnOperationFailed
+ */
+ public abstract void commit(String id, String path, String logMessage)
+ throws SvnOperationFailed;
+ /**
+ * Sets a property on the given path.
+ * @param id Id of the repository.
+ * @param path Path to set the property on.
+ * @param name Name of the property to set.
+ * @param value Value of the property to set.
+ * @throws SvnOperationFailed
+ */
public abstract void setProperty(String id, String path, String name,
- String value);
- public abstract String getProperty(String id, String path, String name);
+ String value) throws SvnOperationFailed;
+ /**
+ * Gets a property from the given path.
+ * @param id Id of the repository.
+ * @param path Path to get the property from.
+ * @param name Name of the property to get.
+ * @return Value of the property or null, if it is not set.
+ * @throws SvnOperationFailed
+ */
+ public abstract String getProperty(String id, String path, String name)
+ throws SvnOperationFailed;
+ /**
+ * Gets content of a node at the specified revision.
+ * @param id Id of the repository.
+ * @param path Path to a file to get the revision of.
+ * @param revision Number of the revision to get (revisions are counted
+ * from 1 with step 1).
+ * @return String representation of this node's content at the given
+ * revision or null, if this node does not have the given revision.
+ * @throws SvnOperationFailed
+ */
public abstract String getNodeAtRevision(String id, String path,
- int revision);
- public abstract String getLogMessage(String id, String revision);
- public abstract int getRevisionCount(String id, String path);
- public abstract void delete(String id, String path);
- public abstract void add(String id, String path);
- public abstract String getFileSystemPath(String id, String path);
+ int revision) throws SvnOperationFailed;
+ /**
+ * Gets a log message with which the given revision was commited.
+ * @param id Id of the repository.
+ * @param revision Number of the revision (svn revision number).
+ * @return Log message with which the given reivison was commited
+ * or null, if no such revision exists.
+ * @throws SvnOperationFailed
+ */
+ public abstract String getLogMessage(String id, String revision)
+ throws SvnOperationFailed;
+ /**
+ * Gets the number of revisions of a given path.
+ * @param id Id of the repository.
+ * @param path Path for which to determine the number of revisions
+ * (number of different versions).
+ * @return Number of revisions of a given path.
+ * @throws SvnOperationFailed
+ */
+ public abstract int getRevisionCount(String id, String path)
+ throws SvnOperationFailed;
+ /**
+ * Deletes a given path (node/ directory) from the repository. The
+ * resource is automatically added to a commite queue.
+ * @param id Id of the repository.
+ * @param path Path to delete.
+ * @throws SvnOperationFailed
+ */
+ public abstract void delete(String id, String path)
+ throws SvnOperationFailed;
+ /**
+ * Adds a given path (node/ directory) to a repository. The resource
+ * is automatically added to a commite queue.
+ * @param id Id of the repository.
+ * @param path Path to add.
+ * @throws SvnOperationFailed
+ */
+ public abstract void add(String id, String path)
+ throws SvnOperationFailed;
+ /**
+ * Gets a full path on the file system to a resource with the given
+ * repository-path.
+ * @param id Id of the repository.
+ * @param path Path to the resource.
+ * @return A full path on the file system to the given resource (represented
+ * by a path).
+ * @throws SvnOperationFailed
+ */
+ public abstract String getFileSystemPath(String id, String path)
+ throws SvnOperationFailed;
+ /**
+ * <code>SVN_SERVICE_NAME</code> - name under which the svn service
+ * is registered.
+ */
public final static String SVN_SERVICE_NAME = "shotoku:service=svn";
}
Added: trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/Tools.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/Tools.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/Tools.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -0,0 +1,24 @@
+package org.jboss.shotoku.svn;
+
+import javax.management.MalformedObjectNameException;
+
+import org.jboss.mx.util.MBeanProxyExt;
+import org.jboss.mx.util.MBeanServerLocator;
+
+public class Tools {
+ private static SvnService instance;
+
+ public static SvnService getService() {
+ try {
+ if (instance == null)
+ instance = (SvnService) MBeanProxyExt.create(
+ SvnService.class,
+ SvnService.SVN_SERVICE_NAME,
+ MBeanServerLocator.locate());
+
+ return instance;
+ } catch (MalformedObjectNameException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
Modified: trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnRepository.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnRepository.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnRepository.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -2,8 +2,11 @@
import java.io.File;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
+import java.util.concurrent.Semaphore;
import org.apache.log4j.Logger;
import org.tmatesoft.svn.core.SVNException;
@@ -15,6 +18,11 @@
import org.tmatesoft.svn.core.wc.SVNUpdateClient;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
+/**
+ * @author adamw
+ * A class for performing operations on a single subversion repository and
+ * its local working copy.
+ */
public class SvnRepository {
private static final Logger log = Logger.getLogger(SvnRepository.class);
@@ -23,6 +31,7 @@
private String localpath;
private File wc;
private Set<String[]> toCommit;
+ private Map<String, Semaphore> semaphores;
public SvnRepository(String username, String password,
String url, String localpath) {
@@ -35,8 +44,13 @@
wc = new File(localpath);
toCommit = Collections.synchronizedSet(new HashSet<String[]>());
+ semaphores = new HashMap<String, Semaphore>();
}
+ /**
+ * Tries to perform a cleanup on the local working copy. Called in case
+ * of execptions that occure while performing other operations.
+ */
private void tryCleanup() {
try {
ourClientManager.getWCClient().doCleanup(wc);
@@ -45,6 +59,9 @@
}
}
+ /**
+ * Updates the local working copy.
+ */
public synchronized void update() {
try {
SVNURL repositoryURL = SVNURL.parseURIEncoded(url);
@@ -69,10 +86,18 @@
}
}
+ /**
+ * Adds a given file with a given log message to a commit queue.
+ * @param path Path (file/ directory) to commit.
+ * @param logMessage Log message with thich to commit.
+ */
public void addToCommit(String path, String logMessage) {
toCommit.add(new String[] { path, logMessage });
}
+ /**
+ * Commits all paths (files/ directories) that were scheduled for a commit.
+ */
public void commit() {
String[][] allToCommit;
@@ -84,12 +109,16 @@
for (String[] oneToCommit : allToCommit) {
SVNCommitClient commitClient = ourClientManager.getCommitClient();
try {
+ log.info("Commiting: " + oneToCommit[0]);
commitClient.doCommit(
new File[] { new File(getFileSystemPath(oneToCommit[0])) },
false, oneToCommit[1], true, false);
+
+ putWriteLock(oneToCommit[0]);
} catch (SVNException e) {
tryCleanup();
- log.warn("Commiting of " + oneToCommit[0] + " failed", e);
+ putWriteLock(oneToCommit[0]);
+ log.warn("Commiting: " + oneToCommit[0] + " failed", e);
}
}
}
@@ -98,6 +127,34 @@
return replaceSeparators(localpath + '/' + path);
}
+ public void getWriteLock(String path) {
+ Semaphore s;
+
+ synchronized (semaphores) {
+ s = semaphores.get(path);
+ if (s == null) {
+ s = new Semaphore(1);
+ semaphores.put(path, s);
+ }
+ }
+
+ try {
+ s.acquire();
+ } catch (InterruptedException e) {
+ // We never interrupt the threads.
+ }
+ }
+
+ public void putWriteLock(String path) {
+ Semaphore s;
+
+ synchronized (semaphores) {
+ s = semaphores.get(path);
+ }
+
+ s.release();
+ }
+
private String replaceSeparators(String path) {
return '/' == File.separatorChar ?
path : path.replace('/', File.separatorChar);
Modified: trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceImpl.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceImpl.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceImpl.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -27,7 +27,7 @@
* <code>DEFAULT_TIMER_INTERVAL</code> - default interval lenght of the
* timer.
*/
- private final static long DEFAULT_TIMER_INTERVAL = 1000*60; // 1 minute
+ private final static long DEFAULT_TIMER_INTERVAL = 1000*5; // 5 seconds
private long timerInterval;
@EJB
@@ -120,6 +120,14 @@
* SvnService implementation.
*/
+ public void getWriteLock(String id, String path) {
+ repositories.get(id).getWriteLock(path);
+ }
+
+ public void putWriteLock(String id, String path) {
+ repositories.get(id).putWriteLock(path);
+ }
+
public void commit(String id, String path, String logMessage) {
repositories.get(id).addToCommit(path, logMessage);
}
Added: trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceLocal.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceLocal.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceLocal.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -0,0 +1,7 @@
+package org.jboss.shotoku.svn.service;
+
+public interface SvnServiceLocal {
+ public void setTimerInterval(long timerInterval);
+ public long getTimerInterval();
+ public void update();
+}
Added: trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceManagement.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceManagement.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceManagement.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -0,0 +1,12 @@
+package org.jboss.shotoku.svn.service;
+
+import org.jboss.annotation.ejb.Management;
+import org.jboss.shotoku.svn.SvnService;
+
+@Management
+public interface SvnServiceManagement extends SvnService, SvnServiceLocal {
+ public void create() throws Exception;
+ public void start() throws Exception;
+ public void stop();
+ public void destroy();
+}
Modified: trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceTimer.java
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceTimer.java 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceTimer.java 2005-09-26 20:56:01 UTC (rev 1215)
@@ -10,7 +10,6 @@
import javax.ejb.Timer;
import javax.management.MalformedObjectNameException;
-import org.apache.log4j.Logger;
import org.jboss.mx.util.MBeanProxyExt;
import org.jboss.mx.util.MBeanServerLocator;
import org.jboss.shotoku.svn.SvnService;
@@ -18,7 +17,7 @@
@Stateless
@Local(SvnServiceTimerLocal.class)
public class SvnServiceTimer {
- private static final Logger log = Logger.getLogger(SvnServiceTimer.class);
+ //private static final Logger log = Logger.getLogger(SvnServiceTimer.class);
private @Resource SessionContext ctx;
public void scheduleTimer(long interval) {
@@ -35,9 +34,7 @@
SvnService.SVN_SERVICE_NAME,
MBeanServerLocator.locate()));
- log.info("Updating svn service ...");
ssi.update();
- log.info("Done updating svn service.");
scheduleTimer(ssi.getTimerInterval());
} catch (MalformedObjectNameException e) {
Property changes on: trunk/forge/portal-extensions/shotoku/shotoku-test
___________________________________________________________________
Name: svn:ignore
+ target
.classpath
.settings
.project
Added: trunk/forge/portal-extensions/shotoku/shotoku-test/maven.xml
===================================================================
--- trunk/forge/portal-extensions/shotoku/shotoku-test/maven.xml 2005-09-26 20:14:14 UTC (rev 1214)
+++ trunk/forge/portal-extensions/shotoku/shotoku-test/maven.xml 2005-09-26 20:56:01 UTC (rev 1215)
@@ -0,0 +1,30 @@
+<!--
+ JBoss, the OpenSource J2EE webOS
+ Distributable under LGPL license.
+ See terms of license at gnu.org.
+ -->
+<project xmlns:j="jelly:core" ...
[truncated message content] |