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.File;
019import java.io.IOException;
020import java.nio.file.Files;
021import java.util.Map;
022import java.util.Objects;
023import java.util.concurrent.ConcurrentHashMap;
024import java.util.logging.Level;
025import java.util.logging.Logger;
026
027import javax.money.MonetaryException;
028
029/**
030 * Default implementation of {@link ResourceCache}, using the local file system.
031 *
032 * @author Anatole Tresch
033 */
034public class DefaultResourceCache implements ResourceCache {
035    /**
036     * The logger used.
037     */
038    private static final Logger LOG = Logger.getLogger(DefaultResourceCache.class.getName());
039    /**
040     * Suffix for files created.
041     */
042    private static final String SUFFIX = ".dat";
043    /**
044     * Local temp directory.
045     */
046    private File localDir = new File(System.getProperty("temp.dir", ".resourceCache"));
047    /**
048     * Cached resources.
049     */
050    private final Map<String, File> cachedResources = new ConcurrentHashMap<>();
051
052    /**
053     * Constructor.
054     */
055    public DefaultResourceCache() {
056        if (!localDir.exists()) {
057            if (!localDir.mkdirs()) {
058                LOG.severe("Error creating cache dir  " + localDir + ", resource cache disabled!");
059                localDir = null;
060            } else {
061                LOG.finest("Created cache dir  " + localDir);
062            }
063        } else if (!localDir.isDirectory()) {
064            LOG.severe("Error initializing cache dir  " + localDir + ", not a directory, resource cache disabled!");
065            localDir = null;
066        } else if (!localDir.canWrite()) {
067            LOG.severe("Error initializing cache dir  " + localDir + ", not writable, resource cache disabled!");
068            localDir = null;
069        }
070        if (Objects.nonNull(localDir)) {
071            File[] files = localDir.listFiles();
072            if (files != null) {
073                for (File file : files) {
074                    if (file.isFile()) {
075                        String resourceId = file.getName().substring(0, file.getName().length() - 4);
076                        cachedResources.put(resourceId, file);
077                    }
078                }
079            }
080        }
081    }
082
083    /*
084     * (non-Javadoc)
085     *
086     * @see
087     * org.javamoney.moneta.loader.format.ResourceCache#write(java.lang.String
088     * , byte[])
089     */
090    @Override
091    public void write(String resourceId, byte[] data) {
092        try {
093            File file = this.cachedResources.get(resourceId);
094            if (Objects.isNull(file)) {
095                file = new File(localDir, resourceId + SUFFIX);
096                Files.write(file.toPath(), data);
097                this.cachedResources.put(resourceId, file);
098            } else {
099                Files.write(file.toPath(), data);
100            }
101        } catch (Exception e) {
102            LOG.log(Level.WARNING, "Caching of resource failed: " + resourceId, e);
103        }
104    }
105
106    /*
107     * (non-Javadoc)
108     *
109     * @see
110     * org.javamoney.moneta.loader.format.ResourceCache#isCached(java.lang
111     * .String)
112     */
113    @Override
114    public boolean isCached(String resourceId) {
115        return this.cachedResources.containsKey(resourceId);
116    }
117
118    /*
119     * (non-Javadoc)
120     *
121     * @see
122     * org.javamoney.moneta.loader.format.ResourceCache#read(java.lang.String)
123     */
124    @Override
125    public byte[] read(String resourceId) {
126        File f = this.cachedResources.get(resourceId);
127        if (Objects.isNull(f)) {
128            return null;
129        }
130        try {
131                        return Files.readAllBytes(f.toPath());
132                } catch (IOException exception) {
133                        throw new MonetaryException("An error on retrieve the resource id: " + resourceId, exception);
134
135                }
136    }
137
138    @Override
139    public void clear(String resourceId) {
140        File file = this.cachedResources.get(resourceId);
141        if (file != null) {
142            if (file.exists()) {
143                if (!file.delete()) {
144                    LOG.warning("Failed to delete caching file: " + file.getAbsolutePath());
145                }
146            }
147            this.cachedResources.remove(resourceId);
148        }
149    }
150
151    @Override
152    public String toString() {
153        return "DefaultResourceCache [localDir=" + localDir + ", cachedResources=" + cachedResources + ']';
154    }
155
156}