= Example 6 - Spell Checker Service Bundle

_(This example should be rewritten to use the Service Tracker.)_

In this example, we complicate things further by defining a new service that uses an arbitrary number of dictionary services to perform its function.
More precisely, we define a spell checker service will aggregate all dictionary services and provide another service that allows us to spell check passages using our underlying dictionary services to verify the spelling of words.
Our bundle will only provide the spell checker service if there is at least one dictionary service available.
First, we will start by defining the spell checker service interface in a file called `SpellChecker.java`:

----
/*
 * Apache Felix OSGi tutorial.
**/

package tutorial.example6.service;

/**
 * A simple service interface that defines a spell checker service.
 * A spell checker service checks the spelling of all words in a
 * given passage. A passage is any number of words separated by
 * a space character and the following punctuation marks: comma,
 * period, exclamation mark, question mark, semi-colon, and colon.
**/
public interface SpellChecker
{
    /**
     * Checks a given passage for spelling errors. A passage is any
     * number of words separated by a space and any of the following
     * punctuation marks: comma (,), period (.), exclamation mark (!),
     * question mark (?), semi-colon (;), and colon(:).
     * @param passage the passage to spell check.
     * @return An array of misspelled words or null if no
     *         words are misspelled.
    **/
    public String[] check(String passage);
}
----

The service interface is quite simple, with only one method that needs to be implemented.
Notice that we put the service interface in the package `tutorial.example6.service`, instead of just putting it in `tutorial.example6`.
We did this because we need to share the interface definition with other bundles, therefore it is better to separate service interfaces that need to be shared from code that does not need to be shared.
Such an approach ensures a strong separation between interface and implementation.

In the following bundle source code, the bundle needs to create a complete list of all dictionary services;
this is somewhat tricky and must be done carefully.
First, the bundle uses its bundle context to register itself as a service event listener, then it queries for all currently available dictionary services.
After creating the list of dictionary services, the bundle then registers its spell checker service if and only if there is at least one dictionary service available.
These actions must be performed in a synchronized block to avoid interference from service events.
Additionally, since the bundle is monitoring the dynamic availability of the dictionary services, when the number of dictionary services falls to zero or increases from zero, the bundle must unregister and register its spell checker service, respectively.
We implement our bundle in a file called `Activator.java`:

----
/*
 * Apache Felix OSGi tutorial.
**/

package tutorial.example6;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceEvent;

import tutorial.example2.service.DictionaryService;
import tutorial.example6.service.SpellChecker;

/**
 * This class implements a bundle that implements a spell
 * checker service. The spell checker service uses all available
 * dictionary services to check for the existence of words in
 * a given sentence. This bundle not only monitors the dynamic
 * availability of dictionary services, but it manages the
 * aggregation of all available dictionary services as they
 * arrive and depart. The spell checker service is only registered
 * if there are dictionary services available, thus the spell
 * checker service will appear and disappear as dictionary
 * services appear and disappear, respectively.
**/
public class Activator implements BundleActivator, ServiceListener
{
    // Bundle's context.
    private BundleContext m_context = null;
    // List of available dictionary service references.
    private ArrayList m_refList = new ArrayList();
    // Maps service references to service objects.
    private HashMap m_refToObjMap = new HashMap();
    // The spell checker service registration.
    private ServiceRegistration m_reg = null;

    /**
     * Implements BundleActivator.start(). Adds itself
     * as a service listener and queries for all currently
     * available dictionary services. Any available dictionary
     * services are added to the service reference list. If
     * dictionary services are found, then the spell checker
     * service is registered.
     * @param context the framework context for the bundle.
    **/
    public void start(BundleContext context) throws Exception
    {
        m_context = context;

        synchronized (m_refList)
        {
            // Listen for events pertaining to dictionary services.
            m_context.addServiceListener(this,
                "(&(objectClass=" + DictionaryService.class.getName() + ")" +
                "(Language=*))");

            // Query for all dictionary services.
            ServiceReference[] refs = m_context.getServiceReferences(
                DictionaryService.class.getName(), "(Language=*)");

            // Add any dictionaries to the service reference list.
            if (refs != null)
            {
                for (int i = 0; i < refs.length; i++)
                {
                    // Get the service object.
                    Object service = m_context.getService(refs[i]);

                    // Make that the service is not being duplicated.
                    if ((service != null) &&
                        (m_refToObjMap.get(refs[i]) == null))
                    {
                        // Add to the reference list.
                        m_refList.add(refs[i]);
                        // Map reference to service object for easy look up.
                        m_refToObjMap.put(refs[i], service);
                    }
                }

                // Register spell checker service if there are any
                // dictionary services.
                if (m_refList.size() > 0)
                {
                    m_reg = m_context.registerService(
                        SpellChecker.class.getName(),
                        new SpellCheckerImpl(), null);
                }
            }
        }
    }

    /**
     * Implements BundleActivator.stop(). Does nothing since
     * the framework will automatically unregister any registered services,
     * release any used services, and remove any event listeners.
     * @param context the framework context for the bundle.
    **/
    public void stop(BundleContext context)
    {
        // NOTE: The services automatically released.
    }

    /**
     * Implements ServiceListener.serviceChanged(). Monitors
     * the arrival and departure of dictionary services, adding and
     * removing them from the service reference list, respectively.
     * In the case where no more dictionary services are available,
     * the spell checker service is unregistered. As soon as any dictionary
     * service becomes available, the spell checker service is
     * reregistered.
     * @param event the fired service event.
    **/
    public void serviceChanged(ServiceEvent event)
    {
        synchronized (m_refList)
        {
            // Add the new dictionary service to the service list.
            if (event.getType() == ServiceEvent.REGISTERED)
            {
                // Get the service object.
                Object service = m_context.getService(event.getServiceReference());

                // Make that the service is not being duplicated.
                if ((service != null) &&
                    (m_refToObjMap.get(event.getServiceReference()) == null))
                {
                    // Add to the reference list.
                    m_refList.add(event.getServiceReference());
                    // Map reference to service object for easy look up.
                    m_refToObjMap.put(event.getServiceReference(), service);

                    // Register spell checker service if necessary.
                    if (m_reg == null)
                    {
                        m_reg = m_context.registerService(
                            SpellChecker.class.getName(),
                            new SpellCheckerImpl(), null);
                    }
                }
                else if (service != null)
                {
                    m_context.ungetService(event.getServiceReference());
                }
            }
            // Remove the departing service from the service list.
            else if (event.getType() == ServiceEvent.UNREGISTERING)
            {
                // Make sure the service is in the list.
                if (m_refToObjMap.get(event.getServiceReference()) != null)
                {
                    // Unget the service object.
                    m_context.ungetService(event.getServiceReference());
                    // Remove service reference.
                    m_refList.remove(event.getServiceReference());
                    // Remove service reference from map.
                    m_refToObjMap.remove(event.getServiceReference());

                    // If there are no more dictionary services,
                    // then unregister spell checker service.
                    if (m_refList.size() == 0)
                    {
                        m_reg.unregister();
                        m_reg = null;
                    }
                }
            }
        }
    }

    /**
     * A private inner class that implements a spell checker service;
     * see SpellChecker for details of the service.
    **/
    private class SpellCheckerImpl implements SpellChecker
    {
        /**
         * Implements SpellChecker.check(). Checks the
         * given passage for misspelled words.
         * @param passage the passage to spell check.
         * @return An array of misspelled words or null if no
         *         words are misspelled.
        **/
        public String[] check(String passage)
        {
            // No misspelled words for an empty string.
            if ((passage == null) || (passage.length() == 0))
            {
                return null;
            }

            ArrayList errorList = new ArrayList();

            // Tokenize the passage using spaces and punctionation.
            StringTokenizer st = new StringTokenizer(passage, " ,.!?;:");

            // Lock the service list.
            synchronized (m_refList)
            {
                // Loop through each word in the passage.
                while (st.hasMoreTokens())
                {
                    String word = st.nextToken();

                    boolean correct = false;

                    // Check each available dictionary for the current word.
                    for (int i = 0; (!correct) && (i < m_refList.size()); i++)
                    {
                        DictionaryService dictionary =
                            (DictionaryService) m_refToObjMap.get(m_refList.get(i));

                        if (dictionary.checkWord(word))
                        {
                            correct = true;
                        }
                    }

                    // If the word is not correct, then add it
                    // to the incorrect word list.
                    if (!correct)
                    {
                        errorList.add(word);
                    }
                }
            }

            // Return null if no words are incorrect.
            if (errorList.size() == 0)
            {
                return null;
            }

            // Return the array of incorrect words.
            return (String[]) errorList.toArray(new String[errorList.size()]);
        }
    }
}
----

Note that we do not need to unregister the service in stop() method, because the OSGi framework will automatically do so for us.
The spell checker service that we have implemented is very simple;
it simply parses a given passage into words and then loops through all available dictionary services for each word until it determines that the word is correct.
Any incorrect words are added to an error list that will be returned to the caller.
This solution is not optimal and is only intended for educational purposes.
Next, we create a `manifest.mf` file that contains the meta-data for our bundle:

 Bundle-Name: Spell checker service
 Bundle-Description: A bundle that implements a simple spell checker service
 Bundle-Vendor: Richard Hall
 Bundle-Version: 1.0.0
 Bundle-Activator: tutorial.example6.Activator
 Export-Package: tutorial.example6.service
 Import-Package: org.osgi.framework,
  tutorial.example2.service

We specify which class used to activate the bundle via the `Bundle-Activator` attribute.
Our bundle exports the spell checker service interface using the `Export-Package` attribute and imports the OSGi core framework and dictionary service interface packages using the `Import-Package` attribute.
(Note: Make sure your manifest file ends in a trailing carriage return or else the last line will be ignored.)

To compile our source, we need to have the `felix.jar` file (found in Felix' `bin` directory) and the example2.jar file in our class path.
We compile the source file using a command like:

 javac -d c:\classes *.java

This command compiles all source files and outputs the generated classes into a subdirectory of the `c:\classes` directory;
this subdirectory is `tutorial\example6`, named after the package we specified in the source file.
For the above command to work, the `c:\classes` directory must exist.
After compiling, we need to create a JAR file containing the generated package directories.
We will also add our manifest file that contains the bundle's meta-data to the JAR file.
To create the JAR file, we issue the command:

 jar cfm example6.jar manifest.mf -C c:\classes tutorial\example6

This command creates a JAR file using the manifest file we created and includes all of the classes in the `tutorial\example6` directory inside of the `c:\classes` directory.
Once the JAR file is created, we are ready to install and start the bundle.

To run Felix, we follow the instructions described in usage.html.
When we start Felix, it asks for a profile name, we will put all of our bundles in a profile named `tutorial`.
After running Felix, we should stop all tutorial bundles except for the service bundles.
Use the `lb` command to make sure that only the bundles from Example 2 and Example 2b are active;
use the `start` and `stop` commands as appropriate to start and stop the various tutorial bundles, respectively.
(Note: Felix uses some bundles to provide its command shell, so do not stop these bundles.) Now we can install and start our spell checker service bundle.
Assuming that we created our bundle in the directory `c:\tutorial`, we can install and start it in Felix' shell using the following command:

 start file:/c:/tutorial/example6.jar

The above command installs and starts the bundle in a single step;
it is also possible to install and start the bundle in two steps by using the Felix `install` and `start` shell commands.
To stop the bundle, use the Felix `stop` shell command.
Using the Felix shell `lb` command to get the bundle identifier number for our spell checker service bundle and we can stop and restart it at will using the `stop` and `start` commands, respectively.
Using the `services` command, we can see which services are currently available in the OSGi framework, including our dictionary and spell checker services.
We can experiment with our spell checker service's dynamic availability by stopping the dictionary service bundles;
when both dictionary services are stopped, the `services` command will reveal that our bundle is no longer offering its spell checker service.
Likewise, when the dictionary services comeback, so will our spell checker service.
We create a client for our spell checker service in Example 7.
To exit Felix, we use the `shutdown` command.
