[jboss-cvs] JBossAS SVN: r89155 - in projects/ejb-book/trunk: ch06-filetransfer and 16 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed May 20 00:48:57 EDT 2009


Author: ALRubinger
Date: 2009-05-20 00:48:57 -0400 (Wed, 20 May 2009)
New Revision: 89155

Added:
   projects/ejb-book/trunk/ch06-filetransfer/
   projects/ejb-book/trunk/ch06-filetransfer/README
   projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/
   projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/
   projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/
   projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/
   projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/
   projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/
   projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/FileTransferBean.java
   projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/FileTransferCommonBusiness.java
   projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/FileTransferException.java
   projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/FileTransferRemoteBusiness.java
   projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/FtpServerPojo.java
   projects/ejb-book/trunk/ch06-filetransfer/src/main/resources/ftpserver-jboss-beans.xml
   projects/ejb-book/trunk/ch06-filetransfer/src/main/resources/ftpusers.properties
   projects/ejb-book/trunk/ch06-filetransfer/src/test/java/org/
   projects/ejb-book/trunk/ch06-filetransfer/src/test/java/org/jboss/
   projects/ejb-book/trunk/ch06-filetransfer/src/test/java/org/jboss/ejb3/
   projects/ejb-book/trunk/ch06-filetransfer/src/test/java/org/jboss/ejb3/examples/
   projects/ejb-book/trunk/ch06-filetransfer/src/test/java/org/jboss/ejb3/examples/ch06/
   projects/ejb-book/trunk/ch06-filetransfer/src/test/java/org/jboss/ejb3/examples/ch06/filetransfer/
   projects/ejb-book/trunk/ch06-filetransfer/src/test/java/org/jboss/ejb3/examples/ch06/filetransfer/FileTransferUnitTestCase.java
   projects/ejb-book/trunk/ch06-filetransfer/src/test/resources/log4j.xml
Modified:
   projects/ejb-book/trunk/ch06-filetransfer/pom.xml
Log:
[EJBBBOOK-8] Retool SFSB example to interact w/ stateful protocol (FTP).  Get Embedded Unit Tests running.  Still to make SFSB Integration Tests.

Copied: projects/ejb-book/trunk/ch06-filetransfer (from rev 89011, projects/ejb-book/trunk/ch06-chronograph)


Property changes on: projects/ejb-book/trunk/ch06-filetransfer
___________________________________________________________________
Name: svn:ignore
   + target
.settings
.classpath
.project

Name: svn:mergeinfo
   + 

Added: projects/ejb-book/trunk/ch06-filetransfer/README
===================================================================
--- projects/ejb-book/trunk/ch06-filetransfer/README	                        (rev 0)
+++ projects/ejb-book/trunk/ch06-filetransfer/README	2009-05-20 04:48:57 UTC (rev 89155)
@@ -0,0 +1,7 @@
+Some author notes on this example for the workbook section:
+
+* Shows use of SFSB for conversational processing
+* Introduces @PostConstruct/@PreDestroy/@Remove lifecycle callbacks
+* TODO
+
+Possible Exercise: TODO 
\ No newline at end of file

Modified: projects/ejb-book/trunk/ch06-filetransfer/pom.xml
===================================================================
--- projects/ejb-book/trunk/ch06-chronograph/pom.xml	2009-05-18 19:47:04 UTC (rev 89011)
+++ projects/ejb-book/trunk/ch06-filetransfer/pom.xml	2009-05-20 04:48:57 UTC (rev 89155)
@@ -13,12 +13,31 @@
   <modelVersion>4.0.0</modelVersion>
 
   <!-- Artifact Information -->
-  <artifactId>jboss-ejb3-examples-ch06-chronograph</artifactId>
-  <name>JBoss EJB 3.x Examples - Chapter 6: Chronograph EJBs</name>
+  <artifactId>jboss-ejb3-examples-ch06-filetransfer</artifactId>
+  <name>JBoss EJB 3.x Examples - Chapter 6: FileTransfer EJBs</name>
   <description>Example to accompany O'Reilly "Enterprise Java Beans 6th Edition" Chapter 6</description>
 
   <!-- Build -->
   <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>copy-dependencies</id>
+            <phase>package</phase>
+            <goals>
+              <goal>copy-dependencies</goal>
+            </goals>
+            <configuration>
+              <includeScope>runtime</includeScope>
+              <outputDirectory>${project.build.directory}/lib</outputDirectory>
+              <stripVersion>true</stripVersion>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
   </build>
 
 
@@ -26,6 +45,9 @@
   <properties>
 
     <!-- Versioning -->
+    <version.org.apache.ftpserver_ftpserver.core>1.0.1</version.org.apache.ftpserver_ftpserver.core>
+    <version.commons.net_commons.net>2.0</version.commons.net_commons.net>
+    <version.org.slf4j_slf4j.jcl>1.5.2</version.org.slf4j_slf4j.jcl>
 
   </properties>
 
@@ -52,6 +74,28 @@
       <artifactId>jboss-logging-spi</artifactId>
     </dependency>
 
+    <!-- For the embedded FTP Server -->
+    <dependency>
+      <groupId>org.apache.ftpserver</groupId>
+      <artifactId>ftpserver-core</artifactId>
+      <version>${version.org.apache.ftpserver_ftpserver.core}</version>
+    </dependency>
+
+    <!-- For the FTP Client our SFSB will use under the hood -->
+    <dependency>
+      <groupId>commons-net</groupId>
+      <artifactId>commons-net</artifactId>
+      <version>${version.commons.net_commons.net}</version>
+    </dependency>
+
+    <!-- For the FTP Server logging framework -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jcl</artifactId>
+      <version>${version.org.slf4j_slf4j.jcl}</version>
+      <scope>test</scope>
+    </dependency>
+
   </dependencies>
 
   <profiles>
@@ -128,7 +172,6 @@
               </execution>
 
               <!--
-
                 Deploy into our custom JBossAS Configuration
               -->
               <execution>
@@ -139,8 +182,11 @@
                 <phase>pre-integration-test</phase>
                 <configuration>
                   <serverConfigName>default</serverConfigName>
-                  <files>${project.build.directory}/lib/commons-codec.jar,${project.build.directory}/${project.build.finalName}.${project.packaging}
-                  </files>
+                  <files>${project.build.directory}/lib/ftplet-api.jar,
+                    ${project.build.directory}/lib/ftpserver-core.jar,
+                    ${project.build.directory}/lib/mina-core.jar,
+                    ${project.build.directory}/lib/slf4j-api.jar,
+                    ${project.build.directory}/${project.build.finalName}.${project.packaging}</files>
                   <jboss.test.run>true</jboss.test.run>
                 </configuration>
               </execution>

Added: projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/FileTransferBean.java
===================================================================
--- projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/FileTransferBean.java	                        (rev 0)
+++ projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/FileTransferBean.java	2009-05-20 04:48:57 UTC (rev 89155)
@@ -0,0 +1,404 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.examples.ch06.filetransfer;
+
+import java.io.IOException;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.annotation.Resource;
+import javax.ejb.PostActivate;
+import javax.ejb.PrePassivate;
+import javax.ejb.Remote;
+import javax.ejb.Stateful;
+
+import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPFile;
+import org.apache.commons.net.ftp.FTPReply;
+import org.jboss.logging.Logger;
+
+/**
+ * FileTransferBean
+ * 
+ * Bean Implementation class of the FileTransferEJB, modeled
+ * as a Stateful Session Bean
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+ at Stateful
+ at Remote(FileTransferRemoteBusiness.class)
+public class FileTransferBean implements FileTransferRemoteBusiness
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Logger
+    */
+   private static final Logger log = Logger.getLogger(FileTransferBean.class);
+
+   /**
+    * Name of the environment entry containing the host to which we'll connect
+    */
+   private static final String ENV_ENTRY_NAME_CONNECT_HOST = "connectHost";
+
+   /**
+    * Name of the environment entry containing the port to which we'll connect
+    */
+   private static final String ENV_ENTRY_NAME_CONNECT_PORT = "connectPort";
+
+   //-------------------------------------------------------------------------------------||
+   // Instance Members -------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * The underlying FTP Client.  We mark this 
+    * as transient because we don't want its state
+    * getting Serialized during passivation.  We'll
+    * reinitialize this client and its connections
+    * upon activation.
+    */
+   private transient FTPClient client;
+
+   /**
+    * The name of the host to which we'll connect.
+    * Initialized from the environment entry named
+    * {@link FileTransferBean#ENV_ENTRY_NAME_CONNECT_HOST}
+    */
+   @Resource(name = ENV_ENTRY_NAME_CONNECT_HOST)
+   private String connectHost;
+
+   /**
+    * The port to which we'll connect.
+    * Initialized from the environment entry named
+    * {@link FileTransferBean#ENV_ENTRY_NAME_CONNECT_PORT}
+    */
+   @Resource(name = ENV_ENTRY_NAME_CONNECT_PORT)
+   private int connectPort;
+
+   /**
+    * Name of the present working directory.  In cases where
+    * we're passivated, if this is specified
+    * we'll change into this directory upon activation.
+    */
+   private String presentWorkingDirectory;
+
+   //-------------------------------------------------------------------------------------||
+   // Lifecycle Callbacks ----------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Called by the container when the instance is about to be passivated or brought 
+    * out of service entirely.
+    * 
+    * @see org.jboss.ejb3.examples.ch06.filetransfer.FileTransferCommonBusiness#disconnect()
+    */
+   @PrePassivate
+   @PreDestroy
+   @Override
+   public void disconnect()
+   {
+      // Obtain FTP Client
+      final FTPClient client = this.getClient();
+
+      // If exists
+      if (client != null)
+      {
+         // If connected
+         if (client.isConnected())
+         {
+            // Logout
+            try
+            {
+               client.logout();
+               log.info("Logged out of: " + client);
+            }
+            catch (final IOException ioe)
+            {
+               log.warn("Exception encountered in logging out of the FTP client", ioe);
+            }
+
+            // Disconnect
+            try
+            {
+               log.debug("Disconnecting: " + client);
+               client.disconnect();
+               log.info("Disconnected: " + client);
+            }
+            catch (final IOException ioe)
+            {
+               log.warn("Exception encountered in disconnecting the FTP client", ioe);
+            }
+         }
+      }
+   }
+
+   /**
+    * Called by the container when the instance has been created or re-activated
+    * (brought out of passivated state).  Will construct the underlying FTP Client
+    * and open all appropriate connections.
+    * 
+    * @see org.jboss.ejb3.examples.ch06.filetransfer.FileTransferCommonBusiness#connect()
+    */
+   @PostConstruct
+   @PostActivate
+   @Override
+   public void connect() throws IllegalStateException, FileTransferException
+   {
+      /*
+       * Precondition checks
+       */
+      final FTPClient clientBefore = this.getClient();
+      if (clientBefore != null && clientBefore.isConnected())
+      {
+         throw new IllegalStateException("FTP Client is already initialized");
+      }
+
+      // Get the connection properties
+      final String connectHost = this.getConnectHost();
+      final int connectPort = this.getConnectPort();
+
+      // Create the client
+      final FTPClient client = new FTPClient();
+      final String canonicalServerName = connectHost + ":" + connectPort;
+      log.debug("Connecting to FTP Server at " + canonicalServerName);
+      try
+      {
+         client.connect(connectHost, connectPort);
+      }
+      catch (final IOException ioe)
+      {
+         throw new FileTransferException("Error in connecting to " + canonicalServerName, ioe);
+      }
+
+      // Set
+      log.info("Connected to FTP Server at: " + canonicalServerName);
+      this.setClient(client);
+
+      // Check that the last operation succeeded
+      this.checkLastOperation();
+
+      try
+      {
+         // Login
+         client.login("user", "password");
+
+         // Check that the last operation succeeded
+         this.checkLastOperation();
+      }
+      catch (final Exception e)
+      {
+         throw new FileTransferException("Could not log in", e);
+      }
+
+      // If there's a pwd defined, cd into it.
+      final String pwd = this.getPresentWorkingDirectory();
+      if (pwd != null)
+      {
+         this.cd(pwd);
+      }
+
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Required Implementations -----------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /* (non-Javadoc)
+    * @see org.jboss.ejb3.examples.ch06.filetransfer.FileTransferCommonBusiness#cd(java.lang.String)
+    */
+   @Override
+   public void cd(final String directory)
+   {
+      // Get the client
+      final FTPClient client = this.getClient();
+
+      // Exec cd
+      try
+      {
+         // Exec cd
+         client.changeWorkingDirectory(directory);
+
+         // Check reply for success
+         this.checkLastOperation();
+      }
+      catch (final Exception e)
+      {
+         throw new FileTransferException("Could not change working directory to \"" + directory + "\"", e);
+      }
+
+      // Set the pwd (used upon activation)
+      log.info("cd > " + directory);
+      this.setPresentWorkingDirectory(directory);
+   }
+
+   /* (non-Javadoc)
+    * @see org.jboss.ejb3.examples.ch06.filetransfer.FileTransferCommonBusiness#mkdir(java.lang.String)
+    */
+   @Override
+   public void mkdir(final String directory)
+   {
+      // Get the client
+      final FTPClient client = this.getClient();
+
+      // Exec cd
+      try
+      {
+         // Exec mkdir
+         client.makeDirectory(directory);
+
+         // Check reply for success
+         this.checkLastOperation();
+      }
+      catch (final Exception e)
+      {
+         throw new FileTransferException("Could not make directory \"" + directory + "\"", e);
+      }
+
+   }
+
+   /* (non-Javadoc)
+    * @see org.jboss.ejb3.examples.ch06.filetransfer.FileTransferCommonBusiness#pwd()
+    */
+   @Override
+   public String pwd()
+   {
+      // Get the client
+      final FTPClient client = this.getClient();
+
+      // Exec pwd
+      try
+      {
+         final FTPFile[] files = client.listFiles();
+         for (final FTPFile file : files)
+         {
+            log.info(file);
+         }
+
+         // Exec pwd
+         return client.printWorkingDirectory();
+
+      }
+      catch (final IOException ioe)
+      {
+         throw new FileTransferException("Could not print working directory", ioe);
+      }
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Internal Helper Methods ------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Ensures that the last operation succeeded with a positive
+    * reply code.  Otherwise a {@link FileTransferException} 
+    * is raised, noting the reply code denoting the error.
+    * 
+    * @throws FileTransferException
+    */
+   protected void checkLastOperation() throws FileTransferException
+   {
+      // Get the client
+      final FTPClient client = this.getClient();
+
+      // Obtain and check the reply from the connection
+      final int connectReply = client.getReplyCode();
+      if (!FTPReply.isPositiveCompletion(connectReply))
+      {
+         // Indicate the problem
+         throw new FileTransferException("Did not receive positive completion code from server, instead code was: "
+               + connectReply);
+      }
+
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Accessors / Mutators ---------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * @return the connectHost
+    */
+   public String getConnectHost()
+   {
+      return connectHost;
+   }
+
+   /**
+    * @param connectHost the connectHost to set
+    */
+   public void setConnectHost(final String connectHost)
+   {
+      this.connectHost = connectHost;
+   }
+
+   /**
+    * @return the connectPort
+    */
+   public int getConnectPort()
+   {
+      return connectPort;
+   }
+
+   /**
+    * @param connectPort the connectPort to set
+    */
+   public void setConnectPort(final int connectPort)
+   {
+      this.connectPort = connectPort;
+   }
+
+   /**
+    * @return the client
+    */
+   protected final FTPClient getClient()
+   {
+      return client;
+   }
+
+   /**
+    * @param client the client to set
+    */
+   private void setClient(final FTPClient client)
+   {
+      this.client = client;
+   }
+
+   /**
+    * @return the presentWorkingDirectory
+    */
+   private String getPresentWorkingDirectory()
+   {
+      return presentWorkingDirectory;
+   }
+
+   /**
+    * @param presentWorkingDirectory the presentWorkingDirectory to set
+    */
+   private void setPresentWorkingDirectory(String presentWorkingDirectory)
+   {
+      this.presentWorkingDirectory = presentWorkingDirectory;
+   }
+}

Added: projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/FileTransferCommonBusiness.java
===================================================================
--- projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/FileTransferCommonBusiness.java	                        (rev 0)
+++ projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/FileTransferCommonBusiness.java	2009-05-20 04:48:57 UTC (rev 89155)
@@ -0,0 +1,80 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.examples.ch06.filetransfer;
+
+/**
+ * FileTransferCommonBusiness
+ *
+ * Contains the contract for operations common to all
+ * business interfaces of the FileTransferEJB.
+ * 
+ * Includes support for //TODO
+ * 
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public interface FileTransferCommonBusiness
+{
+   // ---------------------------------------------------------------------------||
+   // Contracts -----------------------------------------------------------------||
+   // ---------------------------------------------------------------------------||
+
+   /**
+    * Makes a directory of the specified name
+    * 
+    * @throws IllegalStateException If the client connection has not been initialized
+    */
+   void mkdir(String directory) throws IllegalStateException;
+
+   /**
+    * Changes into the named directory
+    * 
+    * @param directory
+    * @throws IllegalStateException If the client connection has not been initialized
+    */
+   void cd(String directory) throws IllegalStateException;
+
+   /**
+    * Obtains the name of the current working directory
+    * 
+    * @return
+    * @throws IllegalStateException If the client connection has not been initialized
+    */
+   String pwd() throws IllegalStateException;
+
+   /**
+    * Denotes that the client is done using this service; flushes
+    * any pending operations and does all appropriate cleanup.  If 
+    * already disconnected, this is a no-op.
+    */
+   void disconnect();
+
+   /**
+    * Opens the underlying connections to the target FTP Server, 
+    * performs any other tasks required before commands may be sent
+    * (ie. login, etc)
+    * 
+    * @throws IllegalStateException If already initialized/connected
+    */
+   void connect() throws IllegalStateException;
+
+}

Added: projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/FileTransferException.java
===================================================================
--- projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/FileTransferException.java	                        (rev 0)
+++ projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/FileTransferException.java	2009-05-20 04:48:57 UTC (rev 89155)
@@ -0,0 +1,70 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.examples.ch06.filetransfer;
+
+import javax.ejb.ApplicationException;
+
+/**
+ * FileTransferException
+ * 
+ * Exception to indicate that a problem has occurred during 
+ * a file transfer operation.  Will rollback the current transaction
+ * if encountered.
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+ at ApplicationException(rollback = true)
+public class FileTransferException extends RuntimeException
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   private static final long serialVersionUID = 1L;
+
+   //-------------------------------------------------------------------------------------||
+   // Constructor ------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   public FileTransferException()
+   {
+      super();
+   }
+
+   public FileTransferException(final String message, final Throwable cause)
+   {
+      super(message, cause);
+   }
+
+   public FileTransferException(final String message)
+   {
+      super(message);
+   }
+
+   public FileTransferException(final Throwable cause)
+   {
+      super(cause);
+   }
+
+}

Added: projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/FileTransferRemoteBusiness.java
===================================================================
--- projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/FileTransferRemoteBusiness.java	                        (rev 0)
+++ projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/FileTransferRemoteBusiness.java	2009-05-20 04:48:57 UTC (rev 89155)
@@ -0,0 +1,35 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.examples.ch06.filetransfer;
+
+/**
+ * FileTransferRemoteBusiness
+ * 
+ * Remote Business interface for the FileTransferEJB
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public interface FileTransferRemoteBusiness extends FileTransferCommonBusiness
+{
+
+}

Added: projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/FtpServerPojo.java
===================================================================
--- projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/FtpServerPojo.java	                        (rev 0)
+++ projects/ejb-book/trunk/ch06-filetransfer/src/main/java/org/jboss/ejb3/examples/ch06/filetransfer/FtpServerPojo.java	2009-05-20 04:48:57 UTC (rev 89155)
@@ -0,0 +1,324 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.examples.ch06.filetransfer;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.apache.ftpserver.FtpServer;
+import org.apache.ftpserver.FtpServerFactory;
+import org.apache.ftpserver.ftplet.FtpException;
+import org.apache.ftpserver.ftplet.UserManager;
+import org.apache.ftpserver.listener.ListenerFactory;
+import org.apache.ftpserver.usermanager.ClearTextPasswordEncryptor;
+import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
+import org.jboss.logging.Logger;
+
+/**
+ * FtpServerPojo
+ * 
+ * MC Bean (POJO) Responsible for starting/stopping 
+ * the Embedded FTP Server.
+ * 
+ * It's the file "ftpserver-jboss-beans.xml" which will
+ * install this into JBoss MicroContainer and invoke 
+ * the appropriate lifecycle callbacks.  This should
+ * be considered part of the test execution environment
+ * and is not really part of the SFSB examples themselves.
+ * The SFSBs for the examples are a client of the FTP server
+ * started by this simple bean.
+ * 
+ * Thread-safe.  Lifecycle operations are synchronized on 
+ * "this".
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public final class FtpServerPojo
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Logger
+    */
+   private static final Logger log = Logger.getLogger(FtpServerPojo.class);
+
+   /**
+    * Name of the Server's default listener
+    */
+   private static final String LISTENER_NAME_DEFAULT = "default";
+
+   //-------------------------------------------------------------------------------------||
+   // Instance Members -------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Port to which the FTP Server will bind.
+    * 
+    * Synchronized on "this", volatile so
+    * we don't block for read-only access
+    */
+   private volatile int bindPort;
+
+   /**
+    * The underlying server.  Must not be exported.
+    */
+   private FtpServer server;
+
+   /**
+    * The name of the users/password configuration filename.
+    * 
+    * Synchronized on "this", volatile so
+    * we don't block for read-only access
+    */
+   private volatile String usersConfigFileName;
+
+   //-------------------------------------------------------------------------------------||
+   // Lifecycle Methods ------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Creates and initializes the underlying server.  Should be 
+    * called along lifecycle when this POJO is created.
+    * 
+    * Synchronized on "this" so we block on all lifecycle events
+    * 
+    * @throws IllegalStateException If the properties for the server have not
+    *       been properly initialized
+    */
+   public synchronized void initializeServer() throws IllegalStateException
+   {
+      // Extract properties
+      final int bindPort = this.getBindPort();
+
+      /*
+       * Precondition checks
+       */
+
+      if (bindPort <= 0)
+      {
+         throw new IllegalStateException("Property for bind port has not been set to a valid value above 0.");
+      }
+
+      // Initialize
+      final FtpServerFactory serverFactory = new FtpServerFactory();
+      final ListenerFactory factory = new ListenerFactory();
+
+      // Set properties
+      log.debug("Using FTP bind port: " + bindPort);
+      factory.setPort(bindPort);
+
+      // Add default listener to the server factory
+      serverFactory.addListener(LISTENER_NAME_DEFAULT, factory.createListener());
+
+      // Get the current CL
+      final ClassLoader tccl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+      {
+
+         @Override
+         public ClassLoader run()
+         {
+            return Thread.currentThread().getContextClassLoader();
+         }
+      });
+
+      // Load the properties file to get its URI
+      final String usersConfigFileName = this.getUsersConfigFileName();
+      log.info("Using users configuration file: " + usersConfigFileName);
+      final URL usersFileUrl = tccl.getResource(usersConfigFileName);
+      if (usersFileUrl == null)
+      {
+         throw new RuntimeException("Could not find specified users configuration file upon the classpath: "
+               + usersConfigFileName);
+      }
+      URI usersFileUri = null;
+      try
+      {
+         usersFileUri = usersFileUrl.toURI();
+      }
+      catch (final URISyntaxException urise)
+      {
+         throw new RuntimeException(urise);
+      }
+      final File usersFile = new File(usersFileUri);
+      if (!usersFile.exists())
+      {
+         throw new RuntimeException("Specified users configuration file does not exist: " + usersFile.getAbsolutePath());
+      }
+
+      // Configure the user auth mechanism
+      final PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
+      userManagerFactory.setFile(usersFile);
+      userManagerFactory.setPasswordEncryptor(new ClearTextPasswordEncryptor());
+      final UserManager userManager = userManagerFactory.createUserManager();
+      serverFactory.setUserManager(userManager);
+
+      // Create the server
+      final FtpServer server = serverFactory.createServer();
+      this.setServer(server);
+      log.info("Created FTP Server: " + server);
+   }
+
+   /**
+    * Starts the server.  Should be called along lifecycle when this
+    * POJO is installed (ie. @Start)
+    * 
+    * Synchronized on "this" so we block on all lifecycle events
+    * 
+    * @throws IllegalStateException If the server has not been initialized or
+    *       if the server has already been started
+    * @throws FtpException If there was an error in starting the server
+    */
+   public synchronized void startServer() throws IllegalStateException, FtpException
+   {
+      // Get the server
+      final FtpServer server = this.getServer();
+
+      /*
+       * Precondition checks
+       */
+
+      // Ensure initialized
+      if (server == null)
+      {
+         throw new IllegalStateException("The server has not yet been initialized");
+      }
+
+      // Ensure not already running or in some other state
+      if (!server.isStopped())
+      {
+         throw new IllegalStateException("Server cannot be started if it is not currently stopped");
+      }
+
+      // Start
+      log.debug("Starting the FTP Server: " + server);
+      server.start();
+      log.info("FTP Server Started: " + server);
+   }
+
+   /**
+    * Stops the server.  Should be called along lifecycle when this
+    * POJO is uninstalled.
+    * 
+    * @throws IllegalStateException If the server is already stopped or the server is
+    *       not initialized 
+    * @throws FtpException
+    */
+   public synchronized void stopServer() throws IllegalStateException
+   {
+      // Get the server
+      final FtpServer server = this.getServer();
+
+      /*
+       * Precondition checks
+       */
+
+      // Ensure initialized
+      if (server == null)
+      {
+         throw new IllegalStateException("The server has not yet been initialized");
+      }
+
+      // Ensure not already running or in some other state
+      if (server.isStopped())
+      {
+         throw new IllegalStateException("Server cannot be stopped if it's already stopped");
+      }
+
+      // Stop
+      log.debug("Stopping the FTP Server: " + server);
+      server.stop();
+      log.info("FTP Server stopped: " + server);
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Accessors / Mutators ---------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Obtains the port to which we'll bind
+    */
+   public int getBindPort()
+   {
+      return bindPort;
+   }
+
+   /**
+    * Sets the port to which we'll bind.  Synchronized on "this"
+    * so we block until lifecycle operations are complete.
+    * 
+    * @param bindPort
+    */
+   public synchronized void setBindPort(final int bindPort)
+   {
+      this.bindPort = bindPort;
+   }
+
+   /**
+    * Obtains the underlying FTP Server
+    * 
+    * @return
+    */
+   protected FtpServer getServer()
+   {
+      return server;
+   }
+
+   /**
+    * Sets the underlying FTP Server.  Synchronized on 
+    * "this" so we block until lifecycle operations are complete.
+    * 
+    * @param server
+    */
+   private synchronized void setServer(final FtpServer server)
+   {
+      this.server = server;
+   }
+
+   /**
+    * Obtains the name of the users configuration file
+    * 
+    * @return the usersConfigFileName
+    */
+   public String getUsersConfigFileName()
+   {
+      return usersConfigFileName;
+   }
+
+   /**
+    * Sets the name of the users configuration file.  Synchronized on "this"
+    * so we block until lifecycle operations are complete.
+    * 
+    * @param usersConfigFileName the usersConfigFileName to set
+    */
+   public synchronized void setUsersConfigFileName(final String usersConfigFileName)
+   {
+      this.usersConfigFileName = usersConfigFileName;
+   }
+}

Added: projects/ejb-book/trunk/ch06-filetransfer/src/main/resources/ftpserver-jboss-beans.xml
===================================================================
--- projects/ejb-book/trunk/ch06-filetransfer/src/main/resources/ftpserver-jboss-beans.xml	                        (rev 0)
+++ projects/ejb-book/trunk/ch06-filetransfer/src/main/resources/ftpserver-jboss-beans.xml	2009-05-20 04:48:57 UTC (rev 89155)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<deployment xmlns="urn:jboss:bean-deployer:2.0">
+
+  <!-- 
+  
+  Define the POJO which will Embed the FTP Server 
+  
+  This FTP Server will be used for our SFSB Examples
+  
+  -->
+  
+  <bean name="org.jboss.ejb3.examples.ch06.filetransfer.FtpServer"
+    class="org.jboss.ejb3.examples.ch06.filetransfer.FtpServerPojo">
+    
+    <!-- Define configurable properties -->
+    <property name="bindPort">12345</property>
+    <property name="usersConfigFileName">ftpusers.properties</property>
+    
+    <!-- Define callbacks to be invoked alongside MC Lifecycle -->
+    <install method="initializeServer" state="Configured" />
+    <install method="startServer" state="Started "/>
+    <uninstall method="stopServer" />
+    
+  </bean>
+  
+</deployment>
\ No newline at end of file

Added: projects/ejb-book/trunk/ch06-filetransfer/src/main/resources/ftpusers.properties
===================================================================
--- projects/ejb-book/trunk/ch06-filetransfer/src/main/resources/ftpusers.properties	                        (rev 0)
+++ projects/ejb-book/trunk/ch06-filetransfer/src/main/resources/ftpusers.properties	2009-05-20 04:48:57 UTC (rev 89155)
@@ -0,0 +1,6 @@
+# Users / Passwords file
+ftpserver.user.user.idletime=0
+ftpserver.user.user.userpassword=password
+ftpserver.user.user.homedirectory=/
+ftpserver.user.user.writepermission=true
+ftpserver.user.user.enableflag=true
\ No newline at end of file

Added: projects/ejb-book/trunk/ch06-filetransfer/src/test/java/org/jboss/ejb3/examples/ch06/filetransfer/FileTransferUnitTestCase.java
===================================================================
--- projects/ejb-book/trunk/ch06-filetransfer/src/test/java/org/jboss/ejb3/examples/ch06/filetransfer/FileTransferUnitTestCase.java	                        (rev 0)
+++ projects/ejb-book/trunk/ch06-filetransfer/src/test/java/org/jboss/ejb3/examples/ch06/filetransfer/FileTransferUnitTestCase.java	2009-05-20 04:48:57 UTC (rev 89155)
@@ -0,0 +1,403 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.examples.ch06.filetransfer;
+
+import java.io.File;
+
+import javax.ejb.PostActivate;
+import javax.ejb.PrePassivate;
+
+import junit.framework.TestCase;
+
+import org.jboss.logging.Logger;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * FileTransferUnitTestCase
+ * 
+ * Test cases to ensure that the FileTransfer business
+ * logic is intact, outside of the container.
+ * 
+ * This is not technically part of the SFSB examples, but is 
+ * in place to ensure that everything with the example itself
+ * is working as expected.
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class FileTransferUnitTestCase
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Logger
+    */
+   private static final Logger log = Logger.getLogger(FileTransferUnitTestCase.class);
+
+   /**
+    * The FTP Service to which we'll connect
+    */
+   private static FtpServerPojo ftpService;
+
+   /**
+    * Port to which the FTP Service will bind
+    */
+   private static final int FTP_SERVICE_BIND_PORT = 12345;
+
+   /**
+    * Host to which the FTP Client will connect
+    */
+   private static final String FTP_CLIENT_CONNECT_HOST = "127.0.0.1";
+
+   /**
+    * Name of the users configuration file for the server
+    */
+   private static final String FILE_NAME_USERS_CONFIG = "ftpusers.properties";
+
+   /**
+    * The name of the directory under the writable temp filesystem which
+    * will act as the home for these tests
+    */
+   private static final String RELATIVE_LOCATION_HOME = "ejb31_ch06-example-ftpHome";
+
+   /**
+    * The name of the system property denoting the I/O temp directory
+    */
+   private static final String SYS_PROP_NAME_IO_TMP_DIR = "java.io.tmpdir";
+
+   /**
+    * The File we'll use as the writeable home for FTP operations.  Created and
+    * destroyed alongside test lifecycle.
+    */
+   private static File ftpHome;
+
+   //-------------------------------------------------------------------------------------||
+   // Instance Members -------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * The FTP Client
+    */
+   private FileTransferBean ftpClient;
+
+   //-------------------------------------------------------------------------------------||
+   // Lifecycle --------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Creates, initializes, and starts the FTP Service 
+    * to which our test clients will connect. 
+    * Called once before any tests run.
+    */
+   @BeforeClass
+   public static void createFtpService() throws Exception
+   {
+      // Create the FTP Service
+      final FtpServerPojo service = new FtpServerPojo();
+
+      // Configure
+      service.setBindPort(FTP_SERVICE_BIND_PORT);
+      service.setUsersConfigFileName(FILE_NAME_USERS_CONFIG);
+
+      // Initialize
+      service.initializeServer();
+
+      // Start
+      service.startServer();
+
+      // Set (on success)
+      log.info("Started up test FTP Service: " + service);
+      ftpService = service;
+   }
+
+   /**
+    * Stops and resets the FTP Service.  Called once after
+    * all tests are done.
+    * 
+    * @throws Exception
+    */
+   @AfterClass
+   public static void destroyFtpService() throws Exception
+   {
+      // Only run if initialization finished
+      if (ftpService == null)
+      {
+         return;
+      }
+
+      // Stop the server
+      ftpService.stopServer();
+
+      // Reset
+      ftpService = null;
+      log.info("Brought down test FTP Service");
+   }
+
+   /**
+    * Creates and initializes the FTP Client used in testing.
+    * Creates the directory which we'll use as the writeable home 
+    * for FTP operations.  Fired before each test is run.
+    */
+   @Before
+   public void initialize() throws Exception
+   {
+      // Create the writeable home
+      this.createFtpHome();
+
+      // Create client
+      final FileTransferBean ftpClient = new FileTransferBean();
+
+      // Set properties
+      ftpClient.setConnectHost(FTP_CLIENT_CONNECT_HOST);
+      ftpClient.setConnectPort(FTP_SERVICE_BIND_PORT);
+
+      // Connect
+      ftpClient.connect();
+
+      // Set
+      this.ftpClient = ftpClient;
+      log.info("Set FTP Client: " + ftpClient);
+   }
+
+   /**
+    * Disconnects and resets the FTP Client.  Removes the writeable
+    * home for FTP operations.  Fired after each 
+    * test has completed.
+    * 
+    * @throws Exception
+    */
+   @After
+   public void cleanup() throws Exception
+   {
+      // Get client
+      final FileTransferBean ftpClient = this.ftpClient;
+
+      // If set
+      if (ftpClient != null)
+      {
+         // Disconnect and reset
+         ftpClient.disconnect();
+         this.ftpClient = null;
+      }
+
+      // Remove the writeable home
+      this.deleteFtpHome();
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Tests ------------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Tests that the a new directory can be made, we can switch 
+    * into it, and we can obtain the present working directory of our newly-created
+    * directory
+    */
+   @Test
+   public void testMkdirCdAndPwd() throws Exception
+   {
+      // Log
+      log.info("testMkdirAndPwd");
+
+      // Get the client
+      final FileTransferCommonBusiness client = this.ftpClient;
+
+      // Switch to home
+      final String home = getFtpHome().getAbsolutePath();
+      client.cd(home);
+
+      // Ensure we're home
+      final String pwdBefore = client.pwd();
+      TestCase.assertEquals("Present working directory should be our home", home, pwdBefore);
+
+      // Make the directory
+      final String newDir = "newDirectory";
+      client.mkdir(newDir);
+
+      // cd into the new dir
+      client.cd(newDir);
+
+      // Ensure we're in the new directory
+      final String pwdAfter = client.pwd();
+      TestCase.assertEquals("Present working directory should be our new directory", home + File.separator + newDir,
+            pwdAfter);
+   }
+
+   /**
+    * Mocks the passivation/activation process by manually invoking
+    * upon the {@link PrePassivate} and {@link PostActivate} lifecycle
+    * callbacks.  The client should function properly after these calls are made,
+    * reconnecting as expected, and resuming into the correct present working 
+    * directory
+    * 
+    * @throws Exception
+    */
+   @Test
+   public void testPassivationAndActivation() throws Exception
+   {
+      // Log
+      log.info("testPassivationAndActivation");
+
+      // Get the client
+      final FileTransferCommonBusiness client = this.ftpClient;
+
+      // Switch to home
+      final String home = getFtpHome().getAbsolutePath();
+      client.cd(home);
+
+      // Test the pwd
+      final String pwdBefore = client.pwd();
+      TestCase.assertEquals("Present working directory should be set to home", home, pwdBefore);
+
+      // Mock passivation
+      log.info("Mock passivation");
+      client.disconnect();
+
+      // Mock activation
+      log.info("Mock activation");
+      client.connect();
+
+      // Test the pwd
+      final String pwdAfter = client.pwd();
+      TestCase.assertEquals("Present working directory should be the same as before passivation/activation", home,
+            pwdAfter);
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Internal Helper Methods ------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Deletes the writable FTP Home
+    * 
+    * @throws Exception
+    */
+   protected void deleteFtpHome() throws Exception
+   {
+      final File ftpHome = getFtpHome();
+      if (!ftpHome.exists())
+      {
+         throw new RuntimeException("Error in test setup; FTP Home should exist: " + ftpHome.getAbsolutePath());
+      }
+      final boolean removed = this.deleteRecursive(ftpHome);
+      if (!removed)
+      {
+         throw new RuntimeException("Request to remove the FTP Home failed: " + ftpHome.getAbsolutePath());
+      }
+      log.info("Removed FTP Home: " + ftpHome.getAbsolutePath());
+   }
+
+   /**
+    * Recursively deletes all contents of the specified root, 
+    * including the root itself.  If the specified root does not exist, 
+    * no action is taken.
+    * 
+    * @param root
+    * @return true if deleted, false otherwise
+    */
+   protected boolean deleteRecursive(final File root)
+   {
+      // Ensure exists
+      if (!root.exists())
+      {
+         return false;
+      }
+
+      // Get all children
+      final File[] children = root.listFiles();
+      // If it's a directory
+      if (children != null)
+      {
+         // Remove all children
+         for (final File child : children)
+         {
+            this.deleteRecursive(child);
+         }
+      }
+
+      // Delete me
+      final boolean success = root.delete();
+      log.info("Deleted: " + root);
+      return success;
+   }
+
+   /**
+    * Creates the writable FTP Home
+    * 
+    * @throws Exception
+    */
+   protected void createFtpHome() throws Exception
+   {
+      final File ftpHome = getFtpHome();
+      if (ftpHome.exists())
+      {
+         throw new RuntimeException("Error in test setup; FTP Home should not yet exist: " + ftpHome.getAbsolutePath());
+      }
+      final boolean created = ftpHome.mkdir();
+      if (!created)
+      {
+         throw new RuntimeException("Request to create the FTP Home failed: " + ftpHome.getAbsolutePath());
+      }
+      log.info("Created FTP Home: " + ftpHome.getAbsolutePath());
+   }
+
+   /**
+    * Obtains the writeable home for these tests, set under the namespace of the
+    * IO Temp directory
+    */
+   private static File getFtpHome() throws Exception
+   {
+      // If the home is not defined
+      if (ftpHome == null)
+      {
+
+         // Get the property
+         final String sysPropIoTempDir = SYS_PROP_NAME_IO_TMP_DIR;
+         final String ioTempDir = System.getProperty(sysPropIoTempDir);
+         if (ioTempDir == null)
+         {
+            throw new RuntimeException("I/O temp directory was not specified by system property: " + sysPropIoTempDir);
+         }
+
+         // Make the File
+         final File ioTempDirFile = new File(ioTempDir);
+         if (!ioTempDirFile.exists())
+         {
+            throw new RuntimeException("I/O Temp directory does not exist: " + ioTempDirFile.getAbsolutePath());
+         }
+
+         // Append the suffix for our home
+         final File home = new File(ioTempDirFile, RELATIVE_LOCATION_HOME);
+         ftpHome = home;
+      }
+
+      // Return
+      return ftpHome;
+   }
+}

Added: projects/ejb-book/trunk/ch06-filetransfer/src/test/resources/log4j.xml
===================================================================
--- projects/ejb-book/trunk/ch06-filetransfer/src/test/resources/log4j.xml	                        (rev 0)
+++ projects/ejb-book/trunk/ch06-filetransfer/src/test/resources/log4j.xml	2009-05-20 04:48:57 UTC (rev 89155)
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<!-- ===================================================================== -->
+<!--  Log4j Configuration                                                  -->
+<!-- ===================================================================== -->
+
+<!--
+   | For more configuration infromation and examples see the Jakarta Log4j
+   | website: http://jakarta.apache.org/log4j
+ -->
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
+
+  <!-- ============================== -->
+  <!-- Append messages to the console -->
+  <!-- ============================== -->
+
+  <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
+    <param name="Target" value="System.out"/>
+    <param name="Threshold" value="INFO"/>
+    <layout class="org.apache.log4j.PatternLayout">
+      <param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
+    </layout>
+  </appender>
+
+
+  <!-- ================ -->
+  <!-- Limit categories -->
+  <!-- ================ -->
+  
+  <category name="org.jboss.ejb3.examples">
+    <priority value="ALL"/>
+  </category>
+  
+  <!-- ======================= -->
+  <!-- Setup the Root category -->
+  <!-- ======================= -->
+
+  <root>
+    <appender-ref ref="CONSOLE"/>
+  </root>
+  
+</log4j:configuration>




More information about the jboss-cvs-commits mailing list