1 /* 2 * Copyright 2011-2012 smartics, Kronseder & Reiner GmbH 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package de.smartics.util.io; 17 18 import java.io.ByteArrayInputStream; 19 import java.io.ByteArrayOutputStream; 20 import java.io.FilterOutputStream; 21 import java.io.IOException; 22 import java.io.InputStream; 23 import java.io.OutputStream; 24 import java.util.HashMap; 25 import java.util.Map; 26 27 import javax.annotation.concurrent.NotThreadSafe; 28 29 /** 30 * Handles resources and stores them in-memory. 31 */ 32 @NotThreadSafe 33 public final class MemoryStreamHandler implements StreamHandler 34 { 35 // ********************************* Fields ********************************* 36 37 // --- constants ------------------------------------------------------------ 38 39 // --- members -------------------------------------------------------------- 40 41 /** 42 * The in-memory store. 43 */ 44 private final Map<String, byte[]> dataStore = new HashMap<String, byte[]>(); 45 46 // ****************************** Initializer ******************************* 47 48 // ****************************** Constructors ****************************** 49 50 /** 51 * Helper to add the streamed information upon closing the stream. 52 */ 53 private final class CloseListenerOutputStream extends FilterOutputStream 54 { 55 /** 56 * The identifier of the resource being monitored. 57 */ 58 private final String resourceId; 59 60 /** 61 * Reference to the stream whose closing is monitored. 62 */ 63 private final ByteArrayOutputStream out; 64 65 private CloseListenerOutputStream(final String resourceId, 66 final ByteArrayOutputStream out) 67 { 68 super(out); 69 this.out = out; 70 this.resourceId = resourceId; 71 } 72 73 @Override 74 public void close() throws IOException 75 { 76 super.close(); 77 final byte[] data = out.toByteArray(); 78 dataStore.put(resourceId, data); 79 } 80 } 81 82 // ****************************** Inner Classes ***************************** 83 84 // ********************************* Methods ******************************** 85 86 // --- init ----------------------------------------------------------------- 87 88 // --- get&set -------------------------------------------------------------- 89 90 // --- business ------------------------------------------------------------- 91 92 /** 93 * Allows direct access to the data stored. 94 * 95 * @param resourceId the identifier of the resource requested. 96 * @return the data from the store or <code>null</code> if there is no data 97 * for this key. 98 */ 99 public byte[] getData(final String resourceId) 100 { 101 final byte[] data = dataStore.get(resourceId); 102 return data; 103 } 104 105 /** 106 * {@inheritDoc} 107 * 108 * @see de.smartics.util.io.StreamHandler#open(java.lang.String) 109 */ 110 @Override 111 public InputStream openToRead(final String resourceId) throws IOException 112 { 113 final byte[] data = dataStore.get(resourceId); 114 if (data == null) 115 { 116 throw new IOException("Resource '" + resourceId + "' cannot be found."); 117 } 118 119 final InputStream in = new ByteArrayInputStream(data); 120 return in; 121 } 122 123 /** 124 * {@inheritDoc} 125 * 126 * @see de.smartics.util.io.StreamHandler#openToWrite(java.lang.String) 127 */ 128 @Override 129 public OutputStream openToWrite(final String resourceId) throws IOException 130 { 131 final ByteArrayOutputStream out = new ByteArrayOutputStream(4092); 132 final CloseListenerOutputStream clout = 133 new CloseListenerOutputStream(resourceId, out); 134 dataStore.remove(resourceId); 135 return clout; 136 } 137 138 // --- object basics -------------------------------------------------------- 139 140 }