Update ooo320-m1
[ooovba.git] / odk / examples / DevelopersGuide / OfficeDev / Linguistic / SampleSpellChecker.java
blob4251887f6d710e6881d35b4c11d4ba5684becac4
1 /*************************************************************************
3 * $RCSfile: SampleSpellChecker.java,v $
5 * $Revision: 1.3 $
7 * last change: $Author: hr $ $Date: 2003-06-30 15:41:09 $
9 * The Contents of this file are made available subject to the terms of
10 * the BSD license.
12 * Copyright (c) 2003 by Sun Microsystems, Inc.
13 * All rights reserved.
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. Neither the name of Sun Microsystems, Inc. nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
31 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
34 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
36 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *************************************************************************/
41 // uno
42 import com.sun.star.lib.uno.helper.ComponentBase;
43 import com.sun.star.uno.UnoRuntime;
45 // factories
46 import com.sun.star.lang.XMultiServiceFactory;
47 import com.sun.star.lang.XSingleServiceFactory;
49 // supported Interfaces
50 import com.sun.star.linguistic2.XSpellChecker;
51 import com.sun.star.linguistic2.XLinguServiceEventBroadcaster;
52 import com.sun.star.lang.XInitialization;
53 import com.sun.star.lang.XComponent;
54 import com.sun.star.lang.XServiceInfo;
55 import com.sun.star.lang.XServiceDisplayName;
57 // Exceptions
58 import com.sun.star.uno.Exception;
59 import com.sun.star.uno.RuntimeException;
60 import com.sun.star.lang.IllegalArgumentException;
62 //used Interfaces
63 import com.sun.star.linguistic2.XLinguServiceEventListener;
64 import com.sun.star.linguistic2.XSpellAlternatives;
65 import com.sun.star.linguistic2.SpellFailure;
66 import com.sun.star.lang.Locale;
67 import com.sun.star.lang.XEventListener;
68 import com.sun.star.lang.EventObject;
69 import com.sun.star.beans.XPropertySet;
70 import com.sun.star.beans.PropertyValue;
71 import com.sun.star.uno.AnyConverter;
72 import com.sun.star.lang.XTypeProvider;
73 import com.sun.star.uno.XInterface;
74 import com.sun.star.uno.Type;
76 import java.util.ArrayList;
78 public class SampleSpellChecker extends ComponentBase implements
79 XSpellChecker,
80 XLinguServiceEventBroadcaster,
81 XInitialization,
82 XServiceDisplayName,
83 XServiceInfo
85 PropChgHelper_Spell aPropChgHelper;
86 ArrayList aEvtListeners;
87 boolean bDisposing;
89 public SampleSpellChecker()
91 // names of relevant properties to be used
92 String[] aProps = new String[]
94 "IsIgnoreControlCharacters",
95 "IsUseDictionaryList",
96 "IsGermanPreReform",
97 "IsSpellUpperCase",
98 "IsSpellWithDigits",
99 "IsSpellCapitalization"
101 aPropChgHelper = new PropChgHelper_Spell( (XSpellChecker) this, aProps );
102 aEvtListeners = new ArrayList();
103 bDisposing = false;
106 private boolean IsEqual( Locale aLoc1, Locale aLoc2 )
108 return aLoc1.Language.equals( aLoc2.Language ) &&
109 aLoc1.Country .equals( aLoc2.Country ) &&
110 aLoc1.Variant .equals( aLoc2.Variant );
113 private boolean GetValueToUse(
114 String aPropName,
115 boolean bDefaultVal,
116 PropertyValue[] aProps )
118 boolean bRes = bDefaultVal;
122 // use temporary value if supplied
123 for (int i = 0; i < aProps.length; ++i)
125 if (aPropName.equals( aProps[i].Name ))
127 Object aObj = aProps[i].Value;
128 if (AnyConverter.isBoolean( aObj ))
130 bRes = AnyConverter.toBoolean( aObj );
131 return bRes;
136 // otherwise use value from property set (if available)
137 XPropertySet xPropSet = aPropChgHelper.GetPropSet();
138 if (xPropSet != null) // should always be the case
140 Object aObj = xPropSet.getPropertyValue( aPropName );
141 if (AnyConverter.isBoolean( aObj ))
142 bRes = AnyConverter.toBoolean( aObj );
145 catch (Exception e) {
146 bRes = bDefaultVal;
149 return bRes;
152 private boolean IsUpper( String aWord, Locale aLocale )
154 java.util.Locale aLang = new java.util.Locale(
155 aLocale.Language, aLocale.Country, aLocale.Variant );
156 return aWord.equals( aWord.toUpperCase( aLang ) );
159 private boolean HasDigits( String aWord )
161 int nLen = aWord.length();
162 for (int i = 0; i < nLen; ++i)
164 if (Character.isDigit( aWord.charAt(i) ))
165 return true;
167 return false;
170 private short GetSpellFailure(
171 String aWord,
172 Locale aLocale,
173 PropertyValue[] aProperties )
175 short nRes = -1;
177 //!! This code needs to be replaced by code calling the actual
178 //!! implementation of your spellchecker
179 boolean bIsGermanPreReform = GetValueToUse( "IsGermanPreReform", false, aProperties );
180 if (IsEqual( aLocale, new Locale( "de", "DE", "" ) ))
182 if (bIsGermanPreReform && aWord.equals( "Schifffahrt" ))
183 nRes = SpellFailure.SPELLING_ERROR;
184 else if (!bIsGermanPreReform && aWord.equals( "Schiffahrt" ))
185 nRes = SpellFailure.SPELLING_ERROR;
187 else if (IsEqual( aLocale, new Locale( "en", "US", "" ) ))
189 // words with 'u', 'U' and 'arizona' are defined to be incorrect
190 boolean bIsValid = !(aWord.indexOf( "u" ) != -1 || aWord.indexOf( "U" ) != -1)
191 && !aWord.equals( "arizona" );
193 if (!bIsValid)
195 // default value (no other SpellFailure type is applicable)
196 nRes = SpellFailure.SPELLING_ERROR;
198 if (aWord.equals( "arizona" ))
199 nRes = SpellFailure.CAPTION_ERROR;
200 else if (aWord.equals( "house" ))
201 nRes = SpellFailure.SPELLING_ERROR;
202 else if (aWord.equals( "course" ))
203 nRes = SpellFailure.IS_NEGATIVE_WORD;
207 return nRes;
210 private XSpellAlternatives GetProposals(
211 String aWord,
212 Locale aLocale,
213 PropertyValue[] aProperties )
215 short nType = SpellFailure.SPELLING_ERROR;
216 String[] aProposals = null;
218 // get values of relevant properties that may be used.
219 //! The values for 'IsIgnoreControlCharacters' and 'IsUseDictionaryList'
220 //! are handled by the dispatcher! Thus there is no need to access
221 //! them here.
222 boolean bIsGermanPreReform = GetValueToUse( "IsGermanPreReform", false, aProperties );
223 boolean bIsSpellWithDigits = GetValueToUse( "IsSpellWithDigits", false, aProperties );
224 boolean bIsSpellUpperCase = GetValueToUse( "IsSpellUpperCase", false, aProperties );
225 boolean bIsSpellCapitalization = GetValueToUse( "IsSpellCapitalization", true, aProperties );
227 //!! This code needs to be replaced by code calling the actual
228 //!! implementation of your spellchecker
229 if (IsEqual( aLocale, new Locale( "de", "DE", "" ) ))
231 if (bIsGermanPreReform && aWord.equals( "Schifffahrt" ))
233 nType = SpellFailure.SPELLING_ERROR;
234 aProposals = new String[]{ "Schiffahrt" };
236 else if (!bIsGermanPreReform && aWord.equals( "Schiffahrt" ))
238 nType = SpellFailure.SPELLING_ERROR;
239 aProposals = new String[]{ "Schifffahrt" };
242 else if (IsEqual( aLocale, new Locale( "en", "US", "" ) ))
244 if (aWord.equals( "arizona" ))
246 nType = SpellFailure.CAPTION_ERROR;
247 aProposals = new String[]{ "Arizona" };
249 else if (aWord.equals( "house" ))
251 nType = SpellFailure.SPELLING_ERROR;
252 aProposals = new String[]{ "horse", "home" };
254 else if (aWord.equals( "course" ))
256 nType = SpellFailure.IS_NEGATIVE_WORD;
257 aProposals = new String[]{ "line", "plan", "approach" };
261 // always return a result if word is incorrect,
262 // proposals may be empty though.
263 return new XSpellAlternatives_impl( aWord, aLocale,
264 nType, aProposals );
267 // __________ interface methods __________
270 //*****************
271 //XSupportedLocales
272 //*****************
273 public Locale[] getLocales()
274 throws com.sun.star.uno.RuntimeException
276 Locale aLocales[] =
278 new Locale( "de", "DE", "" ),
279 new Locale( "en", "US", "" )
282 return aLocales;
285 public boolean hasLocale( Locale aLocale )
286 throws com.sun.star.uno.RuntimeException
288 boolean bRes = false;
289 if ( IsEqual( aLocale, new Locale( "de", "DE", "" ) ) ||
290 IsEqual( aLocale, new Locale( "en", "US", "" ) ))
291 bRes = true;
292 return bRes;
296 //*************
297 //XSpellChecker
298 //*************
299 public boolean isValid(
300 String aWord, Locale aLocale,
301 PropertyValue[] aProperties )
302 throws com.sun.star.uno.RuntimeException,
303 IllegalArgumentException
305 if (IsEqual( aLocale, new Locale() ) || aWord.length() == 0)
306 return true;
308 // linguistic is currently not allowed to throw exceptions
309 // thus we return null which means 'word cannot be spelled'
310 if (!hasLocale( aLocale ))
311 return true;
313 // get values of relevant properties that may be used.
314 //! The values for 'IsIgnoreControlCharacters' and 'IsUseDictionaryList'
315 //! are handled by the dispatcher! Thus there is no need to access
316 //! them here.
317 boolean bIsGermanPreReform = GetValueToUse( "IsGermanPreReform", false, aProperties );
318 boolean bIsSpellWithDigits = GetValueToUse( "IsSpellWithDigits", false, aProperties );
319 boolean bIsSpellUpperCase = GetValueToUse( "IsSpellUpperCase", false, aProperties );
320 boolean bIsSpellCapitalization = GetValueToUse( "IsSpellCapitalization", true, aProperties );
322 short nFailure = GetSpellFailure( aWord, aLocale, aProperties );
323 if (nFailure != -1)
325 // postprocess result for errors that should be ignored
326 if ( (!bIsSpellUpperCase && IsUpper( aWord, aLocale ))
327 || (!bIsSpellWithDigits && HasDigits( aWord ))
328 || (!bIsSpellCapitalization
329 && nFailure == SpellFailure.CAPTION_ERROR)
331 nFailure = -1;
334 return nFailure == -1;
338 public XSpellAlternatives spell(
339 String aWord, Locale aLocale,
340 PropertyValue[] aProperties )
341 throws com.sun.star.uno.RuntimeException,
342 IllegalArgumentException
344 if (IsEqual( aLocale, new Locale() ) || aWord.length() == 0)
345 return null;
347 // linguistic is currently not allowed to throw exceptions
348 // thus we return null fwhich means 'word cannot be spelled'
349 if (!hasLocale( aLocale ))
350 return null;
352 XSpellAlternatives xRes = null;
353 if (!isValid( aWord, aLocale, aProperties ))
355 xRes = GetProposals( aWord, aLocale, aProperties );
357 return xRes;
361 //*****************************
362 //XLinguServiceEventBroadcaster
363 //*****************************
364 public boolean addLinguServiceEventListener (
365 XLinguServiceEventListener xLstnr )
366 throws com.sun.star.uno.RuntimeException
368 boolean bRes = false;
369 if (!bDisposing && xLstnr != null)
370 bRes = aPropChgHelper.addLinguServiceEventListener( xLstnr );
371 return bRes;
374 public boolean removeLinguServiceEventListener(
375 XLinguServiceEventListener xLstnr )
376 throws com.sun.star.uno.RuntimeException
378 boolean bRes = false;
379 if (!bDisposing && xLstnr != null)
380 bRes = aPropChgHelper.removeLinguServiceEventListener( xLstnr );
381 return bRes;
384 //********************
385 // XServiceDisplayName
386 //********************
387 public String getServiceDisplayName( Locale aLocale )
388 throws com.sun.star.uno.RuntimeException
390 return "Java Samples";
393 //****************
394 // XInitialization
395 //****************
396 public void initialize( Object[] aArguments )
397 throws com.sun.star.uno.Exception,
398 com.sun.star.uno.RuntimeException
400 int nLen = aArguments.length;
401 if (2 == nLen)
403 XPropertySet xPropSet = (XPropertySet)UnoRuntime.queryInterface(
404 XPropertySet.class, aArguments[0]);
405 // start listening to property changes
406 aPropChgHelper.AddAsListenerTo( xPropSet );
410 //*************
411 // XServiceInfo
412 //*************
413 public boolean supportsService( String aServiceName )
414 throws com.sun.star.uno.RuntimeException
416 String[] aServices = getSupportedServiceNames_Static();
417 int i, nLength = aServices.length;
418 boolean bResult = false;
420 for( i = 0; !bResult && i < nLength; ++i )
421 bResult = aServiceName.equals( aServices[ i ] );
423 return bResult;
426 public String getImplementationName()
427 throws com.sun.star.uno.RuntimeException
429 return _aSvcImplName;
432 public String[] getSupportedServiceNames()
433 throws com.sun.star.uno.RuntimeException
435 return getSupportedServiceNames_Static();
438 // __________ static things __________
440 public static String _aSvcImplName = "com.sun.star.linguistic2.JavaSamples.SampleSpellChecker";
442 public static String[] getSupportedServiceNames_Static()
444 String[] aResult = { "com.sun.star.linguistic2.SpellChecker" };
445 return aResult;
450 * Returns a factory for creating the service.
451 * This method is called by the <code>JavaLoader</code>
452 * <p>
453 * @return returns a <code>XSingleServiceFactory</code> for creating the component
454 * @param implName the name of the implementation for which a service is desired
455 * @param multiFactory the service manager to be used if needed
456 * @param regKey the registryKey
457 * @see com.sun.star.comp.loader.JavaLoader
459 public static XSingleServiceFactory __getServiceFactory(
460 String aImplName,
461 XMultiServiceFactory xMultiFactory,
462 com.sun.star.registry.XRegistryKey xRegKey )
464 XSingleServiceFactory xSingleServiceFactory = null;
465 if( aImplName.equals( _aSvcImplName ) )
467 xSingleServiceFactory = new OneInstanceFactory(
468 SampleSpellChecker.class, _aSvcImplName,
469 getSupportedServiceNames_Static(),
470 xMultiFactory );
472 return xSingleServiceFactory;
476 * Writes the service information into the given registry key.
477 * This method is called by the <code>JavaLoader</code>
478 * <p>
479 * @return returns true if the operation succeeded
480 * @param xRegKey the registryKey
481 * @see com.sun.star.comp.loader.JavaLoader
483 public static boolean __writeRegistryServiceInfo(
484 com.sun.star.registry.XRegistryKey xRegKey )
486 boolean bResult = true;
487 String[] aServices = getSupportedServiceNames_Static();
488 int i, nLength = aServices.length;
489 for( i = 0; i < nLength; ++i )
491 bResult = bResult && com.sun.star.comp.loader.FactoryHelper.writeRegistryServiceInfo(
492 _aSvcImplName, aServices[i], xRegKey );
494 return bResult;