You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by jb...@apache.org on 2011/08/10 18:08:32 UTC

svn commit: r1156246 - in /karaf/sandbox/jbonofre: ./ cave/ cave/branches/ cave/tags/ cave/trunk/ cave/trunk/server/ cave/trunk/server/backend/ cave/trunk/server/backend/src/ cave/trunk/server/backend/src/main/ cave/trunk/server/backend/src/main/java/ ...

Author: jbonofre
Date: Wed Aug 10 16:08:30 2011
New Revision: 1156246

URL: http://svn.apache.org/viewvc?rev=1156246&view=rev
Log:
Initial import of the Cave sandbox.

Added:
    karaf/sandbox/jbonofre/
    karaf/sandbox/jbonofre/cave/
    karaf/sandbox/jbonofre/cave/branches/
    karaf/sandbox/jbonofre/cave/tags/
    karaf/sandbox/jbonofre/cave/trunk/
    karaf/sandbox/jbonofre/cave/trunk/README
    karaf/sandbox/jbonofre/cave/trunk/pom.xml
    karaf/sandbox/jbonofre/cave/trunk/server/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/pom.xml
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/karaf/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/karaf/cave/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/karaf/cave/server/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/karaf/cave/server/backend/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/karaf/cave/server/backend/CaveRepository.java
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/karaf/cave/server/backend/CaveRepositoryService.java
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/karaf/cave/server/backend/impl/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/karaf/cave/server/backend/impl/CaveRepositoryImpl.java
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/resources/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/test/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/test/java/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/test/java/org/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/test/java/org/apache/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/test/java/org/apache/karaf/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/test/java/org/apache/karaf/cave/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/test/java/org/apache/karaf/cave/server/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/test/java/org/apache/karaf/cave/server/backend/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/test/java/org/apache/karaf/cave/server/backend/impl/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/test/java/org/apache/karaf/cave/server/backend/impl/CaveRepositoryImplTest.java
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/test/resources/
    karaf/sandbox/jbonofre/cave/trunk/server/backend/src/test/resources/log4j.xml
    karaf/sandbox/jbonofre/cave/trunk/server/pom.xml

Added: karaf/sandbox/jbonofre/cave/trunk/README
URL: http://svn.apache.org/viewvc/karaf/sandbox/jbonofre/cave/trunk/README?rev=1156246&view=auto
==============================================================================
--- karaf/sandbox/jbonofre/cave/trunk/README (added)
+++ karaf/sandbox/jbonofre/cave/trunk/README Wed Aug 10 16:08:30 2011
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+Welcome to Apache Karaf Cave
+============================
+Apache Karaf Cave is an Apache Karaf subproject. It provides an OSGi Bundle Repository (OBR) and Karaf 
+Resources Repository (KRR).
+
+OBR provides a service that can automatically install a bundle, with its deployment dependencies, from a bundle
+repository. 
+
+
+Getting Started
+===============
+For an Apache Karaf Cave source distribution, please read
+BUILDING for instructions on building Apache Karaf Cave.
+
+To install Apache Karaf Cave, first you have to register the Cave features descriptor:
+
+karaf@root> features:addurl mvn:org.apache.karaf/cave/2.2.1/xml/features
+
+Now, you can install the Cave feature simply by typing:
+
+karaf@root> features:install cave
+
+The PDF manual is the right place to find any information about Karaf Cave.
+
+Alternatively, you can also find out how to get started here:
+    http://karaf.apache.org/subprojects/cave
+
+If you need more help try talking to us on our mailing lists
+    http://karaf.apache.org/site/mailinglists.html
+
+If you find any issues with Apache Karaf, please submit reports
+with JIRA here:
+    http://issues.apache.org/jira/browse/KARAF
+
+We welcome contributions, and encourage you to get involved in the
+Karaf community. If you'd like to learn more about how you can
+contribute, please see:
+    http://karaf.apache.org/index/community/contributing.html
+
+Many thanks for using Apache Karaf Cave.
+
+
+The Karaf Team

Added: karaf/sandbox/jbonofre/cave/trunk/pom.xml
URL: http://svn.apache.org/viewvc/karaf/sandbox/jbonofre/cave/trunk/pom.xml?rev=1156246&view=auto
==============================================================================
--- karaf/sandbox/jbonofre/cave/trunk/pom.xml (added)
+++ karaf/sandbox/jbonofre/cave/trunk/pom.xml Wed Aug 10 16:08:30 2011
@@ -0,0 +1,105 @@
+<?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">
+
+    <!--
+
+        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.
+    -->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache</groupId>
+        <artifactId>apache</artifactId>
+        <version>8</version>
+    </parent>
+
+    <groupId>org.apache.karaf</groupId>
+    <artifactId>cave</artifactId>
+    <version>3.0.0-SNAPSHOT</version>
+    <packaging>pom</packaging>
+    <name>Apache Karaf :: Cave</name>
+
+    <properties>
+        <felix.bundlerepository.version>1.6.6</felix.bundlerepository.version>
+    </properties>
+
+    <modules>
+        <module>server</module>
+    </modules>
+
+    <!-- TODO add scm section when moving to Karaf svn -->
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>org.apache.felix.bundlerepository</artifactId>
+                <version>${felix.bundlerepository.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+    <dependencies>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.6.1</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.7</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.6.1</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.16</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.felix</groupId>
+                    <artifactId>maven-bundle-plugin</artifactId>
+                    <version>2.3.5</version>
+                    <extensions>true</extensions>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>2.0.2</version>
+                <configuration>
+                    <source>1.5</source>
+                    <target>1.5</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file

Added: karaf/sandbox/jbonofre/cave/trunk/server/backend/pom.xml
URL: http://svn.apache.org/viewvc/karaf/sandbox/jbonofre/cave/trunk/server/backend/pom.xml?rev=1156246&view=auto
==============================================================================
--- karaf/sandbox/jbonofre/cave/trunk/server/backend/pom.xml (added)
+++ karaf/sandbox/jbonofre/cave/trunk/server/backend/pom.xml Wed Aug 10 16:08:30 2011
@@ -0,0 +1,75 @@
+<?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">
+
+    <!--
+
+        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.
+    -->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.karaf.cave</groupId>
+        <artifactId>org.apache.karaf.cave.server</artifactId>
+        <version>3.0.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <groupId>org.apache.karaf.cave.server</groupId>
+    <artifactId>org.apache.karaf.cave.server.backend</artifactId>
+    <name>Apache Karaf :: Cave :: Server :: Backend</name>
+    <packaging>bundle</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.bundlerepository</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Import-Package>
+                            org.apache.felix.bundlerepository*;version="[2,3)",
+                            org.osgi.framework,
+                            org.osgi.service.log,
+                            org.osgi.service.url,
+                            !org.apache.felix.shell,
+                            !org.apache.felix.bundlerepository.impl.wrapper,
+                            !org.osgi.service.obr,
+                            !javax.xml.stream,
+                        </Import-Package>
+                        <Private-Package>
+                            org.kxml2.io,
+                            org.xmlpull.v1,
+                            org.apache.felix.utils*,
+                            org.apache.felix.bundlerepository.impl
+                        </Private-Package>
+                        <Export-Service>
+                            org.apache.felix.bundlerepository.RepositoryAdmin
+                        </Export-Service>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file

Added: karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/karaf/cave/server/backend/CaveRepository.java
URL: http://svn.apache.org/viewvc/karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/karaf/cave/server/backend/CaveRepository.java?rev=1156246&view=auto
==============================================================================
--- karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/karaf/cave/server/backend/CaveRepository.java (added)
+++ karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/karaf/cave/server/backend/CaveRepository.java Wed Aug 10 16:08:30 2011
@@ -0,0 +1,92 @@
+/*
+ * 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.karaf.cave.server.backend;
+
+import java.io.InputStream;
+import java.net.URL;
+
+/**
+ * Cave repository is a storage area where to upload artifacts.
+ * It's already the basement of the OBR repository.xml metadata.
+ */
+public interface CaveRepository {
+
+    /**
+     * Get the name of the repository.
+     *
+     * @return the name of the repository
+     */
+    String getName();
+
+    /**
+     * Get the location (path) of this repository.
+     *
+     * @return the location of this repository.
+     */
+    String getLocation();
+
+    /**
+     * Upload an artifact from the given URL into the repository.
+     * TODO use a Artifact object in place of raw artifact
+     *
+     * @param location  location of the artifact to upload in the repository.
+     * @throws Exception in case of upload failure.
+     */
+    void upload(String location) throws Exception;
+
+    /**
+     * Upload an artifact from the given URL into the repository.
+     * TODO use a Artifact object in place of raw artifact
+     *
+     * @param url the URL of the artifact.
+     * @throws Exception in case of upload failure.
+     */
+    void upload(URL url) throws Exception;
+
+    /**
+     * Upload an artifact from a given stream into the repository.
+     * TODO use a Artifact object in place of raw artifact
+     *
+     * @param stream the input stream of the artifact.
+     * @throws Exception in case of upload failure.
+     */
+    void upload(InputStream stream) throws Exception;
+
+    /**
+     * Scan the whole repository, reading bundle MANIFEST, etc to update
+     * or generate the OBR repository.xml.
+     *
+     * @throws Exception in case of scan failure.
+     */
+    void scan() throws Exception;
+
+    /**
+     * Register the repository into the OBR, giving all repository artifacts visible
+     * for the OBR client.
+     *
+     * @throws Exception in case of register failure.
+     */
+    void register() throws Exception;
+
+    /**
+     * Destroy this repository, removing the contents of the repository and OBR metadata.
+     *
+     * @throws Exception in case of destroy failure.
+     */
+    void destroy() throws Exception;
+
+}

Added: karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/karaf/cave/server/backend/CaveRepositoryService.java
URL: http://svn.apache.org/viewvc/karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/karaf/cave/server/backend/CaveRepositoryService.java?rev=1156246&view=auto
==============================================================================
--- karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/karaf/cave/server/backend/CaveRepositoryService.java (added)
+++ karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/karaf/cave/server/backend/CaveRepositoryService.java Wed Aug 10 16:08:30 2011
@@ -0,0 +1,30 @@
+/*
+ * 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.karaf.cave.server.backend;
+
+/**
+ * Service to manipulate Cave repository.
+ */
+public interface CaveRepositoryService {
+
+    CaveRepository createRepository(String name, String location) throws Exception;
+
+    CaveRepository[] getRepositories();
+
+    CaveRepository getRepository(String name);
+
+}

Added: karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/karaf/cave/server/backend/impl/CaveRepositoryImpl.java
URL: http://svn.apache.org/viewvc/karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/karaf/cave/server/backend/impl/CaveRepositoryImpl.java?rev=1156246&view=auto
==============================================================================
--- karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/karaf/cave/server/backend/impl/CaveRepositoryImpl.java (added)
+++ karaf/sandbox/jbonofre/cave/trunk/server/backend/src/main/java/org/apache/karaf/cave/server/backend/impl/CaveRepositoryImpl.java Wed Aug 10 16:08:30 2011
@@ -0,0 +1,197 @@
+package org.apache.karaf.cave.server.backend.impl;
+
+import org.apache.felix.bundlerepository.Resource;
+import org.apache.felix.bundlerepository.impl.DataModelHelperImpl;
+import org.apache.felix.bundlerepository.impl.RepositoryImpl;
+import org.apache.felix.bundlerepository.impl.ResourceImpl;
+import org.apache.karaf.cave.server.backend.CaveRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.net.URL;
+
+/**
+ * Default implementation of a Karaf Cave repository.
+ */
+public class CaveRepositoryImpl implements CaveRepository {
+
+    private final static Logger LOGGER = LoggerFactory.getLogger(CaveRepositoryImpl.class);
+
+    private String name;
+    private String location;
+    private RepositoryImpl obrRepository;
+
+    public CaveRepositoryImpl(String name, String location) throws Exception {
+        this.name = name;
+        this.location = location;
+
+        this.createRepositoryDirectory();
+    }
+
+    /**
+     * Check if the repository folder exists and create it if not.
+     */
+    private void createRepositoryDirectory() throws Exception {
+        LOGGER.debug("Create Karaf Cave repository {} folder.", name);
+        File directory = new File(this.location);
+        if (!directory.exists()) {
+            directory.mkdirs();
+            LOGGER.debug("Karaf Cave repository {} location has been created.", name);
+            LOGGER.debug(location);
+        }
+        File repositoryXml = new File(location, "repository.xml");
+        if (repositoryXml.exists()) {
+            obrRepository = (RepositoryImpl) new DataModelHelperImpl().repository(repositoryXml.toURI().toURL());
+        } else {
+            obrRepository = new RepositoryImpl();
+        }
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public String getLocation() {
+        return this.location;
+    }
+
+    /**
+     * Update the repository.xml with the artifact at the given URL.
+     *
+     * @param resource the bundle resource
+     * @throws Exception in case of repository.xml update failure.
+     */
+    private void updateRepositoryXml(Resource resource) throws Exception {
+        if (resource != null) {
+            obrRepository.addResource(resource);
+            obrRepository.setLastModified(System.currentTimeMillis());
+            File repositoryXml = new File(location, "repository.xml");
+            OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(repositoryXml));
+            new DataModelHelperImpl().writeRepository(obrRepository, writer);
+            writer.flush();
+            writer.close();
+        }
+    }
+
+    /**
+     * Add an artifact into this repository
+     *
+     * @param path the location of the raw artifact
+     * @throws Exception in case of upload failure
+     */
+    public void upload(String path) throws Exception {
+        LOGGER.debug("Upload new artifact from {}", location);
+        // copy the file
+        LOGGER.debug("Copy the file from {}", location);
+        File source = new File(path);
+        if (!source.exists()) {
+            throw new IllegalArgumentException("The artifact location " + location + " doesn't exist.");
+        }
+        File destination = new File(location, source.getName());
+        FileInputStream fis = new FileInputStream(source);
+        FileOutputStream fos = new FileOutputStream(destination);
+        byte[] buffer = new byte[1024];
+        int len;
+        while ((len = fis.read(buffer)) > 0) {
+            fos.write(buffer, 0, len);
+        }
+        fis.close();
+        fos.flush();
+        fos.close();
+        // update the repository.xml
+        Resource resource = new DataModelHelperImpl().createResource(destination.toURI().toURL());
+        if (resource == null) {
+            destination.delete();
+            throw new IllegalArgumentException("The " + path + " source is not a valid OSGi bundle");
+        }
+        this.updateRepositoryXml(resource);
+    }
+
+    /**
+     * Upload an artifact using a stream.
+     *
+     * @param stream the artifact stream.
+     * @throws Exception in case of upload failure.
+     */
+    public void upload(InputStream stream) throws Exception {
+        LOGGER.debug("Upload new artifact from a stream");
+        String artifactName = "artifact-" + System.currentTimeMillis();
+        File destination = new File(location, artifactName);
+        FileOutputStream fos = new FileOutputStream(destination);
+        byte[] buffer = new byte[1024];
+        int len;
+        while ((len = stream.read(buffer)) > 0) {
+            fos.write(buffer, 0, len);
+        }
+        fos.flush();
+        fos.close();
+        // update the repository.xml
+        Resource resource = new DataModelHelperImpl().createResource(destination.toURI().toURL());
+        if (resource == null) {
+            destination.delete();
+            throw new IllegalArgumentException("The stream source is not a valid OSGi bundle");
+        }
+        destination.renameTo(new File(location, resource.getSymbolicName() + "-" + resource.getVersion()));
+        this.updateRepositoryXml(resource);
+    }
+
+    /**
+     * Upload an artifact from the given URL.
+     *
+     * @param url the URL of the artifact.
+     * @throws Exception in case of upload failure.
+     */
+    public void upload(URL url) throws Exception {
+        LOGGER.debug("Upload new artifact from {}", url);
+        String artifactName = "artifact-" + System.currentTimeMillis();
+        File destination = new File(location, artifactName);
+        FileOutputStream fos = new FileOutputStream(destination);
+        InputStream stream = url.openStream();
+        byte[] buffer = new byte[1024];
+        int len;
+        while ((len = stream.read(buffer)) > 0) {
+            fos.write(buffer, 0, len);
+        }
+        stream.close();
+        fos.flush();
+        fos.close();
+        // update the repository.xml
+        Resource resource = new DataModelHelperImpl().createResource(destination.toURI().toURL());
+        if (resource == null) {
+            destination.delete();
+            throw new IllegalArgumentException("The " + url + " artifact source is not a valid OSGi bundle");
+        }
+        destination.renameTo(new File(location, resource.getSymbolicName() + "-" + resource.getVersion()));
+        this.updateRepositoryXml(resource);
+    }
+
+    /**
+     * Scan the content of the whole repository to update the repository.xml.
+     *
+     * @throws Exception in case of scan failure.
+     */
+    public void scan() throws Exception {
+        // TODO
+    }
+
+    /**
+     * Register the repository (repository.xml) into the OBR (using the OBR RepositoryAdmin service).
+     *
+     * @throws Exception in case of register failure.
+     */
+    public void register() throws Exception {
+        // TODO
+    }
+
+    /**
+     * Destroy this repository by deleting the storage folder.
+     *
+     * @throws Exception in case of destroy failure.
+     */
+    public void destroy() throws Exception {
+        File storage = new File(location);
+        storage.delete();
+    }
+
+}

Added: karaf/sandbox/jbonofre/cave/trunk/server/backend/src/test/java/org/apache/karaf/cave/server/backend/impl/CaveRepositoryImplTest.java
URL: http://svn.apache.org/viewvc/karaf/sandbox/jbonofre/cave/trunk/server/backend/src/test/java/org/apache/karaf/cave/server/backend/impl/CaveRepositoryImplTest.java?rev=1156246&view=auto
==============================================================================
--- karaf/sandbox/jbonofre/cave/trunk/server/backend/src/test/java/org/apache/karaf/cave/server/backend/impl/CaveRepositoryImplTest.java (added)
+++ karaf/sandbox/jbonofre/cave/trunk/server/backend/src/test/java/org/apache/karaf/cave/server/backend/impl/CaveRepositoryImplTest.java Wed Aug 10 16:08:30 2011
@@ -0,0 +1,51 @@
+/*
+ * 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.karaf.cave.server.backend.impl;
+
+import org.apache.karaf.cave.server.backend.CaveRepository;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.net.URL;
+
+/**
+ * Unit test of the Cave Repository Implementation.
+ */
+@RunWith(JUnit4.class)
+public class CaveRepositoryImplTest {
+
+    private CaveRepository repository;
+
+    @Before
+    public void setUp() throws Exception {
+        repository = new CaveRepositoryImpl("test", "target/test-repository");
+    }
+
+    @Test
+    public void testUploadBundleFromURL() throws Exception {
+        repository.upload(new URL("http://repo1.maven.org/maven2/org/apache/servicemix/bundles/org.apache.servicemix.bundles.commons-beanutils/1.8.2_2/org.apache.servicemix.bundles.commons-beanutils-1.8.2_2.jar"));
+        repository.upload(new URL("http://repo1.maven.org/maven2/org/apache/servicemix/bundles/org.apache.servicemix.bundles.commons-lang/2.4_5/org.apache.servicemix.bundles.commons-lang-2.4_5.jar"));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testUploadNonBundleFromURL() throws Exception {
+        repository.upload(new URL("http://repo1.maven.org/maven2/commons-vfs/commons-vfs/1.0/commons-vfs-1.0.jar"));
+    }
+
+}

Added: karaf/sandbox/jbonofre/cave/trunk/server/backend/src/test/resources/log4j.xml
URL: http://svn.apache.org/viewvc/karaf/sandbox/jbonofre/cave/trunk/server/backend/src/test/resources/log4j.xml?rev=1156246&view=auto
==============================================================================
--- karaf/sandbox/jbonofre/cave/trunk/server/backend/src/test/resources/log4j.xml (added)
+++ karaf/sandbox/jbonofre/cave/trunk/server/backend/src/test/resources/log4j.xml Wed Aug 10 16:08:30 2011
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
+
+    <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
+        <param name="threshold" value="DEBUG"/>
+        <layout class="org.apache.log4j.PatternLayout">
+            <param name="ConversionPattern" value="%-5p - %-30c{1} - %m%n"/>
+        </layout>
+    </appender>
+
+    <root>
+        <level value="DEBUG"/>
+        <appender-ref ref="CONSOLE"/>
+    </root>
+
+</log4j:configuration>
\ No newline at end of file

Added: karaf/sandbox/jbonofre/cave/trunk/server/pom.xml
URL: http://svn.apache.org/viewvc/karaf/sandbox/jbonofre/cave/trunk/server/pom.xml?rev=1156246&view=auto
==============================================================================
--- karaf/sandbox/jbonofre/cave/trunk/server/pom.xml (added)
+++ karaf/sandbox/jbonofre/cave/trunk/server/pom.xml Wed Aug 10 16:08:30 2011
@@ -0,0 +1,40 @@
+<?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">
+
+    <!--
+
+        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.
+    -->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.karaf</groupId>
+        <artifactId>cave</artifactId>
+        <version>3.0.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <groupId>org.apache.karaf.cave</groupId>
+    <artifactId>org.apache.karaf.cave.server</artifactId>
+    <name>Apache Karaf :: Cave :: Server</name>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>backend</module>
+    </modules>
+
+</project>
\ No newline at end of file