001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2008-2009 Sun Microsystems, Inc. 015 * Portions Copyright 2015 ForgeRock AS. 016 */ 017 018package org.opends.guitools.controlpanel.datamodel; 019 020import java.io.File; 021import java.text.ParseException; 022import java.util.Objects; 023 024import org.opends.server.util.Base64; 025 026/** 027 * Class used to represent Binary Values. This is required in particular 028 * when the user wants to use the value in a file. To be able to reflect 029 * this this object is used: it contains the binary itself, the base 64 030 * representation and the file that has been used. 031 * 032 */ 033public class BinaryValue 034{ 035 private Type type; 036 private String base64; 037 private byte[] bytes; 038 private File file; 039 private int hashCode; 040 041 /** 042 * The type of the binary value. 043 * 044 */ 045 public enum Type 046 { 047 /** 048 * The binary value is provided as Base 64 string. 049 */ 050 BASE64_STRING, 051 /** 052 * The binary value is provided as a byte array. 053 */ 054 BYTE_ARRAY 055 } 056 057 /** 058 * This is done to force the use of the factory methods (createBase64 and 059 * createFromFile). 060 * 061 */ 062 private BinaryValue() 063 { 064 } 065 066 /** 067 * Creates a binary value using a base64 string. 068 * @param base64 the base64 representation of the binary. 069 * @return the binary value. 070 * @throws ParseException if there is an error decoding the provided base64 071 * string. 072 */ 073 public static BinaryValue createBase64(String base64) throws ParseException 074 { 075 BinaryValue value = new BinaryValue(); 076 value.type = Type.BASE64_STRING; 077 value.base64 = base64; 078 value.bytes = value.getBytes(); 079 value.hashCode = base64.hashCode(); 080 return value; 081 } 082 083 /** 084 * Creates a binary value using an array of bytes. 085 * @param bytes the byte array. 086 * @return the binary value. 087 */ 088 public static BinaryValue createBase64(byte[] bytes) 089 { 090 BinaryValue value = new BinaryValue(); 091 value.type = Type.BASE64_STRING; 092 value.bytes = bytes; 093 value.base64 = value.getBase64(); 094 value.hashCode = value.base64.hashCode(); 095 return value; 096 } 097 098 /** 099 * Creates a binary value using an array of bytes and a file. 100 * @param bytes the bytes in the file. 101 * @param file the file the bytes were read from. 102 * @return the binary value. 103 */ 104 public static BinaryValue createFromFile(byte[] bytes, File file) 105 { 106 BinaryValue value = new BinaryValue(); 107 value.type = Type.BYTE_ARRAY; 108 value.bytes = bytes; 109 value.base64 = value.getBase64(); 110 value.hashCode = value.base64.hashCode(); 111 value.file = file; 112 return value; 113 } 114 115 /** 116 * Returns the base64 representation of the binary value. 117 * @return the base64 representation of the binary value. 118 */ 119 public String getBase64() 120 { 121 if (base64 == null && bytes != null) 122 { 123 base64 = Base64.encode(bytes); 124 } 125 return base64; 126 } 127 128 /** 129 * Returns the byte array of the binary value. 130 * @return the byte array of the binary value. 131 * @throws ParseException if this object was created using a base64 string 132 * and there was an error parsing it. 133 */ 134 public byte[] getBytes() throws ParseException 135 { 136 if (bytes == null && base64 != null) 137 { 138 bytes = Base64.decode(base64); 139 } 140 return bytes; 141 } 142 143 /** 144 * Return the type of the binary value. 145 * @return the type of the binary value. 146 */ 147 public Type getType() 148 { 149 return type; 150 } 151 152 /** 153 * Return the file that was used to read the binary value. 154 * @return the file that was used to read the binary value. 155 */ 156 public File getFile() 157 { 158 return file; 159 } 160 161 /** {@inheritDoc} */ 162 public boolean equals(Object o) 163 { 164 if (this == o) 165 { 166 return true; 167 } 168 if (o instanceof BinaryValue) 169 { 170 BinaryValue candidate = (BinaryValue)o; 171 return candidate.getType() == getType() 172 && Objects.equals(file, candidate.getFile()) 173 && bytesEqual(candidate); 174 } 175 return false; 176 } 177 178 private boolean bytesEqual(BinaryValue candidate) 179 { 180 if (type == Type.BASE64_STRING) 181 { 182 return candidate.getBase64().equals(getBase64()); 183 } 184 185 try 186 { 187 if (candidate.getBytes().length != getBytes().length) { 188 return false; 189 } 190 boolean equals = true; 191 for (int i=0; i<getBytes().length && equals; i++) 192 { 193 equals = bytes[i] == candidate.getBytes()[i]; 194 } 195 return equals; 196 } 197 catch (ParseException pe) 198 { 199 throw new RuntimeException( 200 "Unexpected error getting bytes: "+pe, pe); 201 } 202 } 203 204 /** {@inheritDoc} */ 205 public int hashCode() 206 { 207 return hashCode; 208 } 209}