org.eclipse.dirigible.repository.local.FileSystemRepository.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.dirigible.repository.local.FileSystemRepository.java

Source

/*******************************************************************************
 * Copyright (c) 2015 SAP and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * Contributors:
 * SAP - initial API and implementation
 *******************************************************************************/

package org.eclipse.dirigible.repository.local;

import static org.apache.commons.io.IOCase.INSENSITIVE;
import static org.apache.commons.io.IOCase.SENSITIVE;
import static org.apache.commons.io.filefilter.TrueFileFilter.TRUE;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.AgeFileFilter;
import org.apache.commons.io.filefilter.WildcardFileFilter;
import org.eclipse.dirigible.repository.api.ICollection;
import org.eclipse.dirigible.repository.api.IEntity;
import org.eclipse.dirigible.repository.api.IRepository;
import org.eclipse.dirigible.repository.api.IResource;
import org.eclipse.dirigible.repository.api.IResourceVersion;
import org.eclipse.dirigible.repository.api.RepositoryPath;
import org.eclipse.dirigible.repository.logging.Logger;
import org.eclipse.dirigible.repository.zip.ZipExporter;
import org.eclipse.dirigible.repository.zip.ZipImporter;

/**
 * The File System based implementation of {@link IRepository}
 */
public class FileSystemRepository implements IRepository {

    private static final String CURRENT_DIR = ".";
    private static final String DIRIGIBLE_LOCAL = "dirigible_local";
    public static final String PATH_SEGMENT_ROOT = "root";
    public static final String PATH_SEGMENT_VERSIONS = "versions";
    public static final String PATH_SEGMENT_INFO = "info";

    private static final String PROVIDED_ZIP_DATA_CANNOT_BE_NULL = Messages
            .getString("DBRepository.PROVIDED_ZIP_DATA_CANNOT_BE_NULL"); //$NON-NLS-1$

    private static final String PROVIDED_ZIP_INPUT_STREAM_CANNOT_BE_NULL = Messages
            .getString("DBRepository.PROVIDED_ZIP_INPUT_STREAM_CANNOT_BE_NULL"); //$NON-NLS-1$

    private static Logger logger = Logger.getLogger(FileSystemRepository.class);

    public static final String PATH_DELIMITER = IRepository.SEPARATOR;

    private String repositoryPath = IRepository.SEPARATOR;
    private String versionsPath = IRepository.SEPARATOR;
    private String infoPath = IRepository.SEPARATOR;

    private LocalRepositoryDAO repositoryDAO;
    // private LocalZipImporter importer;
    // private LocalZipExporter exporter;

    private String user;

    /**
     * Constructor with default root folder - user.dir and without database initialization
     *
     * @param user
     * @throws LocalBaseException
     */
    public FileSystemRepository(String user) throws LocalBaseException {
        this(user, null, false);
    }

    /**
     * Constructor with root folder parameter
     *
     * @param user
     * @param rootFolder
     * @throws LocalBaseException
     */
    public FileSystemRepository(String user, String rootFolder) throws LocalBaseException {
        this(user, rootFolder, false);
    }

    /**
     * Constructor with root folder parameter
     *
     * @param user
     * @param rootFolder
     * @param absolute
     * @throws LocalBaseException
     */
    public FileSystemRepository(String user, String rootFolder, boolean absolute) throws LocalBaseException {
        String root;
        if (absolute) {
            if (rootFolder != null) {
                root = rootFolder;
            } else {
                throw new LocalBaseException(
                        "Creating a FileSystemRepository with absolute path flag, but the path itself is null");
            }
        } else {
            root = System.getProperty("user.dir");
            if ((rootFolder != null) && !rootFolder.equals(CURRENT_DIR)) {
                root += File.separator;
                root += rootFolder;
            }
        }
        this.user = user;
        this.repositoryDAO = new LocalRepositoryDAO(this);

        initializeRepository(root);
    }

    public String getRepositoryPath() {
        return repositoryPath;
    }

    public String getVersionsPath() {
        return versionsPath;
    }

    public String getInfoPath() {
        return infoPath;
    }

    protected String getRepositoryRootFolder() {
        return DIRIGIBLE_LOCAL;
    }

    private void initializeRepository(String rootFolder) {
        repositoryPath = rootFolder + IRepository.SEPARATOR + getRepositoryRootFolder() + IRepository.SEPARATOR
                + PATH_SEGMENT_ROOT; // $NON-NLS-1$
        repositoryPath = repositoryPath.replace(IRepository.SEPARATOR, File.separator);
        versionsPath = rootFolder + IRepository.SEPARATOR + getRepositoryRootFolder() + IRepository.SEPARATOR
                + PATH_SEGMENT_VERSIONS; // $NON-NLS-1$
        versionsPath = versionsPath.replace(IRepository.SEPARATOR, File.separator);
        infoPath = rootFolder + IRepository.SEPARATOR + getRepositoryRootFolder() + IRepository.SEPARATOR
                + PATH_SEGMENT_INFO; // $NON-NLS-1$
        infoPath = infoPath.replace(IRepository.SEPARATOR, File.separator);
    }

    @Override
    public ICollection getRoot() {
        logger.debug("entering getRoot"); //$NON-NLS-1$
        final RepositoryPath wrapperPath = new RepositoryPath(IRepository.SEPARATOR);
        LocalCollection dbCollection = new LocalCollection(this, wrapperPath);
        logger.debug("exiting getRoot"); //$NON-NLS-1$
        return dbCollection;
    }

    @Override
    public ICollection createCollection(String path) throws IOException {
        logger.debug("entering createCollection"); //$NON-NLS-1$
        final RepositoryPath wrapperPath = new RepositoryPath(path);
        final LocalCollection collection = new LocalCollection(this, wrapperPath);
        collection.create();
        logger.debug("exiting createCollection"); //$NON-NLS-1$
        return collection;
    }

    @Override
    public ICollection getCollection(String path) {
        logger.debug("entering getCollection"); //$NON-NLS-1$
        final RepositoryPath wrapperPath = new RepositoryPath(path);
        LocalCollection localCollection = new LocalCollection(this, wrapperPath);
        logger.debug("exiting getCollection"); //$NON-NLS-1$
        return localCollection;
    }

    @Override
    public void removeCollection(String path) throws IOException {
        logger.debug("entering removeCollection"); //$NON-NLS-1$
        final RepositoryPath wrapperPath = new RepositoryPath(path);
        final ICollection collection = new LocalCollection(this, wrapperPath);
        collection.delete();
        logger.debug("exiting removeCollection"); //$NON-NLS-1$
    }

    @Override
    public boolean hasCollection(String path) throws IOException {
        logger.debug("entering hasCollection"); //$NON-NLS-1$
        final RepositoryPath wrapperPath = new RepositoryPath(path);
        final ICollection collection = new LocalCollection(this, wrapperPath);
        boolean result = collection.exists();
        logger.debug("exiting hasCollection"); //$NON-NLS-1$
        return result;
    }

    @Override
    public IResource createResource(String path) throws IOException {
        logger.debug("entering createResource"); //$NON-NLS-1$
        final RepositoryPath wrapperPath = new RepositoryPath(path);
        final IResource resource = new LocalResource(this, wrapperPath);
        resource.create();
        logger.debug("exiting createResource"); //$NON-NLS-1$
        return resource;
    }

    @Override
    public IResource createResource(String path, byte[] content) throws IOException {
        logger.debug("entering createResource with Content"); //$NON-NLS-1$
        final RepositoryPath wrapperPath = new RepositoryPath(path);
        final IResource resource = new LocalResource(this, wrapperPath);
        resource.setContent(content);
        logger.debug("exiting createResource with Content"); //$NON-NLS-1$
        return resource;
    }

    @Override
    public IResource createResource(String path, byte[] content, boolean isBinary, String contentType)
            throws IOException {
        return createResource(path, content, isBinary, contentType, false);
    }

    @Override
    public IResource createResource(String path, byte[] content, boolean isBinary, String contentType,
            boolean override) throws IOException {
        logger.debug("entering createResource with Content"); //$NON-NLS-1$
        try {
            getRepositoryDAO().createFile(path, content, isBinary, contentType);
        } catch (LocalBaseException e) {
            throw new IOException(e);
        }
        final IResource resource = getResource(path);
        logger.debug("exiting createResource with Content"); //$NON-NLS-1$
        return resource;
    }

    @Override
    public IResource getResource(String path) {
        logger.debug("entering getResource"); //$NON-NLS-1$
        final RepositoryPath wrapperPath = new RepositoryPath(path);
        LocalResource resource = new LocalResource(this, wrapperPath);
        logger.debug("exiting getResource"); //$NON-NLS-1$
        return resource;
    }

    @Override
    public void removeResource(String path) throws IOException {
        logger.debug("entering removeResource"); //$NON-NLS-1$
        final RepositoryPath wrapperPath = new RepositoryPath(path);
        final IResource resource = new LocalResource(this, wrapperPath);
        resource.delete();
        logger.debug("exiting removeResource"); //$NON-NLS-1$
    }

    @Override
    public boolean hasResource(String path) throws IOException {
        logger.debug("entering hasResource"); //$NON-NLS-1$
        final RepositoryPath wrapperPath = new RepositoryPath(path);
        final IResource resource = new LocalResource(this, wrapperPath);
        boolean result = resource.exists();
        logger.debug("exiting hasResource"); //$NON-NLS-1$
        return result;
    }

    @Override
    public void dispose() {
        // repositoryDAO.dispose();
    }

    public LocalRepositoryDAO getRepositoryDAO() {
        return repositoryDAO;
    }

    @Override
    public void importZip(ZipInputStream zipInputStream, String path) throws IOException {
        importZip(zipInputStream, path, false);
    }

    @Override
    public void importZip(ZipInputStream zipInputStream, String path, boolean override) throws IOException {
        importZip(zipInputStream, path, override, false);
    }

    @Override
    public void importZip(ZipInputStream zipInputStream, String relativeRoot, boolean override,
            boolean excludeRootFolderName) throws IOException {
        if (zipInputStream == null) {
            logger.error(PROVIDED_ZIP_INPUT_STREAM_CANNOT_BE_NULL);
            throw new IOException(PROVIDED_ZIP_INPUT_STREAM_CANNOT_BE_NULL);
        }
        // TODO make use of override and excludeRootFolderName arguments?
        // importer.unzip(relativeRoot, zipInputStream, null);
        ZipImporter.importZip(this, zipInputStream, relativeRoot, override, excludeRootFolderName);
    }

    @Override
    public void importZip(byte[] data, String path) throws IOException {
        importZip(data, path, false);
    }

    @Override
    public void importZip(byte[] data, String path, boolean override) throws IOException {
        importZip(data, path, override, false, null);
    }

    @Override
    public void importZip(byte[] data, String relativeRoot, boolean override, boolean excludeRootFolderName,
            Map<String, String> filter) throws IOException {
        if (data == null) {
            logger.error(PROVIDED_ZIP_DATA_CANNOT_BE_NULL);
            throw new IOException(PROVIDED_ZIP_DATA_CANNOT_BE_NULL);
        }
        // TODO make use of override and excludeRootFolderName arguments?
        // importer.unzip(relativeRoot, new ZipInputStream(new ByteArrayInputStream(data)), filter);
        ZipImporter.importZip(this, new ZipInputStream(new ByteArrayInputStream(data)), relativeRoot, override,
                excludeRootFolderName, filter);
    }

    // @Override
    // public byte[] exportZip(List<String> relativeRoots) throws IOException {
    // ByteArrayOutputStream baos = new ByteArrayOutputStream();
    // ZipOutputStream zipOutputStream = new ZipOutputStream(baos);
    // exporter.zip(relativeRoots, zipOutputStream);
    // return baos.toByteArray();
    // }
    //
    // @Override
    // public byte[] exportZip(String path, boolean inclusive) throws IOException {
    // ByteArrayOutputStream baos = new ByteArrayOutputStream();
    // ZipOutputStream zipOutputStream = new ZipOutputStream(baos);
    // try {
    // exporter.zip(path, zipOutputStream, inclusive);
    // } finally {
    // zipOutputStream.flush();
    // zipOutputStream.close();
    // }
    //
    // return baos.toByteArray();
    // }

    @Override
    public byte[] exportZip(List<String> relativeRoots) throws IOException {
        return ZipExporter.exportZip(this, relativeRoots);
    }

    @Override
    public byte[] exportZip(String relativeRoot, boolean inclusive) throws IOException {
        return ZipExporter.exportZip(this, relativeRoot, inclusive);
    }

    @Override
    public List<IEntity> searchName(String parameter, boolean caseInsensitive) throws IOException {
        // return repositoryDAO.searchName(parameter, caseInsensitive);
        return null;
    }

    @Override
    public List<IEntity> searchName(String root, String parameter, boolean caseInsensitive) throws IOException {

        String workspacePath = LocalWorkspaceMapper.getMappedName(this, root);

        List<IEntity> entities = new ArrayList<IEntity>();

        if ((parameter == null) || "".equals(parameter)) {
            return entities;
        }

        File dir = new File(workspacePath);

        Iterator<File> foundFiles = FileUtils.iterateFiles(dir,
                new WildcardFileFilter("*" + parameter + "*", (caseInsensitive ? INSENSITIVE : SENSITIVE)), TRUE);
        while (foundFiles.hasNext()) {
            File foundFile = foundFiles.next();
            String repositoryName = foundFile.getCanonicalPath().substring(getRepositoryPath().length());
            RepositoryPath localRepositoryPath = new RepositoryPath(repositoryName);
            entities.add(new LocalResource(this, localRepositoryPath));
        }

        return entities;
    }

    @Override
    public List<IEntity> searchPath(String parameter, boolean caseInsensitive) throws IOException {
        String rootRepositoryPath = getRepositoryPath();
        List<IEntity> entities = new ArrayList<IEntity>();
        Iterator<File> foundFiles = FileUtils.iterateFiles(new File(rootRepositoryPath),
                new WildcardFileFilter("*" + parameter + "*", (caseInsensitive ? INSENSITIVE : SENSITIVE)), TRUE);
        while (foundFiles.hasNext()) {
            File foundFile = foundFiles.next();
            String repositoryName = foundFile.getCanonicalPath().substring(getRepositoryPath().length());
            RepositoryPath localRepositoryPath = new RepositoryPath(repositoryName);
            entities.add(new LocalResource(this, localRepositoryPath));
        }

        return entities;
    }

    @Override
    public List<IEntity> searchText(String parameter, boolean caseInsensitive) throws IOException {
        // return repositoryDAO.searchText(parameter, caseInsensitive);
        return null;
    }

    @Override
    public List<IResourceVersion> getResourceVersions(String path) throws IOException {
        return repositoryDAO.getResourceVersionsByPath(path);
    }

    @Override
    public IResourceVersion getResourceVersion(String path, int version) throws IOException {
        List<IResourceVersion> allVersions = getResourceVersions(path);
        for (IResourceVersion resourceVersion : allVersions) {
            if (resourceVersion.getVersion() == version) {
                return resourceVersion;
            }
        }
        return null;
    }

    @Override
    public void cleanupOldVersions() throws IOException {
        String versionsRoot = getVersionsPath();
        synchronized (this.getClass()) {
            GregorianCalendar last = new GregorianCalendar();
            last.add(Calendar.WEEK_OF_YEAR, -1);
            thresholdDate = last.getTime();
            cleanOlderFiles(new File(versionsRoot));
        }
    }

    Date thresholdDate;

    private void cleanOlderFiles(File file) {
        Iterator<File> filesToBeDeleted = FileUtils.iterateFiles(file, new AgeFileFilter(thresholdDate), TRUE);
        while (filesToBeDeleted.hasNext()) {
            File toBeDeleted = filesToBeDeleted.next();
            toBeDeleted.delete();
        }
    }

    @Override
    public String getUser() {
        return user;
    }

}