/* * 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 = "[] ..."; public final static String[] HELP_LIST = new String[] { "List the pids of existing configurations.", " 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 ? "" : reason); } finally { if (srvCA != null) { bc.ungetService(refCA); } } return retcode; } public final static String USAGE_SHOW = "[] ..."; public final static String[] HELP_SHOW = new String[] { "Show the saved versions of configurations.", " 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 ? "" : reason); } finally { if (srvCA != null) { bc.ungetService(refCA); } } return 0; } public final static String USAGE_CREATE = "[-f] "; 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 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 ? "" : reason); } finally { if (srvCA != null) { bc.ungetService(refCA); } } return retcode; } public final static String USAGE_DELETE = ""; public final static String[] HELP_DELETE = new String[] { "Delete an existing configuration.", " 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 ? "" : reason); } finally { if (srvCA != null) { bc.ungetService(refCA); } } return retcode; } public final static String USAGE_EDIT = ""; public final static String[] HELP_EDIT = new String[] { "Edit an existing configuration.", " 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 ? "" : 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 ? "" : reason); } finally { if (srvCA != null) { bc.ungetService(refCA); } } return retcode; } public final static String USAGE_SET = " []"; public final static String[] HELP_SET = new String[] { "Set a property in the currently open configuration.", " Name of property to set in configuration", " New value of property", " 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 ? "" : reason); } finally { // bluerg } return retcode; } public final static String USAGE_UNSET = ""; public final static String[] HELP_UNSET = new String[] { "Remove a property from the currently open configuration.", " 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 ? "" : reason); } finally { } return retcode; } public final static String USAGE_IMPORT = ""; public final static String[] HELP_IMPORT = new String[] { "Import configuration data from xml file at 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 ? "" : reason); } catch (IOException e) { out.println("Import failed. Details:"); String reason = e.getMessage(); out.println(reason == null ? "" : reason); } catch (PrivilegedActionException pae) { out.println("Import failed. Details:"); String reason = pae.getException().toString(); out.println(reason == null ? "" : reason); } catch (Exception e) { out.println("Import failed. Details:"); String reason = e.getMessage(); out.println(reason == null ? "" : reason); } finally { } return retcode; } /* * public final static String USAGE_EXPORT = "[-template] [] * ..."; * * 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.", " Path to file to write xml to.", " * 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 ? "" : reason); } * catch (PrivilegedActionException pae) { out.println("Export failed. * Details:"); String reason = pae.getException().getMessage(); * out.println(reason == null ? "" : reason); } catch (Exception * e) { out.println("Export failed. Details:"); String reason = * e.getMessage(); out.println(reason == null ? "" : 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 null 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; } } }