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
054     * @param 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
063     * @param size
064     * @param checksum
065     */
066    public FixityResultImpl(final CacheEntry entry, final long size,
067                        final URI checksum) throws RepositoryException {
068        this(entry.getExternalIdentifier(), size, checksum);
069    }
070
071    /**
072     *
073     * @param storeIdentifier
074     * @param size
075     * @param checksum
076     */
077    public FixityResultImpl(final String storeIdentifier, final long size, final URI checksum) {
078        this.storeIdentifier = storeIdentifier;
079        computedSize = size;
080        computedChecksum = checksum;
081    }
082
083    /**
084     * Get the identifier for the entry's store
085     * @return the store identifier
086     */
087    @Override
088    public String getStoreIdentifier() {
089        return storeIdentifier;
090    }
091
092    @Override
093    public boolean equals(final Object obj) {
094
095        boolean result = false;
096        if (obj instanceof FixityResult) {
097            final FixityResult that = (FixityResult) obj;
098            result =
099                    computedSize == that.getComputedSize() &&
100                            computedChecksum.equals(that.getComputedChecksum());
101        }
102
103        return result;
104    }
105
106    @Override
107    public int hashCode() {
108        return hash(computedSize, computedChecksum);
109    }
110
111    @Override
112    public String toString() {
113        return "Fixity: checksum: " + computedChecksum + " / " +
114            Long.toString(computedSize);
115    }
116
117    /**
118     * Check if the fixity result matches the given checksum URI
119     * @param checksum
120     * @return true if the checksums match
121     */
122    @Override
123    public boolean matches(final URI checksum) {
124        return computedChecksum.equals(checksum);
125    }
126
127    /**
128     * Check if the fixity result matches the given size
129     * @param size
130     * @return true if fixity result matches the given size
131     */
132    @Override
133    public boolean matches(final long size) {
134        return computedSize == size;
135    }
136
137    /**
138     * Does the fixity entry match the given size and checksum?
139     * @param size bitstream size in bytes
140     * @param checksum checksum URI in the form urn:DIGEST:RESULT
141     * @return true if both conditions matched
142     */
143    @Override
144    public boolean matches(final long size, final URI checksum) {
145        return matches(size) && matches(checksum);
146    }
147
148    /**
149     * @return the status
150     */
151    @Override
152    public Set<FixityState> getStatus(final long size, final URI checksum) {
153
154        final Set<FixityState> status = EnumSet.noneOf(FixityState.class);
155
156
157        if (matches(size, checksum)) {
158            status.add(FixityState.SUCCESS);
159        } else {
160            if (!matches(size)) {
161                status.add(FixityState.BAD_SIZE);
162            }
163
164            if (!matches(checksum)) {
165                status.add(FixityState.BAD_CHECKSUM);
166            }
167        }
168
169        return status;
170    }
171
172    /**
173     * @return the computedSize
174     */
175    @Override
176    public long getComputedSize() {
177        return computedSize;
178    }
179
180    /**
181     * @return the computedChecksum
182     */
183    @Override
184    public URI getComputedChecksum() {
185        return computedChecksum;
186    }
187
188}