com.rapid.server.ActionCache.java Source code

Java tutorial

Introduction

Here is the source code for com.rapid.server.ActionCache.java

Source

/*
    
Copyright (C) 2015 - Gareth Edwards / Rapid Information Systems
    
gareth.edwards@rapid-is.co.uk
    
    
This file is part of the Rapid Application Platform
    
RapidSOA is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as 
published by the Free Software Foundation, either version 3 of the 
License, or (at your option) any later version. The terms require you 
to include the original copyright, and the license notice in all redistributions.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.
    
You should have received a copy of the GNU Affero General Public License
in a file named "COPYING".  If not, see <http://www.gnu.org/licenses/>.
    
*/

package com.rapid.server;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlRootElement;

import org.apache.log4j.Logger;
import org.json.JSONException;
import org.json.JSONObject;

import com.rapid.utils.Files;

public class ActionCache {

    // private static variables
    private static Logger _logger = Logger.getLogger(ActionCache.class);
    private static Marshaller _marshaller;
    private static Unmarshaller _unmarshaller;

    @XmlRootElement
    public static class Cache {

        // private variables

        private File _cacheFile;
        private Map<String, String> _cache;

        // constructors

        // JAXB
        public Cache() {
        }

        // ActionCache
        public Cache(ServletContext servletContext, String appId) throws JAXBException {

            // create a file object for the cache.xml file
            _cacheFile = new File(
                    servletContext.getRealPath("/WEB-INF/applications/" + Files.safeName(appId) + "/cache.xml"));

            if (_cacheFile.exists()) {
                // unmarshall the file into an object
                Cache actionCache = (Cache) _unmarshaller.unmarshal(_cacheFile);
                // bring that objects cache into this one
                _cache = actionCache.getCache();
            } else {
                _cache = new HashMap<String, String>();
            }

            _logger.info("Action cache initialised for " + appId);

        }

        // properties (these are required to be marshalled)

        public Map<String, String> getCache() {
            return _cache;
        }

        public void setCache(Map<String, String> cache) {
            _cache = cache;
        }

        // public methods

        public void save() throws IOException, JAXBException {

            // create a temp file for saving the application to
            File tempFile = new File(_cacheFile.getParentFile().getAbsolutePath() + "/cache-saving.xml");

            // get a file output stream to write the data to
            FileOutputStream fos = new FileOutputStream(tempFile.getAbsolutePath());

            // marshal the security object to the temp file
            _marshaller.marshal(this, fos);

            // close the stream
            fos.close();

            // copy / overwrite the app file with the temp file                     
            Files.copyFile(tempFile, _cacheFile);

            // delete the temp file
            tempFile.delete();

        }

    }

    // private variables

    private ServletContext _servletContext;
    private Map<String, Cache> _applicationCaches;

    // constructors

    public ActionCache(ServletContext servletContext) throws JAXBException {

        // retain servletContext
        _servletContext = servletContext;

        // create the JAXB context and marshalers for this
        JAXBContext jaxb = JAXBContext.newInstance(Cache.class);
        _marshaller = jaxb.createMarshaller();
        _marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        _unmarshaller = jaxb.createUnmarshaller();

        // initialise the map of all application caches
        _applicationCaches = new HashMap<String, Cache>();

    }

    // public methods

    // converts the marshalled string into a JSONObject and stores it in the appropriate application cache
    public JSONObject get(String appId, String actionId, String key) throws JSONException, JAXBException {
        // get the appropriate application cache
        Cache appCache = _applicationCaches.get(appId);
        // create if null
        if (appCache == null)
            appCache = new Cache(_servletContext, appId);
        // fetch any data from the cache
        String value = appCache.getCache().get(actionId + key);
        // check for null
        if (value == null) {
            return null;
        } else {
            // convert to JSON before returning
            return new JSONObject(value);
        }
    }

    // converts the marshalled string into a JSONObject and stores it in the appropriate application cache
    public void put(String appId, String actionId, String key, JSONObject jsonObject) throws JAXBException {
        // get the appropriate application cache
        Cache appCache = _applicationCaches.get(appId);
        // create if null
        if (appCache == null)
            appCache = new Cache(_servletContext, appId);
        // add data to the cache
        appCache.getCache().put(actionId + key, jsonObject.toString());
        // attempt to save the cache (one day this might be on it's own queue thread to avoid file locking)
        try {
            appCache.save();
        } catch (Exception ex) {
            _logger.error(ex);
        }
    }

}