You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pd...@apache.org on 2014/04/13 19:23:52 UTC
svn commit: r1587054 [3/3] - in
/felix/sandbox/pderop/dependencymanager-prototype/dm.annotations: ./
.settings/ generated/ src/ src/dm/ src/dm/annotation/
src/dm/annotation/api/ src/dm/annotation/plugin/
src/dm/annotation/plugin/bnd/
Added: felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/BndLogger.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/BndLogger.java?rev=1587054&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/BndLogger.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/BndLogger.java Sun Apr 13 17:23:51 2014
@@ -0,0 +1,199 @@
+/*
+ * 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 dm.annotation.plugin.bnd;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import aQute.service.reporter.Reporter;
+
+/**
+ * Clas used to log messages into the bnd logger.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class BndLogger extends Logger {
+ private final Reporter m_reporter;
+
+ /**
+ * Writer to log file, in tmp dir/dmplugin-BSN.log
+ */
+ private final PrintWriter logWriter;
+
+ /**
+ * DateFormat used when logging.
+ */
+ private final static SimpleDateFormat dateFormat = new SimpleDateFormat("E yyyy.MM.dd hh:mm:ss.S");
+
+ /**
+ * Enabled log level, which can be configured in bnd plugin declaration.
+ */
+ private Level logEnabled = Level.Warn;
+
+ /**
+ * Creates a new bnd Log implementaiton
+ *
+ * @param reporter
+ * the bnd logger
+ * @param logLevel
+ * @param bsn
+ */
+ public BndLogger(Reporter reporter, String bsn) {
+ m_reporter = reporter;
+ File logFilePath = new File(System.getProperty("java.io.tmpdir") + File.separator + "dmplugin"
+ + File.separator + bsn + ".log");
+ new File(logFilePath.getParent()).mkdirs();
+
+ PrintWriter writer = null;
+ try {
+ writer = new PrintWriter(new FileWriter(logFilePath, false));
+ }
+ catch (IOException e) {
+ reporter.exception(e, "Could not create scrplugin log file: %s", logFilePath);
+ writer = null;
+ }
+ this.logWriter = writer;
+ }
+
+ /**
+ * Close log file.
+ */
+ public void close() {
+ if (logWriter != null) {
+ logWriter.close();
+ }
+ }
+
+ /**
+ * Sets the enabled log level.
+ *
+ * @param level
+ * the enabled level ("Error", "Warn", "Info", or "Debug")
+ */
+ public void setLevel(String level) {
+ try {
+ level = Character.toUpperCase(level.charAt(0))
+ + level.substring(1).toLowerCase();
+ this.logEnabled = Level.valueOf(level);
+ } catch (IllegalArgumentException e) {
+ this.logEnabled = Level.Warn;
+ warn("Bnd scrplugin logger initialized with invalid log level: "
+ + level);
+ }
+ }
+
+ // Reporter
+
+ public boolean isDebugEnabled() {
+ return logEnabled.ordinal() >= Level.Debug.ordinal();
+ }
+
+ public void debug(String content, Object ... args) {
+ if (isDebugEnabled()) {
+ m_reporter.trace(content, args);
+ logDebug(String.format(content, args), null);
+ }
+ }
+
+ public boolean isInfoEnabled() {
+ return logEnabled.ordinal() >= Level.Info.ordinal();
+ }
+
+ public void info(String content, Object ... args) {
+ if (isInfoEnabled()) {
+ m_reporter.trace(content, args);
+ logInfo(String.format(content, args), null);
+ }
+ }
+
+ public boolean isWarnEnabled() {
+ return logEnabled.ordinal() >= Level.Warn.ordinal();
+ }
+
+ public void warn(String content, Object ... args) {
+ if (isWarnEnabled()) {
+ m_reporter.warning(content, args);
+ logWarn(String.format(content, args), null);
+ }
+ }
+
+ public void warn(String content, Throwable err, Object ... args) {
+ if (isWarnEnabled()) {
+ m_reporter.warning(content, args);
+ logWarn(String.format(content, args), err);
+ }
+ }
+
+ public boolean isErrorEnabled() {
+ return logEnabled.ordinal() >= Level.Error.ordinal();
+ }
+
+ public void error(String content, Object ... args) {
+ m_reporter.error(content, args);
+ logErr(String.format(content, args), null);
+ }
+
+ public void error(String content, Throwable err, Object ... args) {
+ m_reporter.error(content, args);
+ logErr(String.format(content, args), err);
+ }
+
+ private void logErr(String msg, Throwable t) {
+ log(Level.Error, msg, t);
+ }
+
+ private void logWarn(String msg, Throwable t) {
+ log(Level.Warn, msg, t);
+ }
+
+ private void logInfo(String msg, Throwable t) {
+ log(Level.Info, msg, t);
+ }
+
+ private void logDebug(String msg, Throwable t) {
+ log(Level.Debug, msg, t);
+ }
+
+ private void log(Level level, String msg, Throwable t) {
+ if (logWriter != null) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(dateFormat.format(new Date()));
+ sb.append(" - ");
+ sb.append(level);
+ sb.append(": ");
+ sb.append(msg);
+ if (t != null) {
+ sb.append(" - ").append(toString(t));
+ }
+ logWriter.println(sb.toString());
+ }
+ }
+
+ private static String toString(Throwable e) {
+ StringWriter buffer = new StringWriter();
+ PrintWriter pw = new PrintWriter(buffer);
+ e.printStackTrace(pw);
+ return (buffer.toString());
+ }
+}
Added: felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/DescriptorGenerator.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/DescriptorGenerator.java?rev=1587054&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/DescriptorGenerator.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/DescriptorGenerator.java Sun Apr 13 17:23:51 2014
@@ -0,0 +1,216 @@
+/*
+ * 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 dm.annotation.plugin.bnd;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import aQute.bnd.osgi.Analyzer;
+import aQute.bnd.osgi.Clazz;
+import aQute.bnd.osgi.EmbeddedResource;
+import aQute.bnd.osgi.Resource;
+import aQute.bnd.osgi.Clazz.QUERY;
+
+/**
+ * This helper parses all classes which contain DM annotations, and generates the corresponding component descriptors.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class DescriptorGenerator
+{
+ /**
+ * This is the bnd analyzer used to lookup classes containing DM annotations.
+ */
+ private Analyzer m_analyzer;
+
+ /**
+ * This is the generated Dependency Manager descriptors. The hashtable key is the path
+ * to a descriptor. The value is a bnd Resource object which contains the content of a
+ * descriptor.
+ */
+ Map<String, Resource> m_resources = new HashMap<String, Resource>();
+
+ /**
+ * This is the generated MetaType XML descriptor, if any Properties/Property annotations have been found.
+ */
+ private Resource m_metaTypeResource;
+
+ /**
+ * Object used to collect logs.
+ */
+ private final Logger m_logger;
+
+ /**
+ * List of imported services found from every ServiceDependency annotations.
+ */
+ private Set<String> m_importService = new HashSet<String>();
+
+ /**
+ * List of exported services found from every service providing components.
+ */
+ private Set<String> m_exportService = new HashSet<String>();
+
+ /**
+ * Creates a new descriptor generator.
+ * @param analyzer The bnd analyzer used to lookup classes containing DM annotations.
+ * @param debug
+ */
+ public DescriptorGenerator(Analyzer analyzer, Logger logger)
+ {
+ m_analyzer = analyzer;
+ m_logger = logger;
+ }
+
+ /**
+ * Starts the scanning.
+ * @return true if some annotations were successfully parsed, false if not. corresponding generated
+ * descriptors can then be retrieved by invoking the getDescriptors/getDescriptorPaths methods.
+ */
+ public boolean execute() throws Exception
+ {
+ boolean annotationsFound = false;
+ // Try to locate any classes in the wildcarded universe
+ // that are annotated with the DependencyManager "Service" annotations.
+ Collection<Clazz> expanded = m_analyzer.getClasses("",
+ // Parse everything
+ QUERY.NAMED.toString(), "*");
+
+ // Create the object which will collect Config Admin MetaTypes.
+ MetaType metaType = new MetaType();
+
+ for (Clazz c : expanded)
+ {
+ // Let's parse all annotations from that class !
+ AnnotationCollector reader = new AnnotationCollector(m_logger, metaType);
+ c.parseClassFileWithCollector(reader);
+ if (reader.finish())
+ {
+ // And store the generated component descriptors in our resource list.
+ String name = c.getFQN();
+ Resource resource = createComponentResource(reader);
+ m_resources.put("META-INF/dependencymanager/" + name, resource);
+ annotationsFound = true;
+
+ m_importService.addAll(reader.getImportService());
+ m_exportService.addAll(reader.getExportService());
+ }
+ }
+
+ // If some Meta Types have been parsed, then creates the corresponding resource file.
+ if (metaType.getSize() > 0)
+ {
+ m_metaTypeResource = createMetaTypeResource(metaType);
+ }
+ return annotationsFound;
+ }
+
+ /**
+ * Returns the path of the descriptor.
+ * @return the path of the generated descriptors.
+ */
+ public String getDescriptorPaths()
+ {
+ StringBuilder descriptorPaths = new StringBuilder();
+ String del = "";
+ for (Map.Entry<String, Resource> entry : m_resources.entrySet())
+ {
+ descriptorPaths.append(del);
+ descriptorPaths.append(entry.getKey());
+ del = ",";
+ }
+ return descriptorPaths.toString();
+ }
+
+ /**
+ * Returns the list of the generated descriptors.
+ * @return the list of the generated descriptors.
+ */
+ public Map<String, Resource> getDescriptors()
+ {
+ return m_resources;
+ }
+
+ /**
+ * Returns the MetaType resource.
+ */
+ public Resource getMetaTypeResource() {
+ return m_metaTypeResource;
+ }
+
+ /**
+ * Returns set of all imported services. Imported services are deduced from every
+ * @ServiceDependency annotations.
+ * @return the list of imported services
+ */
+ public Set<String> getImportService()
+ {
+ return m_importService;
+ }
+
+ /**
+ * Returns set of all exported services. Imported services are deduced from every
+ * annotations which provides a service (@Component, etc ...)
+ * @return the list of exported services
+ */
+ public Set<String> getExportService()
+ {
+ return m_exportService;
+ }
+
+ /**
+ * Creates a bnd resource that contains the generated dm descriptor.
+ * @param collector
+ * @return
+ * @throws IOException
+ */
+ private Resource createComponentResource(AnnotationCollector collector) throws IOException
+ {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(out, "UTF-8"));
+ collector.writeTo(pw);
+ pw.close();
+ byte[] data = out.toByteArray();
+ out.close();
+ return new EmbeddedResource(data, 0);
+ }
+
+ /**
+ * Creates a bnd resource that contains the generated metatype descriptor.
+ * @param metaType the Object that has collected all meta type informations.
+ * @return the meta type resource
+ * @throws IOException on any errors
+ */
+ private Resource createMetaTypeResource(MetaType metaType) throws IOException
+ {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(out, "UTF-8"));
+ metaType.writeTo(pw);
+ pw.close();
+ byte[] data = out.toByteArray();
+ out.close();
+ return new EmbeddedResource(data, 0);
+ }
+}
\ No newline at end of file
Added: felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/EntryParam.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/EntryParam.java?rev=1587054&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/EntryParam.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/EntryParam.java Sun Apr 13 17:23:51 2014
@@ -0,0 +1,66 @@
+/*
+ * 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 dm.annotation.plugin.bnd;
+
+/**
+ * The type of parameters which can be found in a component descriptor.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public enum EntryParam
+{
+ init,
+ start,
+ stop,
+ destroy,
+ impl,
+ provides,
+ properties,
+ composition,
+ service,
+ filter,
+ defaultImpl,
+ required,
+ added,
+ changed,
+ removed,
+ swap,
+ autoConfig,
+ pid,
+ factoryPid,
+ propagate,
+ updated,
+ timeout,
+ adapteeService,
+ adapteeFilter,
+ stateMask,
+ ranking,
+ factorySet,
+ factoryConfigure,
+ factoryMethod,
+ field,
+ name,
+ starter,
+ stopper,
+ bundleContextField,
+ dependencyManagerField,
+ componentField,
+ registered,
+ unregistered
+}
Added: felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/EntryType.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/EntryType.java?rev=1587054&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/EntryType.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/EntryType.java Sun Apr 13 17:23:51 2014
@@ -0,0 +1,38 @@
+/*
+ * 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 dm.annotation.plugin.bnd;
+
+/**
+ * The type of each entry (lines) stored in a component descriptor.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public enum EntryType
+{
+ Component,
+ AspectService,
+ AdapterService,
+ BundleAdapterService,
+ ResourceAdapterService,
+ FactoryConfigurationAdapterService,
+ ServiceDependency,
+ ConfigurationDependency,
+ BundleDependency,
+ ResourceDependency,
+}
Added: felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/EntryWriter.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/EntryWriter.java?rev=1587054&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/EntryWriter.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/EntryWriter.java Sun Apr 13 17:23:51 2014
@@ -0,0 +1,253 @@
+/*
+ * 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 dm.annotation.plugin.bnd;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import aQute.bnd.osgi.Annotation;
+
+/**
+ * This class encodes a component descriptor entry line, using json.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class EntryWriter
+{
+ // Every descriptor entries contains a type parameter for identifying the kind of entry
+ private final static String TYPE = "type";
+
+ /** All parameters as stored in a json object */
+ private JSONObject m_json;
+
+ /** The entry type */
+ private EntryType m_type;
+
+ /**
+ * Makes a new component descriptor entry.
+ */
+ public EntryWriter(EntryType type)
+ {
+ m_type = type;
+ m_json = new JSONObject();
+ try
+ {
+ m_json.put("type", type.toString());
+ }
+ catch (JSONException e)
+ {
+ throw new RuntimeException("could not initialize json object", e);
+ }
+ }
+
+ /**
+ * Returns this entry type.
+ */
+ EntryType getEntryType()
+ {
+ return m_type;
+ }
+
+ /**
+ * Returns a string representation for the given component descriptor entry.
+ */
+ @Override
+ public String toString()
+ {
+ return m_json.toString();
+ }
+
+ /**
+ * Put a String parameter in this descritor entry.
+ */
+ public void put(EntryParam param, String value)
+ {
+ checkType(param.toString());
+ try
+ {
+ m_json.put(param.toString(), value);
+ }
+ catch (JSONException e)
+ {
+ throw new IllegalArgumentException("could not add param " + param + ":" + value, e);
+ }
+ }
+
+ /**
+ * Put a String[] parameter in this descriptor entry.
+ */
+ public void put(EntryParam param, String[] array)
+ {
+ checkType(param.toString());
+ try
+ {
+ m_json.put(param.toString(), new JSONArray(Arrays.asList(array)));
+ }
+ catch (JSONException e)
+ {
+ throw new IllegalArgumentException("could not add param " + param + ":"
+ + Arrays.toString(array), e);
+ }
+ }
+
+ /**
+ * Puts a json object.
+ * @throws JSONException
+ */
+ public void putJsonObject(EntryParam param, JSONObject jsonObject) throws JSONException
+ {
+ m_json.put(param.toString(), jsonObject);
+ }
+
+ /**
+ * Get a String attribute value from an annotation and write it into this descriptor entry.
+ */
+ public String putString(Annotation annotation, EntryParam param, String def)
+ {
+ checkType(param.toString());
+ Object value = annotation.get(param.toString());
+ if (value == null && def != null)
+ {
+ value = def;
+ }
+ if (value != null)
+ {
+ put(param, value.toString());
+ }
+ return value == null ? null : value.toString();
+ }
+
+ /**
+ * Get a String array attribute value from an annotation and write it into this descriptor entry.
+ */
+ public void putStringArray(Annotation annotation, EntryParam param, String[] def)
+ {
+ checkType(param.toString());
+ Object value = annotation.get(param.toString());
+ if (value == null && def != null)
+ {
+ value = def;
+ }
+ if (value != null)
+ {
+ for (Object v: ((Object[]) value))
+ {
+ try
+ {
+ m_json.append(param.toString(), v.toString());
+ }
+ catch (JSONException e)
+ {
+ throw new IllegalArgumentException("Could not add param " + param + ":"
+ + value.toString(), e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Get a class attribute value from an annotation and write it into this descriptor entry.
+ */
+ public void putClass(Annotation annotation, EntryParam param, Object def)
+ {
+ checkType(param.toString());
+
+ Pattern pattern = Patterns.CLASS;
+ Object value = annotation.get(param.toString());
+ if (value == null && def != null)
+ {
+ value = def;
+ pattern = null;
+ }
+ if (value != null)
+ {
+ if (pattern != null)
+ {
+ value = Patterns.parseClass(value.toString(), pattern, 1);
+ }
+ put(param, value.toString());
+ }
+ }
+
+ /**
+ * Get a class array attribute value from an annotation and write it into this descriptor entry.
+ * Also collect classes found from the array into a given Set.
+ * @return the class array size.
+ */
+ public int putClassArray(Annotation annotation, EntryParam param, Object def, Set<String> collect)
+ {
+ checkType(param.toString());
+
+ Pattern pattern = Patterns.CLASS;
+ Object value = annotation.get(param.toString());
+ if (value == null && def != null)
+ {
+ value = def;
+ pattern = null;
+ }
+ if (value != null)
+ {
+ if (!(value instanceof Object[]))
+ {
+ throw new IllegalArgumentException("annotation parameter " + param
+ + " has not a class array type");
+ }
+
+ for (Object v: ((Object[]) value))
+ {
+ if (pattern != null)
+ {
+ v = Patterns.parseClass(v.toString(), pattern, 1);
+ }
+ try
+ {
+ m_json.append(param.toString(), v.toString());
+ collect.add(v.toString());
+ }
+ catch (JSONException e)
+ {
+ throw new IllegalArgumentException("Could not add param " + param + ":"
+ + value.toString(), e);
+ }
+ }
+
+ return ((Object[]) value).length;
+ }
+
+ return 0;
+ }
+
+ /**
+ * Check if the written key is not equals to "type" ("type" is an internal attribute we are using
+ * in order to identify a kind of descriptor entry (Service, ServiceDependency, etc ...).
+ */
+ private void checkType(String key)
+ {
+ if (TYPE.equals(key))
+ {
+ throw new IllegalArgumentException("\"" + TYPE + "\" parameter can't be overriden");
+ }
+ }
+}
Added: felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/Logger.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/Logger.java?rev=1587054&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/Logger.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/Logger.java Sun Apr 13 17:23:51 2014
@@ -0,0 +1,40 @@
+/*
+ * 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 dm.annotation.plugin.bnd;
+
+/**
+ * Base class for our logger. Under Maven, we log into the Maven logger. Under bnd, we log into the Bnd logger.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public abstract class Logger
+{
+ /**
+ * Log Levels.
+ */
+ enum Level {
+ Error, Warn, Info, Debug
+ }
+
+ public abstract void error(String msg, Object ... args);
+ public abstract void error(String msg, Throwable err, Object ... args);
+ public abstract void warn(String msg , Object ... args);
+ public abstract void info(String msg , Object ... args);
+ public abstract void debug(String msg, Object ... args);
+}
Added: felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/MetaType.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/MetaType.java?rev=1587054&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/MetaType.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/MetaType.java Sun Apr 13 17:23:51 2014
@@ -0,0 +1,326 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package dm.annotation.plugin.bnd;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Helper class used to generate an XML representation of a MetaType data structure.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class MetaType
+{
+ /**
+ * The list of Object Class Definitions used to group the attributes of a given
+ * set of properties.
+ */
+ private List<OCD> m_ocdList = new ArrayList<OCD>();
+
+ /**
+ * The list of Designate elements.
+ */
+ private List<Designate> m_designateList = new ArrayList<Designate>();
+
+ /**
+ * The default localization directory.
+ */
+ private final static String LOCALIZATION = "OSGI-INF/metatype/metatype";
+
+ /**
+ * Adds an Object Class Definition into this meta type.
+ * @param ocd the Object Class Definition.
+ */
+ public void add(OCD ocd)
+ {
+ m_ocdList.add(ocd);
+ }
+
+ /**
+ * Adds a Designate element, which maps a PID to an OCD.
+ * @param designate the Designate element.
+ */
+ public void add(Designate designate)
+ {
+ m_designateList.add(designate);
+ }
+
+ /**
+ * Returns the number of OCD contained in this meta type.
+ * @return the number of OCD contained in this meta type.
+ */
+ public int getSize()
+ {
+ return m_ocdList.size();
+ }
+
+ /**
+ * Generates an XML representation of this metatype.
+ * @param pw a PrintWriter where the XML is written
+ */
+ public void writeTo(PrintWriter pw)
+ {
+ pw.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ pw.println("<metatype:MetaData xmlns:metatype=\"http://www.osgi.org/xmlns/metatype/v1.0.0\" localization=\""
+ + LOCALIZATION + "\">");
+ for (OCD ocd : m_ocdList)
+ {
+ ocd.writeTo(pw);
+ }
+ for (Designate designate : m_designateList)
+ {
+ designate.writeTo(pw);
+ }
+ pw.println("</metatype:MetaData>");
+ }
+
+ private static void writeAttribute(String name, Object value, PrintWriter pw)
+ {
+ if (value != null)
+ {
+ pw.print(" " + name + "=" + "\"" + value.toString() + "\"");
+ }
+ }
+
+ /**
+ * An Object Class Definition, which contains a set of Attributes properies.
+ */
+ public static class OCD
+ {
+ String m_id;
+ String m_name;
+ String m_description;
+ List<AD> m_attributes = new ArrayList<AD>();
+
+ OCD(String pid, String name, String desc)
+ {
+ this.m_id = pid;
+ this.m_name = name;
+ this.m_description = desc;
+ }
+
+ public void add(AD ad)
+ {
+ m_attributes.add(ad);
+ }
+
+ public void writeTo(PrintWriter pw)
+ {
+ pw.print(" <OCD");
+ writeAttribute("id", m_id, pw);
+ writeAttribute("name", m_name, pw);
+ writeAttribute("description", m_description, pw);
+ if (m_attributes.size() == 0)
+ {
+ pw.println("/>");
+ }
+ else
+ {
+ pw.println(">");
+ for (AD ad : m_attributes)
+ {
+ ad.writeTo(pw);
+ }
+ pw.println(" </OCD>");
+ }
+ }
+ }
+
+ /**
+ * An Attribute Definition, which describes a given Properties
+ */
+ @SuppressWarnings("serial")
+ public static class AD
+ {
+ String m_id;
+ String m_type;
+ String m_defaults;
+ String m_name;
+ String m_description;
+ Integer m_cardinality;
+ Boolean m_required;
+ List<Option> m_options = new ArrayList<Option>();
+
+ private final static Map<String, String> _allowedTypes = new HashMap<String, String>()
+ {
+ {
+ put(String.class.getName(), "String");
+ put(Long.class.getName(), "Long");
+ put(Integer.class.getName(), "Integer");
+ put(Character.class.getName(), "Char");
+ put(Byte.class.getName(), "Byte");
+ put(Double.class.getName(), "Double");
+ put(Float.class.getName(), "Float");
+ put(Boolean.class.getName(), "Boolean");
+ }
+ };
+
+ public AD(String id, String type, Object[] defaults, String name, String desc, Integer cardinality, Boolean required)
+ {
+ this.m_id = id;
+ this.m_type = (type == null) ? "String" : getType(type);
+ this.m_name = name;
+ this.m_description = desc;
+ this.m_cardinality = cardinality;
+ this.m_required = required;
+
+ if (defaults != null)
+ {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < defaults.length; i++)
+ {
+ sb.append(defaults[i].toString());
+ if (i < defaults.length - 1)
+ {
+ sb.append(",");
+ }
+ }
+ this.m_defaults = sb.toString();
+
+ // Check if the number of default values is consistent with the cardinality.
+ if (cardinality != null)
+ {
+ int max = (cardinality.intValue() == 0) ? 1 : Math.abs(cardinality.intValue());
+ if (defaults.length > max)
+ {
+ throw new IllegalArgumentException("number of default values ("
+ + defaults.length + ") is inconsistent with cardinality ("
+ + cardinality + ")");
+ }
+ }
+ }
+ }
+
+ public void writeTo(PrintWriter pw)
+ {
+ pw.print(" <AD");
+ writeAttribute("id", m_id, pw);
+ writeAttribute("type", m_type, pw);
+ writeAttribute("default", m_defaults, pw);
+ writeAttribute("name", m_name, pw);
+ writeAttribute("description", m_description, pw);
+ writeAttribute("cardinality", m_cardinality, pw);
+ if (m_options.size() == 0)
+ {
+ pw.println("/>");
+ }
+ else
+ {
+ pw.println(">");
+ for (Option option : m_options)
+ {
+ option.writeTo(pw);
+ }
+ pw.println(" </AD>");
+ }
+ }
+
+ private String getType(String t)
+ {
+ String result = _allowedTypes.get(t);
+ if (result == null)
+ {
+ throw new IllegalArgumentException("Invalid Property type: " + m_type);
+ }
+ return result;
+ }
+
+ public void add(Option option)
+ {
+ m_options.add(option);
+ }
+ }
+
+ /**
+ * An Option datastructure, which can be associated with an Attribute.
+ */
+ public static class Option
+ {
+ String m_value;
+ String m_label;
+
+ Option(String value, String label)
+ {
+ this.m_value = value;
+ this.m_label = label;
+ }
+
+ public void writeTo(PrintWriter pw)
+ {
+ pw.print(" <Option");
+ writeAttribute("value", m_value, pw);
+ writeAttribute("label", m_label, pw);
+ pw.println("/>");
+ }
+ }
+
+ /**
+ * A Designate element, which maps a PID to a given Object Class Definition.
+ */
+ public static class Designate
+ {
+ String m_pid;
+ boolean m_factory;
+ OBject m_object;
+
+ public Designate(String pid, boolean factory)
+ {
+ this.m_pid = pid;
+ this.m_factory = factory;
+ this.m_object = new OBject(pid);
+ }
+
+ public void writeTo(PrintWriter pw)
+ {
+ pw.print(" <Designate");
+ writeAttribute("pid", m_pid, pw);
+ if (m_factory)
+ {
+ writeAttribute("factoryPid", m_pid, pw);
+ }
+ pw.println(">");
+ m_object.writeTo(pw);
+ pw.println(" </Designate>");
+ }
+ }
+
+ /**
+ * A definition of an instance.
+ */
+ public static class OBject
+ {
+ String m_ocdref;
+
+ OBject(String ocdref)
+ {
+ this.m_ocdref = ocdref;
+ }
+
+ public void writeTo(PrintWriter pw)
+ {
+ pw.print(" <Object");
+ writeAttribute("ocdref", m_ocdref, pw);
+ pw.println("/>");
+ }
+ }
+}
Added: felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/Patterns.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/Patterns.java?rev=1587054&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/Patterns.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm.annotations/src/dm/annotation/plugin/bnd/Patterns.java Sun Apr 13 17:23:51 2014
@@ -0,0 +1,108 @@
+/*
+ * 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 dm.annotation.plugin.bnd;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Class containings pattern matching helper methods.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Patterns
+{
+ // Pattern used to check if a method is void and does not take any params
+ public final static Pattern VOID = Pattern.compile("\\(\\)V");
+
+ // Pattern used to check if a method returns an array of Objects
+ public final static Pattern COMPOSITION = Pattern.compile("\\(\\)\\[Ljava/lang/Object;");
+
+ // Pattern used to parse the class parameter from the bind methods ("bind(Type)" or "bind(Map, Type)" or "bind(BundleContext, Type)"
+ public final static Pattern BIND_CLASS = Pattern.compile("\\((L[^;]+;)?L([^;]+);\\)V");
+
+ // Pattern used to parse classes from class descriptors;
+ public final static Pattern CLASS = Pattern.compile("L([^;]+);");
+
+ // Pattern used to parse the field on which a Publisher annotation may be applied on
+ public final static Pattern RUNNABLE = Pattern.compile("Ljava/lang/Runnable;");
+
+ // Pattern used to parse a field whose type is BundleContext
+ public final static Pattern BUNDLE_CONTEXT = Pattern.compile("Lorg/osgi/framework/BundleContext;");
+
+ // Pattern used to parse a field whose type is DependencyManager
+ // TODO change package name
+ public final static Pattern DEPENDENCY_MANAGER = Pattern.compile("Ldm.DependencyManager;");
+
+ // Pattern used to parse a field whose type is Component
+ // TODO change package name
+ public final static Pattern COMPONENT = Pattern.compile("Ldm.Component;");
+
+ /**
+ * Parses a class.
+ * @param clazz the class to be parsed (the package is "/" separated).
+ * @param pattern the pattern used to match the class.
+ * @param group the pattern group index where the class can be retrieved.
+ * @return the parsed class.
+ */
+ public static String parseClass(String clazz, Pattern pattern, int group)
+ {
+ Matcher matcher = pattern.matcher(clazz);
+ if (matcher.matches())
+ {
+ return matcher.group(group).replace("/", ".");
+ }
+ else
+ {
+ throw new IllegalArgumentException("Invalid class descriptor: " + clazz);
+ }
+ }
+
+ /**
+ * Checks if a method descriptor matches a given pattern.
+ * @param the method whose signature descriptor is checked
+ * @param pattern the pattern used to check the method signature descriptor
+ * @throws IllegalArgumentException if the method signature descriptor does not match the given pattern.
+ */
+ public static void parseMethod(String method, String descriptor, Pattern pattern)
+ {
+ Matcher matcher = pattern.matcher(descriptor);
+ if (!matcher.matches())
+ {
+ throw new IllegalArgumentException("Invalid method " + method + ", wrong signature: "
+ + descriptor);
+ }
+ }
+
+ /**
+ * Checks if a field descriptor matches a given pattern.
+ * @param field the field whose type descriptor is checked
+ * @param descriptor the field descriptor to be checked
+ * @param pattern the pattern to use
+ * @throws IllegalArgumentException if the method signature descriptor does not match the given pattern.
+ */
+ public static void parseField(String field, String descriptor, Pattern pattern) {
+ Matcher matcher = pattern.matcher(descriptor);
+ if (!matcher.matches())
+ {
+ throw new IllegalArgumentException("Invalid field " + field + ", wrong signature: "
+ + descriptor);
+ }
+ }
+}