ant-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hi...@apache.org
Subject svn commit: r1036848 [2/8] - in /ant/ivy/core/trunk: example/ example/.settings/ example/java/ example/java/src/ example/java/src/com/ example/java/src/com/acme/ example/java/src/com/acme/speedy/ examples/ examples/eclipse-plugin/ examples/eclipse-plug...
Date Fri, 19 Nov 2010 14:06:12 GMT
Added: ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/BundleCapability.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/BundleCapability.java?rev=1036848&view=auto
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/BundleCapability.java (added)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/BundleCapability.java Fri Nov 19 14:06:06 2010
@@ -0,0 +1,95 @@
+/*
+ *  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.ivy.osgi.core;
+
+import org.apache.ivy.osgi.util.Version;
+
+public class BundleCapability {
+
+    private final String name;
+
+    private final Version version;
+
+    private final String type;
+
+    public BundleCapability(String type, String name, Version version) {
+        this.type = type;
+        this.name = name;
+        this.version = version;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Version getVersion() {
+        return version;
+    }
+
+    public Version getRawVersion() {
+        return version;
+    }
+
+    @Override
+    public String toString() {
+        return name + (version == null ? "" : ";" + version);
+    }
+ 
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        result = prime * result + ((version == null) ? 0 : version.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof BundleCapability)) {
+            return false;
+        }
+        BundleCapability other = (BundleCapability) obj;
+        if (name == null) {
+            if (other.name != null) {
+                return false;
+            }
+        } else if (!name.equals(other.name)) {
+            return false;
+        }
+        if (version == null) {
+            if (other.version != null) {
+                return false;
+            }
+        } else if (!version.equals(other.version)) {
+            return false;
+        }
+        return true;
+    }
+
+}
\ No newline at end of file

Added: ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/BundleInfo.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/BundleInfo.java?rev=1036848&view=auto
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/BundleInfo.java (added)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/BundleInfo.java Fri Nov 19 14:06:06 2010
@@ -0,0 +1,286 @@
+/*
+ *  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.ivy.osgi.core;
+
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.ivy.osgi.util.Version;
+
+
+/**
+ * Bundle info extracted from the bundle manifest.
+ * 
+ */
+public class BundleInfo {
+
+    public static final Version DEFAULT_VERSION = new Version(1, 0, 0, null);
+
+    public static final String PACKAGE_TYPE = "package";
+
+    public static final String BUNDLE_TYPE = "bundle";
+
+    public static final String SERVICE_TYPE = "service";
+
+    private String symbolicName;
+
+    private String presentationName;
+
+    private String id;
+
+    private Version version;
+
+    private Set<BundleRequirement> requirements = new LinkedHashSet<BundleRequirement>();
+
+    private Set<BundleCapability> capabilities = new LinkedHashSet<BundleCapability>();
+
+    private List<String> executionEnvironments = Collections.emptyList();
+
+    private String description;
+
+    private String documentation;
+
+    private String license;
+
+    private Integer size;
+
+    private String uri;
+
+    public BundleInfo(String name, Version version) {
+        this.symbolicName = name;
+        this.version = version;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("BundleInfo [executionEnvironments=");
+        builder.append(executionEnvironments);
+        builder.append(", capabilities=");
+        builder.append(capabilities);
+        builder.append(", requirements=");
+        builder.append(requirements);
+        builder.append(", symbolicName=");
+        builder.append(symbolicName);
+        builder.append(", version=");
+        builder.append(version);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    public String getSymbolicName() {
+        return symbolicName;
+    }
+
+    public Version getVersion() {
+        return version == null ? DEFAULT_VERSION : version;
+    }
+
+    public Version getRawVersion() {
+        return version;
+    }
+
+    public void setUri(String uri) {
+        this.uri = uri;
+    }
+    
+    public String getUri() {
+        return uri;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setPresentationName(String presentationName) {
+        this.presentationName = presentationName;
+    }
+
+    public String getPresentationName() {
+        return presentationName;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDocumentation(String documentation) {
+        this.documentation = documentation;
+    }
+
+    public String getDocumentation() {
+        return documentation;
+    }
+
+    public void setLicense(String license) {
+        this.license = license;
+    }
+
+    public String getLicense() {
+        return license;
+    }
+
+    public void setSize(Integer size) {
+        this.size = size;
+    }
+
+    public Integer getSize() {
+        return size;
+    }
+
+    public void addRequirement(BundleRequirement requirement) {
+        requirements.add(requirement);
+    }
+
+    public Set<BundleRequirement> getRequirements() {
+        return requirements;
+    }
+
+    public void addCapability(BundleCapability capability) {
+        capabilities.add(capability);
+    }
+
+    public Set<BundleCapability> getCapabilities() {
+        return capabilities;
+    }
+
+    public List<String> getExecutionEnvironments() {
+        return executionEnvironments;
+    }
+
+    public void setExecutionEnvironments(List<String> executionEnvironment) {
+        this.executionEnvironments = executionEnvironment;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((capabilities == null) ? 0 : capabilities.hashCode());
+        result = prime * result + ((requirements == null) ? 0 : requirements.hashCode());
+        result = prime * result + ((symbolicName == null) ? 0 : symbolicName.hashCode());
+        result = prime * result + ((version == null) ? 0 : version.hashCode());
+        result = prime * result + ((executionEnvironments == null) ? 0 : executionEnvironments.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof BundleInfo)) {
+            return false;
+        }
+        BundleInfo other = (BundleInfo) obj;
+        if (capabilities == null) {
+            if (other.capabilities != null) {
+                return false;
+            }
+        } else if (!capabilities.equals(other.capabilities)) {
+            return false;
+        }
+        if (requirements == null) {
+            if (other.requirements != null) {
+                return false;
+            }
+        } else if (!requirements.equals(other.requirements)) {
+            return false;
+        }
+        if (symbolicName == null) {
+            if (other.symbolicName != null) {
+                return false;
+            }
+        } else if (!symbolicName.equals(other.symbolicName)) {
+            return false;
+        }
+        if (version == null) {
+            if (other.version != null) {
+                return false;
+            }
+        } else if (!version.equals(other.version)) {
+            return false;
+        }
+        if (executionEnvironments == null) {
+            if (other.executionEnvironments != null) {
+                return false;
+            }
+        } else if (!executionEnvironments.equals(other.executionEnvironments)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Deprecated
+    public Set<BundleRequirement> getRequires() {
+        Set<BundleRequirement> set = new LinkedHashSet<BundleRequirement>();
+        for (BundleRequirement requirement : requirements) {
+            if (requirement.getType().equals(BUNDLE_TYPE)) {
+                set.add(requirement);
+            }
+        }
+        return set;
+    }
+
+    @Deprecated
+    public Set<BundleRequirement> getImports() {
+        Set<BundleRequirement> set = new LinkedHashSet<BundleRequirement>();
+        for (BundleRequirement requirement : requirements) {
+            if (requirement.getType().equals(PACKAGE_TYPE)) {
+                set.add(requirement);
+            }
+        }
+        return set;
+    }
+
+    @Deprecated
+    public Set<ExportPackage> getExports() {
+        Set<ExportPackage> set = new LinkedHashSet<ExportPackage>();
+        for (BundleCapability capability : capabilities) {
+            if (capability.getType().equals(PACKAGE_TYPE)) {
+                set.add((ExportPackage) capability);
+            }
+        }
+        return set;
+    }
+
+    @Deprecated
+    public Set<BundleCapability> getServices() {
+        Set<BundleCapability> set = new LinkedHashSet<BundleCapability>();
+        for (BundleCapability capability : capabilities) {
+            if (capability.getType().equals(SERVICE_TYPE)) {
+                set.add(capability);
+            }
+        }
+        return set;
+    }
+
+}
\ No newline at end of file

Added: ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/BundleRequirement.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/BundleRequirement.java?rev=1036848&view=auto
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/BundleRequirement.java (added)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/BundleRequirement.java Fri Nov 19 14:06:06 2010
@@ -0,0 +1,113 @@
+/*
+ *  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.ivy.osgi.core;
+
+import org.apache.ivy.osgi.util.VersionRange;
+
+public class BundleRequirement {
+
+    private final String name;
+
+    private final String resolution;
+
+    private final VersionRange version;
+
+    private final String type;
+
+    public BundleRequirement(String type, String name, VersionRange version, String resolution) {
+        this.type = type;
+        this.name = name;
+        this.version = version;
+        this.resolution = resolution;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public VersionRange getVersion() {
+        return version;
+    }
+
+    public String getResolution() {
+        return resolution;
+    }
+
+    @Override
+    public String toString() {
+        return name + (version == null ? "" : ";" + version) + (resolution == null ? "" : " (" + resolution + ")");
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((type == null) ? 0 : type.hashCode());
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        result = prime * result + ((resolution == null) ? 0 : resolution.hashCode());
+        result = prime * result + ((version == null) ? 0 : version.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof BundleRequirement)) {
+            return false;
+        }
+        BundleRequirement other = (BundleRequirement) obj;
+        if (type == null) {
+            if (other.type != null) {
+                return false;
+            }
+        } else if (!type.equals(other.type)) {
+            return false;
+        }
+        if (name == null) {
+            if (other.name != null) {
+                return false;
+            }
+        } else if (!name.equals(other.name)) {
+            return false;
+        }
+        if (resolution == null) {
+            if (other.resolution != null) {
+                return false;
+            }
+        } else if (!resolution.equals(other.resolution)) {
+            return false;
+        }
+        if (version == null) {
+            if (other.version != null) {
+                return false;
+            }
+        } else if (!version.equals(other.version)) {
+            return false;
+        }
+        return true;
+    }
+}
\ No newline at end of file

Added: ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/ExportPackage.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/ExportPackage.java?rev=1036848&view=auto
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/ExportPackage.java (added)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/ExportPackage.java Fri Nov 19 14:06:06 2010
@@ -0,0 +1,74 @@
+/*
+ *  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.ivy.osgi.core;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.ivy.osgi.util.Version;
+
+
+public class ExportPackage extends BundleCapability {
+
+    private final Set<String> uses = new HashSet<String>();
+
+    public ExportPackage(String name, Version version) {
+        super(BundleInfo.PACKAGE_TYPE, name, version);
+    }
+
+    public void addUse(String pkg) {
+        uses.add(pkg);
+    }
+
+    @Override
+    public Version getVersion() {
+        return super.getVersion() == null ? BundleInfo.DEFAULT_VERSION : super.getVersion();
+    }
+
+    public Set<String> getUses() {
+        return uses;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = super.hashCode();
+        result = prime * result + ((uses == null) ? 0 : uses.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        ExportPackage other = (ExportPackage) obj;
+        if (uses == null) {
+            if (other.uses != null) {
+                return false;
+            }
+        } else if (!uses.equals(other.uses)) {
+            return false;
+        }
+        return true;
+    }
+
+}
\ No newline at end of file

Added: ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/ManifestHeaderElement.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/ManifestHeaderElement.java?rev=1036848&view=auto
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/ManifestHeaderElement.java (added)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/ManifestHeaderElement.java Fri Nov 19 14:06:06 2010
@@ -0,0 +1,113 @@
+/*
+ *  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.ivy.osgi.core;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+public class ManifestHeaderElement {
+    private List<String> values = new ArrayList<String>();
+    private Map<String, String> attributes = new HashMap<String, String>();
+    private Map<String, String> directives = new HashMap<String, String>();
+
+    public List<String> getValues() {
+        return values;
+    }
+
+    public void addValue(String value) {
+        values.add(value);
+    }
+
+    public Map<String, String> getAttributes() {
+        return attributes;
+    }
+
+    public void addAttribute(String name, String value) {
+        attributes.put(name, value);
+    }
+
+    public Map<String, String> getDirectives() {
+        return directives;
+    }
+
+    public void addDirective(String name, String value) {
+        directives.put(name, value);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof ManifestHeaderElement)) {
+            return false;
+        }
+        ManifestHeaderElement other = (ManifestHeaderElement) obj;
+        if (other.values.size() != values.size()) {
+            return false;
+        }
+        for (String value : values) {
+            if (!other.values.contains(value)) {
+                return false;
+            }
+        }
+        if (other.directives.size() != directives.size()) {
+            return false;
+        }
+        for (Entry<String, String> directive : directives.entrySet()) {
+            if (!directive.getValue().equals(other.directives.get(directive.getKey()))) {
+                return false;
+            }
+        }
+        if (other.attributes.size() != attributes.size()) {
+            return false;
+        }
+        for (Entry<String, String> attribute : attributes.entrySet()) {
+            if (!attribute.getValue().equals(other.attributes.get(attribute.getKey()))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        String string = "";
+        Iterator<String> itValues = values.iterator();
+        while (itValues.hasNext()) {
+            string = string.concat(itValues.next());
+            if (itValues.hasNext()) {
+                string = string.concat(";");
+            }
+        }
+        for (Entry<String, String> directive : directives.entrySet()) {
+            string = string.concat(";");
+            string = string.concat(directive.getKey());
+            string = string.concat(":=");
+            string = string.concat(directive.getValue());
+        }
+        for (Entry<String, String> attribute : attributes.entrySet()) {
+            string = string.concat(";");
+            string = string.concat(attribute.getKey());
+            string = string.concat("=");
+            string = string.concat(attribute.getValue());
+        }
+        return string;
+    }
+}

Added: ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/ManifestHeaderValue.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/ManifestHeaderValue.java?rev=1036848&view=auto
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/ManifestHeaderValue.java (added)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/ManifestHeaderValue.java Fri Nov 19 14:06:06 2010
@@ -0,0 +1,425 @@
+/*
+ *  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.ivy.osgi.core;
+
+import java.io.PrintStream;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Parse a header of a manifest. The manifest header is composed with the following rules:
+ * 
+ * <pre>
+ * header ::= header-element (',' header-element)*
+ * header-element ::= values (';' (attribute | directive) )*
+ * values ::= value (';' value)*
+ * value ::= &lt;any string value that does not have ';' or ','&gt;
+ * attribute ::= key '=' value
+ * directive ::= key '=' value
+ * key ::= token
+ * value ::= token | quoted-string | double-quoted-string
+ * </pre>
+ */
+public class ManifestHeaderValue {
+
+    private List<ManifestHeaderElement> elements = new ArrayList<ManifestHeaderElement>();
+
+    ManifestHeaderValue() {
+        // just for unit testing
+    }
+
+    public ManifestHeaderValue(String header) throws ParseException {
+        if (header != null) {
+            new ManifestHeaderParser(header).parse();
+        }
+    }
+
+    public List<ManifestHeaderElement> getElements() {
+        return elements;
+    }
+
+    public String getSingleValue() {
+        if (elements.isEmpty()) {
+            return null;
+        }
+        List<String> values = getElements().iterator().next().getValues();
+        if (values.isEmpty()) {
+            return null;
+        }
+        return values.iterator().next();
+    }
+
+    public List<String> getValues() {
+        if (elements.isEmpty()) {
+            return Collections.emptyList();
+        }
+        List<String> list = new ArrayList<String>();
+        for (ManifestHeaderElement element : getElements()) {
+            list.addAll(element.getValues());
+        }
+        return list;
+    }
+
+    void addElement(ManifestHeaderElement element) {
+        this.elements.add(element);
+    }
+
+    class ManifestHeaderParser {
+
+        /**
+         * header to parse
+         */
+        private final String header;
+
+        /**
+         * the length of the source
+         */
+        private int length;
+
+        /**
+         * buffer
+         */
+        private StringBuilder buffer = new StringBuilder();
+
+        /**
+         * position in the source
+         */
+        private int pos = 0;
+
+        /**
+         * last read character
+         */
+        private char c;
+
+        /**
+         * the header element being build
+         */
+        private ManifestHeaderElement elem = new ManifestHeaderElement();
+
+        /**
+         * Once at true (at the first attribute parsed), only parameters are allowed
+         */
+        private boolean valuesParsed;
+
+        /**
+         * the last parsed parameter name
+         */
+        private String paramName;
+
+        /**
+         * true if the last parsed parameter is a directive (assigned via :=)
+         */
+        private boolean isDirective;
+
+        /**
+         * Default constructor
+         * 
+         * @param header
+         *            the header to parse
+         */
+        ManifestHeaderParser(String header) {
+            this.header = header;
+            this.length = header.length();
+        }
+
+        /**
+         * Do the parsing
+         * 
+         * @throws ParseException
+         */
+        void parse() throws ParseException {
+            do {
+                elem = new ManifestHeaderElement();
+                int posElement = pos;
+                parseElement();
+                if (elem.getValues().isEmpty()) {
+                    error("No defined value", posElement);
+                    // try to recover: ignore that element
+                    continue;
+                }
+                addElement(elem);
+            } while (pos < length);
+        }
+
+        private char readNext() {
+            if (pos == length) {
+                c = '\0';
+            } else {
+                c = header.charAt(pos++);
+            }
+            return c;
+        }
+
+        private void error(String message) throws ParseException {
+            error(message, pos - 1);
+        }
+
+        private void error(String message, int p) throws ParseException {
+            throw new ParseException(message, p);
+        }
+
+        private void parseElement() throws ParseException {
+            valuesParsed = false;
+            do {
+                parseValueOrParameter();
+            } while (c == ';' && pos < length);
+        }
+
+        private void parseValueOrParameter() throws ParseException {
+            // true if the value/parameter parsing has started, white spaces skipped
+            boolean start = false;
+            // true if the value/parameter parsing is ended, then only white spaces are allowed
+            boolean end = false;
+            do {
+                switch (readNext()) {
+                case '\0':
+                    break;
+                case ';':
+                case ',':
+                    endValue();
+                    return;
+                case ':':
+                case '=':
+                    endParameterName();
+                    parseSeparator();
+                    parseParameterValue();
+                    return;
+                case ' ':
+                case '\t':
+                case '\n':
+                case '\r':
+                    if (start) {
+                        end = true;
+                    }
+                    break;
+                default:
+                    if (end) {
+                        error("Expecting the end of a value or of an parameter name");
+                        // try to recover: restart the parsing of the value or parameter
+                        end = false;
+                    }
+                    start = true;
+                    buffer.append(c);
+                }
+            } while (pos < length);
+            endValue();
+        }
+
+        private void endValue() throws ParseException {
+            if (valuesParsed) {
+                error("Early end of a parameter");
+                // try to recover: ignore it
+                buffer.setLength(0);
+                return;
+            }
+            if (buffer.length() == 0) {
+                error("Empty value");
+                // try to recover: just ignore the error
+            }
+            elem.addValue(buffer.toString());
+            buffer.setLength(0);
+        }
+
+        private void endParameterName() throws ParseException {
+            if (buffer.length() == 0) {
+                error("Empty parameter name");
+                // try to recover: won't store the value
+                paramName = null;
+            }
+            paramName = buffer.toString();
+            buffer.setLength(0);
+        }
+
+        private void parseSeparator() throws ParseException {
+            if (c == '=') {
+                isDirective = false;
+                return;
+            }
+            if (readNext() != '=') {
+                error("Expecting '='");
+                // try to recover: will ignore this parameter
+                pos--;
+                paramName = null;
+            }
+            isDirective = true;
+        }
+
+        private void parseParameterValue() throws ParseException {
+            // true if the value parsing has started, white spaces skipped
+            boolean start = false;
+            // true if the value parsing is ended, then only white spaces are allowed
+            boolean end = false;
+            boolean doubleQuoted = false;
+            do {
+                switch (readNext()) {
+                case '\0':
+                    break;
+
+                case ',':
+                case ';':
+                    endParameterValue();
+                    return;
+                case '=':
+                case ':':
+                    error("Illegal character '" + c + "' in parameter value of " + paramName);
+                    // try to recover: ignore that parameter
+                    paramName = null;
+                    break;
+                case '\"':
+                    doubleQuoted = true;
+                case '\'':
+                    if (end && paramName != null) {
+                        error("Expecting the end of a parameter value");
+                        // try to recover: ignore that parameter
+                        paramName = null;
+                    }
+                    if (start) {
+                        // quote in the middle of the value, just add it as a quote
+                        buffer.append(c);
+                    } else {
+                        start = true;
+                        appendQuoted(doubleQuoted);
+                        end = true;
+                    }
+                    break;
+                case '\\':
+                    if (end && paramName != null) {
+                        error("Expecting the end of a parameter value");
+                        // try to recover: ignore that parameter
+                        paramName = null;
+                    }
+                    start = true;
+                    appendEscaped();
+                    break;
+                case ' ':
+                case '\t':
+                case '\n':
+                case '\r':
+                    if (start) {
+                        end = true;
+                    }
+                    break;
+                default:
+                    if (end && paramName != null) {
+                        error("Expecting the end of a parameter value");
+                        // try to recover: ignore that parameter
+                        paramName = null;
+                    }
+                    start = true;
+                    buffer.append(c);
+                }
+            } while (pos < length);
+            endParameterValue();
+        }
+
+        private void endParameterValue() throws ParseException {
+            if (paramName == null) {
+                // recovering from an incorrect parameter: skip the value
+                return;
+            }
+            if (buffer.length() == 0) {
+                error("Empty parameter value");
+                // try to recover: do not store the parameter
+                return;
+            }
+            String value = buffer.toString();
+            if (isDirective) {
+                elem.addDirective(paramName, value);
+            } else {
+                elem.addAttribute(paramName, value);
+            }
+            valuesParsed = true;
+            buffer.setLength(0);
+        }
+
+        private void appendQuoted(boolean doubleQuoted) {
+            do {
+                switch (readNext()) {
+                case '\0':
+                    break;
+                case '\"':
+                    if (doubleQuoted) {
+                        return;
+                    }
+                    buffer.append(c);
+                    break;
+                case '\'':
+                    if (!doubleQuoted) {
+                        return;
+                    }
+                    buffer.append(c);
+                    break;
+                case '\\':
+                    break;
+                default:
+                    buffer.append(c);
+                }
+            } while (pos < length);
+        }
+
+        private void appendEscaped() {
+            if (pos < length) {
+                buffer.append(readNext());
+            } else {
+                buffer.append(c);
+            }
+        }
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof ManifestHeaderValue)) {
+            return false;
+        }
+        ManifestHeaderValue other = (ManifestHeaderValue) obj;
+        if (other.elements.size() != elements.size()) {
+            return false;
+        }
+        for (ManifestHeaderElement element : elements) {
+            if (!other.elements.contains(element)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        String string = "";
+        Iterator<ManifestHeaderElement> it = elements.iterator();
+        while (it.hasNext()) {
+            string = string.concat(it.next().toString());
+            if (it.hasNext()) {
+                string = string.concat(",");
+            }
+        }
+        return string;
+    }
+
+    public static void writeParseException(PrintStream out, String source, ParseException e) {
+        out.println(e.getMessage());
+        out.print("   " + source + "\n   ");
+        for (int i = 0; i < e.getErrorOffset(); i++) {
+            out.print(' ');
+        }
+        out.println('^');
+    }
+}

Added: ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/ManifestParser.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/ManifestParser.java?rev=1036848&view=auto
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/ManifestParser.java (added)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/core/ManifestParser.java Fri Nov 19 14:06:06 2010
@@ -0,0 +1,201 @@
+/*
+ *  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.ivy.osgi.core;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.ParseException;
+import java.util.List;
+import java.util.jar.Attributes;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+import org.apache.ivy.osgi.util.Version;
+import org.apache.ivy.osgi.util.VersionRange;
+
+
+/**
+ * Provides an OSGi manifest parser.
+ * 
+ */
+public class ManifestParser {
+
+    private static final String EXPORT_PACKAGE = "Export-Package";
+    private static final String IMPORT_PACKAGE = "Import-Package";
+    private static final String EXPORT_SERVICE = "Export-Service";
+    private static final String IMPORT_SERVICE = "Import-Service";
+    private static final String REQUIRE_BUNDLE = "Require-Bundle";
+    private static final String BUNDLE_VERSION = "Bundle-Version";
+    private static final String BUNDLE_NAME = "Bundle-Name";
+    private static final String BUNDLE_DESCRIPTION = "Bundle-Description";
+    private static final String BUNDLE_SYMBOLIC_NAME = "Bundle-SymbolicName";
+    private static final String BUNDLE_MANIFEST_VERSION = "Bundle-ManifestVersion";
+    private static final String BUNDLE_REQUIRED_EXECUTION_ENVIRONMENT = "Bundle-RequiredExecutionEnvironment";
+
+    private static final String ATTR_RESOLUTION = "resolution";
+    private static final String ATTR_VERSION = "version";
+    private static final String ATTR_BUNDLE_VERSION = "bundle-version";
+    private static final String ATTR_USE = "use";
+
+    public static BundleInfo parseJarManifest(InputStream jarStream) throws IOException, ParseException {
+        final JarInputStream jis = new JarInputStream(jarStream);
+        final BundleInfo parseManifest = parseManifest(jis.getManifest());
+        jis.close();
+        return parseManifest;
+    }
+
+    public static BundleInfo parseManifest(File manifestFile) throws IOException, ParseException {
+        final FileInputStream fis = new FileInputStream(manifestFile);
+        final BundleInfo parseManifest = parseManifest(fis);
+        fis.close();
+        return parseManifest;
+    }
+
+    public static BundleInfo parseManifest(InputStream manifestStream) throws IOException, ParseException {
+        final BundleInfo parseManifest = parseManifest(new Manifest(manifestStream));
+        manifestStream.close();
+        return parseManifest;
+    }
+
+    public static BundleInfo parseManifest(Manifest manifest) throws ParseException {
+        Attributes mainAttributes = manifest.getMainAttributes();
+
+        String manifestVersion = mainAttributes.getValue(BUNDLE_MANIFEST_VERSION);
+        if (manifestVersion == null) {
+            // non OSGi manifest
+            throw new ParseException("No " + BUNDLE_MANIFEST_VERSION + " in the manifest", 0);
+        }
+
+        String symbolicName = new ManifestHeaderValue(mainAttributes.getValue(BUNDLE_SYMBOLIC_NAME)).getSingleValue();
+        if (symbolicName == null) {
+            throw new ParseException("No " + BUNDLE_SYMBOLIC_NAME + " in the manifest", 0);
+        }
+
+        String description = new ManifestHeaderValue(mainAttributes.getValue(BUNDLE_DESCRIPTION)).getSingleValue();
+        if (description == null) {
+            description = new ManifestHeaderValue(mainAttributes.getValue(BUNDLE_DESCRIPTION)).getSingleValue();
+        }
+
+        String vBundle = new ManifestHeaderValue(mainAttributes.getValue(BUNDLE_VERSION)).getSingleValue();
+        Version version;
+        try {
+            version = versionOf(vBundle);
+        } catch (NumberFormatException e) {
+            throw new ParseException("The " + BUNDLE_VERSION + " has an incorrect version: " + vBundle + " ("
+                    + e.getMessage() + ")", 0);
+        }
+
+        BundleInfo bundleInfo = new BundleInfo(symbolicName, version);
+
+        bundleInfo.setDescription(description);
+
+        List<String> environments = new ManifestHeaderValue(mainAttributes
+                .getValue(BUNDLE_REQUIRED_EXECUTION_ENVIRONMENT)).getValues();
+        bundleInfo.setExecutionEnvironments(environments);
+
+        parseRequirement(bundleInfo, mainAttributes, REQUIRE_BUNDLE, BundleInfo.BUNDLE_TYPE, ATTR_BUNDLE_VERSION);
+        parseRequirement(bundleInfo, mainAttributes, IMPORT_PACKAGE, BundleInfo.PACKAGE_TYPE, ATTR_VERSION);
+        parseRequirement(bundleInfo, mainAttributes, IMPORT_SERVICE, BundleInfo.SERVICE_TYPE, ATTR_VERSION);
+
+        ManifestHeaderValue exportElements = new ManifestHeaderValue(mainAttributes.getValue(EXPORT_PACKAGE));
+        for (ManifestHeaderElement exportElement : exportElements.getElements()) {
+            String vExport = exportElement.getAttributes().get(ATTR_VERSION);
+            Version v = null;
+            try {
+                v = versionOf(vExport);
+            } catch (NumberFormatException e) {
+                throw new ParseException("The " + EXPORT_PACKAGE + " has an incorrect version: " + vExport + " ("
+                        + e.getMessage() + ")", 0);
+            }
+
+            for (String name : exportElement.getValues()) {
+                ExportPackage export = new ExportPackage(name, v);
+                String uses = exportElement.getDirectives().get(ATTR_USE);
+                if (uses != null) {
+                    String[] split = uses.trim().split(",");
+                    for (String u : split) {
+                        export.addUse(u.trim());
+                    }
+                }
+                bundleInfo.addCapability(export);
+            }
+        }
+
+        parseCapability(bundleInfo, mainAttributes, EXPORT_SERVICE, BundleInfo.SERVICE_TYPE);
+
+        return bundleInfo;
+    }
+
+    private static void parseRequirement(BundleInfo bundleInfo, Attributes mainAttributes, String headerName,
+            String type, String versionAttr) throws ParseException {
+        ManifestHeaderValue elements = new ManifestHeaderValue(mainAttributes.getValue(headerName));
+        for (ManifestHeaderElement element : elements.getElements()) {
+            String resolution = element.getDirectives().get(ATTR_RESOLUTION);
+            String attVersion = element.getAttributes().get(versionAttr);
+            VersionRange version = null;
+            try {
+                version = versionRangeOf(attVersion);
+            } catch (ParseException e) {
+                throw new ParseException("The " + headerName + " has an incorrect version: " + attVersion + " ("
+                        + e.getMessage() + ")", 0);
+            }
+
+            for (String name : element.getValues()) {
+                bundleInfo.addRequirement(new BundleRequirement(type, name, version, resolution));
+            }
+        }
+    }
+
+    private static void parseCapability(BundleInfo bundleInfo, Attributes mainAttributes, String headerName, String type)
+            throws ParseException {
+        ManifestHeaderValue elements = new ManifestHeaderValue(mainAttributes.getValue(headerName));
+        for (ManifestHeaderElement element : elements.getElements()) {
+            String attVersion = element.getAttributes().get(ATTR_VERSION);
+            Version version = null;
+            try {
+                version = versionOf(attVersion);
+            } catch (NumberFormatException e) {
+                throw new ParseException("The " + headerName + " has an incorrect version: " + attVersion + " ("
+                        + e.getMessage() + ")", 0);
+            }
+
+            for (String name : element.getValues()) {
+                BundleCapability export = new BundleCapability(type, name, version);
+                bundleInfo.addCapability(export);
+            }
+        }
+
+    }
+
+    private static VersionRange versionRangeOf(String v) throws ParseException {
+        if (v == null) {
+            return null;
+        }
+        return new VersionRange(v);
+    }
+
+    private static Version versionOf(String v) throws NumberFormatException {
+        if (v == null) {
+            return null;
+        }
+        return new Version(v);
+    }
+
+}

Added: ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/ivy/OsgiFileResolver.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/ivy/OsgiFileResolver.java?rev=1036848&view=auto
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/ivy/OsgiFileResolver.java (added)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/ivy/OsgiFileResolver.java Fri Nov 19 14:06:06 2010
@@ -0,0 +1,146 @@
+/*
+ *  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.ivy.osgi.ivy;
+
+import static java.lang.String.format;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Date;
+
+import org.apache.ivy.core.module.descriptor.Artifact;
+import org.apache.ivy.core.module.descriptor.DefaultArtifact;
+import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
+import org.apache.ivy.core.module.id.ModuleRevisionId;
+import org.apache.ivy.core.resolve.ResolveData;
+import org.apache.ivy.osgi.ivy.internal.FilePackageScanner;
+import org.apache.ivy.osgi.ivy.internal.JarEntryResource;
+import org.apache.ivy.osgi.ivy.internal.JarFileRepository;
+import org.apache.ivy.osgi.util.ZipUtil;
+import org.apache.ivy.plugins.repository.Resource;
+import org.apache.ivy.plugins.repository.file.FileRepository;
+import org.apache.ivy.plugins.repository.file.FileResource;
+import org.apache.ivy.plugins.resolver.FileSystemResolver;
+import org.apache.ivy.plugins.resolver.util.ResolvedResource;
+import org.apache.ivy.util.Message;
+
+
+/**
+ * An OSGi file system resolver.
+ * 
+ * @author alex@radeski.net
+ */
+public class OsgiFileResolver extends FileSystemResolver {
+    
+    private final FilePackageScanner packageScanner = new FilePackageScanner();
+
+    public OsgiFileResolver() {
+        setRepository(new JarFileRepository());
+    }
+
+    @Override
+    protected ResolvedResource findArtifactRef(Artifact artifact, Date date) {
+        Message.debug(format("\tfind artifact ref: artifact=%s, date=%s", artifact, date));
+
+        final ModuleRevisionId newMrid = artifact.getModuleRevisionId();
+        ResolvedResource resolvedResource = findResourceUsingPatterns(newMrid,
+                getArtifactPatterns(),
+                artifact,
+                getDefaultRMDParser(artifact.getModuleRevisionId().getModuleId()),
+                date);
+
+        Message.debug(format("\t\tfind artifact ref: mrid=%s, resource=%s", newMrid, resolvedResource));
+
+        if (resolvedResource == null) {
+            Message.debug("\t\tfind artifact file ref: resource was null");
+            return null;
+        }
+
+        final Resource resource = resolvedResource.getResource();
+        if ((resource instanceof FileResource) && ((FileResource) resource).getFile().isDirectory()) {
+            FileResource dirResource = (FileResource) resource;
+            try {
+                final File bundleZipFile = File.createTempFile("ivy-osgi-" + newMrid, ".zip");
+                ZipUtil.zip(dirResource.getFile(), new FileOutputStream(bundleZipFile));
+                Message.debug("\t\tfind artifact ref: zip file=" + bundleZipFile);
+                return new ResolvedResource(new FileResource(dirResource.getRepository(), bundleZipFile), resolvedResource.getRevision());
+            } catch (IOException e) {
+                throw new IllegalStateException("Failed to create temp zip file for bundle:" + newMrid);
+            }
+        }
+
+        Message.debug("\t\tfind artifact ref: resource=" + resolvedResource);
+        return resolvedResource;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public ResolvedResource findIvyFileRef(DependencyDescriptor dd, ResolveData data) {
+        packageScanner.scanAllPackageExportHeaders(getIvyPatterns(), getSettings());
+        
+        Message.debug(format("\tfind ivy file ref: dd=%s, data=%s", dd, data));
+
+        final ModuleRevisionId newMrid = dd.getDependencyRevisionId();
+        final ResolvedResource bundleResolvedResource = findResourceUsingPatterns(newMrid,
+                getIvyPatterns(),
+                DefaultArtifact.newIvyArtifact(newMrid, data.getDate()),
+                getRMDParser(dd, data),
+                data.getDate());
+
+
+        if (bundleResolvedResource == null) {
+            Message.debug("\tfind ivy file ref: resource was null");
+            return null;
+        }
+
+        final Resource bundleResource = bundleResolvedResource.getResource();
+
+        Resource res = null;
+        if ((bundleResource instanceof FileResource) && ((FileResource) bundleResource).getFile().isDirectory()) {
+            final FileResource fileResource = (FileResource) bundleResource;
+            res = new FileResource((FileRepository) getRepository(), new File(fileResource.getFile(), "META-INF/MANIFEST.MF"));
+        } else if (bundleResource.getName().toUpperCase().endsWith(".JAR")) {
+            res = new JarEntryResource(bundleResource, "META-INF/MANIFEST.MF");
+        }
+
+        ResolvedResource resolvedResource = new ResolvedResource(res, bundleResolvedResource.getRevision());
+
+        Message.debug(format("\tfind ivy file ref: resource=%s", bundleResolvedResource));
+
+        return resolvedResource;
+    }
+
+
+//    protected ModuleRevisionId modifyModuleRevisionId(final ModuleRevisionId oldMrid) {
+//        String revision = oldMrid.getRevision();
+//        try {
+//            VersionRange versionRange = new VersionRange(oldMrid.getRevision());
+//            revision = versionRange.toIvyRevision();
+//        } catch (ParseException nfe) {
+//            // Do nothing as we fallback to default behaviour
+//        }
+//        final ModuleRevisionId newMrid = ModuleRevisionId.newInstance(oldMrid.getOrganisation(),
+//                oldMrid.getName(),
+//                oldMrid.getBranch(),
+//                revision,
+//                oldMrid.getExtraAttributes());
+//        return newMrid;
+//    }
+
+}
\ No newline at end of file

Added: ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/ivy/OsgiIvyParser.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/ivy/OsgiIvyParser.java?rev=1036848&view=auto
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/ivy/OsgiIvyParser.java (added)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/ivy/OsgiIvyParser.java Fri Nov 19 14:06:06 2010
@@ -0,0 +1,195 @@
+/*
+ *  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.ivy.osgi.ivy;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.ParseException;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.ivy.core.module.descriptor.Artifact;
+import org.apache.ivy.core.module.descriptor.Configuration;
+import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
+import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
+import org.apache.ivy.core.module.descriptor.ExcludeRule;
+import org.apache.ivy.core.module.descriptor.License;
+import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
+import org.apache.ivy.core.module.id.ModuleRevisionId;
+import org.apache.ivy.plugins.parser.ModuleDescriptorParser;
+import org.apache.ivy.plugins.parser.ModuleDescriptorParserRegistry;
+import org.apache.ivy.plugins.parser.ParserSettings;
+import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorParser;
+import org.apache.ivy.plugins.repository.url.URLResource;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+public class OsgiIvyParser extends XmlModuleDescriptorParser {
+
+    public static class OsgiParser extends Parser {
+
+        private ModuleDescriptor manifestMD = null;
+
+        public OsgiParser(ModuleDescriptorParser parser, ParserSettings ivySettings) {
+            super(parser, ivySettings);
+        }
+
+        @Override
+        protected void infoStarted(Attributes attributes) {
+            String manifest = attributes.getValue("manifest");
+            if (manifest != null) {
+                try {
+                    manifestMD = parseManifest(manifest);
+                    includeMdInfo(getMd(), manifestMD);
+                } catch (SAXException e) {
+                    // it is caught in the startElement method
+                    throw new RuntimeException(e);
+                }
+                return;
+            }
+            super.infoStarted(attributes);
+        }
+
+        public ModuleDescriptor parseManifest(String manifest) throws SAXException {
+            if (getDescriptorURL() == null) {
+                throw new SAXException(
+                        "A reference to a manifest is only supported on module descriptors which are parsed from an URL");
+            }
+            URL includedUrl;
+            try {
+                includedUrl = getSettings().getRelativeUrlResolver().getURL(getDescriptorURL(), manifest);
+            } catch (MalformedURLException e) {
+                SAXException pe = new SAXException("Incorrect relative url of the include in '" + getDescriptorURL()
+                        + "' (" + e.getMessage() + ")");
+                pe.initCause(e);
+                throw pe;
+            }
+            URLResource includeResource = new URLResource(includedUrl);
+            ModuleDescriptorParser parser = ModuleDescriptorParserRegistry.getInstance().getParser(includeResource);
+            ModuleDescriptor manifestMd;
+            try {
+                manifestMd = parser.parseDescriptor(getSettings(), includeResource.getURL(), includeResource,
+                        isValidate());
+            } catch (ParseException e) {
+                SAXException pe = new SAXException("Incorrect included md '" + includeResource + "' in '"
+                        + getDescriptorURL() + "' (" + e.getMessage() + ")");
+                pe.initCause(e);
+                throw pe;
+            } catch (IOException e) {
+                SAXException pe = new SAXException("Unreadable included md '" + includeResource + "' in '"
+                        + getDescriptorURL() + "' (" + e.getMessage() + ")");
+                pe.initCause(e);
+                throw pe;
+            }
+            return manifestMd;
+        }
+
+        @Override
+        public void endDocument() throws SAXException {
+            if (manifestMD != null) {
+                includeMdDepedencies(getMd(), manifestMD);
+            }
+        }
+    }
+
+    @Override
+    protected Parser newParser(ParserSettings ivySettings) {
+        return new OsgiParser(this, ivySettings);
+    }
+
+    private static void includeMdInfo(DefaultModuleDescriptor md, ModuleDescriptor include) {
+        ModuleRevisionId mrid = include.getModuleRevisionId();
+        if (mrid != null) {
+            md.setModuleRevisionId(mrid);
+        }
+
+        ModuleRevisionId resolvedMrid = include.getResolvedModuleRevisionId();
+        if (resolvedMrid != null) {
+            md.setResolvedModuleRevisionId(resolvedMrid);
+        }
+
+        String description = include.getDescription();
+        if (description != null) {
+            md.setDescription(description);
+        }
+
+        String homePage = include.getHomePage();
+        if (homePage != null) {
+            md.setHomePage(homePage);
+        }
+
+        long lastModified = include.getLastModified();
+        if (lastModified > md.getLastModified()) {
+            md.setLastModified(lastModified);
+        }
+
+        String status = include.getStatus();
+        if (status != null) {
+            md.setStatus(status);
+        }
+
+        Map<String, String> extraInfo = include.getExtraInfo();
+        if (extraInfo != null) {
+            for (Entry<String, String> info : extraInfo.entrySet()) {
+                md.addExtraInfo(info.getKey(), info.getValue());
+            }
+        }
+
+        License[] licenses = include.getLicenses();
+        if (licenses != null) {
+            for (int i = 0; i < licenses.length; i++) {
+                md.addLicense(licenses[i]);
+            }
+        }
+
+        Configuration[] configurations = include.getConfigurations();
+        if (configurations != null) {
+            for (int i = 0; i < configurations.length; i++) {
+                md.addConfiguration(configurations[i]);
+            }
+        }
+
+    }
+
+    private static void includeMdDepedencies(DefaultModuleDescriptor md, ModuleDescriptor include) {
+        Artifact[] artifacts = include.getAllArtifacts();
+        if (artifacts != null) {
+            for (int i = 0; i < artifacts.length; i++) {
+                String[] artifactConfs = artifacts[i].getConfigurations();
+                for (int j = 0; j < artifactConfs.length; j++) {
+                    md.addArtifact(artifactConfs[j], artifacts[i]);
+                }
+            }
+        }
+
+        DependencyDescriptor[] dependencies = include.getDependencies();
+        if (dependencies != null) {
+            for (int i = 0; i < dependencies.length; i++) {
+                md.addDependency(dependencies[i]);
+            }
+        }
+
+        ExcludeRule[] excludeRules = include.getAllExcludeRules();
+        if (excludeRules != null) {
+            for (int i = 0; i < excludeRules.length; i++) {
+                md.addExcludeRule(excludeRules[i]);
+            }
+        }
+    }
+}

Added: ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/ivy/OsgiManifestParser.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/ivy/OsgiManifestParser.java?rev=1036848&view=auto
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/ivy/OsgiManifestParser.java (added)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/ivy/OsgiManifestParser.java Fri Nov 19 14:06:06 2010
@@ -0,0 +1,249 @@
+/*
+ *  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.ivy.osgi.ivy;
+
+import static java.lang.String.format;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+import java.util.regex.Pattern;
+
+import org.apache.ivy.core.module.descriptor.Configuration;
+import org.apache.ivy.core.module.descriptor.DefaultArtifact;
+import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
+import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
+import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
+import org.apache.ivy.core.module.id.ModuleRevisionId;
+import org.apache.ivy.osgi.core.BundleInfo;
+import org.apache.ivy.osgi.core.BundleRequirement;
+import org.apache.ivy.osgi.core.ExportPackage;
+import org.apache.ivy.osgi.core.ManifestParser;
+import org.apache.ivy.osgi.ivy.internal.PackageRegistry;
+import org.apache.ivy.osgi.util.NameUtil;
+import org.apache.ivy.osgi.util.NameUtil.OrgAndName;
+import org.apache.ivy.plugins.parser.AbstractModuleDescriptorParser;
+import org.apache.ivy.plugins.parser.ModuleDescriptorParser;
+import org.apache.ivy.plugins.parser.ParserSettings;
+import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorWriter;
+import org.apache.ivy.plugins.repository.Resource;
+import org.apache.ivy.util.Message;
+import org.apache.tools.ant.types.resources.FileResource;
+
+
+/**
+ * An parser for OSGi Manifest descriptor.
+ * 
+ * @author jerome@benois.fr
+ * @author alex@radeski.net
+ */
+public class OsgiManifestParser extends AbstractModuleDescriptorParser {
+
+    public static final String PACKAGE = ".package";
+
+    protected static final Pattern PATH_REGEX = Pattern
+            .compile("(.*/)?([\\w\\.]+)[\\-_](\\d\\.\\d\\.\\d)[\\.]?([\\w]+)?");
+
+    private static final OsgiManifestParser INSTANCE = new OsgiManifestParser();
+
+    public static OsgiManifestParser getInstance() {
+        return INSTANCE;
+    }
+
+    public boolean accept(Resource res) {
+        if (res == null || res.getName() == null || res.getName().trim().equals("")) {
+            return false;
+        }
+        return res.getName().toUpperCase().endsWith("META-INF/MANIFEST.MF")
+                || res.getName().toUpperCase().endsWith(".JAR") || res.getName().toUpperCase().endsWith(".PKGREF");
+    }
+
+    public ModuleDescriptor parseDescriptor(ParserSettings ivySettings, URL descriptorURL, Resource res,
+            boolean validate) throws ParseException, IOException {
+
+        Message.debug(format("\tparse descriptor: resource=%s", res));
+
+        final InternalParser parser = new InternalParser(this);
+        parser.parse(res, ivySettings);
+        return parser.getModuleDescriptor();
+    }
+
+    public ModuleDescriptor parseExports(Resource res) throws ParseException, IOException {
+
+        Message.debug(format("\tparse descriptor: resource=%s", res));
+
+        final InternalParser parser = new InternalParser(this);
+        parser.parse(res, true);
+        return parser.getModuleDescriptor();
+    }
+
+    public void toIvyFile(InputStream is, Resource res, File destFile, ModuleDescriptor md) throws ParseException,
+            IOException {
+        try {
+            XmlModuleDescriptorWriter.write(md, destFile);
+        } finally {
+            if (is != null) {
+                is.close();
+            }
+        }
+    }
+
+    public static class InternalParser extends AbstractParser {
+
+        protected InternalParser(ModuleDescriptorParser parser) {
+            super(parser);
+        }
+
+        public void parse(Resource res, ParserSettings ivySettings) throws IOException {
+            parse(res, false);
+        }
+
+        public void parse(Resource res, boolean useExports) throws IOException {
+            Manifest manifest;
+            if ((res instanceof FileResource) && ((FileResource) res).isDirectory()) {
+                manifest = new Manifest(new FileInputStream(res.getName() + "/META-INF/MANIFEST.MF"));
+            } else if (res.getName().toUpperCase().endsWith(".JAR")) {
+                manifest = new JarInputStream(res.openStream()).getManifest();
+            } else {
+                manifest = new Manifest(res.openStream());
+            }
+
+            if (manifest == null) {
+                return;
+            }
+
+            BundleInfo info;
+            try {
+                info = ManifestParser.parseManifest(manifest);
+            } catch (ParseException e) {
+                IOException ioe = new IOException();
+                ioe.initCause(e);
+                throw ioe;
+            }
+
+            setResource(res);
+
+            // Set Info
+            OrgAndName orgAndName = NameUtil.instance().asOrgAndName(info.getSymbolicName());
+            final ModuleRevisionId mrid = ModuleRevisionId.newInstance(orgAndName.org, orgAndName.name, info
+                    .getVersion().toString());
+
+            getMd().setDescription(info.getDescription());
+            getMd().setResolvedPublicationDate(new Date(res.getLastModified()));
+            getMd().setModuleRevisionId(mrid);
+            getMd().addConfiguration(new Configuration("default"));
+            getMd().addConfiguration(new Configuration("optional"));
+            getMd().addConfiguration(new Configuration("source"));
+            getMd().setStatus("release");
+            getMd().addArtifact("default",
+                    new DefaultArtifact(mrid, getDefaultPubDate(), info.getSymbolicName(), "jar", "jar"));
+            getMd().addArtifact("source",
+                    new DefaultArtifact(mrid, getDefaultPubDate(), info.getSymbolicName() + ".source", "src", "jar"));
+
+            if (useExports) {
+                addExports(getMd(), info.getExports());
+            } else {
+                Set<ModuleRevisionId> processedDeps = new HashSet<ModuleRevisionId>();
+                processedDeps.add(mrid);
+
+                addRequiredBundles(getMd(), info.getRequires(), processedDeps);
+                addImports(getMd(), info.getImports(), processedDeps);
+            }
+
+            Message.debug(format("\t\tparse: bundle info: %s", info.toString()));
+        }
+
+        protected void addExports(DefaultModuleDescriptor parent, Set<ExportPackage> bundleDependencies) {
+            for (final ExportPackage dep : bundleDependencies) {
+                String rev = "";
+                if (dep.getVersion() != null) {
+                    rev = dep.getVersion().toString();
+                }
+
+                final ModuleRevisionId depMrid = ModuleRevisionId.newInstance(PACKAGE, dep.getName(), rev);
+                final DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(parent, depMrid, false, false,
+                        true);
+                dd.addDependencyConfiguration("default", "default");
+                parent.addDependency(dd);
+            }
+        }
+
+        protected void addRequiredBundles(DefaultModuleDescriptor parent, Set<BundleRequirement> bundleDependencies,
+                Set<ModuleRevisionId> processedDeps) {
+            for (final BundleRequirement dep : bundleDependencies) {
+                String rev = "";
+                if (dep.getVersion() != null) {
+                    rev = dep.getVersion().toIvyRevision();
+                }
+
+                OrgAndName orgAndName = NameUtil.instance().asOrgAndName(dep.getName());
+                final ModuleRevisionId depMrid = ModuleRevisionId.newInstance(orgAndName.org, orgAndName.name, rev);
+
+                if (processedDeps.contains(depMrid)) {
+                    return;
+                }
+
+                processedDeps.add(depMrid);
+
+                final DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(parent, depMrid, false, false,
+                        true);
+                if (dep.getResolution() == null) {
+                    dd.addDependencyConfiguration("default", "default");
+                } else {
+                    dd.addDependencyConfiguration(dep.getResolution(), dep.getResolution());
+                }
+                parent.addDependency(dd);
+            }
+
+        }
+
+        protected void addImports(DefaultModuleDescriptor parent, Set<BundleRequirement> bundleDependencies,
+                Set<ModuleRevisionId> processedDeps) {
+            for (final BundleRequirement dep : bundleDependencies) {
+                final ModuleRevisionId pkgMrid = PackageRegistry.getInstance().processImports(dep.getName(), dep.getVersion());
+
+                if (processedDeps.contains(pkgMrid)) {
+                    return;
+                }
+
+                processedDeps.add(pkgMrid);
+
+                if (pkgMrid != null) {
+                    final DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(parent, pkgMrid, false,
+                            false, true);
+                    if (dep.getResolution() == null) {
+                        dd.addDependencyConfiguration("default", "default");
+                    } else {
+                        dd.addDependencyConfiguration(dep.getResolution(), dep.getResolution());
+                    }
+                    parent.addDependency(dd);
+                } else {
+                    Message.error("Failed to resolve imported package: " + dep);
+                }
+            }
+        }
+    }
+}

Added: ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/ivy/OsgiRevisionStrategy.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/ivy/OsgiRevisionStrategy.java?rev=1036848&view=auto
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/ivy/OsgiRevisionStrategy.java (added)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/ivy/OsgiRevisionStrategy.java Fri Nov 19 14:06:06 2010
@@ -0,0 +1,223 @@
+/*
+ *  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.ivy.osgi.ivy;
+
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import org.apache.ivy.core.IvyContext;
+import org.apache.ivy.core.module.id.ModuleRevisionId;
+import org.apache.ivy.plugins.latest.ArtifactInfo;
+import org.apache.ivy.plugins.latest.ComparatorLatestStrategy;
+import org.apache.ivy.plugins.version.VersionMatcher;
+
+public class OsgiRevisionStrategy extends ComparatorLatestStrategy {
+
+    private static final Pattern ALPHA_NUM_REGEX = Pattern.compile("([a-zA-Z])(\\d)");
+    private static final Pattern NUM_ALPHA_REGEX = Pattern.compile("(\\d)([a-zA-Z])");
+    private static final Pattern LABEL_REGEX = Pattern.compile("[_\\-\\+]");
+
+    /**
+     * Compares two ModuleRevisionId by their revision. Revisions are compared using an algorithm inspired by PHP
+     * version_compare one.
+     */
+    final class MridComparator implements Comparator<ModuleRevisionId> {
+
+        public int compare(ModuleRevisionId o1, ModuleRevisionId o2) {
+            String rev1 = o1.getRevision();
+            String rev2 = o2.getRevision();
+
+            String[] outerParts1 = rev1.split("[\\.]");
+            String[] outerParts2 = rev2.split("[\\.]");
+
+            for (int i = 0; i < outerParts1.length && i < outerParts2.length; i++) {
+                String outerPart1 = outerParts1[i];
+                String outerPart2 = outerParts2[i];
+
+                if (outerPart1.equals(outerPart2)) {
+                    continue;
+                }
+
+                outerPart1 = ALPHA_NUM_REGEX.matcher(outerPart1).replaceAll("$1_$2");
+                outerPart1 = NUM_ALPHA_REGEX.matcher(outerPart1).replaceAll("$1_$2");
+                outerPart2 = ALPHA_NUM_REGEX.matcher(outerPart2).replaceAll("$1_$2");
+                outerPart2 = NUM_ALPHA_REGEX.matcher(outerPart2).replaceAll("$1_$2");
+
+                String[] innerParts1 = LABEL_REGEX.split(outerPart1);
+                String[] innerParts2 = LABEL_REGEX.split(outerPart2);
+
+                for (int j = 0; j < innerParts1.length && j < innerParts2.length; j++) {
+                    if (innerParts1[j].equals(innerParts2[j])) {
+                        continue;
+                    }
+                    boolean is1Number = isNumber(innerParts1[j]);
+                    boolean is2Number = isNumber(innerParts2[j]);
+                    if (is1Number && !is2Number) {
+                        return 1;
+                    }
+                    if (is2Number && !is1Number) {
+                        return -1;
+                    }
+                    if (is1Number && is2Number) {
+                        return Long.valueOf(innerParts1[j]).compareTo(Long.valueOf(innerParts2[j]));
+                    }
+                    // both are strings, we compare them taking into account special meaning
+                    Map<String, Integer> meanings = getSpecialMeanings();
+                    Integer sm1 = meanings.get(innerParts1[j].toLowerCase(Locale.US));
+                    Integer sm2 = meanings.get(innerParts2[j].toLowerCase(Locale.US));
+                    if (sm1 != null) {
+                        sm2 = sm2 == null ? new Integer(0) : sm2;
+                        return sm1.compareTo(sm2);
+                    }
+                    if (sm2 != null) {
+                        return new Integer(0).compareTo(sm2);
+                    }
+                    return innerParts1[j].compareTo(innerParts2[j]);
+                }
+                if (i < innerParts1.length) {
+                    return isNumber(innerParts1[i]) ? 1 : -1;
+                }
+                if (i < innerParts2.length) {
+                    return isNumber(innerParts2[i]) ? -1 : 1;
+                }
+            }
+
+            if (outerParts1.length > outerParts2.length) {
+                return 1;
+            } else if (outerParts1.length < outerParts2.length) {
+                return -1;
+            }
+
+            return 0;
+        }
+
+        private boolean isNumber(String str) {
+            return str.matches("\\d+");
+        }
+    }
+
+    /**
+     * Compares two ArtifactInfo by their revision. Revisions are compared using an algorithm inspired by PHP
+     * version_compare one, unless a dynamic revision is given, in which case the version matcher is used to perform the
+     * comparison.
+     */
+    final class ArtifactInfoComparator implements Comparator<ArtifactInfo> {
+        public int compare(ArtifactInfo o1, ArtifactInfo o2) {
+            String rev1 = o1.getRevision();
+            String rev2 = o2.getRevision();
+
+            /*
+             * The revisions can still be not resolved, so we use the current version matcher to know if one revision is
+             * dynamic, and in this case if it should be considered greater or lower than the other one. Note that if
+             * the version matcher compare method returns 0, it's because it's not possible to know which revision is
+             * greater. In this case we consider the dynamic one to be greater, because most of the time it will then be
+             * actually resolved and a real comparison will occur.
+             */
+            VersionMatcher vmatcher = IvyContext.getContext().getSettings().getVersionMatcher();
+            ModuleRevisionId mrid1 = ModuleRevisionId.newInstance("", "", rev1);
+            ModuleRevisionId mrid2 = ModuleRevisionId.newInstance("", "", rev2);
+            if (vmatcher.isDynamic(mrid1)) {
+                int c = vmatcher.compare(mrid1, mrid2, mridComparator);
+                return c >= 0 ? 1 : -1;
+            } else if (vmatcher.isDynamic(mrid2)) {
+                int c = vmatcher.compare(mrid2, mrid1, mridComparator);
+                return c >= 0 ? -1 : 1;
+            }
+
+            return mridComparator.compare(mrid1, mrid2);
+        }
+    }
+
+    public static class SpecialMeaning {
+        private String name;
+
+        private Integer value;
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+
+        public Integer getValue() {
+            return value;
+        }
+
+        public void setValue(Integer value) {
+            this.value = value;
+        }
+
+        public void validate() {
+            if (name == null) {
+                throw new IllegalStateException("a special meaning should have a name");
+            }
+            if (value == null) {
+                throw new IllegalStateException("a special meaning should have a value");
+            }
+        }
+    }
+
+    private static final Map<String, Integer> DEFAULT_SPECIAL_MEANINGS;
+    static {
+        DEFAULT_SPECIAL_MEANINGS = new HashMap<String, Integer>();
+        DEFAULT_SPECIAL_MEANINGS.put("dev", new Integer(-1));
+        DEFAULT_SPECIAL_MEANINGS.put("rc", new Integer(1));
+        DEFAULT_SPECIAL_MEANINGS.put("final", new Integer(2));
+    }
+
+    private final Comparator<ModuleRevisionId> mridComparator = new MridComparator();
+
+    private final Comparator<ArtifactInfo> artifactInfoComparator = new ArtifactInfoComparator();
+
+    private Map<String, Integer> specialMeanings = null;
+
+    private boolean usedefaultspecialmeanings = true;
+
+    public OsgiRevisionStrategy() {
+        setComparator(artifactInfoComparator);
+        setName("latest-revision");
+    }
+
+    public void addConfiguredSpecialMeaning(SpecialMeaning meaning) {
+        meaning.validate();
+        getSpecialMeanings().put(meaning.getName().toLowerCase(Locale.US), meaning.getValue());
+    }
+
+    public synchronized Map<String, Integer> getSpecialMeanings() {
+        if (specialMeanings == null) {
+            specialMeanings = new HashMap<String, Integer>();
+            if (isUsedefaultspecialmeanings()) {
+                specialMeanings.putAll(DEFAULT_SPECIAL_MEANINGS);
+            }
+        }
+        return specialMeanings;
+    }
+
+    public boolean isUsedefaultspecialmeanings() {
+        return usedefaultspecialmeanings;
+    }
+
+    public void setUsedefaultspecialmeanings(boolean usedefaultspecialmeanings) {
+        this.usedefaultspecialmeanings = usedefaultspecialmeanings;
+    }
+}

Added: ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/ivy/internal/FilePackageScanner.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/ivy/internal/FilePackageScanner.java?rev=1036848&view=auto
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/ivy/internal/FilePackageScanner.java (added)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/ivy/internal/FilePackageScanner.java Fri Nov 19 14:06:06 2010
@@ -0,0 +1,86 @@
+/*
+ *  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.ivy.osgi.ivy.internal;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ivy.core.cache.DefaultRepositoryCacheManager;
+import org.apache.ivy.plugins.repository.file.FileResource;
+import org.apache.ivy.plugins.resolver.ResolverSettings;
+import org.apache.ivy.util.Message;
+
+public class FilePackageScanner {
+
+    private final Map<String, Collection<File>> patternFiles = new HashMap<String, Collection<File>>();
+
+    private final boolean useFileCache = false;
+
+    public void scanAllPackageExportHeaders(List<String> ivyPatterns, ResolverSettings settings) {
+        final DefaultRepositoryCacheManager cacheManager = (DefaultRepositoryCacheManager) settings.getDefaultRepositoryCacheManager();
+
+        for (String ivyPattern : ivyPatterns) {
+            Collection<File> fileList = null;
+            if ((fileList = patternFiles.get(ivyPattern)) == null || !useFileCache) {
+                patternFiles.put(ivyPattern, (fileList = new ArrayList<File>()));
+                final File rootDir = new File(ivyPattern.split("\\[[\\w]+\\]")[0]);
+                scanDir(rootDir, fileList);
+            }
+
+            for (File currFile : fileList) {
+                try {
+                    PackageRegistry.getInstance().processExports(cacheManager.getBasedir(), new FileResource(null, currFile));
+                } catch (IOException e) {
+                    Message.error("Failed to process exports for file: " + currFile);
+                }
+            }
+        }
+    }
+
+    protected void scanDir(File currFile, Collection<File> fileList) {
+        if (!currFile.canRead()) {
+            return;
+        }
+
+        if (currFile.isDirectory()) {
+            List<File> files = new ArrayList<File>();
+            for (File file : currFile.listFiles()) {
+                files.add(file);
+                //pre-process to check if we have recursed into an exploded bundle
+                if(file.getPath().endsWith("META-INF")) {
+                    fileList.add(new File(file, "MANIFEST.MF"));
+                    return;
+                }
+            }
+            //continue scanning...
+            for(File file : files) {
+                scanDir(file, fileList);
+            }
+        } else if (currFile.isFile()) {
+            final String path = currFile.getPath();
+            if (path.toUpperCase().endsWith("META-INF/MANIFEST.MF") || path.toUpperCase().endsWith(".JAR")) {
+                fileList.add(currFile);
+            }
+        }
+    }
+}



Mime
View raw message