felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pde...@apache.org
Subject 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/
Date Sun, 13 Apr 2014 17:23:52 GMT
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);
+        }
+    }
+}



Mime
View raw message