Package org.knopflerfish.bundle.cm

Source Code of org.knopflerfish.bundle.cm.ConfigurationStore

/*
* Copyright (c) 2003-2005, KNOPFLERFISH project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
*   notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
*   copyright notice, this list of conditions and the following
*   disclaimer in the documentation and/or other materials
*   provided with the distribution.
*
* - Neither the name of the KNOPFLERFISH project nor the names of its
*   contributors may be used to endorse or promote products derived
*   from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.knopflerfish.bundle.cm;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.PushbackReader;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;

import org.knopflerfish.shared.cm.CMDataReader;
import org.knopflerfish.shared.cm.CMDataWriter;
import org.osgi.framework.Constants;

import org.osgi.service.cm.ConfigurationAdmin;

/**
* Persistent storage of configuration data
*
* @author Per Gustafson
* @version $Revision: 1.1.1.1 $
*/

class ConfigurationStore {
    private final static String storeDataFile = "store_data";

    private final static String pidDataFile = "pid_to_file";

    private final static String factoryPidDataFile = "fpid_to_pids";

    private final static String generatedPids = "generated_pids";

    private final File storeDir;

    private Properties storeData;

    private Properties pidToFileName;

    private Hashtable factoryPidToPids;

    private Hashtable cache = new Hashtable();

    private CMDataReader cmDataReader = new CMDataReader();

    public ConfigurationStore(File storeDir) throws IOException {
        this.storeDir = storeDir;
        storeDir.mkdirs();

        storeData = createAndLoadProperties(storeDataFile);
        pidToFileName = createAndLoadProperties(pidDataFile);
        factoryPidToPids = loadHashtable(factoryPidDataFile);
        if (factoryPidToPids == null) {
            factoryPidToPids = new Hashtable();
        }
    }

    public synchronized Enumeration listPids() {
        return pidToFileName.keys();
    }

    public synchronized ConfigurationDictionary load(String pid)
            throws IOException {
        String fileName = (String) pidToFileName.get(pid);
        if (fileName == null) {
            return null;
        }
        return loadConfigurationDictionary(fileName);
    }

    public synchronized ConfigurationDictionary[] loadAll(String factoryPid)
            throws IOException {
        Vector v = (Vector) factoryPidToPids.get(factoryPid);
        if (v == null) {
            return null;
        }
        Vector loaded = new Vector();
        for (int i = 0; i < v.size(); ++i) {
            ConfigurationDictionary d = load((String) v.elementAt(i));
            if (d != null) {
                loaded.addElement(d);
            }
        }
        ConfigurationDictionary[] configurations = new ConfigurationDictionary[loaded
                .size()];
        loaded.copyInto(configurations);
        return configurations;
    }

    public synchronized void store(String pid, String factoryPid,
            Dictionary configuration) throws IOException {
        String fileName = fileNameOf(pid, factoryPid);

        storeConfigurationDictionary(configuration, fileName);
    }

    public synchronized ConfigurationDictionary delete(String pid)
            throws IOException {
        if (pid == null || "".equals(pid)) {
            return null;
        }
        String fileName = (String) pidToFileName.remove(pid);
        if (fileName == null || "".equals(fileName)) {
            return null;
        }
        storeProperties(pidToFileName, pidDataFile);

        ConfigurationDictionary d = loadConfigurationDictionary(fileName);
        uncacheConfigurationDictionary(fileName);
        String fpid = (String) d.get(ConfigurationAdmin.SERVICE_FACTORYPID);
        if (fpid != null) {
            Vector v = (Vector) factoryPidToPids.get(fpid);
            if (v.removeElement(pid)) {
                storeHashtable(factoryPidToPids, factoryPidDataFile);
            }
        }

        File f = new File(storeDir, fileName);
        if (f.exists()) {
            f.delete();
        }
        return d;
    }

    public synchronized void deleteAll(String factoryPid) throws IOException {
        Vector v = (Vector) factoryPidToPids.get(factoryPid);
        if (v == null) {
            return;
        }
        Enumeration e = v.elements();
        while (e.hasMoreElements()) {
            delete((String) e.nextElement());
        }
    }

    public synchronized String generatePid(String factoryPid)
            throws IOException {
        String suffix = null;
        Properties p = new Properties();
        File pidFile = new File(storeDir, generatedPids);
        if (pidFile.exists()) {
            InputStream is = new BufferedInputStream(new FileInputStream(
                    pidFile));
            p.load(is);
            if (is != null) {
                is.close();
            }
            suffix = (String) p.get(factoryPid);
        }
        if (suffix == null) {
            suffix = new Long(0).toString();
        } else {
            long l = Long.parseLong(suffix) + 1;
            suffix = new Long(l).toString();
        }
        p.put(factoryPid, suffix);
        FileOutputStream os = new FileOutputStream(pidFile);
        p.save(os, "Suffixes used for generating pids");
        if (os != null) {
            os.close();
        }
        return factoryPid + "." + suffix;
    }

    // ////////////////////

    private String fileNameOf(String pid, String factoryPid) throws IOException {
        if (pid == null) {
            return null;
        }
        String s = (String) pidToFileName.get(pid);
        if (s == null) {
            s = generateNewFileName(pid, factoryPid);
        }
        return s;
    }

    private String generateNewFileName(String pid, String factoryPid)
            throws IOException {
        final String lastUsedFileNumber = "lastUsedFileNumber";

        String fileNumber = (String) storeData.get(lastUsedFileNumber);
        if (fileNumber == null) {
            fileNumber = new Long(0).toString();
        } else {
            long l = Long.parseLong(fileNumber) + 1;
            fileNumber = new Long(l).toString();
        }
        storeData.put(lastUsedFileNumber, fileNumber);
        storeProperties(storeData, storeDataFile);

        if (factoryPid != null) {
            Vector v = (Vector) factoryPidToPids.get(factoryPid);
            if (v == null) {
                v = new Vector();
            }
            v.addElement(pid);
            factoryPidToPids.put(factoryPid, v);
            storeHashtable(factoryPidToPids, factoryPidDataFile);
        }

        pidToFileName.put(pid, fileNumber);
        storeProperties(pidToFileName, pidDataFile);

        return fileNumber;
    }

    private Properties createAndLoadProperties(String fileName)
            throws IOException {
        Properties p = new Properties();
        File f = new File(storeDir, fileName);
        if (f.exists()) {
            InputStream is = new BufferedInputStream(new FileInputStream(f));
            p.load(is);
            if (is != null) {
                is.close();
            }
        }
        return p;
    }

    private void storeProperties(Properties p, String fileName)
            throws IOException {
        File f = new File(storeDir, fileName);
        OutputStream os = new FileOutputStream(f);
        p.save(os, "Private data of the ConfigurationStore");
        if (os != null) {
            os.close();
        }
    }

    // ////////////////////
    private Hashtable loadHashtable(String fileName) throws IOException {
        if (fileName == null) {
            return null;
        }

        File f = new File(storeDir, fileName);
        if (!f.exists()) {
            return null;
        }

        PushbackReader r = new PushbackReader(new BufferedReader(
                new InputStreamReader(new FileInputStream(f),
                        CMDataReader.ENCODING), 8192), 8);

        Hashtable h = null;
        try {
            h = cmDataReader.readCMData(r);
        } catch (Exception e) {
            Activator.log.error("Failed reading file " + f.toString(), e);
            h = null;
        }

        if (r != null) {
            r.close();
        }

        return h;
    }

    private void storeHashtable(Hashtable h, String fileName)
            throws IOException {
        File f = new File(storeDir, fileName);
        PrintWriter w = new PrintWriter(new OutputStreamWriter(
                new FileOutputStream(f), CMDataWriter.ENCODING));

        CMDataWriter.writeConfiguration(fileName, h, w);
        if (w != null) {
            w.close();
        }
    }

    // /////////////

    private ConfigurationDictionary getCachedConfigurationDictionary(
            String fileName) {
        return (ConfigurationDictionary) cache.get(fileName);
    }

    private void readAndCacheConfigurationDictionary(String fileName)
            throws IOException {
        Hashtable h = loadHashtable(fileName);
        if (h != null) {
            cache.put(fileName, new ConfigurationDictionary(h));
        }
    }

    private void uncacheConfigurationDictionary(String fileName) {
        cache.remove(fileName);
    }

    private ConfigurationDictionary loadConfigurationDictionary(String fileName)
            throws IOException {
        if (fileName == null) {
            return null;
        }

        ConfigurationDictionary d = getCachedConfigurationDictionary(fileName);
        if (d == null) {
            readAndCacheConfigurationDictionary(fileName);
            d = getCachedConfigurationDictionary(fileName);
        }
        return d;
    }

    private void storeConfigurationDictionary(Dictionary d, String fileName)
            throws IOException {
        uncacheConfigurationDictionary(fileName);
        File f = new File(storeDir, fileName);
        PrintWriter w = new PrintWriter(new OutputStreamWriter(
                new FileOutputStream(f), CMDataWriter.ENCODING));

        String pid = (String) d.get(Constants.SERVICE_PID);
        String fpid = (String) d.get(ConfigurationAdmin.SERVICE_FACTORYPID);
        if (fpid == null) {
            CMDataWriter.writeConfiguration(pid, d, w);
        } else {
            CMDataWriter.writeFactoryConfiguration(fpid, pid, d, w);
        }

        if (w != null) {
            w.close();
        }
    }
}
TOP

Related Classes of org.knopflerfish.bundle.cm.ConfigurationStore

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.