001 /* 002 * JBoss DNA (http://www.jboss.org/dna) 003 * See the COPYRIGHT.txt file distributed with this work for information 004 * regarding copyright ownership. Some portions may be licensed 005 * to Red Hat, Inc. under one or more contributor license agreements. 006 * See the AUTHORS.txt file in the distribution for a full listing of 007 * individual contributors. 008 * 009 * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA 010 * is licensed to you under the terms of the GNU Lesser General Public License as 011 * published by the Free Software Foundation; either version 2.1 of 012 * the License, or (at your option) any later version. 013 * 014 * JBoss DNA is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 017 * Lesser General Public License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this software; if not, write to the Free 021 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 022 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 023 */ 024 package org.jboss.dna.graph.property.basic; 025 026 import java.io.File; 027 import java.io.IOException; 028 import java.io.InputStream; 029 import java.security.NoSuchAlgorithmException; 030 import java.util.Set; 031 import java.util.concurrent.CopyOnWriteArraySet; 032 import net.jcip.annotations.Immutable; 033 import org.jboss.dna.common.util.Base64; 034 import org.jboss.dna.common.util.Logger; 035 import org.jboss.dna.common.util.SecureHash; 036 import org.jboss.dna.graph.GraphI18n; 037 import org.jboss.dna.graph.property.Binary; 038 import org.jboss.dna.graph.property.ValueComparators; 039 040 /** 041 * An abstract implementation of {@link Binary} that provides some common capabilities for other implementations. 042 * 043 * @author Randall Hauch 044 */ 045 @Immutable 046 public abstract class AbstractBinary implements Binary { 047 048 protected static final Set<String> ALGORITHMS_NOT_FOUND_AND_LOGGED = new CopyOnWriteArraySet<String>(); 049 private static final SecureHash.Algorithm ALGORITHM = SecureHash.Algorithm.SHA_1; 050 private static final byte[] NO_HASH = new byte[] {}; 051 052 protected static final byte[] EMPTY_CONTENT = new byte[0]; 053 054 /** 055 * Version {@value} . 056 */ 057 private static final long serialVersionUID = 1L; 058 059 protected AbstractBinary() { 060 } 061 062 protected byte[] computeHash( byte[] content ) { 063 try { 064 return SecureHash.getHash(ALGORITHM, content); 065 } catch (NoSuchAlgorithmException e) { 066 if (ALGORITHMS_NOT_FOUND_AND_LOGGED.add(ALGORITHM.digestName())) { 067 Logger.getLogger(getClass()).error(e, GraphI18n.messageDigestNotFound, ALGORITHM.digestName()); 068 } 069 return NO_HASH; 070 } 071 } 072 073 protected byte[] computeHash( File file ) { 074 try { 075 return SecureHash.getHash(ALGORITHM, file); 076 } catch (NoSuchAlgorithmException e) { 077 if (ALGORITHMS_NOT_FOUND_AND_LOGGED.add(ALGORITHM.digestName())) { 078 Logger.getLogger(getClass()).error(e, GraphI18n.messageDigestNotFound, ALGORITHM.digestName()); 079 } 080 return NO_HASH; 081 } catch (IOException e) { 082 if (ALGORITHMS_NOT_FOUND_AND_LOGGED.add(ALGORITHM.digestName())) { 083 Logger.getLogger(getClass()).error(e, GraphI18n.messageDigestNotFound, ALGORITHM.digestName()); 084 } 085 return NO_HASH; 086 } 087 } 088 089 protected byte[] computeHash( InputStream stream ) { 090 try { 091 return SecureHash.getHash(ALGORITHM, stream); 092 } catch (NoSuchAlgorithmException e) { 093 if (ALGORITHMS_NOT_FOUND_AND_LOGGED.add(ALGORITHM.digestName())) { 094 Logger.getLogger(getClass()).error(e, GraphI18n.messageDigestNotFound, ALGORITHM.digestName()); 095 } 096 return NO_HASH; 097 } catch (IOException e) { 098 if (ALGORITHMS_NOT_FOUND_AND_LOGGED.add(ALGORITHM.digestName())) { 099 Logger.getLogger(getClass()).error(e, GraphI18n.messageDigestNotFound, ALGORITHM.digestName()); 100 } 101 return NO_HASH; 102 } 103 } 104 105 /** 106 * {@inheritDoc} 107 */ 108 public int compareTo( Binary o ) { 109 return ValueComparators.BINARY_COMPARATOR.compare(this, o); 110 } 111 112 /** 113 * {@inheritDoc} 114 */ 115 @Override 116 public boolean equals( Object obj ) { 117 if (obj == this) return true; 118 if (obj instanceof Binary) { 119 Binary that = (Binary)obj; 120 if (this.getSize() != that.getSize()) return false; 121 return ValueComparators.BINARY_COMPARATOR.compare(this, that) == 0; 122 } 123 return false; 124 } 125 126 /** 127 * {@inheritDoc} 128 */ 129 @Override 130 public String toString() { 131 try { 132 acquire(); 133 StringBuilder sb = new StringBuilder(super.toString()); 134 sb.append("binary["); 135 sb.append(getSize()); 136 sb.append("] with hash "); 137 sb.append(Base64.encodeBytes(getHash())); 138 return sb.toString(); 139 } finally { 140 release(); 141 } 142 } 143 144 }