001/*
002 * Copyright 2015 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 */
016package org.fcrepo.migration.handlers;
017
018import java.util.ArrayList;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022
023import org.fcrepo.migration.DatastreamVersion;
024import org.fcrepo.migration.FedoraObjectHandler;
025import org.fcrepo.migration.ObjectInfo;
026import org.fcrepo.migration.ObjectProperties;
027import org.fcrepo.migration.ObjectReference;
028import org.fcrepo.migration.StreamingFedoraObjectHandler;
029
030/**
031 * A StreamingFedoraObjectHandler implementation that caches all the references to
032 * the Fedora 3 object and provides them to a FedoraObjectHandler implementation
033 * which in turn can process the object as a whole in a random-access fashion rather
034 * than as a stream.
035 * @author mdurbin
036 */
037public class ObjectAbstractionStreamingFedoraObjectHandler implements StreamingFedoraObjectHandler {
038
039    private FedoraObjectHandler handler;
040
041    private ObjectInfo objectInfo;
042
043    private ObjectProperties objectProperties;
044
045    private List<String> dsIds;
046
047    private Map<String, List<DatastreamVersion>> dsIdToVersionListMap;
048
049    private int disseminatorsSkipped = 0;
050
051    /**
052     * the object abstraction streaming fedora object handler.
053     * @param objectHandler the fedora object handler
054     */
055    public ObjectAbstractionStreamingFedoraObjectHandler(final FedoraObjectHandler objectHandler) {
056        this.handler = objectHandler;
057        this.dsIds = new ArrayList<String>();
058        this.dsIdToVersionListMap = new HashMap<String, List<DatastreamVersion>>();
059    }
060
061    @Override
062    public void beginObject(final ObjectInfo object) {
063        this.objectInfo = object;
064    }
065
066    @Override
067    public void processObjectProperties(final ObjectProperties properties) {
068        this.objectProperties = properties;
069    }
070
071    @Override
072    public void processDatastreamVersion(final DatastreamVersion dsVersion) {
073        List<DatastreamVersion> versions = dsIdToVersionListMap.get(dsVersion.getDatastreamInfo().getDatastreamId());
074        if (versions == null) {
075            dsIds.add(dsVersion.getDatastreamInfo().getDatastreamId());
076            versions = new ArrayList<DatastreamVersion>();
077            dsIdToVersionListMap.put(dsVersion.getDatastreamInfo().getDatastreamId(), versions);
078        }
079        versions.add(dsVersion);
080    }
081
082    @Override
083    public void processDisseminator() {
084        disseminatorsSkipped ++;
085    }
086
087    @Override
088    public void completeObject(final ObjectInfo object) {
089        try {
090            handler.processObject(new ObjectReference() {
091                @Override
092                public ObjectInfo getObjectInfo() {
093                    return objectInfo;
094                }
095
096                @Override
097                public ObjectProperties getObjectProperties() {
098                    return objectProperties;
099                }
100
101                @Override
102                public List<String> listDatastreamIds() {
103                    return dsIds;
104                }
105
106                @Override
107                public List<DatastreamVersion> getDatastreamVersions(final String datastreamId) {
108                    return dsIdToVersionListMap.get(datastreamId);
109                }
110
111                @Override
112                public boolean hadFedora2Disseminators() {
113                    return disseminatorsSkipped > 0;
114                }
115            });
116        } finally {
117            cleanForReuse();
118        }
119    }
120
121    @Override
122    public void abortObject(final ObjectInfo object) {
123        cleanForReuse();
124    }
125
126    /**
127     * Removes any state that's specific to a Fedora 3 object that was processed
128     * so that this Handler may be reused for a different object.
129     */
130    private void cleanForReuse() {
131        this.dsIds.clear();
132        this.dsIdToVersionListMap.clear();
133    }
134}