001/* 002 * Copyright (c) 2012, 2013, Credit Suisse (Anatole Tresch), Werner Keil. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 005 * use this file except in compliance with the License. You may obtain a copy of 006 * the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 013 * License for the specific language governing permissions and limitations under 014 * the License. 015 * 016 * Contributors: Anatole Tresch - initial implementation 017 */ 018package org.javamoney.moneta.loader.internal; 019 020import java.io.BufferedInputStream; 021import java.io.BufferedOutputStream; 022import java.io.ByteArrayOutputStream; 023import java.io.File; 024import java.io.FileInputStream; 025import java.io.FileOutputStream; 026import java.io.IOException; 027import java.util.Map; 028import java.util.concurrent.ConcurrentHashMap; 029import java.util.logging.Level; 030import java.util.logging.Logger; 031 032/** 033 * Default implementation of {@link ResourceCache}, using the local file system. 034 * 035 * @author Anatole Tresch 036 */ 037public class DefaultResourceCache implements ResourceCache { 038 /** The logger used. */ 039 private static final Logger LOG = Logger 040 .getLogger(DefaultResourceCache.class.getName()); 041 /** Suffix for files created. */ 042 private static final String SUFFIX = ".dat"; 043 /** Local temp directory. */ 044 private File localDir = new File(System.getProperty("temp.dir", 045 ".resourceCache")); 046 /** Cached resources. */ 047 private Map<String, File> cachedResources = new ConcurrentHashMap<>(); 048 049 /** 050 * Constructor. 051 */ 052 public DefaultResourceCache() { 053 if (!localDir.exists()) { 054 if (!localDir.mkdirs()) { 055 LOG.severe("Error creating cache dir " + localDir 056 + ", resource cache disabled!"); 057 localDir = null; 058 } else { 059 LOG.finest("Created cache dir " + localDir); 060 } 061 } else if (!localDir.isDirectory()) { 062 LOG.severe("Error initializing cache dir " + localDir 063 + ", not a directory, resource cache disabled!"); 064 localDir = null; 065 } else if (!localDir.canWrite()) { 066 LOG.severe("Error initializing cache dir " + localDir 067 + ", not writable, resource cache disabled!"); 068 localDir = null; 069 } 070 if (localDir != null) { 071 File[] files = localDir.listFiles(); 072 for (File file : files) { 073 if (file.isFile()) { 074 String resourceId = file.getName().substring(0, 075 file.getName().length() - 4); 076 cachedResources.put(resourceId, file); 077 } 078 } 079 } 080 } 081 082 /* 083 * (non-Javadoc) 084 * 085 * @see 086 * org.javamoney.moneta.loader.internal.ResourceCache#write(java.lang.String 087 * , byte[]) 088 */ 089 @Override 090 public void write(String resourceId, byte[] data) throws IOException { 091 File f = this.cachedResources.get(resourceId); 092 if (f == null) { 093 f = new File(localDir, resourceId + SUFFIX); 094 writeFile(f, data); 095 this.cachedResources.put(resourceId, f); 096 } else { 097 writeFile(f, data); 098 } 099 } 100 101 /** 102 * Writees a file with the given data, 103 * 104 * @param f 105 * the file 106 * @param data 107 * the data 108 * @throws IOException 109 * if writing failed. 110 */ 111 private void writeFile(File f, byte[] data) throws IOException { 112 BufferedOutputStream bos = null; 113 try { 114 bos = new BufferedOutputStream(new FileOutputStream(f)); 115 bos.write(data); 116 bos.flush(); 117 } finally { 118 try { 119 if (bos != null) { 120 bos.close(); 121 } 122 } catch (Exception e2) { 123 LOG.log(Level.SEVERE, "Error closing output stream for " + f, 124 e2); 125 } 126 } 127 128 } 129 130 /* 131 * (non-Javadoc) 132 * 133 * @see 134 * org.javamoney.moneta.loader.internal.ResourceCache#isCached(java.lang 135 * .String) 136 */ 137 @Override 138 public boolean isCached(String resourceId) { 139 return this.cachedResources.containsKey(resourceId); 140 } 141 142 /* 143 * (non-Javadoc) 144 * 145 * @see 146 * org.javamoney.moneta.loader.internal.ResourceCache#read(java.lang.String) 147 */ 148 @Override 149 public byte[] read(String resourceId) { 150 File f = this.cachedResources.get(resourceId); 151 if (f == null) { 152 return null; 153 } 154 return readFile(f); 155 } 156 157 /** 158 * Read a file. 159 * 160 * @param f 161 * the file 162 * @return the bytes read. 163 */ 164 private byte[] readFile(File f) { 165 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 166 BufferedInputStream is = null; 167 try { 168 is = new BufferedInputStream(new FileInputStream(f)); 169 byte[] input = new byte[1024]; 170 int read = 1; 171 while (read > 0) { 172 read = is.read(input); 173 bos.write(input, 0, read); 174 } 175 return bos.toByteArray(); 176 } catch (Exception e) { 177 LOG.log(Level.SEVERE, "Error reading cached resource from " + f, e); 178 return null; 179 } finally { 180 try { 181 if (is != null) { 182 is.close(); 183 } 184 } catch (Exception e2) { 185 LOG.log(Level.SEVERE, "Error closing input stream from " + f, 186 e2); 187 } 188 } 189 190 } 191 192 @Override 193 public String toString() { 194 return "DefaultResourceCache [localDir=" + localDir 195 + ", cachedResources=" + cachedResources + "]"; 196 } 197 198}