fr.inria.atlanmod.neoemf.map.datastore.MapPersistenceBackendFactory.java Source code

Java tutorial

Introduction

Here is the source code for fr.inria.atlanmod.neoemf.map.datastore.MapPersistenceBackendFactory.java

Source

/*******************************************************************************
 * Copyright (c) 2013 Atlanmod INRIA LINA Mines Nantes
 * 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:
 *     Atlanmod INRIA LINA Mines Nantes - initial API and implementation
 *******************************************************************************/
package fr.inria.atlanmod.neoemf.map.datastore;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Map;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.io.FileUtils;
import org.eclipse.emf.common.util.URI;
import org.mapdb.DB;
import org.mapdb.DBMaker;
import org.mapdb.Engine;

import fr.inria.atlanmod.neoemf.datastore.AbstractPersistenceBackendFactory;
import fr.inria.atlanmod.neoemf.datastore.InvalidDataStoreException;
import fr.inria.atlanmod.neoemf.datastore.PersistenceBackend;
import fr.inria.atlanmod.neoemf.datastore.estores.SearcheableResourceEStore;
import fr.inria.atlanmod.neoemf.logger.NeoLogger;
import fr.inria.atlanmod.neoemf.map.datastore.estores.impl.AutocommitMapResourceEStoreImpl;
import fr.inria.atlanmod.neoemf.map.datastore.estores.impl.CachedManyDirectWriteMapResourceEStoreImpl;
import fr.inria.atlanmod.neoemf.map.datastore.estores.impl.DirectWriteMapResourceEStoreImpl;
import fr.inria.atlanmod.neoemf.map.datastore.estores.impl.DirectWriteMapResourceWithListsEStoreImpl;
import fr.inria.atlanmod.neoemf.map.datastore.estores.impl.DirectWriteMapWithIndexesResourceEStoreImpl;
import fr.inria.atlanmod.neoemf.map.resources.MapResourceOptions;
import fr.inria.atlanmod.neoemf.map.util.NeoMapURI;
import fr.inria.atlanmod.neoemf.resources.PersistentResource;
import fr.inria.atlanmod.neoemf.resources.PersistentResourceOptions;

public class MapPersistenceBackendFactory extends AbstractPersistenceBackendFactory {

    public static final String MAPDB_BACKEND = "mapdb";

    @Override
    public PersistenceBackend createTransientBackend() {
        Engine mapEngine = DBMaker.newMemoryDB().makeEngine();
        return new MapPersistenceBackend(mapEngine);
    }

    @Override
    public SearcheableResourceEStore createTransientEStore(PersistentResource resource,
            PersistenceBackend backend) {
        assert backend instanceof DB : "Trying to create a Map-based EStore with an invalid backend";
        return new DirectWriteMapResourceEStoreImpl(resource, (DB) backend);
    }

    @Override
    public PersistenceBackend createPersistentBackend(File file, Map<?, ?> options)
            throws InvalidDataStoreException {
        File dbFile = FileUtils.getFile(
                NeoMapURI.createNeoMapURI(URI.createFileURI(file.getAbsolutePath()).appendSegment("neoemf.mapdb"))
                        .toFileString());
        if (!dbFile.getParentFile().exists()) {
            dbFile.getParentFile().mkdirs();
        }
        PropertiesConfiguration neoConfig = null;
        Path neoConfigPath = Paths.get(file.getAbsolutePath()).resolve(NEO_CONFIG_FILE);
        try {
            neoConfig = new PropertiesConfiguration(neoConfigPath.toFile());
        } catch (ConfigurationException e) {
            throw new InvalidDataStoreException(e);
        }
        if (!neoConfig.containsKey(BACKEND_PROPERTY)) {
            neoConfig.setProperty(BACKEND_PROPERTY, MAPDB_BACKEND);
        }
        if (neoConfig != null) {
            try {
                neoConfig.save();
            } catch (ConfigurationException e) {
                NeoLogger.log(NeoLogger.SEVERITY_ERROR, e);
            }
        }
        Engine mapEngine = DBMaker.newFileDB(dbFile).cacheLRUEnable().mmapFileEnableIfSupported().asyncWriteEnable()
                .makeEngine();
        return new MapPersistenceBackend(mapEngine);
    }

    @Override
    protected SearcheableResourceEStore internalCreatePersistentEStore(PersistentResource resource,
            PersistenceBackend backend, Map<?, ?> options) throws InvalidDataStoreException {
        assert backend instanceof DB : "Trying to create a Map-based EStore with an invalid backend";
        @SuppressWarnings("unchecked")
        ArrayList<PersistentResourceOptions.StoreOption> storeOptions = (ArrayList<PersistentResourceOptions.StoreOption>) options
                .get(PersistentResourceOptions.STORE_OPTIONS);
        if (storeOptions == null || storeOptions.isEmpty()
                || storeOptions.contains(MapResourceOptions.EStoreMapOption.DIRECT_WRITE)) {
            // Default store
            return new DirectWriteMapResourceEStoreImpl(resource, (MapPersistenceBackend) backend);
        } else {
            if (storeOptions.contains(MapResourceOptions.EStoreMapOption.AUTOCOMMIT)) {
                return new AutocommitMapResourceEStoreImpl(resource, (MapPersistenceBackend) backend);
            } else if (storeOptions.contains(MapResourceOptions.EStoreMapOption.CACHED_MANY)) {
                return new CachedManyDirectWriteMapResourceEStoreImpl(resource, (MapPersistenceBackend) backend);
            } else if (storeOptions.contains(MapResourceOptions.EStoreMapOption.DIRECT_WRITE_WITH_LISTS)) {
                return new DirectWriteMapResourceWithListsEStoreImpl(resource, (MapPersistenceBackend) backend);
            } else if (storeOptions.contains(MapResourceOptions.EStoreMapOption.DIRECT_WRITE_WITH_INDEXES)) {
                return new DirectWriteMapWithIndexesResourceEStoreImpl(resource, (MapPersistenceBackend) backend);
            } else {
                throw new InvalidDataStoreException();
            }
        }
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public void copyBackend(PersistenceBackend from, PersistenceBackend to) {
        assert from instanceof MapPersistenceBackend : "The backend to copy is not an instance of MapPersistenceBackend";
        assert to instanceof MapPersistenceBackend : "The target copy backend is not an instance of MapPersistenceBackend";
        MapPersistenceBackend mapFrom = (MapPersistenceBackend) from;
        MapPersistenceBackend mapTo = (MapPersistenceBackend) to;
        Map<String, Object> fromAll = mapFrom.getAll();
        for (String fromKey : fromAll.keySet()) {
            Object collection = fromAll.get(fromKey);
            if (collection instanceof Map) {
                Map fromMap = (Map) collection;
                Map toMap = mapTo.getHashMap(fromKey);
                toMap.putAll(fromMap);
            } else {
                throw new UnsupportedOperationException("Cannot copy Map backend: store type "
                        + collection.getClass().getSimpleName() + " is not supported");
            }
        }
    }

}