[dna-commits] DNA SVN: r1130 - in branches/eclipse/dna-web-jcr-rest-client: src/main/java/org/jboss/dna/web/jcr/rest/client and 6 other directories.

dna-commits at lists.jboss.org dna-commits at lists.jboss.org
Fri Jul 24 14:13:17 EDT 2009


Author: elvisisking
Date: 2009-07-24 14:13:16 -0400 (Fri, 24 Jul 2009)
New Revision: 1130

Modified:
   branches/eclipse/dna-web-jcr-rest-client/pom.xml
   branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/IJcrConstants.java
   branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/IMessages.java
   branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/IRestClient.java
   branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/ServerManager.java
   branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/ServerRegistryEvent.java
   branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/Utils.java
   branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/domain/Repository.java
   branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/domain/Server.java
   branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/domain/Workspace.java
   branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/domain/validation/ServerValidator.java
   branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/FileNode.java
   branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/FolderNode.java
   branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/JsonNode.java
   branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/JsonRestClient.java
   branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/JsonUtils.java
   branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/RepositoryNode.java
   branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/ServerNode.java
   branches/eclipse/dna-web-jcr-rest-client/src/main/resources/org/jboss/dna/web/jcr/rest/client/Messages.properties
   branches/eclipse/dna-web-jcr-rest-client/src/test/java/org/jboss/dna/web/jcr/rest/client/MockRestExecutor.java
   branches/eclipse/dna-web-jcr-rest-client/src/test/java/org/jboss/dna/web/jcr/rest/client/json/JsonRestClientTest.java
Log:
Added trace messages, null arg checks, and got publish and unpublish tests working.

Modified: branches/eclipse/dna-web-jcr-rest-client/pom.xml
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/pom.xml	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/pom.xml	2009-07-24 18:13:16 UTC (rev 1130)
@@ -126,7 +126,8 @@
 							<!-- application to deploy -->
 							<deployable>
 								<groupId>org.jboss.dna</groupId>
-								<artifactId>dna-web-jcr-rest-war</artifactId>
+								<artifactId>dna-web-jcr-rest-war
+								</artifactId>
 								<type>war</type>
 								<properties>
 									<context>resources</context>

Modified: branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/IJcrConstants.java
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/IJcrConstants.java	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/IJcrConstants.java	2009-07-24 18:13:16 UTC (rev 1130)
@@ -55,6 +55,20 @@
      * @since 0.6
      */
     String FOLDER_NODE_TYPE = "nt:folder"; //$NON-NLS-1$
+    
+    /**
+     * The JCR data property name (<code>jcr:lastModified</code>).
+     * 
+     * @since 0.6
+     */
+    String LAST_MODIFIED = "jcr:lastModified"; //$NON-NLS-1$
+    
+    /**
+     * The JCR data property name (<code>jcr:lastModified</code>).
+     * 
+     * @since 0.6
+     */
+    String MIME_TYPE = "jcr:mimeType"; //$NON-NLS-1$
 
     /**
      * The JCR primary type property name (<code>jcr:primaryType</code>).

Modified: branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/IMessages.java
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/IMessages.java	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/IMessages.java	2009-07-24 18:13:16 UTC (rev 1130)
@@ -41,6 +41,8 @@
 
     String ErrorSavingServerRegistry = "ErrorSavingServerRegistry"; //$NON-NLS-1$
 
+    String NullArgumentMsg = "NullArgumentMsg"; //$NON-NLS-1$
+
     String RepositoryEmptyNameMsg = "RepositoryEmptyNameMsg"; //$NON-NLS-1$
 
     String RepositoryNullServerMsg = "RepositoryNullServerMsg"; //$NON-NLS-1$
@@ -76,17 +78,23 @@
     String WorkspaceNullRepositoryMsg = "WorkspaceNullRepositoryMsg"; //$NON-NLS-1$
 
     String WorkspaceShortDescription = "WorkspaceShortDescription"; //$NON-NLS-1$
-    
+
     // JsonRestClient messages
-    
+
+    String ConnectionErrorMsg = "ConnectionErrorMsg"; //$NON-NLS-1$
+
     String CreateFileFailedMsg = "CreateFileFailedMsg"; //$NON-NLS-1$
-    
+
     String CreateFolderFailedMsg = "CreateFolderFailedMsg"; //$NON-NLS-1$
 
     String GetRepositoriesFailedMsg = "GetRepositoriesFailedMsg"; //$NON-NLS-1$
 
     String GetWorkspacesFailedMsg = "GetWorkspacesFailedMsg"; //$NON-NLS-1$
 
+    String PublishFailedMsg = "PublishFailedMsg"; //$NON-NLS-1$
+
     String UnpublishFailedMsg = "UnpublishFailedMsg"; //$NON-NLS-1$
+    
+    String UnpublishNeverPublishedMsg = "UnpublishNeverPublishedMsg"; //$NON-NLS-1$
 
 }

Modified: branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/IRestClient.java
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/IRestClient.java	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/IRestClient.java	2009-07-24 18:13:16 UTC (rev 1130)
@@ -25,6 +25,7 @@
 
 import java.io.File;
 import java.util.Collection;
+import org.jboss.dna.web.jcr.rest.client.Status.Severity;
 import org.jboss.dna.web.jcr.rest.client.domain.Repository;
 import org.jboss.dna.web.jcr.rest.client.domain.Server;
 import org.jboss.dna.web.jcr.rest.client.domain.Workspace;
@@ -40,7 +41,7 @@
      * @throws Exception if there is a problem obtaining the repositories
      * @since 0.6
      */
-    public abstract Collection<Repository> getRepositories( Server server ) throws Exception;
+    Collection<Repository> getRepositories( Server server ) throws Exception;
 
     /**
      * @param repository the repository whose workspaces are being requested (never <code>null</code>)
@@ -48,28 +49,30 @@
      * @throws Exception if there is a problem obtaining the workspaces
      * @since 0.6
      */
-    public abstract Collection<Workspace> getWorkspaces( Repository repository ) throws Exception;
+    Collection<Workspace> getWorkspaces( Repository repository ) throws Exception;
 
     /**
      * @param workspace the workspace where the resource will be published (never <code>null</code>)
-     * @param path the path to the folder where the file will be published
+     * @param path the path to the folder where the file will be published (never <code>null</code>)
      * @param file the resource being published (never <code>null</code>)
-     * @throws Exception if there is a problem publishing
+     * @return a status of the publishing operation outcome (never <code>null</code>)
      * @since 0.6
      */
-    public abstract void publish( Workspace workspace,
-                                  String path,
-                                  File file ) throws Exception;
+    Status publish( Workspace workspace,
+                    String path,
+                    File file );
 
     /**
+     * If a file being unpublished is not found in the workspace an {@link Severity#INFO info status} results.
+     * 
      * @param workspace the workspace where the resource will be unpublished (never <code>null</code>)
      * @param path the path to the folder where the file is published (never <code>null</code>)
      * @param file the file being unpublished (never <code>null</code>)
-     * @throws Exception if there is a problem unpublishing
+     * @return a status of the unpublishing operation outcome (never <code>null</code>)
      * @since 0.6
      */
-    public abstract void unpublish( Workspace workspace,
-                                    String path,
-                                    File file ) throws Exception;
+    Status unpublish( Workspace workspace,
+                      String path,
+                      File file );
 
 }

Modified: branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/ServerManager.java
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/ServerManager.java	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/ServerManager.java	2009-07-24 18:13:16 UTC (rev 1130)
@@ -26,7 +26,6 @@
 import static org.jboss.dna.web.jcr.rest.client.IMessages.MESSAGES;
 import java.io.File;
 import java.io.FileOutputStream;
-import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -161,6 +160,8 @@
      */
     public ServerManager( String stateLocationPath,
                           IRestClient restExecutor ) {
+        Utils.nullArgumentCheck("restExecutor", restExecutor); //$NON-NLS-1$
+
         this.servers = new ArrayList<Server>();
         this.stateLocationPath = stateLocationPath;
         this.restExecutor = restExecutor;
@@ -174,22 +175,24 @@
     /**
      * Listeners already registered will not be added again.
      * 
-     * @param listener the listener being register to receive events
+     * @param listener the listener being register to receive events (never <code>null</code>)
      * @return <code>true</code> if listener was added
      * @since 0.6
      */
     public boolean addRegistryListener( IServerRegistryListener listener ) {
+        Utils.nullArgumentCheck("listener", listener); //$NON-NLS-1$
         return this.listeners.addIfAbsent(listener);
     }
 
     /**
      * Registers the specified <code>Server</code>.
      * 
-     * @param server the server being added
+     * @param server the server being added (never <code>null</code>)
      * @return a status indicating if the server was added to the registry
      * @since 0.6
      */
     public Status addServer( Server server ) {
+        Utils.nullArgumentCheck("server", server); //$NON-NLS-1$
         return internalAddServer(server, true);
     }
 
@@ -221,7 +224,7 @@
     }
 
     /**
-     * @param server the server whose repositories are being requested
+     * @param server the server whose repositories are being requested (never <code>null</code>)
      * @return the server repositories (never <code>null</code>)
      * @throws Exception if there is a problem obtaining the repositories or if the server is not registered
      * @throws RuntimeException if the server is not registered
@@ -229,6 +232,8 @@
      * @since 0.6
      */
     public Collection<Repository> getRepositories( Server server ) throws Exception {
+        Utils.nullArgumentCheck("server", server); //$NON-NLS-1$
+
         try {
             this.serverLock.readLock().lock();
 
@@ -238,15 +243,14 @@
             }
 
             // server must be registered in order to obtain it's repositories
-            String pattern = MESSAGES.getString(IMessages.ServerManagerUnregisteredServer);
-            throw new RuntimeException(MessageFormat.format(pattern, server.getShortDescription()));
+            throw new RuntimeException(Utils.getMessage(IMessages.ServerManagerUnregisteredServer, server.getShortDescription()));
         } finally {
             this.serverLock.readLock().unlock();
         }
     }
 
     /**
-     * @param repository the repository whose workspaces are being requested
+     * @param repository the repository whose workspaces are being requested (never <code>null</code>)
      * @return the DNA repository workspaces (never <code>null</code>)
      * @throws Exception if there is a problem obtaining the workspaces
      * @throws RuntimeException if the repository's server is not registered
@@ -254,6 +258,8 @@
      * @since 0.6
      */
     public Collection<Workspace> getWorkspaces( Repository repository ) throws Exception {
+        Utils.nullArgumentCheck("repository", repository); //$NON-NLS-1$
+
         try {
             this.serverLock.readLock().lock();
 
@@ -263,8 +269,8 @@
             }
 
             // a repository's server must be registered in order to obtain it's workspaces
-            String pattern = MESSAGES.getString(IMessages.ServerManagerUnregisteredServer);
-            throw new RuntimeException(MessageFormat.format(pattern, repository.getServer().getShortDescription()));
+            throw new RuntimeException(Utils.getMessage(IMessages.ServerManagerUnregisteredServer,
+                                                        repository.getServer().getShortDescription()));
         } finally {
             this.serverLock.readLock().unlock();
         }
@@ -302,10 +308,7 @@
         }
 
         // server already exists
-        String pattern = MESSAGES.getString(IMessages.ServerExistsMsg);
-        String msg = MessageFormat.format(pattern, server.getShortDescription());
-        Status status = new Status(Severity.ERROR, msg, null);
-        return status;
+        return new Status(Severity.ERROR, Utils.getMessage(IMessages.ServerExistsMsg, server.getShortDescription()), null);
     }
 
     /**
@@ -342,19 +345,19 @@
         }
 
         // server could not be removed
-        String pattern = MESSAGES.getString(IMessages.ServerManagerRegistryRemoveUnexpectedError);
-        String msg = MessageFormat.format(pattern, server.getShortDescription());
-        Status status = new Status(Severity.ERROR, msg, null);
-        return status;
+        return new Status(Severity.ERROR, Utils.getMessage(IMessages.ServerManagerRegistryRemoveUnexpectedError,
+                                                           server.getShortDescription()), null);
     }
 
     /**
-     * @param server the server being tested
+     * @param server the server being tested (never <code>null</code>)
      * @return <code>true</code> if the server has been registered
      * @see #addServer(Server)
      * @since 0.6
      */
     public boolean isRegistered( Server server ) {
+        Utils.nullArgumentCheck("server", server); //$NON-NLS-1$
+
         try {
             this.serverLock.readLock().lock();
 
@@ -425,20 +428,22 @@
     }
 
     /**
-     * @param listener the listener being unregistered and will no longer receive events
+     * @param listener the listener being unregistered and will no longer receive events (never <code>null</code>)
      * @return <code>true</code> if listener was removed
      * @since 0.6
      */
     public boolean removeRegistryListener( IServerRegistryListener listener ) {
+        Utils.nullArgumentCheck("listener", listener); //$NON-NLS-1$
         return this.listeners.remove(listener);
     }
 
     /**
-     * @param server the server being removed
-     * @return a status indicating if the specified server was removed from the registry
+     * @param server the server being removed (never <code>null</code>)
+     * @return a status indicating if the specified server was removed from the registry (never <code>null</code>)
      * @since 0.6
      */
     public Status removeServer( Server server ) {
+        Utils.nullArgumentCheck("server", server); //$NON-NLS-1$
         return internalRemoveServer(server, true);
     }
 
@@ -474,8 +479,8 @@
                         }
                     }
                 } catch (Exception e) {
-                    String pattern = MESSAGES.getString(IMessages.ErrorRestoringServerRegistry);
-                    return new Status(Severity.ERROR, MessageFormat.format(pattern, getStateFileName()), e);
+                    return new Status(Severity.ERROR,
+                                      Utils.getMessage(IMessages.ErrorRestoringServerRegistry, getStateFileName()), e);
                 }
             }
         }
@@ -521,16 +526,15 @@
                 transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); //$NON-NLS-1$ //$NON-NLS-2$
                 transformer.transform(source, resultXML);
             } catch (Exception e) {
-                String pattern = MESSAGES.getString(IMessages.ErrorSavingServerRegistry);
-                return new Status(Severity.ERROR, MessageFormat.format(pattern, getStateFileName()), e);
+                return new Status(Severity.ERROR, Utils.getMessage(IMessages.ErrorSavingServerRegistry, getStateFileName()), e);
             }
         } else if ((this.stateLocationPath != null) && stateFileExists()) {
             // delete current registry file since all servers have been deleted
             try {
                 new File(getStateFileName()).delete();
             } catch (Exception e) {
-                String pattern = MESSAGES.getString(IMessages.ErrorDeletingServerRegistryFile);
-                return new Status(Severity.ERROR, MessageFormat.format(pattern, getStateFileName()), e);
+                return new Status(Severity.ERROR,
+                                  Utils.getMessage(IMessages.ErrorDeletingServerRegistryFile, getStateFileName()), e);
             }
         }
 
@@ -548,13 +552,16 @@
     /**
      * Updates the server registry with a new version of a server.
      * 
-     * @param previousServerVersion the version of the server being replaced
-     * @param newServerVersion the new version of the server being put in the server registry
-     * @return a status indicating if the server was updated in the registry
+     * @param previousServerVersion the version of the server being replaced (never <code>null</code>)
+     * @param newServerVersion the new version of the server being put in the server registry (never <code>null</code>)
+     * @return a status indicating if the server was updated in the registry (never <code>null</code>)
      * @since 0.6
      */
     public Status updateServer( Server previousServerVersion,
                                 Server newServerVersion ) {
+        Utils.nullArgumentCheck("previousServerVersion", previousServerVersion); //$NON-NLS-1$
+        Utils.nullArgumentCheck("newServerVersion", newServerVersion); //$NON-NLS-1$
+
         Status status = null;
 
         try {
@@ -572,20 +579,17 @@
                 }
 
                 // unexpected problem adding new version of server to registry
-                String pattern = MESSAGES.getString(IMessages.ServerManagerRegistryUpdateAddError);
-                String msg = MessageFormat.format(pattern, status.getMessage());
-                status = new Status(Severity.ERROR, msg, status.getException());
-                return status;
+                return new Status(Severity.ERROR, Utils.getMessage(IMessages.ServerManagerRegistryUpdateAddError,
+                                                                   status.getMessage()), status.getException());
             }
         } finally {
             this.serverLock.writeLock().unlock();
         }
 
         // unexpected problem removing server from registry
-        String pattern = MESSAGES.getString(IMessages.ServerManagerRegistryUpdateRemoveError);
-        String msg = MessageFormat.format(pattern, status.getMessage());
-        status = new Status(Severity.ERROR, msg, status.getException());
-        return status;
+        return new Status(Severity.ERROR,
+                          Utils.getMessage(IMessages.ServerManagerRegistryUpdateRemoveError, status.getMessage()),
+                          status.getException());
     }
 
 }

Modified: branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/ServerRegistryEvent.java
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/ServerRegistryEvent.java	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/ServerRegistryEvent.java	2009-07-24 18:13:16 UTC (rev 1130)
@@ -68,34 +68,39 @@
     // ===========================================================================================================================
 
     /**
-     * @param newServer the server that was added to the server registry
-     * @return the event
+     * @param newServer the server that was added to the server registry (never <code>null</code>)
+     * @return the event (never <code>null</code>)
      * @see Type#NEW
      * @since 0.6
      */
     public static ServerRegistryEvent createNewEvent( Server newServer ) {
+        Utils.nullArgumentCheck("newServer", newServer); //$NON-NLS-1$
         return new ServerRegistryEvent(Type.NEW, newServer);
     }
 
     /**
-     * @param removedServer the server removed from the server registry
-     * @return the event
+     * @param removedServer the server removed from the server registry (never <code>null</code>)
+     * @return the event (never <code>null</code>)
      * @see Type#REMOVE
      * @since 0.6
      */
     public static ServerRegistryEvent createRemoveEvent( Server removedServer ) {
+        Utils.nullArgumentCheck("removedServer", removedServer); //$NON-NLS-1$
         return new ServerRegistryEvent(Type.REMOVE, removedServer);
     }
 
     /**
-     * @param previousServerVersion the server being updated (this instance is no longer found in the server registry)
-     * @param newServerVersion the updated version of the server (this is now contained in the server registry)
-     * @return the event
+     * @param previousServerVersion the server being updated (never <code>null</code>)
+     * @param newServerVersion the updated version of the server (never <code>null</code>)
+     * @return the event (never <code>null</code>)
      * @see Type#UPDATE
      * @since 0.6
      */
     public static ServerRegistryEvent createUpdateEvent( Server previousServerVersion,
                                                          Server newServerVersion ) {
+        Utils.nullArgumentCheck("previousServerVersion", previousServerVersion); //$NON-NLS-1$
+        Utils.nullArgumentCheck("newServerVersion", newServerVersion); //$NON-NLS-1$
+
         ServerRegistryEvent event = new ServerRegistryEvent(Type.UPDATE, previousServerVersion);
         event.updatedServer = newServerVersion;
         return event;

Modified: branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/Utils.java
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/Utils.java	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/Utils.java	2009-07-24 18:13:16 UTC (rev 1130)
@@ -23,6 +23,10 @@
  */
 package org.jboss.dna.web.jcr.rest.client;
 
+import static org.jboss.dna.web.jcr.rest.client.IMessages.MESSAGES;
+import static org.jboss.dna.web.jcr.rest.client.IMessages.NullArgumentMsg;
+import java.text.MessageFormat;
+
 /**
  * @author Dan Florian
  * @since 0.6
@@ -34,9 +38,9 @@
     // ===========================================================================================================================
 
     /**
-     * @param thisObj an object being compared
-     * @param thatObj the other object being compared
-     * @return <code>true</code> if both objects are null or both are not null and equal
+     * @param thisObj an object being compared (may be <code>null</code>)
+     * @param thatObj the other object being compared (may be <code>null</code>)
+     * @return <code>true</code> if both objects are <code>null</code> or both are not <code>null</code> and equal
      * @since 0.6
      */
     public static boolean equivalent( Object thisObj,
@@ -50,6 +54,33 @@
         return thisObj.equals(thatObj);
     }
 
+    /**
+     * @param key the key of the pattern from the {@link IMessages#MESSAGES} resource bundle (never <code>null</code>)
+     * @param arguments the values being inserted into the pattern
+     * @return the localized text
+     * @since 0.6
+     */
+    public static String getMessage( String key,
+                                     Object... arguments ) {
+        Utils.nullArgumentCheck("key", key); //$NON-NLS-1$
+        String pattern = MESSAGES.getString(key);
+        return MessageFormat.format(pattern, arguments);
+    }
+
+    /**
+     * @param name the argument name
+     * @param value the argument value
+     * @throws IllegalArgumentException if the value is <code>null</code>
+     * @since 0.6
+     */
+    public static void nullArgumentCheck( String name,
+                                          Object value ) throws IllegalArgumentException {
+        if (value == null) {
+            String pattern = MESSAGES.getString(NullArgumentMsg);
+            throw new IllegalArgumentException(MessageFormat.format(pattern, name));
+        }
+    }
+
     // ===========================================================================================================================
     // Constructors
     // ===========================================================================================================================

Modified: branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/domain/Repository.java
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/domain/Repository.java	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/domain/Repository.java	2009-07-24 18:13:16 UTC (rev 1130)
@@ -23,11 +23,10 @@
  */
 package org.jboss.dna.web.jcr.rest.client.domain;
 
-import static org.jboss.dna.web.jcr.rest.client.IMessages.MESSAGES;
 import static org.jboss.dna.web.jcr.rest.client.IMessages.RepositoryShortDescription;
-import java.text.MessageFormat;
 import net.jcip.annotations.Immutable;
 import org.jboss.dna.web.jcr.rest.client.Status;
+import org.jboss.dna.web.jcr.rest.client.Utils;
 import org.jboss.dna.web.jcr.rest.client.domain.validation.RepositoryValidator;
 import org.jboss.dna.web.jcr.rest.client.json.JsonUtils;
 
@@ -67,14 +66,17 @@
     /**
      * Constructs a new <code>Repository</code>.
      * 
-     * @param name the repository name
-     * @param server the server where this repository resides
+     * @param name the repository name (never <code>null</code>)
+     * @param server the server where this repository resides (never <code>null</code>)
      * @see RepositoryValidator
      * @throws RuntimeException if any of the input parameters are invalid
      * @since 0.6
      */
     public Repository( String name,
                        Server server ) {
+        Utils.nullArgumentCheck("name", name); //$NON-NLS-1$
+        Utils.nullArgumentCheck("server", server); //$NON-NLS-1$
+
         // validate inputs
         Status status = RepositoryValidator.isValid(name, server);
 
@@ -132,8 +134,9 @@
      * @since 0.6
      */
     public String getShortDescription() {
-        String pattern = MESSAGES.getString(RepositoryShortDescription);
-        return MessageFormat.format(pattern, JsonUtils.decodeEscaping(this.name), this.server.getShortDescription());
+        return Utils.getMessage(RepositoryShortDescription,
+                                JsonUtils.decodeEscaping(this.name),
+                                this.server.getShortDescription());
     }
 
     /**

Modified: branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/domain/Server.java
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/domain/Server.java	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/domain/Server.java	2009-07-24 18:13:16 UTC (rev 1130)
@@ -23,9 +23,7 @@
  */
 package org.jboss.dna.web.jcr.rest.client.domain;
 
-import static org.jboss.dna.web.jcr.rest.client.IMessages.MESSAGES;
 import static org.jboss.dna.web.jcr.rest.client.IMessages.ServerShortDescription;
-import java.text.MessageFormat;
 import net.jcip.annotations.Immutable;
 import org.jboss.dna.web.jcr.rest.client.Status;
 import org.jboss.dna.web.jcr.rest.client.Utils;
@@ -80,9 +78,9 @@
     /**
      * Constructs on new <code>Server</code>.
      * 
-     * @param url the server URL
-     * @param user the server user
-     * @param password the server password
+     * @param url the server URL (never <code>null</code>)
+     * @param user the server user (may be <code>null</code>)
+     * @param password the server password (may be <code>null</code>)
      * @param persistPassword <code>true</code> if the password should be stored
      * @see RepositoryValidator
      * @throws RuntimeException if any of the input parameters are invalid
@@ -92,6 +90,8 @@
                    String user,
                    String password,
                    boolean persistPassword ) {
+        Utils.nullArgumentCheck("url", url); //$NON-NLS-1$
+
         // valid inputs
         Status status = ServerValidator.isValid(url, user, password, persistPassword);
 
@@ -153,8 +153,7 @@
      * @since 0.6
      */
     public String getShortDescription() {
-        String pattern = MESSAGES.getString(ServerShortDescription);
-        return MessageFormat.format(pattern, this.url, this.user);
+        return Utils.getMessage(ServerShortDescription, this.url, this.user);
     }
 
     /**
@@ -198,10 +197,11 @@
     }
 
     /**
-     * @param otherServer the server whose key is being compared
+     * @param otherServer the server whose key is being compared (never <code>null</code>)
      * @return <code>true</code> if the servers have the same key
      */
     public boolean hasSameKey( Server otherServer ) {
+        Utils.nullArgumentCheck("otherServer", otherServer); //$NON-NLS-1$
         return (Utils.equivalent(this.url, otherServer.url) && Utils.equivalent(this.user, otherServer.user));
     }
 
@@ -215,7 +215,7 @@
 
     /**
      * {@inheritDoc}
-     *
+     * 
      * @see java.lang.Object#toString()
      * @since 0.6
      */

Modified: branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/domain/Workspace.java
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/domain/Workspace.java	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/domain/Workspace.java	2009-07-24 18:13:16 UTC (rev 1130)
@@ -23,11 +23,10 @@
  */
 package org.jboss.dna.web.jcr.rest.client.domain;
 
-import static org.jboss.dna.web.jcr.rest.client.IMessages.MESSAGES;
 import static org.jboss.dna.web.jcr.rest.client.IMessages.WorkspaceShortDescription;
-import java.text.MessageFormat;
 import net.jcip.annotations.Immutable;
 import org.jboss.dna.web.jcr.rest.client.Status;
+import org.jboss.dna.web.jcr.rest.client.Utils;
 import org.jboss.dna.web.jcr.rest.client.domain.validation.WorkspaceValidator;
 import org.jboss.dna.web.jcr.rest.client.json.JsonUtils;
 
@@ -65,14 +64,17 @@
     /**
      * Constructs a new <code>Workspace</code>.
      * 
-     * @param name the workspace name
-     * @param repository the repository where this workspace resides
+     * @param name the workspace name (never <code>null</code>)
+     * @param repository the repository where this workspace resides (never <code>null</code>)
      * @see WorkspaceValidator
      * @throws RuntimeException if any of the input parameters are invalid
      * @since 0.6
      */
     public Workspace( String name,
                       Repository repository ) {
+        Utils.nullArgumentCheck("name", name); //$NON-NLS-1$
+        Utils.nullArgumentCheck("repository", repository); //$NON-NLS-1$
+
         // validate inputs
         Status status = WorkspaceValidator.isValid(name, repository);
 
@@ -138,8 +140,9 @@
      * @since 0.6
      */
     public String getShortDescription() {
-        String pattern = MESSAGES.getString(WorkspaceShortDescription);
-        return MessageFormat.format(pattern, JsonUtils.decodeEscaping(this.name), this.repository.getShortDescription());
+        return Utils.getMessage(WorkspaceShortDescription,
+                                JsonUtils.decodeEscaping(this.name),
+                                this.repository.getShortDescription());
     }
 
     /**
@@ -158,7 +161,7 @@
 
     /**
      * {@inheritDoc}
-     *
+     * 
      * @see java.lang.Object#toString()
      * @since 0.6
      */

Modified: branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/domain/validation/ServerValidator.java
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/domain/validation/ServerValidator.java	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/domain/validation/ServerValidator.java	2009-07-24 18:13:16 UTC (rev 1130)
@@ -29,9 +29,9 @@
 import static org.jboss.dna.web.jcr.rest.client.IMessages.ServerExistsMsg;
 import static org.jboss.dna.web.jcr.rest.client.IMessages.ServerInvalidUrlMsg;
 import java.net.URL;
-import java.text.MessageFormat;
 import org.jboss.dna.web.jcr.rest.client.ServerManager;
 import org.jboss.dna.web.jcr.rest.client.Status;
+import org.jboss.dna.web.jcr.rest.client.Utils;
 import org.jboss.dna.web.jcr.rest.client.Status.Severity;
 import org.jboss.dna.web.jcr.rest.client.domain.Server;
 
@@ -67,9 +67,7 @@
         try {
             new URL(url);
         } catch (Exception e) {
-            String pattern = MESSAGES.getString(ServerInvalidUrlMsg);
-            String msg = MessageFormat.format(pattern, url);
-            return new Status(Severity.ERROR, msg, null);
+            return new Status(Severity.ERROR, Utils.getMessage(ServerInvalidUrlMsg, url), null);
         }
 
         return Status.OK_STATUS;
@@ -140,9 +138,7 @@
             Server newServer = new Server(url, user, password, persistPassword);
 
             if (serverManager.isRegistered(newServer)) {
-                String pattern = MESSAGES.getString(ServerExistsMsg);
-                String msg = MessageFormat.format(pattern, newServer.getShortDescription());
-                status = new Status(Severity.ERROR, msg, null);
+                status = new Status(Severity.ERROR, Utils.getMessage(ServerExistsMsg, newServer.getShortDescription()), null);
             }
         }
 

Modified: branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/FileNode.java
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/FileNode.java	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/FileNode.java	2009-07-24 18:13:16 UTC (rev 1130)
@@ -29,11 +29,15 @@
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.net.URL;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.List;
+import java.util.TimeZone;
 import net.jcip.annotations.Immutable;
 import org.codehaus.jettison.json.JSONObject;
 import org.jboss.dna.web.jcr.rest.client.IJcrConstants;
+import org.jboss.dna.web.jcr.rest.client.Utils;
 import org.jboss.dna.web.jcr.rest.client.domain.Workspace;
 
 /**
@@ -75,7 +79,7 @@
     /**
      * @param workspace the workspace being used (never <code>null</code>)
      * @param path the path in the workspace (never <code>null</code>)
-     * @param file the file on the local file system
+     * @param file the file on the local file system (never <code>null</code>)
      * @throws Exception if there is a problem constructing the file node
      * @since 0.6
      */
@@ -83,6 +87,10 @@
                      String path,
                      File file ) throws Exception {
         super(file.getName());
+
+        Utils.nullArgumentCheck("workspace", workspace); //$NON-NLS-1$
+        Utils.nullArgumentCheck("path", path); //$NON-NLS-1$
+
         this.file = file;
         this.path = path;
         this.workspace = workspace;
@@ -105,8 +113,15 @@
         kid.put(IJsonConstants.PROPERTIES_KEY, properties);
         properties.put(IJcrConstants.PRIMARY_TYPE_PROPERTY, IJcrConstants.RESOURCE_NODE_TYPE);
 
-        // TODO need to figure out how to write out file contents
-        properties.put(IJcrConstants.DATA_PROPERTY, readFile(file));
+        // add required jcr:lastModified property
+        Calendar lastModified = Calendar.getInstance();
+        lastModified.setTimeInMillis(file.lastModified());
+        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); //$NON-NLS-1$
+        formatter.setTimeZone(TimeZone.getTimeZone("GMT")); //$NON-NLS-1$
+        properties.put(IJcrConstants.LAST_MODIFIED, formatter.format(lastModified.getTime()));
+
+        // add required jcr:mimeType property (just use a default value)
+        properties.put(IJcrConstants.MIME_TYPE, "application/octet-stream"); //$NON-NLS-1$
     }
 
     // ===========================================================================================================================
@@ -120,7 +135,14 @@
      * @since 0.6
      */
     @Override
-    public byte[] getContent() {
+    public byte[] getContent() throws Exception {
+        // TODO need to figure out how to write binary content to JSONObject
+        // add required jcr:data property (do this lazily only when the content is requested)
+        JSONObject children = (JSONObject)get(IJsonConstants.CHILDREN_KEY);
+        JSONObject kid = (JSONObject)children.get(IJcrConstants.CONTENT_PROPERTY);
+        JSONObject props = (JSONObject)kid.get(IJsonConstants.PROPERTIES_KEY);
+        props.put(IJcrConstants.DATA_PROPERTY, readFile());
+
         return super.getContent();
     }
 
@@ -148,12 +170,17 @@
         return new URL(url.toString());
     }
 
-    private Byte[] readFile( File file ) throws Exception {
+    /**
+     * @return the file content
+     * @throws Exception if there is a problem reading the file
+     * @since 0.6
+     */
+    private Byte[] readFile() throws Exception {
         DataInputStream is = null;
         List<Byte> bytes = new ArrayList<Byte>(1000);
 
         try {
-            is = new DataInputStream(new FileInputStream(file.getAbsoluteFile()));
+            is = new DataInputStream(new FileInputStream(this.file.getAbsoluteFile()));
 
             while (true) {
                 bytes.add(is.readByte());

Modified: branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/FolderNode.java
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/FolderNode.java	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/FolderNode.java	2009-07-24 18:13:16 UTC (rev 1130)
@@ -27,6 +27,7 @@
 import net.jcip.annotations.Immutable;
 import org.codehaus.jettison.json.JSONObject;
 import org.jboss.dna.web.jcr.rest.client.IJcrConstants;
+import org.jboss.dna.web.jcr.rest.client.Utils;
 import org.jboss.dna.web.jcr.rest.client.domain.Workspace;
 
 /**
@@ -60,6 +61,10 @@
     public FolderNode( Workspace workspace,
                        String fullPath ) throws Exception {
         super(fullPath);
+        
+        Utils.nullArgumentCheck("workspace", workspace); //$NON-NLS-1$
+        Utils.nullArgumentCheck("fullPath", fullPath); //$NON-NLS-1$
+
         this.workspace = workspace;
 
         // add properties

Modified: branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/JsonNode.java
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/JsonNode.java	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/JsonNode.java	2009-07-24 18:13:16 UTC (rev 1130)
@@ -25,6 +25,7 @@
 
 import java.net.URL;
 import org.codehaus.jettison.json.JSONObject;
+import org.jboss.dna.web.jcr.rest.client.Utils;
 
 /**
  * @author Dan Florian
@@ -52,6 +53,7 @@
      * @since 0.6
      */
     protected JsonNode( String id ) {
+        Utils.nullArgumentCheck("id", id); //$NON-NLS-1$
         this.id = id;
     }
 
@@ -61,9 +63,10 @@
 
     /**
      * @return the content that gets published
+     * @throws Exception if there is a problem obtaining the node content
      * @since 0.6
      */
-    public byte[] getContent() {
+    public byte[] getContent() throws Exception {
         return toString().getBytes();
     }
 

Modified: branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/JsonRestClient.java
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/JsonRestClient.java	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/JsonRestClient.java	2009-07-24 18:13:16 UTC (rev 1130)
@@ -23,20 +23,24 @@
  */
 package org.jboss.dna.web.jcr.rest.client.json;
 
+import static org.jboss.dna.web.jcr.rest.client.IMessages.ConnectionErrorMsg;
 import static org.jboss.dna.web.jcr.rest.client.IMessages.CreateFileFailedMsg;
 import static org.jboss.dna.web.jcr.rest.client.IMessages.CreateFolderFailedMsg;
 import static org.jboss.dna.web.jcr.rest.client.IMessages.GetRepositoriesFailedMsg;
 import static org.jboss.dna.web.jcr.rest.client.IMessages.GetWorkspacesFailedMsg;
-import static org.jboss.dna.web.jcr.rest.client.IMessages.MESSAGES;
+import static org.jboss.dna.web.jcr.rest.client.IMessages.PublishFailedMsg;
 import static org.jboss.dna.web.jcr.rest.client.IMessages.UnpublishFailedMsg;
 import java.io.File;
+import java.io.IOException;
 import java.net.HttpURLConnection;
 import java.net.URL;
-import java.text.MessageFormat;
 import java.util.Collection;
 import javax.ws.rs.core.MediaType;
 import org.jboss.dna.web.jcr.rest.client.IRestClient;
 import org.jboss.dna.web.jcr.rest.client.Logger;
+import org.jboss.dna.web.jcr.rest.client.Status;
+import org.jboss.dna.web.jcr.rest.client.Utils;
+import org.jboss.dna.web.jcr.rest.client.Status.Severity;
 import org.jboss.dna.web.jcr.rest.client.domain.Repository;
 import org.jboss.dna.web.jcr.rest.client.domain.Server;
 import org.jboss.dna.web.jcr.rest.client.domain.Workspace;
@@ -66,26 +70,33 @@
                                  File file ) throws Exception {
         Logger.trace(JsonRestClient.class,
                      null,
-                     "createFileNode: workspace=" + workspace + ", path=" + path + ", file=" + file.getAbsolutePath()); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+                     "createFileNode: workspace=" + workspace.getName() + ", path=" + path + ", file=" + file.getAbsolutePath()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
         FileNode fileNode = new FileNode(workspace, path, file);
         HttpURLConnection connection = openConnection(fileNode.getUrl(), RequestMethod.POST);
 
         try {
-            Logger.trace(JsonRestClient.class, null, "createFileNode: file node=" + fileNode); //$NON-NLS-1$
+            Logger.trace(JsonRestClient.class, null, "createFileNode: create node=" + fileNode); //$NON-NLS-1$
             connection.getOutputStream().write(fileNode.getContent());
 
             // make sure node was created
             if (connection.getResponseCode() != HttpURLConnection.HTTP_CREATED) {
-                String pattern = MESSAGES.getString(CreateFileFailedMsg);
-                String msg = MessageFormat.format(pattern,
-                                                  file.getName(),
-                                                  path,
-                                                  workspace.getName(),
-                                                  connection.getResponseCode());
+                // log
+                Status status = new Status(Severity.ERROR, Utils.getMessage(ConnectionErrorMsg,
+                                                                            connection.getResponseCode(),
+                                                                            "createFileNode"), null); //$NON-NLS-1$
+                Logger.log(JsonRestClient.class, status);
+
+                // throw exception
+                String msg = Utils.getMessage(CreateFileFailedMsg,
+                                              file.getName(),
+                                              path,
+                                              workspace.getName(),
+                                              connection.getResponseCode());
                 throw new RuntimeException(msg);
             }
         } finally {
             if (connection != null) {
+                Logger.trace(JsonRestClient.class, null, "createFileNode: " + connection.getResponseMessage()); //$NON-NLS-1$
                 connection.disconnect();
             }
         }
@@ -101,22 +112,29 @@
      */
     private void createFolderNode( Workspace workspace,
                                    String path ) throws Exception {
-        Logger.trace(JsonRestClient.class, null, "createFolderNode: workspace=" + workspace + ", path=" + path); //$NON-NLS-1$//$NON-NLS-2$
+        Logger.trace(JsonRestClient.class, null, "createFolderNode: workspace=" + workspace.getName() + ", path=" + path); //$NON-NLS-1$//$NON-NLS-2$
         FolderNode folderNode = new FolderNode(workspace, path);
         HttpURLConnection connection = openConnection(folderNode.getUrl(), RequestMethod.POST);
 
         try {
-            Logger.trace(JsonRestClient.class, null, "createFolderNode: folder node=" + folderNode); //$NON-NLS-1$
+            Logger.trace(JsonRestClient.class, null, "createFolderNode: create node=" + folderNode); //$NON-NLS-1$
             connection.getOutputStream().write(folderNode.getContent());
 
             // make sure node was created
             if (connection.getResponseCode() != HttpURLConnection.HTTP_CREATED) {
-                String pattern = MESSAGES.getString(CreateFolderFailedMsg);
-                String msg = MessageFormat.format(pattern, path, workspace.getName(), connection.getResponseCode());
+                // log
+                Status status = new Status(Severity.ERROR, Utils.getMessage(ConnectionErrorMsg,
+                                                                            connection.getResponseCode(),
+                                                                            "createFolderNode"), null); //$NON-NLS-1$
+                Logger.log(JsonRestClient.class, status);
+
+                // throw exception
+                String msg = Utils.getMessage(CreateFolderFailedMsg, path, workspace.getName(), connection.getResponseCode());
                 throw new RuntimeException(msg);
             }
         } finally {
             if (connection != null) {
+                Logger.trace(JsonRestClient.class, null, "createFolderNode: " + connection.getResponseMessage()); //$NON-NLS-1$
                 connection.disconnect();
             }
         }
@@ -132,7 +150,7 @@
      */
     private void ensureFolderExists( Workspace workspace,
                                      String folderPath ) throws Exception {
-        Logger.trace(JsonRestClient.class, null, "ensureFolderExists: workspace=" + workspace + ", path=" + folderPath); //$NON-NLS-1$//$NON-NLS-2$
+        Logger.trace(JsonRestClient.class, null, "ensureFolderExists: workspace=" + workspace.getName() + ", path=" + folderPath); //$NON-NLS-1$//$NON-NLS-2$
         FolderNode folderNode = new FolderNode(workspace, folderPath);
 
         if (!pathExists(folderNode.getUrl())) {
@@ -171,7 +189,9 @@
      * @since 0.6
      */
     public Collection<Repository> getRepositories( Server server ) throws Exception {
+        Utils.nullArgumentCheck("server", server); //$NON-NLS-1$
         Logger.trace(JsonRestClient.class, null, "getRepositories: server=" + server); //$NON-NLS-1$
+
         ServerNode serverNode = new ServerNode(server);
         HttpURLConnection connection = openConnection(serverNode.getFindRepositoriesUrl(), RequestMethod.GET);
 
@@ -180,12 +200,18 @@
                 return serverNode.getRepositories(JsonUtils.readInputStream(connection));
             }
 
+            // log
+            Status status = new Status(Severity.ERROR, Utils.getMessage(ConnectionErrorMsg,
+                                                                        connection.getResponseCode(),
+                                                                        "getRepositories"), null); //$NON-NLS-1$
+            Logger.log(JsonRestClient.class, status);
+
             // not a good response code
-            String pattern = MESSAGES.getString(GetRepositoriesFailedMsg);
-            String msg = MessageFormat.format(pattern, server.getName(), connection.getResponseCode());
+            String msg = Utils.getMessage(GetRepositoriesFailedMsg, server.getName(), connection.getResponseCode());
             throw new RuntimeException(msg);
         } finally {
             if (connection != null) {
+                Logger.trace(JsonRestClient.class, null, "getRepositories: " + connection.getResponseMessage()); //$NON-NLS-1$
                 connection.disconnect();
             }
         }
@@ -198,7 +224,9 @@
      * @since 0.6
      */
     public Collection<Workspace> getWorkspaces( Repository repository ) throws Exception {
+        Utils.nullArgumentCheck("repository", repository); //$NON-NLS-1$
         Logger.trace(JsonRestClient.class, null, "getWorkspaces: repository=" + repository); //$NON-NLS-1$
+
         RepositoryNode repositoryNode = new RepositoryNode(repository);
         HttpURLConnection connection = openConnection(repositoryNode.getUrl(), RequestMethod.GET);
 
@@ -207,15 +235,21 @@
                 return repositoryNode.getWorkspaces(JsonUtils.readInputStream(connection));
             }
 
+            // log
+            Status status = new Status(Severity.ERROR, Utils.getMessage(ConnectionErrorMsg,
+                                                                        connection.getResponseCode(),
+                                                                        "getWorkspaces"), null); //$NON-NLS-1$
+            Logger.log(JsonRestClient.class, status);
+
             // not a good response code
-            String pattern = MESSAGES.getString(GetWorkspacesFailedMsg);
-            String msg = MessageFormat.format(pattern,
-                                              repository.getName(),
-                                              repository.getServer().getName(),
-                                              connection.getResponseCode());
+            String msg = Utils.getMessage(GetWorkspacesFailedMsg,
+                                          repository.getName(),
+                                          repository.getServer().getName(),
+                                          connection.getResponseCode());
             throw new RuntimeException(msg);
         } finally {
             if (connection != null) {
+                Logger.trace(JsonRestClient.class, null, "getWorkspaces: " + connection.getResponseMessage()); //$NON-NLS-1$
                 connection.disconnect();
             }
         }
@@ -249,10 +283,10 @@
         HttpURLConnection connection = openConnection(url, RequestMethod.GET);
 
         try {
-            Logger.trace(JsonRestClient.class, null, "pathExists: response code=" + connection.getResponseCode()); //$NON-NLS-1$
             return (connection.getResponseCode() == HttpURLConnection.HTTP_OK);
         } finally {
             if (connection != null) {
+                Logger.trace(JsonRestClient.class, null, "pathExists: " + connection.getResponseMessage()); //$NON-NLS-1$
                 connection.disconnect();
             }
         }
@@ -269,9 +303,6 @@
     protected boolean pathExists( Workspace workspace,
                                   String path,
                                   File file ) throws Exception {
-        Logger.trace(JsonRestClient.class,
-                     null,
-                     "pathExists: workspace=" + workspace + ", path=" + path + ", file=" + file.getAbsolutePath()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
         FileNode fileNode = new FileNode(workspace, path, file);
         return pathExists(fileNode.getUrl());
     }
@@ -283,24 +314,35 @@
      *      java.lang.String, java.io.File)
      * @since 0.6
      */
-    public void publish( Workspace workspace,
-                         String path,
-                         File file ) throws Exception {
+    public Status publish( Workspace workspace,
+                           String path,
+                           File file ) {
+        Utils.nullArgumentCheck("workspace", workspace); //$NON-NLS-1$
+        Utils.nullArgumentCheck("path", path); //$NON-NLS-1$
+        Utils.nullArgumentCheck("file", file); //$NON-NLS-1$
         Logger.trace(JsonRestClient.class,
                      null,
-                     "publish: workspace=" + workspace + ", path=" + path + ", file=" + file.getAbsolutePath()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                     "publish: workspace=" + workspace.getName() + ", path=" + path + ", file=" + file.getAbsolutePath()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 
-        // see if file exists at that path
-        if (pathExists(workspace, path, file)) {
-            // must be an update
-            updateFileNode(workspace, path, file);
-        } else {
-            // doesn't exist so make sure the parent path exists
-            ensureFolderExists(workspace, path);
+        try {
+            // first delete if file exists at that path
+            if (pathExists(workspace, path, file)) {
+                unpublish(workspace, path, file);
+            } else {
+                // doesn't exist so make sure the parent path exists
+                ensureFolderExists(workspace, path);
+            }
 
-            // publish new file
+            // publish file
             createFileNode(workspace, path, file);
+        } catch (Exception e) {
+            return new Status(Severity.ERROR, Utils.getMessage(PublishFailedMsg,
+                                                               file.getAbsolutePath(),
+                                                               path,
+                                                               workspace.getName()), e);
         }
+
+        return Status.OK_STATUS;
     }
 
     /**
@@ -310,54 +352,55 @@
      *      java.lang.String, java.io.File)
      * @since 0.6
      */
-    public void unpublish( Workspace workspace,
-                           String path,
-                           File file ) throws Exception {
+    public Status unpublish( Workspace workspace,
+                             String path,
+                             File file ) {
+        Utils.nullArgumentCheck("workspace", workspace); //$NON-NLS-1$
+        Utils.nullArgumentCheck("path", path); //$NON-NLS-1$
+        Utils.nullArgumentCheck("file", file); //$NON-NLS-1$
         Logger.trace(JsonRestClient.class,
                      null,
-                     "publish: workspace=" + workspace + ", path=" + path + ", file=" + file.getAbsolutePath()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        FileNode fileNode = new FileNode(workspace, path, file);
-        HttpURLConnection connection = openConnection(fileNode.getUrl(), RequestMethod.DELETE);
+                     "unpublish: workspace=" + workspace.getName() + ", path=" + path + ", file=" + file.getAbsolutePath()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 
+        HttpURLConnection connection = null;
+
         try {
-            if (connection.getResponseCode() != HttpURLConnection.HTTP_NO_CONTENT) {
-                String pattern = MESSAGES.getString(UnpublishFailedMsg);
-                String msg = MessageFormat.format(pattern,
-                                                  file.getName(),
-                                                  workspace.getName(),
-                                                  path,
-                                                  connection.getResponseCode());
+            FileNode fileNode = new FileNode(workspace, path, file);
+            connection = openConnection(fileNode.getUrl(), RequestMethod.DELETE);
+            int responseCode = connection.getResponseCode();
+
+            if (responseCode != HttpURLConnection.HTTP_NO_CONTENT) {
+                // check to see if the file was never published
+                if (!pathExists(fileNode.getUrl())) {
+                    return new Status(Severity.INFO, Utils.getMessage(PublishFailedMsg,
+                                                                      file.getAbsolutePath(),
+                                                                      workspace.getName(),
+                                                                      path), null);
+                }
+
+                // unexpected result
+                Status status = new Status(Severity.ERROR, Utils.getMessage(ConnectionErrorMsg, responseCode, "unpublish"), null); //$NON-NLS-1$
+                Logger.log(JsonRestClient.class, status);
+
+                // throw exception
+                String msg = Utils.getMessage(UnpublishFailedMsg, file.getName(), workspace.getName(), path, responseCode);
                 throw new RuntimeException(msg);
             }
+
+            return Status.OK_STATUS;
+        } catch (Exception e) {
+            return new Status(Severity.ERROR, Utils.getMessage(PublishFailedMsg,
+                                                               workspace.getName(),
+                                                               path,
+                                                               file.getAbsolutePath()), e);
         } finally {
             if (connection != null) {
-                connection.disconnect();
-            }
-        }
-    }
+                try {
+                    Logger.trace(JsonRestClient.class, null, "unpublish: " + connection.getResponseMessage()); //$NON-NLS-1$
+                } catch (IOException e) {
+                    Logger.log(JsonRestClient.class, new Status(Severity.ERROR, null, e));
+                }
 
-    /**
-     * Updates a file node in the specified workspace. Note: All parent folders are assumed to already exist.
-     * 
-     * @param workspace the workspace where the file node is being updated
-     * @param path the path to the folder where the file node is being updated
-     * @param file the file whose contents will be contained in the file node being created
-     * @throws Exception if there is a problem creating the file
-     * @since 0.6
-     */
-    private void updateFileNode( Workspace workspace,
-                                 String path,
-                                 File file ) throws Exception {
-        Logger.trace(JsonRestClient.class,
-                     null,
-                     "updateFileNode: workspace=" + workspace + ", path=" + path + ", file=" + file.getAbsolutePath()); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
-        FileNode fileNode = new FileNode(workspace, path, file);
-        HttpURLConnection connection = openConnection(fileNode.getUrl(), RequestMethod.PUT);
-
-        try {
-            connection.getOutputStream().write(fileNode.getContent());
-        } finally {
-            if (connection != null) {
                 connection.disconnect();
             }
         }

Modified: branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/JsonUtils.java
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/JsonUtils.java	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/JsonUtils.java	2009-07-24 18:13:16 UTC (rev 1130)
@@ -26,6 +26,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.HttpURLConnection;
+import org.jboss.dna.web.jcr.rest.client.Utils;
 
 /**
  * @author Dan Florian
@@ -38,23 +39,26 @@
     // ===========================================================================================================================
 
     /**
-     * @param text the text whose escape sequences will be replaced with the actual characters
+     * @param text the text whose escape sequences will be replaced with the actual characters (never <code>null</code>)
      * @return the decoded text
      * @since 0.6
      */
     public static String decodeEscaping( String text ) {
+        Utils.nullArgumentCheck("text", text); //$NON-NLS-1$
         return text.replace("%3a", ":"); //$NON-NLS-1$ //$NON-NLS-2$
     }
 
     /**
      * Note: The connection is not disconnected during this method.
      * 
-     * @param connection the connection whose input stream is going to be read from
-     * @return the data read from the connection input stream
+     * @param connection the connection whose input stream is going to be read from (never <code>null</code>)
+     * @return the data read from the connection input stream (never <code>null</code>)
      * @throws IOException if there is a problem reading from the connection
      * @since 0.6
      */
     public static String readInputStream( HttpURLConnection connection ) throws IOException {
+        Utils.nullArgumentCheck("connection", connection); //$NON-NLS-1$
+
         InputStream stream = connection.getInputStream();
         int bytesRead;
         byte[] bytes = new byte[1024];

Modified: branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/RepositoryNode.java
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/RepositoryNode.java	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/RepositoryNode.java	2009-07-24 18:13:16 UTC (rev 1130)
@@ -28,6 +28,7 @@
 import java.util.Collection;
 import java.util.Iterator;
 import org.codehaus.jettison.json.JSONObject;
+import org.jboss.dna.web.jcr.rest.client.Utils;
 import org.jboss.dna.web.jcr.rest.client.domain.Repository;
 import org.jboss.dna.web.jcr.rest.client.domain.Workspace;
 
@@ -91,6 +92,7 @@
      */
     @SuppressWarnings( "unchecked" )
     public Collection<Workspace> getWorkspaces( String jsonResponse ) throws Exception {
+        Utils.nullArgumentCheck("jsonResponse", jsonResponse); //$NON-NLS-1$
         Collection<Workspace> workspaces = new ArrayList<Workspace>();
         JSONObject jsonObj = new JSONObject(jsonResponse);
 

Modified: branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/ServerNode.java
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/ServerNode.java	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/src/main/java/org/jboss/dna/web/jcr/rest/client/json/ServerNode.java	2009-07-24 18:13:16 UTC (rev 1130)
@@ -29,6 +29,7 @@
 import java.util.Iterator;
 import org.codehaus.jettison.json.JSONObject;
 import org.jboss.dna.web.jcr.rest.client.Logger;
+import org.jboss.dna.web.jcr.rest.client.Utils;
 import org.jboss.dna.web.jcr.rest.client.domain.Repository;
 import org.jboss.dna.web.jcr.rest.client.domain.Server;
 
@@ -104,6 +105,7 @@
      */
     @SuppressWarnings( "unchecked" )
     public Collection<Repository> getRepositories( String jsonResponse ) throws Exception {
+        Utils.nullArgumentCheck("jsonResponse", jsonResponse); //$NON-NLS-1$
         Collection<Repository> repositories = new ArrayList<Repository>();
         Logger.trace(ServerNode.class, null, "getRepositories:jsonResponse=" + jsonResponse); //$NON-NLS-1$
         JSONObject jsonObj = new JSONObject(jsonResponse);
@@ -112,7 +114,7 @@
         for (Iterator<String> itr = jsonObj.keys(); itr.hasNext();) {
             Repository repository = new Repository(itr.next(), this.server);
             repositories.add(repository);
-            Logger.trace(ServerNode.class, null, "getRepositories:repository=" + repository); //$NON-NLS-1$
+            Logger.trace(ServerNode.class, null, "getRepositories: adding repository=" + repository); //$NON-NLS-1$
         }
 
         return repositories;

Modified: branches/eclipse/dna-web-jcr-rest-client/src/main/resources/org/jboss/dna/web/jcr/rest/client/Messages.properties
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/src/main/resources/org/jboss/dna/web/jcr/rest/client/Messages.properties	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/src/main/resources/org/jboss/dna/web/jcr/rest/client/Messages.properties	2009-07-24 18:13:16 UTC (rev 1130)
@@ -25,6 +25,8 @@
 ErrorRestoringServerRegistry = Error trying to restore the server registry from file "{0}"
 ErrorSavingServerRegistry = Error trying to save the server registry to "{0}"
 
+NullArgumentMsg = The argument "{0}" may not be null.
+
 RepositoryEmptyNameMsg = A repository name cannot be empty
 RepositoryNullServerMsg = A repository server cannot be null
 RepositoryShortDescription = DNA Repository: Name: {0}, {1}
@@ -49,8 +51,11 @@
 
 # JsonRestClient messages
 
+ConnectionErrorMsg = response code={0}: {1}
 CreateFileFailedMsg = Creating the "{0}" file node in folder "{1}" in workspace "{2}" failed with HTTP response code of "{3}"
 CreateFolderFailedMsg = Creating the "{0}" folder node in workspace "{1}" failed with HTTP response code of "{2}"
 GetRepositoriesFailedMsg = Obtaining the repositories from server "{0}" failed with HTTP response code of "{1}"
 GetWorkspacesFailedMsg = Obtaining the workspaces from repository "{0}" at server "{1}" failed with HTTP response code of "{2}"
-UnpublishFailedMsg = The file "{0}" could not be unpublished in repository "{1}" at path "{2}". The HTTP response code was "{3}".
+PublishFailedMsg = Publishing file "{0}" to path "{1}" in workspace "{2}" failed.
+UnpublishFailedMsg = The file "{0}" could not be unpublished in workspace "{1}" at path "{2}". The HTTP response code was "{3}".
+UnpublishNeverPublishedMsg = The file "{0}" could not be unpublished in workspace "{1}" at path "{2}" because it could not be found.

Modified: branches/eclipse/dna-web-jcr-rest-client/src/test/java/org/jboss/dna/web/jcr/rest/client/MockRestExecutor.java
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/src/test/java/org/jboss/dna/web/jcr/rest/client/MockRestExecutor.java	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/src/test/java/org/jboss/dna/web/jcr/rest/client/MockRestExecutor.java	2009-07-24 18:13:16 UTC (rev 1130)
@@ -66,9 +66,10 @@
      *      java.lang.String, java.io.File)
      * @since 0.6
      */
-    public void publish( Workspace workspace,
-                         String path,
-                         File file ) throws Exception {
+    public Status publish( Workspace workspace,
+                           String path,
+                           File file ) {
+        return null;
     }
 
     /**
@@ -78,9 +79,10 @@
      *      java.lang.String, java.io.File)
      * @since 0.6
      */
-    public void unpublish( Workspace workspace,
-                           String path,
-                           File file ) throws Exception {
+    public Status unpublish( Workspace workspace,
+                             String path,
+                             File file ) {
+        return null;
     }
 
 }

Modified: branches/eclipse/dna-web-jcr-rest-client/src/test/java/org/jboss/dna/web/jcr/rest/client/json/JsonRestClientTest.java
===================================================================
--- branches/eclipse/dna-web-jcr-rest-client/src/test/java/org/jboss/dna/web/jcr/rest/client/json/JsonRestClientTest.java	2009-07-24 13:42:58 UTC (rev 1129)
+++ branches/eclipse/dna-web-jcr-rest-client/src/test/java/org/jboss/dna/web/jcr/rest/client/json/JsonRestClientTest.java	2009-07-24 18:13:16 UTC (rev 1130)
@@ -61,7 +61,7 @@
 
     private static final String WORKSPACE_PATH = "/myproject/myfolder/"; //$NON-NLS-1$
     private static final String FILE_PATH = WORKSPACE_PATH + "document.txt"; //$NON-NLS-1$
-//    private static final String BINARY_FILE_PATH = WORKSPACE_PATH + "picture.txt"; //$NON-NLS-1$
+    private static final String BINARY_FILE_PATH = WORKSPACE_PATH + "picture.jpg"; //$NON-NLS-1$
 
     // ===========================================================================================================================
     // Fields
@@ -103,22 +103,51 @@
         assertThat(workspaces.iterator().next(), is(WORKSPACE1));
     }
 
-    // @Test
-    public void shouldPublishResource() throws Exception {
+    @Test
+    public void shouldNotUnpublishNonexistentFile() throws Exception {
+        File file = new File("bogusfile"); //$NON-NLS-1$
+        assertThat(this.restClient.unpublish(WORKSPACE1, WORKSPACE_PATH, file).isInfo(), is(true));
+    }
+
+    @Test
+    public void shouldPublishBinaryResource() throws Exception {
+        URL binaryFile = getClass().getResource(BINARY_FILE_PATH);
+        assertThat(binaryFile, is(notNullValue()));
+
+        // publish
+        File file = new File(binaryFile.toURI());
+        assertThat(this.restClient.publish(WORKSPACE1, WORKSPACE_PATH, file).isOk(), is(true));
+
+        // confirm it exists in repository
+        assertThat(((JsonRestClient)this.restClient).pathExists(WORKSPACE1, WORKSPACE_PATH, file), is(true));
+        
+        // TODO: get jcr:data and compare
+    }
+
+    @Test
+    public void shouldPublishTextResource() throws Exception {
         URL textFile = getClass().getResource(FILE_PATH);
         assertThat(textFile, is(notNullValue()));
 
         // publish
         File file = new File(textFile.toURI());
-        this.restClient.publish(WORKSPACE1, WORKSPACE_PATH, file);
+        assertThat(this.restClient.publish(WORKSPACE1, WORKSPACE_PATH, file).isOk(), is(true));
 
         // confirm it exists in repository
         assertThat(((JsonRestClient)this.restClient).pathExists(WORKSPACE1, WORKSPACE_PATH, file), is(true));
     }
 
-    // @Test
+    @Test
     public void shouldUnpublish() throws Exception {
-        this.restClient.unpublish(WORKSPACE1, WORKSPACE_PATH, new File(FILE_PATH));
+        // first publish
+        shouldPublishTextResource();
+
+        URL textFile = getClass().getResource(FILE_PATH);
+        File file = new File(textFile.toURI());
+        assertThat(this.restClient.unpublish(WORKSPACE1, WORKSPACE_PATH, file).isOk(), is(true));
+
+        // confirm it does not exist in repository
+        assertThat(((JsonRestClient)this.restClient).pathExists(WORKSPACE1, WORKSPACE_PATH, file), is(false));
     }
 
 }



More information about the dna-commits mailing list