/*
 * Copyright, 2010, Nico Schmoigl: 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
 * <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>.
 * 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.
 * Origin: http://blog.schmoigl-online.de
 */
package tutorial.example6var;

import java.util.Properties;
import java.util.StringTokenizer;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
import tutorial.example2.service.DictionaryService;

public class Activator implements BundleActivator {
    // Bundle's context.
    private BundleContext m_context = null;
    // The service tacker object.
    private ServiceTracker m_tracker = null;

    /**
     * start routine for the Bundle
     * @param arg0 reference to the BundleContext in which this bundle should run
     * @throws java.lang.Exception may throw any exception
     */
    public void start(BundleContext context) throws Exception {
        this.m_context = context;

        // Create a service tracker to monitor dictionary services.
        m_tracker = new ServiceTracker(
            m_context,
            m_context.createFilter(
                "(&" +
                    "(objectClass=" + DictionaryService.class.getName() + ")" +
                    "(Language=*)" +
                    "(!(Language=Meta))" +
                 ")"),
            null);
        m_tracker.open();

        Properties props = new Properties();
        props.put("Language", "Meta");

        m_context.registerService(DictionaryService.class.getName(), new MetaSpellChecker(), props);
        
    }

    /**
     * Implements BundleActivator.stop(). Does nothing since
     * the framework will automatically unget any used services.
     * @param context the framework context for the bundle.
    **/
    public void stop(BundleContext context)
    {
    }

    /**
     * implementation of another DictionaryService which forwards its requests
     * to all currently registered DictionaryServices and asks if in their
     * language the word is valid. As soon as one DictionaryService provides
     * a positive response, also the result of the check of this DictionaryService
     * is positive.
     */
    public class MetaSpellChecker implements tutorial.example2.service.DictionaryService {
        /**
         * checks the validity of a word; now could also supports multiple words
         * within the same string
         * @param word the word or the words to check
         * @return true, if all words are checked positively by at least one
         * available DictionaryService; false otherwise
         */
        public boolean checkWord(String word) {

            // No misspelled words for an empty string.
            if ((word == null) || (word.length() == 0)) {
                return true;
            }

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

            // get the list of all available spell checker services
            Object[] spellchecker_objects = m_tracker.getServices();

            // safety checks
            if ( (spellchecker_objects == null) || (spellchecker_objects.length == 0) )
                return false;

            // iterate over all words in the input string
            while (st.hasMoreTokens()) {
                // fetch the single word
                String singleWord = st.nextToken();

                boolean found = false;
                // take the list of available DictionaryServices
                for (Object o : spellchecker_objects) {
                    // safety: if that DictionaryService is not a valid reference: skip it
                    if (o == null)
                        continue;

                    // convert the object
                    DictionaryService ds = (DictionaryService) o;
                    // trigger the check
                    if (ds.checkWord(singleWord))  {
                        // the single word is valid and we may skip asking
                        // all further DictionaryServices
                        found = true;
                        break;
                    }
                }

                // if at least one word could not be found to be valid,
                // answer with a negative result
                if (!found)
                    return false;
            }
            // all words must be checked positively; answer with a positive result
            return true;
        }

    }
}