Issue
=====
ExtendedProperties is used as the persistence mechanism for TurbineResources.
It has a nice feature which allows to include external properties file with
an include directive, thus allowing complex webapp like Jetspeed to store their
specific properties in their own file without adding too much complexity
to the existing TurbineResources.
Unfortunately, such an include directive requires the path given to be an 
absolute reference to the file or a JVM relative one since it uses default
java.io.File() behavior. This makes it unsuitable for webapp WAR distribution
since it's impossible to know in advance either the JVM or absolute reference
to a file on a target computer.

Description of the patch
========================
This patch allows to use the directory of the currently parsed properties file
as the base directory for resolving relative paths.
For example, if I have a TurbineResources.properties file in

d:/cvs/jetspeed/config/TurbineResources.properties

and in this file a directive :

include=./JetspeedResources.properties

This can be resolved with the patch as 

d:/cvs/jetspeed/config/JetspeedResources.properties.

Impact on existing code
=======================
This patch should have no impact on existing code since it still
allows all the previous include path description to resolve normally.
The new relative case is only tested as a fallback of the default 
resolution mechanism.

Patch
=====

8<----------------------------------------------8<-----------------------------------------8<
cvs diff -u ExtendedProperties.java (in directory
D:\cvs\turbine\src\java\org\apache\java\util)
Index: ExtendedProperties.java
===================================================================
RCS file:
/products/cvs/turbine/turbine/src/java/org/apache/java/util/ExtendedProperties.java,v
retrieving revision 1.4
diff -u -r1.4 ExtendedProperties.java
--- ExtendedProperties.java     2000/09/15 23:58:10     1.4
+++ ExtendedProperties.java     2000/11/23 13:08:32
@@ -96,7 +96,8 @@
  *  <li>
  *   If a property is named "include" (or whatever is defined by
  *   setInclude() and getInclude() and the value of that property is
- *   the full path to a file on disk, that file will be included into
+ *   either the full path to a file on disk or a relative path to the
+ *   currently parsed properties file, that file will be included into
  *   the ConfigurationsRepository.  Duplicate name values will be
  *   replaced, so be careful.
  *  </li>
@@ -278,7 +279,7 @@
     public ExtendedProperties (String file)
         throws IOException
     {
-        this.load(new FileInputStream(file));
+        this.load(new FileInputStream(file), new File(file));
     }
 
     /**
@@ -312,6 +313,22 @@
     public synchronized void load(InputStream input)
         throws IOException
     {
+        // load with an empty context
+        load(input, null);
+    }
+
+    /**
+     * Load the properties from the given input stream and provides 
+     * a directory context for resolving relative include paths.
+     *
+     * @param input An InputStream.
+     * @param parent the directory to use as reference
+     *        when resolving relative include directives
+     * @exception IOException.
+     */
+    public synchronized void load(InputStream input, File parent)
+        throws IOException
+    {
         PropertiesReader reader =
             new PropertiesReader(new InputStreamReader(input));
 
@@ -333,14 +350,36 @@
                         continue;
 
                     // Recursively load properties files.
-                    File file = new File(value);
+                    
                     if (getInclude() != null &&
-                        key.equalsIgnoreCase(getInclude()) &&
-                        file != null &&
-                        file.exists() &&
-                        file.canRead())
-                        load ( new FileInputStream(file) );
+                        key.equalsIgnoreCase(getInclude()) ) {
 
+                        // First try to load the file as
+                        // an absolute path or relative to the
+                        // JVM
+                        File file = new File(value);
+                        
+                        if (file != null &&
+                            file.exists() &&
+                            file.canRead()) {
+                            load ( new FileInputStream(file), file );
+                         } else if (!file.isAbsolute()) {
+                             // try a parent relative path if file
+                             // is relative, else give up
+                             
+                            // make sure parent file refers to a
directory
+                            if ((parent!=null) &&
(!parent.isDirectory())) {
+                                parent = parent.getParentFile();
+                            }
+                            
+                            file = new File(parent, value);
+                            if (file != null &&
+                                file.exists() &&
+                                file.canRead())
+                                load ( new FileInputStream(file), file
);
+                        }
+                    }
+                    
                     PropertiesTokenizer tokenizer =
                         new PropertiesTokenizer(value);
                     while (tokenizer.hasMoreTokens())

8<----------------------------------------------8<-----------------------------------------8<

Thanks for committing this patch to the Turbine codebase.

--
Rapha�l Luta - [EMAIL PROTECTED]


------------------------------------------------------------
To subscribe:        [EMAIL PROTECTED]
To unsubscribe:      [EMAIL PROTECTED]
Search: <http://www.mail-archive.com/turbine%40list.working-dogs.com/>
Problems?:           [EMAIL PROTECTED]

Reply via email to