Author: davidb
Date: Tue Apr  5 12:51:42 2016
New Revision: 1737831

URL: http://svn.apache.org/viewvc?rev=1737831&view=rev
Log:
Very initial version of the Converter Service.

The API comes from OSGi RFC 215 and is ASL-2 licensed. It's included here as 
the API is not yet release by OSGi. 
The implementation of this service is utterly incomplete. This is just a very 
small starting point written by me which can be built out in the Felix codebase.

Added:
    felix/trunk/converter/
    felix/trunk/converter/pom.xml
    felix/trunk/converter/src/
    felix/trunk/converter/src/main/
    felix/trunk/converter/src/main/java/
    felix/trunk/converter/src/main/java/org/
    felix/trunk/converter/src/main/java/org/apache/
    felix/trunk/converter/src/main/java/org/apache/felix/
    felix/trunk/converter/src/main/java/org/apache/felix/converter/
    felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/
    
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/AdapterImpl.java
    
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConverterImpl.java
    
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConvertingImpl.java
    
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/JsonCodecImpl.java
    
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/JsonDecodingImpl.java
    
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/JsonEncodingImpl.java
    felix/trunk/converter/src/main/java/org/osgi/
    felix/trunk/converter/src/main/java/org/osgi/service/
    felix/trunk/converter/src/main/java/org/osgi/service/converter/
    felix/trunk/converter/src/main/java/org/osgi/service/converter/Adapter.java
    felix/trunk/converter/src/main/java/org/osgi/service/converter/Codec.java
    
felix/trunk/converter/src/main/java/org/osgi/service/converter/Converter.java
    
felix/trunk/converter/src/main/java/org/osgi/service/converter/Converting.java
    felix/trunk/converter/src/main/java/org/osgi/service/converter/Decoding.java
    felix/trunk/converter/src/main/java/org/osgi/service/converter/Encoding.java
    felix/trunk/converter/src/main/java/org/osgi/service/converter/Rule.java
    
felix/trunk/converter/src/main/java/org/osgi/service/converter/TypeReference.java
    
felix/trunk/converter/src/main/java/org/osgi/service/converter/package-info.java
    felix/trunk/converter/src/test/
    felix/trunk/converter/src/test/java/
    felix/trunk/converter/src/test/java/org/
    felix/trunk/converter/src/test/java/org/apache/
    felix/trunk/converter/src/test/java/org/apache/felix/
    felix/trunk/converter/src/test/java/org/apache/felix/converter/
    felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/
    
felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/ConverterTest.java

Added: felix/trunk/converter/pom.xml
URL: 
http://svn.apache.org/viewvc/felix/trunk/converter/pom.xml?rev=1737831&view=auto
==============================================================================
--- felix/trunk/converter/pom.xml (added)
+++ felix/trunk/converter/pom.xml Tue Apr  5 12:51:42 2016
@@ -0,0 +1,94 @@
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>felix-parent</artifactId>
+        <version>4</version>
+        <relativePath>../pom/pom.xml</relativePath>
+    </parent>
+
+    <name>Apache Felix Converter Service</name>
+    <artifactId>org.apache.felix.converter</artifactId>
+    <version>0.1-SNAPSHOT</version>
+    <packaging>jar</packaging>
+
+    <scm>
+        
<connection>scm:svn:http://svn.apache.org/repos/asf/felix/trunk/converter</connection>
+        
<developerConnection>scm:svn:https://svn.apache.org/repos/asf/felix/trunk/converter</developerConnection>
+        <url>http://svn.apache.org/viewvc/felix/trunk/converter/</url>
+    </scm>
+
+    <properties>
+        <felix.java.version>8</felix.java.version>
+        
<felix.java.signature.artifactId>java18</felix.java.signature.artifactId>
+    </properties>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <version>2.5.3</version>
+                <executions>
+                    <execution>
+                        <id>bundle</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>bundle</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>baseline</id>
+                        <goals>
+                            <goal>baseline</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <instructions>
+                        <Private-Package>
+                            org.apache.felix.converter.*
+                        </Private-Package>
+                        
<Export-Package>org.osgi.service.converter</Export-Package>
+                        <Import-Package>
+                            *
+                        </Import-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>osgi.annotation</artifactId>
+            <version>6.0.1</version>
+        </dependency>
+        
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>

Added: 
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/AdapterImpl.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/AdapterImpl.java?rev=1737831&view=auto
==============================================================================
--- 
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/AdapterImpl.java
 (added)
+++ 
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/AdapterImpl.java
 Tue Apr  5 12:51:42 2016
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.converter.impl;
+
+import java.lang.reflect.Type;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
+
+import org.osgi.service.converter.Adapter;
+import org.osgi.service.converter.Converter;
+import org.osgi.service.converter.Converting;
+import org.osgi.service.converter.Rule;
+import org.osgi.service.converter.TypeReference;
+
+public class AdapterImpl implements Adapter {
+    private final Converter delegate;
+    private final Map<ClassPair, Function<Object, Object>> classRules =
+            new ConcurrentHashMap<>();
+
+    public AdapterImpl(Converter converter) {
+        this.delegate = converter;
+    }
+
+    @Override
+    public Converting convert(Object obj) {
+        Converting converting = delegate.convert(obj);
+        return new ConvertingWrapper(obj, converting);
+    }
+
+    @Override
+    public Adapter getAdapter() {
+        return new AdapterImpl(this);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <F, T> Adapter rule(Class<F> fromCls, Class<T> toCls,
+            Function<F, T> toFun, Function<T, F> fromFun) {
+        if (fromCls.equals(toCls))
+            throw new IllegalArgumentException();
+
+        classRules.put(new ClassPair(fromCls, toCls), (Function<Object, 
Object>) toFun);
+        classRules.put(new ClassPair(toCls, fromCls), (Function<Object, 
Object>) fromFun);
+        return this;
+    }
+
+
+    @Override
+    public <F, T> Adapter rule(Rule<F, T> rule) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public <F, T> Adapter rule(Function<F, T> toFun, Function<T, F> fromFun) {
+        // TODO Auto-generated method stub
+        return this;
+    }
+
+    private class ConvertingWrapper implements Converting {
+        private final Converting del;
+        private final Object object;
+
+        ConvertingWrapper(Object obj, Converting c) {
+            object = obj;
+            del = c;
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public <T> T to(Class<T> cls) {
+            Function<Object, Object> f = classRules.get(new 
ClassPair(object.getClass(), cls));
+            if (f != null)
+                return (T) f.apply(object);
+
+            return del.to(cls);
+        }
+
+        @Override
+        public <T> T to(TypeReference<T> ref) {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Object to(Type type) {
+            // TODO Auto-generated method stub
+            return null;
+        }
+    }
+
+    static class ClassPair {
+        private final Class<?> from;
+        private final Class<?> to;
+
+        ClassPair(Class<?> from, Class<?> to) {
+            this.from = from;
+            this.to = to;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(from, to);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == this)
+                return true;
+            if (!(obj instanceof ClassPair))
+                return false;
+
+            ClassPair o = (ClassPair) obj;
+            return Objects.equals(from, o.from) &&
+                    Objects.equals(to, o.to);
+        }
+    }
+}

Added: 
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConverterImpl.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConverterImpl.java?rev=1737831&view=auto
==============================================================================
--- 
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConverterImpl.java
 (added)
+++ 
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConverterImpl.java
 Tue Apr  5 12:51:42 2016
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.converter.impl;
+
+import org.osgi.service.converter.Adapter;
+import org.osgi.service.converter.Converter;
+import org.osgi.service.converter.Converting;
+
+public class ConverterImpl implements Converter {
+    @Override
+    public Adapter getAdapter() {
+        return new AdapterImpl(this);
+    }
+
+    @Override
+    public Converting convert(Object obj) {
+        return new ConvertingImpl(this, obj);
+    }
+}

Added: 
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConvertingImpl.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConvertingImpl.java?rev=1737831&view=auto
==============================================================================
--- 
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConvertingImpl.java
 (added)
+++ 
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConvertingImpl.java
 Tue Apr  5 12:51:42 2016
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.converter.impl;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+
+import org.osgi.service.converter.Converter;
+import org.osgi.service.converter.Converting;
+import org.osgi.service.converter.TypeReference;
+
+public class ConvertingImpl implements Converting {
+    private Converter converter;
+    private final Object object;
+
+    ConvertingImpl(Converter c, Object obj) {
+        converter = c;
+        object = obj;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T> T to(Class<T> cls) {
+        if (String.class.equals(cls)) {
+            if (object instanceof Object[])
+                return (T) ((Object[])object)[0];
+            return (T) object.toString();
+        } else if (String[].class.equals(cls)) {
+            String[] res = new String[1];
+            res[0] = object.toString();
+            return (T) res;
+        }
+
+        T res = tryStandardMethods(cls);
+
+        if (res != null) {
+            return res;
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public <T> T to(TypeReference<T> ref) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Object to(Type type) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @SuppressWarnings("unchecked")
+    private <T> T tryStandardMethods(Class<T> cls) {
+        try {
+            Method m = cls.getDeclaredMethod("valueOf", String.class);
+            if (m != null) {
+                return (T) m.invoke(null, object);
+            }
+        } catch (Exception e) {
+            return null;
+        }
+        return null;
+    }
+}

Added: 
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/JsonCodecImpl.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/JsonCodecImpl.java?rev=1737831&view=auto
==============================================================================
--- 
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/JsonCodecImpl.java
 (added)
+++ 
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/JsonCodecImpl.java
 Tue Apr  5 12:51:42 2016
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.converter.impl;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.Type;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.osgi.service.converter.Codec;
+import org.osgi.service.converter.Converter;
+import org.osgi.service.converter.Decoding;
+import org.osgi.service.converter.Encoding;
+import org.osgi.service.converter.TypeReference;
+
+public class JsonCodecImpl implements Codec {
+    private Map<String, Object> configuration = new ConcurrentHashMap<>();
+    private ThreadLocal<Boolean> threadLocal = new ThreadLocal<>();
+    private Converter converter = new ConverterImpl(); // TODO inject?
+
+    @Override
+    public Codec with(Converter c) {
+        converter = c;
+        return this;
+    }
+
+    @Override
+    public <T> Decoding<T> decode(Class<T> cls) {
+        return new JsonDecodingImpl<T>(converter, cls);
+    }
+
+    @Override
+    public Encoding encode(Object obj) {
+        Encoding encoding = new JsonEncodingImpl(converter, configuration, 
obj);
+
+        if (pretty()) {
+            Boolean top = threadLocal.get();
+            if (top == null) {
+                threadLocal.set(Boolean.TRUE);
+
+                encoding = new EncodingWrapper("{}{}{}{}{}", encoding, 
"{}{}{}{}{}");
+            }
+        }
+        return encoding;
+    }
+
+    private boolean pretty() {
+        return Boolean.TRUE.equals(Boolean.parseBoolean((String) 
configuration.get("pretty")));
+    }
+
+    private class EncodingWrapper implements Encoding {
+        private final Encoding delegate;
+        private String prefix;
+        private String postfix;
+
+        EncodingWrapper(String pre, Encoding encoding, String post) {
+            prefix = pre;
+            delegate = encoding;
+            postfix = post;
+        }
+
+        @Override
+        public void to(OutputStream os) throws IOException {
+            os.write(toString().getBytes(StandardCharsets.UTF_8));
+        }
+
+        @Override
+        public String toString() {
+            try {
+                return prefix + delegate.toString() + postfix;
+            } finally {
+                threadLocal.set(null);
+            }
+        }
+
+        @Override
+        public Encoding pretty() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public void to(OutputStream out, Charset charset) throws IOException {
+            // TODO Auto-generated method stub
+
+        }
+
+        @Override
+        public Appendable to(Appendable out) {
+            // TODO Auto-generated method stub
+            return null;
+        }
+    }
+
+    @Override
+    public <T> Decoding<T> decode(TypeReference<T> ref) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Decoding<?> decode(Type type) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}

Added: 
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/JsonDecodingImpl.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/JsonDecodingImpl.java?rev=1737831&view=auto
==============================================================================
--- 
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/JsonDecodingImpl.java
 (added)
+++ 
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/JsonDecodingImpl.java
 Tue Apr  5 12:51:42 2016
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.converter.impl;
+
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osgi.service.converter.Converter;
+import org.osgi.service.converter.Decoding;
+
+public class JsonDecodingImpl<T> implements Decoding<T> {
+    private final Class<T> clazz;
+    private final Converter converter;
+
+    public JsonDecodingImpl(Converter c, Class<T> cls) {
+        converter = c;
+        clazz = cls;
+    }
+
+    @Override
+    public T from(CharSequence in) {
+        if (Map.class.isAssignableFrom(clazz)) {
+            return createMapFromJSONString(in);
+        }
+        return deserializeSingleJSONValue(clazz, in);
+    }
+
+    private T createMapFromJSONString(CharSequence in) {
+        Map m = new HashMap();
+        String s = in.toString().trim();
+        if (!s.startsWith("{") || !s.endsWith("}"))
+            throw new IllegalArgumentException("JSON Should start and end with 
'{' and '}': " + s);
+
+        // Eat braces
+        s = s.substring(1, s.length() - 1);
+
+        int commaIdx = -1;
+        do {
+            int colonIdx = s.indexOf(':');
+            if (colonIdx <= 0)
+                throw new IllegalArgumentException("JSON Should contain 
key-value pairs: " + s);
+
+            String key = s.substring(0, colonIdx).trim();
+            if (!key.startsWith("\"") || !key.endsWith("\""))
+                throw new IllegalArgumentException("JSON key should be 
double-quoted: " + s);
+            key = key.substring(1, key.length() - 1);
+
+            // move to after ':'
+            s = s.substring(colonIdx + 1);
+
+            commaIdx = getNextComma(s);
+            String val;
+            if (commaIdx > 0) {
+                val = s.substring(0, commaIdx);
+
+                // move to after ','
+                s = s.substring(commaIdx + 1);
+            } else {
+                val = s;
+            }
+
+
+            val = val.trim();
+            Object parsed;
+            if (val.startsWith("{")) {
+                parsed = new JsonCodecImpl().decode(Map.class).from(val);
+            } else {
+                if ("null".equals(val))
+                    parsed = null;
+                else if ("true".equals(val))
+                    parsed = true;
+                else if ("false".equals(val))
+                    parsed = false;
+                else if (val.startsWith("\""))
+                    parsed = val;
+                else if (val.contains("."))
+                    parsed = Double.valueOf(val);
+                else
+                    parsed = Integer.valueOf(val);
+            }
+            m.put(key, parsed);
+        } while (commaIdx > 0);
+
+        return (T) m;
+    }
+
+    private int getNextComma(String s) {
+        int bracelevel = 0;
+        for (int i=0; i<s.length(); i++) {
+            switch(s.charAt(i)) {
+            case '{': bracelevel++;
+                break;
+            case '}': bracelevel--;
+                break;
+            case ',': if (bracelevel == 0) return i;
+                break;
+            }
+        }
+        return -1;
+    }
+
+    @SuppressWarnings("unchecked")
+    private <T> T deserializeSingleJSONValue(Class<T> cls, CharSequence cs) {
+        try {
+            Method m = cls.getDeclaredMethod("valueOf", String.class);
+            if (m != null) {
+                return (T) m.invoke(null, cs);
+            }
+        } catch (Exception e) {
+            return null;
+        }
+        return null;
+    }
+
+    @Override
+    public T from(InputStream in) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public T from(InputStream in, Charset charset) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public T from(Readable in) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}

Added: 
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/JsonEncodingImpl.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/JsonEncodingImpl.java?rev=1737831&view=auto
==============================================================================
--- 
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/JsonEncodingImpl.java
 (added)
+++ 
felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/JsonEncodingImpl.java
 Tue Apr  5 12:51:42 2016
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.converter.impl;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.osgi.service.converter.Converter;
+import org.osgi.service.converter.Encoding;
+
+public class JsonEncodingImpl implements Encoding {
+    private final Converter converter;
+    private final Map<String, Object> configuration;
+    private final Object object;
+
+    JsonEncodingImpl(Converter c, Map<String, Object> cfg, Object obj) {
+        converter = c;
+        configuration = cfg;
+        object = obj;
+    }
+
+    private boolean ignoreNull() {
+        return Boolean.TRUE.equals(Boolean.parseBoolean((String) 
configuration.get("ignoreNull")));
+    }
+
+    @Override
+    public void to(OutputStream os) throws IOException {
+        os.write(encode(object).getBytes(StandardCharsets.UTF_8));
+    }
+
+    @Override
+    public String toString() {
+        return encode(object);
+    }
+
+    public String encode(Object obj) {
+        if (obj == null) {
+            return ignoreNull() ? "" : "null";
+        }
+
+        if (obj instanceof Map) {
+            return encodeMap((Map) obj);
+        } else if (obj instanceof Number) {
+            return obj.toString();
+        } else if (obj instanceof Boolean) {
+            return obj.toString();
+        }
+
+        return "\"" + converter.convert(obj).to(String.class) + "\"";
+    }
+
+    private String encodeMap(Map m) {
+        StringBuilder sb = new StringBuilder("{");
+        for (Entry<?,?> entry : (Set<Entry>) m.entrySet()) {
+            if (entry.getKey() == null || entry.getValue() == null)
+                if (ignoreNull())
+                    continue;
+
+            if (sb.length() > 1)
+                sb.append(',');
+            sb.append('"');
+            sb.append(entry.getKey().toString());
+            sb.append("\":");
+            sb.append(encode(entry.getValue()));
+        }
+        sb.append("}");
+
+        return sb.toString();
+    }
+
+    @Override
+    public Encoding pretty() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void to(OutputStream out, Charset charset) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public Appendable to(Appendable out) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}

Added: 
felix/trunk/converter/src/main/java/org/osgi/service/converter/Adapter.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/osgi/service/converter/Adapter.java?rev=1737831&view=auto
==============================================================================
--- felix/trunk/converter/src/main/java/org/osgi/service/converter/Adapter.java 
(added)
+++ felix/trunk/converter/src/main/java/org/osgi/service/converter/Adapter.java 
Tue Apr  5 12:51:42 2016
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) OSGi Alliance (2016). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.converter;
+
+import java.util.function.Function;
+
+/**
+ * An {@link Adapter} is used to modify the behaviour of the Converter service,
+ * which can be useful when some of the conversions should be done different to
+ * the Converter Specification.
+ * 
+ * @author $Id:$
+ */
+public interface Adapter extends Converter {
+       /**
+        * Specify a conversion rule by providing a rule object.
+        * 
+        * @param rule The conversion rule.
+        * @return The current adapter, can be used to chain invocations.
+        */
+    <F, T> Adapter rule(Rule<F, T> rule);
+
+       /**
+        * Specify a rule for the conversion to and from two classes. The rule
+        * specifies the conversion in both directions. This overload makes it 
easy
+        * to provide the conversions as lambdas, for example:
+        * 
+        * <pre>
+        *  adapter.rule(String[].class, String.class,
+        *      v -> Stream.of(v).collect(Collectors.joining(",")),
+        *      v -> v.split(","));
+        * </pre>
+        * 
+        * @param <F> the type to convert from.
+        * @param <T> the type to convert to.
+        * @param fromCls the class to convert from.
+        * @param toCls the class to convert to.
+        * @param toFun the function to perform the conversion.
+        * @param fromFun the function to perform the reverse conversion.
+        * @return The current adapter, can be used to chain invocations.
+        */
+    <F, T> Adapter rule(Class<F> fromCls, Class<T> toCls,
+            Function<F, T> toFun, Function<T, F> fromFun);
+
+       /**
+        * Specify a rule for the conversion to and from two classes. The rule
+        * specifies the conversion in both directions. This overload makes it 
easy
+        * to provide the conversions as method references.
+        *
+        * @param <F> the type to convert from.
+        * @param <T> the type to convert to.
+        * @param toFun the function to perform the conversion.
+        * @param fromFun the function to perform the reverse conversion.
+        * @return The current adapter, can be used to chain invocations.
+        */
+    <F, T> Adapter rule(Function<F, T> toFun, Function<T, F> fromFun);
+
+//    <F, T> Adapter rule(Function<TypeReference<F>, TypeReference<T>> toFun,
+//            Function<TypeReference<T>,TypeReference<F>> fromFun);
+}

Added: felix/trunk/converter/src/main/java/org/osgi/service/converter/Codec.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/osgi/service/converter/Codec.java?rev=1737831&view=auto
==============================================================================
--- felix/trunk/converter/src/main/java/org/osgi/service/converter/Codec.java 
(added)
+++ felix/trunk/converter/src/main/java/org/osgi/service/converter/Codec.java 
Tue Apr  5 12:51:42 2016
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) OSGi Alliance (2016). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.converter;
+
+import java.lang.reflect.Type;
+
+/**
+ * The Codec service can be used to encode a given object in a certain
+ * representation, for example JSON, YAML or XML. The Codec service can also
+ * decode the representation it produced. A single Codec service can
+ * encode/decode only a single format. To support multiple encoding formats
+ * register multiple services.
+ * 
+ * @author $Id:$
+ */
+public interface Codec {
+       /**
+        * Start specifying a decode operation.
+        * 
+        * @param <T> The type to decode to.
+        * @param cls The class to decode to.
+        * @return A {@link Decoding} object to specify the source for the 
decode
+        *         operation.
+        */
+    <T> Decoding<T> decode(Class<T> cls);
+
+       /**
+        * Start specifying a decode operation.
+        * 
+        * @param <T> The type to decode to.
+        * @param ref A type reference for the target type.
+        * @return A {@link Decoding} object to specify the source for the 
decode
+        *         operation.
+        */
+       <T> Decoding<T> decode(TypeReference<T> ref);
+
+       /**
+        * Start specifying a decode operation.
+        * 
+        * @param type The type to convert to.
+        * @return A {@link Decoding} object to specify the source for the 
decode
+        *         operation.
+        */
+       Decoding<?> decode(Type type);
+
+    /**
+        * Start specifying an encode opertation.
+        * 
+        * @param obj The object to encode.
+        * @return an Encoding object to specify the target for the decode
+        *         operation.
+        */
+    Encoding encode(Object obj);
+
+    /**
+        * Specify the converter to be used by the code, if an alternative, 
adapted,
+        * converter is to be used.
+        * 
+        * @param converter The converter to use.
+        * @return A codec that uses the converter as specified.
+        */
+    Codec with(Converter converter);
+}

Added: 
felix/trunk/converter/src/main/java/org/osgi/service/converter/Converter.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/osgi/service/converter/Converter.java?rev=1737831&view=auto
==============================================================================
--- 
felix/trunk/converter/src/main/java/org/osgi/service/converter/Converter.java 
(added)
+++ 
felix/trunk/converter/src/main/java/org/osgi/service/converter/Converter.java 
Tue Apr  5 12:51:42 2016
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) OSGi Alliance (2016). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.converter;
+
+/**
+ * The Converter service is used to start a conversion. The service is obtained
+ * from the service registry. The conversion is then completed via the
+ * Converting interface that has methods to specify the target type.
+ * 
+ * @author $Id:$
+ */
+public interface Converter {
+       /**
+        * Start a conversion for the given object.
+        * 
+        * @param obj The object that should be converted.
+        * @return A {@link Converting} object to complete the conversion.
+        */
+    Converting convert(Object obj);
+
+       /**
+        * Obtain an adapter to this converter. The adapter behaves just like 
the
+        * converter except for the exception rules registered with is. For more
+        * details see the {@link Adapter} interface.
+        * 
+        * @return An adapter to this converter.
+        */
+    Adapter getAdapter();
+}

Added: 
felix/trunk/converter/src/main/java/org/osgi/service/converter/Converting.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/osgi/service/converter/Converting.java?rev=1737831&view=auto
==============================================================================
--- 
felix/trunk/converter/src/main/java/org/osgi/service/converter/Converting.java 
(added)
+++ 
felix/trunk/converter/src/main/java/org/osgi/service/converter/Converting.java 
Tue Apr  5 12:51:42 2016
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) OSGi Alliance (2016). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.converter;
+
+import java.lang.reflect.Type;
+
+/**
+ * This interface is used to specify the target that an object should be
+ * converted to. A {@link Converting} instance can be obtained via the
+ * {@link Converter} service by starting a conversion for a specific object.
+ * 
+ * @author $Id:$
+ */
+public interface Converting {
+       /**
+        * Specify the target object type for the conversion as a class object.
+        * 
+        * @param cls The class to convert to.
+        * @return The converted object.
+        */
+    <T> T to(Class<T> cls);
+
+       /**
+        * Specify the target object type as a {@link TypeReference}. If the 
target
+        * class carries generics information a TypeReference should be used as 
this
+        * preserves the generic information whereas a Class object has this
+        * information erased. Example use:
+        * 
+        * <pre>
+        *  List<String> result =
+        *      converter.convert(Arrays.asList(1,2,3)).
+        *          to(new TypeReference&lt;List&lt;String&gt;&gt;() {});
+        * </pre>
+        * 
+        * @param ref A type reference to the object being converted to.
+        * @return The converted object.
+        */
+       <T> T to(TypeReference<T> ref);
+
+       /**
+        * Specify the target object type as a Java Refelection Type object.
+        * 
+        * @param type A Type object to represent the target type to be 
converted
+        *        to.
+        * @return The converted object.
+        */
+       Object to(Type type);
+}

Added: 
felix/trunk/converter/src/main/java/org/osgi/service/converter/Decoding.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/osgi/service/converter/Decoding.java?rev=1737831&view=auto
==============================================================================
--- 
felix/trunk/converter/src/main/java/org/osgi/service/converter/Decoding.java 
(added)
+++ 
felix/trunk/converter/src/main/java/org/osgi/service/converter/Decoding.java 
Tue Apr  5 12:51:42 2016
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) OSGi Alliance (2016). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.converter;
+
+import java.io.InputStream;
+import java.nio.charset.Charset;
+
+/**
+ * Interface to specify the source of the decoding operation
+ *
+ * @param <T> The target type for the decoding operation.
+ * @author $Id:$
+ */
+public interface Decoding<T> {
+       /**
+        * Use an input stream as the source of the decoding operation. As 
encoding
+        * UTF-8 is used.
+        * 
+        * @param in The stream to use.
+        * @return the decoded object.
+        */
+       T from(InputStream in);
+
+       /**
+        * Use an input stream as the source of the decoding operation.
+        * 
+        * @param in The stream to use.
+        * @param charset The character set to use.
+        * @return the decoded object.
+        */
+       T from(InputStream in, Charset charset);
+
+       /**
+        * Use a Readable as the source of the decoding operation.
+        * 
+        * @param in The readable to use.
+        * @return the decoded object.
+        */
+       T from(Readable in);
+
+       /**
+        * Use a Char Sequence as the source of the decoding operation.
+        * 
+        * @param in The char sequence to use.
+        * @return the decoded object.
+        */
+    T from(CharSequence in);
+}

Added: 
felix/trunk/converter/src/main/java/org/osgi/service/converter/Encoding.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/osgi/service/converter/Encoding.java?rev=1737831&view=auto
==============================================================================
--- 
felix/trunk/converter/src/main/java/org/osgi/service/converter/Encoding.java 
(added)
+++ 
felix/trunk/converter/src/main/java/org/osgi/service/converter/Encoding.java 
Tue Apr  5 12:51:42 2016
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) OSGi Alliance (2016). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.converter;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+
+/**
+ * Interface to specify the target of the encoding operation.
+ *
+ * @author $Id:$
+ */
+public interface Encoding {
+       /**
+        * Specify that the encoded output should be formatted to look 'pretty',
+        * which may make it easier for humans to read. If not specified, the
+        * encoded output should be formatted to be compact, so save space.
+        *
+        * @return This Encoding object to allow further invocations on it.
+        */
+       Encoding pretty();
+
+       /**
+        * Use an output stream as the target of the encoding operation. UTF-8 
will
+        * be used.
+        *
+        * @param out The output stream to use.
+        */
+       void to(OutputStream out) throws IOException;
+
+       /**
+        * Use an output stream as the target of the encoding operation.
+        *
+        * @param out The output stream to use.
+        * @param charset The character set to use.
+        */
+       void to(OutputStream out, Charset charset) throws IOException;
+
+       /**
+        * Encode the object and append the result to an appendable.
+        *
+        * @param out The appendable object to use.
+        * @return The appendable object provided in, which allows further 
appends
+        *         to it be done in a fluent programming style.
+        */
+       Appendable to(Appendable out);
+
+       /**
+        * Encode the object and return the result as a string.
+        *
+        * @return The encoded object.
+        */
+       @Override
+       String toString();
+}

Added: felix/trunk/converter/src/main/java/org/osgi/service/converter/Rule.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/osgi/service/converter/Rule.java?rev=1737831&view=auto
==============================================================================
--- felix/trunk/converter/src/main/java/org/osgi/service/converter/Rule.java 
(added)
+++ felix/trunk/converter/src/main/java/org/osgi/service/converter/Rule.java 
Tue Apr  5 12:51:42 2016
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) OSGi Alliance (2016). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.converter;
+
+import java.util.function.Function;
+
+/**
+ * A rule is a data entity can hold all the information needed to specify a
+ * custom conversion for use by an @{link Adapter}.
+ *
+ * @param <F> The type to convert from.
+ * @param <T> The type to convert to.
+ * @author $Id:$
+ */
+public class Rule<F, T> {
+    private final Function<F, T> toFun;
+    private final Function<T, F> fromFun;
+
+       /**
+        * Specify the functions to do the conversions in both directions.
+        * 
+        * @param to The function that performs the conversion.
+        * @param from The function that performs the reverse conversion.
+        */
+    public Rule(Function<F, T> to, Function<T, F> from) {
+        toFun = to;
+        fromFun = from;
+    }
+
+       /**
+        * Obtain the conversion function.
+        * 
+        * @return The conversion function.
+        */
+    public Function<F, T> getToFunction() {
+        return toFun;
+    }
+
+       /**
+        * Obtain the reverse conversion function.
+        * 
+        * @return The reverse conversion function.
+        */
+    public Function<T, F> getFromFunction() {
+        return fromFun;
+    }
+}

Added: 
felix/trunk/converter/src/main/java/org/osgi/service/converter/TypeReference.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/osgi/service/converter/TypeReference.java?rev=1737831&view=auto
==============================================================================
--- 
felix/trunk/converter/src/main/java/org/osgi/service/converter/TypeReference.java
 (added)
+++ 
felix/trunk/converter/src/main/java/org/osgi/service/converter/TypeReference.java
 Tue Apr  5 12:51:42 2016
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) OSGi Alliance (2015, 2016). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.converter;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+/**
+ * An object does not carry any runtime information about its generic type.
+ * However sometimes it is necessary to specify a generic type, that is the
+ * purpose of this class. It allows you to specify an generic type by defining 
a
+ * type T, then subclassing it. The subclass will have a reference to the super
+ * class that contains this generic information. Through reflection, we pick
+ * this reference up and return it with the getType() call.
+ *
+ * <pre>
+ *  List<String> result =
+ *      converter.convert(Arrays.asList(1,2,3)).
+ *          to(new TypeReference&lt;List&lt;String&gt;&gt;() {});
+ * </pre>
+ *
+ * @param <T> The target type for the conversion.
+ * @author $Id:$
+ */
+public class TypeReference<T> {
+       /**
+        * A {@link TypeReference} cannot be directly instantiated. To use it 
it has
+        * to be extended, typically as an anonymous inner class.
+        */
+       protected TypeReference() {
+       }
+
+    /**
+     * Return the actual type of this Type Reference
+     *
+     * @return the type of this reference.
+     */
+    public Type getType() {
+        return ((ParameterizedType) getClass().
+            getGenericSuperclass()).getActualTypeArguments()[0];
+    }
+}
\ No newline at end of file

Added: 
felix/trunk/converter/src/main/java/org/osgi/service/converter/package-info.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/osgi/service/converter/package-info.java?rev=1737831&view=auto
==============================================================================
--- 
felix/trunk/converter/src/main/java/org/osgi/service/converter/package-info.java
 (added)
+++ 
felix/trunk/converter/src/main/java/org/osgi/service/converter/package-info.java
 Tue Apr  5 12:51:42 2016
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) OSGi Alliance (2016). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Converter Package.
+ * 
+ * @author $Id:$
+ */
+@org.osgi.annotation.versioning.Version("1.0")
+package org.osgi.service.converter;
+

Added: 
felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/ConverterTest.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/ConverterTest.java?rev=1737831&view=auto
==============================================================================
--- 
felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/ConverterTest.java
 (added)
+++ 
felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/ConverterTest.java
 Tue Apr  5 12:51:42 2016
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.converter.impl;
+
+import org.junit.Test;
+import org.osgi.service.converter.Converter;
+
+import static org.junit.Assert.assertEquals;
+
+public class ConverterTest {
+    @Test
+    public void testConverter() {
+        Converter c = new ConverterImpl();
+        int i = c.convert("123").to(Integer.class);
+        assertEquals(123, i);
+    }
+}


Reply via email to