Latest bnd code
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1355520 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundleplugin/src/main/java/aQute/lib/collections/ExtList.java b/bundleplugin/src/main/java/aQute/lib/collections/ExtList.java
index 40c80ca..4943d92 100644
--- a/bundleplugin/src/main/java/aQute/lib/collections/ExtList.java
+++ b/bundleplugin/src/main/java/aQute/lib/collections/ExtList.java
@@ -12,6 +12,22 @@
}
}
+ public ExtList(int size) {
+ super(size);
+ }
+
+ public static ExtList<String> from(String s) {
+ // TODO make sure no \ before comma
+ return from(s, "\\s*,\\s*");
+ }
+ public static ExtList<String> from(String s, String delimeter) {
+ ExtList<String> result = new ExtList<String>();
+ String[] parts = s.split(delimeter);
+ for (String p : parts)
+ result.add(p);
+ return result;
+ }
+
public String join() {
return join(",");
}
diff --git a/bundleplugin/src/main/java/aQute/lib/converter/Converter.java b/bundleplugin/src/main/java/aQute/lib/converter/Converter.java
index f22f840..621b558 100644
--- a/bundleplugin/src/main/java/aQute/lib/converter/Converter.java
+++ b/bundleplugin/src/main/java/aQute/lib/converter/Converter.java
@@ -32,14 +32,18 @@
}
public <T> T convert(TypeReference<T> type, Object o) throws Exception {
- return (T) convert( type.getType(), o);
+ return (T) convert(type.getType(), o);
}
-
- public Object convert(Type type, Object o) throws Exception {
- if (o == null)
- return null; // compatible with any
-
+ public Object convert(Type type, Object o) throws Exception {
+ Class resultType = getRawClass(type);
+ if (o == null) {
+ if (resultType.isPrimitive()|| Number.class.isAssignableFrom(resultType))
+ return convert(type,0);
+
+ return null; // compatible with any
+ }
+
Hook hook = hooks.get(type);
if (hook != null) {
Object value = hook.convert(type, o);
@@ -47,7 +51,6 @@
return value;
}
- Class resultType = getRawClass(type);
Class< ? > actualType = o.getClass();
// We can always make a string
@@ -111,6 +114,10 @@
if (resultType.isAssignableFrom(o.getClass()))
return o;
+ if (Map.class.isAssignableFrom(actualType) && resultType.isInterface()) {
+ return proxy(resultType, (Map) o);
+ }
+
// Simple type coercion
if (resultType == boolean.class || resultType == Boolean.class) {
@@ -243,6 +250,8 @@
return error("No conversion found for " + o.getClass() + " to " + type);
}
+
+
private Number number(Object o) {
if (o instanceof Number)
return (Number) o;
@@ -311,8 +320,9 @@
result = new TreeMap();
else if (rawClass.isAssignableFrom(ConcurrentHashMap.class))
result = new ConcurrentHashMap();
- else
+ else {
return (Map) error("Cannot find suitable map for map interface " + rawClass);
+ }
} else
result = rawClass.newInstance();
@@ -421,4 +431,44 @@
this.hooks.put(type, hook);
return this;
}
+
+ /**
+ * Convert a map to an interface.
+ *
+ * @param interfc
+ * @param properties
+ * @return
+ */
+ public <T> T proxy(Class<T> interfc, final Map< ? , ? > properties) {
+ return (T) Proxy.newProxyInstance(interfc.getClassLoader(), new Class[] {
+ interfc
+ }, new InvocationHandler() {
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ Object o = properties.get(method.getName());
+ if ( o == null)
+ o = properties.get(mangleMethodName(method.getName()));
+
+ return convert( method.getGenericReturnType(), o);
+ }
+
+ });
+ }
+
+ public static String mangleMethodName(String id) {
+ StringBuilder sb = new StringBuilder(id);
+ for (int i = 0; i < sb.length(); i++) {
+ char c = sb.charAt(i);
+ boolean twice = i < sb.length() - 1 && sb.charAt(i + 1) == c;
+ if (c == '$' || c == '_') {
+ if (twice)
+ sb.deleteCharAt(i + 1);
+ else if (c == '$')
+ sb.deleteCharAt(i--); // Remove dollars
+ else
+ sb.setCharAt(i, '.'); // Make _ into .
+ }
+ }
+ return sb.toString();
+ }
}
diff --git a/bundleplugin/src/main/java/aQute/lib/converter/TypeReference.java b/bundleplugin/src/main/java/aQute/lib/converter/TypeReference.java
index 2b52308..3271227 100644
--- a/bundleplugin/src/main/java/aQute/lib/converter/TypeReference.java
+++ b/bundleplugin/src/main/java/aQute/lib/converter/TypeReference.java
@@ -4,6 +4,9 @@
public class TypeReference<T> implements Type {
+ protected TypeReference() {
+ // Make sure it cannot be directly instantiated
+ }
public Type getType() {
return ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
diff --git a/bundleplugin/src/main/java/aQute/lib/deployer/FileInstallRepo.java b/bundleplugin/src/main/java/aQute/lib/deployer/FileInstallRepo.java
index 4d0f5b9..9b01ff7 100644
--- a/bundleplugin/src/main/java/aQute/lib/deployer/FileInstallRepo.java
+++ b/bundleplugin/src/main/java/aQute/lib/deployer/FileInstallRepo.java
@@ -7,8 +7,8 @@
import aQute.lib.osgi.*;
import aQute.libg.header.*;
-import aQute.libg.reporter.*;
import aQute.libg.version.*;
+import aQute.service.reporter.*;
public class FileInstallRepo extends FileRepo {
diff --git a/bundleplugin/src/main/java/aQute/lib/deployer/FileRepo.java b/bundleplugin/src/main/java/aQute/lib/deployer/FileRepo.java
index 4be5ec8..3703b8b 100644
--- a/bundleplugin/src/main/java/aQute/lib/deployer/FileRepo.java
+++ b/bundleplugin/src/main/java/aQute/lib/deployer/FileRepo.java
@@ -9,8 +9,8 @@
import aQute.lib.io.*;
import aQute.lib.osgi.*;
import aQute.libg.header.*;
-import aQute.libg.reporter.*;
import aQute.libg.version.*;
+import aQute.service.reporter.*;
public class FileRepo implements Plugin, RepositoryPlugin, Refreshable, RegistryPlugin {
public final static String LOCATION = "location";
@@ -157,10 +157,10 @@
reporter.trace("updating %s ", file.getAbsolutePath());
if (!file.exists() || file.lastModified() < jar.lastModified()) {
jar.write(file);
- reporter.progress("updated " + file.getAbsolutePath());
+ reporter.progress(-1, "updated " + file.getAbsolutePath());
fireBundleAdded(jar, file);
} else {
- reporter.progress("Did not update " + jar + " because repo has a newer version");
+ reporter.progress(-1, "Did not update " + jar + " because repo has a newer version");
reporter.trace("NOT Updating " + fName + " (repo is newer)");
}
diff --git a/bundleplugin/src/main/java/aQute/lib/getopt/CommandLine.java b/bundleplugin/src/main/java/aQute/lib/getopt/CommandLine.java
index c36727f..e1b7560 100644
--- a/bundleplugin/src/main/java/aQute/lib/getopt/CommandLine.java
+++ b/bundleplugin/src/main/java/aQute/lib/getopt/CommandLine.java
@@ -9,6 +9,7 @@
import aQute.lib.justif.*;
import aQute.libg.generics.*;
import aQute.libg.reporter.*;
+import aQute.service.reporter.*;
/**
* Helps parsing command lines. This class takes target object, a primary
@@ -101,7 +102,7 @@
// Handle vararg
- if (pattern.equals("...")) {
+ if (pattern.contains("...")) {
i = Integer.MAX_VALUE;
break;
}
diff --git a/bundleplugin/src/main/java/aQute/lib/getopt/CommandLineMessages.java b/bundleplugin/src/main/java/aQute/lib/getopt/CommandLineMessages.java
index afeb0b9..4f2cce3 100644
--- a/bundleplugin/src/main/java/aQute/lib/getopt/CommandLineMessages.java
+++ b/bundleplugin/src/main/java/aQute/lib/getopt/CommandLineMessages.java
@@ -1,19 +1,3 @@
-/*
- * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
- *
- * 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 aQute.lib.getopt;
import java.util.*;
diff --git a/bundleplugin/src/main/java/aQute/lib/json/JSONCodec.java b/bundleplugin/src/main/java/aQute/lib/json/JSONCodec.java
index 032f08f..8e608f8 100644
--- a/bundleplugin/src/main/java/aQute/lib/json/JSONCodec.java
+++ b/bundleplugin/src/main/java/aQute/lib/json/JSONCodec.java
@@ -190,6 +190,8 @@
h = new CollectionHandler(rawClass, pt.getActualTypeArguments()[0]);
else if (Map.class.isAssignableFrom(rawClass))
h = new MapHandler(rawClass, pt.getActualTypeArguments()[0], pt.getActualTypeArguments()[1]);
+ else if (Dictionary.class.isAssignableFrom(rawClass))
+ h = new MapHandler(Hashtable.class, pt.getActualTypeArguments()[0], pt.getActualTypeArguments()[1]);
else
throw new IllegalArgumentException("Found a parameterized type that is not a map or collection");
}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/MapHandler.java b/bundleplugin/src/main/java/aQute/lib/json/MapHandler.java
index 349737a..62bf07f 100644
--- a/bundleplugin/src/main/java/aQute/lib/json/MapHandler.java
+++ b/bundleplugin/src/main/java/aQute/lib/json/MapHandler.java
@@ -21,6 +21,8 @@
rawClass = Hashtable.class;
else if (rawClass.isAssignableFrom(LinkedHashMap.class))
rawClass = LinkedHashMap.class;
+ else if (rawClass.isAssignableFrom(Dictionary.class))
+ rawClass = Hashtable.class;
else
throw new IllegalArgumentException("Unknown map interface: " + rawClass);
}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/AnalyzerMessages.java b/bundleplugin/src/main/java/aQute/lib/osgi/AnalyzerMessages.java
index 3efea0a..a91a0f0 100644
--- a/bundleplugin/src/main/java/aQute/lib/osgi/AnalyzerMessages.java
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/AnalyzerMessages.java
@@ -1,19 +1,3 @@
-/*
- * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
- *
- * 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 aQute.lib.osgi;
import aQute.libg.reporter.*;
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Builder.java b/bundleplugin/src/main/java/aQute/lib/osgi/Builder.java
index f49d6e3..b31be5c 100755
--- a/bundleplugin/src/main/java/aQute/lib/osgi/Builder.java
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Builder.java
@@ -117,7 +117,6 @@
dot.setName(getBsn());
sign(dot);
- doDigests(dot);
doSaveManifest(dot);
doDiff(dot); // check if need to diff this bundle
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/CombinedResource.java b/bundleplugin/src/main/java/aQute/lib/osgi/CombinedResource.java
index d76b695..3886c48 100644
--- a/bundleplugin/src/main/java/aQute/lib/osgi/CombinedResource.java
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/CombinedResource.java
@@ -1,19 +1,3 @@
-/*
- * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
- *
- * 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 aQute.lib.osgi;
import java.io.*;
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/CommandResource.java b/bundleplugin/src/main/java/aQute/lib/osgi/CommandResource.java
index eefc1e2..47ba4ac 100644
--- a/bundleplugin/src/main/java/aQute/lib/osgi/CommandResource.java
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/CommandResource.java
@@ -1,19 +1,3 @@
-/*
- * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
- *
- * 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 aQute.lib.osgi;
import java.io.*;
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Domain.java b/bundleplugin/src/main/java/aQute/lib/osgi/Domain.java
index f520378..e705534 100644
--- a/bundleplugin/src/main/java/aQute/lib/osgi/Domain.java
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Domain.java
@@ -6,8 +6,8 @@
import java.util.jar.*;
import aQute.libg.header.*;
-import aQute.libg.reporter.*;
import aQute.libg.version.*;
+import aQute.service.reporter.*;
/**
* This class abstracts domains that have properties holding OSGi meta data. It
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Jar.java b/bundleplugin/src/main/java/aQute/lib/osgi/Jar.java
index 76a4b0d..725b065 100755
--- a/bundleplugin/src/main/java/aQute/lib/osgi/Jar.java
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Jar.java
@@ -11,7 +11,7 @@
import aQute.lib.base64.*;
import aQute.lib.io.*;
-import aQute.libg.reporter.*;
+import aQute.service.reporter.*;
public class Jar implements Closeable {
public enum Compression {
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Processor.java b/bundleplugin/src/main/java/aQute/lib/osgi/Processor.java
index 608e9a0..c6b5dd9 100755
--- a/bundleplugin/src/main/java/aQute/lib/osgi/Processor.java
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Processor.java
@@ -13,7 +13,7 @@
import aQute.lib.io.*;
import aQute.libg.generics.*;
import aQute.libg.header.*;
-import aQute.libg.reporter.*;
+import aQute.service.reporter.*;
public class Processor extends Domain implements Reporter, Registry, Constants, Closeable {
@@ -113,41 +113,64 @@
return p;
}
- public void warning(String string, Object... args) {
+ public SetLocation warning(String string, Object... args) {
Processor p = current();
String s = formatArrays(string, args);
if (!p.warnings.contains(s))
p.warnings.add(s);
p.signal();
+ return location(s);
}
- public void error(String string, Object... args) {
+ public SetLocation error(String string, Object... args) {
Processor p = current();
- if (p.isFailOk())
- p.warning(string, args);
- else {
- String s = formatArrays(string, args == null ? new Object[0] : args);
- if (!p.errors.contains(s))
- p.errors.add(s);
+ try {
+ if (p.isFailOk())
+ return p.warning(string, args);
+ else {
+ String s = formatArrays(string, args == null ? new Object[0] : args);
+ if (!p.errors.contains(s))
+ p.errors.add(s);
+ return location(s);
+ }
}
- p.signal();
+ finally {
+ p.signal();
+ }
}
- public void error(String string, Throwable t, Object... args) {
+ public void progress(float progress, String format, Object... args) {
+ format = String.format("[%2d] %s", (int)progress, format);
+ trace(format, args);
+ }
+
+ public void progress(String format, Object... args) {
+ progress(-1f, format, args);
+ }
+
+ public SetLocation exception(Throwable t, String format, Object... args) {
+ return error(format, t, args);
+ }
+
+ public SetLocation error(String string, Throwable t, Object... args) {
Processor p = current();
-
- if (p.isFailOk())
- p.warning(string + ": " + t, args);
- else {
- p.errors.add("Exception: " + t.getMessage());
- String s = formatArrays(string, args == null ? new Object[0] : args);
- if (!p.errors.contains(s))
- p.errors.add(s);
+ try {
+ if (p.exceptions)
+ t.printStackTrace();
+ if (p.isFailOk()) {
+ return p.warning(string + ": " + t, args);
+ }
+ else {
+ p.errors.add("Exception: " + t.getMessage());
+ String s = formatArrays(string, args == null ? new Object[0] : args);
+ if (!p.errors.contains(s))
+ p.errors.add(s);
+ return location(s);
+ }
}
- if (p.exceptions)
- t.printStackTrace();
-
- p.signal();
+ finally {
+ p.signal();
+ }
}
public void signal() {}
@@ -184,10 +207,6 @@
toBeClosed.remove(jar);
}
- public void progress(String s, Object... args) {
- trace(s, args);
- }
-
public boolean isPedantic() {
return current().pedantic;
}
@@ -1584,4 +1603,64 @@
return s + newExtension;
}
+
+ /**
+ * Create a location object and add it to the locations
+ *
+ * @param s
+ * @return
+ */
+ List<Location> locations = new ArrayList<Location>();
+
+ static class SetLocationImpl extends Location implements SetLocation {
+ public SetLocationImpl(String s) {
+ this.message = s;
+ }
+
+ public SetLocation file(String file) {
+ this.file = file;
+ return this;
+ }
+
+ public SetLocation header(String header) {
+ this.header = header;
+ return this;
+ }
+
+ public SetLocation context(String context) {
+ this.context = context;
+ return this;
+ }
+
+ public SetLocation method(String methodName) {
+ this.methodName = methodName;
+ return this;
+ }
+
+ public SetLocation line(int n) {
+ this.line = n;
+ return this;
+ }
+
+ public SetLocation reference(String reference) {
+ this.reference = reference;
+ return this;
+ }
+
+ }
+
+ private SetLocation location(String s) {
+ SetLocationImpl loc = new SetLocationImpl(s);
+ locations.add(loc);
+ return loc;
+ }
+
+ public Location getLocation(String msg) {
+ for (Location l : locations)
+ if ((l.message != null) && l.message.equals(msg))
+ return l;
+
+ return null;
+ }
+
}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/eclipse/EclipseClasspath.java b/bundleplugin/src/main/java/aQute/lib/osgi/eclipse/EclipseClasspath.java
index cb511e7..c146477 100755
--- a/bundleplugin/src/main/java/aQute/lib/osgi/eclipse/EclipseClasspath.java
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/eclipse/EclipseClasspath.java
@@ -9,7 +9,7 @@
import org.w3c.dom.*;
import org.xml.sax.*;
-import aQute.libg.reporter.*;
+import aQute.service.reporter.*;
/**
* Parse the Eclipse project information for the classpath. Unfortunately, it is
diff --git a/bundleplugin/src/main/java/aQute/lib/properties/CopyOnWriteTextStore.java b/bundleplugin/src/main/java/aQute/lib/properties/CopyOnWriteTextStore.java
index 77bb9f6..179ab25 100644
--- a/bundleplugin/src/main/java/aQute/lib/properties/CopyOnWriteTextStore.java
+++ b/bundleplugin/src/main/java/aQute/lib/properties/CopyOnWriteTextStore.java
@@ -29,7 +29,7 @@
/**
* Create an empty text store.
*/
- private StringTextStore() {
+ StringTextStore() {
super();
}
@@ -39,7 +39,7 @@
* @param text
* the initial content
*/
- private StringTextStore(String text) {
+ StringTextStore(String text) {
super();
set(text);
}
diff --git a/bundleplugin/src/main/java/aQute/lib/properties/PropertiesReader.java b/bundleplugin/src/main/java/aQute/lib/properties/PropertiesReader.java
new file mode 100644
index 0000000..58426af
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/properties/PropertiesReader.java
@@ -0,0 +1,115 @@
+package aQute.lib.properties;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.lib.io.*;
+
+public class PropertiesReader {
+ static Pattern PROPERTY = Pattern.compile("(\\s*#.*$)|(([^\\s]+)\\s*[:=]?\\s*([^#])(#.*)$)|\\s+([^#]*)(#.*)$)",
+ Pattern.MULTILINE);
+
+ public static Properties read(Properties p, File f) throws Exception {
+ return read(p, IO.reader(f));
+ }
+
+ public static Properties read(Properties p, InputStream in, String charset) throws IOException {
+ return read(p, IO.reader(in, charset));
+ }
+
+ public static Properties read(Properties p, InputStream in) throws IOException {
+ return read(p, IO.reader(in));
+ }
+
+ public static Properties read(Properties p, URL in) throws IOException {
+ return read(p, IO.reader(in.openStream()));
+ }
+
+ private static Properties read(Properties p, BufferedReader reader) throws IOException {
+ if (p != null)
+ p = new Properties();
+
+ String line = reader.readLine();
+ String key = null;
+ StringBuilder value = new StringBuilder();
+
+ while (line != null) {
+ Matcher m = PROPERTY.matcher(line);
+ if (m.matches()) {
+
+ if (m.group(1) != null)
+ continue; // comment line
+
+ if (m.group(2) != null) {
+ // header
+ if (key != null) {
+ cleanup(value);
+ p.put(key.toString(), value.toString());
+ key = null;
+ value.delete(0, value.length());
+ }
+ key = m.group(3);
+ value.append(m.group(4));
+ } else {
+ value.append(m.group(6));
+ }
+ } else {
+ System.out.println("Assume empty: " + line);
+ }
+ line = reader.readLine();
+ }
+ if (key != null) {
+ cleanup(value);
+ p.put(key.toString(), value.toString());
+ }
+ return p;
+ }
+
+ private static void cleanup(StringBuilder value) {
+ for (int i = 0; i < value.length(); i++) {
+ if (value.charAt(i) == '\\') {
+ value.deleteCharAt(i);
+ if (i < value.length()) {
+ char c = value.charAt(i);
+ switch (c) {
+ case 't' :
+ value.setCharAt(i, '\t');
+ break;
+ case 'r' :
+ value.setCharAt(i, '\r');
+ break;
+ case 'n' :
+ value.setCharAt(i, '\n');
+ break;
+ case 'f' :
+ value.setCharAt(i, '\f');
+ break;
+ case 'b' :
+ value.setCharAt(i, '\b');
+ break;
+
+ case 'u' :
+ if (i + 5 >= value.length())
+ throw new IllegalArgumentException("Invalid unicode escape " + value.substring(i));
+
+ String n = value.substring(i + 1, i + 5);
+ try {
+ int code = Integer.valueOf(n, 16);
+ value.delete(i + 1, i + 5);
+ value.setCharAt(i, (char) code);
+ }
+ catch (Exception e) {
+ throw new IllegalArgumentException("Invalid unicode escape " + value.substring(i));
+ }
+ break;
+ default :
+ throw new IllegalArgumentException("Invalid escape " + value);
+ }
+ }
+
+ }
+ }
+ }
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/tag/Tag.java b/bundleplugin/src/main/java/aQute/lib/tag/Tag.java
index 03ae971..cf8668e 100755
--- a/bundleplugin/src/main/java/aQute/lib/tag/Tag.java
+++ b/bundleplugin/src/main/java/aQute/lib/tag/Tag.java
@@ -392,7 +392,7 @@
}
String suri = sn == null ? mapping.getAttribute("xmlns") : mapping.getAttribute("xmlns:" + sn);
String turi = tn == null ? child.findRecursiveAttribute("xmlns") : child.findRecursiveAttribute("xmlns:" + tn);
- return turi == suri || (turi != null && suri != null && turi.equals(suri));
+ return ((turi == null) && (suri == null)) || ((turi != null) && turi.equals(suri));
}
public String getString(String path) {