felix-gogo-command-0.14.0/0000755000175000017500000000000012465440117013374 5ustar apoapofelix-gogo-command-0.14.0/doc/0000755000175000017500000000000012465440117014141 5ustar apoapofelix-gogo-command-0.14.0/doc/changelog.txt0000644000175000017500000000500712350001701016614 0ustar apoapoChanges from 0.10.0 to 0.12.0 ----------------------------- * Fix a NPE with the obr:info command Changes from 0.10.0 to 0.12.0 ----------------------------- ** Improvement * [FELIX-3050] - [Gogo Command] Update "inspect" command to work with OSGi R4.3 generic capabilities/requirements * [FELIX-3088] - [Gogo Command] The "resolve" command should print some message if not all bundles could be resolved * [FELIX-3118] - obr:deploy should allow user to specify whether optional bundles are deployed or not Changes from 0.8.0 to 0.10.0 ---------------------------- ** Bug * [FELIX-2937] - [Gogo Command] OBR commands do not output anything when nothing is found * [FELIX-2938] - [Gogo Command] The "info" command throws an NPE if the specified bundle identifier doesn't exist * [FELIX-3001] - [gogo] help command throws ClassCastException if any osgi.command.function service property is not String[] Changes from 0.6.1 to 0.8.0 --------------------------- ** Bug * [FELIX-2676] - bundlelevel gogo command will never work for modifying bundle level Changes from 0.6.0 to 0.6.1 --------------------------- * Import Gogo packages with mandatory attribute. Gogo Command 0.6.0 ------------------ ** Bug * [FELIX-1473] - [gogo] The syntax does not provide a way to call methods on a string * [FELIX-1474] - [gogo] result of commands is implicitly written to pipe * [FELIX-1493] - [gogo] automatic expansion of $args in Closure stops direct access to $args list * [FELIX-2337] - [gogo] no way to access array[] elements produced by assignment * [FELIX-2375] - [gogo] when supplied args can't be coerced, the error message prints the arg values, rather than their types * [FELIX-2380] - [gogo] lock contention in piped writer when reader doesn't read all input ** Improvement * [FELIX-1487] - Support for commands on multiple lines * [FELIX-2328] - [gogo] tidy-up runtime to remove optional code etc * [FELIX-2339] - [gogo] add support for running scripts * [FELIX-2342] - [gogo] remove old felix command adaptor ** New Feature * [FELIX-2363] - [Gogo] Add annotations for creating commands with optional and out-of-order arguments ** Task * [FELIX-1670] - [gogo] launcher bundle not required * [FELIX-1889] - Gogo should depend on the official OSGi jars * [FELIX-2334] - [Gogo] Use org.apache.felix as Maven groupId * [FELIX-2367] - [Gogo] Use org.apache.felix namespace to avoid any perceived legal issues felix-gogo-command-0.14.0/src/0000755000175000017500000000000012465440116014162 5ustar apoapofelix-gogo-command-0.14.0/src/main/0000755000175000017500000000000012465440116015106 5ustar apoapofelix-gogo-command-0.14.0/src/main/java/0000755000175000017500000000000012465440116016027 5ustar apoapofelix-gogo-command-0.14.0/src/main/java/org/0000755000175000017500000000000012465440116016616 5ustar apoapofelix-gogo-command-0.14.0/src/main/java/org/apache/0000755000175000017500000000000012465440116020037 5ustar apoapofelix-gogo-command-0.14.0/src/main/java/org/apache/felix/0000755000175000017500000000000012465440116021146 5ustar apoapofelix-gogo-command-0.14.0/src/main/java/org/apache/felix/gogo/0000755000175000017500000000000012465440116022101 5ustar apoapofelix-gogo-command-0.14.0/src/main/java/org/apache/felix/gogo/command/0000755000175000017500000000000012465440117023520 5ustar apoapofelix-gogo-command-0.14.0/src/main/java/org/apache/felix/gogo/command/Inspect.java0000644000175000017500000003677311636141231026002 0ustar apoapo/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.command; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.felix.service.command.Descriptor; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.ServiceReference; import org.osgi.framework.wiring.BundleCapability; import org.osgi.framework.wiring.BundleRequirement; import org.osgi.framework.wiring.BundleWire; import org.osgi.framework.wiring.BundleWiring; import org.osgi.service.packageadmin.ExportedPackage; import org.osgi.service.packageadmin.PackageAdmin; import org.osgi.service.packageadmin.RequiredBundle; public class Inspect { public static final String NONSTANDARD_SERVICE_NAMESPACE = "service"; public static final String CAPABILITY = "capability"; public static final String REQUIREMENT = "requirement"; private static final String EMPTY_MESSAGE = "[EMPTY]"; private static final String UNUSED_MESSAGE = "[UNUSED]"; private static final String UNRESOLVED_MESSAGE = "[UNRESOLVED]"; private final BundleContext m_bc; public Inspect(BundleContext bc) { m_bc = bc; } @Descriptor("inspects bundle capabilities and requirements") public void inspect( @Descriptor("('capability' | 'requirement')") String direction, @Descriptor("( | 'service')") String namespace, @Descriptor("target bundles") Bundle[] bundles) { inspect(m_bc, direction, namespace, bundles); } private static void inspect( BundleContext bc, String direction, String namespace, Bundle[] bundles) { // Verify arguments. if (isValidDirection(direction)) { bundles = ((bundles == null) || (bundles.length == 0)) ? bc.getBundles() : bundles; if (CAPABILITY.startsWith(direction)) { printCapabilities(bc, Util.parseSubstring(namespace), bundles); } else { printRequirements(bc, Util.parseSubstring(namespace), bundles); } } else { if (!isValidDirection(direction)) { System.out.println("Invalid argument: " + direction); } } } public static void printCapabilities( BundleContext bc, List namespace, Bundle[] bundles) { boolean separatorNeeded = false; for (Bundle b : bundles) { if (separatorNeeded) { System.out.println(""); } // Print out any matching generic capabilities. BundleWiring wiring = b.adapt(BundleWiring.class); if (wiring != null) { String title = b + " provides:"; System.out.println(title); System.out.println(Util.getUnderlineString(title.length())); // Print generic capabilities for matching namespaces. boolean matches = printMatchingCapabilities(wiring, namespace); // Handle service capabilities separately, since they aren't part // of the generic model in OSGi. if (matchNamespace(namespace, NONSTANDARD_SERVICE_NAMESPACE)) { matches |= printServiceCapabilities(b); } // If there were no capabilities for the specified namespace, // then say so. if (!matches) { System.out.println(Util.unparseSubstring(namespace) + " " + EMPTY_MESSAGE); } } else { System.out.println("Bundle " + b.getBundleId() + " is not resolved."); } separatorNeeded = true; } } private static boolean printMatchingCapabilities(BundleWiring wiring, List namespace) { List wires = wiring.getProvidedWires(null); Map> aggregateCaps = aggregateCapabilities(namespace, wires); List allCaps = wiring.getCapabilities(null); boolean matches = false; for (BundleCapability cap : allCaps) { if (matchNamespace(namespace, cap.getNamespace())) { matches = true; List dependents = aggregateCaps.get(cap); Object keyAttr = cap.getAttributes().get(cap.getNamespace()); if (dependents != null) { String msg; if (keyAttr != null) { msg = cap.getNamespace() + "; " + keyAttr + " " + getVersionFromCapability(cap); } else { msg = cap.toString(); } msg = msg + " required by:"; System.out.println(msg); for (BundleWire wire : dependents) { System.out.println(" " + wire.getRequirerWiring().getBundle()); } } else if (keyAttr != null) { System.out.println(cap.getNamespace() + "; " + cap.getAttributes().get(cap.getNamespace()) + " " + getVersionFromCapability(cap) + " " + UNUSED_MESSAGE); } else { System.out.println(cap + " " + UNUSED_MESSAGE); } } } return matches; } private static Map> aggregateCapabilities( List namespace, List wires) { // Aggregate matching capabilities. Map> map = new HashMap>(); for (BundleWire wire : wires) { if (matchNamespace(namespace, wire.getCapability().getNamespace())) { List dependents = map.get(wire.getCapability()); if (dependents == null) { dependents = new ArrayList(); map.put(wire.getCapability(), dependents); } dependents.add(wire); } } return map; } static boolean printServiceCapabilities(Bundle b) { boolean matches = false; try { ServiceReference[] refs = b.getRegisteredServices(); if ((refs != null) && (refs.length > 0)) { matches = true; // Print properties for each service. for (ServiceReference ref : refs) { // Print object class with "namespace". System.out.println( NONSTANDARD_SERVICE_NAMESPACE + "; " + Util.getValueString(ref.getProperty("objectClass")) + " with properties:"); // Print service properties. String[] keys = ref.getPropertyKeys(); for (String key : keys) { if (!key.equalsIgnoreCase(Constants.OBJECTCLASS)) { Object v = ref.getProperty(key); System.out.println(" " + key + " = " + Util.getValueString(v)); } } Bundle[] users = ref.getUsingBundles(); if ((users != null) && (users.length > 0)) { System.out.println(" Used by:"); for (Bundle user : users) { System.out.println(" " + user); } } } } } catch (Exception ex) { System.err.println(ex.toString()); } return matches; } public static void printRequirements( BundleContext bc, List namespace, Bundle[] bundles) { boolean separatorNeeded = false; for (Bundle b : bundles) { if (separatorNeeded) { System.out.println(""); } // Print out any matching generic requirements. BundleWiring wiring = b.adapt(BundleWiring.class); if (wiring != null) { String title = b + " requires:"; System.out.println(title); System.out.println(Util.getUnderlineString(title.length())); boolean matches = printMatchingRequirements(wiring, namespace); // Handle service requirements separately, since they aren't part // of the generic model in OSGi. if (matchNamespace(namespace, NONSTANDARD_SERVICE_NAMESPACE)) { matches |= printServiceRequirements(b); } // If there were no requirements for the specified namespace, // then say so. if (!matches) { System.out.println(Util.unparseSubstring(namespace) + " " + EMPTY_MESSAGE); } } else { System.out.println("Bundle " + b.getBundleId() + " is not resolved."); } separatorNeeded = true; } } private static boolean printMatchingRequirements(BundleWiring wiring, List namespace) { List wires = wiring.getRequiredWires(null); Map> aggregateReqs = aggregateRequirements(namespace, wires); List allReqs = wiring.getRequirements(null); boolean matches = false; for (BundleRequirement req : allReqs) { if (matchNamespace(namespace, req.getNamespace())) { matches = true; List providers = aggregateReqs.get(req); if (providers != null) { System.out.println( req.getNamespace() + "; " + req.getDirectives().get(Constants.FILTER_DIRECTIVE) + " resolved by:"); for (BundleWire wire : providers) { String msg; Object keyAttr = wire.getCapability().getAttributes() .get(wire.getCapability().getNamespace()); if (keyAttr != null) { msg = wire.getCapability().getNamespace() + "; " + keyAttr + " " + getVersionFromCapability(wire.getCapability()); } else { msg = wire.getCapability().toString(); } msg = " " + msg + " from " + wire.getProviderWiring().getBundle(); System.out.println(msg); } } else { System.out.println( req.getNamespace() + "; " + req.getDirectives().get(Constants.FILTER_DIRECTIVE) + " " + UNRESOLVED_MESSAGE); } } } return matches; } private static Map> aggregateRequirements( List namespace, List wires) { // Aggregate matching capabilities. Map> map = new HashMap>(); for (BundleWire wire : wires) { if (matchNamespace(namespace, wire.getRequirement().getNamespace())) { List providers = map.get(wire.getRequirement()); if (providers == null) { providers = new ArrayList(); map.put(wire.getRequirement(), providers); } providers.add(wire); } } return map; } static boolean printServiceRequirements(Bundle b) { boolean matches = false; try { ServiceReference[] refs = b.getServicesInUse(); if ((refs != null) && (refs.length > 0)) { matches = true; // Print properties for each service. for (ServiceReference ref : refs) { // Print object class with "namespace". System.out.println( NONSTANDARD_SERVICE_NAMESPACE + "; " + Util.getValueString(ref.getProperty("objectClass")) + " provided by:"); System.out.println(" " + ref.getBundle()); } } } catch (Exception ex) { System.err.println(ex.toString()); } return matches; } private static String getVersionFromCapability(BundleCapability c) { Object o = c.getAttributes().get(Constants.VERSION_ATTRIBUTE); if (o == null) { o = c.getAttributes().get(Constants.BUNDLE_VERSION_ATTRIBUTE); } return (o == null) ? "" : o.toString(); } private static boolean matchNamespace(List namespace, String actual) { return Util.compareSubstring(namespace, actual); } private static boolean isValidDirection(String direction) { return (CAPABILITY.startsWith(direction) || REQUIREMENT.startsWith(direction)); } private static boolean isFragment(Bundle bundle) { return bundle.getHeaders().get(Constants.FRAGMENT_HOST) != null; } }felix-gogo-command-0.14.0/src/main/java/org/apache/felix/gogo/command/Files.java0000644000175000017500000002204111445732513025425 0ustar apoapo/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.command; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.felix.service.command.CommandSession; import org.apache.felix.service.command.Descriptor; import org.osgi.framework.BundleContext; public class Files { private static final String CWD = "_cwd"; private final BundleContext m_bc; public Files(BundleContext bc) { m_bc = bc; } @Descriptor("get current directory") public File cd( @Descriptor("automatically supplied shell session") CommandSession session) { try { return cd(session, null); } catch (IOException ex) { throw new RuntimeException("Unable to get current directory"); } } @Descriptor("change current directory") public File cd( @Descriptor("automatically supplied shell session") CommandSession session, @Descriptor("target directory") String dir) throws IOException { File cwd = (File) session.get(CWD); if (cwd == null) { cwd = new File(".").getCanonicalFile(); session.put(CWD, cwd); } if ((dir == null) || (dir.length() == 0)) { return cwd; } cwd = new File(cwd, dir); if (!cwd.exists()) { throw new IOException("Directory does not exist"); } else if (!cwd.isDirectory()) { throw new IOException("Target is not a directory"); } session.put(CWD, cwd.getCanonicalFile()); return cwd; } @Descriptor("get current directory contents") public File[] ls( @Descriptor("automatically supplied shell session") CommandSession session) throws IOException { return ls(session, null); } @Descriptor("get specified path contents") public File[] ls( @Descriptor("automatically supplied shell session") CommandSession session, @Descriptor("path with optionally wildcarded file name") String pattern) throws IOException { pattern = ((pattern == null) || (pattern.length() == 0)) ? "." : pattern; pattern = ((pattern.charAt(0) != File.separatorChar) && (pattern.charAt(0) != '.')) ? "./" + pattern : pattern; int idx = pattern.lastIndexOf(File.separatorChar); String parent = (idx < 0) ? "." : pattern.substring(0, idx + 1); String target = (idx < 0) ? pattern : pattern.substring(idx + 1); File actualParent = ((parent.charAt(0) == File.separatorChar) ? new File(parent) : new File(cd(session), parent)).getCanonicalFile(); idx = target.indexOf(File.separatorChar, idx); boolean isWildcarded = (target.indexOf('*', idx) >= 0); File[] files; if (isWildcarded) { if (!actualParent.exists()) { throw new IOException("File does not exist"); } final List pieces = parseSubstring(target); files = actualParent.listFiles(new FileFilter() { public boolean accept(File pathname) { return compareSubstring(pieces, pathname.getName()); } }); } else { File actualTarget = new File(actualParent, target).getCanonicalFile(); if (!actualTarget.exists()) { throw new IOException("File does not exist"); } if (actualTarget.isDirectory()) { files = actualTarget.listFiles(); } else { files = new File[] { actualTarget }; } } return files; } public static List parseSubstring(String value) { List pieces = new ArrayList(); StringBuffer ss = new StringBuffer(); // int kind = SIMPLE; // assume until proven otherwise boolean wasStar = false; // indicates last piece was a star boolean leftstar = false; // track if the initial piece is a star boolean rightstar = false; // track if the final piece is a star int idx = 0; // We assume (sub)strings can contain leading and trailing blanks boolean escaped = false; loop: for (;;) { if (idx >= value.length()) { if (wasStar) { // insert last piece as "" to handle trailing star rightstar = true; } else { pieces.add(ss.toString()); // accumulate the last piece // note that in the case of // (cn=); this might be // the string "" (!=null) } ss.setLength(0); break loop; } // Read the next character and account for escapes. char c = value.charAt(idx++); if (!escaped && ((c == '(') || (c == ')'))) { throw new IllegalArgumentException( "Illegal value: " + value); } else if (!escaped && (c == '*')) { if (wasStar) { // encountered two successive stars; // I assume this is illegal throw new IllegalArgumentException("Invalid filter string: " + value); } if (ss.length() > 0) { pieces.add(ss.toString()); // accumulate the pieces // between '*' occurrences } ss.setLength(0); // if this is a leading star, then track it if (pieces.size() == 0) { leftstar = true; } wasStar = true; } else if (!escaped && (c == '\\')) { escaped = true; } else { escaped = false; wasStar = false; ss.append(c); } } if (leftstar || rightstar || pieces.size() > 1) { // insert leading and/or trailing "" to anchor ends if (rightstar) { pieces.add(""); } if (leftstar) { pieces.add(0, ""); } } return pieces; } public static boolean compareSubstring(List pieces, String s) { // Walk the pieces to match the string // There are implicit stars between each piece, // and the first and last pieces might be "" to anchor the match. // assert (pieces.length > 1) // minimal case is * boolean result = true; int len = pieces.size(); int index = 0; loop: for (int i = 0; i < len; i++) { String piece = pieces.get(i); // If this is the first piece, then make sure the // string starts with it. if (i == 0) { if (!s.startsWith(piece)) { result = false; break loop; } } // If this is the last piece, then make sure the // string ends with it. if (i == len - 1) { if (s.endsWith(piece)) { result = true; } else { result = false; } break loop; } // If this is neither the first or last piece, then // make sure the string contains it. if ((i > 0) && (i < (len - 1))) { index = s.indexOf(piece, index); if (index < 0) { result = false; break loop; } } // Move string index beyond the matching piece. index += piece.length(); } return result; } }felix-gogo-command-0.14.0/src/main/java/org/apache/felix/gogo/command/Base64Encoder.java0000644000175000017500000000757711376551562026736 0ustar apoapo/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.command; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class Base64Encoder { 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 }; 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); } } }felix-gogo-command-0.14.0/src/main/java/org/apache/felix/gogo/command/Basic.java0000644000175000017500000010416611625720221025406 0ustar apoapo/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.command; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.Dictionary; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; import org.apache.felix.service.command.Descriptor; import org.apache.felix.service.command.Parameter; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; import org.osgi.framework.BundleReference; import org.osgi.framework.Constants; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.osgi.service.log.LogEntry; import org.osgi.service.log.LogReaderService; import org.osgi.service.log.LogService; import org.osgi.service.packageadmin.PackageAdmin; import org.osgi.service.startlevel.StartLevel; public class Basic { private final BundleContext m_bc; public Basic(BundleContext bc) { m_bc = bc; } @Descriptor("query bundle start level") public void bundlelevel(@Descriptor("bundle to query") Bundle bundle) { // Keep track of service references. List refs = new ArrayList(); // Get start level service. StartLevel sl = Util.getService(m_bc, StartLevel.class, refs); if (sl == null) { System.out.println("Start Level service is unavailable."); } // Get the bundle start level. else { if (bundle != null) { System.out.println(bundle + " is level " + sl.getBundleStartLevel(bundle)); } } Util.ungetServices(m_bc, refs); } @Descriptor("set bundle start level or initial bundle start level") public void bundlelevel( @Descriptor("set the bundle's start level") @Parameter(names = { "-s", "--setlevel" }, presentValue = "true", absentValue = "false") boolean set, @Descriptor("set the initial bundle start level") @Parameter(names = { "-i", "--setinitial" }, presentValue = "true", absentValue = "false") boolean initial, @Descriptor("target level") int level, @Descriptor("target identifiers") Bundle[] bundles) { // Keep track of service references. List refs = new ArrayList(); // Get start level service. StartLevel sl = Util.getService(m_bc, StartLevel.class, refs); if (sl == null) { System.out.println("Start Level service is unavailable."); } else if (set && initial) { System.out.println("Cannot specify '-s' and '-i' at the same time."); } else if (!set && !initial) { System.out.println("Must specify either '-s' or '-i'."); } else if (level <= 0) { System.out.println("Specified start level must be greater than zero."); } // Set the initial bundle start level. else if (initial) { if ((bundles != null) && (bundles.length == 0)) { sl.setInitialBundleStartLevel(level); } else { System.out.println("Cannot specify bundles when setting initial start level."); } } // Set the bundle start level. else if (set) { if ((bundles != null) && (bundles.length != 0)) { for (Bundle bundle : bundles) { sl.setBundleStartLevel(bundle, level); } } else { System.out.println("Must specify target bundles."); } } Util.ungetServices(m_bc, refs); } @Descriptor("query framework active start level") public void frameworklevel() { // Keep track of service references. List refs = new ArrayList(); // Get start level service. StartLevel sl = Util.getService(m_bc, StartLevel.class, refs); if (sl == null) { System.out.println("Start Level service is unavailable."); } System.out.println("Level is " + sl.getStartLevel()); Util.ungetServices(m_bc, refs); } @Descriptor("set framework active start level") public void frameworklevel(@Descriptor("target start level") int level) { // Keep track of service references. List refs = new ArrayList(); // Get start level service. StartLevel sl = Util.getService(m_bc, StartLevel.class, refs); if (sl == null) { System.out.println("Start Level service is unavailable."); } sl.setStartLevel(level); Util.ungetServices(m_bc, refs); } @Descriptor("display bundle headers") public void headers(@Descriptor("target bundles") Bundle[] bundles) { bundles = ((bundles == null) || (bundles.length == 0)) ? m_bc.getBundles() : bundles; for (Bundle bundle : bundles) { String title = Util.getBundleName(bundle); System.out.println("\n" + title); System.out.println(Util.getUnderlineString(title.length())); Dictionary dict = bundle.getHeaders(); Enumeration keys = dict.keys(); while (keys.hasMoreElements()) { Object k = (String) keys.nextElement(); Object v = dict.get(k); System.out.println(k + " = " + Util.getValueString(v)); } } } @Descriptor("displays available commands") public void help() { Map> commands = getCommands(); for (String name : commands.keySet()) { System.out.println(name); } } @Descriptor("displays information about a specific command") public void help(@Descriptor("target command") String name) { Map> commands = getCommands(); List methods = null; // If the specified command doesn't have a scope, then // search for matching methods by ignoring the scope. int scopeIdx = name.indexOf(':'); if (scopeIdx < 0) { for (Entry> entry : commands.entrySet()) { String k = entry.getKey().substring(entry.getKey().indexOf(':') + 1); if (name.equals(k)) { name = entry.getKey(); methods = entry.getValue(); break; } } } // Otherwise directly look up matching methods. else { methods = commands.get(name); } if ((methods != null) && (methods.size() > 0)) { for (Method m : methods) { Descriptor d = m.getAnnotation(Descriptor.class); if (d == null) { System.out.println("\n" + m.getName()); } else { System.out.println("\n" + m.getName() + " - " + d.value()); } System.out.println(" scope: " + name.substring(0, name.indexOf(':'))); // Get flags and options. Class[] paramTypes = m.getParameterTypes(); Map flags = new TreeMap(); Map flagDescs = new TreeMap(); Map options = new TreeMap(); Map optionDescs = new TreeMap(); List params = new ArrayList(); Annotation[][] anns = m.getParameterAnnotations(); for (int paramIdx = 0; paramIdx < anns.length; paramIdx++) { Parameter p = findAnnotation(anns[paramIdx], Parameter.class); d = findAnnotation(anns[paramIdx], Descriptor.class); if (p != null) { if (p.presentValue().equals(Parameter.UNSPECIFIED)) { options.put(p.names()[0], p); if (d != null) { optionDescs.put(p.names()[0], d.value()); } } else { flags.put(p.names()[0], p); if (d != null) { flagDescs.put(p.names()[0], d.value()); } } } else if (d != null) { params.add(paramTypes[paramIdx].getSimpleName()); params.add(d.value()); } else { params.add(paramTypes[paramIdx].getSimpleName()); params.add(""); } } // Print flags and options. if (flags.size() > 0) { System.out.println(" flags:"); for (Entry entry : flags.entrySet()) { // Print all aliases. String[] names = entry.getValue().names(); System.out.print(" " + names[0]); for (int aliasIdx = 1; aliasIdx < names.length; aliasIdx++) { System.out.print(", " + names[aliasIdx]); } System.out.println(" " + flagDescs.get(entry.getKey())); } } if (options.size() > 0) { System.out.println(" options:"); for (Entry entry : options.entrySet()) { // Print all aliases. String[] names = entry.getValue().names(); System.out.print(" " + names[0]); for (int aliasIdx = 1; aliasIdx < names.length; aliasIdx++) { System.out.print(", " + names[aliasIdx]); } System.out.println(" " + optionDescs.get(entry.getKey()) + ((entry.getValue().absentValue() == null) ? "" : " [optional]")); } } if (params.size() > 0) { System.out.println(" parameters:"); for (Iterator it = params.iterator(); it.hasNext();) { System.out.println(" " + it.next() + " " + it.next()); } } } } } private static T findAnnotation(Annotation[] anns, Class clazz) { for (int i = 0; (anns != null) && (i < anns.length); i++) { if (clazz.isInstance(anns[i])) { return clazz.cast(anns[i]); } } return null; } private Map> getCommands() { ServiceReference[] refs = null; try { refs = m_bc.getAllServiceReferences(null, "(osgi.command.scope=*)"); } catch (InvalidSyntaxException ex) { // This should never happen. } Map> commands = new TreeMap(); for (ServiceReference ref : refs) { Object svc = m_bc.getService(ref); if (svc != null) { String scope = (String) ref.getProperty("osgi.command.scope"); Object ofunc = ref.getProperty("osgi.command.function"); String[] funcs = (ofunc instanceof String[]) ? (String[]) ofunc : new String[] { String.valueOf(ofunc) }; for (String func : funcs) { commands.put(scope + ":" + func, new ArrayList()); } if (!commands.isEmpty()) { Method[] methods = svc.getClass().getMethods(); for (Method method : methods) { List commandMethods = commands.get(scope + ":" + method.getName()); if (commandMethods != null) { commandMethods.add(method); } } } // Remove any missing commands. Iterator>> it = commands.entrySet().iterator(); while (it.hasNext()) { if (it.next().getValue().size() == 0) { it.remove(); } } } } return commands; } @Descriptor("install bundle using URLs") public void install(@Descriptor("target URLs") String[] urls) { StringBuffer sb = new StringBuffer(); for (String url : urls) { String location = url.trim(); Bundle bundle = null; try { bundle = m_bc.installBundle(location, null); } catch (IllegalStateException ex) { System.err.println(ex.toString()); } catch (BundleException ex) { if (ex.getNestedException() != null) { System.err.println(ex.getNestedException().toString()); } else { System.err.println(ex.toString()); } } catch (Exception ex) { System.err.println(ex.toString()); } if (bundle != null) { if (sb.length() > 0) { sb.append(", "); } sb.append(bundle.getBundleId()); } } if (sb.toString().indexOf(',') > 0) { System.out.println("Bundle IDs: " + sb.toString()); } else if (sb.length() > 0) { System.out.println("Bundle ID: " + sb.toString()); } } @Descriptor("list all installed bundles") public void lb( @Descriptor("show location") @Parameter(names = { "-l", "--location" }, presentValue = "true", absentValue = "false") boolean showLoc, @Descriptor("show symbolic name") @Parameter(names = { "-s", "--symbolicname" }, presentValue = "true", absentValue = "false") boolean showSymbolic, @Descriptor("show update location") @Parameter(names = { "-u", "--updatelocation" }, presentValue = "true", absentValue = "false") boolean showUpdate) { lb(showLoc, showSymbolic, showUpdate, null); } @Descriptor("list installed bundles matching a substring") public void lb( @Descriptor("show location") @Parameter(names = { "-l", "--location" }, presentValue = "true", absentValue = "false") boolean showLoc, @Descriptor("show symbolic name") @Parameter(names = { "-s", "--symbolicname" }, presentValue = "true", absentValue = "false") boolean showSymbolic, @Descriptor("show update location") @Parameter(names = { "-u", "--updatelocation" }, presentValue = "true", absentValue = "false") boolean showUpdate, @Descriptor("subtring matched against name or symbolic name") String pattern) { // Keep track of service references. List refs = new ArrayList(); // Get start level service. StartLevel sl = Util.getService(m_bc, StartLevel.class, refs); if (sl == null) { System.out.println("Start Level service is unavailable."); } List found = new ArrayList(); if (pattern == null) { found.addAll(Arrays.asList(m_bc.getBundles())); } else { Bundle[] bundles = m_bc.getBundles(); for (int i = 0; i < bundles.length; i++) { Bundle bundle = bundles[i]; String name = (String) bundle.getHeaders().get(Constants.BUNDLE_NAME); if (matchBundleName(bundle.getSymbolicName(), pattern) || matchBundleName(name, pattern)) { found.add(bundle); } } } if (found.size() > 0) { printBundleList((Bundle[]) found.toArray(new Bundle[found.size()]), sl, showLoc, showSymbolic, showUpdate); } else { System.out.println("No matching bundles found"); } Util.ungetServices(m_bc, refs); } private boolean matchBundleName(String name, String pattern) { return (name != null) && name.toLowerCase().contains(pattern.toLowerCase()); } @Descriptor("display all matching log entries") public void log( @Descriptor("minimum log level [ debug | info | warn | error ]") String logLevel) { log(-1, logLevel); } @Descriptor("display some matching log entries") public void log(@Descriptor("maximum number of entries") int maxEntries, @Descriptor("minimum log level [ debug | info | warn | error ]") String logLevel) { // Keep track of service references. List refs = new ArrayList(); // Get start level service. LogReaderService lrs = Util.getService(m_bc, LogReaderService.class, refs); if (lrs == null) { System.out.println("Log reader service is unavailable."); } else { Enumeration entries = lrs.getLog(); int minLevel = logLevelAsInt(logLevel); int index = 0; while (entries.hasMoreElements() && (maxEntries < 0 || index < maxEntries)) { LogEntry entry = (LogEntry) entries.nextElement(); if (entry.getLevel() <= minLevel) { display(entry); index++; } } Util.ungetServices(m_bc, refs); } } private void display(LogEntry entry) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); StringBuffer buffer = new StringBuffer(); buffer.append(sdf.format(new Date(entry.getTime()))).append(" "); buffer.append(logLevelAsString(entry.getLevel())).append(" - "); buffer.append("Bundle: ").append(entry.getBundle().getSymbolicName()); if (entry.getServiceReference() != null) { buffer.append(" - "); buffer.append(entry.getServiceReference().toString()); } buffer.append(" - ").append(entry.getMessage()); if (entry.getException() != null) { buffer.append(" - "); StringWriter writer = new StringWriter(); PrintWriter pw = new PrintWriter(writer); entry.getException().printStackTrace(pw); buffer.append(writer.toString()); } System.out.println(buffer.toString()); } private static int logLevelAsInt(String logLevel) { if ("error".equalsIgnoreCase(logLevel)) { return LogService.LOG_ERROR; } else if ("warn".equalsIgnoreCase(logLevel)) { return LogService.LOG_WARNING; } else if ("info".equalsIgnoreCase(logLevel)) { return LogService.LOG_INFO; } return LogService.LOG_DEBUG; } private static String logLevelAsString(int level) { switch (level) { case LogService.LOG_ERROR: return "ERROR"; case LogService.LOG_WARNING: return "WARNING"; case LogService.LOG_INFO: return "INFO"; default: return "DEBUG"; } } @Descriptor("refresh bundles") public void refresh( @Descriptor("target bundles (can be null or empty)") Bundle[] bundles) { if ((bundles != null) && (bundles.length == 0)) { bundles = null; } // Keep track of service references. List refs = new ArrayList(); // Get package admin service. PackageAdmin pa = Util.getService(m_bc, PackageAdmin.class, refs); if (pa == null) { System.out.println("Package Admin service is unavailable."); } pa.refreshPackages((bundles == null) ? null : bundles); Util.ungetServices(m_bc, refs); } @Descriptor("resolve bundles") public void resolve( @Descriptor("target bundles (can be null or empty)") Bundle[] bundles) { if ((bundles != null) && (bundles.length == 0)) { bundles = null; } // Keep track of service references. List refs = new ArrayList(); // Get package admin service. PackageAdmin pa = Util.getService(m_bc, PackageAdmin.class, refs); if (pa == null) { System.out.println("Package Admin service is unavailable."); } if (!pa.resolveBundles(bundles)) { System.out.println("Not all bundles could be resolved."); } Util.ungetServices(m_bc, refs); } @Descriptor("start bundles") public void start( @Descriptor("start bundle transiently") @Parameter(names = { "-t", "--transient" }, presentValue = "true", absentValue = "false") boolean trans, @Descriptor("use declared activation policy") @Parameter(names = { "-p", "--policy" }, presentValue = "true", absentValue = "false") boolean policy, @Descriptor("target bundle identifiers or URLs") String[] ss) { int options = 0; // Check for "transient" switch. if (trans) { options |= Bundle.START_TRANSIENT; } // Check for "start policy" switch. if (policy) { options |= Bundle.START_ACTIVATION_POLICY; } // There should be at least one bundle id. if ((ss != null) && (ss.length >= 1)) { for (String s : ss) { String id = s.trim(); try { Bundle bundle = null; // The id may be a number or a URL, so check. if (Character.isDigit(id.charAt(0))) { long l = Long.parseLong(id); bundle = m_bc.getBundle(l); } else { bundle = m_bc.installBundle(id); } if (bundle != null) { bundle.start(options); } else { System.err.println("Bundle ID " + id + " is invalid."); } } catch (NumberFormatException ex) { System.err.println("Unable to parse id '" + id + "'."); } catch (BundleException ex) { if (ex.getNestedException() != null) { ex.printStackTrace(); System.err.println(ex.getNestedException().toString()); } else { System.err.println(ex.toString()); } } catch (Exception ex) { System.err.println(ex.toString()); } } } else { System.err.println("Incorrect number of arguments"); } } @Descriptor("stop bundles") public void stop(@Descriptor("stop bundle transiently") @Parameter(names = { "-t", "--transient" }, presentValue = "true", absentValue = "false") boolean trans, @Descriptor("target bundles") Bundle[] bundles) { if ((bundles == null) || (bundles.length == 0)) { System.out.println("Please specify the bundles to stop."); } int options = 0; // Check for "transient" switch. if (trans) { options |= Bundle.STOP_TRANSIENT; } for (Bundle bundle : bundles) { try { bundle.stop(options); } catch (BundleException ex) { if (ex.getNestedException() != null) { System.err.println(ex.getNestedException().toString()); } else { System.err.println(ex.toString()); } } catch (Exception ex) { System.err.println(ex.toString()); } } } @Descriptor("uninstall bundles") public void uninstall(@Descriptor("target bundles") Bundle[] bundles) { if ((bundles == null) || (bundles.length == 0)) { System.out.println("Please specify the bundles to uninstall."); } else { try { for (Bundle bundle : bundles) { bundle.uninstall(); } } catch (BundleException ex) { if (ex.getNestedException() != null) { ex.printStackTrace(); System.err.println(ex.getNestedException().toString()); } else { System.err.println(ex.toString()); } } catch (Exception ex) { System.err.println(ex.toString()); } } } @Descriptor("update bundle") public void update(@Descriptor("target bundle") Bundle bundle) { try { // Get the bundle. if (bundle != null) { bundle.update(); } } catch (BundleException ex) { if (ex.getNestedException() != null) { System.err.println(ex.getNestedException().toString()); } else { System.err.println(ex.toString()); } } catch (Exception ex) { System.err.println(ex.toString()); } } @Descriptor("update bundle from URL") public void update(@Descriptor("target bundle") Bundle bundle, @Descriptor("URL from where to retrieve bundle") String location) { if (location != null) { try { // Get the bundle. if (bundle != null) { InputStream is = new URL(location).openStream(); bundle.update(is); } else { System.err.println("Please specify a bundle to update"); } } catch (MalformedURLException ex) { System.err.println("Unable to parse URL"); } catch (IOException ex) { System.err.println("Unable to open input stream: " + ex); } catch (BundleException ex) { if (ex.getNestedException() != null) { System.err.println(ex.getNestedException().toString()); } else { System.err.println(ex.toString()); } } catch (Exception ex) { System.err.println(ex.toString()); } } else { System.err.println("Must specify a location."); } } @Descriptor("determines from where a bundle loads a class") public void which(@Descriptor("target bundle") Bundle bundle, @Descriptor("target class name") String className) { if (bundle == null) { System.err.println("Please specify a bundle"); } else { Class clazz = null; try { clazz = bundle.loadClass(className); if (clazz.getClassLoader() == null) { System.out.println("Loaded from: boot class loader"); } else if (clazz.getClassLoader() instanceof BundleReference) { Bundle p = ((BundleReference) clazz.getClassLoader()).getBundle(); System.out.println("Loaded from: " + p); } else { System.out.println("Loaded from: " + clazz.getClassLoader()); } } catch (ClassNotFoundException ex) { System.out.println("Class not found"); } } } private static void printBundleList(Bundle[] bundles, StartLevel startLevel, boolean showLoc, boolean showSymbolic, boolean showUpdate) { // Display active start level. if (startLevel != null) { System.out.println("START LEVEL " + startLevel.getStartLevel()); } // Determine last column. String lastColumn = "Name"; if (showLoc) { lastColumn = "Location"; } else if (showSymbolic) { lastColumn = "Symbolic name"; } else if (showUpdate) { lastColumn = "Update location"; } // Print column headers. if (startLevel != null) { System.out.println(String.format("%5s|%-11s|%5s|%s", "ID", "State", "Level", lastColumn)); } else { System.out.println(String.format("%5s|%-11s|%s", "ID", "State", lastColumn)); } for (Bundle bundle : bundles) { // Get the bundle name or location. String name = (String) bundle.getHeaders().get(Constants.BUNDLE_NAME); // If there is no name, then default to symbolic name. name = (name == null) ? bundle.getSymbolicName() : name; // If there is no symbolic name, resort to location. name = (name == null) ? bundle.getLocation() : name; // Overwrite the default value is the user specifically // requested to display one or the other. if (showLoc) { name = bundle.getLocation(); } else if (showSymbolic) { name = bundle.getSymbolicName(); name = (name == null) ? "" : name; } else if (showUpdate) { name = (String) bundle.getHeaders().get(Constants.BUNDLE_UPDATELOCATION); name = (name == null) ? bundle.getLocation() : name; } // Show bundle version if not showing location. name = (!showLoc && !showUpdate) ? name + " (" + bundle.getVersion() + ")" : name; // Get the bundle's start level. int level = (startLevel == null) ? -1 : startLevel.getBundleStartLevel(bundle); if (level < 0) { System.out.println(String.format("%5d|%-11s|%s", bundle.getBundleId(), getStateString(bundle), name, bundle.getVersion())); } else { System.out.println(String.format("%5d|%-11s|%5d|%s", bundle.getBundleId(), getStateString(bundle), level, name, bundle.getVersion())); } } } private static String getStateString(Bundle bundle) { int state = bundle.getState(); if (state == Bundle.ACTIVE) { return "Active "; } else if (state == Bundle.INSTALLED) { return "Installed "; } else if (state == Bundle.RESOLVED) { return "Resolved "; } else if (state == Bundle.STARTING) { return "Starting "; } else if (state == Bundle.STOPPING) { return "Stopping "; } else { return "Unknown "; } } }felix-gogo-command-0.14.0/src/main/java/org/apache/felix/gogo/command/OBR.java0000644000175000017500000005705212330717665025024 0ustar apoapo/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.command; import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.lang.reflect.Array; import java.net.URL; import java.util.Comparator; import java.util.Iterator; import java.util.Map; import java.util.TreeMap; import org.apache.felix.bundlerepository.Capability; import org.apache.felix.bundlerepository.Reason; import org.apache.felix.bundlerepository.RepositoryAdmin; import org.apache.felix.bundlerepository.Requirement; import org.apache.felix.bundlerepository.Resolver; import org.apache.felix.bundlerepository.Resource; import org.apache.felix.service.command.Descriptor; import org.apache.felix.service.command.Parameter; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.Version; import org.osgi.util.tracker.ServiceTracker; public class OBR { private static final String REPO_ADD = "add"; private static final String REPO_REMOVE = "remove"; private static final String REPO_LIST = "list"; private static final String REPO_REFRESH = "refresh"; private static final char VERSION_SEPARATOR = '@'; private final BundleContext m_bc; private final ServiceTracker m_tracker; public OBR(BundleContext bc, ServiceTracker tracker) { m_bc = bc; m_tracker = tracker; } private RepositoryAdmin getRepositoryAdmin() { Object svcObj; try { svcObj = m_tracker.getService(); } catch (Exception ex) { svcObj = null; } if (svcObj == null) { System.out.println("No repository admin service available"); } return (RepositoryAdmin) svcObj; } @Descriptor("manage repositories") public void repos( @Descriptor("( add | list | refresh | remove )") String action, @Descriptor("space-delimited list of repository URLs") String[] args) throws IOException { Object svcObj = getRepositoryAdmin(); if (svcObj == null) { return; } RepositoryAdmin ra = (RepositoryAdmin) svcObj; if (args.length > 0) { for (int i = 0; i < args.length; i++) { try { if (action.equals(REPO_ADD)) { ra.addRepository(args[i]); } else if (action.equals(REPO_REFRESH)) { ra.removeRepository(args[i]); ra.addRepository(args[i]); } else if (action.equals(REPO_REMOVE)) { ra.removeRepository(args[i]); } else { System.out.println("Unknown repository operation: " + action); } } catch (Exception ex) { ex.printStackTrace(System.err); } } } else { org.apache.felix.bundlerepository.Repository[] repos = ra.listRepositories(); if ((repos != null) && (repos.length > 0)) { for (int i = 0; i < repos.length; i++) { System.out.println(repos[i].getURI()); } } else { System.out.println("No repository URLs are set."); } } } @Descriptor("list repository resources") public void list( @Descriptor("display all versions") @Parameter(names={ "-v", "--verbose" }, presentValue="true", absentValue="false") boolean verbose, @Descriptor("optional strings used for name matching") String[] args) throws IOException, InvalidSyntaxException { Object svcObj = getRepositoryAdmin(); if (svcObj == null) { return; } RepositoryAdmin ra = (RepositoryAdmin) svcObj; // Create a filter that will match presentation name or symbolic name. StringBuffer sb = new StringBuffer(); if ((args == null) || (args.length == 0)) { sb.append("(|(presentationname=*)(symbolicname=*))"); } else { StringBuffer value = new StringBuffer(); for (int i = 0; i < args.length; i++) { if (i > 0) { value.append(" "); } value.append(args[i]); } sb.append("(|(presentationname=*"); sb.append(value); sb.append("*)(symbolicname=*"); sb.append(value); sb.append("*))"); } // Use filter to get matching resources. Resource[] resources = ra.discoverResources(sb.toString()); // Group the resources by symbolic name in descending version order, // but keep them in overall sorted order by presentation name. Map revisionMap = new TreeMap(new Comparator() { public int compare(Object o1, Object o2) { Resource r1 = (Resource) o1; Resource r2 = (Resource) o2; // Assume if the symbolic name is equal, then the two are equal, // since we are trying to aggregate by symbolic name. int symCompare = r1.getSymbolicName().compareTo(r2.getSymbolicName()); if (symCompare == 0) { return 0; } // Otherwise, compare the presentation name to keep them sorted // by presentation name. If the presentation names are equal, then // use the symbolic name to differentiate. int compare = (r1.getPresentationName() == null) ? -1 : (r2.getPresentationName() == null) ? 1 : r1.getPresentationName().compareToIgnoreCase( r2.getPresentationName()); if (compare == 0) { return symCompare; } return compare; } }); for (int resIdx = 0; (resources != null) && (resIdx < resources.length); resIdx++) { Resource[] revisions = (Resource[]) revisionMap.get(resources[resIdx]); revisionMap.put(resources[resIdx], addResourceByVersion(revisions, resources[resIdx])); } // Print any matching resources. for (Iterator i = revisionMap.entrySet().iterator(); i.hasNext(); ) { Map.Entry entry = (Map.Entry) i.next(); Resource[] revisions = (Resource[]) entry.getValue(); String name = revisions[0].getPresentationName(); name = (name == null) ? revisions[0].getSymbolicName() : name; System.out.print(name); if (verbose && revisions[0].getPresentationName() != null) { System.out.print(" [" + revisions[0].getSymbolicName() + "]"); } System.out.print(" ("); int revIdx = 0; do { if (revIdx > 0) { System.out.print(", "); } System.out.print(revisions[revIdx].getVersion()); revIdx++; } while (verbose && (revIdx < revisions.length)); if (!verbose && (revisions.length > 1)) { System.out.print(", ..."); } System.out.println(")"); } if ((resources == null) || (resources.length == 0)) { System.out.println("No matching bundles."); } } @Descriptor("retrieve resource description from repository") public void info( @Descriptor("( | | )[@] ...") String[] args) throws IOException, InvalidSyntaxException { Object svcObj = getRepositoryAdmin(); if (svcObj == null) { return; } RepositoryAdmin ra = (RepositoryAdmin) svcObj; for (int argIdx = 0; (args != null) && (argIdx < args.length); argIdx++) { // Find the target's bundle resource. String targetName = args[argIdx]; String targetVersion = null; int idx = args[argIdx].indexOf(VERSION_SEPARATOR); if (idx > 0) { targetName = args[argIdx].substring(0, idx); targetVersion = args[argIdx].substring(idx + 1); } Resource[] resources = searchRepository(ra, targetName, targetVersion); if ((resources == null) || (resources.length == 0)) { System.err.println("Unknown bundle and/or version: " + args[argIdx]); } else { for (int resIdx = 0; resIdx < resources.length; resIdx++) { if (resIdx > 0) { System.out.println(""); } printResource(System.out, resources[resIdx]); } } } } @Descriptor("deploy resource from repository") public void deploy( @Descriptor("start deployed bundles") @Parameter(names={ "-s", "--start" }, presentValue="true", absentValue="false") boolean start, @Descriptor("deploy required bundles only") @Parameter(names={ "-ro", "--required-only" }, presentValue="true", absentValue="false") boolean requiredOnly, @Descriptor("( | | )[@] ...") String[] args) throws IOException, InvalidSyntaxException { Object svcObj = getRepositoryAdmin(); if (svcObj == null) { return; } RepositoryAdmin ra = (RepositoryAdmin) svcObj; Resolver resolver = ra.resolver(); for (int argIdx = 0; (args != null) && (argIdx < args.length); argIdx++) { // Find the target's bundle resource. String targetName = args[argIdx]; String targetVersion = null; int idx = args[argIdx].indexOf(VERSION_SEPARATOR); if (idx > 0) { targetName = args[argIdx].substring(0, idx); targetVersion = args[argIdx].substring(idx + 1); } Resource resource = selectNewestVersion( searchRepository(ra, targetName, targetVersion)); if (resource != null) { resolver.add(resource); } else { System.err.println("Unknown bundle - " + args[argIdx]); } } if ((resolver.getAddedResources() != null) && (resolver.getAddedResources().length > 0)) { if (resolver.resolve()) { System.out.println("Target resource(s):"); System.out.println(Util.getUnderlineString(19)); Resource[] resources = resolver.getAddedResources(); for (int resIdx = 0; (resources != null) && (resIdx < resources.length); resIdx++) { System.out.println(" " + resources[resIdx].getPresentationName() + " (" + resources[resIdx].getVersion() + ")"); } resources = resolver.getRequiredResources(); if ((resources != null) && (resources.length > 0)) { System.out.println("\nRequired resource(s):"); System.out.println(Util.getUnderlineString(21)); for (int resIdx = 0; resIdx < resources.length; resIdx++) { System.out.println(" " + resources[resIdx].getPresentationName() + " (" + resources[resIdx].getVersion() + ")"); } } if (!requiredOnly) { resources = resolver.getOptionalResources(); if ((resources != null) && (resources.length > 0)) { System.out.println("\nOptional resource(s):"); System.out.println(Util.getUnderlineString(21)); for (int resIdx = 0; resIdx < resources.length; resIdx++) { System.out.println(" " + resources[resIdx].getPresentationName() + " (" + resources[resIdx].getVersion() + ")"); } } } try { System.out.print("\nDeploying...\n"); int options = 0; if (start) { options |= Resolver.START; } if (requiredOnly) { options |= Resolver.NO_OPTIONAL_RESOURCES; } resolver.deploy(options); System.out.println("done."); } catch (IllegalStateException ex) { System.err.println(ex); } } else { Reason[] reqs = resolver.getUnsatisfiedRequirements(); if ((reqs != null) && (reqs.length > 0)) { System.out.println("Unsatisfied requirement(s):"); System.out.println(Util.getUnderlineString(27)); for (int reqIdx = 0; reqIdx < reqs.length; reqIdx++) { System.out.println(" " + reqs[reqIdx].getRequirement().getFilter()); System.out.println(" " + reqs[reqIdx].getResource().getPresentationName()); } } else { System.out.println("Could not resolve targets."); } } } } @Descriptor("retrieve resource source code from repository") public void source( @Descriptor("extract source code") @Parameter(names={ "-x", "--extract" }, presentValue="true", absentValue="false") boolean extract, @Descriptor("local target directory") File localDir, @Descriptor("( | | )[@] ...") String[] args) throws IOException, InvalidSyntaxException { Object svcObj = getRepositoryAdmin(); if (svcObj == null) { return; } RepositoryAdmin ra = (RepositoryAdmin) svcObj; for (int argIdx = 0; argIdx < args.length; argIdx++) { // Find the target's bundle resource. String targetName = args[argIdx]; String targetVersion = null; int idx = args[argIdx].indexOf(VERSION_SEPARATOR); if (idx > 0) { targetName = args[argIdx].substring(0, idx); targetVersion = args[argIdx].substring(idx + 1); } Resource resource = selectNewestVersion( searchRepository(ra, targetName, targetVersion)); if (resource == null) { System.err.println("Unknown bundle and/or version: " + args[argIdx]); } else { String srcURI = (String) resource.getProperties().get(Resource.SOURCE_URI); if (srcURI != null) { Util.downloadSource( System.out, System.err, new URL(srcURI), localDir, extract); } else { System.err.println("Missing source URL: " + args[argIdx]); } } } } @Descriptor("retrieve resource JavaDoc from repository") public void javadoc( @Descriptor("extract documentation") @Parameter(names={"-x", "--extract" }, presentValue="true", absentValue="false") boolean extract, @Descriptor("local target directory") File localDir, @Descriptor("( | | )[@] ...") String[] args) throws IOException, InvalidSyntaxException { Object svcObj = getRepositoryAdmin(); if (svcObj == null) { return; } RepositoryAdmin ra = (RepositoryAdmin) svcObj; for (int argIdx = 0; argIdx < args.length; argIdx++) { // Find the target's bundle resource. String targetName = args[argIdx]; String targetVersion = null; int idx = args[argIdx].indexOf(VERSION_SEPARATOR); if (idx > 0) { targetName = args[argIdx].substring(0, idx); targetVersion = args[argIdx].substring(idx + 1); } Resource resource = selectNewestVersion( searchRepository(ra, targetName, targetVersion)); if (resource == null) { System.err.println("Unknown bundle and/or version: " + args[argIdx]); } else { URL docURL = (URL) resource.getProperties().get("javadoc"); if (docURL != null) { Util.downloadSource( System.out, System.err, docURL, localDir, extract); } else { System.err.println("Missing javadoc URL: " + args[argIdx]); } } } } private Resource[] searchRepository( RepositoryAdmin ra, String targetId, String targetVersion) throws InvalidSyntaxException { // Try to see if the targetId is a bundle ID. try { Bundle bundle = m_bc.getBundle(Long.parseLong(targetId)); if (bundle != null) { targetId = bundle.getSymbolicName(); } else { return null; } } catch (NumberFormatException ex) { // It was not a number, so ignore. } // The targetId may be a bundle name or a bundle symbolic name, // so create the appropriate LDAP query. StringBuffer sb = new StringBuffer("(|(presentationname="); sb.append(targetId); sb.append(")(symbolicname="); sb.append(targetId); sb.append("))"); if (targetVersion != null) { sb.insert(0, "(&"); sb.append("(version="); sb.append(targetVersion); sb.append("))"); } return ra.discoverResources(sb.toString()); } private Resource selectNewestVersion(Resource[] resources) { int idx = -1; Version v = null; for (int i = 0; (resources != null) && (i < resources.length); i++) { if (i == 0) { idx = 0; v = resources[i].getVersion(); } else { Version vtmp = resources[i].getVersion(); if (vtmp.compareTo(v) > 0) { idx = i; v = vtmp; } } } return (idx < 0) ? null : resources[idx]; } private void printResource(PrintStream out, Resource resource) { String presentationName = resource.getPresentationName(); if (presentationName == null) presentationName = resource.getSymbolicName(); System.out.println(Util.getUnderlineString(presentationName.length())); out.println(presentationName); System.out.println(Util.getUnderlineString(presentationName.length())); Map map = resource.getProperties(); for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); ) { Map.Entry entry = (Map.Entry) iter.next(); if (entry.getValue().getClass().isArray()) { out.println(entry.getKey() + ":"); for (int j = 0; j < Array.getLength(entry.getValue()); j++) { out.println(" " + Array.get(entry.getValue(), j)); } } else { out.println(entry.getKey() + ": " + entry.getValue()); } } Requirement[] reqs = resource.getRequirements(); if ((reqs != null) && (reqs.length > 0)) { out.println("Requires:"); for (int i = 0; i < reqs.length; i++) { out.println(" " + reqs[i].getFilter()); } } Capability[] caps = resource.getCapabilities(); if ((caps != null) && (caps.length > 0)) { out.println("Capabilities:"); for (int i = 0; i < caps.length; i++) { out.println(" " + caps[i].getPropertiesAsMap()); } } } private static Resource[] addResourceByVersion(Resource[] revisions, Resource resource) { // We want to add the resource into the array of revisions // in descending version sorted order (i.e., newest first) Resource[] sorted = null; if (revisions == null) { sorted = new Resource[] { resource }; } else { Version version = resource.getVersion(); Version middleVersion = null; int top = 0, bottom = revisions.length - 1, middle = 0; while (top <= bottom) { middle = (bottom - top) / 2 + top; middleVersion = revisions[middle].getVersion(); // Sort in reverse version order. int cmp = middleVersion.compareTo(version); if (cmp < 0) { bottom = middle - 1; } else { top = middle + 1; } } // Ignore duplicates. if ((top >= revisions.length) || (revisions[top] != resource)) { sorted = new Resource[revisions.length + 1]; System.arraycopy(revisions, 0, sorted, 0, top); System.arraycopy(revisions, top, sorted, top + 1, revisions.length - top); sorted[top] = resource; } } return sorted; } } felix-gogo-command-0.14.0/src/main/java/org/apache/felix/gogo/command/Util.java0000644000175000017500000003531411624544636025315 0ustar apoapo/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.command; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.ServiceReference; public class Util { public static String getBundleName(Bundle bundle) { if (bundle != null) { String name = (String) bundle.getHeaders().get(Constants.BUNDLE_NAME); return (name == null) ? "Bundle " + Long.toString(bundle.getBundleId()) : name + " (" + Long.toString(bundle.getBundleId()) + ")"; } return "[STALE BUNDLE]"; } private final static StringBuffer m_sb = new StringBuffer(); public static String getUnderlineString(int len) { synchronized (m_sb) { m_sb.delete(0, m_sb.length()); for (int i = 0; i < len; i++) { m_sb.append('-'); } return m_sb.toString(); } } public static String getValueString(Object obj) { synchronized (m_sb) { if (obj instanceof String) { return (String) obj; } else if (obj instanceof String[]) { String[] array = (String[]) obj; m_sb.delete(0, m_sb.length()); for (int i = 0; i < array.length; i++) { if (i != 0) { m_sb.append(", "); } m_sb.append(array[i].toString()); } return m_sb.toString(); } else if (obj instanceof Boolean) { return ((Boolean) obj).toString(); } else if (obj instanceof Long) { return ((Long) obj).toString(); } else if (obj instanceof Integer) { return ((Integer) obj).toString(); } else if (obj instanceof Short) { return ((Short) obj).toString(); } else if (obj instanceof Double) { return ((Double) obj).toString(); } else if (obj instanceof Float) { return ((Float) obj).toString(); } else if (obj == null) { return "null"; } else { return obj.toString(); } } } public static T getService( BundleContext bc, Class clazz, List refs) { ServiceReference ref = bc.getServiceReference(clazz.getName()); if (ref == null) { return null; } T t = (T) bc.getService(ref); if (t != null) { refs.add(ref); } return t; } public static void ungetServices(BundleContext bc, List refs) { while (refs.size() > 0) { bc.ungetService(refs.remove(0)); } } public static void downloadSource( PrintStream out, PrintStream err, URL srcURL, File localDir, boolean extract) { // Get the file name from the URL. String fileName = (srcURL.getFile().lastIndexOf('/') > 0) ? srcURL.getFile().substring(srcURL.getFile().lastIndexOf('/') + 1) : srcURL.getFile(); try { out.println("Connecting..."); if (!localDir.exists()) { err.println("Destination directory does not exist."); } File file = new File(localDir, fileName); OutputStream os = new FileOutputStream(file); URLConnection conn = srcURL.openConnection(); Util.setProxyAuth(conn); int total = conn.getContentLength(); InputStream is = conn.getInputStream(); if (total > 0) { out.println("Downloading " + fileName + " ( " + total + " bytes )."); } else { out.println("Downloading " + fileName + "."); } byte[] buffer = new byte[4096]; int count = 0; for (int len = is.read(buffer); len > 0; len = is.read(buffer)) { count += len; os.write(buffer, 0, len); } os.close(); is.close(); if (extract) { is = new FileInputStream(file); JarInputStream jis = new JarInputStream(is); out.println("Extracting..."); unjar(jis, localDir); jis.close(); file.delete(); } } catch (Exception ex) { err.println(ex); } } public static void unjar(JarInputStream jis, File dir) throws IOException { // Reusable buffer. byte[] buffer = new byte[4096]; // Loop through JAR entries. for (JarEntry je = jis.getNextJarEntry(); je != null; je = jis.getNextJarEntry()) { if (je.getName().startsWith("/")) { throw new IOException("JAR resource cannot contain absolute paths."); } File target = new File(dir, je.getName()); // Check to see if the JAR entry is a directory. if (je.isDirectory()) { if (!target.exists()) { if (!target.mkdirs()) { throw new IOException("Unable to create target directory: " + target); } } // Just continue since directories do not have content to copy. continue; } int lastIndex = je.getName().lastIndexOf('/'); String name = (lastIndex >= 0) ? je.getName().substring(lastIndex + 1) : je.getName(); String destination = (lastIndex >= 0) ? je.getName().substring(0, lastIndex) : ""; // JAR files use '/', so convert it to platform separator. destination = destination.replace('/', File.separatorChar); copy(jis, dir, name, destination, buffer); } } public static void copy( InputStream is, File dir, String destName, String destDir, byte[] buffer) throws IOException { if (destDir == null) { destDir = ""; } // Make sure the target directory exists and // that is actually a directory. File targetDir = new File(dir, destDir); if (!targetDir.exists()) { if (!targetDir.mkdirs()) { throw new IOException("Unable to create target directory: " + targetDir); } } else if (!targetDir.isDirectory()) { throw new IOException("Target is not a directory: " + targetDir); } BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(new File(targetDir, destName))); int count = 0; while ((count = is.read(buffer)) > 0) { bos.write(buffer, 0, count); } bos.close(); } public static void setProxyAuth(URLConnection conn) throws IOException { // Support for http proxy authentication String auth = System.getProperty("http.proxyAuth"); if ((auth != null) && (auth.length() > 0)) { if ("http".equals(conn.getURL().getProtocol()) || "https".equals(conn.getURL().getProtocol())) { String base64 = Base64Encoder.base64Encode(auth); conn.setRequestProperty("Proxy-Authorization", "Basic " + base64); } } } public static InputStream openURL(final URL url) throws IOException { // Do it the manual way to have a chance to // set request properties as proxy auth (EW). return openURL(url.openConnection()); } public static InputStream openURL(final URLConnection conn) throws IOException { // Do it the manual way to have a chance to // set request properties as proxy auth (EW). setProxyAuth(conn); return conn.getInputStream(); } public static List parseSubstring(String value) { List pieces = new ArrayList(); StringBuffer ss = new StringBuffer(); // int kind = SIMPLE; // assume until proven otherwise boolean wasStar = false; // indicates last piece was a star boolean leftstar = false; // track if the initial piece is a star boolean rightstar = false; // track if the final piece is a star int idx = 0; // We assume (sub)strings can contain leading and trailing blanks boolean escaped = false; loop: for (;;) { if (idx >= value.length()) { if (wasStar) { // insert last piece as "" to handle trailing star rightstar = true; } else { pieces.add(ss.toString()); // accumulate the last piece // note that in the case of // (cn=); this might be // the string "" (!=null) } ss.setLength(0); break loop; } // Read the next character and account for escapes. char c = value.charAt(idx++); if (!escaped && ((c == '(') || (c == ')'))) { throw new IllegalArgumentException( "Illegal value: " + value); } else if (!escaped && (c == '*')) { if (wasStar) { // encountered two successive stars; // I assume this is illegal throw new IllegalArgumentException("Invalid filter string: " + value); } if (ss.length() > 0) { pieces.add(ss.toString()); // accumulate the pieces // between '*' occurrences } ss.setLength(0); // if this is a leading star, then track it if (pieces.isEmpty()) { leftstar = true; } wasStar = true; } else if (!escaped && (c == '\\')) { escaped = true; } else { escaped = false; wasStar = false; ss.append(c); } } if (leftstar || rightstar || pieces.size() > 1) { // insert leading and/or trailing "" to anchor ends if (rightstar) { pieces.add(""); } if (leftstar) { pieces.add(0, ""); } } return pieces; } public static String unparseSubstring(List pieces) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < pieces.size(); i++) { if (i > 0) { sb.append("*"); } sb.append(pieces.get(i)); } return sb.toString(); } public static boolean compareSubstring(List pieces, String s) { // Walk the pieces to match the string // There are implicit stars between each piece, // and the first and last pieces might be "" to anchor the match. // assert (pieces.length > 1) // minimal case is * boolean result = true; int len = pieces.size(); // Special case, if there is only one piece, then // we must perform an equality test. if (len == 1) { return s.equals(pieces.get(0)); } // Otherwise, check whether the pieces match // the specified string. int index = 0; loop: for (int i = 0; i < len; i++) { String piece = pieces.get(i); // If this is the first piece, then make sure the // string starts with it. if (i == 0) { if (!s.startsWith(piece)) { result = false; break loop; } } // If this is the last piece, then make sure the // string ends with it. if (i == len - 1) { if (s.endsWith(piece)) { result = true; } else { result = false; } break loop; } // If this is neither the first or last piece, then // make sure the string contains it. if ((i > 0) && (i < (len - 1))) { index = s.indexOf(piece, index); if (index < 0) { result = false; break loop; } } // Move string index beyond the matching piece. index += piece.length(); } return result; } }felix-gogo-command-0.14.0/src/main/java/org/apache/felix/gogo/command/Inspect42.java0000644000175000017500000004515511624744407026155 0ustar apoapo/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.command; import java.util.ArrayList; import java.util.List; import org.apache.felix.service.command.Descriptor; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.ServiceReference; import org.osgi.service.packageadmin.ExportedPackage; import org.osgi.service.packageadmin.PackageAdmin; import org.osgi.service.packageadmin.RequiredBundle; public class Inspect42 { public static final String LEGACY_PACKAGE_NAMESPACE = "package"; public static final String LEGACY_BUNDLE_NAMESPACE = "bundle"; public static final String LEGACY_HOST_NAMESPACE = "host"; public static final String NONSTANDARD_SERVICE_NAMESPACE = "service"; public static final String CAPABILITY = "capability"; public static final String REQUIREMENT = "requirement"; private static final String EMPTY_MESSAGE = "[EMPTY]"; private static final String UNUSED_MESSAGE = "[UNUSED]"; private static final String UNRESOLVED_MESSAGE = "[UNRESOLVED]"; private final BundleContext m_bc; public Inspect42(BundleContext bc) { m_bc = bc; } @Descriptor("inspects bundle capabilities and requirements") public void inspect( @Descriptor("('capability' | 'requirement')") String direction, @Descriptor("('package' | 'bundle' | 'host' | 'service')") String namespace, @Descriptor("target bundles") Bundle[] bundles) { inspect(m_bc, direction, namespace, bundles); } private static void inspect( BundleContext bc, String direction, String namespace, Bundle[] bundles) { // Verify arguments. if (isValidDirection(direction)) { bundles = ((bundles == null) || (bundles.length == 0)) ? bc.getBundles() : bundles; if (CAPABILITY.startsWith(direction)) { printNonstandardCapabilities(bc, Util.parseSubstring(namespace), bundles); } else { printNonstandardRequirements(bc, Util.parseSubstring(namespace), bundles); } } else { if (!isValidDirection(direction)) { System.out.println("Invalid argument: " + direction); } } } private static void printNonstandardCapabilities( BundleContext bc, List namespace, Bundle[] bundles) { boolean separatorNeeded = false; for (Bundle b : bundles) { if (separatorNeeded) { System.out.println(""); } String title = b + " provides:"; System.out.println(title); System.out.println(Util.getUnderlineString(title.length())); boolean matches = false; if (matchNamespace(namespace, LEGACY_BUNDLE_NAMESPACE)) { matches |= printRequiringBundles(bc, b); } if (matchNamespace(namespace, LEGACY_HOST_NAMESPACE)) { matches |= printHostedFragments(bc, b); } if (matchNamespace(namespace, LEGACY_PACKAGE_NAMESPACE)) { matches |= printExportedPackages(bc, b); } if (matchNamespace(namespace, NONSTANDARD_SERVICE_NAMESPACE)) { matches |= Inspect.printServiceCapabilities(b); } // If there were no capabilities for the specified namespace, // then say so. if (!matches) { System.out.println(Util.unparseSubstring(namespace) + " " + EMPTY_MESSAGE); } separatorNeeded = true; } } private static void printNonstandardRequirements( BundleContext bc, List namespace, Bundle[] bundles) { boolean separatorNeeded = false; for (Bundle b : bundles) { if (separatorNeeded) { System.out.println(""); } String title = b + " requires:"; System.out.println(title); System.out.println(Util.getUnderlineString(title.length())); boolean matches = false; if (matchNamespace(namespace, LEGACY_BUNDLE_NAMESPACE)) { matches |= printRequiredBundles(bc, b); } if (matchNamespace(namespace, LEGACY_HOST_NAMESPACE)) { matches |= printFragmentHosts(bc, b); } if (matchNamespace(namespace, LEGACY_PACKAGE_NAMESPACE)) { matches |= printImportedPackages(bc, b); } if (matchNamespace(namespace, NONSTANDARD_SERVICE_NAMESPACE)) { matches |= Inspect.printServiceRequirements(b); } // If there were no capabilities for the specified namespace, // then say so. if (!matches) { System.out.println(Util.unparseSubstring(namespace) + " " + EMPTY_MESSAGE); } separatorNeeded = true; } } public static boolean printExportedPackages(BundleContext bc, Bundle b) { boolean matches = false; // Keep track of service references. List refs = new ArrayList(); // Fragments cannot export packages. if (!isFragment(b)) { // Get package admin service. PackageAdmin pa = Util.getService(bc, PackageAdmin.class, refs); if (pa == null) { System.out.println("PackageAdmin service is unavailable."); } else { try { ExportedPackage[] exports = pa.getExportedPackages(b); if (exports != null) { for (ExportedPackage ep : exports) { matches = true; Bundle[] importers = ep.getImportingBundles(); if ((importers != null) && (importers.length > 0)) { String msg = LEGACY_PACKAGE_NAMESPACE + "; " + ep.getName() + "; " + ep.getVersion().toString() + " required by:"; System.out.println(msg); for (Bundle importer : importers) { System.out.println(" " + importer); } } else { System.out.println( LEGACY_PACKAGE_NAMESPACE + "; " + ep.getName() + "; " + ep.getVersion().toString() + " " + UNUSED_MESSAGE); } } } } catch (Exception ex) { System.err.println(ex.toString()); } } } Util.ungetServices(bc, refs); return matches; } private static boolean printImportedPackages(BundleContext bc, Bundle b) { boolean matches = false; // Keep track of service references. List refs = new ArrayList(); // Fragments cannot import packages. if (!isFragment(b)) { // Get package admin service. PackageAdmin pa = Util.getService(bc, PackageAdmin.class, refs); if (pa == null) { System.out.println("PackageAdmin service is unavailable."); } else { ExportedPackage[] exports = pa.getExportedPackages((Bundle) null); if (exports != null) { for (ExportedPackage ep : exports) { Bundle[] importers = ep.getImportingBundles(); if (importers != null) { for (Bundle importer : importers) { if (importer == b) { matches = true; System.out.println( LEGACY_PACKAGE_NAMESPACE + "; " + ep.getName() + " resolved by:"); System.out.println( " " + ep.getName() + "; " + ep.getVersion().toString() + " from " + ep.getExportingBundle()); } } } } } } } Util.ungetServices(bc, refs); return matches; } public static boolean printRequiringBundles(BundleContext bc, Bundle b) { boolean matches = false; // Keep track of service references. List refs = new ArrayList(); // Fragments cannot be required. if (!isFragment(b)) { // Get package admin service. PackageAdmin pa = Util.getService(bc, PackageAdmin.class, refs); if (pa == null) { System.out.println("PackageAdmin service is unavailable."); } else { try { RequiredBundle[] rbs = pa.getRequiredBundles(b.getSymbolicName()); if (rbs != null) { for (RequiredBundle rb : rbs) { if (rb.getBundle() == b) { Bundle[] requires = rb.getRequiringBundles(); if ((requires != null) && (requires.length > 0)) { matches = true; System.out.println( LEGACY_BUNDLE_NAMESPACE + "; " + b.getSymbolicName() + "; " + b.getVersion().toString() + " required by:"); for (Bundle requirer : requires) { System.out.println(" " + requirer); } } } } } if (!matches) { matches = true; System.out.println( LEGACY_BUNDLE_NAMESPACE + "; " + b.getSymbolicName() + "; " + b.getVersion().toString() + " " + UNUSED_MESSAGE); } } catch (Exception ex) { System.err.println(ex.toString()); } } } Util.ungetServices(bc, refs); return matches; } private static boolean printRequiredBundles(BundleContext bc, Bundle b) { boolean matches = false; // Keep track of service references. List refs = new ArrayList(); // Fragments cannot require bundles. if (!isFragment(b)) { // Get package admin service. PackageAdmin pa = Util.getService(bc, PackageAdmin.class, refs); if (pa == null) { System.out.println("PackageAdmin service is unavailable."); } else { RequiredBundle[] rbs = pa.getRequiredBundles(null); if (rbs != null) { for (RequiredBundle rb : rbs) { Bundle[] requirers = rb.getRequiringBundles(); if (requirers != null) { for (Bundle requirer : requirers) { if (requirer == b) { matches = true; System.out.println( LEGACY_BUNDLE_NAMESPACE + "; " + rb.getSymbolicName() + " resolved by:"); System.out.println(" " + rb.getBundle()); } } } } } } } Util.ungetServices(bc, refs); return matches; } public static boolean printHostedFragments(BundleContext bc, Bundle b) { boolean matches = false; // Keep track of service references. List refs = new ArrayList(); // Get package admin service. PackageAdmin pa = Util.getService(bc, PackageAdmin.class, refs); if (pa == null) { System.out.println("PackageAdmin service is unavailable."); } else { try { if (!isFragment(b)) { matches = true; Bundle[] fragments = pa.getFragments(b); if ((fragments != null) && (fragments.length > 0)) { System.out.println( LEGACY_HOST_NAMESPACE + "; " + b.getSymbolicName() + "; " + b.getVersion().toString() + " required by:"); for (Bundle fragment : fragments) { System.out.println(" " + fragment); } } else { System.out.println( LEGACY_HOST_NAMESPACE + "; " + b.getSymbolicName() + "; " + b.getVersion().toString() + " " + UNUSED_MESSAGE); } } } catch (Exception ex) { System.err.println(ex.toString()); } Util.ungetServices(bc, refs); } return matches; } public static boolean printFragmentHosts(BundleContext bc, Bundle b) { boolean matches = false; // Keep track of service references. List refs = new ArrayList(); // Get package admin service. PackageAdmin pa = Util.getService(bc, PackageAdmin.class, refs); if (pa == null) { System.out.println("PackageAdmin service is unavailable."); } else { try { if (isFragment(b)) { matches = true; Bundle[] hosts = pa.getHosts(b); if ((hosts != null) && (hosts.length > 0)) { System.out.println( LEGACY_HOST_NAMESPACE + "; " + b.getHeaders().get(Constants.FRAGMENT_HOST) + " resolved by:"); for (Bundle host : hosts) { System.out.println(" " + host); } } else { System.out.println( LEGACY_HOST_NAMESPACE + "; " + b.getHeaders().get(Constants.FRAGMENT_HOST) + " " + UNRESOLVED_MESSAGE); } } } catch (Exception ex) { System.err.println(ex.toString()); } Util.ungetServices(bc, refs); } return matches; } private static boolean matchNamespace(List namespace, String actual) { return Util.compareSubstring(namespace, actual); } private static boolean isValidDirection(String direction) { return (CAPABILITY.startsWith(direction) || REQUIREMENT.startsWith(direction)); } private static boolean isFragment(Bundle bundle) { return bundle.getHeaders().get(Constants.FRAGMENT_HOST) != null; } }felix-gogo-command-0.14.0/src/main/java/org/apache/felix/gogo/command/Activator.java0000644000175000017500000000557311624744407026336 0ustar apoapo/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.gogo.command; import java.util.Hashtable; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.util.tracker.ServiceTracker; public class Activator implements BundleActivator { private volatile ServiceTracker m_tracker = null; public void start(BundleContext bc) throws Exception { Hashtable props = new Hashtable(); props.put("osgi.command.scope", "felix"); props.put("osgi.command.function", new String[] { "bundlelevel", "frameworklevel", "headers", "help", "install", "lb", "log", "refresh", "resolve", "start", "stop", "uninstall", "update", "which" }); bc.registerService( Basic.class.getName(), new Basic(bc), props); // Register "inspect" command for R4.3 or R4.2 depending // on the underlying framework. props.put("osgi.command.scope", "felix"); props.put("osgi.command.function", new String[] { "inspect" }); try { getClass().getClassLoader().loadClass("org.osgi.framework.wiring.BundleWiring"); bc.registerService( Inspect.class.getName(), new Inspect(bc), props); } catch (Throwable th) { bc.registerService( Inspect42.class.getName(), new Inspect42(bc), props); } props.put("osgi.command.scope", "felix"); props.put("osgi.command.function", new String[] { "cd", "ls" }); bc.registerService( Files.class.getName(), new Files(bc), props); m_tracker = new ServiceTracker( bc, "org.apache.felix.bundlerepository.RepositoryAdmin", null); m_tracker.open(); props.put("osgi.command.scope", "obr"); props.put("osgi.command.function", new String[] { "deploy", "info", "javadoc", "list", "repos", "source" }); bc.registerService( OBR.class.getName(), new OBR(bc, m_tracker), props); } public void stop(BundleContext bc) throws Exception { m_tracker.close(); } }felix-gogo-command-0.14.0/src/main/resources/0000755000175000017500000000000012465440116017120 5ustar apoapofelix-gogo-command-0.14.0/DEPENDENCIES0000644000175000017500000000130412350001701015124 0ustar apoapoApache Felix Gogo Command Copyright 2014 The Apache Software Foundation This software was developed at the Apache Software Foundation (http://www.apache.org) and may have dependencies on other Apache software licensed under Apache License 2.0. I. Included Third-Party Software This product includes software developed at The OSGi Alliance (http://www.osgi.org/). Copyright (c) OSGi Alliance (2000, 2009). Licensed under the Apache License 2.0. II. Used Third-Party Software This product uses software developed at The OSGi Alliance (http://www.osgi.org/). Copyright (c) OSGi Alliance (2000, 2009). Licensed under the Apache License 2.0. III. License Summary - Apache License 2.0 felix-gogo-command-0.14.0/LICENSE0000644000175000017500000002613611400007002014365 0ustar apoapo Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. felix-gogo-command-0.14.0/pom.xml0000644000175000017500000000746712350012657014724 0ustar apoapo 4.0.0 org.apache.felix gogo-parent 0.6.0 ../gogo-parent/pom.xml org.apache.felix.gogo.command bundle 0.14.0 Apache Felix Gogo Command Provides basic shell commands for Gogo. org.osgi org.osgi.core 4.3.1 org.osgi org.osgi.compendium 4.0.0 org.apache.felix org.apache.felix.gogo.runtime 0.10.0 org.apache.felix org.apache.felix.bundlerepository 1.6.0 org.apache.maven.plugins maven-compiler-plugin 1.5 1.5 org.apache.felix maven-bundle-plugin 2.3.5 true org.osgi.service.log ${artifactId} ${pom.artifactId} ${pom.artifactId}.Activator org.apache.felix.service.command; status="provisional", org.osgi.framework; version="[1.5,2.0)", org.osgi.framework.wiring; resolution:=optional, * {maven-resources},META-INF/LICENSE=LICENSE,META-INF/NOTICE=NOTICE,META-INF/DEPENDENCIES=DEPENDENCIES org.apache.felix.bundlerepository, org.apache.felix.bundlerepository.* scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.gogo.command-0.14.0 scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.gogo.command-0.14.0 scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.gogo.command-0.14.0 felix-gogo-command-0.14.0/NOTICE0000644000175000017500000000061012350001701014256 0ustar apoapoApache Felix Gogo Command Copyright 2014 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). Licensed under the Apache License 2.0. This product includes software developed at The OSGi Alliance (http://www.osgi.org/). Copyright (c) OSGi Alliance (2000, 2009). Licensed under the Apache License 2.0.