Use service tracker to correctly track command services and which also
helps us avoid some locking issues. (FELIX-2378, FELIX-2379)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@950098 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/shell/src/main/java/org/apache/felix/shell/impl/Activator.java b/shell/src/main/java/org/apache/felix/shell/impl/Activator.java
index d68ed0c..69d51d7 100644
--- a/shell/src/main/java/org/apache/felix/shell/impl/Activator.java
+++ b/shell/src/main/java/org/apache/felix/shell/impl/Activator.java
@@ -20,15 +20,16 @@
import java.io.PrintStream;
import java.security.*;
-import java.util.*;
import org.apache.felix.shell.Command;
import org.osgi.framework.*;
+import org.osgi.util.tracker.ServiceTracker;
public class Activator implements BundleActivator
{
- private transient BundleContext m_context = null;
- private transient ShellServiceImpl m_shell = null;
+ private BundleContext m_context = null;
+ private ShellServiceImpl m_shell = null;
+ private volatile ServiceTracker m_tracker = null;
public void start(BundleContext context)
{
@@ -41,44 +42,23 @@
};
context.registerService(classes, m_shell = new ShellServiceImpl(), null);
- // Listen for registering/unregistering of impl command
- // services so that we can automatically add/remove them
- // from our list of available commands.
- ServiceListener sl = new ServiceListener() {
- public void serviceChanged(ServiceEvent event)
- {
- if (event.getType() == ServiceEvent.REGISTERED)
- {
- m_shell.addCommand(event.getServiceReference());
- }
- else if (event.getType() == ServiceEvent.UNREGISTERING)
- {
- m_shell.removeCommand(event.getServiceReference());
- }
- else
- {
- }
- }
- };
-
- try
- {
- m_context.addServiceListener(sl,
- "(|(objectClass="
+ // Create a service tracker to listen for command services.
+ String filter = "(|(objectClass="
+ org.apache.felix.shell.Command.class.getName()
+ ")(objectClass="
+ org.ungoverned.osgi.service.shell.Command.class.getName()
- + "))");
+ + "))";
+ try
+ {
+ m_tracker = new ServiceTracker(
+ context, FrameworkUtil.createFilter(filter), m_tracker);
}
catch (InvalidSyntaxException ex)
{
- System.err.println("Activator: Cannot register service listener.");
- System.err.println("Activator: " + ex);
+ // This should never happen.
}
- // Now manually try to find any commands that have already
- // been registered (i.e., we didn't see their service events).
- initializeCommands();
+ m_tracker.open();
// Register "bundlelevel" command service.
context.registerService(
@@ -180,97 +160,65 @@
public void stop(BundleContext context)
{
- m_shell.clearCommands();
- }
-
- private void initializeCommands()
- {
- synchronized (m_shell)
- {
- try
- {
- ServiceReference[] refs = m_context.getServiceReferences(
- org.apache.felix.shell.Command.class.getName(), null);
- if (refs != null)
- {
- for (int i = 0; i < refs.length; i++)
- {
- m_shell.addCommand(refs[i]);
- }
- }
- }
- catch (Exception ex)
- {
- System.err.println("Activator: " + ex);
- }
- }
+ m_tracker.close();
}
private class ShellServiceImpl implements
org.apache.felix.shell.ShellService,
org.ungoverned.osgi.service.shell.ShellService
{
- private final HashMap m_commandRefMap = new HashMap();
- private final TreeMap m_commandNameMap = new TreeMap();
-
public String[] getCommands()
{
- synchronized(m_commandRefMap)
+ Object[] commands = m_tracker.getServices();
+ String[] names = (commands == null)
+ ? new String[0] : new String[commands.length];
+ for (int i = 0; i < names.length; i++)
{
- Set ks = m_commandNameMap.keySet();
- String[] cmds = (ks == null)
- ? new String[0] : (String[]) ks.toArray(new String[ks.size()]);
- return cmds;
- }
+ names[i] = ((Command) commands[i]).getName();
+ }
+ return names;
}
public String getCommandUsage(String name)
{
- synchronized(m_commandRefMap)
+ Object[] commands = m_tracker.getServices();
+ for (int i = 0; (commands != null) && (i < commands.length); i++)
{
- Command command = (Command) m_commandNameMap.get(name);
- return (command == null) ? null : command.getUsage();
- }
+ Command command = (Command) commands[i];
+ if (command.getName().equals(name))
+ {
+ return command.getUsage();
+ }
+ }
+ return null;
}
public String getCommandDescription(String name)
{
- synchronized(m_commandRefMap)
+ Object[] commands = m_tracker.getServices();
+ for (int i = 0; (commands != null) && (i < commands.length); i++)
{
- Command command = (Command) m_commandNameMap.get(name);
- return (command == null) ? null : command.getShortDescription();
- }
+ Command command = (Command) commands[i];
+ if (command.getName().equals(name))
+ {
+ return command.getShortDescription();
+ }
+ }
+ return null;
}
public ServiceReference getCommandReference(String name)
{
- ServiceReference ref = null;
- synchronized(m_commandRefMap)
+ ServiceReference[] refs = m_tracker.getServiceReferences();
+ for (int i = 0; (refs != null) && (i < refs.length); i++)
{
- Iterator itr = m_commandRefMap.entrySet().iterator();
- while (itr.hasNext())
- {
- Map.Entry entry = (Map.Entry) itr.next();
- if (((Command) entry.getValue()).getName().equals(name))
- {
- ref = (ServiceReference) entry.getKey();
- break;
- }
- }
+ Command command = (Command) m_tracker.getService(refs[i]);
+ if ((command != null) && command.getName().equals(name))
+ {
+ return refs[i];
+ }
}
- return ref;
- }
-
- public void removeCommand(ServiceReference ref)
- {
- synchronized(m_commandRefMap)
- {
- Command command = (Command) m_commandRefMap.remove(ref);
- if (command != null)
- {
- m_commandNameMap.remove(command.getName());
- }
- }
+ return null;
}
public void executeCommand(
@@ -313,36 +261,18 @@
}
}
- protected Command getCommand(String name)
+ Command getCommand(String name)
{
- synchronized(m_commandRefMap)
+ Object[] commands = m_tracker.getServices();
+ for (int i = 0; (commands != null) && (i < commands.length); i++)
{
- Command command = (Command) m_commandNameMap.get(name);
- return (command == null) ? null : command;
- }
- }
-
- protected void addCommand(ServiceReference ref)
- {
- Object cmdObj = m_context.getService(ref);
- Command command =
- (cmdObj instanceof org.ungoverned.osgi.service.shell.Command)
- ? new OldCommandWrapper((org.ungoverned.osgi.service.shell.Command) cmdObj)
- : (Command) cmdObj;
- synchronized(m_commandRefMap)
- {
- m_commandRefMap.put(ref, command);
- m_commandNameMap.put(command.getName(), command);
+ Command command = (Command) commands[i];
+ if (command.getName().equals(name))
+ {
+ return command;
+ }
}
- }
-
- protected void clearCommands()
- {
- synchronized(m_commandRefMap)
- {
- m_commandRefMap.clear();
- m_commandNameMap.clear();
- }
+ return null;
}
}