Package org.knopflerfish.bundle.cm.commands.impl

Source Code of org.knopflerfish.bundle.cm.commands.impl.CMCommands

/*
* Copyright (c) 2003, 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.commands.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.PushbackReader;
import java.io.Reader;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import org.knopflerfish.service.console.CommandGroupAdapter;
import org.knopflerfish.service.console.Session;
import org.knopflerfish.shared.cm.CMDataReader;
import org.knopflerfish.shared.cm.DictionaryUtils;
import org.knopflerfish.util.sort.Sort;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;

// ******************** CMCommands ********************
/**
* * Console interface to the CM. * *
*
* @author Per Gustafson *
* @version $Id: CMCommands.java,v 1.1.1.1 2004/03/05 20:34:54 wistrand Exp $
*/

public class CMCommands extends CommandGroupAdapter implements ServiceListener {
    /***************************************************************************
     * Key in the session properties dictionary used to store the current (open)
     * configuration.*
     **************************************************************************/
    private static final String CURRENT = "org.knopflerfish.bundle.cm.commands.impl.current";

    /***************************************************************************
     * Key in the session properties dictionary used to store the dictionary
     * that is edited for the current configuration.*
     **************************************************************************/
    private static final String EDITED = "org.knopflerfish.bundle.cm.commands.impl.edited";

    /***************************************************************************
     * Key in the session properties dictionary used to store the * result of
     * the latest list command for later reference using -i options to several
     * commands. *
     **************************************************************************/
    private static final String LISTED_CONFIGS = "org.knopflerfish.bundle.cm.commands.impl.listed.configs";

    BundleContext bc;

    ServiceReference refCA = null;

    private static Class classBigDecimal;

    private static Constructor consBigDecimal;

    static {
        try {
            classBigDecimal = Class.forName("java.math.BigDecimal");
            consBigDecimal = classBigDecimal
                    .getConstructor(new Class[] { String.class });
        } catch (Exception ignore) {
            classBigDecimal = null;
            consBigDecimal = null;
        }
    }

    public CMCommands(BundleContext bc) {
        super("configuration", "Configuration commands");
        this.bc = bc;
        refCA = bc.getServiceReference(ConfigurationAdmin.class.getName());
        try {
            bc.addServiceListener(this, "(objectClass="
                    + ConfigurationAdmin.class.getName() + ")");
        } catch (InvalidSyntaxException ignored) {
        }
    }

    public final static String USAGE_LIST = "[<selection>] ...";

    public final static String[] HELP_LIST = new String[] {
            "List the pids of existing configurations.",
            "<selection>  A pid that can contain wildcards '*',",
            "             or an ldap filter, or an index in output",
            "             from the latest use of this command.",
            "             If no selection is given all existing pids",
            "             will be listed." };

    public int cmdList(Dictionary opts, Reader in, PrintWriter out,
            Session session) {
        int retcode = 1; // 1 initially not set to 0 until end of try block
        ConfigurationAdmin srvCA = null;
        try {
            srvCA = getCA();

            String[] selection = (String[]) opts.get("selection");

            Configuration[] cs = null;
            if (selection == null) {
                cs = srvCA.listConfigurations(null);
            } else {
                cs = getConfigurations(session, srvCA, selection);
            }
            if (cs == null || cs.length == 0) {
                out.println("No configurations available");
            } else {
                sortConfigurationArray(cs);
                setSessionProperty(session, LISTED_CONFIGS, cs);
                out.println("Available configurations:");
                for (int i = 0; i < cs.length; ++i) {
                    out.println("[" + i + "] " + cs[i].getPid());
                }
            }

            retcode = 0; // Success!
        } catch (Exception e) {
            out.println("List failed. Details:");
            String reason = e.getMessage();
            out.println(reason == null ? "<unknown>" : reason);

        } finally {
            if (srvCA != null) {
                bc.ungetService(refCA);
            }
        }
        return retcode;
    }

    public final static String USAGE_SHOW = "[<selection>] ...";

    public final static String[] HELP_SHOW = new String[] {
            "Show the saved versions of configurations.",
            "<selection>  A pid that can contain wildcards '*',",
            "             or an ldap filter, or an index in output",
            "             from the latest use of the 'list' command.",
            "             If no selection is given all configurations",
            "             will be shown.",
            "             Use 'current' command to see the properties",
            "             of the currently edited configuration." };

    public int cmdShow(Dictionary opts, Reader in, PrintWriter out,
            Session session) {
        ConfigurationAdmin srvCA = null;

        try {
            srvCA = getCA();
            String[] selection = (String[]) opts.get("selection");
            Configuration[] cs = getConfigurations(session, srvCA, selection);
            if (cs == null || cs.length == 0) {
                throw new Exception("No matching configurations for selection.");
            }
            for (int i = 0; i < cs.length; ++i) {
                if (i > 0) {
                    out.println();
                }
                Dictionary d = cs[i].getProperties();
                if (d == null) {
                    out.println("No properties set in " + cs[i].getPid());
                } else {
                    out.println("Properties for " + cs[i].getPid());
                    printDictionary(out, d);
                }
            }
        } catch (Exception e) {
            out.println("Show failed. Details:");
            String reason = e.getMessage();
            out.println(reason == null ? "<unknown>" : reason);
        } finally {
            if (srvCA != null) {
                bc.ungetService(refCA);
            }
        }
        return 0;
    }

    public final static String USAGE_CREATE = "[-f] <pid>";

    public final static String[] HELP_CREATE = new String[] {
            "Create a configuration and open it for editing.",
            "-f     If specified the pid argument is a factory pid.",
            "<pid>  Pid or factory pid of configuration to create",
            "       depending on if -f flag is specified." };

    public int cmdCreate(Dictionary opts, Reader in, PrintWriter out,
            Session session) {
        int retcode = 1; // 1 initially not set to 0 until end of try block
        setCurrent(session, null);
        setEditingDict(session, null);
        ConfigurationAdmin srvCA = null;
        try {
            srvCA = getCA();
            String pid = (String) opts.get("pid");
            boolean createFactoryConfiguration = opts.get("-f") != null;
            Configuration cfg = null;
            if (createFactoryConfiguration) {
                cfg = srvCA.createFactoryConfiguration(pid, null);
            } else {
                cfg = srvCA.getConfiguration(pid, null);
            }

            if (cfg == null) {
                throw new Exception("Failed creating configuration for " + pid);
            }
            setCurrent(session, cfg);
            retcode = 0; // Success!
        } catch (Exception e) {
            out.println("Create failed. Details:");
            String reason = e.getMessage();
            out.println(reason == null ? "<unknown>" : reason);

        } finally {
            if (srvCA != null) {
                bc.ungetService(refCA);
            }
        }
        return retcode;
    }

    public final static String USAGE_DELETE = "<selection>";

    public final static String[] HELP_DELETE = new String[] {
            "Delete an existing configuration.",
            "<selection>  A pid that can contain wildcards '*',",
            "             or an ldap filter, or an index in output",
            "             from the latest use of the 'list' command.",
            "             If the selection doesn't match exactly one",
            "             configuration it will have to be refined." };

    public int cmdDelete(Dictionary opts, Reader in, PrintWriter out,
            Session session) {
        int retcode = 1; // 1 initially not set to 0 until end of try block
        ConfigurationAdmin srvCA = null;
        try {
            String selection = (String) opts.get("selection");

            srvCA = getCA();

            Configuration[] cs = getConfigurations(session, srvCA, selection);
            if (cs == null || cs.length == 0) {
                throw new Exception(
                        "Selection didn't match any configurations. "
                                + "Change your selection to match exactly "
                                + "one configuration.");
            } else if (cs.length == 1) {
                out.println("Deleting " + cs[0].getPid());
                Configuration current = getCurrent(session);
                if (current != null && current.getPid().equals(cs[0].getPid())) {
                    setCurrent(session, null);
                    setEditingDict(session, null);
                }
                cs[0].delete();
            } else {
                throw new Exception(
                        "Selection matched "
                                + cs.length
                                + " configurations. "
                                + "Refine your selection to match exactly one configuration.");
            }
            retcode = 0; // Success!
        } catch (Exception e) {
            out.println("Delete failed. Details:");
            String reason = e.getMessage();
            out.println(reason == null ? "<unknown>" : reason);

        } finally {
            if (srvCA != null) {
                bc.ungetService(refCA);
            }
        }
        return retcode;
    }

    public final static String USAGE_EDIT = "<selection>";

    public final static String[] HELP_EDIT = new String[] {
            "Edit an existing configuration.",
            "<selection>  A pid that can contain wildcards '*',",
            "             or an ldap filter, or an index in output",
            "             from the latest use of the 'list' command.",
            "             If the selection doesn't match exactly one",
            "             configuration it will have to be refined." };

    public int cmdEdit(Dictionary opts, Reader in, PrintWriter out,
            Session session) {
        int retcode = 1; // 1 initially not set to 0 until end of try block
        setEditingDict(session, null);
        setCurrent(session, null);

        ConfigurationAdmin srvCA = null;
        try {
            String selection = (String) opts.get("selection");

            srvCA = getCA();

            Configuration[] cs = getConfigurations(session, srvCA, selection);
            if (cs == null || cs.length == 0) {
                throw new Exception(
                        "Selection didn't match any configurations. "
                                + "Use 'create' to create the configuration you want to edit "
                                + "if it doesnt exist, or change your selection to match "
                                + "exactly one configuration.");
            } else if (cs.length == 1) {
                out.println("Editing " + cs[0].getPid());
                setCurrent(session, cs[0]);
            } else {
                throw new Exception(
                        "Selection matched "
                                + cs.length
                                + " configurations. "
                                + "Refine your selection to match exactly one configuration.");
            }

            retcode = 0; // Success!
        } catch (Exception e) {
            out.println("Edit failed. Details:");
            String reason = e.getMessage();
            out.println(reason == null ? "<unknown>" : reason);

        } finally {
            if (srvCA != null) {
                bc.ungetService(refCA);
            }
        }
        return retcode;
    }

    public final static String USAGE_CURRENT = "";

    public final static String[] HELP_CURRENT = new String[] { "Show the currently open configuration." };

    public int cmdCurrent(Dictionary opts, Reader in, PrintWriter out,
            Session session) {
        Configuration cfg = getCurrent(session);
        if (cfg == null) {
            out.println("No configuration open currently");
        } else {
            if (isEditing(session)) {
                printDictionary(out, getEditingDict(session));
            } else {
                Dictionary d = cfg.getProperties();
                if (d == null) {
                    out.println("No properties set in current configuration");
                } else {
                    printDictionary(out, d);
                }
            }
        }
        return 0;
    }

    public final static String USAGE_SAVE = "[-force]";

    public final static String[] HELP_SAVE = new String[] {
            "Save the currently open configuration in the CM.",
            "-force   Force the save" };

    public int cmdSave(Dictionary opts, Reader in, PrintWriter out,
            Session session) {
        int retcode = 1; // 1 initially not set to 0 until end of try block
        boolean forceOptionNotSpecified = opts.get("-force") == null;
        ConfigurationAdmin srvCA = null;
        try {
            Configuration cfg = getCurrent(session);
            if (cfg == null) {
                throw new Exception("No configuration open currently");
            }
            srvCA = getCA();

            if (forceOptionNotSpecified && configurationHasChanged(srvCA, cfg)) {
                throw new Exception(
                        "The configuration has changed in CM since it was opened."
                                + "Use -force option if you want to force saving of your changes.");
            }

            if (isEditing(session)) {
                cfg.update(getEditingDict(session));
                setEditingDict(session, null);
            } else {
                throw new Exception("No changes to save");
            }
            retcode = 0; // Success!
        } catch (Exception e) {
            out.println("Save failed. Details:");
            String reason = e.getMessage();
            out.println(reason == null ? "<unknown>" : reason);
        } finally {
            if (srvCA != null) {
                bc.ungetService(refCA);
            }
        }
        return retcode;
    }

    public final static String USAGE_SET = "<property> <value> [<type>]";

    public final static String[] HELP_SET = new String[] {
            "Set a property in the currently open configuration.",
            "<property> Name of property to set in configuration",
            "<value>    New value of property", "<type>     Type of value",
            "Allowed types:", "  String|Integer|Long|Float|Double|Byte|Short|",
            "  Character|Boolean|BigInteger|BigDecimal" };

    public int cmdSet(Dictionary opts, Reader in, PrintWriter out,
            Session session) {
        int retcode = 1; // 1 initially not set to 0 until end of try block
        try {
            if (getCurrent(session) == null)
                throw new Exception("No configuration open currently");

            String p = (String) opts.get("property");
            String v = (String) opts.get("value");
            String t = (String) opts.get("type");
            Dictionary dict = getEditingDict(session);
            Object ov = dict.get(p);

            if (t == null) {
                if (ov == null) {
                    dict.put(p, v);
                } else {
                    Class ovc = ov.getClass();
                    Object nv = stringToObjectOfClass(v, ovc);
                    if (nv == null) {
                        throw new Exception(
                                "Unable to convert argument to the same type as old value of property");
                    }
                    dict.put(p, nv);
                }
            } else {
                Object o = null;
                try {
                    o = createValue(t, v);
                } catch (Exception e) {
                    o = null;
                }
                if (o == null) {
                    throw new Exception("Unable to convert " + v + " to " + t);
                }
                dict.put(p, o);
            }
            retcode = 0; // Success!
        } catch (Exception e) {
            out.println("Set failed. Details:");
            String reason = e.getMessage();
            out.println(reason == null ? "<unknown>" : reason);
        } finally {
            // bluerg
        }

        return retcode;
    }

    public final static String USAGE_UNSET = "<property>";

    public final static String[] HELP_UNSET = new String[] {
            "Remove a property from the currently open configuration.",
            "<property> Name of property to remove from the configuration." };

    public int cmdUnset(Dictionary opts, Reader in, PrintWriter out,
            Session session) {
        int retcode = 1; // 1 initially not set to 0 until end of try block
        try {
            if (getCurrent(session) == null) {
                throw new Exception("No configuration open currently");
            }
            String p = (String) opts.get("property");
            Dictionary dict = getEditingDict(session);
            Object o = dict.remove(p);
            if (o == null) {
                throw new Exception("No property named " + p
                        + " in current configuration.");
            }
            retcode = 0; // Success!
        } catch (Exception e) {
            out.println("Unset failed. Details:");
            String reason = e.getMessage();
            out.println(reason == null ? "<unknown>" : reason);
        } finally {

        }

        return retcode;
    }

    public final static String USAGE_IMPORT = "<url>";

    public final static String[] HELP_IMPORT = new String[] {
            "Import configuration data from xml file at url.",
            "<url>   URL to an xml file containing configuration data" };

    public int cmdImport(Dictionary opts, Reader in, final PrintWriter out,
            Session session) {
        int retcode = 1; // 1 initially not set to 0 until end of try block
        try {
            final String spec = (String) opts.get("url");
            final URL url = new URL(spec);
            if (url == null) {
                throw new Exception("URL Object construction failed");
            }

            AccessController.doPrivileged(new PrivilegedExceptionAction() {
                public Object run() throws Exception {
                    ConfigurationAdmin configAdmin = null;
                    PushbackReader reader = null;
                    try {
                        configAdmin = getCA();

                        CMDataReader cmDataReader = new CMDataReader();
                        reader = new PushbackReader(new BufferedReader(
                                new InputStreamReader(url.openStream(),
                                        CMDataReader.ENCODING), 8192), 8);
                        Hashtable[] configs = cmDataReader.readCMDatas(reader);

                        for (int i = 0; i < configs.length; i++) {
                            String pid = (String) configs[i]
                                    .get(CMDataReader.SERVICE_PID);
                            String fpid = (String) configs[i]
                                    .get(CMDataReader.FACTORY_PID);
                            Configuration config;
                            if (fpid == null) {
                                config = configAdmin
                                        .getConfiguration(pid, null);
                            } else {
                                config = configAdmin
                                        .createFactoryConfiguration(fpid, null);
                            }
                            if (config.getBundleLocation() != null) {
                                config.setBundleLocation(null);
                            }
                            if (configs[i].get("service.bundleLocation") != null) {
                                configs[i].remove("service.bundleLocation");
                            }
                            config.update(configs[i]);
                        }
                    } finally {
                        if (reader != null) {
                            reader.close();
                        }
                        if (configAdmin != null) {
                            bc.ungetService(refCA);
                        }
                    }
                    return null;
                }
            });

            retcode = 0; // Success!
        } catch (MalformedURLException e) {
            out.println("Could not create URL. Details:");
            String reason = e.getMessage();
            out.println(reason == null ? "<unknown>" : reason);
        } catch (IOException e) {
            out.println("Import failed. Details:");
            String reason = e.getMessage();
            out.println(reason == null ? "<unknown>" : reason);
        } catch (PrivilegedActionException pae) {
            out.println("Import failed. Details:");
            String reason = pae.getException().toString();
            out.println(reason == null ? "<unknown>" : reason);
        } catch (Exception e) {
            out.println("Import failed. Details:");
            String reason = e.getMessage();
            out.println(reason == null ? "<unknown>" : reason);
        } finally {

        }
        return retcode;
    }

    /*
     * public final static String USAGE_EXPORT = "[-template] <file> [<selection>]
     * ...";
     *
     * public final static String[] HELP_EXPORT = new String[] { "Export
     * configuration data in xml format to a file.", "-template If the output
     * should be a template.", "<file> Path to file to write xml to.", "<selection>
     * A pid that can contain wildcards '*',", " or an ldap filter, or an index
     * in output", " from the latest use of the 'list' command.", " If no
     * selection is given all existing ", " configurations will be exported." };
     *
     * public int cmdExport(Dictionary opts, Reader in, PrintWriter out, Session
     * session) { int retcode = 1; // 1 initially not set to 0 until end of try
     * block OutputStream os = null; ConfigurationAdmin srvCA = null; try {
     * srvCA = getCA();
     *
     * boolean isTemplate = opts.get("-template") != null; String[] selection =
     * (String[]) opts.get("selection"); boolean deleteAllOldConfigs = false;
     * Configuration[] cs = null; if (selection == null || selection.length ==
     * 0) { deleteAllOldConfigs = true; cs = srvCA.listConfigurations(null); }
     * else { cs = getConfigurations(session, srvCA, selection); }
     *
     * if (cs == null || cs.length == 0) { throw new Exception("No
     * configurations matching selection."); }
     *
     * final String fileName = (String) opts.get("file"); final File f = new
     * File(fileName); os = (FileOutputStream) AccessController
     * .doPrivileged(new PrivilegedExceptionAction() { public Object run()
     * throws Exception { return new FileOutputStream(f); } }); try {
     * CMDataManager.exportCMData(cs, deleteAllOldConfigs, isTemplate, srvCA,
     * os); } finally { os.close(); } retcode = 0; // Success! } catch
     * (IOException e) { out.println("Export failed. Details:"); String reason =
     * e.getMessage(); out.println(reason == null ? "<unknown>" : reason); }
     * catch (PrivilegedActionException pae) { out.println("Export failed.
     * Details:"); String reason = pae.getException().getMessage();
     * out.println(reason == null ? "<unknown>" : reason); } catch (Exception
     * e) { out.println("Export failed. Details:"); String reason =
     * e.getMessage(); out.println(reason == null ? "<unknown>" : reason); }
     * finally { if (srvCA != null) { bc.ungetService(refCA); } } return
     * retcode; }
     */

    /** Helper method that get the CA service. */
    ConfigurationAdmin getCA() throws Exception {
        ConfigurationAdmin srvCA = null;
        if (refCA == null) {
            throw new Exception("CM service is not available");
        }
        try {
            srvCA = (ConfigurationAdmin) AccessController
                    .doPrivileged(new PrivilegedExceptionAction() {
                        public Object run() throws Exception {
                            return bc.getService(refCA);
                        }
                    });
        } catch (PrivilegedActionException pae) {
            // Rethrow wrapped exception
            throw pae.getException();
        }
        if (srvCA == null) {
            throw new Exception("CM service is not available");
        }
        return srvCA;
    }

    /***************************************************************************
     * Helper method that gets the current configuration from the session.
     * Returns <code>null</code> if not availble.*
     **************************************************************************/
    private Configuration getCurrent(Session session) {
        return (Configuration) session.getProperties().get(CURRENT);
    }

    /***************************************************************************
     * Helper method that sets the current configuration in the session.*
     **************************************************************************/
    private void setSessionProperty(Session session, String key, Object value) {
        if (value == null) {
            session.getProperties().remove(key);
        } else {
            session.getProperties().put(key, value);
        }
    }

    /***************************************************************************
     * Helper method that sets the current configuration in the session.*
     **************************************************************************/
    private void setCurrent(Session session, Configuration cfg) {
        setSessionProperty(session, CURRENT, cfg);
    }

    /***************************************************************************
     * Helper method that returns true if the current configuration is * set and
     * its dictionary has been fetched. I.e. it returns true if the EDITING
     * property of the session is set.*
     **************************************************************************/
    private boolean isEditing(Session session) {
        return session.getProperties().get(EDITED) != null;
    }

    /***************************************************************************
     * Helper method that gets the editing dictionary of the current *
     * configuration from the session. Returns a new empty dictionary if current
     * is set but have no dictionary set yet.*
     **************************************************************************/
    private Dictionary getEditingDict(Session session) {
        Dictionary dict = (Dictionary) session.getProperties().get(EDITED);
        if (dict == null) {
            Configuration cfg = getCurrent(session);
            if (cfg != null) {
                dict = cfg.getProperties();
            }
            if (dict == null) {
                dict = new Hashtable();
            }
            setEditingDict(session, dict);
        }
        return dict;
    }

    private boolean configurationHasChanged(ConfigurationAdmin ca,
            Configuration c1) throws Exception {
        String pid = c1.getPid();
        Configuration c2 = ca.getConfiguration(pid, null);
        return DictionaryUtils.dictionariesAreNotEqual(c1.getProperties(), c2
                .getProperties());
    }

    private Configuration[] getConfigurations(Session session,
            ConfigurationAdmin cm, String[] selection) throws Exception {
        Filter[] filters = convertToFilters(session, selection);
        return getConfigurationsMatchingFilters(cm, filters);
    }

    private Configuration[] getConfigurations(Session session,
            ConfigurationAdmin cm, String selection) throws Exception {
        return getConfigurations(session, cm, new String[] { selection });
    }

    private Filter[] convertToFilters(Session session, String[] selection)
            throws Exception {
        if (selection == null) {
            return null;
        }
        Filter[] filters = new Filter[selection.length];
        for (int i = 0; i < selection.length; ++i) {
            String current = selection[i];
            Filter filter = null;
            if (isInteger(current)) {
                filter = tryToCreateFilterFromIndex(session, current);
            } else if (startsWithParenthesis(current)) {
                filter = tryToCreateFilterFromLdapExpression(current);
            } else {
                filter = tryToCreateFilterFromPidContainingWildcards(current);
            }
            if (filter == null) {
                throw new Exception("Unable to handle selection argument "
                        + current);
            }
            filters[i] = filter;
        }
        return filters;
    }

    private boolean isInteger(String possiblyAnInteger) {
        try {
            Integer.parseInt(possiblyAnInteger);
        } catch (NumberFormatException e) {
            return false;
        }
        return true;
    }

    private boolean startsWithParenthesis(String selection) {
        return selection.startsWith("(");
    }

    private Filter tryToCreateFilterFromIndex(Session session, String index)
            throws Exception {
        String pid = getPidWithIndexInLastList(session, index);
        return tryToCreateFilterFromPidContainingWildcards(pid);
    }

    private Filter tryToCreateFilterFromPidContainingWildcards(
            String pidContainingWildcards) throws Exception {
        return tryToCreateFilterFromLdapExpression("(" + Constants.SERVICE_PID
                + "=" + pidContainingWildcards + ")");
    }

    private Filter tryToCreateFilterFromLdapExpression(String ldapExpression)
            throws Exception {
        return bc.createFilter(ldapExpression);
    }

    private String getPidWithIndexInLastList(Session session, String index)
            throws Exception {
        Configuration[] cs = (Configuration[]) session.getProperties().get(
                LISTED_CONFIGS);
        if (cs == null) {
            throw new Exception(
                    "The 'list' command has not been used yet to create a list.");
        }
        if (cs.length == 0) {
            throw new Exception(
                    "No configurations listed by latest 'list' call.");
        }
        int i = Integer.parseInt(index);
        if (i < 0 || cs.length <= i) {
            throw new Exception("Invalid index."
                    + ((cs.length == 1) ? "0 is the only valid index."
                            : ("Valid indices are 0 to " + (cs.length - 1))));
        }

        String pid = cs[i].getPid();
        if (pid == null) {
            throw new Exception("Unable to retrieve pid with index " + index
                    + " from last 'list'.");
        }

        return pid;
    }

    private Configuration[] getConfigurationsMatchingFilters(
            ConfigurationAdmin cm, Filter[] filters) throws Exception {
        Configuration[] cs = cm.listConfigurations(null);
        if (cs == null || cs.length == 0) {
            return new Configuration[0];
        }
        if (filters == null || filters.length == 0) {
            return cs;
        }

        Vector matching = new Vector();
        for (int i = 0; i < cs.length; ++i) {
            for (int j = 0; j < filters.length; ++j) {
                if (filters[j].match(cs[i].getProperties())) {
                    matching.addElement(cs[i]);
                    break;
                }
            }
        }

        Configuration[] result = new Configuration[matching.size()];
        matching.copyInto(result);
        return result;
    }

    /***************************************************************************
     * Helper method that sets the editing dictionary of the current
     * configuration in the session.*
     **************************************************************************/
    private void setEditingDict(Session session, Dictionary dict) {
        if (dict == null)
            session.getProperties().remove(EDITED);
        else
            session.getProperties().put(EDITED, dict);
    }

    private void printDictionary(PrintWriter out, Dictionary d) {
        String[] keyNames = new String[d.size()];
        int i = 0;
        for (Enumeration keys = d.keys(); keys.hasMoreElements();) {
            keyNames[i++] = (String) keys.nextElement();
        }
        Sort.sortStringArray(keyNames);
        for (i = 0; i < keyNames.length; i++) {
            out.print(" ");
            out.print(keyNames[i]);
            out.print(": ");
            printValue(out, d.get(keyNames[i]));
            out.println();
        }
    }

    private void printValue(PrintWriter out, Object val) {
        if (val instanceof Vector) {
            Vector v = (Vector) val;
            out.print("{");
            for (int i = 0; i < v.size(); i++) {
                if (i > 0)
                    out.print(", ");
                printValue(out, v.elementAt(i));
            }
            out.print("}");
        } else if (val.getClass().isArray()) {
            int length = Array.getLength(val);
            out.print("[");
            for (int i = 0; i < length; i++) {
                if (i > 0)
                    out.print(", ");
                printValue(out, Array.get(val, i));
            }
            out.print("]");
        } else {
            out.print(val.toString());
        }
    }

    private Object stringToObjectOfClass(String str, Class c) {
        if (str == null) {
            return null;
        }
        Object o = null;
        try {
            if (c == null || c == String.class) {
                o = str;
            } else if (str.length() == 0) {
                // None of the other Classes can handle a zero length String
                o = null;
            } else if (c == Integer.class) {
                return new Integer(str);
            } else if (c == Long.class) {
                o = new Long(str);
            } else if (c == Float.class) {
                o = new Float(str);
            } else if (c == Double.class) {
                o = new Double(str);
            } else if (c == Byte.class) {
                o = new Byte(str);
            } else if (c == Short.class) {
                o = new Short(str);
            } else if (c == BigInteger.class) {
                o = new BigInteger(str);
            } else if (classBigDecimal != null && c == classBigDecimal) {
                if (consBigDecimal != null) {
                    o = consBigDecimal.newInstance(new Object[] { str });
                } else {
                    o = null;
                }
            } else if (c == Character.class) {
                o = new Character(str.charAt(0));
            } else if (c == Boolean.class) {
                o = new Boolean(str);
            } else {
                o = null;
            }
        } catch (Exception ignored) {
            o = null;
        }
        return o;
    }

    Object createValue(String type, String def) {
        def = def.equals("") ? null : def;
        if (type.equals("String")) {
            return def == null ? new String() : new String(def);
        } else if (type.equals("Integer")) {
            return def == null ? new Integer(0) : new Integer(def);
        } else if (type.equals("Long")) {
            return def == null ? new Long(0) : new Long(def);
        } else if (type.equals("Float")) {
            return def == null ? new Float(0) : new Float(def);
        } else if (type.equals("Double")) {
            return def == null ? new Double(0) : new Double(def);
        } else if (type.equals("Byte")) {
            return def == null ? new Byte("0") : new Byte(def);
        } else if (type.equals("Short")) {
            return def == null ? new Short("0") : new Short(def);
        } else if (type.equals("BigInteger")) {
            return def == null ? new BigInteger("0") : new BigInteger(def);
        } else if (type.equals("BigDecimal")) {
            Object o = null;
            if (classBigDecimal != null && consBigDecimal != null) {
                def = def == null ? "0" : def;
                try {
                    o = consBigDecimal.newInstance(new Object[] { def });
                } catch (Exception ignored) {
                    o = null;
                }
            }
            return o;
        } else if (type.equals("Character")) {
            return def == null ? new Character('a') : new Character(def
                    .charAt(0));
        } else if (type.equals("Boolean")) {
            return def == null ? new Boolean(false) : new Boolean(def);
        } else {
            // Unsupported type
            return null;
        }
    }

    // ////////////////
    private static void sortConfigurationArray(Configuration[] a) {
        sortConfigurationArray(a, 0, a.length);
    }

    private static void sortConfigurationArray(Configuration[] a,
            int fromIndex, int toIndex) {
        int middle;
        if (a == null)
            return;

        if (fromIndex + 1 < toIndex) {
            middle = (fromIndex + toIndex) / 2;
            sortConfigurationArray(a, fromIndex, middle);
            sortConfigurationArray(a, middle, toIndex);
            mergeConfigurationArray(a, fromIndex, toIndex);
        }
    }

    private static void mergeConfigurationArray(Configuration[] a,
            int fromIndex, int toIndex) {
        int i, j, k, middle, n;
        n = toIndex - fromIndex;
        Configuration[] b = new Configuration[n]; // temporary array

        k = 0;
        middle = (fromIndex + toIndex) / 2;

        // Copy lower half to array b
        for (i = fromIndex; i < middle; i++)
            b[k++] = a[i];
        // Copy upper half to array b in oppsite order
        for (j = toIndex - 1; j >= middle; j--)
            b[k++] = a[j];

        i = 0;
        j = n - 1;
        k = fromIndex;

        // Copy back next-greatest element at each time
        // until i and j cross
        while (i <= j) {
            if (b[i].getPid().compareTo(b[j].getPid()) < 0)
                a[k++] = b[i++];
            else
                a[k++] = b[j--];
        }
    }

    // //////////////////////////////////
    public void serviceChanged(ServiceEvent event) {
        switch (event.getType()) {
        case ServiceEvent.REGISTERED:
            ServiceReference sr = event.getServiceReference();
            if (refCA != sr) {
                refCA = sr;
            }
            break;
        case ServiceEvent.MODIFIED:
            break;
        case ServiceEvent.UNREGISTERING:
            if (refCA != null) {
                refCA = null;
            }
            break;
        default:
            break;
        }
    }
}
TOP

Related Classes of org.knopflerfish.bundle.cm.commands.impl.CMCommands

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.