You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2008/09/01 17:08:10 UTC

svn commit: r690991 [9/20] - in /cxf/sandbox/dosgi: ./ discovery/ discovery/local/ discovery/local/src/ discovery/local/src/main/ discovery/local/src/main/java/ discovery/local/src/main/java/org/ discovery/local/src/main/java/org/apache/ discovery/loca...

Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java Mon Sep  1 08:08:01 2008
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.cache;
+
+import java.io.File;
+import java.util.Map;
+
+import org.apache.felix.framework.Logger;
+import org.apache.felix.moduleloader.IContent;
+
+/**
+ * <p>
+ * This class implements an abstract revision of a bundle archive. A revision
+ * is an abstraction of a bundle's actual content and is associated with a
+ * parent bundle archive. A bundle archive may have multiple revisions assocaited
+ * with it at one time, since updating a bundle results in a new version of the
+ * bundle's content until the bundle is refreshed. Upon a refresh, then old
+ * revisions are then purged. This abstract class is the base class for all
+ * concrete types of revisions, such as ones for a JAR file or directories. All
+ * revisions are assigned a root directory into which all of their state should
+ * be stored, if necessary. Clean up of this directory is the responsibility
+ * of the parent bundle archive and not of the revision itself.
+ * </p>
+ * @see org.apache.felix.framework.cache.BundleCache
+ * @see org.apache.felix.framework.cache.BundleArchive
+**/
+public abstract class BundleRevision
+{
+    private Logger m_logger;
+    private File m_revisionRootDir = null;
+    private String m_location = null;
+
+    /**
+     * <p>
+     * This class is abstract and cannot be created. It represents a revision
+     * of a bundle, i.e., its content. A revision is associated with a particular
+     * location string, which is typically in URL format. Subclasses of this
+     * class provide particular functionality, such as a revision in the form
+     * of a JAR file or a directory. Each revision subclass is expected to use
+     * the root directory associated with the abstract revision instance to
+     * store any state; this will ensure that resources used by the revision are
+     * properly freed when the revision is no longer needed.
+     * </p>
+     * @param logger a logger for use by the revision.
+     * @param revisionRootDir the root directory to be used by the revision
+     *        subclass for storing any state.
+     * @param location the location string associated with the revision.
+     * @param trustedCaCerts the trusted CA certificates if any.
+     * @throws Exception if any errors occur.
+    **/
+    public BundleRevision(Logger logger, File revisionRootDir, String location)
+        throws Exception
+    {
+        m_logger = logger;
+        m_revisionRootDir = revisionRootDir;
+        m_location = location;
+    }
+
+    /**
+     * <p>
+     * Returns the logger for this revision.
+     * </p>
+     * @return the logger instance for this revision.
+    **/
+    public Logger getLogger()
+    {
+        return m_logger;
+    }
+
+    /**
+     * <p>
+     * Returns the root directory for this revision.
+     * </p>
+     * @return the root directory for this revision.
+    **/
+    public File getRevisionRootDir()
+    {
+        return m_revisionRootDir;
+    }
+
+    /**
+     * <p>
+     * Returns the location string this revision.
+     * </p>
+     * @return the location string for this revision.
+    **/
+    public String getLocation()
+    {
+        return m_location;
+    }
+
+    /**
+     * <p>
+     * Returns the main attributes of the JAR file manifest header of the
+     * revision. The returned map is case insensitive.
+     * </p>
+     * @return the case-insensitive JAR file manifest header of the revision.
+     * @throws java.lang.Exception if any error occurs.
+    **/
+    public abstract Map getManifestHeader() throws Exception;
+
+    public abstract IContent getContent() throws Exception;
+
+    /**
+     * <p>
+     * This method is called when the revision is no longer needed. The directory
+     * associated with the revision will automatically be removed for each
+     * revision, so this method only needs to be concerned with other issues,
+     * such as open files.
+     * </p>
+     * @throws Exception if any error occurs.
+    **/
+    public abstract void dispose() throws Exception;
+}
\ No newline at end of file

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/ContentDirectoryContent.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/ContentDirectoryContent.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/ContentDirectoryContent.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/ContentDirectoryContent.java Mon Sep  1 08:08:01 2008
@@ -0,0 +1,192 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.cache;
+
+import org.apache.felix.moduleloader.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+public class ContentDirectoryContent implements IContent
+{
+    private IContent m_content = null;
+    private String m_rootPath = null;
+    private boolean m_opened = false;
+
+    public ContentDirectoryContent(IContent content, String path)
+    {
+        m_content = content;
+        // Add a '/' to the end if not present.
+        m_rootPath = (path.length() > 0) && (path.charAt(path.length() - 1) != '/')
+            ? path + "/" : path;
+    }
+
+    public void open()
+    {
+        m_content.open();
+        m_opened = true;
+    }
+
+    public synchronized void close()
+    {
+        // We do not actually close the associated content
+        // from which we are filtering our directory because
+        // we assume that this will be close manually by
+        // the owner of that content.
+        m_content = null;
+        m_opened = false;
+    }
+
+    public synchronized boolean hasEntry(String name) throws IllegalStateException
+    {
+        if (!m_opened)
+        {
+            throw new IllegalStateException("ContentDirectoryContent is not open");
+        }
+
+        if ((name.length() > 0) && (name.charAt(0) == '/'))
+        {
+            name = name.substring(1);
+        }
+
+        return m_content.hasEntry(m_rootPath + name);
+    }
+
+    public synchronized Enumeration getEntries()
+    {
+        if (!m_opened)
+        {
+            throw new IllegalStateException("ContentDirectoryContent is not open");
+        }
+
+        return new EntriesEnumeration(m_content.getEntries(), m_rootPath);
+    }
+
+    public synchronized byte[] getEntryAsBytes(String name) throws IllegalStateException
+    {
+        if (!m_opened)
+        {
+            throw new IllegalStateException("ContentDirectoryContent is not open");
+        }
+
+        if ((name.length() > 0) && (name.charAt(0) == '/'))
+        {
+            name = name.substring(1);
+        }
+
+        return m_content.getEntryAsBytes(m_rootPath + name);
+    }
+
+    public synchronized InputStream getEntryAsStream(String name)
+        throws IllegalStateException, IOException
+    {
+        if (!m_opened)
+        {
+            throw new IllegalStateException("ContentDirectoryContent is not open");
+        }
+
+        if ((name.length() > 0) && (name.charAt(0) == '/'))
+        {
+            name = name.substring(1);
+        }
+
+        return m_content.getEntryAsStream(m_rootPath + name);
+    }
+
+    public IContent getEntryAsContent(String name)
+    {
+        if (!m_opened)
+        {
+            throw new IllegalStateException("ContentDirectoryContent is not open");
+        }
+
+        if ((name.length() > 0) && (name.charAt(0) == '/'))
+        {
+            name = name.substring(1);
+        }
+
+        return m_content.getEntryAsContent(m_rootPath + name);
+    }
+
+    public String getEntryAsNativeLibrary(String name)
+    {
+        if (!m_opened)
+        {
+            throw new IllegalStateException("ContentDirectoryContent is not open");
+        }
+
+        if ((name.length() > 0) && (name.charAt(0) == '/'))
+        {
+            name = name.substring(1);
+        }
+
+        return m_content.getEntryAsNativeLibrary(m_rootPath + name);
+    }
+
+    public String toString()
+    {
+        return "CONTENT DIR " + m_rootPath + " (" + m_content + ")";
+    }
+
+    private static class EntriesEnumeration implements Enumeration
+    {
+        private Enumeration m_enumeration = null;
+        private String m_rootPath = null;
+        private String m_nextEntry = null;
+
+        public EntriesEnumeration(Enumeration enumeration, String rootPath)
+        {
+            m_enumeration = enumeration;
+            m_rootPath = rootPath;
+            m_nextEntry = findNextEntry();
+        }
+
+        public boolean hasMoreElements()
+        {
+            return (m_nextEntry != null);
+        }
+
+        public Object nextElement()
+        {
+            if (m_nextEntry == null)
+            {
+                throw new NoSuchElementException("No more elements.");
+            }
+            String currentEntry = m_nextEntry;
+            m_nextEntry = findNextEntry();
+            return currentEntry;
+        }
+
+        private String findNextEntry()
+        {
+            // Find next entry that is inside the root directory.
+            while (m_enumeration.hasMoreElements())
+            {
+                String next = (String) m_enumeration.nextElement();
+                if (next.startsWith(m_rootPath) && !next.equals(m_rootPath))
+                {
+                    // Strip off the root directory.
+                    return next.substring(m_rootPath.length());
+                }
+            }
+            return null;
+        }
+    }
+}
\ No newline at end of file

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/ContentDirectoryContent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/ContentDirectoryContent.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java Mon Sep  1 08:08:01 2008
@@ -0,0 +1,280 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.cache;
+
+import org.apache.felix.moduleloader.*;
+import java.io.*;
+import java.util.*;
+import org.apache.felix.framework.Logger;
+
+public class DirectoryContent implements IContent
+{
+    private static final int BUFSIZE = 4096;
+    private static final transient String EMBEDDED_DIRECTORY = "-embedded";
+    private static final transient String LIBRARY_DIRECTORY = "lib";
+
+    private Logger m_logger;
+    private Object m_revisionLock;
+    private File m_rootDir;
+    private File m_dir;
+    private boolean m_opened = false;
+
+    public DirectoryContent(Logger logger, Object revisionLock, File rootDir, File dir)
+    {
+        m_logger = logger;
+        m_revisionLock = revisionLock;
+        m_rootDir = rootDir;
+        m_dir = dir;
+    }
+
+    public void open()
+    {
+        m_opened = true;
+    }
+
+    public synchronized void close()
+    {
+        m_opened = false;
+    }
+
+    public synchronized boolean hasEntry(String name) throws IllegalStateException
+    {
+        if (!m_opened)
+        {
+            throw new IllegalStateException("DirectoryContent is not open");
+        }
+
+        if ((name.length() > 0) && (name.charAt(0) == '/'))
+        {
+            name = name.substring(1);
+        }
+
+        return new File(m_dir, name).exists();
+    }
+
+    public synchronized Enumeration getEntries()
+    {
+        if (!m_opened)
+        {
+            throw new IllegalStateException("JarContent is not open");
+        }
+
+        // Wrap entries enumeration to filter non-matching entries.
+        Enumeration e = new EntriesEnumeration(m_dir);
+
+        // Spec says to return null if there are no entries.
+        return (e.hasMoreElements()) ? e : null;
+    }
+
+    public synchronized byte[] getEntryAsBytes(String name) throws IllegalStateException
+    {
+        if (!m_opened)
+        {
+            throw new IllegalStateException("DirectoryContent is not open");
+        }
+
+        if ((name.length() > 0) && (name.charAt(0) == '/'))
+        {
+            name = name.substring(1);
+        }
+
+        // Get the embedded resource.
+        InputStream is = null;
+        ByteArrayOutputStream baos = null;
+
+        try
+        {
+            is = new BufferedInputStream(new FileInputStream(new File(m_dir, name)));
+            baos = new ByteArrayOutputStream(BUFSIZE);
+            byte[] buf = new byte[BUFSIZE];
+            int n = 0;
+            while ((n = is.read(buf, 0, buf.length)) >= 0)
+            {
+                baos.write(buf, 0, n);
+            }
+            return baos.toByteArray();
+
+        }
+        catch (Exception ex)
+        {
+            return null;
+        }
+        finally
+        {
+            try
+            {
+                if (baos != null) baos.close();
+            }
+            catch (Exception ex)
+            {
+            }
+            try
+            {
+                if (is != null) is.close();
+            }
+            catch (Exception ex)
+            {
+            }
+        }
+    }
+
+    public synchronized InputStream getEntryAsStream(String name)
+        throws IllegalStateException, IOException
+    {
+        if (!m_opened)
+        {
+            throw new IllegalStateException("DirectoryContent is not open");
+        }
+
+        if ((name.length() > 0) && (name.charAt(0) == '/'))
+        {
+            name = name.substring(1);
+        }
+
+        return new FileInputStream(new File(m_dir, name));
+    }
+
+    public synchronized IContent getEntryAsContent(String entryName)
+    {
+        if (!m_opened)
+        {
+            throw new IllegalStateException("DirectoryContent is not open");
+        }
+
+        // Remove any leading slash, since all bundle class path
+        // entries are relative to the root of the bundle.
+        entryName = (entryName.startsWith("/")) ? entryName.substring(1) : entryName;
+
+        // Any embedded JAR files will be extracted to the embedded directory.
+        File embedDir = new File(m_rootDir, m_dir.getName() + EMBEDDED_DIRECTORY);
+
+        // Determine if the entry is an emdedded JAR file or
+        // directory in the bundle JAR file. Ignore any entries
+        // that do not exist per the spec.
+        File file = new File(m_dir, entryName);
+        if (BundleCache.getSecureAction().isFileDirectory(file))
+        {
+            return new DirectoryContent(m_logger, m_revisionLock, m_rootDir, file);
+        }
+        else if (BundleCache.getSecureAction().fileExists(file)
+            && entryName.endsWith(".jar"))
+        {
+            File extractedDir = new File(embedDir,
+                (entryName.lastIndexOf('/') >= 0)
+                    ? entryName.substring(0, entryName.lastIndexOf('/'))
+                    : entryName);
+            synchronized (m_revisionLock)
+            {
+                if (!BundleCache.getSecureAction().fileExists(extractedDir))
+                {
+                    if (!BundleCache.getSecureAction().mkdirs(extractedDir))
+                    {
+                        m_logger.log(
+                            Logger.LOG_ERROR,
+                            "Unable to extract embedded directory.");
+                    }
+                }
+            }
+            System.out.println("+++ EXTRACTED JAR DIR " + extractedDir);
+            return new JarContent(m_logger, m_revisionLock, extractedDir, file);
+        }
+
+        // The entry could not be found, so return null.
+        return null;
+    }
+
+// TODO: This will need to consider security.
+    public synchronized String getEntryAsNativeLibrary(String name)
+    {
+        if (!m_opened)
+        {
+            throw new IllegalStateException("DirectoryContent is not open");
+        }
+
+        return BundleCache.getSecureAction().getAbsolutePath(new File(m_rootDir, name));
+    }
+
+    public String toString()
+    {
+        return "DIRECTORY " + m_dir;
+    }
+
+    private static class EntriesEnumeration implements Enumeration
+    {
+        private File m_dir = null;
+        private File[] m_children = null;
+        private int m_counter = 0;
+
+        public EntriesEnumeration(File dir)
+        {
+            m_dir = dir;
+            m_children = listFilesRecursive(m_dir);
+        }
+
+        public boolean hasMoreElements()
+        {
+            return (m_children != null) && (m_counter < m_children.length);
+        }
+
+        public Object nextElement()
+        {
+            if ((m_children == null) || (m_counter >= m_children.length))
+            {
+                throw new NoSuchElementException("No more entry paths.");
+            }
+
+            // Convert the file separator character to slashes.
+            String abs = m_children[m_counter].getAbsolutePath()
+                .replace(File.separatorChar, '/');
+
+            // Remove the leading path of the reference directory, since the
+            // entry paths are supposed to be relative to the root.
+            StringBuffer sb = new StringBuffer(abs);
+            sb.delete(0, m_dir.getAbsolutePath().length() + 1);
+            // Add a '/' to the end of directory entries.
+            if (m_children[m_counter].isDirectory())
+            {
+                sb.append('/');
+            }
+            m_counter++;
+            return sb.toString();
+        }
+
+        public File[] listFilesRecursive(File dir)
+        {
+            File[] children = dir.listFiles();
+            File[] combined = children;
+            for (int i = 0; i < children.length; i++)
+            {
+                if (children[i].isDirectory())
+                {
+                    File[] grandchildren = listFilesRecursive(children[i]);
+                    if (grandchildren.length > 0)
+                    {
+                        File[] tmp = new File[combined.length + grandchildren.length];
+                        System.arraycopy(combined, 0, tmp, 0, combined.length);
+                        System.arraycopy(grandchildren, 0, tmp, combined.length, grandchildren.length);
+                        combined = tmp;
+                    }
+                }
+            }
+            return combined;
+        }
+    }
+}
\ No newline at end of file

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java Mon Sep  1 08:08:01 2008
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.cache;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.Manifest;
+
+import org.apache.felix.framework.Logger;
+import org.apache.felix.framework.util.FelixConstants;
+import org.apache.felix.framework.util.StringMap;
+import org.apache.felix.framework.util.manifestparser.ManifestParser;
+import org.apache.felix.framework.cache.DirectoryContent;
+import org.apache.felix.moduleloader.IContent;
+import org.apache.felix.framework.cache.JarContent;
+
+/**
+ * <p>
+ * This class implements a bundle archive revision for exploded bundle
+ * JAR files. It uses the specified location directory "in-place" to
+ * execute the bundle and does not copy the bundle content at all.
+ * </p>
+**/
+class DirectoryRevision extends BundleRevision
+{
+    private File m_refDir = null;
+    private Map m_header = null;
+
+    public DirectoryRevision(
+        Logger logger, File revisionRootDir, String location) throws Exception
+    {
+        super(logger, revisionRootDir, location);
+        m_refDir = new File(location.substring(
+            location.indexOf(BundleArchive.FILE_PROTOCOL)
+                + BundleArchive.FILE_PROTOCOL.length()));
+
+        // If the revision directory exists, then we don't
+        // need to initialize since it has already been done.
+        if (BundleCache.getSecureAction().fileExists(getRevisionRootDir()))
+        {
+            return;
+        }
+
+        // Create revision directory, we only need this to store the
+        // revision location, since nothing else needs to be extracted
+        // since we are referencing a read directory already.
+        if (!BundleCache.getSecureAction().mkdir(getRevisionRootDir()))
+        {
+            getLogger().log(
+                Logger.LOG_ERROR,
+                getClass().getName() + ": Unable to create revision directory.");
+            throw new IOException("Unable to create archive directory.");
+        }
+    }
+
+    public synchronized Map getManifestHeader()
+        throws Exception
+    {
+        if (m_header != null)
+        {
+            return m_header;
+        }
+
+        // Read the header file from the reference directory.
+        InputStream is = null;
+
+        try
+        {
+            // Open manifest file.
+            is = BundleCache.getSecureAction()
+                .getFileInputStream(new File(m_refDir, "META-INF/MANIFEST.MF"));
+            // Error if no jar file.
+            if (is == null)
+            {
+                throw new IOException("No manifest file found.");
+            }
+
+            // Get manifest.
+            Manifest mf = new Manifest(is);
+            // Create a case insensitive map of manifest attributes.
+            m_header = new StringMap(mf.getMainAttributes(), false);
+            return m_header;
+        }
+        finally
+        {
+            if (is != null) is.close();
+        }
+    }
+
+    public synchronized IContent getContent() throws Exception
+    {
+        return new DirectoryContent(getLogger(), this, getRevisionRootDir(), m_refDir);
+    }
+
+    public void dispose() throws Exception
+    {
+        // Nothing to dispose of, since we don't maintain any state outside
+        // of the revision directory, which will be automatically deleted
+        // by the parent bundle archive.
+    }
+}
\ No newline at end of file

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/JarContent.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/JarContent.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/JarContent.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/JarContent.java Mon Sep  1 08:08:01 2008
@@ -0,0 +1,596 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.cache;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import org.apache.felix.framework.Logger;
+import org.apache.felix.framework.util.JarFileX;
+import org.apache.felix.moduleloader.IContent;
+
+public class JarContent implements IContent
+{
+    private static final int BUFSIZE = 4096;
+    private static final transient String LEGACY_EMBEDDED_DIRECTORY = "embedded";
+    private static final transient String EMBEDDED_DIRECTORY = "-embedded";
+    private static final transient String LIBRARY_DIRECTORY = "lib";
+
+    private final Logger m_logger;
+    private final Object m_revisionLock;
+    private final File m_rootDir;
+    private final File m_file;
+    private JarFileX m_jarFile = null;
+    // TODO: CACHE - It would be nice to eventually remove this legacy flag.
+    private final boolean m_legacy;
+    private boolean m_opened = false;
+
+    public JarContent(Logger logger, Object revisionLock, File rootDir, File file)
+    {
+        m_logger = logger;
+        m_revisionLock = revisionLock;
+        m_rootDir = rootDir;
+        m_file = file;
+        m_legacy = false;
+    }
+
+    // This is only used by JarRevision.
+    public JarContent(Logger logger, Object revisionLock, File rootDir, File file, boolean legacy)
+    {
+        m_logger = logger;
+        m_revisionLock = revisionLock;
+        m_rootDir = rootDir;
+        m_file = file;
+        m_legacy = legacy;
+    }
+
+    protected void finalize()
+    {
+        if (m_jarFile != null)
+        {
+            try
+            {
+                m_jarFile.close();
+            }
+            catch (IOException ex)
+            {
+                // Not much we can do, so ignore it.
+            }
+        }
+    }
+
+    public synchronized void open()
+    {
+        m_opened = true;
+    }
+
+    public synchronized void close()
+    {
+        try
+        {
+            if (m_jarFile != null)
+            {
+                m_jarFile.close();
+            }
+        }
+        catch (Exception ex)
+        {
+            m_logger.log(
+                Logger.LOG_ERROR,
+                "JarContent: Unable to open JAR file.", ex);
+        }
+
+        m_jarFile = null;
+        m_opened = false;
+    }
+
+    public synchronized boolean hasEntry(String name) throws IllegalStateException
+    {
+        if (!m_opened)
+        {
+            throw new IllegalStateException("JarContent is not open");
+        }
+
+        // Open JAR file if not already opened.
+        if (m_jarFile == null)
+        {
+            try
+            {
+                openJarFile();
+            }
+            catch (IOException ex)
+            {
+                m_logger.log(
+                    Logger.LOG_ERROR,
+                    "JarContent: Unable to open JAR file.", ex);
+                return false;
+            }
+        }
+
+        try
+        {
+            ZipEntry ze = m_jarFile.getEntry(name);
+            return ze != null;
+        }
+        catch (Exception ex)
+        {
+            return false;
+        }
+        finally
+        {
+        }
+    }
+
+    public synchronized Enumeration getEntries()
+    {
+        if (!m_opened)
+        {
+            throw new IllegalStateException("JarContent is not open");
+        }
+
+        // Open JAR file if not already opened.
+        if (m_jarFile == null)
+        {
+            try
+            {
+                openJarFile();
+            }
+            catch (IOException ex)
+            {
+                m_logger.log(
+                    Logger.LOG_ERROR,
+                    "JarContent: Unable to open JAR file.", ex);
+                return null;
+            }
+        }
+
+        // Wrap entries enumeration to filter non-matching entries.
+        Enumeration e = new EntriesEnumeration(m_jarFile.entries());
+
+        // Spec says to return null if there are no entries.
+        return (e.hasMoreElements()) ? e : null;
+    }
+
+    public synchronized byte[] getEntryAsBytes(String name) throws IllegalStateException
+    {
+        if (!m_opened)
+        {
+            throw new IllegalStateException("JarContent is not open");
+        }
+
+        // Open JAR file if not already opened.
+        if (m_jarFile == null)
+        {
+            try
+            {
+                openJarFile();
+            }
+            catch (IOException ex)
+            {
+                m_logger.log(
+                    Logger.LOG_ERROR,
+                    "JarContent: Unable to open JAR file.", ex);
+                return null;
+            }
+        }
+
+        // Get the embedded resource.
+        InputStream is = null;
+        ByteArrayOutputStream baos = null;
+
+        try
+        {
+            ZipEntry ze = m_jarFile.getEntry(name);
+            if (ze == null)
+            {
+                return null;
+            }
+            is = m_jarFile.getInputStream(ze);
+            if (is == null)
+            {
+                return null;
+            }
+            baos = new ByteArrayOutputStream(BUFSIZE);
+            byte[] buf = new byte[BUFSIZE];
+            int n = 0;
+            while ((n = is.read(buf, 0, buf.length)) >= 0)
+            {
+                baos.write(buf, 0, n);
+            }
+            return baos.toByteArray();
+
+        }
+        catch (Exception ex)
+        {
+            m_logger.log(
+                Logger.LOG_ERROR,
+                "JarContent: Unable to read bytes.", ex);
+            return null;
+        }
+        finally
+        {
+            try
+            {
+                if (baos != null) baos.close();
+            }
+            catch (Exception ex)
+            {
+            }
+            try
+            {
+                if (is != null) is.close();
+            }
+            catch (Exception ex)
+            {
+            }
+        }
+    }
+
+    public synchronized InputStream getEntryAsStream(String name)
+        throws IllegalStateException, IOException
+    {
+        if (!m_opened)
+        {
+            throw new IllegalStateException("JarContent is not open");
+        }
+
+        // Open JAR file if not already opened.
+        if (m_jarFile == null)
+        {
+            try
+            {
+                openJarFile();
+            }
+            catch (IOException ex)
+            {
+                m_logger.log(
+                    Logger.LOG_ERROR,
+                    "JarContent: Unable to open JAR file.", ex);
+                return null;
+            }
+        }
+
+        // Get the embedded resource.
+        InputStream is = null;
+
+        try
+        {
+            ZipEntry ze = m_jarFile.getEntry(name);
+            if (ze == null)
+            {
+                return null;
+            }
+            is = m_jarFile.getInputStream(ze);
+            if (is == null)
+            {
+                return null;
+            }
+        }
+        catch (Exception ex)
+        {
+            return null;
+        }
+
+        return is;
+    }
+
+    public synchronized IContent getEntryAsContent(String entryName)
+    {
+        if (!m_opened)
+        {
+            throw new IllegalStateException("JarContent is not open");
+        }
+
+        // Open JAR file if not already opened.
+        if (m_jarFile == null)
+        {
+            try
+            {
+                openJarFile();
+            }
+            catch (IOException ex)
+            {
+                m_logger.log(
+                    Logger.LOG_ERROR,
+                    "JarContent: Unable to open JAR file.", ex);
+                return null;
+            }
+
+        }
+
+        // Remove any leading slash.
+        entryName = (entryName.startsWith("/")) ? entryName.substring(1) : entryName;
+
+        // Any embedded JAR files will be extracted to the embedded directory.
+        // Since embedded JAR file names may clash when extracting from multiple
+        // embedded JAR files, the embedded directory is per embedded JAR file.
+        // For backwards compatibility purposes, don't use the file cache name
+        // for the root bundle JAR file.
+        File embedDir;
+        if (m_legacy)
+        {
+            embedDir = new File(m_rootDir, LEGACY_EMBEDDED_DIRECTORY);
+        }
+        else
+        {
+            embedDir = new File(m_rootDir, m_file.getName() + EMBEDDED_DIRECTORY);
+        }
+
+        // Find the entry in the JAR file and create the
+        // appropriate content type for it.
+
+        // Determine if the entry is an emdedded JAR file or
+        // directory in the bundle JAR file. Ignore any entries
+        // that do not exist per the spec.
+        ZipEntry ze = m_jarFile.getEntry(entryName);
+        if ((ze != null) && ze.isDirectory())
+        {
+            File extractedDir = new File(embedDir, entryName);
+
+            // Extracting an embedded directory file impacts all other existing
+            // contents for this revision, so we have to grab the revision
+            // lock first before trying to create a directory for an embedded
+            // directory to avoid a race condition.
+            synchronized (m_revisionLock)
+            {
+                if (!BundleCache.getSecureAction().fileExists(extractedDir))
+                {
+                    if (!BundleCache.getSecureAction().mkdirs(extractedDir))
+                    {
+                        m_logger.log(
+                            Logger.LOG_ERROR,
+                            "Unable to extract embedded directory.");
+                    }
+                }
+            }
+            return new ContentDirectoryContent(this, entryName);
+        }
+        else if ((ze != null) && ze.getName().endsWith(".jar"))
+        {
+            File extractedJar = new File(embedDir, entryName);
+
+            // Extracting the embedded JAR file impacts all other existing
+            // contents for this revision, so we have to grab the revision
+            // lock first before trying to extract the embedded JAR file
+            // to avoid a race condition.
+            synchronized (m_revisionLock)
+            {
+                if (!BundleCache.getSecureAction().fileExists(extractedJar))
+                {
+                    try
+                    {
+                        extractEmbeddedJar(entryName);
+                    }
+                    catch (Exception ex)
+                    {
+                        m_logger.log(
+                            Logger.LOG_ERROR,
+                            "Unable to extract embedded JAR file.", ex);
+                    }
+                }
+            }
+            return new JarContent(
+                m_logger, m_revisionLock, extractedJar.getParentFile(), extractedJar);
+        }
+
+        // The entry could not be found, so return null.
+        return null;
+    }
+
+// TODO: This will need to consider security.
+    public synchronized String getEntryAsNativeLibrary(String name)
+    {
+        if (!m_opened)
+        {
+            throw new IllegalStateException("JarContent is not open");
+        }
+
+        // Open JAR file if not already opened.
+        if (m_jarFile == null)
+        {
+            try
+            {
+                openJarFile();
+            }
+            catch (IOException ex)
+            {
+                m_logger.log(
+                    Logger.LOG_ERROR,
+                    "JarContent: Unable to open JAR file.", ex);
+                return null;
+            }
+        }
+
+        // Get bundle lib directory.
+        File libDir = new File(m_rootDir, LIBRARY_DIRECTORY);
+        // Get lib file.
+        File libFile = new File(libDir, File.separatorChar + name);
+        // Make sure that the library's parent directory exists;
+        // it may be in a sub-directory.
+        libDir = libFile.getParentFile();
+        if (!BundleCache.getSecureAction().fileExists(libDir))
+        {
+            if (!BundleCache.getSecureAction().mkdirs(libDir))
+            {
+                m_logger.log(
+                    Logger.LOG_ERROR,
+                    "JarContent: Unable to create library directory.");
+                return null;
+            }
+        }
+        // Extract the library from the JAR file if it does not
+        // already exist.
+        if (!BundleCache.getSecureAction().fileExists(libFile))
+        {
+            InputStream is = null;
+
+            try
+            {
+                ZipEntry ze = m_jarFile.getEntry(name);
+                if (ze == null)
+                {
+                    return null;
+                }
+                is = new BufferedInputStream(
+                    m_jarFile.getInputStream(ze), BundleCache.BUFSIZE);
+                if (is == null)
+                {
+                    throw new IOException("No input stream: " + name);
+                }
+
+                // Create the file.
+                BundleCache.copyStreamToFile(is, libFile);
+            }
+            catch (Exception ex)
+            {
+                m_logger.log(
+                    Logger.LOG_ERROR,
+                    "JarContent: Extracting native library.", ex);
+            }
+            finally
+            {
+                try
+                {
+                    if (is != null) is.close();
+                }
+                catch (IOException ex)
+                {
+                    // Not much we can do.
+                }
+            }
+        }
+
+        return BundleCache.getSecureAction().getAbsolutePath(libFile);
+    }
+
+    public String toString()
+    {
+        return "JAR " + m_file.getPath();
+    }
+
+    public File getFile()
+    {
+        return m_file;
+    }
+
+    private void openJarFile() throws IOException
+    {
+        if (m_jarFile == null)
+        {
+            m_jarFile = BundleCache.getSecureAction().openJAR(m_file);
+        }
+    }
+
+    /**
+     * This method extracts an embedded JAR file from the bundle's
+     * JAR file.
+     * @param id the identifier of the bundle that owns the embedded JAR file.
+     * @param jarPath the path to the embedded JAR file inside the bundle JAR file.
+    **/
+    private void extractEmbeddedJar(String jarPath)
+        throws Exception
+    {
+        // Remove leading slash if present.
+        jarPath = (jarPath.length() > 0) && (jarPath.charAt(0) == '/')
+            ? jarPath.substring(1) : jarPath;
+
+        // Any embedded JAR files will be extracted to the embedded directory.
+        // Since embedded JAR file names may clash when extracting from multiple
+        // embedded JAR files, the embedded directory is per embedded JAR file.
+        // For backwards compatibility purposes, don't use the file cache name
+        // for the root bundle JAR file.
+        File embedDir;
+        if (m_legacy)
+        {
+            embedDir = new File(m_rootDir, LEGACY_EMBEDDED_DIRECTORY);
+        }
+        else
+        {
+            embedDir = new File(m_rootDir, m_file.getName() + EMBEDDED_DIRECTORY);
+        }
+        File jarFile = new File(embedDir, jarPath);
+
+        if (!BundleCache.getSecureAction().fileExists(jarFile))
+        {
+            InputStream is = null;
+            try
+            {
+                // Make sure class path entry is a JAR file.
+                ZipEntry ze = m_jarFile.getEntry(jarPath);
+                if (ze == null)
+                {
+                    return;
+                }
+                // If the zip entry is a directory, then ignore it since
+                // we don't need to extact it; otherwise, it points to an
+                // embedded JAR file, so extract it.
+                else if (!ze.isDirectory())
+                {
+                    // Make sure that the embedded JAR's parent directory exists;
+                    // it may be in a sub-directory.
+                    File jarDir = jarFile.getParentFile();
+                    if (!BundleCache.getSecureAction().fileExists(jarDir))
+                    {
+                        if (!BundleCache.getSecureAction().mkdirs(jarDir))
+                        {
+                            throw new IOException("Unable to create embedded JAR directory.");
+                        }
+                    }
+
+                    // Extract embedded JAR into its directory.
+                    is = new BufferedInputStream(m_jarFile.getInputStream(ze), BundleCache.BUFSIZE);
+                    if (is == null)
+                    {
+                        throw new IOException("No input stream: " + jarPath);
+                    }
+                    // Copy the file.
+                    BundleCache.copyStreamToFile(is, jarFile);
+                }
+            }
+            finally
+            {
+                if (is != null) is.close();
+            }
+        }
+    }
+
+    private static class EntriesEnumeration implements Enumeration
+    {
+        private Enumeration m_enumeration = null;
+
+        public EntriesEnumeration(Enumeration enumeration)
+        {
+            m_enumeration = enumeration;
+        }
+
+        public boolean hasMoreElements()
+        {
+            return m_enumeration.hasMoreElements();
+        }
+
+        public Object nextElement()
+        {
+            return ((ZipEntry) m_enumeration.nextElement()).getName();
+        }
+    }
+}
\ No newline at end of file

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/JarContent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/JarContent.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/JarRevision.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/JarRevision.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/JarRevision.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/JarRevision.java Mon Sep  1 08:08:01 2008
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.cache;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Map;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import org.apache.felix.framework.Logger;
+import org.apache.felix.framework.util.StringMap;
+import org.apache.felix.framework.util.Util;
+import org.apache.felix.moduleloader.IContent;
+
+/**
+ * <p>
+ * This class implements a bundle archive revision for a standard bundle
+ * JAR file. The specified location is the URL of the JAR file. By default,
+ * the associated JAR file is copied into the revision's directory on the
+ * file system, but it is possible to mark the JAR as 'by reference', which
+ * will result in the bundle JAR be used 'in place' and not being copied. In
+ * either case, some of the contents may be extracted into the revision
+ * directory, such as embedded JAR files and native libraries.
+ * </p>
+**/
+class JarRevision extends BundleRevision
+{
+    private static final transient String BUNDLE_JAR_FILE = "bundle.jar";
+
+    private File m_bundleFile = null;
+    private Map m_header = null;
+
+    public JarRevision(
+        Logger logger, File revisionRootDir, String location, boolean byReference)
+        throws Exception
+    {
+        this(logger, revisionRootDir, location, byReference, null);
+    }
+
+    public JarRevision(
+        Logger logger, File revisionRootDir, String location,
+        boolean byReference, InputStream is)
+        throws Exception
+    {
+        super(logger, revisionRootDir, location);
+
+        if (byReference)
+        {
+            m_bundleFile = new File(location.substring(
+                location.indexOf(BundleArchive.FILE_PROTOCOL)
+                    + BundleArchive.FILE_PROTOCOL.length()));
+        }
+        else
+        {
+            m_bundleFile = new File(getRevisionRootDir(), BUNDLE_JAR_FILE);
+        }
+
+        // Save and process the bundle JAR.
+        initialize(byReference, is);
+    }
+
+    public synchronized Map getManifestHeader() throws Exception
+    {
+        if (m_header != null)
+        {
+            return m_header;
+        }
+
+        // Get the embedded resource.
+        JarFile jarFile = null;
+
+        try
+        {
+            // Open bundle JAR file.
+            jarFile = BundleCache.getSecureAction().openJAR(m_bundleFile);
+            // Error if no jar file.
+            if (jarFile == null)
+            {
+                throw new IOException("No JAR file found.");
+            }
+            // Get manifest.
+            Manifest mf = jarFile.getManifest();
+            // Create a case insensitive map of manifest attributes.
+            m_header = new StringMap(mf.getMainAttributes(), false);
+            return m_header;
+
+        }
+        finally
+        {
+            if (jarFile != null) jarFile.close();
+        }
+    }
+
+    public synchronized IContent getContent() throws Exception
+    {
+        return new JarContent(getLogger(), this, getRevisionRootDir(), m_bundleFile, true);
+    }
+
+    public void dispose() throws Exception
+    {
+        // Nothing to dispose of, since we don't maintain any state outside
+        // of the revision directory, which will be automatically deleted
+        // by the parent bundle archive.
+    }
+
+    //
+    // Private methods.
+    //
+
+    private void initialize(boolean byReference, InputStream is)
+        throws Exception
+    {
+        try
+        {
+            // If the revision directory exists, then we don't
+            // need to initialize since it has already been done.
+            if (BundleCache.getSecureAction().fileExists(getRevisionRootDir()))
+            {
+                return;
+            }
+
+            // Create revision directory.
+            if (!BundleCache.getSecureAction().mkdir(getRevisionRootDir()))
+            {
+                getLogger().log(
+                    Logger.LOG_ERROR,
+                    getClass().getName() + ": Unable to create revision directory.");
+                throw new IOException("Unable to create archive directory.");
+            }
+
+            if (!byReference)
+            {
+                if (is == null)
+                {
+                    // Do it the manual way to have a chance to
+                    // set request properties such as proxy auth.
+                    URL url = new URL(getLocation());
+                    URLConnection conn = url.openConnection();
+
+                    // Support for http proxy authentication.
+                    String auth = BundleCache.getSecureAction()
+                        .getSystemProperty("http.proxyAuth", null);
+                    if ((auth != null) && (auth.length() > 0))
+                    {
+                        if ("http".equals(url.getProtocol()) ||
+                            "https".equals(url.getProtocol()))
+                        {
+                            String base64 = Util.base64Encode(auth);
+                            conn.setRequestProperty(
+                                "Proxy-Authorization", "Basic " + base64);
+                        }
+                    }
+                    is = BundleCache.getSecureAction().getURLConnectionInputStream(conn);
+                }
+
+                // Save the bundle jar file.
+                BundleCache.copyStreamToFile(is, m_bundleFile);
+            }
+        }
+        finally
+        {
+            if (is != null) is.close();
+        }
+    }
+}
\ No newline at end of file

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/JarRevision.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/cache/JarRevision.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ext/FelixBundleContext.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ext/FelixBundleContext.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ext/FelixBundleContext.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ext/FelixBundleContext.java Mon Sep  1 08:08:01 2008
@@ -0,0 +1,30 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.ext;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+
+public interface FelixBundleContext extends BundleContext
+{
+    public void addRequirement(String s) throws BundleException;
+    public void removeRequirement() throws BundleException;
+    public void addCapability() throws BundleException;
+    public void removeCapability() throws BundleException;
+}
\ No newline at end of file

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ext/FelixBundleContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ext/FelixBundleContext.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ext/SecurityProvider.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ext/SecurityProvider.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ext/SecurityProvider.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ext/SecurityProvider.java Mon Sep  1 08:08:01 2008
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.ext;
+
+import java.security.Permission;
+import java.security.ProtectionDomain;
+
+import org.osgi.framework.Bundle;
+
+public interface SecurityProvider
+{
+    boolean hasBundlePermission(ProtectionDomain pd, Permission p, boolean direct);
+
+    Object getSignerMatcher(Bundle bundle);
+    
+    void checkBundle(Bundle bundle) throws Exception;
+}

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ext/SecurityProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ext/SecurityProvider.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentClassLoader.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentClassLoader.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentClassLoader.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentClassLoader.java Mon Sep  1 08:08:01 2008
@@ -0,0 +1,326 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.searchpolicy;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.security.SecureClassLoader;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.felix.framework.util.Util;
+import org.apache.felix.moduleloader.IContent;
+import org.apache.felix.moduleloader.IContentLoader;
+import org.apache.felix.framework.cache.JarContent;
+import org.apache.felix.moduleloader.ResourceNotFoundException;
+
+public class ContentClassLoader extends SecureClassLoader
+{
+    private static final Constructor m_dexFileClassConstructor;
+    private static final Method m_dexFileClassLoadClass;
+    static
+    {
+        Constructor dexFileClassConstructor = null;
+        Method dexFileClassLoadClass = null;
+        try
+        {
+            Class dexFileClass =  Class.forName("android.dalvik.DexFile");
+            dexFileClassConstructor = dexFileClass.getConstructor(
+                new Class[] { java.io.File.class });
+            dexFileClassLoadClass = dexFileClass.getMethod("loadClass",
+                new Class[] { String.class, ClassLoader.class });
+        }
+        catch (Exception ex)
+        {
+           dexFileClassConstructor = null;
+           dexFileClassLoadClass = null;
+        }
+        m_dexFileClassConstructor = dexFileClassConstructor;
+        m_dexFileClassLoadClass = dexFileClassLoadClass;
+    }
+
+    private ContentLoaderImpl m_contentLoader = null;
+    private ProtectionDomain m_protectionDomain = null;
+    private Map m_jarContentToDexFile = null;
+
+    public ContentClassLoader(ContentLoaderImpl contentLoader,
+        ProtectionDomain protectionDomain)
+    {
+        m_contentLoader = contentLoader;
+        m_protectionDomain = protectionDomain;
+        if (m_dexFileClassConstructor != null)
+        {
+            m_jarContentToDexFile = new HashMap();
+        }
+    }
+
+    public IContentLoader getContentLoader()
+    {
+        return m_contentLoader;
+    }
+
+    protected Class loadClassFromModule(String name)
+        throws ClassNotFoundException
+    {
+        // Ask the search policy for the clas before consulting the module.
+        Class clazz = findClass(name);
+
+        // If not found, then throw an exception.
+        if (clazz == null)
+        {
+            throw new ClassNotFoundException(name);
+        }
+        return clazz;
+    }
+
+    protected Class loadClass(String name, boolean resolve)
+        throws ClassNotFoundException
+    {
+        Class clazz = null;
+
+        // Make sure the class was not already loaded.
+        synchronized (this)
+        {
+            clazz = findLoadedClass(name);
+        }
+
+        if (clazz == null)
+        {
+            // Ask the search policy for the class.
+            clazz = m_contentLoader.getSearchPolicy().findClass(name);
+        }
+
+        // If still not found, then throw an exception.
+        if (clazz == null)
+        {
+            throw new ClassNotFoundException(name);
+        }
+        // Otherwise resolve the class.
+        if (resolve)
+        {
+            resolveClass(clazz);
+        }
+        return clazz;
+    }
+
+    protected Class findClass(String name) throws ClassNotFoundException
+    {
+        // Do a quick check here to see if we can short-circuit this
+        // entire process if the class was already loaded.
+        Class clazz = null;
+        synchronized (this)
+        {
+            clazz = findLoadedClass(name);
+        }
+
+        // Search for class in module.
+        if (clazz == null)
+        {
+            String actual = name.replace('.', '/') + ".class";
+
+            byte[] bytes = null;
+
+            IContent content = null;
+            // Check the module class path.
+            for (int i = 0;
+                (bytes == null) &&
+                (i < m_contentLoader.getClassPath().length); i++)
+            {
+                bytes = m_contentLoader.getClassPath()[i].getEntryAsBytes(actual);
+                content = m_contentLoader.getClassPath()[i];
+            }
+
+            if (bytes != null)
+            {
+                // Before we actually attempt to define the class, grab
+                // the lock for this class loader and make sure than no
+                // other thread has defined this class in the meantime.
+                synchronized (this)
+                {
+                    clazz = findLoadedClass(name);
+
+                    if (clazz == null)
+                    {
+                        // We need to try to define a Package object for the class
+                        // before we call defineClass(). Get the package name and
+                        // see if we have already created the package.
+                        String pkgName = Util.getClassPackage(name);
+                        if (pkgName.length() > 0)
+                        {
+                            if (getPackage(pkgName) == null)
+                            {
+                                Object[] params =
+                                    m_contentLoader.getSearchPolicy()
+                                        .definePackage(pkgName);
+                                if (params != null)
+                                {
+                                    definePackage(
+                                        pkgName,
+                                        (String) params[0],
+                                        (String) params[1],
+                                        (String) params[2],
+                                        (String) params[3],
+                                        (String) params[4],
+                                        (String) params[5],
+                                        null);
+                                }
+                                else
+                                {
+                                    definePackage(pkgName, null, null,
+                                        null, null, null, null, null);
+                                }
+                            }
+                        }
+
+                        // If we can load the class from a dex file do so
+                        if (content instanceof JarContent)
+                        {
+                            try
+                            {
+                                clazz = getDexFileClass((JarContent) content, name, this);
+                            }
+                            catch (Exception ex)
+                            {
+                                // Looks like we can't
+                            }
+                        }
+
+                        if (clazz == null)
+                        {
+                            // If we have a security context, then use it to
+                            // define the class with it for security purposes,
+                            // otherwise define the class without a protection domain.
+                            if (m_protectionDomain != null)
+                            {
+                                clazz = defineClass(name, bytes, 0, bytes.length,
+                                    m_protectionDomain);
+                            }
+                            else
+                            {
+                                clazz = defineClass(name, bytes, 0, bytes.length);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return clazz;
+    }
+
+    private Class getDexFileClass(JarContent content, String name, ClassLoader loader)
+        throws Exception
+    {
+        if (m_jarContentToDexFile == null)
+        {
+            return null;
+        }
+
+        Object dexFile = null;
+
+        if (!m_jarContentToDexFile.containsKey(content))
+        {
+            try
+            {
+                dexFile = m_dexFileClassConstructor.newInstance(
+                    new Object[] { content.getFile() });
+            }
+            finally
+            {
+                m_jarContentToDexFile.put(content, dexFile);
+            }
+        }
+        else
+        {
+            dexFile = m_jarContentToDexFile.get(content);
+        }
+
+        if (dexFile != null)
+        {
+            return (Class) m_dexFileClassLoadClass.invoke(dexFile,
+                new Object[] { name.replace('.','/'), loader });
+        }
+        return null;
+    }
+
+    public URL getResourceFromModule(String name)
+    {
+        try
+        {
+            return findResource(name);
+        }
+        catch (Throwable th)
+        {
+            // Ignore and just return null.
+        }
+        return null;
+    }
+
+    public URL getResource(String name)
+    {
+        // Ask the search policy for the class before consulting the module.
+        try
+        {
+            return m_contentLoader.getSearchPolicy().findResource(name);
+        }
+        catch (ResourceNotFoundException ex)
+        {
+        }
+        return null;
+    }
+
+    protected URL findResource(String name)
+    {
+        // Ask the search policy for the resource.
+        try
+        {
+            return m_contentLoader.getSearchPolicy().findResource(name);
+        }
+        catch (ResourceNotFoundException ex)
+        {
+        }
+        return null;
+    }
+
+    protected Enumeration findResources(String name)
+    {
+        // Ask the search policy for the resources.
+        try
+        {
+            return m_contentLoader.getSearchPolicy().findResources(name);
+        }
+        catch (ResourceNotFoundException ex)
+        {
+        }
+        return null;
+    }
+
+    protected String findLibrary(String name)
+    {
+        return m_contentLoader.getSearchPolicy().findLibrary(name);
+    }
+
+    public String toString()
+    {
+        return m_contentLoader.toString();
+    }
+}
\ No newline at end of file

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentClassLoader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentClassLoader.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java Mon Sep  1 08:08:01 2008
@@ -0,0 +1,362 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.searchpolicy;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import java.util.jar.Manifest;
+import org.apache.felix.framework.Logger;
+import org.apache.felix.framework.util.FelixConstants;
+import org.apache.felix.framework.util.SecureAction;
+import org.apache.felix.framework.util.StringMap;
+import org.apache.felix.framework.util.manifestparser.ManifestParser;
+import org.apache.felix.moduleloader.*;
+
+public class ContentLoaderImpl implements IContentLoader
+{
+    private Logger m_logger = null;
+    private IContent m_content = null;
+    private IContent[] m_contentPath = null;
+    private ISearchPolicy m_searchPolicy = null;
+    private IURLPolicy m_urlPolicy = null;
+    private ContentClassLoader m_classLoader = null;
+    private ProtectionDomain m_protectionDomain = null;
+    private static SecureAction m_secureAction = new SecureAction();
+
+    public ContentLoaderImpl(Logger logger, IContent content)
+    {
+        m_logger = logger;
+        m_content = content;
+    }
+
+    public Logger getLogger()
+    {
+        return m_logger;
+    }
+
+    public void open()
+    {
+        m_content.open();
+        try
+        {
+            initializeContentPath();
+        }
+        catch (Exception ex)
+        {
+            m_logger.log(Logger.LOG_ERROR, "Unable to initialize content path.", ex);
+        }
+
+        for (int i = 0; (m_contentPath != null) && (i < m_contentPath.length); i++)
+        {
+            m_contentPath[i].open();
+        }
+    }
+
+    public void close()
+    {
+        m_content.close();
+        for (int i = 0; (m_contentPath != null) && (i < m_contentPath.length); i++)
+        {
+            m_contentPath[i].close();
+        }
+    }
+
+    public IContent getContent()
+    {
+        return m_content;
+    }
+
+    public IContent[] getClassPath()
+    {
+        return m_contentPath;
+    }
+
+    public void setSearchPolicy(ISearchPolicy searchPolicy)
+    {
+        m_searchPolicy = searchPolicy;
+    }
+
+    public ISearchPolicy getSearchPolicy()
+    {
+        return m_searchPolicy;
+    }
+
+    public void setURLPolicy(IURLPolicy urlPolicy)
+    {
+        m_urlPolicy = urlPolicy;
+    }
+
+    public IURLPolicy getURLPolicy()
+    {
+        return m_urlPolicy;
+    }
+
+    public synchronized void setSecurityContext(Object securityContext)
+    {
+        m_protectionDomain = (ProtectionDomain) securityContext;
+    }
+
+    public synchronized Object getSecurityContext()
+    {
+        return m_protectionDomain;
+    }
+
+    public Class getClass(String name)
+    {
+        synchronized (this)
+        {
+            if (m_classLoader == null)
+            {
+                m_classLoader = m_secureAction.createContentClassLoader(this,
+                    m_protectionDomain);
+            }
+        }
+
+        try
+        {
+            return m_classLoader.loadClassFromModule(name);
+        }
+        catch (ClassNotFoundException ex)
+        {
+            return null;
+        }
+    }
+
+    public URL getResource(String name)
+    {
+        URL url = null;
+
+        // Remove leading slash, if present, but special case
+        // "/" so that it returns a root URL...this isn't very
+        // clean or meaninful, but the Spring guys want it.
+        if (name.equals("/"))
+        {
+            // Just pick a class path index since it doesn't really matter.
+            url = getURLPolicy().createURL(1, name);
+        }
+        else if (name.startsWith("/"))
+        {
+            name = name.substring(1);
+        }
+
+        // Check the module class path.
+        for (int i = 0;
+            (url == null) &&
+            (i < getClassPath().length); i++)
+        {
+            if (getClassPath()[i].hasEntry(name))
+            {
+                url = getURLPolicy().createURL(i + 1, name);
+            }
+        }
+
+        return url;
+    }
+
+    public Enumeration getResources(String name)
+    {
+        Vector v = new Vector();
+
+        // Special case "/" so that it returns a root URLs for
+        // each bundle class path entry...this isn't very
+        // clean or meaningful, but the Spring guys want it.
+        if (name.equals("/"))
+        {
+            for (int i = 0; i < getClassPath().length; i++)
+            {
+                v.addElement(getURLPolicy().createURL(i + 1, name));
+            }
+        }
+        else
+        {
+            // Remove leading slash, if present.
+            if (name.startsWith("/"))
+            {
+                name = name.substring(1);
+            }
+
+            // Check the module class path.
+            for (int i = 0; i < getClassPath().length; i++)
+            {
+                if (getClassPath()[i].hasEntry(name))
+                {
+                    // Use the class path index + 1 for creating the path so
+                    // that we can differentiate between module content URLs
+                    // (where the path will start with 0) and module class
+                    // path URLs.
+                    v.addElement(getURLPolicy().createURL(i + 1, name));
+                }
+            }
+        }
+
+        return v.elements();
+    }
+
+    // TODO: API: Investigate how to handle this better, perhaps we need
+    // multiple URL policies, one for content -- one for class path.
+    public URL getResourceFromContent(String name)
+    {
+        URL url = null;
+
+        // Check for the special case of "/", which represents
+        // the root of the bundle according to the spec.
+        if (name.equals("/"))
+        {
+            url = getURLPolicy().createURL(0, "/");
+        }
+
+        if (url == null)
+        {
+            // Remove leading slash, if present.
+            if (name.startsWith("/"))
+            {
+                name = name.substring(1);
+            }
+
+            // Check the module content.
+            if (getContent().hasEntry(name))
+            {
+                // Module content URLs start with 0, whereas module
+                // class path URLs start with the index into the class
+                // path + 1.
+                url = getURLPolicy().createURL(0, name);
+            }
+        }
+
+        return url;
+    }
+
+    public boolean hasInputStream(int index, String urlPath)
+    {
+        if (urlPath.startsWith("/"))
+        {
+            urlPath = urlPath.substring(1);
+        }
+        if (index == 0)
+        {
+            return m_content.hasEntry(urlPath);
+        }
+        return m_contentPath[index - 1].hasEntry(urlPath);
+    }
+
+    public InputStream getInputStream(int index, String urlPath)
+        throws IOException
+    {
+        if (urlPath.startsWith("/"))
+        {
+            urlPath = urlPath.substring(1);
+        }
+        if (index == 0)
+        {
+            return m_content.getEntryAsStream(urlPath);
+        }
+        return m_contentPath[index - 1].getEntryAsStream(urlPath);
+    }
+
+    public String toString()
+    {
+        return m_searchPolicy.toString();
+    }
+
+    private void initializeContentPath() throws Exception
+    {
+        // Creating the content path entails examining the bundle's
+        // class path to determine whether the bundle JAR file itself
+        // is on the bundle's class path and then creating content
+        // objects for everything on the class path.
+
+        // Get the bundle's manifest header.
+        InputStream is = null;
+        Map headers = null;
+        try
+        {
+            is = m_content.getEntryAsStream("META-INF/MANIFEST.MF");
+            headers = new StringMap(new Manifest(is).getMainAttributes(), false);
+        }
+        finally
+        {
+            if (is != null) is.close();
+        }
+
+        // Find class path meta-data.
+        String classPath = (headers == null)
+            ? null : (String) headers.get(FelixConstants.BUNDLE_CLASSPATH);
+
+        // Parse the class path into strings.
+        String[] classPathStrings = ManifestParser.parseDelimitedString(
+            classPath, FelixConstants.CLASS_PATH_SEPARATOR);
+
+        if (classPathStrings == null)
+        {
+            classPathStrings = new String[0];
+        }
+
+        // Create the bundles class path.
+        List contentList = new ArrayList();
+        for (int i = 0; i < classPathStrings.length; i++)
+        {
+            // Remove any leading slash, since all bundle class path
+            // entries are relative to the root of the bundle.
+            classPathStrings[i] = (classPathStrings[i].startsWith("/"))
+                ? classPathStrings[i].substring(1)
+                : classPathStrings[i];
+
+            // Check for the bundle itself on the class path.
+            if (classPathStrings[i].equals(FelixConstants.CLASS_PATH_DOT))
+            {
+                contentList.add(m_content);
+            }
+            else
+            {
+                // Determine if the class path entry is a file or directory
+                // in the bundle JAR file.
+                IContent content = m_content.getEntryAsContent(classPathStrings[i]);
+                if (content != null)
+                {
+                    contentList.add(content);
+                }
+                else
+                {
+// TODO: FRAMEWORK - Per the spec, this should fire a FrameworkEvent.INFO event;
+//       need to create an "Eventer" class like "Logger" perhaps.
+                    m_logger.log(Logger.LOG_INFO,
+                        "Class path entry not found: "
+                        + classPathStrings[i]);
+                }
+            }
+        }
+
+        // If there is nothing on the class path, then include
+        // "." by default, as per the spec.
+        if (contentList.size() == 0)
+        {
+            contentList.add(m_content);
+        }
+
+        m_contentPath = (IContent[]) contentList.toArray(new IContent[contentList.size()]);
+    }
+}
\ No newline at end of file

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/searchpolicy/ModuleDefinition.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/searchpolicy/ModuleDefinition.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/searchpolicy/ModuleDefinition.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/searchpolicy/ModuleDefinition.java Mon Sep  1 08:08:01 2008
@@ -0,0 +1,68 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.searchpolicy;
+
+import org.apache.felix.framework.util.manifestparser.R4Library;
+import org.apache.felix.moduleloader.*;
+
+public class ModuleDefinition implements IModuleDefinition
+{
+    public ICapability[] m_capabilities = null;
+    public IRequirement[] m_requirements = null;
+    public IRequirement[] m_dynamicRequirements = null;
+    private R4Library[] m_libraries = null;
+
+    public ModuleDefinition(
+        ICapability[] capabilities, IRequirement[] requirements,
+        IRequirement[] dynamicRequirements, R4Library[] libraries)
+    {
+        m_capabilities = capabilities;
+        m_requirements = requirements;
+        m_dynamicRequirements = dynamicRequirements;
+        m_libraries = libraries;
+    }
+
+    public ICapability[] getCapabilities()
+    {
+// TODO: RB - These should probably all return copies of the array.
+        return m_capabilities;
+    }
+
+    public IRequirement[] getRequirements()
+    {
+        return m_requirements;
+    }
+
+    public IRequirement[] getDynamicRequirements()
+    {
+        return m_dynamicRequirements;
+    }
+
+    // TODO: EXPERIMENTAL - Experimental implicit wire concept to try
+    //       to deal with code generation.
+    public void setDynamicRequirements(IRequirement[] reqs)
+    {
+        m_dynamicRequirements = reqs;
+    }
+
+    public R4Library[] getLibraries()
+    {
+        return m_libraries;
+    }
+}
\ No newline at end of file

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/searchpolicy/ModuleDefinition.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/searchpolicy/ModuleDefinition.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date