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