You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2005/08/16 20:34:41 UTC
svn commit: r233031 [3/21] - in /incubator/oscar/trunk: ./ etc/ lib/ src/
src/org/ src/org/apache/ src/org/apache/osgi/ src/org/apache/osgi/bundle/
src/org/apache/osgi/bundle/bundlerepository/
src/org/apache/osgi/bundle/bundlerepository/kxmlsax/ src/or...
Added: incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/RepositoryState.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/RepositoryState.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/RepositoryState.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/RepositoryState.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,563 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.osgi.bundle.bundlerepository;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import org.apache.osgi.bundle.bundlerepository.kxmlsax.KXmlSAXParser;
+import org.apache.osgi.bundle.bundlerepository.metadataparser.MultivalueMap;
+import org.apache.osgi.bundle.bundlerepository.metadataparser.XmlCommonHandler;
+import org.apache.osgi.service.bundlerepository.BundleRecord;
+import org.apache.osgi.service.bundlerepository.ResolveException;
+import org.osgi.framework.*;
+
+public class RepositoryState
+{
+ private BundleContext m_context = null;
+ private String[] m_urls = null;
+ private Map m_recordMap = new HashMap();
+ private BundleRecord[] m_recordArray = null;
+ private boolean m_initialized = false;
+
+ private int m_hopCount = 1;
+
+ private static final String[] DEFAULT_REPOSITORY_URL = {
+ "http://oscar-osgi.sf.net/alpha/repository.xml"
+ };
+ public static final String REPOSITORY_URL_PROP = "osgi.repository.url";
+ public static final String EXTERN_REPOSITORY_TAG = "extern-repositories";
+
+ public RepositoryState(BundleContext context)
+ {
+ m_context = context;
+
+ String urlStr = m_context.getProperty(REPOSITORY_URL_PROP);
+ if (urlStr != null)
+ {
+ StringTokenizer st = new StringTokenizer(urlStr);
+ if (st.countTokens() > 0)
+ {
+ m_urls = new String[st.countTokens()];
+ for (int i = 0; i < m_urls.length; i++)
+ {
+ m_urls[i] = st.nextToken();
+ }
+ }
+ }
+
+ // Use the default URL if none were specified.
+ if (m_urls == null)
+ {
+ m_urls = DEFAULT_REPOSITORY_URL;
+ }
+ }
+
+ public String[] getURLs()
+ {
+ // Return a copy because the array is mutable.
+ return (m_urls == null) ? null : (String[]) m_urls.clone();
+ }
+
+ public void setURLs(String[] urls)
+ {
+ if (urls != null)
+ {
+ m_urls = urls;
+ initialize();
+ }
+ }
+
+ public BundleRecord[] getRecords()
+ {
+ if (!m_initialized)
+ {
+ initialize();
+ }
+
+ // Returned cached array of bundle records.
+ return m_recordArray;
+ }
+
+ public BundleRecord[] getRecords(String symName)
+ {
+ if (!m_initialized)
+ {
+ initialize();
+ }
+
+ // Return a copy of the array, since it would be mutable
+ // otherwise.
+ BundleRecord[] records = (BundleRecord[]) m_recordMap.get(symName);
+ // Return a copy because the array is mutable.
+ return (records == null) ? null : (BundleRecord[]) records.clone();
+ }
+
+ public BundleRecord getRecord(String symName, int[] version)
+ {
+ if (!m_initialized)
+ {
+ initialize();
+ }
+
+ BundleRecord[] records = (BundleRecord[]) m_recordMap.get(symName);
+ if ((records != null) && (records.length > 0))
+ {
+ for (int i = 0; i < records.length; i++)
+ {
+ int[] targetVersion = Util.parseVersionString(
+ (String) records[i].getAttribute(BundleRecord.BUNDLE_VERSION));
+
+ if (Util.compareVersion(targetVersion, version) == 0)
+ {
+ return records[i];
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public BundleRecord[] resolvePackages(LocalState localState, Filter[] reqFilters)
+ throws ResolveException
+ {
+ // Create a list that will contain the transitive closure of
+ // all import dependencies; use a list because this will keep
+ // everything in order.
+ List deployList = new ArrayList();
+ // Add the target bundle
+ resolvePackages(localState, reqFilters, deployList);
+
+ // Convert list of symbolic names to an array of bundle
+ // records and return it.
+ BundleRecord[] records = new BundleRecord[deployList.size()];
+ return (BundleRecord[]) deployList.toArray(records);
+ }
+
+ private void resolvePackages(
+ LocalState localState, Filter[] reqFilters, List deployList)
+ throws ResolveException
+ {
+ for (int reqIdx = 0;
+ (reqFilters != null) && (reqIdx < reqFilters.length);
+ reqIdx++)
+ {
+ // If the package can be locally resolved, then
+ // it can be completely ignored; otherwise, try
+ // to find a resolving bundle.
+ if (!localState.isResolvable(reqFilters[reqIdx]))
+ {
+ // Select resolving bundle for current package.
+ BundleRecord source = selectResolvingBundle(
+ deployList, localState, reqFilters[reqIdx]);
+ // If there is no resolving bundle, then throw a
+ // resolve exception.
+ if (source == null)
+ {
+throw new IllegalArgumentException("HACK: SHOULD THROW RESOLVE EXCEPTION: " + reqFilters[reqIdx]);
+// throw new ResolveException(reqFilters[reqIdx]);
+ }
+ // If the resolving bundle is already in the deploy list,
+ // then just ignore it; otherwise, add it to the deploy
+ // list and resolve its packages.
+ if (!deployList.contains(source))
+ {
+ deployList.add(source);
+ Filter[] filters = (Filter[])
+ source.getAttribute("requirements");
+ resolvePackages(localState, filters, deployList);
+ }
+ }
+ }
+ }
+
+ /**
+ * Selects a single source bundle record for the target package from
+ * the repository. The algorithm tries to select a source bundle record
+ * if it is already installed locally in the framework; this approach
+ * favors updating already installed bundles rather than installing
+ * new ones. If no matching bundles are installed locally, then the
+ * first bundle record providing the target package is returned.
+ * @param targetPkg the target package for which to select a source
+ * bundle record.
+ * @return the selected bundle record or <tt>null</tt> if no sources
+ * could be found.
+ **/
+ private BundleRecord selectResolvingBundle(
+ List deployList, LocalState localState, Filter targetFilter)
+ {
+ BundleRecord[] exporters = findExporters(targetFilter);
+ if (exporters == null)
+ {
+ return null;
+ }
+
+ // Try to select a source bundle record that is already
+ // in the deployed list to minimize the number of bundles
+ // that need to be deployed. If this is not possible, then
+ // try to select a bundle that is already installed locally,
+ // since it might be possible to update this bundle to
+ // minimize the number of bundles installed in the framework.
+ for (int i = 0; i < exporters.length; i++)
+ {
+ if (deployList.contains(exporters[i]))
+ {
+ return exporters[i];
+ }
+ else
+ {
+ String symName = (String)
+ exporters[i].getAttribute(BundleRecord.BUNDLE_SYMBOLICNAME);
+ if (symName != null)
+ {
+ BundleRecord[] records = localState.findBundles(symName);
+ if (records != null)
+ {
+ return exporters[i];
+ }
+ }
+ }
+ }
+
+ // If none of the sources are installed locally, then
+ // just pick the first one.
+ return exporters[0];
+ }
+
+ /**
+ * Returns an array of bundle records that resolve the supplied
+ * package declaration.
+ * @param target the package declaration to resolve.
+ * @return an array of bundle records that resolve the package
+ * declaration or <tt>null</tt> if none are found.
+ **/
+ private BundleRecord[] findExporters(Filter targetFilter)
+ {
+ MapToDictionary mapDict = new MapToDictionary(null);
+
+ // Create a list for storing bundles that can resolve package.
+ List resolveList = new ArrayList();
+ for (int recIdx = 0; recIdx < m_recordArray.length; recIdx++)
+ {
+ Map[] capMaps = (Map[]) m_recordArray[recIdx].getAttribute("capability");
+ for (int capIdx = 0; capIdx < capMaps.length; capIdx++)
+ {
+ mapDict.setSourceMap(capMaps[capIdx]);
+ if (targetFilter.match(mapDict))
+ {
+ resolveList.add(m_recordArray[recIdx]);
+ }
+ }
+ }
+
+ // If no resolving bundles were found, return null.
+ if (resolveList.size() == 0)
+ {
+ return null;
+ }
+
+ // Otherwise, return an array containing resolving bundles.
+ return (BundleRecord[]) resolveList.toArray(new BundleRecord[resolveList.size()]);
+ }
+
+ private boolean isUpdateAvailable(
+ PrintStream out, PrintStream err, Bundle bundle)
+ {
+ // Get the bundle's update location.
+ String symname =
+ (String) bundle.getHeaders().get(BundleRecord.BUNDLE_SYMBOLICNAME);
+
+ // Get associated repository bundle recorded for the
+ // local bundle and see if an update is necessary.
+ BundleRecord[] records = getRecords(symname);
+ if (records == null)
+ {
+ err.println(Util.getBundleName(bundle) + " not in repository.");
+ return false;
+ }
+
+ // Check bundle version againts bundle record version.
+ for (int i = 0; i < records.length; i++)
+ {
+ int[] bundleVersion = Util.parseVersionString(
+ (String) bundle.getHeaders().get(BundleRecord.BUNDLE_VERSION));
+ int[] recordVersion = Util.parseVersionString(
+ (String) records[i].getAttribute(BundleRecord.BUNDLE_VERSION));
+ if (Util.compareVersion(recordVersion, bundleVersion) > 0)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void initialize()
+ {
+ m_initialized = true;
+ m_recordMap.clear();
+
+ for (int urlIdx = 0; (m_urls != null) && (urlIdx < m_urls.length); urlIdx++)
+ {
+ parseRepositoryFile(m_hopCount, m_urls[urlIdx]);
+ }
+
+ // Cache a sorted array of all bundle records.
+ List list = new ArrayList();
+ for (Iterator i = m_recordMap.entrySet().iterator(); i.hasNext(); )
+ {
+ BundleRecord[] records = (BundleRecord[]) ((Map.Entry) i.next()).getValue();
+ for (int recIdx = 0; recIdx < records.length; recIdx++)
+ {
+ list.add(records[recIdx]);
+ }
+ }
+ m_recordArray = (BundleRecord[]) list.toArray(new BundleRecord[list.size()]);
+ Arrays.sort(m_recordArray, new Comparator() {
+ public int compare(Object o1, Object o2)
+ {
+ BundleRecord r1 = (BundleRecord) o1;
+ BundleRecord r2 = (BundleRecord) o2;
+ String name1 = (String) r1.getAttribute(BundleRecord.BUNDLE_NAME);
+ String name2 = (String) r2.getAttribute(BundleRecord.BUNDLE_NAME);
+ return name1.compareToIgnoreCase(name2);
+ }
+ });
+ }
+
+ private void parseRepositoryFile(int hopCount, String urlStr)
+ {
+ InputStream is = null;
+ BufferedReader br = null;
+
+ try
+ {
+ // Do it the manual way to have a chance to
+ // set request properties as proxy auth (EW).
+ URL url = new URL(urlStr);
+ URLConnection conn = url.openConnection();
+
+ // Support for http proxy authentication
+ String auth = System.getProperty("http.proxyAuth");
+ if ((auth != null) && (auth.length() > 0))
+ {
+ if ("http".equals(url.getProtocol()) ||
+ "https".equals(url.getProtocol()))
+ {
+ String base64 = Util.base64Encode(auth);
+ conn.setRequestProperty(
+ "Proxy-Authorization", "Basic " + base64);
+ }
+ }
+ is = conn.getInputStream();
+
+ // Create the parser Kxml
+ XmlCommonHandler handler = new XmlCommonHandler();
+ handler.addType("bundles", ArrayList.class);
+ handler.addType("repository", HashMap.class);
+ handler.addType("extern-repositories", ArrayList.class);
+ handler.addType("bundle", MultivalueMap.class);
+ handler.addType("requirement", String.class);
+ handler.addType("capability", ArrayList.class);
+ handler.addType("property", HashMap.class);
+ handler.setDefaultType(String.class);
+
+ br = new BufferedReader(new InputStreamReader(is));
+ KXmlSAXParser parser;
+ parser = new KXmlSAXParser(br);
+ try
+ {
+ parser.parseXML(handler);
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ return;
+ }
+
+ List root = (List) handler.getRoot();
+ for (int bundleIdx = 0; bundleIdx < root.size(); bundleIdx++)
+ {
+ Object obj = root.get(bundleIdx);
+
+ // The elements of the root will either be a HashMap for
+ // the repository tag or a MultivalueMap for the bundle
+ // tag, as indicated above when we parsed the file.
+
+ // If HashMap, then read repository information.
+ if (obj instanceof HashMap)
+ {
+ // Create a case-insensitive map.
+ Map repoMap = new TreeMap(new Comparator() {
+ public int compare(Object o1, Object o2)
+ {
+ return o1.toString().compareToIgnoreCase(o2.toString());
+ }
+ });
+ repoMap.putAll((Map) obj);
+
+ // Process external repositories if hop count is
+ // greater than zero.
+ if (hopCount > 0)
+ {
+ // Get the external repository list.
+ List externList = (List) repoMap.get(EXTERN_REPOSITORY_TAG);
+ for (int i = 0; (externList != null) && (i < externList.size()); i++)
+ {
+ parseRepositoryFile(hopCount - 1, (String) externList.get(i));
+ }
+ }
+ }
+ // Else if mulitvalue map, then create a bundle record
+ // for the associated bundle meta-data.
+ else if (obj instanceof MultivalueMap)
+ {
+ // Create a case-insensitive map.
+ Map bundleMap = new TreeMap(new Comparator() {
+ public int compare(Object o1, Object o2)
+ {
+ return o1.toString().compareToIgnoreCase(o2.toString());
+ }
+ });
+ bundleMap.putAll((Map) obj);
+
+ // Convert capabilities into case-insensitive maps.
+ List list = (List) bundleMap.get("capability");
+ Map[] capabilityMaps = convertCapabilities(list);
+ bundleMap.put("capability", capabilityMaps);
+
+ // Convert requirements info filters.
+ list = (List) bundleMap.get("requirement");
+ Filter[] filters = convertRequirements(list);
+ bundleMap.put("requirement", filters);
+
+ // Convert any remaining single-element lists into
+ // the element itself.
+ for (Iterator i = bundleMap.keySet().iterator(); i.hasNext(); )
+ {
+ Object key = i.next();
+ Object value = bundleMap.get(key);
+ if ((value instanceof List) &&
+ (((List) value).size() == 1))
+ {
+ bundleMap.put(key, ((List) value).get(0));
+ }
+ }
+
+ // Create a bundle record using the map.
+ BundleRecord record = new BundleRecord(bundleMap);
+ // TODO: Filter duplicates.
+ BundleRecord[] records =
+ (BundleRecord[]) m_recordMap.get(
+ record.getAttribute(BundleRecord.BUNDLE_SYMBOLICNAME));
+ if (records == null)
+ {
+ records = new BundleRecord[] { record };
+ }
+ else
+ {
+ BundleRecord[] newRecords = new BundleRecord[records.length + 1];
+ System.arraycopy(records, 0, newRecords, 0, records.length);
+ newRecords[records.length] = record;
+ records = newRecords;
+ }
+ m_recordMap.put(
+ record.getAttribute(BundleRecord.BUNDLE_SYMBOLICNAME), records);
+ }
+ }
+ }
+ catch (MalformedURLException ex)
+ {
+ ex.printStackTrace(System.err);
+// System.err.println("Error: " + ex);
+ }
+ catch (IOException ex)
+ {
+ ex.printStackTrace(System.err);
+// System.err.println("Error: " + ex);
+ }
+ finally
+ {
+ try
+ {
+ if (is != null) is.close();
+ }
+ catch (IOException ex)
+ {
+ // Not much we can do.
+ }
+ }
+ }
+
+ private Map[] convertCapabilities(List capLists)
+ {
+ Map[] capabilityMaps = new Map[(capLists == null) ? 0 : capLists.size()];
+ for (int capIdx = 0; (capLists != null) && (capIdx < capLists.size()); capIdx++)
+ {
+ // Create a case-insensitive map.
+ capabilityMaps[capIdx] = new TreeMap(new Comparator() {
+ public int compare(Object o1, Object o2)
+ {
+ return o1.toString().compareToIgnoreCase(o2.toString());
+ }
+ });
+
+ List capList = (List) capLists.get(capIdx);
+
+ for (int propIdx = 0; propIdx < capList.size(); propIdx++)
+ {
+ Map propMap = (Map) capList.get(propIdx);
+ String name = (String) propMap.get("name");
+ String type = (String) propMap.get("type");
+ String value = (String) propMap.get("value");
+ try
+ {
+ Class clazz = this.getClass().getClassLoader().loadClass(type);
+ Object o = clazz
+ .getConstructor(new Class[] { String.class })
+ .newInstance(new Object[] { value });
+ capabilityMaps[capIdx].put(name, o);
+ }
+ catch (Exception ex)
+ {
+// TODO: DETERMINE WHAT TO DO HERE.
+ // Two options here, we can either ignore the
+ // entire capability or we can just ignore the
+ // property. For now, just ignore the property.
+ continue;
+ }
+ }
+ }
+ return capabilityMaps;
+ }
+
+ private Filter[] convertRequirements(List reqsList)
+ {
+ Filter[] filters = new Filter[(reqsList == null) ? 0 : reqsList.size()];
+ for (int i = 0; (reqsList != null) && (i < reqsList.size()); i++)
+ {
+ try
+ {
+ filters[i] = m_context.createFilter((String) reqsList.get(i));
+ }
+ catch (InvalidSyntaxException ex)
+ {
+ }
+ }
+ return filters;
+ }
+}
\ No newline at end of file
Added: incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/Util.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/Util.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/Util.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/Util.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.osgi.bundle.bundlerepository;
+
+import java.io.*;
+import java.util.StringTokenizer;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+
+public class Util
+{
+ public static String getBundleName(Bundle bundle)
+ {
+ String name = (String) bundle.getHeaders().get(Constants.BUNDLE_NAME);
+ return (name == null)
+ ? "Bundle " + Long.toString(bundle.getBundleId())
+ : name;
+ }
+
+ public static int compareVersion(int[] v1, int[] v2)
+ {
+ if (v1[0] > v2[0])
+ {
+ return 1;
+ }
+ else if (v1[0] < v2[0])
+ {
+ return -1;
+ }
+ else if (v1[1] > v2[1])
+ {
+ return 1;
+ }
+ else if (v1[1] < v2[1])
+ {
+ return -1;
+ }
+ else if (v1[2] > v2[2])
+ {
+ return 1;
+ }
+ else if (v1[2] < v2[2])
+ {
+ return -1;
+ }
+ return 0;
+ }
+
+ public static int[] parseVersionString(String s)
+ {
+ int[] version = new int[] { 0, 0, 0 };
+
+ if (s != null)
+ {
+ StringTokenizer st = new StringTokenizer(s, ".");
+ if (st.hasMoreTokens())
+ {
+ try
+ {
+ version[0] = Integer.parseInt(st.nextToken());
+ if (st.hasMoreTokens())
+ {
+ version[1] = Integer.parseInt(st.nextToken());
+ if (st.hasMoreTokens())
+ {
+ version[2] = Integer.parseInt(st.nextToken());
+ }
+ }
+ return version;
+ }
+ catch (NumberFormatException ex)
+ {
+ throw new IllegalArgumentException(
+ "Improper version number.");
+ }
+ }
+ }
+
+ return version;
+ }
+
+ private static final byte encTab[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
+ 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52,
+ 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64,
+ 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
+ 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2b, 0x2f };
+
+ private static final byte decTab[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1,
+ -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1,
+ -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, -1, -1, -1, -1, -1 };
+
+ public static String base64Encode(String s) throws IOException
+ {
+ return encode(s.getBytes(), 0);
+ }
+
+ /**
+ * Encode a raw byte array to a Base64 String.
+ *
+ * @param in Byte array to encode.
+ * @param len Length of Base64 lines. 0 means no line breaks.
+ **/
+ public static String encode(byte[] in, int len) throws IOException
+ {
+ ByteArrayOutputStream baos = null;
+ ByteArrayInputStream bais = null;
+ try
+ {
+ baos = new ByteArrayOutputStream();
+ bais = new ByteArrayInputStream(in);
+ encode(bais, baos, len);
+ // ASCII byte array to String
+ return (new String(baos.toByteArray()));
+ }
+ finally
+ {
+ if (baos != null)
+ {
+ baos.close();
+ }
+ if (bais != null)
+ {
+ bais.close();
+ }
+ }
+ }
+
+ public static void encode(InputStream in, OutputStream out, int len)
+ throws IOException
+ {
+
+ // Check that length is a multiple of 4 bytes
+ if (len % 4 != 0)
+ {
+ throw new IllegalArgumentException("Length must be a multiple of 4");
+ }
+
+ // Read input stream until end of file
+ int bits = 0;
+ int nbits = 0;
+ int nbytes = 0;
+ int b;
+
+ while ((b = in.read()) != -1)
+ {
+ bits = (bits << 8) | b;
+ nbits += 8;
+ while (nbits >= 6)
+ {
+ nbits -= 6;
+ out.write(encTab[0x3f & (bits >> nbits)]);
+ nbytes++;
+ // New line
+ if (len != 0 && nbytes >= len)
+ {
+ out.write(0x0d);
+ out.write(0x0a);
+ nbytes -= len;
+ }
+ }
+ }
+
+ switch (nbits)
+ {
+ case 2:
+ out.write(encTab[0x3f & (bits << 4)]);
+ out.write(0x3d); // 0x3d = '='
+ out.write(0x3d);
+ break;
+ case 4:
+ out.write(encTab[0x3f & (bits << 2)]);
+ out.write(0x3d);
+ break;
+ }
+
+ if (len != 0)
+ {
+ if (nbytes != 0)
+ {
+ out.write(0x0d);
+ out.write(0x0a);
+ }
+ out.write(0x0d);
+ out.write(0x0a);
+ }
+ }
+}
\ No newline at end of file
Added: incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/kxmlsax/KXmlSAXHandler.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/kxmlsax/KXmlSAXHandler.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/kxmlsax/KXmlSAXHandler.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/kxmlsax/KXmlSAXHandler.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.osgi.bundle.bundlerepository.kxmlsax;
+
+import java.util.Properties;
+
+import org.xml.sax.SAXException;
+
+/**
+ * Interface for SAX handler with kXML
+ *
+ * @author Didier Donsez (didier.donsez@imag.fr)
+ */
+public interface KXmlSAXHandler {
+
+ /**
+ * Method called when parsing text
+ *
+ * @param ch
+ * @param offset
+ * @param length
+ * @exception SAXException
+ */
+ public void characters(char[] ch, int offset, int length) throws Exception;
+
+ /**
+ * Method called when a tag opens
+ *
+ * @param uri
+ * @param localName
+ * @param qName
+ * @param attrib
+ * @exception SAXException
+ **/
+ public void startElement(
+ String uri,
+ String localName,
+ String qName,
+ Properties attrib)
+ throws Exception;
+ /**
+ * Method called when a tag closes
+ *
+ * @param uri
+ * @param localName
+ * @param qName
+ * @exception SAXException
+ */
+ public void endElement(
+ java.lang.String uri,
+ java.lang.String localName,
+ java.lang.String qName)
+ throws Exception;
+}
\ No newline at end of file
Added: incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/kxmlsax/KXmlSAXParser.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/kxmlsax/KXmlSAXParser.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/kxmlsax/KXmlSAXParser.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/kxmlsax/KXmlSAXParser.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.osgi.bundle.bundlerepository.kxmlsax;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Properties;
+
+import org.kxml.Attribute;
+import org.kxml.Xml;
+import org.kxml.parser.ParseEvent;
+import org.kxml.parser.XmlParser;
+
+/**
+ * The KXmlSAXParser extends the XmlParser from kxml. This is a very
+ * simple parser that does not take into account the DTD
+ *
+ * @version 1.0 08 Nov 2002
+ * @version 1.1 24 Apr 2004
+ * @author Humberto Cervantes, Didier Donsez
+ */
+public class KXmlSAXParser extends XmlParser {
+ /**
+ * The constructor for a parser, it receives a java.io.Reader.
+ *
+ * @param reader The reader
+ * @exception IOException thrown by the superclass
+ */
+ public KXmlSAXParser(Reader r) throws IOException {
+ super(r);
+ }
+
+ /**
+ * Parser from the reader provided in the constructor, and call
+ * the startElement and endElement in a KxmlHandler
+ *
+ * @param reader The reader
+ * @exception Exception thrown by the superclass
+ */
+ public void parseXML(KXmlSAXHandler handler) throws Exception {
+ ParseEvent evt = null;
+ do {
+ evt = read();
+ if (evt.getType() == Xml.START_TAG) {
+ Properties props = new Properties();
+ for (int i = 0; i < evt.getAttributeCount(); i++) {
+ Attribute attr = evt.getAttribute(i);
+ props.put(attr.getName(), attr.getValue());
+ }
+ handler.startElement(
+ "uri",
+ evt.getName(),
+ evt.getName(),
+ props);
+ } else if (evt.getType() == Xml.END_TAG) {
+ handler.endElement("uri", evt.getName(), evt.getName());
+ } else if (evt.getType() == Xml.TEXT) {
+ String text = evt.getText();
+ handler.characters(text.toCharArray(),0,text.length());
+ } else {
+ // do nothing
+ }
+ } while (evt.getType() != Xml.END_DOCUMENT);
+ }
+}
Added: incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/manifest.mf
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/manifest.mf?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/manifest.mf (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/manifest.mf Tue Aug 16 11:33:34 2005
@@ -0,0 +1,10 @@
+Bundle-Name: Bundle Repository
+Bundle-SymbolicName: org.apache.osgi.bundle.bundlerepository
+Bundle-Description: A simple bundle repository for Felix.
+Bundle-Activator: org.apache.osgi.bundle.bundlerepository.Activator
+Bundle-ClassPath: .,org/apache/osgi/bundle/bundlerepository/kxml.jar
+Bundle-Version: 2.0.0.alpha2
+Import-Package: org.osgi.framework
+DynamicImport-Package: org.apache.osgi.service.shell
+Export-Package:
+ org.apache.osgi.service.bundlerepository; specification-version="1.1.0"
Added: incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/metadataparser/ClassUtility.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/metadataparser/ClassUtility.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/metadataparser/ClassUtility.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/metadataparser/ClassUtility.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.osgi.bundle.bundlerepository.metadataparser;
+
+/**
+ * This class provides methods to process class name
+ */
+
+public class ClassUtility {
+
+ /**
+ * This method capitalizes the first character in the provided string.
+ * @return resulted string
+ */
+ public static String capitalize(String name) {
+
+ int len=name.length();
+ StringBuffer sb=new StringBuffer(len);
+ boolean setCap=true;
+ for(int i=0; i<len; i++){
+ char c=name.charAt(i);
+ if(c=='-' || c=='_') {
+ setCap=true;
+ } else {
+ if(setCap){
+ sb.append(Character.toUpperCase(c));
+ setCap=false;
+ } else {
+ sb.append(c);
+ }
+ }
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * This method capitalizes all characters in the provided string.
+ * @return resulted string
+ */
+ public static String finalstaticOf(String membername) {
+ int len=membername.length();
+ StringBuffer sb=new StringBuffer(len+2);
+ for(int i=0; i<len; i++){
+ char c=membername.charAt(i);
+ if(Character.isLowerCase(c) ) {
+ sb.append(Character.toUpperCase(c));
+ } else if(Character.isUpperCase(c) ) {
+ sb.append('_').append(c);
+ } else {
+ sb.append(c);
+ }
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * This method returns the package name in a full class name
+ * @return resulted string
+ */
+ public static String packageOf(String fullclassname) {
+ int index=fullclassname.lastIndexOf(".");
+ if(index>0) {
+ return fullclassname.substring(0,index);
+ } else {
+ return "";
+ }
+ }
+
+ /**
+ * This method returns the package name in a full class name
+ * @return resulted string
+ */
+ public static String classOf(String fullclassname) {
+ int index=fullclassname.lastIndexOf(".");
+ if(index>0) {
+ return fullclassname.substring(index+1);
+ } else {
+ return fullclassname;
+ }
+ }
+}
\ No newline at end of file
Added: incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/metadataparser/KXmlMetadataHandler.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/metadataparser/KXmlMetadataHandler.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/metadataparser/KXmlMetadataHandler.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/metadataparser/KXmlMetadataHandler.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.osgi.bundle.bundlerepository.metadataparser;
+
+import java.io.*;
+
+import org.apache.osgi.bundle.bundlerepository.kxmlsax.KXmlSAXParser;
+
+
+/**
+ * handles the metadata in XML format
+ * (use kXML (http://kxml.enhydra.org/) a open-source very light weight XML parser
+ * @version 1.00 11 Nov 2003
+ * @author Didier Donsez
+ */
+public class KXmlMetadataHandler /*implements MetadataHandler*/ {
+
+ private XmlCommonHandler handler;
+
+ public KXmlMetadataHandler() {
+ handler = new XmlCommonHandler();
+ }
+
+ /**
+ * Called to parse the InputStream and set bundle list and package hash map
+ */
+ public void parse(InputStream is) throws Exception {
+ BufferedReader br = new BufferedReader(new InputStreamReader(is));
+ KXmlSAXParser parser;
+ parser = new KXmlSAXParser(br);
+ parser.parseXML(handler);
+ }
+
+ /**
+ * return the metadata
+ * @return a Objet
+ */
+ public Object getMetadata() {
+ return handler.getRoot();
+ }
+
+ public void addType(String qname, Class clazz) {
+ handler.addType(qname, clazz);
+ }
+
+ public void setDefaultType(Class clazz) {
+ handler.setDefaultType(clazz);
+ }
+}
Added: incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/metadataparser/MultivalueMap.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/metadataparser/MultivalueMap.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/metadataparser/MultivalueMap.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/metadataparser/MultivalueMap.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.osgi.bundle.bundlerepository.metadataparser;
+
+import java.util.*;
+
+public class MultivalueMap implements Map {
+ private Map m_map = null;
+
+ public MultivalueMap() {
+ m_map = new HashMap();
+ }
+
+ public MultivalueMap(Map map) {
+ m_map = map;
+ }
+
+ /**
+ * @see java.util.Map#size()
+ */
+ public int size() {
+ return m_map.size();
+ }
+
+ /**
+ * @see java.util.Map#clear()
+ */
+ public void clear() {
+ m_map.clear();
+ }
+
+ /**
+ * @see java.util.Map#isEmpty()
+ */
+ public boolean isEmpty() {
+ return m_map.isEmpty();
+ }
+
+ /**
+ * @see java.util.Map#containsKey(java.lang.Object)
+ */
+ public boolean containsKey(Object arg0) {
+ return m_map.containsKey(arg0);
+ }
+
+ /**
+ * @see java.util.Map#containsValue(java.lang.Object)
+ */
+ public boolean containsValue(Object arg0) {
+ return false;
+ }
+
+ /**
+ * @see java.util.Map#values()
+ */
+ public Collection values() {
+ return null;
+ }
+
+ /**
+ * @see java.util.Map#putAll(java.util.Map)
+ */
+ public void putAll(Map arg0) {
+ }
+
+ /**
+ * @see java.util.Map#entrySet()
+ */
+ public Set entrySet() {
+ return m_map.entrySet();
+ }
+
+ /**
+ * @see java.util.Map#keySet()
+ */
+ public Set keySet() {
+ return m_map.keySet();
+ }
+
+ /**
+ * @see java.util.Map#get(java.lang.Object)
+ */
+ public Object get(Object key) {
+ return m_map.get(key);
+ }
+
+ /**
+ * @see java.util.Map#remove(java.lang.Object)
+ */
+ public Object remove(Object arg0) {
+ return m_map.remove(arg0);
+ }
+
+ /**
+ * @see java.util.Map#put(java.lang.Object, java.lang.Object)
+ */
+ public Object put(Object key, Object value) {
+ Object prev = m_map.get(key);
+ if (prev == null) {
+ List list = new ArrayList();
+ list.add(value);
+ m_map.put(key, list);
+ return list;
+ } else {
+ ((List) prev).add(value);
+ return prev;
+ }
+ }
+
+ public String toString() {
+ StringBuffer sb=new StringBuffer();
+ sb.append("[MultivalueMap:");
+ if(m_map.isEmpty()) {
+ sb.append("empty");
+ } else {
+ Set keys=m_map.keySet();
+ Iterator iter=keys.iterator();
+ while(iter.hasNext()){
+ String key=(String)iter.next();
+ sb.append("\n\"").append(key).append("\":");
+ sb.append(m_map.get(key).toString());
+ }
+ sb.append('\n');
+ }
+ sb.append(']');
+ return sb.toString();
+ }
+}
\ No newline at end of file
Added: incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/metadataparser/XmlCommonHandler.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/metadataparser/XmlCommonHandler.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/metadataparser/XmlCommonHandler.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/bundle/bundlerepository/metadataparser/XmlCommonHandler.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,405 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.osgi.bundle.bundlerepository.metadataparser;
+
+import java.lang.reflect.Method;
+import java.util.*;
+
+import org.apache.osgi.bundle.bundlerepository.kxmlsax.KXmlSAXHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * SAX handler for the XML OBR file
+ *
+ * @author Didier Donsez (didier.donsez@imag.fr)
+ */
+public class XmlCommonHandler implements KXmlSAXHandler {
+
+ private static final String PI_MAPPING="mapping";
+
+ private int columnNumber;
+
+ private int lineNumber;
+
+ //
+ // Data
+ //
+
+ private Object root;
+
+ private Stack objectStack;
+ private Stack qnameStack;
+
+ private Map types;
+ private Class defaultType;
+
+ private StringBuffer currentText;
+
+ public XmlCommonHandler() {
+ objectStack = new Stack();
+ qnameStack = new Stack();
+ types = new HashMap();
+ }
+
+ public void addType(String qname, Class clazz) {
+ types.put(qname, clazz);
+ }
+
+ public void setDefaultType(Class clazz) {
+ defaultType=clazz;
+ }
+
+ public Object getRoot() {
+ return root;
+ }
+
+ /* for PCDATA */
+ public void characters(char[] ch, int offset, int length)
+ throws Exception {
+ if (currentText != null)
+ currentText.append(ch, offset, length);
+ }
+
+ private String adderOf(Class clazz) {
+ return "add"
+ + ClassUtility.capitalize(ClassUtility.classOf(clazz.getName()));
+ }
+
+ private String adderOf(String key) {
+ return "add" + ClassUtility.capitalize(key);
+ }
+
+ private String setterOf(Class clazz) {
+ return "set"
+ + ClassUtility.capitalize(ClassUtility.classOf(clazz.getName()));
+ }
+
+ private String setterOf(String key) {
+ return "set" + ClassUtility.capitalize(key);
+ }
+
+ /**
+ * Method called when a tag opens
+ *
+ * @param uri
+ * @param localName
+ * @param qName
+ * @param attrib
+ * @exception SAXException
+ **/
+ public void startElement(
+ String uri,
+ String localName,
+ String qName,
+ Properties attrib)
+ throws Exception {
+
+ trace("START ("+lineNumber+","+columnNumber+"):" + uri + ":" + qName);
+
+ Class clazz = (Class) types.get(qName);
+ // TODO: should add uri in the future
+
+ if(clazz==null && defaultType!=null)
+ clazz=defaultType;
+
+ Object obj;
+ if (clazz != null) {
+
+ try {
+ obj = clazz.newInstance();
+ } catch (InstantiationException e) {
+ throw new Exception(lineNumber+","+columnNumber+":"+
+ "class "+clazz.getName()+" for element " + qName + " should have an empty constructor");
+ } catch (IllegalAccessException e) {
+ throw new Exception(lineNumber+","+columnNumber+":"+
+ "illegal access on the empty constructor of class "+clazz.getName()+" for element " + qName);
+ }
+
+ Set keyset = attrib.keySet();
+ Iterator iter = keyset.iterator();
+ while (iter.hasNext()) {
+ String key = (String) iter.next();
+
+ if (obj instanceof Map) {
+ ((Map) obj).put(key, attrib.get(key));
+ } else if (obj instanceof List) {
+ throw new Exception(lineNumber+","+columnNumber+":"+
+ "List element " + qName + " cannot have any attribute");
+ } else if (obj instanceof String) {
+ if(key.equals("value")){
+ obj=(String)attrib.get(key);
+ } else {
+ throw new Exception(lineNumber+","+columnNumber+":"+
+ "String element " + qName + " cannot have other attribute than value");
+ }
+ } else {
+ Method method = null;
+ try {
+ method =
+ clazz.getMethod(
+ setterOf(key),
+ new Class[] { String.class });
+ } catch (NoSuchMethodException e) {
+ // do nothing
+ }
+ if (method == null)
+ try {
+ method =
+ clazz.getMethod(
+ adderOf(key),
+ new Class[] { String.class });
+
+ } catch (NoSuchMethodException e) {
+ throw new Exception(lineNumber+","+columnNumber+":"+
+ "element "
+ + qName
+ + " does not support the attribute "
+ + key);
+ }
+ if (method != null)
+ method.invoke(
+ obj,
+ new String[] {(String) attrib.get(key)});
+ }
+
+ }
+
+ } else {
+ throw new Exception(lineNumber+","+columnNumber+":"+
+ "this element " + qName + " has not corresponding class");
+ }
+
+ if (root == null)
+ root = obj;
+ objectStack.push(obj);
+ qnameStack.push(qName);
+ currentText = new StringBuffer();
+
+ trace("START/ ("+lineNumber+","+columnNumber+"):" + uri + ":" + qName);
+ }
+
+ /**
+ * Method called when a tag closes
+ *
+ * @param uri
+ * @param localName
+ * @param qName
+ * @exception SAXException
+ */
+ public void endElement(
+ java.lang.String uri,
+ java.lang.String localName,
+ java.lang.String qName)
+ throws Exception {
+
+ trace("END ("+lineNumber+","+columnNumber+"):" + uri + ":" + qName);
+
+ Object obj = objectStack.pop();
+
+ if (currentText != null && currentText.length() != 0) {
+ if (obj instanceof Map) {
+ ((Map) obj).put(qName, currentText.toString().trim());
+ } else if (obj instanceof List) {
+ throw new Exception(lineNumber+","+columnNumber+":"+
+ "List element " + qName + " cannot have PCDATAs");
+ } else if (obj instanceof String) {
+ String str=(String)obj;
+ if(str.length()!=0){
+ throw new Exception(lineNumber+","+columnNumber+":"+
+ "String element " + qName + " cannot have both PCDATA and an attribute value");
+ } else {
+ obj=currentText.toString().trim();
+ }
+ } else {
+ Method method = null;
+ try {
+ method =
+ obj.getClass().getMethod(
+ "addText",
+ new Class[] { String.class });
+ } catch (NoSuchMethodException e) {
+ // do nothing
+ }
+ if (method != null) {
+ method.invoke(obj, new String[] { currentText.toString().trim()});
+ }
+ }
+ }
+
+ currentText = null;
+
+ if (!objectStack.isEmpty()) {
+
+ Object parent = objectStack.peek();
+ String parentName = (String) qnameStack.peek();
+
+ if (parent instanceof Map) {
+ ((Map) parent).put(qName, obj);
+ } else if (parent instanceof List) {
+ ((List) parent).add(obj);
+ } else {
+ Method method = null;
+ try {
+ method =
+ parent.getClass().getMethod(
+ adderOf(ClassUtility.capitalize(qName)),
+ new Class[] { obj.getClass()});
+ } catch (NoSuchMethodException e) {
+ trace(
+ "NoSuchMethodException: "
+ + adderOf(ClassUtility.capitalize(qName)));
+ // do nothing
+ }
+ if (method == null)
+ try {
+ method =
+ parent.getClass().getMethod(
+ setterOf(ClassUtility.capitalize(qName)),
+ new Class[] { obj.getClass()});
+ } catch (NoSuchMethodException e) {
+ trace(
+ "NoSuchMethodException: "
+ + setterOf(ClassUtility.capitalize(qName)));
+ // do nothing
+ }
+ if (method == null)
+ try {
+ method =
+ parent.getClass().getMethod(
+ adderOf(obj.getClass()),
+ new Class[] { obj.getClass()});
+ } catch (NoSuchMethodException e) {
+ trace(
+ "NoSuchMethodException: "
+ + adderOf(obj.getClass()));
+ // do nothing
+ }
+ if (method == null)
+ try {
+ method =
+ parent.getClass().getMethod(
+ setterOf(obj.getClass()),
+ new Class[] { obj.getClass()});
+ } catch (NoSuchMethodException e) {
+ trace(
+ "NoSuchMethodException: "
+ + setterOf(obj.getClass()));
+ // do nothing
+ }
+
+ if (method != null) {
+ trace(method.getName());
+ method.invoke(parent, new Object[] { obj });
+ } else {
+ throw new Exception(lineNumber+","+columnNumber+":"+
+ " element " + parentName + " cannot have an attribute " + qName + " of type " + obj.getClass());
+ }
+ }
+
+ }
+
+ trace("END/ ("+lineNumber+","+columnNumber+"):" + uri + ":" + qName);
+
+ }
+
+ private void trace(String msg) {
+ if (false)
+ System.err.println(msg);
+ }
+
+ /**
+ * @see kxml.sax.KXmlSAXHandler#setLineNumber(int)
+ */
+ public void setLineNumber(int lineNumber) {
+ this.lineNumber=lineNumber;
+ }
+
+ /**
+ * @see kxml.sax.KXmlSAXHandler#setColumnNumber(int)
+ */
+ public void setColumnNumber(int columnNumber) {
+ this.columnNumber=columnNumber;
+
+ }
+
+ /**
+ * @see kxml.sax.KXmlSAXHandler#processingInstruction(java.lang.String, java.lang.String)
+ */
+ public void processingInstruction(String target, String data) throws Exception {
+ trace("pi:"+target+";"+data);
+ if(target==null){ // TODO kXML
+ if(!data.startsWith(PI_MAPPING)) return;
+ } else if(!target.equals(PI_MAPPING))return;
+
+
+ // defaultclass attribute
+ String datt="defaultclass=\"";
+ int dstart=data.indexOf(datt);
+ if(dstart!=-1) {
+ int dend=data.indexOf("\"",dstart+datt.length());
+ if(dend==-1)
+ throw new Exception(lineNumber+","+columnNumber+":"+
+ " \"defaultclass\" attribute in \"mapping\" PI is not quoted");
+
+ String classname=data.substring(dstart+datt.length(),dend);
+ Class clazz=null;
+ try {
+ clazz=getClass().getClassLoader().loadClass(classname);
+ } catch (ClassNotFoundException e) {
+ throw new Exception(lineNumber+","+columnNumber+":"+
+ " cannot found class "+ classname+" for \"mapping\" PI");
+ }
+ setDefaultType(clazz);
+ return;
+ }
+
+ // element attribute
+ String eatt="element=\"";
+ int estart=data.indexOf(eatt);
+ if(estart==-1)
+ throw new Exception(lineNumber+","+columnNumber+":"+
+ " missing \"element\" attribute in \"mapping\" PI");
+ int eend=data.indexOf("\"",estart+eatt.length());
+ if(eend==-1)
+ throw new Exception(lineNumber+","+columnNumber+":"+
+ " \"element\" attribute in \"mapping\" PI is not quoted");
+
+ String element=data.substring(estart+eatt.length(),eend);
+
+ // element class
+ String catt="class=\"";
+ int cstart=data.indexOf(catt);
+ if(cstart==-1)
+ throw new Exception(lineNumber+","+columnNumber+":"+
+ " missing \"class\" attribute in \"mapping\" PI");
+ int cend=data.indexOf("\"",cstart+catt.length());
+ if(cend==-1)
+ throw new Exception(lineNumber+","+columnNumber+":"+
+ " \"class\" attribute in \"mapping\" PI is not quoted");
+
+ String classname=data.substring(cstart+catt.length(),cend);
+
+ Class clazz=null;
+ try {
+ clazz=getClass().getClassLoader().loadClass(classname);
+ } catch (ClassNotFoundException e) {
+ throw new Exception(lineNumber+","+columnNumber+":"+
+ " cannot found class "+ classname+" for \"mapping\" PI");
+ }
+ addType(element,clazz);
+ }
+}
Added: incubator/oscar/trunk/src/org/apache/osgi/bundle/shell/Activator.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/bundle/shell/Activator.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/bundle/shell/Activator.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/bundle/shell/Activator.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,351 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.osgi.bundle.shell;
+
+import java.io.PrintStream;
+import java.security.*;
+import java.util.*;
+
+import org.apache.osgi.service.shell.Command;
+import org.osgi.framework.*;
+
+public class Activator implements BundleActivator
+{
+ private transient BundleContext m_context = null;
+ private transient ShellServiceImpl m_shell = null;
+
+ public void start(BundleContext context)
+ {
+ m_context = context;
+
+ // Register shell service implementation.
+ String[] classes = {
+ org.apache.osgi.service.shell.ShellService.class.getName(),
+ org.ungoverned.osgi.service.shell.ShellService.class.getName()
+ };
+ context.registerService(classes, m_shell = new ShellServiceImpl(), null);
+
+ // Listen for registering/unregistering of shell command
+ // services so that we can automatically add/remove them
+ // from our list of available commands.
+ ServiceListener sl = new ServiceListener() {
+ public void serviceChanged(ServiceEvent event)
+ {
+ if (event.getType() == ServiceEvent.REGISTERED)
+ {
+ m_shell.addCommand(event.getServiceReference());
+ }
+ else if (event.getType() == ServiceEvent.UNREGISTERING)
+ {
+ m_shell.removeCommand(event.getServiceReference());
+ }
+ else
+ {
+ }
+ }
+ };
+
+ try
+ {
+ m_context.addServiceListener(sl,
+ "(|(objectClass="
+ + org.apache.osgi.service.shell.Command.class.getName()
+ + ")(objectClass="
+ + org.ungoverned.osgi.service.shell.Command.class.getName()
+ + "))");
+ }
+ catch (InvalidSyntaxException ex)
+ {
+ System.err.println("Activator: Cannot register service listener.");
+ System.err.println("Activator: " + ex);
+ }
+
+ // Now manually try to find any commands that have already
+ // been registered (i.e., we didn't see their service events).
+ initializeCommands();
+
+ // Register "exports" command service.
+ context.registerService(
+ org.apache.osgi.service.shell.Command.class.getName(),
+ new BundleLevelCommandImpl(m_context), null);
+
+ // Register "cd" command service.
+ classes = new String[2];
+ classes[0] = org.apache.osgi.service.shell.Command.class.getName();
+ classes[1] = org.apache.osgi.service.shell.CdCommand.class.getName();
+ context.registerService(
+ classes, new CdCommandImpl(m_context), null);
+
+ // Register "exports" command service.
+ context.registerService(
+ org.apache.osgi.service.shell.Command.class.getName(),
+ new PackagesCommandImpl(m_context), null);
+
+ // Register "headers" command service.
+ context.registerService(
+ org.apache.osgi.service.shell.Command.class.getName(),
+ new HeadersCommandImpl(m_context), null);
+
+ // Register "help" command service.
+ context.registerService(
+ org.apache.osgi.service.shell.Command.class.getName(),
+ new HelpCommandImpl(m_context), null);
+
+ // Register "install" command service.
+ context.registerService(
+ org.apache.osgi.service.shell.Command.class.getName(),
+ new InstallCommandImpl(m_context), null);
+
+ // Register "ps" command service.
+ context.registerService(
+ org.apache.osgi.service.shell.Command.class.getName(),
+ new PsCommandImpl(m_context), null);
+
+ // Register "refresh" command service.
+ context.registerService(
+ org.apache.osgi.service.shell.Command.class.getName(),
+ new RefreshCommandImpl(m_context), null);
+
+ // Register "services" command service.
+ context.registerService(
+ org.apache.osgi.service.shell.Command.class.getName(),
+ new ServicesCommandImpl(m_context), null);
+
+ // Register "startlevel" command service.
+ context.registerService(
+ org.apache.osgi.service.shell.Command.class.getName(),
+ new StartLevelCommandImpl(m_context), null);
+
+ // Register "shutdown" command service.
+ context.registerService(
+ org.apache.osgi.service.shell.Command.class.getName(),
+ new ShutdownCommandImpl(m_context), null);
+
+ // Register "start" command service.
+ context.registerService(
+ org.apache.osgi.service.shell.Command.class.getName(),
+ new StartCommandImpl(m_context), null);
+
+ // Register "stop" command service.
+ context.registerService(
+ org.apache.osgi.service.shell.Command.class.getName(),
+ new StopCommandImpl(m_context), null);
+
+ // Register "uninstall" command service.
+ context.registerService(
+ org.apache.osgi.service.shell.Command.class.getName(),
+ new UninstallCommandImpl(m_context), null);
+
+ // Register "update" command service.
+ context.registerService(
+ org.apache.osgi.service.shell.Command.class.getName(),
+ new UpdateCommandImpl(m_context), null);
+
+ // Register "version" command service.
+ context.registerService(
+ org.apache.osgi.service.shell.Command.class.getName(),
+ new VersionCommandImpl(m_context), null);
+ }
+
+ public void stop(BundleContext context)
+ {
+ m_shell.clearCommands();
+ }
+
+ private void initializeCommands()
+ {
+ synchronized (m_shell)
+ {
+ try
+ {
+ ServiceReference[] refs = m_context.getServiceReferences(
+ org.apache.osgi.service.shell.Command.class.getName(), null);
+ if (refs != null)
+ {
+ for (int i = 0; i < refs.length; i++)
+ {
+ m_shell.addCommand(refs[i]);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ System.err.println("Activator: " + ex);
+ }
+ }
+ }
+
+ private class ShellServiceImpl implements
+ org.apache.osgi.service.shell.ShellService,
+ org.ungoverned.osgi.service.shell.ShellService
+ {
+ private HashMap m_commandRefMap = new HashMap();
+ private TreeMap m_commandNameMap = new TreeMap();
+
+ public synchronized String[] getCommands()
+ {
+ Set ks = m_commandNameMap.keySet();
+ String[] cmds = (ks == null)
+ ? new String[0] : (String[]) ks.toArray(new String[ks.size()]);
+ return cmds;
+ }
+
+ public synchronized String getCommandUsage(String name)
+ {
+ Command command = (Command) m_commandNameMap.get(name);
+ return (command == null) ? null : command.getUsage();
+ }
+
+ public synchronized String getCommandDescription(String name)
+ {
+ Command command = (Command) m_commandNameMap.get(name);
+ return (command == null) ? null : command.getShortDescription();
+ }
+
+ public synchronized ServiceReference getCommandReference(String name)
+ {
+ return (ServiceReference) m_commandNameMap.get(name);
+ }
+
+ public synchronized void removeCommand(ServiceReference ref)
+ {
+ Command command = (Command) m_commandRefMap.remove(ref);
+ if (command != null)
+ {
+ m_commandNameMap.remove(command.getName());
+ }
+ }
+
+ public synchronized void executeCommand(
+ String commandLine, PrintStream out, PrintStream err) throws Exception
+ {
+ commandLine = commandLine.trim();
+ String commandName = (commandLine.indexOf(' ') >= 0)
+ ? commandLine.substring(0, commandLine.indexOf(' ')) : commandLine;
+ Command command = getCommand(commandName);
+ if (command != null)
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ AccessController.doPrivileged(
+ new ExecutePrivileged(command, commandLine, out, err));
+ }
+ catch (PrivilegedActionException ex)
+ {
+ throw ex.getException();
+ }
+ }
+ else
+ {
+ try
+ {
+ command.execute(commandLine, out, err);
+ }
+ catch (Throwable ex)
+ {
+ err.println("Unable to execute command: " + ex);
+ ex.printStackTrace(err);
+ }
+ }
+ }
+ else
+ {
+ err.println("Command not found.");
+ }
+ }
+
+ protected synchronized Command getCommand(String name)
+ {
+ Command command = (Command) m_commandNameMap.get(name);
+ return (command == null) ? null : command;
+ }
+
+ protected synchronized void addCommand(ServiceReference ref)
+ {
+ Object cmdObj = m_context.getService(ref);
+ Command command =
+ (cmdObj instanceof org.ungoverned.osgi.service.shell.Command)
+ ? new OldCommandWrapper((org.ungoverned.osgi.service.shell.Command) cmdObj)
+ : (Command) cmdObj;
+ m_commandRefMap.put(ref, command);
+ m_commandNameMap.put(command.getName(), command);
+ }
+
+ protected synchronized void clearCommands()
+ {
+ m_commandRefMap.clear();
+ m_commandNameMap.clear();
+ }
+ }
+
+ private static class OldCommandWrapper implements Command
+ {
+ private org.ungoverned.osgi.service.shell.Command m_oldCommand = null;
+
+ public OldCommandWrapper(org.ungoverned.osgi.service.shell.Command oldCommand)
+ {
+ m_oldCommand = oldCommand;
+ }
+
+ public String getName()
+ {
+ return m_oldCommand.getName();
+ }
+
+ public String getUsage()
+ {
+ return m_oldCommand.getUsage();
+ }
+
+ public String getShortDescription()
+ {
+ return m_oldCommand.getShortDescription();
+ }
+
+ public void execute(String line, PrintStream out, PrintStream err)
+ {
+ m_oldCommand.execute(line, out, err);
+ }
+ }
+
+ public static class ExecutePrivileged implements PrivilegedExceptionAction
+ {
+ private Command m_command = null;
+ private String m_commandLine = null;
+ private PrintStream m_out = null;
+ private PrintStream m_err = null;
+
+ public ExecutePrivileged(
+ Command command, String commandLine,
+ PrintStream out, PrintStream err)
+ throws Exception
+ {
+ m_command = command;
+ m_commandLine = commandLine;
+ m_out = out;
+ m_err = err;
+ }
+
+ public Object run() throws Exception
+ {
+ m_command.execute(m_commandLine, m_out, m_err);
+ return null;
+ }
+ }
+}
\ No newline at end of file
Added: incubator/oscar/trunk/src/org/apache/osgi/bundle/shell/BundleLevelCommandImpl.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/bundle/shell/BundleLevelCommandImpl.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/bundle/shell/BundleLevelCommandImpl.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/bundle/shell/BundleLevelCommandImpl.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.osgi.bundle.shell;
+
+import java.io.PrintStream;
+import java.util.StringTokenizer;
+
+import org.apache.osgi.service.shell.Command;
+import org.osgi.framework.*;
+import org.osgi.service.startlevel.StartLevel;
+
+public class BundleLevelCommandImpl implements Command
+{
+ private BundleContext m_context = null;
+
+ public BundleLevelCommandImpl(BundleContext context)
+ {
+ m_context = context;
+ }
+
+ public String getName()
+ {
+ return "bundlelevel";
+ }
+
+ public String getUsage()
+ {
+ return "bundlelevel <level> <id> ... | <id>";
+ }
+
+ public String getShortDescription()
+ {
+ return "set or get bundle start level.";
+ }
+
+ public void execute(String s, PrintStream out, PrintStream err)
+ {
+ // Get start level service.
+ ServiceReference ref = m_context.getServiceReference(
+ org.osgi.service.startlevel.StartLevel.class.getName());
+ if (ref == null)
+ {
+ out.println("StartLevel service is unavailable.");
+ return;
+ }
+
+ StartLevel sl = (StartLevel) m_context.getService(ref);
+ if (sl == null)
+ {
+ out.println("StartLevel service is unavailable.");
+ return;
+ }
+
+ // Parse command line.
+ StringTokenizer st = new StringTokenizer(s, " ");
+
+ // Ignore the command name.
+ st.nextToken();
+
+ // If there is only one token, then assume it is
+ // a bundle ID for which we must retrieve the bundle
+ // level.
+ if (st.countTokens() == 1)
+ {
+ // Get the bundle and display start level.
+ Bundle bundle = null;
+ String token = null;
+ try
+ {
+ token = st.nextToken();
+ long id = Long.parseLong(token);
+ bundle = m_context.getBundle(id);
+ if (bundle != null)
+ {
+ out.println("Bundle " + token + " is level "
+ + sl.getBundleStartLevel(bundle));
+ }
+ else
+ {
+ err.println("Bundle ID " + token + " is invalid.");
+ }
+ }
+ catch (NumberFormatException ex)
+ {
+ err.println("Unable to parse integer '" + token + "'.");
+ }
+ catch (Exception ex)
+ {
+ err.println(ex.toString());
+ }
+ }
+ // If there is more than one token, assume the first
+ // token is the new start level and the remaining
+ // tokens are the bundle IDs whose start levels should
+ // be changed.
+ else if (st.countTokens() > 1)
+ {
+ // Get the bundle.
+ Bundle bundle = null;
+ String token = null;
+ int startLevel = -1;
+
+ try
+ {
+ token = st.nextToken();
+ startLevel = Integer.parseInt(token);
+ }
+ catch (NumberFormatException ex)
+ {
+ err.println("Unable to parse start level '" + token + "'.");
+ }
+
+ // Ignore invalid start levels.
+ if (startLevel > 0)
+ {
+ // Set the start level for each specified bundle.
+ while (st.hasMoreTokens())
+ {
+ try
+ {
+ token = st.nextToken();
+ long id = Long.parseLong(token);
+ bundle = m_context.getBundle(id);
+ if (bundle != null)
+ {
+ sl.setBundleStartLevel(bundle, startLevel);
+ }
+ else
+ {
+ err.println("Bundle ID '" + token + "' is invalid.");
+ }
+ }
+ catch (NumberFormatException ex)
+ {
+ err.println("Unable to parse bundle ID '" + token + "'.");
+ }
+ catch (Exception ex)
+ {
+ err.println(ex.toString());
+ }
+ }
+ }
+ else
+ {
+ err.println("Invalid start level.");
+ }
+ }
+ else
+ {
+ err.println("Incorrect number of arguments.");
+ }
+ }
+}
\ No newline at end of file
Added: incubator/oscar/trunk/src/org/apache/osgi/bundle/shell/CdCommandImpl.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/bundle/shell/CdCommandImpl.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/bundle/shell/CdCommandImpl.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/bundle/shell/CdCommandImpl.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.osgi.bundle.shell;
+
+import java.io.PrintStream;
+import java.util.StringTokenizer;
+
+import org.apache.osgi.service.shell.CdCommand;
+import org.osgi.framework.BundleContext;
+
+public class CdCommandImpl implements CdCommand
+{
+ private BundleContext m_context = null;
+ private String m_baseURL = "";
+
+ public CdCommandImpl(BundleContext context)
+ {
+ m_context = context;
+
+ // See if the initial base URL is specified.
+ String baseURL = m_context.getProperty(BASE_URL_PROPERTY);
+ setBaseURL(baseURL);
+ }
+
+ public String getName()
+ {
+ return "cd";
+ }
+
+ public String getUsage()
+ {
+ return "cd [<base-URL>]";
+ }
+
+ public String getShortDescription()
+ {
+ return "change or display base URL.";
+ }
+
+ public void execute(String s, PrintStream out, PrintStream err)
+ {
+ StringTokenizer st = new StringTokenizer(s, " ");
+
+ // Ignore the command name.
+ st.nextToken();
+
+ // No more tokens means to display the base URL,
+ // otherwise set the base URL.
+ if (st.countTokens() == 0)
+ {
+ out.println(m_baseURL);
+ }
+ else if (st.countTokens() == 1)
+ {
+ setBaseURL(st.nextToken());
+ }
+ else
+ {
+ err.println("Incorrect number of arguments");
+ }
+ }
+
+ public String getBaseURL()
+ {
+ return m_baseURL;
+ }
+
+ public void setBaseURL(String s)
+ {
+ m_baseURL = (s == null) ? "" : s;
+ }
+}
\ No newline at end of file
Added: incubator/oscar/trunk/src/org/apache/osgi/bundle/shell/HeadersCommandImpl.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/bundle/shell/HeadersCommandImpl.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/bundle/shell/HeadersCommandImpl.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/bundle/shell/HeadersCommandImpl.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.osgi.bundle.shell;
+
+import java.io.PrintStream;
+import java.util.*;
+
+import org.apache.osgi.service.shell.Command;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+public class HeadersCommandImpl implements Command
+{
+ private BundleContext m_context = null;
+
+ public HeadersCommandImpl(BundleContext context)
+ {
+ m_context = context;
+ }
+
+ public String getName()
+ {
+ return "headers";
+ }
+
+ public String getUsage()
+ {
+ return "headers [<id> ...]";
+ }
+
+ public String getShortDescription()
+ {
+ return "display bundle header properties.";
+ }
+
+ public void execute(String s, PrintStream out, PrintStream err)
+ {
+ StringTokenizer st = new StringTokenizer(s, " ");
+
+ // Ignore the command name.
+ st.nextToken();
+
+ // Print the specified bundles or all if none are specified.
+ if (st.hasMoreTokens())
+ {
+ while (st.hasMoreTokens())
+ {
+ String id = st.nextToken().trim();
+
+ try
+ {
+ long l = Long.parseLong(id);
+ Bundle bundle = m_context.getBundle(l);
+ if (bundle != null)
+ {
+ printHeaders(out, bundle);
+ }
+ else
+ {
+ err.println("Bundle ID " + id + " is invalid.");
+ }
+ }
+ catch (NumberFormatException ex)
+ {
+ err.println("Unable to parse id '" + id + "'.");
+ }
+ catch (Exception ex)
+ {
+ err.println(ex.toString());
+ }
+ }
+ }
+ else
+ {
+ Bundle[] bundles = m_context.getBundles();
+ for (int i = 0; i < bundles.length; i++)
+ {
+ printHeaders(out, bundles[i]);
+ }
+ }
+ }
+
+ private void printHeaders(PrintStream out, Bundle bundle)
+ {
+ String title = Util.getBundleName(bundle);
+ out.println("\n" + title);
+ out.println(Util.getUnderlineString(title));
+ Dictionary dict = bundle.getHeaders();
+ Enumeration keys = dict.keys();
+ while (keys.hasMoreElements())
+ {
+ Object k = (String) keys.nextElement();
+ Object v = dict.get(k);
+ out.println(k + " = " + Util.getValueString(v));
+ }
+ }
+}
\ No newline at end of file
Added: incubator/oscar/trunk/src/org/apache/osgi/bundle/shell/HelpCommandImpl.java
URL: http://svn.apache.org/viewcvs/incubator/oscar/trunk/src/org/apache/osgi/bundle/shell/HelpCommandImpl.java?rev=233031&view=auto
==============================================================================
--- incubator/oscar/trunk/src/org/apache/osgi/bundle/shell/HelpCommandImpl.java (added)
+++ incubator/oscar/trunk/src/org/apache/osgi/bundle/shell/HelpCommandImpl.java Tue Aug 16 11:33:34 2005
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.osgi.bundle.shell;
+
+import java.io.PrintStream;
+
+import org.apache.osgi.service.shell.Command;
+import org.apache.osgi.service.shell.ShellService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+public class HelpCommandImpl implements Command
+{
+ private BundleContext m_context = null;
+
+ public HelpCommandImpl(BundleContext context)
+ {
+ m_context = context;
+ }
+
+ public String getName()
+ {
+ return "help";
+ }
+
+ public String getUsage()
+ {
+ return "help";
+ }
+
+ public String getShortDescription()
+ {
+ return "display shell commands.";
+ }
+
+ public void execute(String s, PrintStream out, PrintStream err)
+ {
+ try {
+ // Get a reference to the shell service.
+ ServiceReference ref = m_context.getServiceReference(
+ org.apache.osgi.service.shell.ShellService.class.getName());
+
+ if (ref != null)
+ {
+ ShellService ss = (ShellService) m_context.getService(ref);
+ String[] cmds = ss.getCommands();
+ String[] usage = new String[cmds.length];
+ String[] desc = new String[cmds.length];
+ int maxUsage = 0;
+ for (int i = 0; i < cmds.length; i++)
+ {
+ usage[i] = ss.getCommandUsage(cmds[i]);
+ desc[i] = ss.getCommandDescription(cmds[i]);
+ // Just in case the command has gone away.
+ if ((usage[i] != null) && (desc[i] != null))
+ {
+ maxUsage = Math.max(maxUsage, usage[i].length());
+ }
+ }
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < cmds.length; i++)
+ {
+ // Just in case the command has gone away.
+ if ((usage[i] != null) && (desc[i] != null))
+ {
+ sb.delete(0, sb.length());
+ for (int j = 0; j < (maxUsage - usage[i].length()); j++)
+ {
+ sb.append(' ');
+ }
+ out.println(usage[i] + sb + " - " + desc[i]);
+ }
+ }
+ }
+ else
+ {
+ err.println("No ShellService is unavailable.");
+ }
+ } catch (Exception ex) {
+ err.println(ex.toString());
+ }
+ }
+}