Package org.apache.felix.prefs.impl

Source Code of org.apache.felix.prefs.impl.DataFileBackingStoreImpl

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.felix.prefs.impl;

import java.io.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.*;

import org.apache.felix.prefs.*;
import org.osgi.framework.BundleContext;
import org.osgi.service.prefs.BackingStoreException;

/**
* This implementating of the backing store uses the bundle mechanism to store
* binary data.
*/
public class DataFileBackingStoreImpl extends StreamBackingStoreImpl {

    /** The root directory (or null if not available) */
    protected final File rootDirectory;

    public DataFileBackingStoreImpl(BundleContext context) {
        super(context);
        this.rootDirectory = context.getDataFile("");
    }

    public DataFileBackingStoreImpl(BundleContext context, File rootDirectory) {
        super(context);
        this.rootDirectory = rootDirectory;
    }

    /**
     * @see org.apache.felix.sandbox.preferences.impl.StreamBackingStoreImpl#checkAccess()
     */
    protected void checkAccess() throws BackingStoreException {
        if ( this.rootDirectory == null ) {
            throw new BackingStoreException("Saving of data files to the bundle context is currently not supported.");
        }
    }

    /**
     * @see org.apache.felix.sandbox.preferences.impl.StreamBackingStoreImpl#getOutputStream(org.apache.felix.sandbox.preferences.PreferencesDescription)
     */
    protected OutputStream getOutputStream(PreferencesDescription desc) throws IOException {
        final File file = this.getFile(desc);
        return getFileOutputStream(file);
    }

    /**
     * @see org.apache.felix.prefs.BackingStore#availableBundles()
     */
    public Long[] availableBundles() {
        // If the root directory is not available, then we do nothing!
        try {
            this.checkAccess();
        } catch (BackingStoreException ignore) {
            return new Long[0];
        }
        final Set bundleIds = new HashSet();
        final File[] children = getFilesList(this.rootDirectory);
        for( int i=0; i<children.length; i++ ) {
            final File current = children[i];

            final PreferencesDescription desc = this.getDescription(current);
            if ( desc != null ) {
                bundleIds.add(desc.getBundleId());
            }
        }
        return (Long[])bundleIds.toArray(new Long[bundleIds.size()]);
    }

    protected PreferencesDescription getDescription(File file) {
        final String fileName = file.getName();
        // parse the file name to get: bundle id, user|system identifer
        if ( fileName.startsWith("P") && fileName.endsWith(".ser") ) {
            final String name = fileName.substring(1, fileName.length() - 4);
            final String key;
            final String identifier;
            int pos = name.indexOf("_");
            if ( pos != -1 ) {
                identifier = name.substring(pos+1);
                key = name.substring(0, pos);
            } else {
                key = name;
                identifier = null;
            }
            final Long bundleId = Long.valueOf(key);
            return new PreferencesDescription(bundleId, identifier);
        }
        return null;
    }

    /**
     * @see org.apache.felix.prefs.BackingStore#remove(java.lang.Long)
     */
    public void remove(Long bundleId) throws BackingStoreException {
        this.checkAccess();
        final File[] children = getFilesList(this.rootDirectory);
        for( int i=0; i<children.length; i++ ) {
            final File current = children[i];

            final PreferencesDescription desc = this.getDescription(current);
            if ( desc != null ) {
                if ( desc.getBundleId().equals(bundleId) ) {
                    current.delete();
                }
            }
        }
    }

    /**
     * @see org.apache.felix.prefs.BackingStore#loadAll(org.apache.felix.prefs.BackingStoreManager, java.lang.Long)
     */
    public PreferencesImpl[] loadAll(BackingStoreManager manager, Long bundleId) throws BackingStoreException {
        this.checkAccess();
        final List list = new ArrayList();
        final File[] children = getFilesList(this.rootDirectory);
        for( int i=0; i<children.length; i++ ) {
            final File current = children[i];

            final PreferencesDescription desc = this.getDescription(current);
            if ( desc != null ) {
                if ( desc.getBundleId().equals(bundleId) ) {
                    final PreferencesImpl root = new PreferencesImpl(desc, manager);
                    try {
                        final FileInputStream fis = getFileInputStream(current);
                        this.read(root, fis);
                        fis.close();
                    } catch (IOException ioe) {
                        throw new BackingStoreException("Unable to load preferences.", ioe);
                    }
                    list.add(root);
                }
            }
        }
        return (PreferencesImpl[])list.toArray(new PreferencesImpl[list.size()]);
    }

    /**
     * @see org.apache.felix.prefs.BackingStore#load(org.apache.felix.prefs.BackingStoreManager, org.apache.felix.prefs.PreferencesDescription)
     */
    public PreferencesImpl load(BackingStoreManager manager, PreferencesDescription desc) throws BackingStoreException {
        this.checkAccess();
        final File file = this.getFile(desc);
        if ( fileExists(file).booleanValue() ) {
            try {
                final PreferencesImpl root = new PreferencesImpl(desc, manager);
                final FileInputStream fis = getFileInputStream(file);
                this.read(root, fis);
                fis.close();

                return root;
            } catch (IOException ioe) {
                throw new BackingStoreException("Unable to load preferences.", ioe);
            }
        }
        return null;
    }

    /**
     * Get the file fo the preferences tree.
     * @param desc
     * @return
     */
    protected File getFile(PreferencesDescription desc) {
        final StringBuffer buffer = new StringBuffer("P");
        buffer.append(desc.getBundleId());
        if ( desc.getIdentifier() != null ) {
            buffer.append('_');
            buffer.append(desc.getIdentifier());
        }
        buffer.append(".ser");
        final File file = new File(this.rootDirectory, buffer.toString());
        return file;
    }

    // few utility methods to access File APIs from a privileged block
   
    private static File[] getFilesList(final File file) {
        return (File[]) AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {
                return file.listFiles();
            }
        });
    }
   
    private static Boolean fileExists(final File file) {
        return (Boolean) AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {
                return (file.exists() ? Boolean.TRUE : Boolean.FALSE);
            }
        });
    }
   
    private static FileInputStream getFileInputStream(final File file) throws IOException {
        try {
            return (FileInputStream) AccessController.doPrivileged(
                    new PrivilegedExceptionAction() {
                public Object run() throws FileNotFoundException {
                    return new FileInputStream(file);
                }
            });
        } catch (PrivilegedActionException e) {
            // e.getException() should be an instance of FileNotFoundException, as
            // only "checked" exceptions will be "wrapped" in PrivilegedActionException.
            throw (FileNotFoundException) e.getException();
        }
    }
   
    private static FileOutputStream getFileOutputStream(final File file) throws IOException {
        try {
            return (FileOutputStream) AccessController.doPrivileged(
                    new PrivilegedExceptionAction() {
                public Object run() throws FileNotFoundException {
                    return new FileOutputStream(file);
                }
            });
        } catch (PrivilegedActionException e) {
            // e.getException() should be an instance of FileNotFoundException, as
            // only "checked" exceptions will be "wrapped" in PrivilegedActionException.
            throw (FileNotFoundException) e.getException();
        }
    }
}
TOP

Related Classes of org.apache.felix.prefs.impl.DataFileBackingStoreImpl

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.