Update internal values that use sets etc to use null objects or arrays to improve memory profile FELIX-2092

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@911063 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/SigilBundle.java b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/SigilBundle.java
index 6915a88..cbf93bd 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/SigilBundle.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/SigilBundle.java
@@ -30,8 +30,9 @@
 import java.net.URI;
 import java.net.URL;
 import java.net.URLConnection;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
 
 import org.apache.felix.sigil.core.BldCore;
 import org.apache.felix.sigil.model.AbstractCompoundModelElement;
@@ -55,9 +56,9 @@
     private static final long serialVersionUID = 1L;
 
     private IBundleModelElement bundle;
-    private Set<IPath> sourcePaths;
-    private Set<String> classpath;
-    private Set<String> packages;
+    private IPath[] sourcePaths;
+    private String[] classpath;
+    private String[] packages;
     private IPath location;
 
     private IPath sourcePathLocation;
@@ -67,9 +68,9 @@
     public SigilBundle()
     {
         super( "Sigil Bundle" );
-        sourcePaths = new HashSet<IPath>();
-        classpath = new HashSet<String>();
-        packages = new HashSet<String>();
+        sourcePaths = new IPath[0];
+        classpath = new String[0];
+        packages = new String[0];
     }
 
 
@@ -104,6 +105,15 @@
                     .getCause() );
             }
         }
+        
+        updateManifest(location);
+    }
+
+
+    private void updateManifest(IPath location2)
+    {
+        // TODO Auto-generated method stub
+        
     }
 
 
@@ -212,43 +222,53 @@
 
     public void addSourcePath( IPath path )
     {
-        sourcePaths.add( path );
+        ArrayList<IPath> tmp = new ArrayList<IPath>(getSourcePaths());
+        tmp.add(path);
+        sourcePaths = tmp.toArray( new IPath[tmp.size()] );
     }
 
 
     public void removeSourcePath( IPath path )
     {
-        sourcePaths.remove( path );
+        ArrayList<IPath> tmp = new ArrayList<IPath>(getSourcePaths());
+        if ( tmp.remove(path) ) {
+            sourcePaths = tmp.toArray( new IPath[tmp.size()] );
+        }
     }
 
 
-    public Set<IPath> getSourcePaths()
+    public Collection<IPath> getSourcePaths()
     {
-        return sourcePaths;
+        return Arrays.asList(sourcePaths);
     }
 
 
     public void clearSourcePaths()
     {
-        sourcePaths.clear();
+        sourcePaths = new IPath[0];
     }
 
 
     public void addClasspathEntry( String encodedClasspath )
     {
-        classpath.add( encodedClasspath.trim() );
+        ArrayList<String> tmp = new ArrayList<String>(getClasspathEntrys());
+        tmp.add(encodedClasspath.trim());
+        classpath = tmp.toArray( new String[tmp.size()] );
     }
 
 
-    public Set<String> getClasspathEntrys()
+    public Collection<String> getClasspathEntrys()
     {
-        return classpath;
+        return Arrays.asList(classpath);
     }
 
 
     public void removeClasspathEntry( String encodedClasspath )
     {
-        classpath.remove( encodedClasspath.trim() );
+        ArrayList<String> tmp = new ArrayList<String>(getClasspathEntrys());
+        if ( tmp.remove( encodedClasspath.trim() ) ) {
+            classpath = tmp.toArray( new String[tmp.size()] );
+        }
     }
 
 
@@ -356,21 +376,30 @@
     }
 
 
-    public Set<String> getPackages()
+    public Collection<String> getPackages()
     {
-        return packages;
+        return Arrays.asList(packages);
     }
 
 
     public void addPackage( String pkg )
     {
-        packages.add( pkg );
+        ArrayList<String> tmp = new ArrayList<String>(getClasspathEntrys());
+        tmp.add(pkg);
+        packages = tmp.toArray( new String[tmp.size()] );
     }
 
 
     public boolean removePackage( String pkg )
     {
-        return packages.remove( pkg );
+        ArrayList<String> tmp = new ArrayList<String>(getClasspathEntrys());
+        if ( tmp.remove(pkg) ) {
+            packages = tmp.toArray( new String[tmp.size()] );
+            return true;
+        }
+        else {
+            return false;
+        }
     }
 
 
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/BundleModelElement.java b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/BundleModelElement.java
index 4a8cc44..abc446c 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/BundleModelElement.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/BundleModelElement.java
@@ -21,6 +21,8 @@
 
 
 import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
@@ -46,9 +48,9 @@
     private URI updateLocation;
     private String symbolicName;
     private Version version = Version.emptyVersion;
-    private Set<IPackageImport> imports;
-    private Set<IPackageExport> exports;
-    private Set<IRequiredBundle> requires;
+    private IPackageImport[] imports;
+    private IPackageExport[] exports;
+    private IRequiredBundle[] requires;
     private URI sourceLocation;
     private Set<String> classpathElements;
     private IRequiredBundle fragmentHost;
@@ -71,9 +73,9 @@
     public BundleModelElement()
     {
         super( "OSGi Bundle" );
-        this.imports = new HashSet<IPackageImport>();
-        this.exports = new HashSet<IPackageExport>();
-        this.requires = new HashSet<IRequiredBundle>();
+        this.imports = new IPackageImport[0];
+        this.exports = new IPackageExport[0];
+        this.requires = new IRequiredBundle[0];
         this.classpathElements = new HashSet<String>();
         this.libraries = new HashSet<ILibraryImport>();
     }
@@ -157,67 +159,78 @@
     }
 
 
-    public Set<IPackageExport> getExports()
+    public Collection<IPackageExport> getExports()
     {
-        return exports;
+        return Arrays.asList(exports);
     }
 
 
     public void addExport( IPackageExport packageExport )
     {
-        exports.add( packageExport );
-        packageExport.setParent( this );
+        HashSet<IPackageExport> tmp = new HashSet<IPackageExport>(getExports());
+        if ( tmp.add(packageExport) ) {
+            exports = tmp.toArray( new IPackageExport[tmp.size()] );
+            packageExport.setParent( this );
+        }
     }
 
-
     public void removeExport( IPackageExport packageExport )
     {
-        if ( exports.remove( packageExport ) )
-        {
+        HashSet<IPackageExport> tmp = new HashSet<IPackageExport>(getExports());
+        if ( tmp.remove(packageExport) ) {
+            exports = tmp.toArray( new IPackageExport[tmp.size()] );
             packageExport.setParent( null );
         }
     }
 
 
-    public Set<IPackageImport> getImports()
+    public Collection<IPackageImport> getImports()
     {
-        return imports;
+        return Arrays.asList(imports);
     }
 
 
     public void addImport( IPackageImport packageImport )
     {
-        imports.add( packageImport );
-        packageImport.setParent( this );
+        HashSet<IPackageImport> tmp = new HashSet<IPackageImport>(getImports());
+        if ( tmp.add(packageImport) ) {
+            imports = tmp.toArray( new IPackageImport[tmp.size()] );
+            packageImport.setParent( this );
+        }
     }
 
 
     public void removeImport( IPackageImport packageImport )
     {
-        if ( imports.remove( packageImport ) )
-        {
+        HashSet<IPackageImport> tmp = new HashSet<IPackageImport>(getImports());
+        if ( tmp.remove(packageImport) ) {
+            imports = tmp.toArray( new IPackageImport[tmp.size()] );
             packageImport.setParent( null );
         }
     }
 
 
-    public Set<IRequiredBundle> getRequiredBundles()
+    public Collection<IRequiredBundle> getRequiredBundles()
     {
-        return requires;
+        return Arrays.asList(requires);
     }
 
 
     public void addRequiredBundle( IRequiredBundle bundle )
     {
-        requires.add( bundle );
-        bundle.setParent( this );
+        HashSet<IRequiredBundle> tmp = new HashSet<IRequiredBundle>(getRequiredBundles());
+        if ( tmp.add(bundle) ) {
+            requires = tmp.toArray( new IRequiredBundle[tmp.size()] );
+            bundle.setParent( this );
+        }
     }
 
 
     public void removeRequiredBundle( IRequiredBundle bundle )
     {
-        if ( requires.remove( bundle ) )
-        {
+        HashSet<IRequiredBundle> tmp = new HashSet<IRequiredBundle>(getRequiredBundles());
+        if ( tmp.remove(bundle) ) {
+            requires = tmp.toArray( new IRequiredBundle[tmp.size()] );
             bundle.setParent( null );
         }
     }
@@ -306,23 +319,23 @@
     {
         BundleModelElement bd = ( BundleModelElement ) super.clone();
 
-        bd.imports = new HashSet<IPackageImport>();
-        bd.exports = new HashSet<IPackageExport>();
-        bd.requires = new HashSet<IRequiredBundle>();
+        bd.imports = new IPackageImport[imports.length];
+        bd.exports = new IPackageExport[exports.length];
+        bd.requires = new IRequiredBundle[requires.length];
 
-        for ( IPackageImport pi : imports )
+        for ( int i = 0; i < imports.length; i++ ) 
         {
-            bd.imports.add( ( IPackageImport ) pi.clone() );
+            bd.imports[i] = (IPackageImport) imports[i].clone();
         }
 
-        for ( IPackageExport pe : exports )
+        for ( int i = 0; i < exports.length; i++ )
         {
-            bd.exports.add( ( IPackageExport ) pe.clone() );
+            bd.exports[i] = ( IPackageExport ) exports[i].clone();
         }
 
-        for ( IRequiredBundle rb : requires )
+        for ( int i = 0; i < requires.length; i++ )
         {
-            bd.requires.add( ( IRequiredBundle ) rb.clone() );
+            bd.requires[i] = ( IRequiredBundle ) requires[i].clone();
         }
 
         return bd;
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/PackageExport.java b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/PackageExport.java
index 70051ee..d3ab4b9 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/PackageExport.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/PackageExport.java
@@ -20,8 +20,9 @@
 package org.apache.felix.sigil.core.internal.model.osgi;
 
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
-import java.util.HashSet;
 
 import org.apache.felix.sigil.model.AbstractModelElement;
 import org.apache.felix.sigil.model.eclipse.ISigilBundle;
@@ -36,8 +37,7 @@
 
     private String name;
     private Version version;
-    private HashSet<String> uses = new HashSet<String>();
-
+    private String[] uses = new String[0];
 
     public PackageExport()
     {
@@ -94,19 +94,23 @@
 
     public void addUse( String use )
     {
-        uses.add( use );
+        ArrayList<String> tmp = new ArrayList<String>(getUses());
+        tmp.add(use);
+        uses = tmp.toArray( new String[tmp.size()] );
     }
 
 
     public Collection<String> getUses()
     {
-        return uses;
+        return Arrays.asList(uses);
     }
 
 
     public void removeUse( String use )
     {
-        uses.remove( use );
+        ArrayList<String> tmp = new ArrayList<String>(getUses());
+        tmp.remove(use);
+        uses = tmp.toArray( new String[tmp.size()] );
     }
 
 
@@ -119,8 +123,8 @@
 
     public void setUses( Collection<String> uses )
     {
-        this.uses.clear();
-        this.uses.addAll( uses );
+        ArrayList<String> tmp = new ArrayList<String>(uses);
+        this.uses = tmp.toArray( new String[tmp.size()] );
     }
 
 
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/AbstractModelElement.java b/sigil/common/core/src/org/apache/felix/sigil/model/AbstractModelElement.java
index 519d1eb..b29ad0a 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/AbstractModelElement.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/AbstractModelElement.java
@@ -46,8 +46,6 @@
     {
         support = new ModelElementSupport( this );
         this.description = description.intern();
-        this.meta = new HashMap<Object, Object>();
-        this.serializedMeta = new HashMap<Serializable, Serializable>();
     }
 
 
@@ -59,7 +57,7 @@
 
     public Map<Object, Object> getMeta()
     {
-        return meta;
+        return meta == null ? Collections.emptyMap() : Collections.unmodifiableMap(meta);
     }
 
 
@@ -76,7 +74,9 @@
         {
             AbstractModelElement clone = ( AbstractModelElement ) super.clone();
 
-            clone.meta = new HashMap<Object, Object>( meta );
+            if ( meta != null ) {
+                clone.meta = new HashMap<Object, Object>( meta );
+            }
 
             return clone;
         }
@@ -186,35 +186,36 @@
         return Collections.emptySet();
     }
 
-
-    protected Object writeReplace()
-    {
-        AbstractModelElement clone = clone();
-
-        for ( Map.Entry<Object, Object> e : clone.meta.entrySet() )
-        {
-            if ( e.getKey() instanceof Serializable && e.getValue() instanceof Serializable )
-            {
-                serializedMeta.put( ( Serializable ) e.getKey(), ( Serializable ) e.getValue() );
-            }
-        }
-
-        clone.meta.clear();
-
-        return clone;
-    }
-
-
     public Class<?> getPropertyType( String name ) throws NoSuchMethodException
     {
         return support.getPropertyType( name );
     }
 
+    protected Object writeReplace()
+    {
+        AbstractModelElement clone = clone();
+
+        if ( clone.meta != null ) {
+            clone.serializedMeta = new HashMap<Serializable, Serializable>(clone.meta.size());
+            
+            for ( Map.Entry<Object, Object> e : clone.meta.entrySet() )
+            {
+                if ( e.getKey() instanceof Serializable && e.getValue() instanceof Serializable )
+                {
+                    clone.serializedMeta.put( ( Serializable ) e.getKey(), ( Serializable ) e.getValue() );
+                }
+            }
+    
+            clone.meta = null;
+        }
+
+        return clone;
+    }
 
     protected Object readResolve()
     {
-        this.meta = new HashMap<Object, Object>( serializedMeta );
-        serializedMeta.clear();
+        meta = serializedMeta == null ? null : new HashMap<Object, Object>( serializedMeta );
+        serializedMeta = null;
         return this;
     }
 
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ISigilBundle.java b/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ISigilBundle.java
index 0e7424f..05c9a3d 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ISigilBundle.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ISigilBundle.java
@@ -21,7 +21,7 @@
 
 
 import java.io.IOException;
-import java.util.Set;
+import java.util.Collection;
 
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -59,13 +59,13 @@
     void removeSourcePath( IPath path );
 
 
-    Set<IPath> getSourcePaths();
+    Collection<IPath> getSourcePaths();
 
 
     void clearSourcePaths();
 
 
-    Set<String> getClasspathEntrys();
+    Collection<String> getClasspathEntrys();
 
 
     void addClasspathEntry( String encodedClasspath );
@@ -102,7 +102,7 @@
      * get package names included in bundle.
      * Can contain wildcards e.g. org.foo.*
      */
-    Set<String> getPackages();
+    Collection<String> getPackages();
 
 
     /**
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IBundleModelElement.java b/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IBundleModelElement.java
index 1ebf287..bd211b9 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IBundleModelElement.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IBundleModelElement.java
@@ -63,7 +63,7 @@
     void setDocURI( URI docURI );
 
 
-    Set<IPackageExport> getExports();
+    Collection<IPackageExport> getExports();
 
 
     void addExport( IPackageExport packageExport );
@@ -72,7 +72,7 @@
     void removeExport( IPackageExport packageExport );
 
 
-    Set<IPackageImport> getImports();
+    Collection<IPackageImport> getImports();
 
 
     void addImport( IPackageImport packageImport );
@@ -81,7 +81,7 @@
     void removeImport( IPackageImport packageImport );
 
 
-    Set<IRequiredBundle> getRequiredBundles();
+    Collection<IRequiredBundle> getRequiredBundles();
 
 
     void addRequiredBundle( IRequiredBundle bundle );
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/job/ResolveProjectsJob.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/job/ResolveProjectsJob.java
index d1f869f..f9bddd8 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/job/ResolveProjectsJob.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/job/ResolveProjectsJob.java
@@ -116,7 +116,7 @@
                     IResolution resolution = resolver.resolve( sigilProject, config, resolutionMonitor );
 
                     // Find missing imports
-                    Set<IPackageImport> imports = sigilProject.getBundle().getBundleInfo().getImports();
+                    Collection<IPackageImport> imports = sigilProject.getBundle().getBundleInfo().getImports();
                     for ( IPackageImport pkgImport : imports )
                     {
                         if ( resolution.getProvider( pkgImport ) == null )
@@ -126,7 +126,7 @@
                     }
 
                     // Find missing required bundles
-                    Set<IRequiredBundle> requiredBundles = sigilProject.getBundle().getBundleInfo()
+                    Collection<IRequiredBundle> requiredBundles = sigilProject.getBundle().getBundleInfo()
                         .getRequiredBundles();
                     for ( IRequiredBundle requiredBundle : requiredBundles )
                     {
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/DependencyManagementSection.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/DependencyManagementSection.java
index 15a7048..e95bf45 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/DependencyManagementSection.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/DependencyManagementSection.java
@@ -176,7 +176,7 @@
 
         // Get the existing imports for the bundle
         IBundleModelElement bundleInfo = getProjectModel().getBundle().getBundleInfo();
-        Set<IPackageImport> existingImports = bundleInfo.getImports();
+        Collection<IPackageImport> existingImports = bundleInfo.getImports();
         Map<String, IPackageImport> existingImportsMap = new HashMap<String, IPackageImport>();
         for ( IPackageImport existingImport : existingImports )
         {
@@ -204,7 +204,7 @@
         }
 
         // Remove required bundles
-        Set<IRequiredBundle> requiredBundles = bundleInfo.getRequiredBundles();
+        Collection<IRequiredBundle> requiredBundles = bundleInfo.getRequiredBundles();
         int requiredBundlesSize = requiredBundles.size();
         for ( IRequiredBundle requiredBundle : requiredBundles )
         {