Temporarily include bndlib 1.47 for testing purposes (not yet on central)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1185095 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/ConsumerType.java b/bundleplugin/src/main/java/aQute/bnd/annotation/ConsumerType.java
new file mode 100644
index 0000000..cbbc17b
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/ConsumerType.java
@@ -0,0 +1,14 @@
+package aQute.bnd.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Adding this annotation to a type in an API package indicates the the owner of
+ * that package will not change this interface in a minor update. Any backward
+ * compatible change to this interface requires a major update of the version of
+ * this package.
+ *
+ */
+@Retention(RetentionPolicy.CLASS) @Target(ElementType.TYPE) public @interface ConsumerType {
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/Export.java b/bundleplugin/src/main/java/aQute/bnd/annotation/Export.java
new file mode 100644
index 0000000..27ea389
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/Export.java
@@ -0,0 +1,30 @@
+package aQute.bnd.annotation;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.PACKAGE)
+public @interface Export {
+ String MANDATORY = "mandatory";
+ String OPTIONAL = "optional";
+ String USES = "uses";
+ String EXCLUDE = "exclude";
+ String INCLUDE = "include";
+
+ String[] mandatory() default "";
+
+ String[] optional() default "";
+
+ Class<?>[] exclude() default Object.class;
+
+ Class<?>[] include() default Object.class;
+
+ /**
+ * Use {@link @Version} annotation instead
+ * @return
+ */
+ @Deprecated()
+ String version() default "";
+
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/ProviderType.java b/bundleplugin/src/main/java/aQute/bnd/annotation/ProviderType.java
new file mode 100644
index 0000000..15ee17e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/ProviderType.java
@@ -0,0 +1,19 @@
+package aQute.bnd.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * This type is provided for convenience because it is the default. A change
+ * in a provider type (that is all except Consumer types) can be changed with
+ * only a minor update to the package API version number.
+ *
+ * This interface is similar to the Eclipse @noextend and @noimplement annotations.
+ *
+ *
+ *
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.TYPE)
+public @interface ProviderType {
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/UsePolicy.java b/bundleplugin/src/main/java/aQute/bnd/annotation/UsePolicy.java
new file mode 100644
index 0000000..36f0eaf
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/UsePolicy.java
@@ -0,0 +1,20 @@
+package aQute.bnd.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation can be applied to interface where an implementation should be
+ * treated as a use policy, not an implementation policy. Many package have
+ * interfaces that are very stable and can be maintained backward compatible for
+ * implementers during minor changes. For example, in Event Admin, the
+ * EventAdmin implementers should follow the minor version, e.g. [1.1,1.2), however,
+ * an implementer of EventHandler should not require such a small range. Therefore
+ * an interface like EventHandler should use this anotation.
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.TYPE)
+@Deprecated
+public @interface UsePolicy {
+ String RNAME = "LaQute/bnd/annotation/UsePolicy;";
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/Version.java b/bundleplugin/src/main/java/aQute/bnd/annotation/Version.java
new file mode 100644
index 0000000..fae42b1
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/Version.java
@@ -0,0 +1,9 @@
+package aQute.bnd.annotation;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.PACKAGE})
+public @interface Version {
+ String value();
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/component/Activate.java b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Activate.java
new file mode 100644
index 0000000..52284a0
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Activate.java
@@ -0,0 +1,10 @@
+package aQute.bnd.annotation.component;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.METHOD)
+public @interface Activate {
+ String RNAME = "LaQute/bnd/annotation/component/Activate;";
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/component/Attribute.java b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Attribute.java
new file mode 100644
index 0000000..f089b75
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Attribute.java
@@ -0,0 +1,10 @@
+package aQute.bnd.annotation.component;
+
+public @interface Attribute {
+ class C {}
+
+ String name() default "";
+ String description() default "";
+ String[] options();
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/component/Component.java b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Component.java
new file mode 100644
index 0000000..1fb39d6
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Component.java
@@ -0,0 +1,38 @@
+package aQute.bnd.annotation.component;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS) @Target(ElementType.TYPE) public @interface Component {
+ String RNAME = "LaQute/bnd/annotation/component/Component;";
+ String PROVIDE = "provide";
+ String NAME = "name";
+ String FACTORY = "factory";
+ String SERVICEFACTORY = "servicefactory";
+ String IMMEDIATE = "immediate";
+ String CONFIGURATION_POLICY = "configurationPolicy";
+ String ENABLED = "enabled";
+ String PROPERTIES = "properties";
+ String VERSION = "version";
+ String DESIGNATE = "designate";
+ String DESIGNATE_FACTORY = "designateFactory";
+
+ String name() default "";
+
+ Class<?>[] provide() default Object.class;
+
+ String factory() default "";
+
+ boolean servicefactory() default false;
+
+ boolean enabled() default true;
+
+ boolean immediate() default false;
+
+ ConfigurationPolicy configurationPolicy() default ConfigurationPolicy.optional;
+
+ String[] properties() default {};
+
+ Class<?> designate() default Object.class;
+
+ Class<?> designateFactory() default Object.class;
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/component/ConfigurationPolicy.java b/bundleplugin/src/main/java/aQute/bnd/annotation/component/ConfigurationPolicy.java
new file mode 100644
index 0000000..7651557
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/component/ConfigurationPolicy.java
@@ -0,0 +1,5 @@
+package aQute.bnd.annotation.component;
+
+public enum ConfigurationPolicy {
+ optional, require, ignore;
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/component/Deactivate.java b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Deactivate.java
new file mode 100644
index 0000000..5858ea0
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Deactivate.java
@@ -0,0 +1,10 @@
+package aQute.bnd.annotation.component;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.METHOD)
+public @interface Deactivate {
+ String RNAME = "LaQute/bnd/annotation/component/Deactivate;";
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/component/Modified.java b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Modified.java
new file mode 100644
index 0000000..655a535
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Modified.java
@@ -0,0 +1,10 @@
+package aQute.bnd.annotation.component;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.METHOD)
+public @interface Modified {
+ String RNAME = "LaQute/bnd/annotation/component/Modified;";
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/component/Reference.java b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Reference.java
new file mode 100644
index 0000000..58894dd
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Reference.java
@@ -0,0 +1,33 @@
+package aQute.bnd.annotation.component;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.METHOD)
+public @interface Reference {
+ String RNAME = "LaQute/bnd/annotation/component/Reference;";
+ String NAME = "name";
+ String SERVICE = "service";
+ String OPTIONAL = "optional";
+ String MULTIPLE = "multiple";
+ String DYNAMIC = "dynamic";
+ String TARGET = "target";
+ String TYPE = "type";
+ String UNBIND = "unbind";
+
+ String name() default "";
+
+ Class<?> service() default Object.class;
+
+ boolean optional() default false;
+
+ boolean multiple() default false;
+
+ boolean dynamic() default false;
+
+ String target() default "";
+
+ String unbind() default "";
+
+ char type() default 0;
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/component/packageinfo b/bundleplugin/src/main/java/aQute/bnd/annotation/component/packageinfo
new file mode 100644
index 0000000..ec0efd4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/component/packageinfo
@@ -0,0 +1 @@
+version 1.43.1
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/Configurable.java b/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/Configurable.java
new file mode 100644
index 0000000..6dcf614
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/Configurable.java
@@ -0,0 +1,262 @@
+package aQute.bnd.annotation.metatype;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.regex.*;
+
+public class Configurable<T> {
+
+
+
+
+ public static <T> T createConfigurable(Class<T> c, Map<?, ?> properties) {
+ Object o = Proxy.newProxyInstance(c.getClassLoader(), new Class<?>[] { c },
+ new ConfigurableHandler(properties, c.getClassLoader()));
+ return c.cast(o);
+ }
+
+ public static <T> T createConfigurable(Class<T> c, Dictionary<?, ?> properties) {
+ Map<Object,Object> alt = new HashMap<Object,Object>();
+ for( Enumeration<?> e = properties.keys(); e.hasMoreElements(); ) {
+ Object key = e.nextElement();
+ alt.put(key, properties.get(key));
+ }
+ return createConfigurable(c, alt);
+ }
+
+ static class ConfigurableHandler implements InvocationHandler {
+ final Map<?, ?> properties;
+ final ClassLoader loader;
+
+ ConfigurableHandler(Map<?, ?> properties, ClassLoader loader) {
+ this.properties = properties;
+ this.loader = loader;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ Meta.AD ad = method.getAnnotation(Meta.AD.class);
+ String id = Configurable.mangleMethodName(method.getName());
+
+ if (ad != null && !ad.id().equals(Meta.NULL))
+ id = ad.id();
+
+ Object o = properties.get(id);
+
+ if (o == null) {
+ if (ad != null) {
+ if (ad.required())
+ throw new IllegalStateException("Attribute is required but not set "
+ + method.getName());
+
+ o = ad.deflt();
+ if (o.equals(Meta.NULL))
+ o = null;
+ }
+ }
+ if (o == null) {
+ if (method.getReturnType().isPrimitive()
+ || Number.class.isAssignableFrom(method.getReturnType())) {
+
+ o = "0";
+ } else
+ return null;
+ }
+
+ return convert(method.getGenericReturnType(), o);
+ }
+
+ @SuppressWarnings( { "unchecked" }) public Object convert(Type type, Object o)
+ throws Exception {
+ if (type instanceof ParameterizedType) {
+ ParameterizedType pType = (ParameterizedType) type;
+ return convert(pType, o);
+ }
+
+ if (type instanceof GenericArrayType) {
+ GenericArrayType gType = (GenericArrayType) type;
+ return convertArray(gType.getGenericComponentType(), o);
+ }
+
+ Class<?> resultType = (Class<?>) type;
+
+ if (resultType.isArray()) {
+ return convertArray(resultType.getComponentType(), o);
+ }
+
+ Class<?> actualType = o.getClass();
+ if (actualType.isAssignableFrom(resultType))
+ return o;
+
+ if (resultType == boolean.class || resultType == Boolean.class) {
+ if ( actualType == boolean.class || actualType == Boolean.class)
+ return o;
+
+ if (Number.class.isAssignableFrom(actualType)) {
+ double b = ((Number) o).doubleValue();
+ if (b == 0)
+ return false;
+ else
+ return true;
+ }
+ return true;
+
+ } else if (resultType == byte.class || resultType == Byte.class) {
+ if (Number.class.isAssignableFrom(actualType))
+ return ((Number) o).byteValue();
+ resultType = Byte.class;
+ } else if (resultType == char.class) {
+ resultType = Character.class;
+ } else if (resultType == short.class) {
+ if (Number.class.isAssignableFrom(actualType))
+ return ((Number) o).shortValue();
+ resultType = Short.class;
+ } else if (resultType == int.class) {
+ if (Number.class.isAssignableFrom(actualType))
+ return ((Number) o).intValue();
+ resultType = Integer.class;
+ } else if (resultType == long.class) {
+ if (Number.class.isAssignableFrom(actualType))
+ return ((Number) o).longValue();
+ resultType = Long.class;
+ } else if (resultType == float.class) {
+ if (Number.class.isAssignableFrom(actualType))
+ return ((Number) o).floatValue();
+ resultType = Float.class;
+ } else if (resultType == double.class) {
+ if (Number.class.isAssignableFrom(actualType))
+ return ((Number) o).doubleValue();
+ resultType = Double.class;
+ }
+
+ if (resultType.isPrimitive())
+ throw new IllegalArgumentException("Unknown primitive: " + resultType);
+
+ if (Number.class.isAssignableFrom(resultType) && actualType == Boolean.class) {
+ Boolean b = (Boolean) o;
+ o = b ? "1" : "0";
+ } else if (actualType == String.class) {
+ String input = (String) o;
+ if (Enum.class.isAssignableFrom(resultType)) {
+ return Enum.valueOf((Class<Enum>) resultType, input);
+ }
+ if (resultType == Class.class && loader != null) {
+ return loader.loadClass(input);
+ }
+ if (resultType == Pattern.class) {
+ return Pattern.compile(input);
+ }
+ }
+
+ try {
+ Constructor<?> c = resultType.getConstructor(String.class);
+ return c.newInstance(o.toString());
+ } catch (Throwable t) {
+ // handled on next line
+ }
+ throw new IllegalArgumentException("No conversion to " + resultType + " from "
+ + actualType + " value " + o);
+ }
+
+ private Object convert(ParameterizedType pType, Object o) throws InstantiationException,
+ IllegalAccessException, Exception {
+ Class<?> resultType = (Class<?>) pType.getRawType();
+ if (Collection.class.isAssignableFrom(resultType)) {
+ Collection<?> input = toCollection(o);
+ if (resultType.isInterface()) {
+ if (resultType == Collection.class || resultType == List.class)
+ resultType = ArrayList.class;
+ else if (resultType == Set.class || resultType == SortedSet.class)
+ resultType = TreeSet.class;
+ else if (resultType == Queue.class /*|| resultType == Deque.class*/)
+ resultType = LinkedList.class;
+ else if (resultType == Queue.class /*|| resultType == Deque.class*/)
+ resultType = LinkedList.class;
+ else
+ throw new IllegalArgumentException(
+ "Unknown interface for a collection, no concrete class found: "
+ + resultType);
+ }
+
+ @SuppressWarnings("unchecked") Collection<Object> result = (Collection<Object>) resultType
+ .newInstance();
+ Type componentType = pType.getActualTypeArguments()[0];
+
+ for (Object i : input) {
+ result.add(convert(componentType, i));
+ }
+ return result;
+ } else if (pType.getRawType() == Class.class) {
+ return loader.loadClass(o.toString());
+ }
+ throw new IllegalArgumentException("cannot convert to " + pType
+ + " because it uses generics and is not a Collection");
+ }
+
+ Object convertArray(Type componentType, Object o) throws Exception {
+ Collection<?> input = toCollection(o);
+ Class<?> componentClass = getRawClass(componentType);
+ Object array = Array.newInstance(componentClass, input.size());
+
+ int i = 0;
+ for (Object next : input) {
+ Array.set(array, i++, convert(componentType, next));
+ }
+ return array;
+ }
+
+ private Class<?> getRawClass(Type type) {
+ if (type instanceof Class)
+ return (Class<?>) type;
+
+ if (type instanceof ParameterizedType)
+ return (Class<?>) ((ParameterizedType) type).getRawType();
+
+ throw new IllegalArgumentException(
+ "For the raw type, type must be ParamaterizedType or Class but is " + type);
+ }
+
+ private Collection<?> toCollection(Object o) {
+ if (o instanceof Collection)
+ return (Collection<?>) o;
+
+ if (o.getClass().isArray()) {
+ if ( o.getClass().getComponentType().isPrimitive()) {
+ int length = Array.getLength(o);
+ List<Object> result = new ArrayList<Object>(length);
+ for ( int i=0; i<length; i++) {
+ result.add( Array.get(o, i));
+ }
+ return result;
+ } else
+ return Arrays.asList((Object[]) o);
+ }
+
+ if ( o instanceof String) {
+ String s = (String)o;
+ if (s.indexOf('|')>0)
+ return Arrays.asList(s.split("\\|"));
+ }
+ return Arrays.asList(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/bnd/annotation/metatype/Meta.java b/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/Meta.java
new file mode 100644
index 0000000..a2686e5
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/Meta.java
@@ -0,0 +1,180 @@
+package aQute.bnd.annotation.metatype;
+
+import java.lang.annotation.*;
+
+/**
+ * The Metadata interface provides access to the properties that underly a
+ * Configurable interface. Any Configurable interface can implement this
+ * interface. The interface provides the annotations that can be used to create
+ * metatype objects.
+ *
+ * @ConsumerInterface
+ */
+
+public interface Meta {
+ enum Type {
+ Boolean,
+ Byte,
+ Character,
+ Short,
+ Integer,
+ Long,
+ Float,
+ Double,
+ String,
+ Password
+ }
+
+ /**
+ * Constant NULL for default usage
+ */
+ final String NULL = "§NULL§";
+
+ /**
+ * The OCD Annotation maps to the OCD element in the Metatype specification.
+ * The only difference is that it is possible to create a Designate element
+ * as well.
+ *
+ */
+ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface OCD {
+ /**
+ * The name for this component. The default name is a the short class
+ * name that us un-camel cased to make it more readable.
+ *
+ * @return The name of this component
+ */
+ String name() default NULL;
+
+ /**
+ * The id of the component. Default the name of the class in FQN
+ * notation but with nested classes using the $ as separator (not .).
+ *
+ * The Felix webconsole always uses this id as the PID and not the pid
+ * in the Designate element. Reported as an error.
+ *
+ * @return the id
+ */
+ String id() default NULL;
+
+ /**
+ * The localization prefix. The default localization prefix is the name
+ * of the class with a $ separator for nested classes.
+ *
+ * @return the localization prefix.
+ */
+ String localization() default NULL;
+
+ /**
+ * A description for this ocd. The default is empty.
+ *
+ * @return the description
+ */
+ String description() default NULL;
+
+ /**
+ * Defines if this is for a factory or not.
+ */
+ boolean factory() default false;
+ }
+
+ /**
+ * The AD element in the Metatype specification.
+ *
+ */
+ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @interface AD {
+ /**
+ * A description of the attribute. Default is empty.
+ *
+ * @return The description of the attribute.
+ */
+ String description() default NULL;
+
+ /**
+ * The name of the attribute. By default the un-camel cased version of
+ * the method name.
+ *
+ * @return the name
+ */
+ String name() default NULL;
+
+ /**
+ * The id of the attribute. By default the name of the method. The id is
+ * the key used to access the properties. This is the reason the AD is a
+ * runtime annotation so the runtime can find the proper key.
+ *
+ * @return the id
+ */
+ String id() default NULL;
+
+ /**
+ * The type of the field. This must be one of the basic types in the
+ * metatype specification. By default, the type is derived from the
+ * return type of the method. This includes most collections and arrays.
+ * Unrecognized types are defaulted to String.
+ *
+ * @return the type to be used.
+ */
+ Type type() default Type.String;
+
+ /**
+ * The cardinality of the attribute. If not explicitly set it will be
+ * derived from the attributes return type. Collections return
+ * Integer.MIN_VALUE and arrays use Integer.MAX_VALUE.
+ *
+ * If a single string needs to be converted to a Collection or array
+ * then the | will be used as a separator to split the line.
+ *
+ * @return the cardinality of the attribute
+ */
+ int cardinality() default 0;
+
+ /**
+ * The minimum value. This string must be converted to the attribute
+ * type before comparison takes place.
+ *
+ * @return the min value
+ */
+ String min() default NULL;
+
+ /**
+ * The maximum value. This string must be converted to the attribute
+ * type before comparison takes place.
+ *
+ * @return the max value
+ */
+ String max() default NULL;
+
+ /**
+ * The default value. This value must be converted to the return type of
+ * the attribute. For multi valued returns use the | as separator.
+ *
+ * @return the default value
+ */
+ String deflt() default NULL;
+
+ /**
+ * Indicates that this attribute is required. By default attributes are
+ * required.
+ *
+ * @return
+ */
+ boolean required() default true;
+
+ /**
+ * Provide labels for options. These labels must match the values. If no
+ * labels are set, the un-cameled version of the values are used (if
+ * they are set of course).
+ *
+ * @return the option labels
+ */
+ String[] optionLabels() default NULL;
+
+ /**
+ * The values of options. If not set and the return type is an enum
+ * class then the values will be derived from this return type.
+ *
+ * @return the option labels
+ */
+ String[] optionValues() default NULL;
+ }
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/packageinfo b/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/packageinfo
new file mode 100644
index 0000000..ec0efd4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/packageinfo
@@ -0,0 +1 @@
+version 1.43.1
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/packageinfo b/bundleplugin/src/main/java/aQute/bnd/annotation/packageinfo
new file mode 100644
index 0000000..ec0efd4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/packageinfo
@@ -0,0 +1 @@
+version 1.43.1