I'm sending my patch for Turbine based web-apps that are being deployed as a 
WAR/EAR modules.

This is a workaround and not a complete solution of the issue, since there is 
a need for a major refactoring in turbine's services which assumes that there 
is always an "applicationRoot" available.

The hack here is based on the fact that fortunately all services (or most of 
them) and the turbine's main servlet initialization access resources through 
the turbine's static getRealPath(String) method which returns an absolute 
path of the resource.

The proposed new behaviour is:

There are two new methods.

[1] java.io.InputStream getResourceAsStream(String) which returns an 
InputStream, obtained from the servlet's context, to the specified resource.

[2] java.io.File getTempFileFromResource(String) which retrieves an 
InputStream, using the above method, and writes all resource's content to a 
temporary created file somewhere in the platforms temp directory 
(File.createTempFile(Stirng, String) is used).

Turbine's static method getRealPath(String) is altered as:

1) first an attempt is made to retrieve the requested resource from the 
servlet's context and if successfull the absolute path of the temporary file 
is returned to the caller

2) if step (1) is not succesfull then the old behaviour is used instead (which 
should only happen if we're running junit tests AFAIK) 

patch against TURBINE_2_3 version.

I have succesfully compiled turbine with the patch applied and deployed an WAR 
turbine based app contained within an EAR module. Certainly this is just a 
workaround and not all services will run correctly. In my case, the following 
services were enabled during tests:
services.FactoryService.classname=org.apache.turbine.services.factory.TurbineFactoryService
services.PoolService.classname=org.apache.turbine.services.pool.TurbinePoolService
services.RunDataService.classname=org.apache.turbine.services.rundata.TurbineRunDataService
services.ServletService.classname=org.apache.turbine.services.servlet.TurbineServletService
services.AssemblerBrokerService.classname=org.apache.turbine.services.assemblerbroker.TurbineAssemblerBrokerService
services.PullService.classname=org.apache.turbine.services.pull.TurbinePullService
services.MimeTypeService.classname=org.apache.turbine.services.mimetype.TurbineMimeTypeService
services.GlobalCacheService.classname=org.apache.turbine.services.cache.TurbineGlobalCacheService
services.UniqueIdService.classname=org.apache.turbine.services.uniqueid.TurbineUniqueIdService
services.SecurityService.classname=gr.forthnet.backgroundftp.web.turbine.services.security.BackgroundFTPSecurityService
services.TemplateService.classname=org.apache.turbine.services.template.TurbineTemplateService
services.VelocityService.classname=org.apache.turbine.services.velocity.TurbineVelocityService

And I had no problems at all. 

If the patch will be accepted I would like to continue and refactor some 
services which currently requires an "applicationRoot" available. 

Best Regards 
Filippos Slavik



Index: Turbine.java
===================================================================
RCS file: /home/cvspublic/jakarta-turbine-2/src/java/org/apache/turbine/
Turbine.java,v
retrieving revision 1.45
diff -u -r1.45 Turbine.java
--- Turbine.java        2 Jul 2003 16:52:24 -0000       1.45
+++ Turbine.java        9 Dec 2003 21:14:20 -0000
@@ -54,10 +54,15 @@
  * <http://www.apache.org/>.
  */
 
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.Properties;
 
 import javax.servlet.ServletConfig;
@@ -135,6 +140,7 @@
  * @author <a href="mailto:[EMAIL PROTECTED]">Henning P. Schmiedehausen</a>
  * @author <a href="mailto:[EMAIL PROTECTED]">Quinton McCombs</a>
  * @author <a href="mailto:[EMAIL PROTECTED]">Eric Pugh</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Filippos Slavik</a>
  * @version $Id: Turbine.java,v 1.45 2003/07/02 16:52:24 henning Exp $
  */
 public class Turbine
@@ -263,6 +269,9 @@
     private void configure(ServletConfig config, ServletContext context)
             throws Exception
     {
+               // Set the Servlet's context right away.
+               setTurbineServletContext(context);
+               
         //
         // Set up Commons Logging to use the Log4J Logging
         //
@@ -284,6 +293,14 @@
         if (applicationRoot == null || applicationRoot.equals(WEB_CONTEXT))
         {
             applicationRoot = webappRoot;
+            if(applicationRoot==null) {
+               // if we're running within a servlet container enviroment
+               // the applicationRoot attribute will have a null value, since
+               // the applicationRoot can be a WAR or EAR file. Just set here
+               // a dummy value to avoid NullPointerExceptions with jakarta's
+               // common configuration framework
+               applicationRoot="foo";
+            }
             // log.info("got empty or 'webContext' Application root. 
Application root now: " + applicationRoot);
         }
 
@@ -390,7 +407,7 @@
 
         
         setTurbineServletConfig(config);
-        setTurbineServletContext(context);
+        
 
         getServiceManager().setApplicationRoot(applicationRoot);
 
@@ -459,6 +476,60 @@
     }
 
     /**
+     * Returns the resource located at the named path as an 
<code>InputStream</code> object.
+     * 
+        * @param resource_path a <code>String</code> specifying the path to the 
resource
+        * @return the <code>InputStream</code> returned, or <code>null</code> if no 
resource exists at the specified path.
+        */
+       public static InputStream getResourceAsStream(String resource_path) {
+       return getTurbineServletContext().getResourceAsStream(resource_path);
+    }
+    
+    /**
+     * Returns a File instance of a given resource. This method is supplied 
here
+     * as a workaround for all turbine specific code which tries to access 
web-app
+     * resources directly with absolute paths (getRealPath()).
+     * 
+     * The tweak here is that the resource is retrieved from an 
<code>InputStream</code>
+     * acquired from the servlet's context and it is written to a temporary 
file. 
+     * 
+        * @param resource_path a <code>String</code> specifying the path to the 
resource
+        * @return An <code>File</code> instance pointing to the temp file or 
<code>null</code>
+        * if the resource couldn't be found.
+        */
+       public static File getTempFileFromResource(String resource_path) {
+       InputStream in = null;
+       OutputStream out = null;
+       try {
+                       File f_out = File.createTempFile("turbine_temp_resource", 
".tmp");
+                       f_out.deleteOnExit();
+                       in = new 
BufferedInputStream(getResourceAsStream(resource_path));
+                       out = new BufferedOutputStream(new FileOutputStream(f_out));
+                       int b;
+                       while((b=in.read())!=-1)
+                               out.write(b);
+                       return f_out;
+               } catch (Exception ex) {
+                       return null;
+               } finally {
+                       if(in!=null) {
+                               try {
+                                       in.close();
+                                       in = null;
+                               } catch(Exception ex) {
+                               }
+                       }
+                       if(out!=null) {
+                               try {
+                                       out.flush();
+                                       out.close();
+                                       out = null;
+                               } catch(Exception ex) {
+                               }
+                       }
+               }
+    }
+    /**
      * Finds the specified servlet configuration/initialization
      * parameter, looking first for a servlet-specific parameter, then
      * for a global parameter, and using the provided default if not
@@ -1120,13 +1191,19 @@
      */
     public static String getRealPath(String path)
     {
-        if (path.startsWith("/"))
-        {
-            path = path.substring(1);
+        // try to retrieve the requested resource
+        // using the getTempFileFromResource(String).
+        File resource_file = getTempFileFromResource(path);
+        if(resource_file==null || !resource_file.exists()) {
+               // oops! Resource is not available which means that
+               // either we are not currently running within a servlet
+               // container enviroment or we were unable to retrieve
+               // the resource via getResourceAsStream() for some reason. 
+               // Fallback to Turbine's default behaviour;
+                       resource_file = new File(getApplicationRoot(), 
path.startsWith("/") ? 
path.substring(1) : path);
         }
-
-        return new File(getApplicationRoot(), path).getAbsolutePath();
-    }
+        return resource_file.getAbsolutePath();
+       }
 
     /**
      * Return an instance of the currently configured Service Manager
-- 
####################################################################
Filippos Slavik
FORTHnet R&D, Heraklion, Greece
e-mail : [EMAIL PROTECTED]
phone : (+30) 2811 391230
Key ID: 0xF4B5B375 Filippos Slavik(search pgp.mit.edu)
Key FingerPrint: 81D4 25D0 01EB 9DCA 62E4  B694 20E7 31FB F4B5 B375
####################################################################

"The software said 'runs on Win95 or better,' so I installed it
on Linux..."




---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to