public interface RepositoryStorage {

    /**
     * Get the associated reposistory;
     */
    XRepository getRepository();

    /**
     * Find the capabilities that match the specified requirement.
     *
     * @param requirement The requirements for which matching capabilities should be returned. Must not be {@code null}.
     * @return A collection of matching capabilities for the specified requirements.
     *         If there are no matching capabilities an empty collection is returned.
     *         The returned collection is the property of the caller and can be modified by the caller.
     */
    Collection<Capability> findProviders(Requirement requirement);

    /**
     * Get the repository reader for this storage
     */
    RepositoryReader getRepositoryReader();

    /**
     * Get the resource for the given identity capability.
     *
     * @return The resource or null
     */
    XResource getResource(XIdentityCapability icap);

    /**
     * Add the given resource to storage
     *
     * @param resource The resource to add
     * @return The resource being added, which may be a modified copy of the give resource
     * @throws RepositoryStorageException If there is a problem storing the resource
     */
    XResource addResource(XResource resource) throws RepositoryStorageException;

    /**
     * Remove a the given resource from the cache.
     *
     * @param resource The resource to remove
     * @return true if the resource could be found and removed
     * @throws RepositoryStorageException If there is a problem removing the resource from storage
     */
    boolean removeResource(XResource resource) throws RepositoryStorageException;
} public interface RepositoryStorageFactory {

    /**
     * Create the storage for a given repository
     *
     * @param repository The associated repository
     */
    RepositoryStorage create(XRepository repository);
} public interface ResourceInstaller {

    XBundle installResource(BundleContext context, XResource res) throws BundleException;

    XBundle installBundleResource(BundleContext context, XResource res) throws BundleException;

    XBundle installModuleResource(BundleContext context, XResource res) throws BundleException;
} public interface XPersistentRepository extends XRepository {

    void addRepositoryDelegate(XRepository delegate);

    void removeRepositoryDelegate(XRepository delegate);

    List<XRepository> getRepositoryDelegates();
} public interface XRepository extends Repository {

    /**
     * The property that defines the Maven Repository base URLs.
     */
    String PROPERTY_MAVEN_REPOSITORY_BASE_URLS = "org.jboss.osgi.repository.maven.base.urls";
    /**
     * The property that defines the repository storage directory.
     */
    String PROPERTY_REPOSITORY_STORAGE_DIR = "org.jboss.osgi.repository.storage.dir";
    /**
     * The property that defines the repository storage file.
     */
    String PROPERTY_REPOSITORY_STORAGE_FILE = "org.jboss.osgi.repository.storage.file";

    /**
     * Get the name for this repository
     */
    String getName();

    /**
     * Find the capabilities that match the specified requirement.
     *
     * @param requirement The requirements for which matching capabilities
     *        should be returned. Must not be {@code null}.
     * @return A collection of matching capabilities for the specified requirements.
     *         If there are no matching capabilities an empty collection is returned.
     *         The returned collection is the property of the caller and can be modified by the caller.
     */
    Collection<Capability> findProviders(Requirement requirement);

    /**
     * Adapt this repository tor the given type
     */
    <T> T adapt(Class<T> type);
} public class AbstractPersistentRepository extends AbstractRepository implements XPersistentRepository {

    private final RepositoryStorage storage;
    private final List<XRepository> delegates = new ArrayList<XRepository>();

    public AbstractPersistentRepository(RepositoryStorageFactory factory) {
        if (factory == null)
            throw MESSAGES.illegalArgumentNull("factory");

        this.storage = factory.create(this);
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> T adapt(Class<T> type) {
        T result = super.adapt(type);
        if (result == null) {
            if (RepositoryStorage.class.isAssignableFrom(type)) {
                result = (T) storage;
            } else {
                for (XRepository delegate : delegates) {
                    result = delegate.adapt(type);
                    if (result != null) {
                        break;
                    }
                }
            }
        }
        return result;
    }

    public void addRepositoryDelegate(XRepository delegate) {
        synchronized (delegates) {
            if (delegate != this) {
                LOGGER.debugf("Add repository: %s", delegate);
                delegates.add(delegate);
            }
        }
    }

    public void removeRepositoryDelegate(XRepository delegate) {
        synchronized (delegates) {
            if (delegate != this) {
                LOGGER.debugf("Remove repository: %s", delegate);
                delegates.remove(delegate);
            }
        }
    }

    public List<XRepository> getRepositoryDelegates() {
        synchronized (delegates) {
            return Collections.unmodifiableList(delegates);
        }
    }

    @Override
    public Collection<Capability> findProviders(Requirement req) {
        if (req == null)
            throw MESSAGES.illegalArgumentNull("req");

        // Try to find the providers in the storage
        List<Capability> providers = new ArrayList<Capability>();
        providers.addAll(storage.findProviders(req));

        // Try to find the providers in the delegates
        if (providers.isEmpty()) {
            for (XRepository delegate : delegates) {
                Collection<Capability> caps = delegate.findProviders(req);
                if (!caps.isEmpty()) {
                    // Add the delegate resources to the storage
                    for (Capability cap : caps) {
                        XResource res = (XResource) cap.getResource();
                        XIdentityCapability icap = res.getIdentityCapability();
                        XResource storageResource = storage.getResource(icap);
                        if (storageResource == null) {
                            storageResource = storage.addResource(res);
                        }
                        providers.add(storageResource.getIdentityCapability());
                    }
                    break;
                }
            }
        }

        return Collections.unmodifiableList(providers);
    }

} public class AbstractResourceInstaller implements ResourceInstaller {

    @Override
    public XBundle installResource(BundleContext context, XResource res) throws BundleException {
        XBundle bundle;
        XIdentityCapability icap = res.getIdentityCapability();
        String namespace = icap.getNamespace();
        if (namespace.equals(IdentityNamespace.IDENTITY_NAMESPACE) && res instanceof RepositoryContent) {
            bundle = installBundleResource(context, res);
        } else {
            bundle = installModuleResource(context, res);
        }
        return bundle;
    }

    @Override
    public XBundle installBundleResource(BundleContext context, XResource res) throws BundleException {
        XIdentityCapability icap = res.getIdentityCapability();
        if (!icap.getNamespace().equals(IdentityNamespace.IDENTITY_NAMESPACE))
            throw RepositoryMessages.MESSAGES.unsupportedResource(res);

        if (!(res instanceof RepositoryContent))
            throw RepositoryMessages.MESSAGES.unsupportedResource(res);

        InputStream input = ((RepositoryContent) res).getContent();
        try {
            return (XBundle) context.installBundle(icap.getName(), input);
        } finally {
            safeClose(input);
        }
    }

    @Override
    public XBundle installModuleResource(BundleContext context, XResource res) throws BundleException {
        throw new UnsupportedOperationException();
    }
    
    private void safeClose(Closeable input) {
        try {
            input.close();
        } catch (IOException e) {
            // ignore
        }
    }
} public class FileBasedRepositoryStorage extends MemoryRepositoryStorage {

    public static final String REPOSITORY_XML_NAME = "repository.xml";

    private final File storageDir;
    private final File repoFile;

    public FileBasedRepositoryStorage(XRepository repository, File storageDir, ConfigurationPropertyProvider propProvider) {
        super(repository);
        if (storageDir == null)
            throw MESSAGES.illegalArgumentNull("storageDir");
        if (propProvider == null)
            throw MESSAGES.illegalArgumentNull("propProvider");

        this.storageDir = storageDir;

        String filename = propProvider.getProperty(XRepository.PROPERTY_REPOSITORY_STORAGE_FILE, REPOSITORY_XML_NAME);
        repoFile = new File(storageDir.getAbsolutePath() + File.separator + filename).getAbsoluteFile();

        // Initialize repository content
        if (repoFile.exists()) {
            RepositoryReader reader;
            try {
                reader = RepositoryXMLReader.create(new FileInputStream(repoFile));
            } catch (IOException ex) {
                throw MESSAGES.cannotInitializeRepositoryReader(ex);
            }
            String incatt = reader.getRepositoryAttributes().get(Attribute.INCREMENT.getLocalName());
            Long increment = new Long(incatt != null ? incatt : "0");
            XResource res = reader.nextResource();
            while(res != null) {
                addResourceInternal(res, false);
                res = reader.nextResource();
            }
            long delta = increment - getResourceIndex().get();
            getResourceIndex().addAndGet(delta);
            reader.close();
        }
    }

    @Override
    public XResource addResource(XResource res) throws RepositoryStorageException {
        return addResourceInternal(res, true);
    }

    private synchronized XResource addResourceInternal(XResource res, boolean writeXML) throws RepositoryStorageException {
        if (res == null)
            throw MESSAGES.illegalArgumentNull("resource");

        XIdentityCapability icap = res.getIdentityCapability();
        if (XResource.MAVEN_IDENTITY_NAMESPACE.equals(icap.getNamespace()))
            throw MESSAGES.cannotAddMavenResourceToStorage(null, res);

        String moduleId = (String) icap.getAttribute(XResource.MODULE_IDENTITY_NAMESPACE);
        if (res.isAbstract() || moduleId != null) {
            return addAbstractResource(res, writeXML);
        } else {
            return addContentResource(res, writeXML);
        }
    }

    private XResource addContentResource(XResource res, boolean writeXML) throws RepositoryStorageException {
        List<Capability> ccaps = res.getCapabilities(ContentNamespace.CONTENT_NAMESPACE);
        if (ccaps.isEmpty())
            throw MESSAGES.cannotObtainContentCapablility(res);

        XCapability ccap = (XCapability) ccaps.get(0);
        String contentURL = (String) ccap.getAttribute(ContentNamespace.CAPABILITY_URL_ATTRIBUTE);
        if (contentURL == null)
            throw MESSAGES.cannotObtainContentURL(res);

        XResource result;

        // Copy the resource to this storage, if the content URL does not match
        if (contentURL.startsWith(getBaseURL().toExternalForm()) == false) {
            XResourceBuilder<XResource> builder = createResourceInternal(res);
            for (Capability cap : res.getCapabilities(null)) {
                if (!ContentNamespace.CONTENT_NAMESPACE.equals(cap.getNamespace())) {
                    builder.addCapability(cap.getNamespace(), cap.getAttributes(), cap.getDirectives());
                }
            }
            for (Requirement req : res.getRequirements(null)) {
                String namespace = req.getNamespace();
                builder.addRequirement(namespace, req.getAttributes(), req.getDirectives());
            }
            result = builder.getResource();
        } else {
            result = res;
        }
        result = super.addResource(result);
        if (writeXML == true) {
            writeRepositoryXML();
        }
        return result;
    }

    private XResource addAbstractResource(XResource res, boolean writeXML) throws RepositoryStorageException {
        XResource result = super.addResource(res);
        if (writeXML == true) {
            writeRepositoryXML();
        }
        return result;
    }

    @Override
    public boolean removeResource(XResource res) throws RepositoryStorageException {
        return removeResourceInternal(res, true);
    }

    private synchronized boolean removeResourceInternal(XResource res, boolean writeXML) {
        boolean result = true;
        List<Capability> ccaps = res.getCapabilities(ContentNamespace.CONTENT_NAMESPACE);
        if (!ccaps.isEmpty()) {
            XCapability ccap = (XCapability) ccaps.iterator().next();
            String fileURL = (String) ccap.getAttribute(ContentNamespace.CAPABILITY_URL_ATTRIBUTE);
            File contentFile = new File(fileURL.substring("file:".length()));
            if (contentFile.exists()) {
                result = deleteRecursive(contentFile.getParentFile());
            }
        }
        result &= super.removeResource(res);
        if (writeXML == true) {
            writeRepositoryXML();
        }
        return result;
    }

    private XResourceBuilder<XResource> createResourceInternal(XResource resource) {
        XResourceBuilder<XResource> factory = null;
        for (Capability cap : resource.getCapabilities(ContentNamespace.CONTENT_NAMESPACE)) {
            XCapability ccap = (XCapability)cap;
            Map<String, Object> contentAtts = new HashMap<String, Object>();
            String mimeType = (String) ccap.getAttribute(ContentNamespace.CAPABILITY_MIME_ATTRIBUTE);
            if (mimeType != null) {
                contentAtts.put(ContentNamespace.CAPABILITY_MIME_ATTRIBUTE, mimeType);
            }
            InputStream input = getResourceContent(ccap);
            try {
                URL contentURL = addResourceContent(input, contentAtts);
                if (factory == null) {
                    factory = URLResourceBuilderFactory.create(contentURL, contentAtts);
                } else {
                    factory.addCapability(ContentNamespace.CONTENT_NAMESPACE, contentAtts, null);
                }
            } catch (IOException ex) {
                throw MESSAGES.cannotAddResourceToStorage(ex, mimeType);
            }
        }
        return factory;
    }

    private InputStream getResourceContent(XCapability ccap) {
        InputStream input;
        Resource resource = ccap.getResource();
        Capability defaultContent = resource.getCapabilities(ContentNamespace.CONTENT_NAMESPACE).get(0);
        if (defaultContent == ccap && resource instanceof RepositoryContent) {
            input = ((RepositoryContent) resource).getContent();
        } else {
            String contentURL = (String) ccap.getAttribute(ContentNamespace.CAPABILITY_URL_ATTRIBUTE);
            try {
                URL url = new URL(contentURL);
                if (url.getProtocol().equals("file")) {
                    return new FileInputStream(URLResourceBuilderFactory.urlToFile(url));
                } else {
                    input = url.openStream();
                }
            } catch (IOException ex) {
                throw MESSAGES.cannotAccessContentURL(ex, contentURL);
            }
            catch (URISyntaxException ex) {
                throw MESSAGES.cannotAccessContentURL(ex, contentURL);
            }
        }
        return input;
    }

    private URL addResourceContent(InputStream input, Map<String, Object> atts) throws IOException {
        synchronized (storageDir) {
            // Copy the input stream to temporary storage
            File tempFile = new File(storageDir.getAbsolutePath() + File.separator + "temp-content");
            Long size = copyResourceContent(input, tempFile);
            atts.put(ContentNamespace.CAPABILITY_SIZE_ATTRIBUTE, size);
            // Calculate the SHA-256
            String sha256;
            String algorithm = RepositoryContentHelper.DEFAULT_DIGEST_ALGORITHM;
            try {
                sha256 = RepositoryContentHelper.getDigest(new FileInputStream(tempFile), algorithm);
                atts.put(ContentNamespace.CONTENT_NAMESPACE, sha256);
            } catch (NoSuchAlgorithmException ex) {
                throw MESSAGES.noSuchAlgorithm(ex, algorithm);
            }
            // Move the content to storage location
            String contentPath = sha256.substring(0, 2) + File.separator + sha256.substring(2) + File.separator + "content";
            File targetFile = new File(storageDir.getAbsolutePath() + File.separator + contentPath);
            targetFile.getParentFile().mkdirs();
            tempFile.renameTo(targetFile);
            URL url = targetFile.toURI().toURL();
            atts.put(ContentNamespace.CAPABILITY_URL_ATTRIBUTE, url.toExternalForm());
            return url;
        }
    }

    private long copyResourceContent(InputStream input, File targetFile) throws IOException {
        int len = 0;
        long total = 0;
        byte[] buf = new byte[4096];
        targetFile.getParentFile().mkdirs();
        OutputStream out = new FileOutputStream(targetFile);
        while ((len = input.read(buf)) >= 0) {
            out.write(buf, 0, len);
            total += len;
        }
        input.close();
        out.close();
        return total;
    }

    private URL getBaseURL() {
        try {
            return storageDir.toURI().toURL();
        } catch (MalformedURLException e) {
            // ignore
            return null;
        }
    }

    private void writeRepositoryXML() {
        RepositoryWriter writer;
        try {
            repoFile.getParentFile().mkdirs();
            writer = RepositoryXMLWriter.create(new FileOutputStream(repoFile));
        } catch (IOException ex) {
            throw MESSAGES.cannotInitializeRepositoryWriter(ex);
        }
        Map<String, String> attributes = new HashMap<String, String>();
        attributes.put(Attribute.NAME.getLocalName(), getRepository().getName());
        attributes.put(Attribute.INCREMENT.getLocalName(), new Long(getResourceIndex().get()).toString());
        writer.writeRepositoryElement(attributes);
        RepositoryReader reader = getRepositoryReader();
        XResource resource = reader.nextResource();
        while(resource != null) {
            writer.writeResource(resource);
            resource = reader.nextResource();
        }
        writer.close();
    }

    private boolean deleteRecursive(File file) {
        boolean result = true;
        if (file.isDirectory()) {
            for (File aux : file.listFiles())
                result &= deleteRecursive(aux);
        }
        result &= file.delete();
        return result;
    }
} public class MavenIdentityRepository extends AbstractRepository implements XRepository {

    private final URL[] baserepos;

    /** The configuration for the {@link MavenIdentityRepository} */
    public interface Configuration {

        /** The default JBoss Nexus repository: http://repository.jboss.org/nexus/content/groups/public */
        String JBOSS_NEXUS_BASE = "http://repository.jboss.org/nexus/content/groups/public";

        /** The default Maven Central repository: http://repo1.maven.org/maven2 */
        String MAVEN_CENTRAL_BASE = "http://repo1.maven.org/maven2";

        /** Get the list of configured base URLs */
        List<URL> getBaseURLs();
    }

    /** A configuration property provider */
    public interface ConfigurationPropertyProvider {

        /** Get the list of configured base URLs */
        String getProperty(String key, String defaultValue);
    }

    public MavenIdentityRepository() {
        this(new ConfigurationPropertyProvider() {
            @Override
            public String getProperty(String key, String defaultValue) {
                return SecurityActions.getSystemProperty(key, defaultValue);
            }
        });
    }

    public MavenIdentityRepository(ConfigurationPropertyProvider provider) {
        this(getDefaultConfiguration(provider));
    }

    public MavenIdentityRepository(Configuration configuration) {
        List<URL> repos = new ArrayList<URL>();
        for (URL baseURL : configuration.getBaseURLs()) {
            repos.add(baseURL);
        }
        baserepos = repos.toArray(new URL[repos.size()]);
    }

    /**
     * Get the default configuration which delegates to
     *
     * #1 The local maven repository at ~/.m2/repository
     * #2 The default JBoss Nexus repository
     * #3 The default Maven Central repository
     */
    public static Configuration getDefaultConfiguration(final ConfigurationPropertyProvider provider) {
        return new Configuration() {
            @Override
            public List<URL> getBaseURLs() {
                List<URL> result = new ArrayList<URL>();
                String property = provider.getProperty(PROPERTY_MAVEN_REPOSITORY_BASE_URLS, null);
                if (property == null) {
                    property = "";
                    String userhome = SecurityActions.getSystemProperty("user.home", "");
                    File localrepo = new File(userhome + File.separator + ".m2" + File.separator + "repository");
                    if (localrepo.isDirectory()) {
                        property += localrepo.toURI().toString() + ",";
                    }
                    property += JBOSS_NEXUS_BASE + ",";
                    property += MAVEN_CENTRAL_BASE;
                }
                for (String urlspec : property.split(",")) {
                    result.add(getBaseURL(urlspec));
                }
                return Collections.unmodifiableList(result);
            }
        };
    }

    @Override
    public Collection<Capability> findProviders(Requirement req) {

        String namespace = req.getNamespace();
        if (!XResource.MAVEN_IDENTITY_NAMESPACE.equals(namespace))
            return Collections.emptyList();

        MavenCoordinates mavenId;
        if (req.getDirectives().get("filter") != null) {
            Filter filter = ((XRequirement)req).getFilter();
            String gpart = AbstractRequirement.getValueFromFilter(filter, "groupId", null);
            String apart = AbstractRequirement.getValueFromFilter(filter, "artifactId", null);
            String tpart = AbstractRequirement.getValueFromFilter(filter, "type", null);
            String vpart = AbstractRequirement.getValueFromFilter(filter, "version", null);
            String cpart = AbstractRequirement.getValueFromFilter(filter, "classifier", null);
            mavenId = MavenCoordinates.create(gpart, apart, vpart, tpart, cpart);
        } else {
            String nsvalue = (String) req.getAttributes().get(XResource.MAVEN_IDENTITY_NAMESPACE);
            mavenId = MavenCoordinates.parse(nsvalue);
        }

        LOGGER.infoFindMavenProviders(mavenId);

        URL contentURL = null;
        for (URL baseURL : baserepos) {
            URL url = mavenId.getArtifactURL(baseURL);
            try {
                url.openStream().close();
                contentURL = url;
                break;
            } catch (IOException e) {
                LOGGER.debugf("Cannot access input stream for: %s", url);
            }
        }

        if (contentURL == null)
            return Collections.emptyList();
        
        XResourceBuilder<XResource> builder = URLResourceBuilderFactory.create(contentURL, null);
        builder.addIdentityCapability(mavenId);
        XResource resource = builder.getResource();
        LOGGER.debugf("Found maven resource: %s", resource);
        
        // Convert the resource to the given target type
        List<Capability> result = new ArrayList<Capability>();
        try {
            resource = getTargetResource(resource);
            result.add(resource.getIdentityCapability());
        } catch (Exception ex) {
            LOGGER.errorCannotCreateResource(ex, mavenId.toExternalForm());
        }

        return Collections.unmodifiableList(result);
    }

    private static URL getBaseURL(String urlspec) {
        try {
            return new URL(urlspec);
        } catch (MalformedURLException e) {
            throw MESSAGES.invalidRepositoryBase(urlspec);
        }
    }
} public interface ConfigurationPropertyProvider {

    /** Get the list of configured base URLs */
    String getProperty(String key, String defaultValue);
} @ProviderType
public interface Repository {
	/**
	 * Service property to provide URLs related to this repository.
	 *
	 * <p>
	 * The value of this property must be of type {@code String},
	 * {@code String[]}, or {@code Collection<String>}.
	 */
	String	URL	= "repository.url";

	/**
	 * Find the capabilities that match the specified requirements.
	 *
	 * @param requirements The requirements for which matching capabilities
	 *        should be returned. Must not be {@code null}.
	 * @return A map of matching capabilities for the specified requirements.
	 *         Each specified requirement must appear as a key in the map. If
	 *         there are no matching capabilities for a specified requirement,
	 *         then the value in the map for the specified requirement must be
	 *         an empty collection. The returned map is the property of the
	 *         caller and can be modified by the caller. The returned map may be
	 *         lazily populated, so calling {@code size()} may result in a long
	 *         running operation.
	 */
	Map<Requirement, Collection<Capability>> findProviders(Collection<? extends Requirement> requirements);

	/**
	 * Find the resources that match the specified requirement expression.
	 *
	 * @param expression The {@code RequirementExpression} for which matching
	 *        capabilities should be returned. Must not be {@code null}.
	 * @return A promise to a collection of matching {@code Resource}s. If there
	 *         are no matching resources, an empty collection is returned. The
	 *         returned collection is the property of the caller and can be
	 *         modified by the caller. The returned collection may be lazily
	 *         populated, so calling {@code size()} may result in a long running
	 *         operation.
	 * @since 1.1
	 */
	Promise<Collection<Resource>> findProviders(RequirementExpression expression);

	/**
	 * Return an expression combiner. An expression combiner can be used to
	 * combine multiple requirement expressions into more complex requirement
	 * expressions using {@link AndExpression and}, {@link OrExpression or} and
	 * {@link NotExpression not} operators.
	 *
	 * @return An {@code ExpressionCombiner}.
	 * @since 1.1
	 */
	ExpressionCombiner getExpressionCombiner();

	/**
	 * Return a new {@code RequirementBuilder} which provides a convenient way
	 * to create a requirement.
	 *
	 * <p>
	 * For example:
	 *
	 * <pre>
     * Requirement myReq = repository.newRequirementBuilder("org.foo.ns1").
     *   addDirective("filter", "(org.foo.ns1=val1)").
     *   addDirective("cardinality", "multiple").build();
	 * </pre>
	 *
	 * @param namespace The namespace for the requirement to be created.
	 * @return A new requirement builder for a requirement in the specified
	 *         namespace.
	 * @since 1.1
	 */
	RequirementBuilder newRequirementBuilder(String namespace);
}
import static org.jboss.osgi.repository.RepositoryMessages.MESSAGES;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
import org.jboss.osgi.repository.RepositoryStorage;
import org.jboss.osgi.repository.RepositoryStorageFactory;
import org.jboss.osgi.repository.ResourceInstaller;
import org.jboss.osgi.repository.XPersistentRepository;
import org.jboss.osgi.repository.XRepository;
import org.jboss.osgi.repository.spi.AbstractPersistentRepository;
import org.jboss.osgi.repository.spi.AbstractResourceInstaller;
import org.jboss.osgi.repository.spi.FileBasedRepositoryStorage;
import org.jboss.osgi.repository.spi.MavenIdentityRepository;
import org.jboss.osgi.repository.spi.MavenIdentityRepository.ConfigurationPropertyProvider;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.repository.Repository;
/*
 * #%L
 * JBossOSGi Repository
 * %%
 * Copyright (C) 2010 - 2012 JBoss by Red Hat
 * %%
 * 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.
 * #L%
 */
package org.jboss.osgi.repository.internal;



/**
 * An activator for {@link Repository} services.
 *
 * @author thomas.diesler@jboss.com
 * @since 16-Jan-2012
 */
public class RepositoryActivator implements BundleActivator {

    private List<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();

    @Override
    public void start(final BundleContext context) throws Exception {

        // Create the {@link ConfigurationPropertyProvider}
        final ConfigurationPropertyProvider propProvider = new ConfigurationPropertyProvider() {
            @Override
            public String getProperty(String key, String defaultValue) {
                String value = context.getProperty(key);
                return value != null ? value : defaultValue;
            }
        };

        // Create the {@link RepositoryStorageFactory}
        final RepositoryStorageFactory factory = new RepositoryStorageFactory() {