001/** 002 * Copyright (c) 2012, 2014, Credit Suisse (Anatole Tresch), Werner Keil and others by the @author tag. 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 */ 016package org.javamoney.moneta.internal.loader; 017 018import java.io.*; 019import java.util.Map; 020import java.util.concurrent.ConcurrentHashMap; 021import java.util.logging.Level; 022import java.util.logging.Logger; 023 024/** 025 * Default implementation of {@link ResourceCache}, using the local file system. 026 * 027 * @author Anatole Tresch 028 */ 029public class DefaultResourceCache implements ResourceCache { 030 /** 031 * The logger used. 032 */ 033 private static final Logger LOG = Logger.getLogger(DefaultResourceCache.class.getName()); 034 /** 035 * Suffix for files created. 036 */ 037 private static final String SUFFIX = ".dat"; 038 /** 039 * Local temp directory. 040 */ 041 private File localDir = new File(System.getProperty("temp.dir", ".resourceCache")); 042 /** 043 * Cached resources. 044 */ 045 private final Map<String, File> cachedResources = new ConcurrentHashMap<>(); 046 047 /** 048 * Constructor. 049 */ 050 public DefaultResourceCache() { 051 if (!localDir.exists()) { 052 if (!localDir.mkdirs()) { 053 LOG.severe("Error creating cache dir " + localDir + ", resource cache disabled!"); 054 localDir = null; 055 } else { 056 LOG.finest("Created cache dir " + localDir); 057 } 058 } else if (!localDir.isDirectory()) { 059 LOG.severe("Error initializing cache dir " + localDir + ", not a directory, resource cache disabled!"); 060 localDir = null; 061 } else if (!localDir.canWrite()) { 062 LOG.severe("Error initializing cache dir " + localDir + ", not writable, resource cache disabled!"); 063 localDir = null; 064 } 065 if (localDir!=null) { 066 File[] files = localDir.listFiles(); 067 if (files != null) { 068 for (File file : files) { 069 if (file.isFile()) { 070 String resourceId = file.getName().substring(0, file.getName().length() - 4); 071 cachedResources.put(resourceId, file); 072 } 073 } 074 } 075 } 076 } 077 078 /* 079 * (non-Javadoc) 080 * 081 * @see 082 * org.javamoney.moneta.loader.format.ResourceCache#write(java.lang.String 083 * , byte[]) 084 */ 085 @Override 086 public void write(String resourceId, byte[] data) { 087 try { 088 File f = this.cachedResources.get(resourceId); 089 if (f==null) { 090 f = new File(localDir, resourceId + SUFFIX); 091 writeFile(f, data); 092 this.cachedResources.put(resourceId, f); 093 } else { 094 writeFile(f, data); 095 } 096 } catch (Exception e) { 097 LOG.log(Level.WARNING, "Caching of resource failed: " + resourceId, e); 098 } 099 } 100 101 /** 102 * Writees a file with the given data, 103 * 104 * @param f the file 105 * @param data the data 106 * @throws IOException if writing failed. 107 */ 108 private void writeFile(File f, byte[] data) throws IOException { 109 BufferedOutputStream bos = null; 110 try { 111 bos = new BufferedOutputStream(new FileOutputStream(f)); 112 bos.write(data); 113 bos.flush(); 114 } finally { 115 try { 116 if (bos!=null) { 117 bos.close(); 118 } 119 } catch (Exception e2) { 120 LOG.log(Level.SEVERE, "Error closing output stream for " + f, e2); 121 } 122 } 123 124 } 125 126 /* 127 * (non-Javadoc) 128 * 129 * @see 130 * org.javamoney.moneta.loader.format.ResourceCache#isCached(java.lang 131 * .String) 132 */ 133 @Override 134 public boolean isCached(String resourceId) { 135 return this.cachedResources.containsKey(resourceId); 136 } 137 138 /* 139 * (non-Javadoc) 140 * 141 * @see 142 * org.javamoney.moneta.loader.format.ResourceCache#read(java.lang.String) 143 */ 144 @Override 145 public byte[] read(String resourceId) { 146 File f = this.cachedResources.get(resourceId); 147 if (f==null) { 148 return null; 149 } 150 return readFile(f); 151 } 152 153 @Override 154 public void clear(String resourceId) { 155 File f = this.cachedResources.get(resourceId); 156 if (f != null) { 157 if (f.exists()) { 158 if (!f.delete()) { 159 LOG.warning("Failed to delete caching file: " + f.getAbsolutePath()); 160 } 161 } 162 this.cachedResources.remove(resourceId); 163 } 164 } 165 166 /** 167 * Read a file. 168 * 169 * @param f the file 170 * @return the bytes read. 171 */ 172 private byte[] readFile(File f) { 173 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 174 BufferedInputStream is = null; 175 try { 176 is = new BufferedInputStream(new FileInputStream(f)); 177 byte[] input = new byte[1024]; 178 int read = 1; 179 while (read > 0) { 180 read = is.read(input); 181 if (read > 0) { 182 bos.write(input, 0, read); 183 } 184 } 185 return bos.toByteArray(); 186 } catch (Exception e) { 187 LOG.log(Level.SEVERE, "Error reading cached resource from " + f, e); 188 return null; 189 } finally { 190 try { 191 if (is!=null) { 192 is.close(); 193 } 194 } catch (Exception e2) { 195 LOG.log(Level.SEVERE, "Error closing input stream from " + f, e2); 196 } 197 } 198/* 199URI fileUri = this.cachedResource; 200 if(fileUri == null){ 201 String userHome = System.getProperty("user.home"); 202 File file = new File(userHome + "/.cache", resourceId); 203 if(file.exists()){ 204 fileUri = file.toURI(); 205 } 206 } 207 if(fileUri != null){ 208 File file = new File(fileUri); 209 try( 210 FileInputStream fis = new FileInputStream(file); 211 BufferedInputStream bis = new BufferedInputStream(fis); 212 ObjectInputStream ois = new ObjectInputStream(bis) 213 ){ 214 long loadTS = ois.readLong(); 215 byte[] data = (byte[]) ois.readObject(); 216 this.lastLoaded = loadTS; 217 setData(data); 218 return true; 219 } 220 catch(Exception e){ 221 LOG.log(Level.WARNING, "Failed to read data from cache: " + fileUri, e); 222 } 223 } 224 return false; 225 */ 226 } 227 228 @Override 229 public String toString() { 230 return "DefaultResourceCache [localDir=" + localDir + ", cachedResources=" + cachedResources + ']'; 231 } 232 233}