Package org.jboss.gravia.repository.spi

Source Code of org.jboss.gravia.repository.spi.AbstractRepositoryStorage

/*
* #%L
* Gravia :: Repository
* %%
* Copyright (C) 2012 - 2014 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.gravia.repository.spi;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

import org.jboss.gravia.repository.MavenDelegateRepository;
import org.jboss.gravia.repository.Namespace100.Attribute;
import org.jboss.gravia.repository.Repository;
import org.jboss.gravia.repository.RepositoryAggregator;
import org.jboss.gravia.repository.RepositoryReader;
import org.jboss.gravia.repository.RepositoryStorage;
import org.jboss.gravia.repository.RepositoryStorageException;
import org.jboss.gravia.repository.RepositoryWriter;
import org.jboss.gravia.resource.Capability;
import org.jboss.gravia.resource.ContentCapability;
import org.jboss.gravia.resource.ContentNamespace;
import org.jboss.gravia.resource.MavenCoordinates;
import org.jboss.gravia.resource.Requirement;
import org.jboss.gravia.resource.Resource;
import org.jboss.gravia.resource.ResourceBuilder;
import org.jboss.gravia.resource.ResourceContent;
import org.jboss.gravia.resource.ResourceIdentity;

/**
* A simple {@link RepositoryStorage} that uses
* the local file system.
*
* @author thomas.diesler@jboss.com
* @since 16-Jan-2012
*/
public abstract class AbstractRepositoryStorage extends MemoryRepositoryStorage {

    private final AtomicLong increment = new AtomicLong();

    public AbstractRepositoryStorage(Repository repository) {
        super(repository);
    }

    public void initRepositoryStorage() throws RepositoryStorageException {

        RepositoryReader reader = getPersistentRepositoryReader();
        if (reader != null) {
            String incatt = reader.getRepositoryAttributes().get(Attribute.INCREMENT.getLocalName());
            increment.set(incatt != null ? new Long(incatt) : increment.get());
            Resource res = reader.nextResource();
            while (res != null) {
                addResourceInternal(res, false);
                res = reader.nextResource();
            }
            reader.close();
        }
    }

    protected abstract ResourceBuilder createResourceBuilder();

    protected abstract RepositoryReader getPersistentRepositoryReader() throws RepositoryStorageException;

    protected abstract RepositoryWriter getPersistentRepositoryWriter() throws RepositoryStorageException;

    protected abstract void addResourceContent(InputStream input, Map<String, Object> atts) throws RepositoryStorageException;

    protected abstract URL getBaseURL();

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

    private synchronized Resource addResourceInternal(Resource resource, boolean writeXML) throws RepositoryStorageException {
        if (resource == null)
            throw new IllegalArgumentException("Null resource");

        // Convert to a maven resource if needed
        Capability icap = resource.getIdentityCapability();
        List<Capability> ccaps = resource.getCapabilities(ContentNamespace.CONTENT_NAMESPACE);
        MavenCoordinates mavenid = (MavenCoordinates) icap.getAttribute(ContentNamespace.CAPABILITY_MAVEN_IDENTITY_ATTRIBUTE);
        if (ccaps.isEmpty() && mavenid != null) {
            Resource mvnres = getMavenResource(mavenid);
            ccaps = mvnres.getCapabilities(ContentNamespace.CONTENT_NAMESPACE);
        }

        if (ccaps.size() > 0) {
            return addContentResource(resource, ccaps, writeXML);
        } else {
            return addAbstractResource(resource, writeXML);
        }
    }

    private Resource getMavenResource(MavenCoordinates mavenid) {
        MavenDelegateRepository mvnrepo = null;
        Repository repository = getRepository();
        Repository delegate = repository.getFallbackRepository();
        if (delegate instanceof MavenDelegateRepository) {
            mvnrepo = (MavenDelegateRepository) delegate;
        } else if (delegate instanceof RepositoryAggregator) {
            RepositoryAggregator aggregator = (RepositoryAggregator) delegate;
            for (Repository repo : aggregator.getDelegates()) {
                if (repo instanceof MavenDelegateRepository) {
                    mvnrepo = (MavenDelegateRepository) repo;
                    break;
                }
            }
        }
        return mvnrepo != null ? mvnrepo.findMavenResource(mavenid) : null;
    }

    private Resource addContentResource(Resource res, List<Capability> ccaps, boolean writeXML) throws RepositoryStorageException {

        // Copy the resource to this storage, if the content URL does not match
        URL urlatt = (URL) ccaps.get(0).getAttribute(ContentNamespace.CAPABILITY_URL_ATTRIBUTE);
        if (urlatt == null || urlatt.toExternalForm().startsWith(getBaseURL().toExternalForm()) == false) {
            ResourceBuilder builder = createResourceBuilder();
            for (Capability cap : res.getCapabilities(null)) {
                if (!ContentNamespace.CONTENT_NAMESPACE.equals(cap.getNamespace())) {
                    builder.addCapability(cap.getNamespace(), cap.getAttributes(), cap.getDirectives());
                }
            }
            for (Capability cap : ccaps) {
                ContentCapability ccap = cap.adapt(ContentCapability.class);
                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 {
                    addResourceContent(input, contentAtts);
                    builder.addCapability(ContentNamespace.CONTENT_NAMESPACE, contentAtts, cap.getDirectives());
                } catch (RepositoryStorageException ex) {
                    throw new RepositoryStorageException("Cannot add resource to storeage: " + mimeType, ex);
                }
            }
            for (Requirement req : res.getRequirements(null)) {
                String namespace = req.getNamespace();
                builder.addRequirement(namespace, req.getAttributes(), req.getDirectives());
            }
            res = builder.getResource();
        }

        Resource result = super.addResource(res);
        if (writeXML == true) {
            writeRepositoryXML();
        }

        return result;
    }

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

    @Override
    public Resource removeResource(ResourceIdentity resid) {
        return removeResourceInternal(resid, true);
    }

    private synchronized Resource removeResourceInternal(ResourceIdentity resid, boolean writeXML) {
        Resource res = getResource(resid);
        List<Capability> ccaps = res.getCapabilities(ContentNamespace.CONTENT_NAMESPACE);
        if (!ccaps.isEmpty()) {
            Capability ccap = ccaps.iterator().next();
            URL fileURL = (URL) ccap.getAttribute(ContentNamespace.CAPABILITY_URL_ATTRIBUTE);
            File contentFile = new File(fileURL.toExternalForm().substring("file:".length()));
            if (contentFile.exists()) {
                deleteRecursive(contentFile.getParentFile());
            }
        }
        super.removeResource(res.getIdentity());
        if (writeXML == true) {
            writeRepositoryXML();
        }
        return res;
    }

    private InputStream getResourceContent(ContentCapability ccap) {
        InputStream input;
        Resource resource = ccap.getResource();
        Capability defaultContent = resource.getCapabilities(ContentNamespace.CONTENT_NAMESPACE).get(0);
        if (defaultContent == ccap) {
            input = resource.adapt(ResourceContent.class).getContent();
        } else {
            URL contentURL = ccap.getContentURL();
            try {
                input = contentURL.openStream();
            } catch (IOException ex) {
                throw new IllegalStateException("Cannot access content URL: " + contentURL, ex);
            }
        }
        return input;
    }

    private void writeRepositoryXML() {
        RepositoryWriter writer;
        try {
            writer = getPersistentRepositoryWriter();
        } catch (RepositoryStorageException ex) {
            throw new IllegalStateException("Cannot initialize repository writer", ex);
        }
        Map<String, String> attributes = new HashMap<String, String>();
        attributes.put(Attribute.NAME.getLocalName(), getRepository().getName());
        attributes.put(Attribute.INCREMENT.getLocalName(), increment.toString());
        writer.writeRepositoryElement(attributes);
        RepositoryReader reader = getRepositoryReader();
        Resource 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;
    }
}
TOP

Related Classes of org.jboss.gravia.repository.spi.AbstractRepositoryStorage

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.