add clone support for config objects


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@995661 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/sigil/common/core/src/org/apache/felix/sigil/common/config/BldConfig.java b/sigil/common/core/src/org/apache/felix/sigil/common/config/BldConfig.java
index 34734fd..c3d72f9 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/common/config/BldConfig.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/common/config/BldConfig.java
@@ -32,7 +32,7 @@
 
 import org.apache.felix.sigil.common.util.QuoteUtil;
 
-public class BldConfig
+public class BldConfig implements Cloneable
 {
     // control properties
     public static final String C_BUNDLES = "-bundles";
@@ -593,4 +593,66 @@
         return "STRING: " + string + " LIST:" + list + " MAP: " + map + " PROPERTY: "
             + property + " CONFIG:" + config + "\nDFLT{ " + dflt + "}";
     }
+    
+    public BldConfig clone() {
+        try
+        {
+            BldConfig bc = (BldConfig) super.clone();
+            bc.string = new TreeMap<String, String>(bc.string);
+            bc.list = cloneMap(bc.list);
+            bc.map = cloneMap(bc.map);
+            bc.config = new TreeMap<String, BldConfig>(bc.config);
+            bc.property = new TreeMap<String, Properties>(bc.property);
+
+            // default config - not modified or saved
+            // bc.dflt = bc.dflt.clone();
+
+            bc.unknown = cloneProps(bc.unknown);
+            
+            return bc;
+        }
+        catch (CloneNotSupportedException e)
+        {
+            throw new IllegalStateException(e);
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    private static <K, V> Map<K, V> cloneMap(Map<K,V> map) {
+        Map clone = new TreeMap();
+        for (Map.Entry<?,?> e : map.entrySet()) {
+            if ( e.getValue() == null ) {
+                clone.put(e.getKey(), null);
+            }
+            else if ( e.getValue() instanceof List<?> ) {
+                clone.put(e.getKey(), new ArrayList((List<?>) e.getValue()));
+            }
+            else if (e.getValue() instanceof Map<?,?>) {
+                clone.put(e.getKey(), cloneMap((Map<?,?>)e.getValue()));
+            }
+            else if (e.getValue() instanceof String) {
+                clone.put(e.getKey(), e.getValue());
+            }
+            else if (e.getValue() instanceof BldConfig) {
+                BldConfig c = (BldConfig) e.getValue();
+                clone.put(e.getKey(), c.clone());
+            }
+            else if (e.getValue() instanceof Properties) {
+                Properties p = (Properties) e.getValue();
+                clone.put(e.getKey(), cloneProps(p));
+            }
+            else {
+                throw new IllegalStateException("Unexpected value: " + e.getValue());
+            }
+        }
+        return clone;
+    }
+    
+    private static Properties cloneProps(Properties p) {
+        Properties props = new Properties();
+        for (Map.Entry<?,?> pe : props.entrySet()) {
+            props.put(pe.getKey(), pe.getValue());
+        }
+        return props;
+    }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/common/config/BldProject.java b/sigil/common/core/src/org/apache/felix/sigil/common/config/BldProject.java
index 6768f6c..43b4c40 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/common/config/BldProject.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/common/config/BldProject.java
@@ -57,7 +57,7 @@
 import org.apache.felix.sigil.common.osgi.VersionRange;
 import org.apache.felix.sigil.common.osgi.VersionTable;
 
-public class BldProject implements IBldProject, IRepositoryConfig
+public class BldProject implements IBldProject, IRepositoryConfig, Cloneable
 {
     private static final String OVERRIDE_PREFIX = "sigil.";
     private static final int MAX_HEADER = 10240;
@@ -840,6 +840,22 @@
         for (File d : dirs)
             findSrcPkgs(d, pkg, result);
     }
+    
+    public BldProject clone() {
+        BldProject p;
+        try
+        {
+            p = (BldProject) super.clone();
+            p.config = p.config.clone();
+            p.convert = new BldConverter(p.config);
+            p.requirements = p.requirements == null ? null : p.requirements.clone();
+        }
+        catch (CloneNotSupportedException e)
+        {
+            throw new IllegalStateException(e);
+        }
+        return p;
+    }
 
     /**
      * BldBundle
diff --git a/sigil/common/core/src/org/apache/felix/sigil/common/config/IBldProject.java b/sigil/common/core/src/org/apache/felix/sigil/common/config/IBldProject.java
index 5db4c5f..d7838c1 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/common/config/IBldProject.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/common/config/IBldProject.java
@@ -129,6 +129,8 @@
      * gets the last modification date of the project file.
      */
     long getLastModified();
+    
+    IBldProject clone();
 
     interface IBldBundle
     {