1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 package org.apache.shiro.util; 20 21 import java.io.File; 22 import java.io.InputStream; 23 24 /** 25 * A {@code ByteSource} wraps a byte array and provides additional encoding operations. Most users will find the 26 * {@link Util} inner class sufficient to construct ByteSource instances. 27 * 28 * @since 1.0 29 */ 30 public interface ByteSource { 31 32 /** 33 * Returns the wrapped byte array. 34 * 35 * @return the wrapped byte array. 36 */ 37 byte[] getBytes(); 38 39 /** 40 * Returns the <a href="http://en.wikipedia.org/wiki/Hexadecimal">Hex</a>-formatted String representation of the 41 * underlying wrapped byte array. 42 * 43 * @return the <a href="http://en.wikipedia.org/wiki/Hexadecimal">Hex</a>-formatted String representation of the 44 * underlying wrapped byte array. 45 */ 46 String toHex(); 47 48 /** 49 * Returns the <a href="http://en.wikipedia.org/wiki/Base64">Base 64</a>-formatted String representation of the 50 * underlying wrapped byte array. 51 * 52 * @return the <a href="http://en.wikipedia.org/wiki/Base64">Base 64</a>-formatted String representation of the 53 * underlying wrapped byte array. 54 */ 55 String toBase64(); 56 57 /** 58 * Returns {@code true} if the underlying wrapped byte array is null or empty (zero length), {@code false} 59 * otherwise. 60 * 61 * @return {@code true} if the underlying wrapped byte array is null or empty (zero length), {@code false} 62 * otherwise. 63 * @since 1.2 64 */ 65 boolean isEmpty(); 66 67 /** 68 * Utility class that can construct ByteSource instances. This is slightly nicer than needing to know the 69 * {@code ByteSource} implementation class to use. 70 * 71 * @since 1.2 72 */ 73 public static final class Util { 74 75 /** 76 * Returns a new {@code ByteSource} instance representing the specified byte array. 77 * 78 * @param bytes the bytes to represent as a {@code ByteSource} instance. 79 * @return a new {@code ByteSource} instance representing the specified byte array. 80 */ 81 public static ByteSource bytes(byte[] bytes) { 82 return new SimpleByteSource(bytes); 83 } 84 85 /** 86 * Returns a new {@code ByteSource} instance representing the specified character array's bytes. The byte 87 * array is obtained assuming {@code UTF-8} encoding. 88 * 89 * @param chars the character array to represent as a {@code ByteSource} instance. 90 * @return a new {@code ByteSource} instance representing the specified character array's bytes. 91 */ 92 public static ByteSource bytes(char[] chars) { 93 return new SimpleByteSource(chars); 94 } 95 96 /** 97 * Returns a new {@code ByteSource} instance representing the specified string's bytes. The byte 98 * array is obtained assuming {@code UTF-8} encoding. 99 * 100 * @param string the string to represent as a {@code ByteSource} instance. 101 * @return a new {@code ByteSource} instance representing the specified string's bytes. 102 */ 103 public static ByteSource bytes(String string) { 104 return new SimpleByteSource(string); 105 } 106 107 /** 108 * Returns a new {@code ByteSource} instance representing the specified ByteSource. 109 * 110 * @param source the ByteSource to represent as a new {@code ByteSource} instance. 111 * @return a new {@code ByteSource} instance representing the specified ByteSource. 112 */ 113 public static ByteSource../../../../org/apache/shiro/util/ByteSource.html#ByteSource">ByteSource bytes(ByteSource source) { 114 return new SimpleByteSource(source); 115 } 116 117 /** 118 * Returns a new {@code ByteSource} instance representing the specified File's bytes. 119 * 120 * @param file the file to represent as a {@code ByteSource} instance. 121 * @return a new {@code ByteSource} instance representing the specified File's bytes. 122 */ 123 public static ByteSource bytes(File file) { 124 return new SimpleByteSource(file); 125 } 126 127 /** 128 * Returns a new {@code ByteSource} instance representing the specified InputStream's bytes. 129 * 130 * @param stream the InputStream to represent as a {@code ByteSource} instance. 131 * @return a new {@code ByteSource} instance representing the specified InputStream's bytes. 132 */ 133 public static ByteSource bytes(InputStream stream) { 134 return new SimpleByteSource(stream); 135 } 136 137 /** 138 * Returns {@code true} if the specified object can be easily represented as a {@code ByteSource} using 139 * the {@link ByteSource.Util}'s default heuristics, {@code false} otherwise. 140 * <p/> 141 * This implementation merely returns {@link SimpleByteSource}.{@link SimpleByteSource#isCompatible(Object) isCompatible(source)}. 142 * 143 * @param source the object to test to see if it can be easily converted to ByteSource instances using default 144 * heuristics. 145 * @return {@code true} if the specified object can be easily represented as a {@code ByteSource} using 146 * the {@link ByteSource.Util}'s default heuristics, {@code false} otherwise. 147 */ 148 public static boolean isCompatible(Object source) { 149 return SimpleByteSource.isCompatible(source); 150 } 151 152 /** 153 * Returns a {@code ByteSource} instance representing the specified byte source argument. If the argument 154 * <em>cannot</em> be easily converted to bytes (as is indicated by the {@link #isCompatible(Object)} JavaDoc), 155 * this method will throw an {@link IllegalArgumentException}. 156 * 157 * @param source the byte-backed instance that should be represented as a {@code ByteSource} instance. 158 * @return a {@code ByteSource} instance representing the specified byte source argument. 159 * @throws IllegalArgumentException if the argument <em>cannot</em> be easily converted to bytes 160 * (as indicated by the {@link #isCompatible(Object)} JavaDoc) 161 */ 162 public static ByteSource bytes(Object source) throws IllegalArgumentException { 163 if (source == null) { 164 return null; 165 } 166 if (!isCompatible(source)) { 167 String msg = "Unable to heuristically acquire bytes for object of type [" + 168 source.getClass().getName() + "]. If this type is indeed a byte-backed data type, you might " + 169 "want to write your own ByteSource implementation to extract its bytes explicitly."; 170 throw new IllegalArgumentException(msg); 171 } 172 if (source instanceof byte[]) { 173 return bytes((byte[]) source); 174 } else if (source instanceof ByteSource) { 175 return (ByteSource) source; 176 } else if (source instanceof char[]) { 177 return bytes((char[]) source); 178 } else if (source instanceof String) { 179 return bytes((String) source); 180 } else if (source instanceof File) { 181 return bytes((File) source); 182 } else if (source instanceof InputStream) { 183 return bytes((InputStream) source); 184 } else { 185 throw new IllegalStateException("Encountered unexpected byte source. This is a bug - please notify " + 186 "the Shiro developer list asap (the isCompatible implementation does not reflect this " + 187 "method's implementation)."); 188 } 189 } 190 } 191 }