You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2005/08/16 20:34:41 UTC

svn commit: r233031 [10/21] - in /incubator/oscar/trunk: ./ etc/ lib/ src/ src/org/ src/org/apache/ src/org/apache/osgi/ src/org/apache/osgi/bundle/ src/org/apache/osgi/bundle/bundlerepository/ src/org/apache/osgi/bundle/bundlerepository/kxmlsax/ src/o...

Added: incubator/oscar/trunk/src/org/apache/osgi/framework/installer/property/StringPropertyImpl.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/framework/installer/property/StringPropertyImpl.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/framework/installer/property/StringPropertyImpl.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/framework/installer/property/StringPropertyImpl.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,69 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   Licensed 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.osgi.framework.installer.property;
+
+import javax.swing.JComponent;
+
+import org.apache.osgi.framework.installer.StringProperty;
+import org.apache.osgi.framework.installer.editor.StringEditor;
+
+public class StringPropertyImpl implements StringProperty
+{
+    private String m_name = null;
+    private String m_value = "";
+    private JComponent m_editor = null;
+
+    public StringPropertyImpl(String name, String value)
+    {
+        m_name = name;
+        m_value = value;
+    }
+
+    public String getName()
+    {
+        return m_name;
+    }
+
+    public String getStringValue()
+    {
+        return m_value;
+    }
+
+    public void setStringValue(String s)
+    {
+        m_value = s;
+    }
+
+    public JComponent getEditor()
+    {
+        if (m_editor == null)
+        {
+            m_editor = new StringEditor(this);
+        }
+        return m_editor;
+    }
+
+    public void setEditor(JComponent comp)
+    {
+        m_editor = comp;
+    }
+
+    public String toString()
+    {
+        return m_value;
+    }
+}
\ No newline at end of file

Added: incubator/oscar/trunk/src/org/apache/osgi/framework/installer/resource/ResourceLoader.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/framework/installer/resource/ResourceLoader.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/framework/installer/resource/ResourceLoader.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/framework/installer/resource/ResourceLoader.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,33 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   Licensed 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.osgi.framework.installer.resource;
+
+import java.io.InputStream;
+import java.net.URL;
+
+public class ResourceLoader
+{
+    public static URL getResource(String name)
+    {
+        return ResourceLoader.class.getResource(name);
+    }
+
+    public static InputStream getResourceAsStream(String name)
+    {
+        return ResourceLoader.class.getResourceAsStream(name);
+    }
+}
\ No newline at end of file

Added: incubator/oscar/trunk/src/org/apache/osgi/framework/manifest.mf
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/framework/manifest.mf?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/framework/manifest.mf (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/framework/manifest.mf Tue Aug 16 11:33:34 2005
@@ -0,0 +1,2 @@
+Main-Class: org.apache.osgi.framework.Main
+Class-Path: osgi.jar moduleloader.jar

Added: incubator/oscar/trunk/src/org/apache/osgi/framework/searchpolicy/R4Attribute.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/framework/searchpolicy/R4Attribute.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/framework/searchpolicy/R4Attribute.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/framework/searchpolicy/R4Attribute.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,46 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   Licensed 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.osgi.framework.searchpolicy;
+
+public class R4Attribute
+{
+    private String m_name = "";
+    private String m_value = "";
+    private boolean m_isMandatory = false;
+    
+    public R4Attribute(String name, String value, boolean isMandatory)
+    {
+        m_name = name;
+        m_value = value;
+        m_isMandatory = isMandatory;
+    }
+
+    public String getName()
+    {
+        return m_name;
+    }
+
+    public String getValue()
+    {
+        return m_value;
+    }
+
+    public boolean isMandatory()
+    {
+        return m_isMandatory;
+    }
+}
\ No newline at end of file

Added: incubator/oscar/trunk/src/org/apache/osgi/framework/searchpolicy/R4Directive.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/framework/searchpolicy/R4Directive.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/framework/searchpolicy/R4Directive.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/framework/searchpolicy/R4Directive.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,39 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   Licensed 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.osgi.framework.searchpolicy;
+
+public class R4Directive
+{
+    private String m_name = "";
+    private String m_value = "";
+    
+    public R4Directive(String name, String value)
+    {
+        m_name = name;
+        m_value = value;
+    }
+
+    public String getName()
+    {
+        return m_name;
+    }
+
+    public String getValue()
+    {
+        return m_value;
+    }
+}
\ No newline at end of file

Added: incubator/oscar/trunk/src/org/apache/osgi/framework/searchpolicy/R4Package.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/framework/searchpolicy/R4Package.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/framework/searchpolicy/R4Package.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/framework/searchpolicy/R4Package.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,634 @@
+/*
+ *   Copyright 2005 The Apache Software Foundation
+ *
+ *   Licensed 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.osgi.framework.searchpolicy;
+
+import java.util.*;
+
+import org.apache.osgi.framework.util.FelixConstants;
+import org.apache.osgi.framework.util.Util;
+
+public class R4Package
+{
+    private String m_id = "";
+    private R4Directive[] m_directives = null;
+    private R4Attribute[] m_attrs = null;
+    private R4Version m_versionLow = null;
+    private R4Version m_versionHigh = null;
+    private String[] m_uses = null;
+    private boolean m_isOptional = false;
+    private String[][] m_includeFilter = null;
+    private String[][] m_excludeFilter = null;
+
+    protected R4Package(R4Package pkg)
+    {
+        m_id = pkg.m_id;
+        m_directives = pkg.m_directives;
+        m_attrs = pkg.m_attrs;
+        m_versionLow = pkg.m_versionLow;
+        m_versionHigh = pkg.m_versionHigh;
+        m_uses = pkg.m_uses;
+        m_isOptional = pkg.m_isOptional;
+        m_includeFilter = pkg.m_includeFilter;
+        m_excludeFilter = pkg.m_excludeFilter;
+    }
+
+    public R4Package(String id, R4Directive[] directives, R4Attribute[] attrs)
+    {
+        m_id = id;
+        m_directives = (directives == null) ? new R4Directive[0] : directives;
+        m_attrs = (attrs == null) ? new R4Attribute[0] : attrs;
+
+        // Find all directives: uses, mandatory, resolution, include, and exclude.
+        String mandatory = "", uses = "";
+        for (int i = 0; i < m_directives.length; i++)
+        {
+            if (m_directives[i].getName().equals(FelixConstants.USES_DIRECTIVE))
+            {
+                uses = m_directives[i].getValue();
+            }
+            else if (m_directives[i].getName().equals(FelixConstants.MANDATORY_DIRECTIVE))
+            {
+                mandatory = m_directives[i].getValue();
+            }
+            else if (m_directives[i].getName().equals(FelixConstants.RESOLUTION_DIRECTIVE))
+            {
+                m_isOptional = m_directives[i].getValue().equals(FelixConstants.RESOLUTION_OPTIONAL);
+            }
+            else if (m_directives[i].getName().equals(FelixConstants.INCLUDE_DIRECTIVE))
+            {
+                String[] ss = Util.parseDelimitedString(m_directives[i].getValue(), ",");
+                m_includeFilter = new String[ss.length][];
+                for (int filterIdx = 0; filterIdx < ss.length; filterIdx++)
+                {
+                    m_includeFilter[filterIdx] = parseSubstring(ss[filterIdx]);
+                }
+            }
+            else if (m_directives[i].getName().equals(FelixConstants.EXCLUDE_DIRECTIVE))
+            {
+                String[] ss = Util.parseDelimitedString(m_directives[i].getValue(), ",");
+                m_excludeFilter = new String[ss.length][];
+                for (int filterIdx = 0; filterIdx < ss.length; filterIdx++)
+                {
+                    m_excludeFilter[filterIdx] = parseSubstring(ss[filterIdx]);
+                }
+            }
+        }
+
+        // Parse these uses directive.
+        StringTokenizer tok = new StringTokenizer(uses, ",");
+        m_uses = new String[tok.countTokens()];
+        for (int i = 0; i < m_uses.length; i++)
+        {
+            m_uses[i] = tok.nextToken().trim();
+        }
+
+        // Parse mandatory directive and mark specified
+        // attributes as mandatory.
+        tok = new StringTokenizer(mandatory, ",");
+        while (tok.hasMoreTokens())
+        {
+            // Get attribute name.
+            String attrName = tok.nextToken().trim();
+            // Find attribute and mark it as mandatory.
+            boolean found = false;
+            for (int i = 0; (!found) && (i < m_attrs.length); i++)
+            {
+                if (m_attrs[i].getName().equals(attrName))
+                {
+                    m_attrs[i] = new R4Attribute(
+                        m_attrs[i].getName(), m_attrs[i].getValue(), true);
+                    found = true;
+                }
+            }
+            // If a specified mandatory attribute was not found,
+            // then error.
+            if (!found)
+            {
+                throw new IllegalArgumentException(
+                    "Mandatory attribute '" + attrName + "' does not exist.");
+            }
+        }
+
+        // Find and parse version attribute, if present.
+        String versionInterval = "0.0.0";
+        for (int i = 0; i < m_attrs.length; i++)
+        {
+            if (m_attrs[i].getName().equals(FelixConstants.VERSION_ATTRIBUTE) ||
+                m_attrs[i].getName().equals(FelixConstants.PACKAGE_SPECIFICATION_VERSION))
+            {
+                // Normalize version attribute name.
+                m_attrs[i] = new R4Attribute(
+                    FelixConstants.VERSION_ATTRIBUTE, m_attrs[i].getValue(),
+                    m_attrs[i].isMandatory());
+                versionInterval = m_attrs[i].getValue();
+                break;
+            }
+        }
+        
+        R4Version[] versions = parseVersionInterval(versionInterval);
+        m_versionLow = versions[0];
+        if (versions.length == 2)
+        {
+            m_versionHigh = versions[1];
+        }
+    }
+
+    public String getId()
+    {
+        return m_id;
+    }
+
+    public R4Directive[] getDirectives()
+    {
+        return m_directives;
+    }
+
+    public R4Attribute[] getAttributes()
+    {
+        return m_attrs;
+    }
+
+    public R4Version getVersionLow()
+    {
+        return m_versionLow;
+    }
+
+    public R4Version getVersionHigh()
+    {
+        return m_versionHigh;
+    }
+
+    public String[] getUses()
+    {
+        return m_uses;
+    }
+
+    public boolean isOptional()
+    {
+        return m_isOptional;
+    }
+
+    public boolean isIncluded(String name)
+    {
+        if ((m_includeFilter == null) && (m_excludeFilter == null))
+        {
+            return true;
+        }
+
+        // Get the class name portion of the target class.
+        String className = org.apache.osgi.moduleloader.Util.getClassName(name);
+
+        // If there are no include filters then all classes are included
+        // by default, otherwise try to find one match.
+        boolean included = (m_includeFilter == null);
+        for (int i = 0;
+            (!included) && (m_includeFilter != null) && (i < m_includeFilter.length);
+            i++)
+        {
+            included = checkSubstring(m_includeFilter[i], className);
+        }
+
+        // If there are no exclude filters then no classes are excluded
+        // by default, otherwise try to find one match.
+        boolean excluded = false;
+        for (int i = 0;
+            (!excluded) && (m_excludeFilter != null) && (i < m_excludeFilter.length);
+            i++)
+        {
+            excluded = checkSubstring(m_excludeFilter[i], className);
+        }
+        return included && !excluded;
+    }
+
+    // PREVIOUSLY PART OF COMPATIBILITY POLICY.
+    public boolean doesSatisfy(R4Package pkg)
+    {
+        // For packages to be compatible, they must have the
+        // same name.
+        if (!m_id.equals(pkg.m_id))
+        {
+            return false;
+        }
+        
+        return isVersionInRange(m_versionLow, pkg.m_versionLow, pkg.m_versionHigh)
+            && doAttributesMatch(pkg);
+    }
+
+    // PREVIOUSLY PART OF COMPATIBILITY POLICY.
+    public static boolean isVersionInRange(R4Version version, R4Version low, R4Version high)
+    {
+        // We might not have an upper end to the range.
+        if (high == null)
+        {
+            return (version.compareTo(low) >= 0);
+        }
+        else if (low.isInclusive() && high.isInclusive())
+        {
+            return (version.compareTo(low) >= 0) && (version.compareTo(high) <= 0);
+        }
+        else if (high.isInclusive())
+        {
+            return (version.compareTo(low) > 0) && (version.compareTo(high) <= 0);
+        }
+        else if (low.isInclusive())
+        {
+            return (version.compareTo(low) >= 0) && (version.compareTo(high) < 0);
+        }
+
+        return (version.compareTo(low) > 0) && (version.compareTo(high) < 0);
+    }
+
+    private boolean doAttributesMatch(R4Package pkg)
+    {
+        // Cycle through all attributes of the specified package
+        // and make sure their values match the attribute values
+        // of this package.
+        for (int attrIdx = 0; attrIdx < pkg.m_attrs.length; attrIdx++)
+        {
+            // Get current attribute from specified package.
+            R4Attribute attr = pkg.m_attrs[attrIdx];
+
+            // Ignore version attribute, since it is a special case that
+            // has already been compared using isVersionInRange() before
+            // the call to this method was made.
+            if (attr.getName().equals(FelixConstants.VERSION_ATTRIBUTE))
+            {
+                continue;
+            }
+
+            // Check if this package has the same attribute.
+            boolean found = false;
+            for (int thisAttrIdx = 0;
+                (!found) && (thisAttrIdx < m_attrs.length);
+                thisAttrIdx++)
+            {
+                // Get current attribute for this package.
+                R4Attribute thisAttr = m_attrs[thisAttrIdx];
+                // Check if the attribute names are equal.
+                if (attr.getName().equals(thisAttr.getName()))
+                {
+                    // If the values are not equal, then return false immediately.
+                    // We should not compare version values here, since they are
+                    // a special case and have already been compared by a call to
+                    // isVersionInRange() before getting here; however, it is
+                    // possible for version to be mandatory, so make sure it is
+                    // present below.
+                    if (!attr.getValue().equals(thisAttr.getValue()))
+                    {
+                        return false;
+                    }
+                    found = true;
+                }
+            }
+            // If the attribute was not found, then return false.
+            if (!found)
+            {
+                return false;
+            }
+        }
+
+        // Now, cycle through all attributes of this package and verify that
+        // all mandatory attributes are present in the speceified package.
+        for (int thisAttrIdx = 0; thisAttrIdx < m_attrs.length; thisAttrIdx++)
+        {
+            // Get current attribute for this package.
+            R4Attribute thisAttr = m_attrs[thisAttrIdx];
+            
+            // If the attribute is mandatory, then make sure
+            // the specified package has the attribute.
+            if (thisAttr.isMandatory())
+            {
+                boolean found = false;
+                for (int attrIdx = 0;
+                    (!found) && (attrIdx < pkg.m_attrs.length);
+                    attrIdx++)
+                {
+                    // Get current attribute from specified package.
+                    R4Attribute attr = pkg.m_attrs[attrIdx];
+        
+                    // Check if the attribute names are equal
+                    // and set found flag.
+                    if (thisAttr.getName().equals(attr.getName()))
+                    {
+                        found = true;
+                    }
+                }
+                // If not found, then return false.
+                if (!found)
+                {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    public String toString()
+    {
+        String msg = getId();
+        for (int i = 0; (m_directives != null) && (i < m_directives.length); i++)
+        {
+            msg = msg + " [" + m_directives[i].getName() + ":="+ m_directives[i].getValue() + "]";
+        }
+        for (int i = 0; (m_attrs != null) && (i < m_attrs.length); i++)
+        {
+            msg = msg + " [" + m_attrs[i].getName() + "="+ m_attrs[i].getValue() + "]";
+        }
+        return msg;
+    }
+
+    // Like this: pkg1; pkg2; dir1:=dirval1; dir2:=dirval2; attr1=attrval1; attr2=attrval2,
+    //            pkg1; pkg2; dir1:=dirval1; dir2:=dirval2; attr1=attrval1; attr2=attrval2
+    public static R4Package[] parseImportOrExportHeader(String s)
+    {
+        R4Package[] pkgs = null;
+        if (s != null)
+        {
+            if (s.length() == 0)
+            {
+                throw new IllegalArgumentException(
+                    "The import and export headers cannot be an empty string.");
+            }
+            String[] ss = Util.parseDelimitedString(
+                s, FelixConstants.CLASS_PATH_SEPARATOR);
+            pkgs = parsePackageStrings(ss);
+        }
+        return (pkgs == null) ? new R4Package[0] : pkgs;
+    }
+
+    // Like this: pkg1; pkg2; dir1:=dirval1; dir2:=dirval2; attr1=attrval1; attr2=attrval2
+    public static R4Package[] parsePackageStrings(String[] ss)
+        throws IllegalArgumentException
+    {
+        if (ss == null)
+        {
+            return null;
+        }
+
+        List completeList = new ArrayList();
+        for (int ssIdx = 0; ssIdx < ss.length; ssIdx++)
+        {
+            // Break string into semi-colon delimited pieces.
+            String[] pieces = Util.parseDelimitedString(
+                ss[ssIdx], FelixConstants.PACKAGE_SEPARATOR);
+
+            // Count the number of different packages; packages
+            // will not have an '=' in their string. This assumes
+            // that packages come first, before directives and
+            // attributes.
+            int pkgCount = 0;
+            for (int pieceIdx = 0; pieceIdx < pieces.length; pieceIdx++)
+            {
+                if (pieces[pieceIdx].indexOf('=') >= 0)
+                {
+                    break;
+                }
+                pkgCount++;
+            }
+
+            // Error if no packages were specified.
+            if (pkgCount == 0)
+            {
+                throw new IllegalArgumentException(
+                    "No packages specified on import: " + ss[ssIdx]);
+            }
+
+            // Parse the directives/attributes.
+            R4Directive[] dirs = new R4Directive[pieces.length - pkgCount];
+            R4Attribute[] attrs = new R4Attribute[pieces.length - pkgCount];
+            int dirCount = 0, attrCount = 0;
+            int idx = -1;
+            String sep = null;
+            for (int pieceIdx = pkgCount; pieceIdx < pieces.length; pieceIdx++)
+            {
+                // Check if it is a directive.
+                if ((idx = pieces[pieceIdx].indexOf(FelixConstants.DIRECTIVE_SEPARATOR)) >= 0)
+                {
+                    sep = FelixConstants.DIRECTIVE_SEPARATOR;
+                }
+                // Check if it is an attribute.
+                else if ((idx = pieces[pieceIdx].indexOf(FelixConstants.ATTRIBUTE_SEPARATOR)) >= 0)
+                {
+                    sep = FelixConstants.ATTRIBUTE_SEPARATOR;
+                }
+                // It is an error.
+                else
+                {
+                    throw new IllegalArgumentException(
+                        "Not a directive/attribute: " + ss[ssIdx]);
+                }
+
+                String key = pieces[pieceIdx].substring(0, idx).trim();
+                String value = pieces[pieceIdx].substring(idx + sep.length()).trim();
+
+                // Remove quotes, if value is quoted.
+                if (value.startsWith("\"") && value.endsWith("\""))
+                {
+                    value = value.substring(1, value.length() - 1);
+                }
+
+                // Save the directive/attribute in the appropriate array.
+                if (sep.equals(FelixConstants.DIRECTIVE_SEPARATOR))
+                {
+                    dirs[dirCount++] = new R4Directive(key, value);
+                }
+                else
+                {
+                    attrs[attrCount++] = new R4Attribute(key, value, false);
+                }
+            }
+
+            // Shrink directive array.
+            R4Directive[] dirsFinal = new R4Directive[dirCount];
+            System.arraycopy(dirs, 0, dirsFinal, 0, dirCount);
+            // Shrink attribute array.
+            R4Attribute[] attrsFinal = new R4Attribute[attrCount];
+            System.arraycopy(attrs, 0, attrsFinal, 0, attrCount);
+
+            // Create package attributes for each package and
+            // set directives/attributes. Add each package to
+            // completel list of packages.
+            R4Package[] pkgs = new R4Package[pkgCount];
+            for (int pkgIdx = 0; pkgIdx < pkgCount; pkgIdx++)
+            {
+                pkgs[pkgIdx] = new R4Package(pieces[pkgIdx], dirsFinal, attrsFinal);
+                completeList.add(pkgs[pkgIdx]);
+            }
+        }
+    
+        R4Package[] ips = (R4Package[])
+            completeList.toArray(new R4Package[completeList.size()]);
+        return ips;
+    }
+
+    public static R4Version[] parseVersionInterval(String interval)
+    {
+        // Check if the version is an interval.
+        if (interval.indexOf(',') >= 0)
+        {
+            String s = interval.substring(1, interval.length() - 1);
+            String vlo = s.substring(0, s.indexOf(','));
+            String vhi = s.substring(s.indexOf(',') + 1, s.length());
+            return new R4Version[] {
+                new R4Version(vlo, (interval.charAt(0) == '[')),
+                new R4Version(vhi, (interval.charAt(interval.length() - 1) == ']'))
+            };
+        }
+        else
+        {
+            return new R4Version[] { new R4Version(interval, true) };
+        }
+    }
+
+    //
+    // The following substring-related code was lifted and modified
+    // from the LDAP parser code.
+    //
+
+    private static String[] parseSubstring(String target)
+    {
+        List pieces = new ArrayList();
+        StringBuffer ss = new StringBuffer();
+        // int kind = SIMPLE; // assume until proven otherwise
+        boolean wasStar = false; // indicates last piece was a star
+        boolean leftstar = false; // track if the initial piece is a star
+        boolean rightstar = false; // track if the final piece is a star
+
+        int idx = 0;
+
+        // We assume (sub)strings can contain leading and trailing blanks
+loop:   for (;;)
+        {
+            if (idx >= target.length())
+            {
+                if (wasStar)
+                {
+                    // insert last piece as "" to handle trailing star
+                    rightstar = true;
+                }
+                else
+                {
+                    pieces.add(ss.toString());
+                    // accumulate the last piece
+                    // note that in the case of
+                    // (cn=); this might be
+                    // the string "" (!=null)
+                }
+                ss.setLength(0);
+                break loop;
+            }
+
+            char c = target.charAt(idx++);
+            if (c == '*')
+            {
+                if (wasStar)
+                {
+                    // encountered two successive stars;
+                    // I assume this is illegal
+                    throw new IllegalArgumentException("Invalid filter string: " + target);
+                }
+                if (ss.length() > 0)
+                {
+                    pieces.add(ss.toString()); // accumulate the pieces
+                    // between '*' occurrences
+                }
+                ss.setLength(0);
+                // if this is a leading star, then track it
+                if (pieces.size() == 0)
+                {
+                    leftstar = true;
+                }
+                ss.setLength(0);
+                wasStar = true;
+            }
+            else
+            {
+                wasStar = false;
+                ss.append(c);
+            }
+        }
+        if (leftstar || rightstar || pieces.size() > 1)
+        {
+            // insert leading and/or trailing "" to anchor ends
+            if (rightstar)
+            {
+                pieces.add("");
+            }
+            if (leftstar)
+            {
+                pieces.add(0, "");
+            }
+        }
+        return (String[]) pieces.toArray(new String[pieces.size()]);
+    }
+
+    private static boolean checkSubstring(String[] pieces, String s)
+    {
+        // Walk the pieces to match the string
+        // There are implicit stars between each piece,
+        // and the first and last pieces might be "" to anchor the match.
+        // assert (pieces.length > 1)
+        // minimal case is <string>*<string>
+
+        boolean result = false;
+        int len = pieces.length;
+
+loop:   for (int i = 0; i < len; i++)
+        {
+            String piece = (String) pieces[i];
+            int index = 0;
+            if (i == len - 1)
+            {
+                // this is the last piece
+                if (s.endsWith(piece))
+                {
+                    result = true;
+                }
+                else
+                {
+                    result = false;
+                }
+                break loop;
+            }
+            // initial non-star; assert index == 0
+            else if (i == 0)
+            {
+                if (!s.startsWith(piece))
+                {
+                    result = false;
+                    break loop;
+                }
+            }
+            // assert i > 0 && i < len-1
+            else
+            {
+                // Sure wish stringbuffer supported e.g. indexOf
+                index = s.indexOf(piece, index);
+                if (index < 0)
+                {
+                    result = false;
+                    break loop;
+                }
+            }
+            // start beyond the matching piece
+            index += piece.length();
+        }
+
+        return result;
+    }
+}
\ No newline at end of file

Propchange: incubator/oscar/trunk/src/org/apache/osgi/framework/searchpolicy/R4Package.java
------------------------------------------------------------------------------
    svn:executable = *