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.kernel.impl.utils;
017
018import org.fcrepo.kernel.utils.CacheEntry;
019import org.fcrepo.kernel.utils.FixityResult;
020
021import javax.jcr.RepositoryException;
022
023import static java.util.Objects.hash;
024
025import java.net.URI;
026import java.util.EnumSet;
027import java.util.Set;
028
029/**
030 * Structure for presenting the results of a fixity check
031 * (and any repair operations that may have occurred)
032 *
033 * @author bbpennel
034 */
035public class FixityResultImpl implements FixityResult {
036
037    /**
038     * the size computed by the fixity check
039     * @todo make this private
040     */
041    private long computedSize;
042
043    /**
044     * the checksum computed by the fixity check
045     * @todo make this private
046     */
047    private URI computedChecksum;
048
049    private final String storeIdentifier;
050
051    /**
052     * Prepare a fixity result given the computed checksum and size
053     * @param size the given size
054     * @param checksum the given checksum
055     */
056    public FixityResultImpl(final long size, final URI checksum) {
057        this("comparison-only-identifier", size, checksum);
058    }
059
060    /**
061     * Prepare a fixity result with the expected size and checksum
062     * @param entry the entry
063     * @param size the expected size
064     * @param checksum the checksum
065     * @throws RepositoryException if repository exception occurred
066     */
067    public FixityResultImpl(final CacheEntry entry, final long size,
068                        final URI checksum) throws RepositoryException {
069        this(entry.getExternalIdentifier(), size, checksum);
070    }
071
072    /**
073     *
074     * @param storeIdentifier the store identifier
075     * @param size the size
076     * @param checksum the checksum
077     */
078    public FixityResultImpl(final String storeIdentifier, final long size, final URI checksum) {
079        this.storeIdentifier = storeIdentifier;
080        computedSize = size;
081        computedChecksum = checksum;
082    }
083
084    /**
085     * Get the identifier for the entry's store
086     * @return the store identifier
087     */
088    @Override
089    public String getStoreIdentifier() {
090        return storeIdentifier;
091    }
092
093    @Override
094    public boolean equals(final Object obj) {
095
096        boolean result = false;
097        if (obj instanceof FixityResult) {
098            final FixityResult that = (FixityResult) obj;
099            result =
100                    computedSize == that.getComputedSize() &&
101                            computedChecksum.equals(that.getComputedChecksum());
102        }
103
104        return result;
105    }
106
107    @Override
108    public int hashCode() {
109        return hash(computedSize, computedChecksum);
110    }
111
112    @Override
113    public String toString() {
114        return "Fixity: checksum: " + computedChecksum + " / " +
115            Long.toString(computedSize);
116    }
117
118    /**
119     * Check if the fixity result matches the given checksum URI
120     * @param checksum the checksum uri
121     * @return true if the checksums match
122     */
123    @Override
124    public boolean matches(final URI checksum) {
125        return computedChecksum.equals(checksum);
126    }
127
128    /**
129     * Check if the fixity result matches the given size
130     * @param size the size
131     * @return true if fixity result matches the given size
132     */
133    @Override
134    public boolean matches(final long size) {
135        return computedSize == size;
136    }
137
138    /**
139     * Does the fixity entry match the given size and checksum?
140     * @param size bitstream size in bytes
141     * @param checksum checksum URI in the form urn:DIGEST:RESULT
142     * @return true if both conditions matched
143     */
144    @Override
145    public boolean matches(final long size, final URI checksum) {
146        return matches(size) && matches(checksum);
147    }
148
149    /**
150     * @return the status
151     */
152    @Override
153    public Set<FixityState> getStatus(final long size, final URI checksum) {
154
155        final Set<FixityState> status = EnumSet.noneOf(FixityState.class);
156
157
158        if (matches(size, checksum)) {
159            status.add(FixityState.SUCCESS);
160        } else {
161            if (!matches(size)) {
162                status.add(FixityState.BAD_SIZE);
163            }
164
165            if (!matches(checksum)) {
166                status.add(FixityState.BAD_CHECKSUM);
167            }
168        }
169
170        return status;
171    }
172
173    /**
174     * @return the computedSize
175     */
176    @Override
177    public long getComputedSize() {
178        return computedSize;
179    }
180
181    /**
182     * @return the computedChecksum
183     */
184    @Override
185    public URI getComputedChecksum() {
186        return computedChecksum;
187    }
188
189}