/* * 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.karaf.bundle.command; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import org.apache.karaf.shell.api.action.Command; import org.apache.karaf.shell.api.action.Option; import org.apache.karaf.shell.api.action.lifecycle.Service; import org.apache.karaf.shell.support.ShellUtil; import org.osgi.framework.Bundle; import org.osgi.framework.Constants; import org.osgi.framework.ServiceReference; @Command(scope = "bundle", name = "services", description = "Lists OSGi services per Bundle") @Service public class Services extends BundlesCommand { @Option(name = "-a", aliases = {}, description = "Shows all services. (Karaf commands and completers are hidden by default)", required = false, multiValued = false) boolean showAll; @Option(name = "-u", aliases = {}, description = "Shows the services each bundle uses. (By default the provided services are shown)", required = false, multiValued = false) boolean inUse; @Option(name = "-p", aliases = {}, description = "Shows the properties of the services", required = false, multiValued = false) boolean showProperties = false; Set<String> hidden = new HashSet<String>(Arrays.asList(new String[] { "org.apache.felix.service.command.Function", "org.apache.karaf.shell.console.Completer" })); @Override protected void executeOnBundle(Bundle bundle) throws Exception { ServiceReference<?>[] refs = (inUse) ? bundle.getServicesInUse() : bundle.getRegisteredServices(); printServices(bundle, refs, showProperties); } private void printServices(Bundle bundle, ServiceReference<?>[] refs, boolean showProperties) { boolean headerPrinted = false; boolean needSeparator = false; if (refs == null) { return; } for (ServiceReference<?> serviceRef : refs) { String[] objectClass = (String[]) serviceRef.getProperty(Constants.OBJECTCLASS); boolean print = showAll || !isCommandOrCompleter(objectClass); // Print header if we have not already done so. if (!headerPrinted) { headerPrinted = true; System.out.println(""); String title = ShellUtil.getBundleName(bundle) + ((inUse) ? " uses:" : " provides:"); System.out.println(title); System.out.println(ShellUtil.getUnderlineString(title)); } if (print) { // Print service separator if necessary. if (needSeparator && showProperties) { System.out.println("----"); } if (showProperties) { printProperties(serviceRef); } else { System.out.println(ShellUtil.getValueString(objectClass)); } needSeparator = true; } } } private boolean isCommandOrCompleter(String[] objectClasses) { for (String objectClass : objectClasses) { if (hidden.contains(objectClass)) { return true; } } return false; } private void printProperties(ServiceReference<?> serviceRef) { for (String key : serviceRef.getPropertyKeys()) { System.out.println(key + " = " + ShellUtil.getValueString(serviceRef.getProperty(key))); } } }