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-2016 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 */ 032public class BinaryValue 033{ 034 private Type type; 035 private String base64; 036 private byte[] bytes; 037 private File file; 038 private int hashCode; 039 040 /** The type of the binary value. */ 041 public enum Type 042 { 043 /** The binary value is provided as Base 64 string. */ 044 BASE64_STRING, 045 /** The binary value is provided as a byte array. */ 046 BYTE_ARRAY 047 } 048 049 /** This is done to force the use of the factory methods (createBase64 and createFromFile). */ 050 private BinaryValue() 051 { 052 } 053 054 /** 055 * Creates a binary value using a base64 string. 056 * @param base64 the base64 representation of the binary. 057 * @return the binary value. 058 * @throws ParseException if there is an error decoding the provided base64 059 * string. 060 */ 061 public static BinaryValue createBase64(String base64) throws ParseException 062 { 063 BinaryValue value = new BinaryValue(); 064 value.type = Type.BASE64_STRING; 065 value.base64 = base64; 066 value.bytes = value.getBytes(); 067 value.hashCode = base64.hashCode(); 068 return value; 069 } 070 071 /** 072 * Creates a binary value using an array of bytes. 073 * @param bytes the byte array. 074 * @return the binary value. 075 */ 076 public static BinaryValue createBase64(byte[] bytes) 077 { 078 BinaryValue value = new BinaryValue(); 079 value.type = Type.BASE64_STRING; 080 value.bytes = bytes; 081 value.base64 = value.getBase64(); 082 value.hashCode = value.base64.hashCode(); 083 return value; 084 } 085 086 /** 087 * Creates a binary value using an array of bytes and a file. 088 * @param bytes the bytes in the file. 089 * @param file the file the bytes were read from. 090 * @return the binary value. 091 */ 092 public static BinaryValue createFromFile(byte[] bytes, File file) 093 { 094 BinaryValue value = new BinaryValue(); 095 value.type = Type.BYTE_ARRAY; 096 value.bytes = bytes; 097 value.base64 = value.getBase64(); 098 value.hashCode = value.base64.hashCode(); 099 value.file = file; 100 return value; 101 } 102 103 /** 104 * Returns the base64 representation of the binary value. 105 * @return the base64 representation of the binary value. 106 */ 107 public String getBase64() 108 { 109 if (base64 == null && bytes != null) 110 { 111 base64 = Base64.encode(bytes); 112 } 113 return base64; 114 } 115 116 /** 117 * Returns the byte array of the binary value. 118 * @return the byte array of the binary value. 119 * @throws ParseException if this object was created using a base64 string 120 * and there was an error parsing it. 121 */ 122 public byte[] getBytes() throws ParseException 123 { 124 if (bytes == null && base64 != null) 125 { 126 bytes = Base64.decode(base64); 127 } 128 return bytes; 129 } 130 131 /** 132 * Return the type of the binary value. 133 * @return the type of the binary value. 134 */ 135 public Type getType() 136 { 137 return type; 138 } 139 140 /** 141 * Return the file that was used to read the binary value. 142 * @return the file that was used to read the binary value. 143 */ 144 public File getFile() 145 { 146 return file; 147 } 148 149 @Override 150 public boolean equals(Object o) 151 { 152 if (this == o) 153 { 154 return true; 155 } 156 if (o instanceof BinaryValue) 157 { 158 BinaryValue candidate = (BinaryValue)o; 159 return candidate.getType() == getType() 160 && Objects.equals(file, candidate.getFile()) 161 && bytesEqual(candidate); 162 } 163 return false; 164 } 165 166 private boolean bytesEqual(BinaryValue candidate) 167 { 168 if (type == Type.BASE64_STRING) 169 { 170 return candidate.getBase64().equals(getBase64()); 171 } 172 173 try 174 { 175 if (candidate.getBytes().length != getBytes().length) { 176 return false; 177 } 178 boolean equals = true; 179 for (int i=0; i<getBytes().length && equals; i++) 180 { 181 equals = bytes[i] == candidate.getBytes()[i]; 182 } 183 return equals; 184 } 185 catch (ParseException pe) 186 { 187 throw new RuntimeException( 188 "Unexpected error getting bytes: "+pe, pe); 189 } 190 } 191 192 @Override 193 public int hashCode() 194 { 195 return hashCode; 196 } 197}