001/*
002 * Copyright 2019 DuraSpace, Inc.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.fcrepo.migration;
018
019import com.fasterxml.jackson.annotation.JsonInclude;
020import com.fasterxml.jackson.databind.ObjectMapper;
021import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
022import edu.wisc.library.ocfl.core.OcflRepositoryBuilder;
023import edu.wisc.library.ocfl.core.extension.storage.layout.config.HashedTruncatedNTupleConfig;
024import edu.wisc.library.ocfl.core.path.mapper.LogicalPathMappers;
025import edu.wisc.library.ocfl.core.storage.filesystem.FileSystemOcflStorage;
026import org.apache.commons.lang3.SystemUtils;
027import org.fcrepo.migration.handlers.ocfl.PlainOcflObjectSessionFactory;
028import org.fcrepo.storage.ocfl.CommitType;
029import org.fcrepo.storage.ocfl.DefaultOcflObjectSessionFactory;
030import org.fcrepo.storage.ocfl.OcflObjectSessionFactory;
031import org.fcrepo.storage.ocfl.cache.NoOpCache;
032import org.springframework.beans.factory.FactoryBean;
033
034import java.nio.file.Path;
035
036import static com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS;
037
038/**
039 * Spring FactoryBean for easy OcflObjectSessionFactory creation.
040 *
041 * @author pwinckles
042 */
043public class OcflSessionFactoryFactoryBean implements FactoryBean<OcflObjectSessionFactory> {
044
045    private final Path ocflRoot;
046    private final Path stagingDir;
047    private final MigrationType migrationType;
048    private final String user;
049    private final String userUri;
050
051    /**
052     * @param ocflRoot OCFL storage root
053     * @param stagingDir OCFL staging dir
054     * @param migrationType migration type
055     * @param user user to add to OCFL versions
056     * @param userUri user's address
057     */
058    public OcflSessionFactoryFactoryBean(final Path ocflRoot,
059                                         final Path stagingDir,
060                                         final MigrationType migrationType,
061                                         final String user,
062                                         final String userUri) {
063        this.ocflRoot = ocflRoot;
064        this.stagingDir = stagingDir;
065        this.migrationType = migrationType;
066        this.user = user;
067        this.userUri = userUri;
068    }
069
070    @Override
071    public OcflObjectSessionFactory getObject() {
072        final var logicalPathMapper = SystemUtils.IS_OS_WINDOWS ?
073                LogicalPathMappers.percentEncodingWindowsMapper() : LogicalPathMappers.percentEncodingLinuxMapper();
074
075        final var ocflRepo =  new OcflRepositoryBuilder()
076                .layoutConfig(new HashedTruncatedNTupleConfig())
077                .logicalPathMapper(logicalPathMapper)
078                .storage(FileSystemOcflStorage.builder().repositoryRoot(ocflRoot).build())
079                .workDir(stagingDir)
080                .buildMutable();
081
082        if (migrationType == MigrationType.FEDORA_OCFL) {
083            final var objectMapper = new ObjectMapper()
084                    .configure(WRITE_DATES_AS_TIMESTAMPS, false)
085                    .registerModule(new JavaTimeModule())
086                    .setSerializationInclusion(JsonInclude.Include.NON_NULL);
087
088            return new DefaultOcflObjectSessionFactory(ocflRepo, stagingDir, objectMapper,
089                    new NoOpCache<>(), CommitType.NEW_VERSION,
090                    "Generated by Fedora 3 to Fedora 6 migration", user, userUri);
091        } else {
092            return new PlainOcflObjectSessionFactory(ocflRepo, stagingDir,
093                    "Generated by Fedora 3 to Fedora 6 migration", user, userUri);
094        }
095    }
096
097    @Override
098    public Class<?> getObjectType() {
099        return OcflObjectSessionFactory.class;
100    }
101
102    @Override
103    public boolean isSingleton() {
104        return true;
105    }
106
107}