Author: dam...@jb... Date: 2005-09-27 10:55:35 -0400 (Tue, 27 Sep 2005) New Revision: 1222 Added: qa/forge/portal-extensions/forge-theme/jbossForgeLayout.war/portlet.css qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/ qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/NodeReadOnly.java qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/RepositoryException.java qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/ResourceAlreadyExists.java qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/ResourceDoesNotExist.java qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceLocal.java qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceManagement.java qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/operations/ qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/operations/AddDelayedOperation.java qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/operations/CommitDelayedOperation.java qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/operations/DelayedOperation.java qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHeadNode.java qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHistoricNode.java qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnNewDirectory.java qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnNewNode.java qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnOperationFailed.java qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/Tools.java qa/forge/portal-extensions/shotoku/shotoku-test/ qa/forge/portal-extensions/shotoku/shotoku-test/maven.xml qa/forge/portal-extensions/shotoku/shotoku-test/project.properties qa/forge/portal-extensions/shotoku/shotoku-test/project.xml qa/forge/portal-extensions/shotoku/shotoku-test/src/ qa/forge/portal-extensions/shotoku/shotoku-test/src/java/ qa/forge/portal-extensions/shotoku/shotoku-test/src/java/org/ qa/forge/portal-extensions/shotoku/shotoku-test/src/java/org/jboss/ qa/forge/portal-extensions/shotoku/shotoku-test/src/java/org/jboss/shotoku/ qa/forge/portal-extensions/shotoku/shotoku-test/src/java/org/jboss/shotoku/test/ qa/forge/portal-extensions/shotoku/shotoku-test/src/java/org/jboss/shotoku/test/ShotokuTest.java qa/forge/portal-extensions/shotoku/shotoku-test/src/web/ qa/forge/portal-extensions/shotoku/shotoku-test/src/web/WEB-INF/ qa/forge/portal-extensions/shotoku/shotoku-test/src/web/WEB-INF/web.xml Removed: qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/NodeReadOnly.java qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/RepositoryException.java qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/ResourceAlreadyExists.java qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/ResourceDoesNotExist.java qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/operations/AddDelayedOperation.java qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/operations/CommitDelayedOperation.java qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/operations/DelayedOperation.java qa/forge/portal-extensions/shotoku/shotoku-test/maven.xml qa/forge/portal-extensions/shotoku/shotoku-test/project.properties qa/forge/portal-extensions/shotoku/shotoku-test/project.xml qa/forge/portal-extensions/shotoku/shotoku-test/src/ qa/forge/portal-extensions/shotoku/shotoku-test/src/java/ qa/forge/portal-extensions/shotoku/shotoku-test/src/java/org/ qa/forge/portal-extensions/shotoku/shotoku-test/src/java/org/jboss/ qa/forge/portal-extensions/shotoku/shotoku-test/src/java/org/jboss/shotoku/ qa/forge/portal-extensions/shotoku/shotoku-test/src/java/org/jboss/shotoku/test/ qa/forge/portal-extensions/shotoku/shotoku-test/src/java/org/jboss/shotoku/test/ShotokuTest.java qa/forge/portal-extensions/shotoku/shotoku-test/src/web/ qa/forge/portal-extensions/shotoku/shotoku-test/src/web/WEB-INF/ qa/forge/portal-extensions/shotoku/shotoku-test/src/web/WEB-INF/web.xml Modified: qa/forge/portal-extensions/forge-forums/scripts/all.sql qa/forge/portal-extensions/forge-forums/scripts/conv.sql qa/forge/portal-extensions/forge-navigation/src/java/org/jboss/forge/navigation/Entry.java qa/forge/portal-extensions/forge-theme/jbossForgeLayout.war/layouts/jbossForge.jsp qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/AbstractResource.java qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/ContentManager.java qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/Directory.java qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/History.java qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/Node.java qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/NodeList.java qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnRepository.java qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceImpl.java qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceTimer.java qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/AbstractSvnResource.java qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnContentManager.java qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnDirectory.java qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnService.java Log: MERGED: -r 1214:1221 trunk forge into qa forge for bug fix 1.0.4 release. Modified: qa/forge/portal-extensions/forge-forums/scripts/all.sql =================================================================== --- qa/forge/portal-extensions/forge-forums/scripts/all.sql 2005-09-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/forge-forums/scripts/all.sql 2005-09-27 14:55:35 UTC (rev 1222) @@ -5,7 +5,3 @@ \. conv.sql \. portal-keys.sql \. fix.sql - --- TODO: --- - migrate topics watch --- - lost fields - what's with them? Modified: qa/forge/portal-extensions/forge-forums/scripts/conv.sql =================================================================== --- qa/forge/portal-extensions/forge-forums/scripts/conv.sql 2005-09-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/forge-forums/scripts/conv.sql 2005-09-27 14:55:35 UTC (rev 1222) @@ -102,3 +102,65 @@ SELECT 1, p.jbp_uid FROM jbp_users p WHERE p.jbp_uname = "adamw"; INSERT INTO jbp_role_membership (jbp_rid, jbp_uid) SELECT 1, p.jbp_uid FROM jbp_users p WHERE p.jbp_uname = "admin"; + +-- Importing user properties. +INSERT INTO jbp_user_prop (jbp_uid, jbp_name, jbp_value) + SELECT n.pn_uid, "portal.user.im.aim", n.pn_user_aim + FROM nuke_users n + WHERE n.pn_user_aim IS NOT NULL; + +INSERT INTO jbp_user_prop (jbp_uid, jbp_name, jbp_value) + SELECT n.pn_uid, "portal.user.im.icq", n.pn_user_icq + FROM nuke_users n + WHERE n.pn_user_icq IS NOT NULL; + +INSERT INTO jbp_user_prop (jbp_uid, jbp_name, jbp_value) + SELECT n.pn_uid, "portal.user.im.msnm", n.pn_user_msnm + FROM nuke_users n + WHERE n.pn_user_msnm IS NOT NULL; + +INSERT INTO jbp_user_prop (jbp_uid, jbp_name, jbp_value) + SELECT n.pn_uid, "portal.user.interests", n.pn_user_intrest + FROM nuke_users n + WHERE n.pn_user_intrest IS NOT NULL; + +INSERT INTO jbp_user_prop (jbp_uid, jbp_name, jbp_value) + SELECT n.pn_uid, "portal.user.homepage", n.pn_url + FROM nuke_users n + WHERE n.pn_url IS NOT NULL; + +INSERT INTO jbp_user_prop (jbp_uid, jbp_name, jbp_value) + SELECT n.pn_uid, "portal.user.occupation", n.pn_user_occ + FROM nuke_users n + WHERE n.pn_user_occ IS NOT NULL; + +INSERT INTO jbp_user_prop (jbp_uid, jbp_name, jbp_value) + SELECT n.pn_uid, "portal.user.signature", n.pn_user_sig + FROM nuke_users n + WHERE n.pn_user_sig IS NOT NULL; + +INSERT INTO jbp_user_prop (jbp_uid, jbp_name, jbp_value) + SELECT n.pn_uid, "portal.user.im.yim", n.pn_user_yim + FROM nuke_users n + WHERE n.pn_user_yim IS NOT NULL; + +INSERT INTO jbp_user_prop (jbp_uid, jbp_name, jbp_value) + SELECT n.pn_uid, "portal.user.time-zone-offset", n.pn_timezone_offset + FROM nuke_users n + WHERE n.pn_timezone_offset IS NOT NULL; + +INSERT INTO jbp_user_prop (jbp_uid, jbp_name, jbp_value) + SELECT n.pn_uid, "portal.user.location", n.pn_user_from + FROM nuke_users n + WHERE n.pn_user_from IS NOT NULL; + +INSERT INTO jbp_user_prop (jbp_uid, jbp_name, jbp_value) + SELECT n.pn_uid, "portal.user.security.answer", n.pn_answer + FROM nuke_users n + WHERE n.pn_answer IS NOT NULL; + +INSERT INTO jbp_user_prop (jbp_uid, jbp_name, jbp_value) + SELECT n.pn_uid, "portal.user.security.question", n.pn_question + FROM nuke_users n + WHERE n.pn_question IS NOT NULL; + Modified: qa/forge/portal-extensions/forge-navigation/src/java/org/jboss/forge/navigation/Entry.java =================================================================== --- qa/forge/portal-extensions/forge-navigation/src/java/org/jboss/forge/navigation/Entry.java 2005-09-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/forge-navigation/src/java/org/jboss/forge/navigation/Entry.java 2005-09-27 14:55:35 UTC (rev 1222) @@ -73,8 +73,6 @@ private Set<String> allLinks; - - public Entry(String portalName, Node root) { permission = XmlTools.getAttributeValue(root, PERMISSION_ATTRIBUTE); Modified: qa/forge/portal-extensions/forge-theme/jbossForgeLayout.war/layouts/jbossForge.jsp =================================================================== --- qa/forge/portal-extensions/forge-theme/jbossForgeLayout.war/layouts/jbossForge.jsp 2005-09-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/forge-theme/jbossForgeLayout.war/layouts/jbossForge.jsp 2005-09-27 14:55:35 UTC (rev 1222) @@ -19,6 +19,7 @@ <link rel="stylesheet" href="/jbossForge/common.css" type="text/css" media="all"> <link rel="stylesheet" href="/jbossForge/jboss-forge.css" type="text/css" media="all"> <link rel="stylesheet" href="/jbossForge/jboss-forge-forums.css" type="text/css" media="all"> +<link rel="stylesheet" href="/jbossForge/portlet.css" type="text/css" media="all"> <!-- insert the dynamically determined theme elements here, or use the 'simple-sample' theme by default --> <!-- <p:theme themeName='jboss-forge' /> --> Copied: qa/forge/portal-extensions/forge-theme/jbossForgeLayout.war/portlet.css (from rev 1221, trunk/forge/portal-extensions/forge-theme/jbossForgeLayout.war/portlet.css) Modified: qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/AbstractResource.java =================================================================== --- qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/AbstractResource.java 2005-09-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/AbstractResource.java 2005-09-27 14:55:35 UTC (rev 1222) @@ -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: qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/ContentManager.java =================================================================== --- qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/ContentManager.java 2005-09-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/ContentManager.java 2005-09-27 14:55:35 UTC (rev 1222) @@ -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: qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/Directory.java =================================================================== --- qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/Directory.java 2005-09-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/Directory.java 2005-09-27 14:55:35 UTC (rev 1222) @@ -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: qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/History.java =================================================================== --- qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/History.java 2005-09-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/History.java 2005-09-27 14:55:35 UTC (rev 1222) @@ -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: qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/Node.java =================================================================== --- qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/Node.java 2005-09-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/Node.java 2005-09-27 14:55:35 UTC (rev 1222) @@ -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: qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/NodeList.java =================================================================== --- qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/NodeList.java 2005-09-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/NodeList.java 2005-09-27 14:55:35 UTC (rev 1222) @@ -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; } Copied: qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions (from rev 1221, trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions) Deleted: qa/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-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/NodeReadOnly.java 2005-09-27 14:55:35 UTC (rev 1222) @@ -1,5 +0,0 @@ -package org.jboss.shotoku.exceptions; - -public class NodeReadOnly extends RuntimeException { - -} Copied: qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/NodeReadOnly.java (from rev 1221, trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/NodeReadOnly.java) Deleted: qa/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-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/RepositoryException.java 2005-09-27 14:55:35 UTC (rev 1222) @@ -1,7 +0,0 @@ -package org.jboss.shotoku.exceptions; - -public class RepositoryException extends RuntimeException { - public RepositoryException(Exception e) { - super(e); - } -} Copied: qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/RepositoryException.java (from rev 1221, trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/RepositoryException.java) Deleted: qa/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-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/ResourceAlreadyExists.java 2005-09-27 14:55:35 UTC (rev 1222) @@ -1,5 +0,0 @@ -package org.jboss.shotoku.exceptions; - -public class ResourceAlreadyExists extends RuntimeException { - -} Copied: qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/ResourceAlreadyExists.java (from rev 1221, trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/ResourceAlreadyExists.java) Deleted: qa/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-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/ResourceDoesNotExist.java 2005-09-27 14:55:35 UTC (rev 1222) @@ -1,5 +0,0 @@ -package org.jboss.shotoku.exceptions; - -public class ResourceDoesNotExist extends RuntimeException { - -} Copied: qa/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/ResourceDoesNotExist.java (from rev 1221, trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/exceptions/ResourceDoesNotExist.java) Modified: qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/AbstractSvnResource.java =================================================================== --- qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/AbstractSvnResource.java 2005-09-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/AbstractSvnResource.java 2005-09-27 14:55:35 UTC (rev 1222) @@ -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() > 0; + } + + /** + * 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: qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnContentManager.java =================================================================== --- qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnContentManager.java 2005-09-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnContentManager.java 2005-09-27 14:55:35 UTC (rev 1222) @@ -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); } @@ -51,8 +81,8 @@ public Directory getDirectory(String path) { File file = getFileForPath(path); - if (!file.isFile()) - throw new NodeDoesNotExist(); + if (!file.isDirectory()) + throw new ResourceDoesNotExist(); return new SvnDirectory(id, getPrefixedPath(path), file); } Modified: qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnDirectory.java =================================================================== --- qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnDirectory.java 2005-09-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnDirectory.java 2005-09-27 14:55:35 UTC (rev 1222) @@ -1,31 +1,102 @@ 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; +import org.jboss.shotoku.exceptions.ResourceAlreadyExists; 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 { + File newFile = new File(service.getFileSystemPath(id, + childFullPath)); + + if (newFile.exists()) + throw new ResourceAlreadyExists(); + + return new SvnNewNode(id, childFullPath, newFile); + } catch (SvnOperationFailed e) { + throw new RepositoryException(e); + } } public Directory newDirectory(String name) { - throw new RuntimeException("Operation not yet implemented"); + String childFullPath = fullPath + '/' + name; + try { + File newDir = new File(service.getFileSystemPath(id, + childFullPath)); + + if (newDir.exists()) + throw new ResourceAlreadyExists(); + + return new SvnNewDirectory(id, childFullPath, newDir); + } catch (SvnOperationFailed e) { + throw new RepositoryException(e); + } } public boolean hasIndex(String propertyName) { Copied: qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHeadNode.java (from rev 1221, trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHeadNode.java) Copied: qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHistoricNode.java (from rev 1221, trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHistoricNode.java) Copied: qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnNewDirectory.java (from rev 1221, trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnNewDirectory.java) Copied: qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnNewNode.java (from rev 1221, trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnNewNode.java) Copied: qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnOperationFailed.java (from rev 1221, trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnOperationFailed.java) Modified: qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnService.java =================================================================== --- qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnService.java 2005-09-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnService.java 2005-09-27 14:55:35 UTC (rev 1222) @@ -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"; } Copied: qa/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/Tools.java (from rev 1221, trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/Tools.java) Modified: qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnRepository.java =================================================================== --- qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnRepository.java 2005-09-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnRepository.java 2005-09-27 14:55:35 UTC (rev 1222) @@ -1,20 +1,31 @@ package org.jboss.shotoku.svn.service; import java.io.File; +import java.util.ArrayList; import java.util.Collections; -import java.util.HashSet; -import java.util.Set; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Semaphore; import org.apache.log4j.Logger; +import org.jboss.shotoku.svn.SvnOperationFailed; +import org.jboss.shotoku.svn.service.operations.DelayedOperation; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.wc.ISVNOptions; +import org.tmatesoft.svn.core.wc.ISVNPropertyHandler; import org.tmatesoft.svn.core.wc.SVNClientManager; -import org.tmatesoft.svn.core.wc.SVNCommitClient; +import org.tmatesoft.svn.core.wc.SVNPropertyData; import org.tmatesoft.svn.core.wc.SVNRevision; 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); @@ -22,7 +33,8 @@ private String url; private String localpath; private File wc; - private Set<String[]> toCommit; + private List<DelayedOperation> delayedOperations; + private Map<String, Semaphore> semaphores; public SvnRepository(String username, String password, String url, String localpath) { @@ -34,9 +46,14 @@ this.localpath = localpath; wc = new File(localpath); - toCommit = Collections.synchronizedSet(new HashSet<String[]>()); + delayedOperations = Collections.synchronizedList(new ArrayList<DelayedOperation>()); + 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 +62,9 @@ } } + /** + * Updates the local working copy. + */ public synchronized void update() { try { SVNURL repositoryURL = SVNURL.parseURIEncoded(url); @@ -64,32 +84,43 @@ SVNRevision.HEAD, SVNRevision.HEAD, true); } } catch (SVNException e) { + // TODO e.printStackTrace(); + tryCleanup(); } } - public void addToCommit(String path, String logMessage) { - toCommit.add(new String[] { path, logMessage }); + /** + * Adds a delayed operation to an execution queue. + * @param op Operation to add. + */ + public void addDelayedOperation(DelayedOperation op) { + delayedOperations.add(op); } - public void commit() { - String[][] allToCommit; + /** + * Performs all scheduled delayed operations. + */ + public void performDelayedOperations() { + DelayedOperation[] allOps; - synchronized (toCommit) { - allToCommit = toCommit.toArray(new String[0][0]); - toCommit.clear(); + synchronized (delayedOperations) { + allOps = delayedOperations.toArray(new DelayedOperation[0]); + delayedOperations.clear(); } - for (String[] oneToCommit : allToCommit) { - SVNCommitClient commitClient = ourClientManager.getCommitClient(); + for (DelayedOperation op : allOps) { try { - commitClient.doCommit( - new File[] { new File(getFileSystemPath(oneToCommit[0])) }, - false, oneToCommit[1], true, false); + log.info("Performing delayed op: " + op.getClass().getName()); + + op.performOperation(ourClientManager); } catch (SVNException e) { + // TODO Delete + e.printStackTrace(); + tryCleanup(); - log.warn("Commiting of " + oneToCommit[0] + " failed", e); + log.warn("Performing delayed op: " + op.getClass().getName() + " failed.", e); } } } @@ -98,8 +129,62 @@ 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); } + + public String getProperty(String path, String name) + throws SvnOperationFailed { + try { + SVNPropertyData data = + ourClientManager.getWCClient().doGetProperty( + new File(getFileSystemPath(path)), name, + SVNRevision.WORKING, SVNRevision.WORKING, + false); + + return data == null ? null : data.getValue(); + } catch (SVNException e) { + throw new SvnOperationFailed(e); + } + } + + public void setProperty(String path, String name, String value) + throws SvnOperationFailed { + try { + ourClientManager.getWCClient().doSetProperty( + new File(getFileSystemPath(path)), name, + value, true, false, ISVNPropertyHandler.NULL); + } catch (SVNException e) { + throw new SvnOperationFailed(e); + } + } } Modified: qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceImpl.java =================================================================== --- qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceImpl.java 2005-09-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceImpl.java 2005-09-27 14:55:35 UTC (rev 1222) @@ -12,7 +12,10 @@ import org.jboss.annotation.ejb.Service; import org.jboss.shotoku.ContentManager; import org.jboss.shotoku.Tools; +import org.jboss.shotoku.svn.SvnOperationFailed; import org.jboss.shotoku.svn.SvnService; +import org.jboss.shotoku.svn.service.operations.AddDelayedOperation; +import org.jboss.shotoku.svn.service.operations.CommitDelayedOperation; import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory; import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl; import org.w3c.dom.Document; @@ -27,7 +30,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 @@ -112,7 +115,7 @@ public void update() { for (SvnRepository repo : repositories.values()) { repo.update(); - repo.commit(); + repo.performDelayedOperations(); } } @@ -120,16 +123,29 @@ * SvnService implementation. */ - public void commit(String id, String path, String logMessage) { - repositories.get(id).addToCommit(path, logMessage); + 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) + throws SvnOperationFailed { + SvnRepository repo = repositories.get(id); + repo.addDelayedOperation( new CommitDelayedOperation(repo, path, + logMessage)); + } - public void setProperty(String id, String path, String name, String value) { - + public void setProperty(String id, String path, String name, String value) + throws SvnOperationFailed{ + repositories.get(id).setProperty(path, name, value); } - public String getProperty(String id, String path, String name) { - return null; + public String getProperty(String id, String path, String name) + throws SvnOperationFailed{ + return repositories.get(id).getProperty(path, name); } public String getNodeAtRevision(String id, String path, int revision) { @@ -148,8 +164,9 @@ } - public void add(String id, String path) { - + public void add(String id, String path) throws SvnOperationFailed { + SvnRepository repo = repositories.get(id); + repo.addDelayedOperation(new AddDelayedOperation(repo, path)); } public String getFileSystemPath(String id, String path) { Copied: qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceLocal.java (from rev 1221, trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceLocal.java) Copied: qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceManagement.java (from rev 1221, trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceManagement.java) Modified: qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceTimer.java =================================================================== --- qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceTimer.java 2005-09-27 14:24:12 UTC (rev 1221) +++ qa/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnServiceTimer.java 2005-09-27 14:55:35 UTC (rev 1222) @@ -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.up... [truncated message content] |