This is an automated email from the ASF dual-hosted git repository.

hasan pushed a commit to branch reunited
in repository https://gitbox.apache.org/repos/asf/clerezza.git

commit 9647fd3c481ce6a569ba38f0b89c52e718024919
Author: Hasan <[email protected]>
AuthorDate: Mon May 14 00:52:52 2018 +0200

    CLEREZZA-1025: Copy serializedform in core to a new module called 
representation
---
 representation/pom.xml                             |  80 ++++++
 .../org/apache/clerezza/representation/Parser.java | 311 +++++++++++++++++++++
 .../clerezza/representation/ParsingProvider.java   |  49 ++++
 .../apache/clerezza/representation/Serializer.java | 253 +++++++++++++++++
 .../representation/SerializingProvider.java        |  49 ++++
 .../clerezza/representation/SupportedFormat.java   |  61 ++++
 .../representation/UnsupportedFormatException.java |  37 +++
 .../UnsupportedParsingFormatException.java         |  35 +++
 .../UnsupportedSerializationFormatException.java   |  35 +++
 .../apache/clerezza/representation/ParserTest.java |  88 ++++++
 .../clerezza/representation/SerializerTest.java    |  87 ++++++
 .../representation/TestServiceManagedProvider.java |  50 ++++
 ....apache.clerezza.representation.ParsingProvider |  18 ++
 13 files changed, 1153 insertions(+)

diff --git a/representation/pom.xml b/representation/pom.xml
new file mode 100644
index 0000000..274fc53
--- /dev/null
+++ b/representation/pom.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/xsd/maven-4.0.0.xsd";>
+    <parent>
+        <artifactId>clerezza</artifactId>
+        <groupId>org.apache.clerezza</groupId>
+        <version>8-SNAPSHOT</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>representation</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.clerezza.commons-rdf</groupId>
+            <artifactId>commons-rdf-api</artifactId>
+            <version>0.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.clerezza.commons-rdf</groupId>
+            <artifactId>commons-rdf-impl-utils</artifactId>
+            <version>0.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.scr.annotations</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.scr.ds-annotations</artifactId>
+            <version>1.2.8</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.clerezza</groupId>
+            <artifactId>utils</artifactId>
+            <version>0.2</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        
<Export-Package>org.apache.clerezza.representation.*</Export-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>generate-scr-scrdescriptor</id>
+                        <goals>
+                            <goal>scr</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git 
a/representation/src/main/java/org/apache/clerezza/representation/Parser.java 
b/representation/src/main/java/org/apache/clerezza/representation/Parser.java
new file mode 100644
index 0000000..4202ad6
--- /dev/null
+++ 
b/representation/src/main/java/org/apache/clerezza/representation/Parser.java
@@ -0,0 +1,311 @@
+/*
+ * 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.clerezza.representation;
+
+import org.apache.clerezza.commons.rdf.Graph;
+import org.apache.clerezza.commons.rdf.IRI;
+import org.apache.clerezza.commons.rdf.ImmutableGraph;
+import org.apache.clerezza.commons.rdf.impl.utils.simple.SimpleMGraph;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.*;
+
+/**
+ * This singleton class provides a method
+ * <code>parse</code> to transform serialized RDF forms into {@link 
ImmutableGraph}s.
+ *
+ * Functionality is delegated to registered {@link ParsingProvider}s. Such
+ * <code>ParsingProvider</code>s can be registered and unregistered, later
+ * registered
+ * <code>ParsingProvider</code>s shadow previously registered providers for the
+ * same format.
+ *
+ * Note on synchronization:
+ * <code>ParsingProvider</code>s must be able to handle concurrent requests.
+ *
+ * @author reto
+ *
+ */
+@Component(service = Parser.class)
+public class Parser {
+
+    private ConfigurationAdmin configurationAdmin;
+    /**
+     * The list of providers in the order of registration
+     */
+    private List<ParsingProvider> providerList = new 
ArrayList<ParsingProvider>();
+    /**
+     * A map to quickly locate a provider
+     */
+    private volatile Map<String, ParsingProvider> providerMap = new 
HashMap<String, ParsingProvider>();
+    /**
+     * The singleton instance
+     */
+    private volatile static Parser instance;
+    private boolean active;
+
+    private static final Logger log = LoggerFactory.getLogger(Parser.class);
+    /**
+     * the constructor sets the singleton instance to allow instantiation
+     * by OSGi-DS. This constructor should not be called except by OSGi-DS,
+     * otherwise the static <code>getInstance</code> method should be used.
+     */
+    public Parser() {
+        log.info("constructing Parser");
+        Parser.instance = this;
+    }
+
+    /**
+     * A constructor for tests, which doesn't set the singleton instance
+     *
+     * @param dummy an ignored argument to distinguish this from the other 
constructor
+     */
+    Parser(Object dummy) {
+        active = true;
+    }
+
+    /**
+     * This returns the singleton instance, if an instance has been previously
+     * created (e.g. by OSGi declarative services) this instance is returned,
+     * otherwise a new instance is created and providers are injected using 
+     * the service provider interface (META-INF/services/)
+     *
+     * @return the singleton Parser instance
+     */
+    public static Parser getInstance() {
+        if (instance == null) {
+            synchronized (Parser.class) {
+                if (instance == null) {
+                    new Parser();
+                    Iterator<ParsingProvider> parsingProviders =
+                            
ServiceLoader.load(ParsingProvider.class).iterator();
+                    while (parsingProviders.hasNext()) {
+                        ParsingProvider parsingProvider = 
parsingProviders.next();
+                        instance.bindParsingProvider(parsingProvider);
+                    }
+                    instance.active = true;
+                    instance.refreshProviderMap();
+                }
+            }
+        }
+        return instance;
+
+    }
+
+    @Activate
+    protected void activate(final ComponentContext componentContext) {
+        active = true;
+        refreshProviderMap();
+        //changing the congiguration before this finshed activating causes a 
new instance to be created
+        /*(new Thread() {
+            @Override
+            public void run() {
+                try {
+                    Thread.sleep(100);
+                } catch (InterruptedException ex) {
+                    return;
+                }
+                refreshProviderMap();
+            }
+            
+            
+        }).start();*/
+    }
+
+    @Deactivate
+    protected void deactivate(final ComponentContext componentContext) {
+        active = false;
+    }
+    
+    @Modified
+    void modified(ComponentContext ctx) {
+        log.debug("modified");
+    }
+
+    /**
+     * Parses a serialized ImmutableGraph from an InputStream. This delegates 
the
+     * processing to the provider registered for the specified format, if
+     * the formatIdentifier contains a ';'-character only the section before
+     * that character is used for choosing the provider.
+     *
+     * @param serializedGraph an inputstream with the serialization
+     * @param formatIdentifier a string identifying the format (usually the 
MIME-type)
+     * @return the ImmutableGraph read from the stream
+     * @throws UnsupportedFormatException
+     */
+    public ImmutableGraph parse(InputStream serializedGraph,
+            String formatIdentifier) throws UnsupportedFormatException {
+        return parse(serializedGraph, formatIdentifier, null);
+    }
+
+    /**
+     * Parses a serialized ImmutableGraph from an InputStream. This delegates 
the
+     * processing to the provider registered for the specified format, if
+     * the formatIdentifier contains a ';'-character only the section before
+     * that character is used for choosing the provider.
+     *
+     * @param target the Graph to which the parsed triples are added
+     * @param serializedGraph an inputstream with the serialization
+     * @param formatIdentifier a string identifying the format (usually the 
MIME-type)
+     * @throws UnsupportedFormatException
+     */
+    public void parse(Graph target, InputStream serializedGraph,
+            String formatIdentifier) throws UnsupportedFormatException {
+        parse(target, serializedGraph, formatIdentifier, null);
+    }
+
+    /**
+     * Parses a serialized ImmutableGraph from an InputStream. This delegates 
the
+     * processing to the provider registered for the specified format, if
+     * the formatIdentifier contains a ';'-character only the section before
+     * that character is used for choosing the provider.
+     *
+     * @param serializedGraph an inputstream with the serialization
+     * @param formatIdentifier a string identifying the format (usually the 
MIME-type)
+     * @param baseUri the uri against which relative uri-refs are evaluated
+     * @return the ImmutableGraph read from the stream
+     * @throws UnsupportedFormatException
+     */
+    public ImmutableGraph parse(InputStream serializedGraph,
+            String formatIdentifier, IRI baseUri) throws 
UnsupportedFormatException {
+        Graph graph = new SimpleMGraph();
+        parse(graph, serializedGraph, formatIdentifier, baseUri);
+        return graph.getImmutableGraph();
+    }
+
+    /**
+     * Parses a serialized ImmutableGraph from an InputStream. This delegates 
the
+     * processing to the provider registered for the specified format, if
+     * the formatIdentifier contains a ';'-character only the section before
+     * that character is used for choosing the provider.
+     *
+     * @param target the Graph to which the parsed triples are added
+     * @param serializedGraph an inputstream with the serialization
+     * @param formatIdentifier a string identifying the format (usually the 
MIME-type)
+     * @param baseUri the uri against which relative uri-refs are evaluated
+     * @throws UnsupportedFormatException
+     */
+    public void parse(Graph target, InputStream serializedGraph,
+            String formatIdentifier, IRI baseUri) throws 
UnsupportedFormatException {
+        String deParameterizedIdentifier;
+        int semicolonPos = formatIdentifier.indexOf(';');
+        if (semicolonPos > -1) {
+            deParameterizedIdentifier = formatIdentifier.substring(0, 
semicolonPos);
+        } else {
+            deParameterizedIdentifier = formatIdentifier;
+        }
+        ParsingProvider provider = providerMap.get(deParameterizedIdentifier);
+        if (provider == null) {
+            throw new UnsupportedParsingFormatException(formatIdentifier);
+        }
+        provider.parse(target, serializedGraph, formatIdentifier, baseUri);
+    }
+
+    /**
+     * Get a set of supported formats
+     *
+     * @return a set if stings identifying formats (usually the MIME-type)
+     */
+    public Set<String> getSupportedFormats() {
+        return Collections.unmodifiableSet(providerMap.keySet());
+    }
+
+    /**
+     * Registers a parsing provider
+     *
+     * @param provider the provider to be registered
+     */
+    @Reference(policy = ReferencePolicy.DYNAMIC,
+            cardinality = ReferenceCardinality.MULTIPLE)
+    public void bindParsingProvider(ParsingProvider provider) {
+        providerList.add(provider);
+        refreshProviderMap();
+    }
+
+    /**
+     * Unregister a parsing provider
+     *
+     * @param provider the provider to be deregistered
+     */
+    public void unbindParsingProvider(ParsingProvider provider) {
+        providerList.remove(provider);
+        refreshProviderMap();
+    }
+
+    /**
+     * Update providerMap with the providers in the providerList
+     *
+     */
+    private void refreshProviderMap() {
+        if (active) {
+            try {
+                final Map<String, ParsingProvider> newProviderMap = new 
HashMap<String, ParsingProvider>();
+                for (ParsingProvider provider : providerList) {
+                    String[] formatIdentifiers = 
getFormatIdentifiers(provider);
+                    for (String formatIdentifier : formatIdentifiers) {
+                        newProviderMap.put(formatIdentifier, provider);
+                    }
+                }
+                providerMap = newProviderMap;
+                if (configurationAdmin != null) { //i.e. when we are in an 
OSGi environment
+                    Dictionary<String, Object> newConfig = 
configurationAdmin.getConfiguration(getClass().getName()).getProperties();
+                    if (newConfig == null) {
+                        newConfig = new Hashtable<String, Object>();
+                    }
+                    Set<String> supportedFormats = getSupportedFormats();
+                    String[] supportedFromatsArray = 
supportedFormats.toArray(new String[supportedFormats.size()]);
+                    newConfig.put(SupportedFormat.supportedFormat, 
supportedFromatsArray);
+                    
configurationAdmin.getConfiguration(getClass().getName()).update(newConfig);
+                }
+            } catch (IOException ex) {
+                throw new RuntimeException(ex);
+            }
+        }
+    }
+
+    
+
+    /**
+     * Extract format identifiers for a parsing provider
+     *
+     * @param provider the provider to be registered
+     * @return formatIdentifiers
+     */
+    private String[] getFormatIdentifiers(ParsingProvider parsingProvider) {
+        Class<? extends ParsingProvider> clazz = parsingProvider.getClass();
+        SupportedFormat supportedFormatAnnotation = 
clazz.getAnnotation(SupportedFormat.class);
+        String[] formatIdentifiers = supportedFormatAnnotation.value();
+        return formatIdentifiers;
+    }
+
+    @Reference
+    protected void bindConfigurationAdmin(ConfigurationAdmin 
configurationAdmin) {
+        this.configurationAdmin = configurationAdmin;
+    }
+
+    protected void unbindConfigurationAdmin(ConfigurationAdmin 
configurationAdmin) {
+        this.configurationAdmin = null;
+    }
+}
diff --git 
a/representation/src/main/java/org/apache/clerezza/representation/ParsingProvider.java
 
b/representation/src/main/java/org/apache/clerezza/representation/ParsingProvider.java
new file mode 100644
index 0000000..fbdf721
--- /dev/null
+++ 
b/representation/src/main/java/org/apache/clerezza/representation/ParsingProvider.java
@@ -0,0 +1,49 @@
+/*
+ * 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.clerezza.representation;
+
+import org.apache.clerezza.commons.rdf.Graph;
+import org.apache.clerezza.commons.rdf.IRI;
+
+import java.io.InputStream;
+
+/**
+ * An instance of this class parses RDF-ImmutableGraph from one or more 
serialization
+ * formats. The supported formats are indicated using the {@link 
SupportedFormat}
+ * annotation.
+ *
+ * @author reto
+ */
+public interface ParsingProvider {
+
+    /**
+     * Parses a stream as the specified RDF-format. This method will be invoked
+     * for a supported format, a format is considered as supported if the part
+     * before a ';'-character in the <code>formatIdentifier</code> matches
+     * a <code>SupportedFormat</code> annotation of the implementing class.
+     *
+     * @param target the mutable ImmutableGraph to which the read triples 
shall be added
+     * @param serializedGraph the stream from which the serialized 
ImmutableGraph is read
+     * @param formatIdentifier a String identifying the format
+     * @param baseUri the baseUri for interpreting relative uris, may be null
+     */
+    void parse(Graph target, InputStream serializedGraph,
+               String formatIdentifier, IRI baseUri);
+
+}
diff --git 
a/representation/src/main/java/org/apache/clerezza/representation/Serializer.java
 
b/representation/src/main/java/org/apache/clerezza/representation/Serializer.java
new file mode 100644
index 0000000..e36b9c7
--- /dev/null
+++ 
b/representation/src/main/java/org/apache/clerezza/representation/Serializer.java
@@ -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 org.apache.clerezza.representation;
+
+import org.apache.clerezza.commons.rdf.Graph;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.*;
+
+/**
+ * This singleton class provides a method <code>serialize</code> to transform a
+ * {@link ImmutableGraph} into serialized RDF forms.
+ * 
+ * Functionality is delegated to registered {@link SerializingProvider}s. Such
+ * <code>SerializingProvider</code>s can be registered and unregistered, later
+ * registered <code>SerializingProvider</code>s shadow previously registered
+ * providers for the same format.
+ * 
+ * Note on synchronization: <code>SerializingProvider</code>s must be able to
+ * handle concurrent requests.
+ * 
+ * @author mir
+ * 
+ */
+@Component(service = Serializer.class)
+public class Serializer {
+    
+    private ConfigurationAdmin configurationAdmin;
+
+    /**
+     * The list of providers in the order of registration
+     */
+    private List<SerializingProvider> providerList = new 
ArrayList<SerializingProvider>();
+
+    /**
+     * A map to quickly locate a provider
+     */
+    private volatile Map<String, SerializingProvider> providerMap = new 
HashMap<String, SerializingProvider>();
+
+    /**
+     * The singleton instance
+     */
+    private volatile static Serializer instance;
+    
+    private static final Logger log = 
LoggerFactory.getLogger(Serializer.class);
+    
+    private boolean active;
+
+    /**
+     * the constructor sets the singleton instance to allow instantiation
+     * by OSGi-DS. This constructor should not be called except by OSGi-DS,
+     * otherwise the static <code>getInstance</code> method should be used.
+     */
+    public Serializer() {
+        Serializer.instance = this;
+    }
+
+    /**
+     * A constructor for tests, which doesn't set the singleton instance
+     * 
+     * @param dummy
+     *            an ignored argument to distinguish this from the other
+     *            constructor
+     */
+    Serializer(Object dummy) {
+        active = true;
+    }
+
+    /**
+     * This returns the singleton instance, if an instance has been previously
+     * created (e.g. by OSGi declarative services) this instance is returned,
+     * otherwise a new instance is created and providers are injected using the
+     * service provider interface (META-INF/services/)
+     * 
+     * @return the singleton Serializer instance
+     */
+    public static Serializer getInstance() {
+        if (instance == null) {
+            synchronized (Serializer.class) {
+                if (instance == null) {
+                    new Serializer();
+                    Iterator<SerializingProvider> SerializingProviders = 
ServiceLoader
+                            .load(SerializingProvider.class).iterator();
+                    while (SerializingProviders.hasNext()) {
+                        SerializingProvider SerializingProvider = 
SerializingProviders
+                                .next();
+                        instance.bindSerializingProvider(SerializingProvider);
+                    }
+                    instance.active = true;
+                    instance.refreshProviderMap();
+                }
+            }
+        }
+        return instance;
+
+    }
+ 
+    @Activate
+    protected void activate(final ComponentContext componentContext) {
+        active = true;
+        refreshProviderMap();
+    }
+
+    @Deactivate
+    protected void deactivate(final ComponentContext componentContext) {
+        active = false;
+    }
+    
+    @Modified
+    void modified(ComponentContext ctx) {
+        log.debug("modified");
+    }
+
+    /**
+     * Serializes a ImmutableGraph into an OutputStream. This delegates the
+     * processing to the provider registered for the specified format, if
+     * the formatIdentifier contains a ';'-character only the section before
+     * that character is used for choosing the provider.
+     * 
+     * @param serializedGraph
+     *            an outputStream into which the ImmutableGraph will be 
serialized
+     * @param tc  the <code>Graph</code> to be serialized
+     * @param formatIdentifier
+     *            a string specifying the serialization format (usually the
+     *            MIME-type)
+     * @throws UnsupportedFormatException
+     */
+    public void serialize(OutputStream serializedGraph, Graph tc,
+            String formatIdentifier) throws UnsupportedFormatException {
+        String deParameterizedIdentifier;
+        int semicolonPos = formatIdentifier.indexOf(';');
+        if (semicolonPos > -1) {
+            deParameterizedIdentifier = formatIdentifier.substring(0, 
semicolonPos);
+        } else {
+            deParameterizedIdentifier = formatIdentifier;
+        }
+        SerializingProvider provider = 
providerMap.get(deParameterizedIdentifier);
+        if (provider == null) {
+            throw new 
UnsupportedSerializationFormatException(formatIdentifier);
+        }
+        provider.serialize(serializedGraph, tc, formatIdentifier);
+    }
+
+    /**
+     * Get a set of supported formats
+     *
+     * @return a set if stings identifying formats (usually the MIME-type)
+     */
+    public Set<String> getSupportedFormats() {
+        return Collections.unmodifiableSet(providerMap.keySet());
+    }
+    
+    /**
+     * Registers a Serializing provider
+     * 
+     * @param provider
+     *            the provider to be registered
+     */
+    @Reference(policy = ReferencePolicy.DYNAMIC, 
+            cardinality = ReferenceCardinality.MULTIPLE)
+    public void bindSerializingProvider(SerializingProvider provider) {
+        providerList.add(provider);
+        refreshProviderMap();
+
+    }
+
+    /**
+     * Unregister a Serializing provider
+     * 
+     * @param provider
+     *            the provider to be unregistered
+     */
+    public void unbindSerializingProvider(SerializingProvider provider) {
+        providerList.remove(provider);
+        refreshProviderMap();
+
+    }
+
+    private void refreshProviderMap() {
+        if (active) {
+            final Map<String, SerializingProvider> newProviderMap = new 
HashMap<String, SerializingProvider>();
+            //we want more generic providers first so they get overridden by 
more specific ones
+            Collections.sort(providerList, new 
Comparator<SerializingProvider>() {
+                @Override
+                public int compare(SerializingProvider s1, SerializingProvider 
s2) {
+                    return getFormatIdentifiers(s2).length - 
getFormatIdentifiers(s1).length;
+                }
+            });
+            for (SerializingProvider provider : providerList) {
+                String[] formatIdentifiers = getFormatIdentifiers(provider);
+                for (String formatIdentifier : formatIdentifiers) {
+                    newProviderMap.put(formatIdentifier, provider);
+                }
+            }
+            providerMap = newProviderMap;
+            if (configurationAdmin != null) { //we are in OSGi environment
+                try {
+                    Dictionary<String, Object> newConfig = 
configurationAdmin.getConfiguration(getClass().getName()).getProperties();
+                    if (newConfig == null) {
+                        newConfig = new Hashtable<String, Object>();
+                    }
+                    Set<String> supportedFormats = getSupportedFormats();
+                    String[] supportedFromatsArray = 
supportedFormats.toArray(new String[supportedFormats.size()]);
+                    newConfig.put(SupportedFormat.supportedFormat, 
supportedFromatsArray);
+                    
configurationAdmin.getConfiguration(getClass().getName()).update(newConfig);
+                } catch (IOException ex) {
+                    throw new RuntimeException(ex);
+                }
+            }
+        }
+    }
+
+    private String[] getFormatIdentifiers(
+            SerializingProvider SerializingProvider) {
+        Class<? extends SerializingProvider> clazz = SerializingProvider
+                .getClass();
+        SupportedFormat supportedFormatAnnotation = clazz
+                .getAnnotation(SupportedFormat.class);
+        String[] formatIdentifiers = supportedFormatAnnotation.value();
+        return formatIdentifiers;
+    }
+    
+    @Reference
+    protected void bindConfigurationAdmin(ConfigurationAdmin 
configurationAdmin) {
+        this.configurationAdmin = configurationAdmin;
+    }
+
+    protected void unbindConfigurationAdmin(ConfigurationAdmin 
configurationAdmin) {
+        this.configurationAdmin = null;
+    }
+}
diff --git 
a/representation/src/main/java/org/apache/clerezza/representation/SerializingProvider.java
 
b/representation/src/main/java/org/apache/clerezza/representation/SerializingProvider.java
new file mode 100644
index 0000000..3053e45
--- /dev/null
+++ 
b/representation/src/main/java/org/apache/clerezza/representation/SerializingProvider.java
@@ -0,0 +1,49 @@
+/*
+ * 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.clerezza.representation;
+
+import org.apache.clerezza.commons.rdf.Graph;
+
+import java.io.OutputStream;
+
+
+/**
+ * An instance of this class serializes <code>Graph</code>s to a
+ * specified serialization format. The supported formats are indicated using 
the
+ * {@link SupportedFormat} annotation.
+ *
+ * @author mir
+ */
+public interface SerializingProvider {
+    
+    /** Serializes a <code>Graph</code> to a specified
+     * <code>OutputStream</code> in the format identified by
+     * <code>formatIdentifier</code>. This method will be invoked
+     * for a supported format, a format is considered as supported if the part
+     * before a ';'-character in the <code>formatIdentifier</code> matches
+     * a <code>SupportedFormat</code> annotation of the implementing class.
+     * 
+     * @param outputStream
+     * @param tc
+     * @param formatIdentifier
+     */
+    public void serialize(OutputStream outputStream, Graph tc,
+                          String formatIdentifier);
+
+}
diff --git 
a/representation/src/main/java/org/apache/clerezza/representation/SupportedFormat.java
 
b/representation/src/main/java/org/apache/clerezza/representation/SupportedFormat.java
new file mode 100644
index 0000000..d246a39
--- /dev/null
+++ 
b/representation/src/main/java/org/apache/clerezza/representation/SupportedFormat.java
@@ -0,0 +1,61 @@
+/*
+ * 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.clerezza.representation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation is used to annotate {@link ParsingProvider}s to indicate
+ * the format(s) they support.
+ *
+ * @author reto
+ */
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface SupportedFormat {
+
+    /**
+     * used as a key for the OSGi service property
+     */
+    public static final String supportedFormat = "supportedFormat";
+    public static final String RDF_XML = "application/rdf+xml";
+    public static final String TURTLE = "text/turtle";
+    public static final String X_TURTLE = "application/x-turtle";
+    public static final String N_TRIPLE = "application/n-triples";
+    /**
+    * @deprecated: The mime-type for N Triples is "application/n-triples": 
http://www.w3.org/TR/n-triples/#sec-mediaReg-n-triples
+    */
+    @Deprecated
+    public static final String TEXT_RDF_NT = "text/rdf+nt";
+    public static final String N3 = "text/rdf+n3";
+    public static final String RDF_JSON = "application/rdf+json";
+    //both html and xhtml can be rdf formats with RDFa
+    public static final String XHTML = "application/xhtml+xml";
+    public static final String HTML = "text/html";
+
+    /**
+     * A list of format Identifiers (typically MIME-types) types without
+     * parameter (without ';'-character).
+     * E.g. {"application/rdf+xml","application/turtle"}
+     */
+    String[] value();
+}
diff --git 
a/representation/src/main/java/org/apache/clerezza/representation/UnsupportedFormatException.java
 
b/representation/src/main/java/org/apache/clerezza/representation/UnsupportedFormatException.java
new file mode 100644
index 0000000..d914a3d
--- /dev/null
+++ 
b/representation/src/main/java/org/apache/clerezza/representation/UnsupportedFormatException.java
@@ -0,0 +1,37 @@
+/*
+ * 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.clerezza.representation;
+
+/**
+ *
+ * This exception is thrown on an attempt to parse a format for which no 
+ * <code>ParsingProvider</code> is known.
+ *
+ * @author reto
+ */
+public abstract class UnsupportedFormatException extends RuntimeException {
+
+    public UnsupportedFormatException(String message) {
+        super(message);
+    }
+
+
+    
+
+}
diff --git 
a/representation/src/main/java/org/apache/clerezza/representation/UnsupportedParsingFormatException.java
 
b/representation/src/main/java/org/apache/clerezza/representation/UnsupportedParsingFormatException.java
new file mode 100644
index 0000000..51fafc9
--- /dev/null
+++ 
b/representation/src/main/java/org/apache/clerezza/representation/UnsupportedParsingFormatException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.clerezza.representation;
+
+/**
+ *
+ * @author reto
+ */
+public class UnsupportedParsingFormatException extends 
UnsupportedFormatException {
+    /**
+     * Creates an instance for a specified unsupported format.
+     * 
+     * @param formatIdentifier the unsupported format
+     */
+    public UnsupportedParsingFormatException(String formatIdentifier) {
+        super("No parser available for "+formatIdentifier);
+    }
+
+}
diff --git 
a/representation/src/main/java/org/apache/clerezza/representation/UnsupportedSerializationFormatException.java
 
b/representation/src/main/java/org/apache/clerezza/representation/UnsupportedSerializationFormatException.java
new file mode 100644
index 0000000..b2bf5cc
--- /dev/null
+++ 
b/representation/src/main/java/org/apache/clerezza/representation/UnsupportedSerializationFormatException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.clerezza.representation;
+
+/**
+ *
+ * @author reto
+ */
+public class UnsupportedSerializationFormatException extends 
UnsupportedFormatException {
+    /**
+     * Creates an instance for a specified unsupported format.
+     * 
+     * @param formatIdentifier the unsupported format
+     */
+    public UnsupportedSerializationFormatException(String formatIdentifier) {
+        super("No serializer available for "+formatIdentifier);
+    }
+
+}
diff --git 
a/representation/src/test/java/org/apache/clerezza/representation/ParserTest.java
 
b/representation/src/test/java/org/apache/clerezza/representation/ParserTest.java
new file mode 100644
index 0000000..97f6e69
--- /dev/null
+++ 
b/representation/src/test/java/org/apache/clerezza/representation/ParserTest.java
@@ -0,0 +1,88 @@
+/*
+ * 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.clerezza.representation;
+
+import junit.framework.Assert;
+import org.apache.clerezza.commons.rdf.Graph;
+import org.apache.clerezza.commons.rdf.IRI;
+import org.junit.Test;
+
+import java.io.InputStream;
+
+/**
+ *
+ * @author reto
+ */
+public class ParserTest {
+
+    private static boolean providerAInvoked;
+    private static boolean providerBInvoked;
+    private ParsingProvider parsingProviderA = new ParsingProviderA();
+    private ParsingProvider parsingProviderB = new ParsingProviderB();
+
+    @Test
+    public void registerOneProvider() {
+        Parser parser = new Parser(null);
+        parser.bindParsingProvider(parsingProviderA);
+        providerAInvoked = false;
+        parser.parse(null, "application/x-fantasy2+rdf");
+        Assert.assertTrue(providerAInvoked);
+    }
+    
+    @Test
+    public void registerAndUnregisterSecond() {
+        Parser parser = new Parser(null);
+        parser.bindParsingProvider(parsingProviderA);
+        parser.bindParsingProvider(parsingProviderB);
+        providerAInvoked = false;
+        providerBInvoked = false;
+        parser.parse(null, "application/x-fantasy2+rdf");
+        Assert.assertFalse(providerAInvoked);
+        Assert.assertTrue(providerBInvoked);
+        providerAInvoked = false;
+        providerBInvoked = false;
+        parser.parse(null, "application/x-fantasy1+rdf");
+        Assert.assertTrue(providerAInvoked);
+        Assert.assertFalse(providerBInvoked);
+        parser.unbindParsingProvider(parsingProviderB);
+        providerAInvoked = false;
+        providerBInvoked = false;
+        parser.parse(null, "application/x-fantasy2+rdf");
+        Assert.assertTrue(providerAInvoked);
+        Assert.assertFalse(providerBInvoked);
+        
+    }
+
+    @SupportedFormat({"application/x-fantasy1+rdf", 
"application/x-fantasy2+rdf"})
+    static class ParsingProviderA implements ParsingProvider {
+
+        @Override
+        public void parse(Graph target, InputStream serializedGraph, String 
formatIdentifier, IRI baseUri) {
+            providerAInvoked = true;
+        }
+    };
+    @SupportedFormat("application/x-fantasy2+rdf")
+    static class ParsingProviderB implements ParsingProvider {
+
+        @Override
+        public void parse(Graph target, InputStream serializedGraph, String 
formatIdentifier, IRI baseUri) {
+            providerBInvoked = true;
+        }
+    };
+}
diff --git 
a/representation/src/test/java/org/apache/clerezza/representation/SerializerTest.java
 
b/representation/src/test/java/org/apache/clerezza/representation/SerializerTest.java
new file mode 100644
index 0000000..feae79a
--- /dev/null
+++ 
b/representation/src/test/java/org/apache/clerezza/representation/SerializerTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.clerezza.representation;
+
+import junit.framework.Assert;
+import org.apache.clerezza.commons.rdf.Graph;
+import org.junit.Test;
+
+import java.io.OutputStream;
+
+/**
+ *
+ * @author mir
+ */
+public class SerializerTest {
+
+    private static boolean providerAInvoked;
+    private static boolean providerBInvoked;
+    private SerializingProvider serializingProviderA = new 
SerializingProviderA();
+    private SerializingProvider serializingProviderB = new 
SerializingProviderB();
+
+    @Test
+    public void registerOneProvider() {
+        Serializer serializer = new Serializer(null);
+        serializer.bindSerializingProvider(serializingProviderA);
+        providerAInvoked = false;
+        serializer.serialize(null, null, "application/x-fantasy2+rdf");
+        Assert.assertTrue(providerAInvoked);
+    }
+    
+    @Test
+    public void registerAndUnregisterSecond() {
+        Serializer serializer = new Serializer(null);
+        serializer.bindSerializingProvider(serializingProviderA);
+        serializer.bindSerializingProvider(serializingProviderB);
+        providerAInvoked = false;
+        providerBInvoked = false;
+        serializer.serialize(null, null, "application/x-fantasy2+rdf");
+        Assert.assertFalse(providerAInvoked);
+        Assert.assertTrue(providerBInvoked);
+        providerAInvoked = false;
+        providerBInvoked = false;
+        serializer.serialize(null, null, "application/x-fantasy1+rdf");
+        Assert.assertTrue(providerAInvoked);
+        Assert.assertFalse(providerBInvoked);
+        serializer.unbindSerializingProvider(serializingProviderB);
+        providerAInvoked = false;
+        providerBInvoked = false;
+        serializer.serialize(null, null, "application/x-fantasy2+rdf");
+        Assert.assertTrue(providerAInvoked);
+        Assert.assertFalse(providerBInvoked);
+        
+    }
+
+    @SupportedFormat({"application/x-fantasy1+rdf", 
"application/x-fantasy2+rdf"})
+    static class SerializingProviderA implements SerializingProvider {
+
+        @Override
+        public void serialize(OutputStream serializedGraph, Graph tc, String 
formatIdentifier) {
+            providerAInvoked = true;
+        }
+    };
+    @SupportedFormat("application/x-fantasy2+rdf")
+    static class SerializingProviderB implements SerializingProvider {
+
+        @Override
+        public void serialize(OutputStream serializedGraph, Graph tc, String 
formatIdentifier) {
+            providerBInvoked = true;
+        }
+    };
+}
diff --git 
a/representation/src/test/java/org/apache/clerezza/representation/TestServiceManagedProvider.java
 
b/representation/src/test/java/org/apache/clerezza/representation/TestServiceManagedProvider.java
new file mode 100644
index 0000000..ec6fe9c
--- /dev/null
+++ 
b/representation/src/test/java/org/apache/clerezza/representation/TestServiceManagedProvider.java
@@ -0,0 +1,50 @@
+/*
+ * 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.clerezza.representation;
+
+import org.apache.clerezza.commons.rdf.Graph;
+import org.apache.clerezza.commons.rdf.IRI;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.InputStream;
+
+/**
+ * This class is listed in
+ * META-INF/services/org.apache.clerezza.serializedform.ParsingProvider
+ *
+ * @author reto
+ */
+@SupportedFormat("application/x-test+rdf")
+public class TestServiceManagedProvider implements ParsingProvider {
+
+    private static boolean parseInvoked;
+
+    @Override
+    public void parse(Graph target, InputStream serializedGraph, String 
formatIdentifier, IRI baseUri) {
+        parseInvoked = true;
+    }
+    
+    @Test
+    public void registerOneProvider() {
+        Parser parser = Parser.getInstance();
+        parser.parse(null, "application/x-test+rdf");
+        Assert.assertTrue(parseInvoked);
+    }
+}
diff --git 
a/representation/src/test/resources/META-INF/services/org.apache.clerezza.representation.ParsingProvider
 
b/representation/src/test/resources/META-INF/services/org.apache.clerezza.representation.ParsingProvider
new file mode 100644
index 0000000..16e04f4
--- /dev/null
+++ 
b/representation/src/test/resources/META-INF/services/org.apache.clerezza.representation.ParsingProvider
@@ -0,0 +1,18 @@
+# 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.
+
+org.apache.clerezza.representation.TestServiceManagedProvider
\ No newline at end of file

Reply via email to