| /* |
| * Copyright 2006 The Apache Software Foundation |
| * |
| * 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. |
| * |
| */ |
| package org.apache.felix.examples.spellcheckservice.impl; |
| |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.StringTokenizer; |
| |
| import org.apache.felix.examples.dictionaryservice.DictionaryService; |
| import org.apache.felix.examples.spellcheckservice.SpellCheckService; |
| |
| import org.osgi.framework.BundleActivator; |
| import org.osgi.framework.BundleContext; |
| import org.osgi.framework.ServiceEvent; |
| import org.osgi.framework.ServiceListener; |
| import org.osgi.framework.ServiceReference; |
| import org.osgi.framework.ServiceRegistration; |
| |
| |
| /** |
| * This class implements a bundle that implements a spell check service. The |
| * spell check 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 |
| * check service is only registered if there are dictionary services available, |
| * thus the spell check service will appear and disappear as dictionary services |
| * appear and disappear, respectively. |
| * |
| * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a> |
| */ |
| 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 check 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 check service is |
| * registered. |
| * |
| * @param context the framework context for the bundle. |
| */ |
| public void start( BundleContext context ) throws Exception |
| { |
| m_context = context; |
| |
| // 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 ) |
| { |
| // Lock the list. |
| synchronized ( m_refList ) |
| { |
| 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 check service if there are any dictionary services. |
| if ( m_refList.size() > 0 ) |
| { |
| m_reg = m_context.registerService( SpellCheckService.class.getName(), |
| new SpellCheckServiceImpl(), 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 check service is registered. |
| * As soon as any dictionary spell check becomes available, the spell check |
| * service is reregistered. |
| * |
| * @param event the fired service event. |
| */ |
| public void serviceChanged( ServiceEvent event ) |
| { |
| // Add the new dictionary service to the service list. |
| if ( event.getType() == ServiceEvent.REGISTERED ) |
| { |
| synchronized ( m_refList ) |
| { |
| // 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 check service if necessary. |
| if ( m_reg == null ) |
| { |
| m_reg = m_context.registerService( SpellCheckService.class.getName(), |
| new SpellCheckServiceImpl(), null ); |
| } |
| } |
| else if ( service != null ) |
| { |
| m_context.ungetService( event.getServiceReference() ); |
| } |
| } |
| } |
| // Remove the departing service from the service list. |
| else if ( event.getType() == ServiceEvent.UNREGISTERING ) |
| { |
| synchronized ( m_refList ) |
| { |
| // 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 check service. |
| if ( m_refList.size() == 0 ) |
| { |
| m_reg.unregister(); |
| m_reg = null; |
| } |
| } |
| } |
| } |
| } |
| |
| |
| /** |
| * A private inner class that implements a spell check service; see |
| * SpellCheckService for details of the service. |
| */ |
| private class SpellCheckServiceImpl implements SpellCheckService |
| { |
| /** |
| * Implements SpellCheckService.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()] ); |
| } |
| } |
| } |