1 /************************************************************************* 2 * 3 * The Contents of this file are made available subject to the terms of 4 * the BSD license. 5 * 6 * Copyright 2000, 2010 Oracle and/or its affiliates. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of Sun Microsystems, Inc. nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 28 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 30 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 31 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * 33 *************************************************************************/ 34 35 // uno 36 import com.sun.star.lib.uno.helper.ComponentBase; 37 import com.sun.star.uno.UnoRuntime; 38 39 // factories 40 import com.sun.star.lang.XMultiServiceFactory; 41 import com.sun.star.lang.XSingleServiceFactory; 42 43 // supported Interfaces 44 import com.sun.star.linguistic2.XHyphenator; 45 import com.sun.star.linguistic2.XLinguServiceEventBroadcaster; 46 import com.sun.star.lang.XInitialization; 47 import com.sun.star.lang.XComponent; 48 import com.sun.star.lang.XServiceInfo; 49 import com.sun.star.lang.XServiceDisplayName; 50 51 // Exceptions 52 import com.sun.star.uno.Exception; 53 import com.sun.star.uno.RuntimeException; 54 import com.sun.star.lang.IllegalArgumentException; 55 56 //used Interfaces 57 import com.sun.star.linguistic2.XLinguServiceEventListener; 58 import com.sun.star.linguistic2.XHyphenatedWord; 59 import com.sun.star.linguistic2.XPossibleHyphens; 60 import com.sun.star.lang.Locale; 61 import com.sun.star.lang.XEventListener; 62 import com.sun.star.lang.EventObject; 63 import com.sun.star.beans.XPropertySet; 64 import com.sun.star.beans.PropertyValue; 65 import com.sun.star.uno.AnyConverter; 66 import com.sun.star.lang.XTypeProvider; 67 import com.sun.star.uno.XInterface; 68 import com.sun.star.uno.Type; 69 70 import java.util.ArrayList; 71 72 public class SampleHyphenator extends ComponentBase implements 73 XHyphenator, 74 XLinguServiceEventBroadcaster, 75 XInitialization, 76 XServiceDisplayName, 77 XServiceInfo 78 { 79 PropChgHelper_Hyph aPropChgHelper; 80 ArrayList aEvtListeners; 81 boolean bDisposing; 82 83 public SampleHyphenator() 84 { 85 // names of relevant properties to be used 86 String[] aProps = new String[] 87 { 88 "IsIgnoreControlCharacters", 89 "IsUseDictionaryList", 90 "IsGermanPreReform", 91 "HyphMinLeading", 92 "HyphMinTrailing", 93 "HyphMinWordLength" 94 }; 95 aPropChgHelper = new PropChgHelper_Hyph( (XHyphenator) this, aProps ); 96 aEvtListeners = new ArrayList();; 97 bDisposing = false; 98 } 99 100 private boolean IsEqual( Locale aLoc1, Locale aLoc2 ) 101 { 102 return aLoc1.Language.equals( aLoc2.Language ) && 103 aLoc1.Country .equals( aLoc2.Country ) && 104 aLoc1.Variant .equals( aLoc2.Variant ); 105 } 106 107 private boolean GetValueToUse( 108 String aPropName, 109 boolean bDefaultVal, 110 PropertyValue[] aProps ) 111 { 112 boolean bRes = bDefaultVal; 113 114 try 115 { 116 // use temporary value if supplied 117 for (int i = 0; i < aProps.length; ++i) 118 { 119 if (aPropName.equals( aProps[i].Name )) 120 { 121 Object aObj = aProps[i].Value; 122 if (AnyConverter.isBoolean( aObj )) 123 { 124 bRes = AnyConverter.toBoolean( aObj ); 125 return bRes; 126 } 127 } 128 } 129 130 // otherwise use value from property set (if available) 131 XPropertySet xPropSet = aPropChgHelper.GetPropSet(); 132 if (xPropSet != null) // should always be the case 133 { 134 Object aObj = xPropSet.getPropertyValue( aPropName ); 135 if (AnyConverter.isBoolean( aObj )) 136 bRes = AnyConverter.toBoolean( aObj ); 137 } 138 } 139 catch (Exception e) { 140 bRes = bDefaultVal; 141 } 142 143 return bRes; 144 } 145 146 private short GetValueToUse( 147 String aPropName, 148 short nDefaultVal, 149 PropertyValue[] aProps ) 150 { 151 short nRes = nDefaultVal; 152 153 try 154 { 155 // use temporary value if supplied 156 for (int i = 0; i < aProps.length; ++i) 157 { 158 if (aPropName.equals( aProps[i].Name )) 159 { 160 Object aObj = aProps[i].Value; 161 if (AnyConverter.isShort( aObj )) 162 { 163 nRes = AnyConverter.toShort( aObj ); 164 return nRes; 165 } 166 } 167 } 168 169 // otherwise use value from property set (if available) 170 XPropertySet xPropSet = aPropChgHelper.GetPropSet(); 171 if (xPropSet != null) // should always be the case 172 { 173 Object aObj = xPropSet.getPropertyValue( aPropName ); 174 if (AnyConverter.isShort( aObj )) 175 nRes = AnyConverter.toShort( aObj ); 176 } 177 } 178 catch (Exception e) { 179 nRes = nDefaultVal; 180 } 181 182 return nRes; 183 } 184 185 // __________ interface methods __________ 186 187 188 //***************** 189 //XSupportedLocales 190 //***************** 191 public Locale[] getLocales() 192 throws com.sun.star.uno.RuntimeException 193 { 194 Locale aLocales[] = 195 { 196 new Locale( "de", "DE", "" ), 197 new Locale( "en", "US", "" ) 198 }; 199 200 return aLocales; 201 } 202 203 public boolean hasLocale( Locale aLocale ) 204 throws com.sun.star.uno.RuntimeException 205 { 206 boolean bRes = false; 207 if ( IsEqual( aLocale, new Locale( "de", "DE", "" ) ) || 208 IsEqual( aLocale, new Locale( "en", "US", "" ) )) 209 bRes = true; 210 return bRes; 211 } 212 213 //*********** 214 //XHyphenator 215 //*********** 216 public XHyphenatedWord hyphenate( 217 String aWord, Locale aLocale, 218 short nMaxLeading, PropertyValue[] aProperties ) 219 throws com.sun.star.uno.RuntimeException, 220 IllegalArgumentException 221 { 222 if (IsEqual( aLocale, new Locale() ) || aWord.length() == 0) 223 return null; 224 225 // linguistic is currently not allowed to throw exceptions 226 // thus we return null fwhich means 'word cannot be hyphenated' 227 if (!hasLocale( aLocale )) 228 return null; 229 230 // get values of relevant properties that may be used. 231 //! The values for 'IsIgnoreControlCharacters' and 'IsUseDictionaryList' 232 //! are handled by the dispatcher! Thus there is no need to access 233 //! them here. 234 boolean bIsIgnoreControlCharacters = GetValueToUse( "IsIgnoreControlCharacters", true, aProperties ); 235 boolean bIsUseDictionaryList = GetValueToUse( "IsUseDictionaryList", true, aProperties ); 236 boolean bIsGermanPreReform = GetValueToUse( "IsGermanPreReform", false, aProperties ); 237 short nHyphMinLeading = GetValueToUse( "HyphMinLeading", (short)2, aProperties ); 238 short nHyphMinTrailing = GetValueToUse( "HyphMinTrailing", (short)2, aProperties ); 239 short nHyphMinWordLen = GetValueToUse( "HyphMinWordLength", (short)5, aProperties ); 240 241 XHyphenatedWord xRes = null; 242 243 if (aWord.length() >= nHyphMinWordLen) 244 { 245 String aHyphenatedWord = aWord; 246 short nHyphenationPos = -1; 247 short nHyphenPos = -1; 248 249 //!! This code needs to be replaced by code calling the actual 250 //!! implementation of your hyphenator 251 if (IsEqual( aLocale, new Locale( "de", "DE", "" ) ) ) 252 { 253 if (bIsGermanPreReform && aWord.equals( "Schiffahrt" )) 254 { 255 // Note: there is only one position where the word 256 // can be hyphenated... 257 258 aHyphenatedWord = "Schifffahrt"; 259 nHyphenationPos = 4; 260 nHyphenPos = 5; 261 } 262 else if (!bIsGermanPreReform && aWord.equals( "Schifffahrt" )) 263 { 264 nHyphenationPos = nHyphenPos = 5; 265 } 266 } 267 else if (IsEqual( aLocale, new Locale( "en", "US", "" ) ) ) 268 { 269 int nLast = aWord.length() - 1 - nHyphMinTrailing; 270 271 if ( aWord.equals( "waterfall" ) ) 272 { 273 if (4 <= nLast) 274 nHyphenationPos = nHyphenPos = 4; 275 else 276 nHyphenationPos = nHyphenPos = 1; 277 } 278 else if ( aWord.equals( "driving" ) ) 279 { 280 nHyphenationPos = nHyphenPos = 3; 281 } 282 } 283 284 // check if hyphenation pos is valid, 285 // a value of -1 indicates that hyphenation is not possible 286 if ( nHyphenationPos != -1 && 287 !(nHyphenationPos < nHyphMinLeading) && 288 !(nHyphenationPos >= aWord.length() - nHyphMinTrailing)) 289 { 290 xRes = new XHyphenatedWord_impl(aWord, aLocale, 291 nHyphenationPos, aHyphenatedWord, nHyphenPos); 292 } 293 } 294 return xRes; 295 } 296 297 public XHyphenatedWord queryAlternativeSpelling( 298 String aWord, Locale aLocale, 299 short nIndex, PropertyValue[] aProperties ) 300 throws com.sun.star.uno.RuntimeException, 301 IllegalArgumentException 302 { 303 if (IsEqual( aLocale, new Locale() ) || aWord.length() == 0) 304 return null; 305 306 // linguistic is currently not allowed to throw exceptions 307 // thus we return null which means 'word cannot be hyphenated' 308 if (!hasLocale( aLocale )) 309 return null; 310 311 // get values of relevant properties that may be used. 312 //! The values for 'IsIgnoreControlCharacters' and 'IsUseDictionaryList' 313 //! are handled by the dispatcher! Thus there is no need to access 314 //! them here. 315 boolean bIsIgnoreControlCharacters = GetValueToUse( "IsIgnoreControlCharacters", true, aProperties ); 316 boolean bIsUseDictionaryList = GetValueToUse( "IsUseDictionaryList", true, aProperties ); 317 boolean bIsGermanPreReform = GetValueToUse( "IsGermanPreReform", false, aProperties ); 318 short nHyphMinLeading = GetValueToUse( "HyphMinLeading", (short)2, aProperties ); 319 short nHyphMinTrailing = GetValueToUse( "HyphMinTrailing", (short)2, aProperties ); 320 short nHyphMinWordLen = GetValueToUse( "HyphMinWordLength", (short)5, aProperties ); 321 322 XHyphenatedWord xRes = null; 323 324 //!! This code needs to be replaced by code calling the actual 325 //!! implementation of your hyphenator 326 if ( IsEqual( aLocale, new Locale( "de", "DE", "" ) ) ) 327 { 328 // there is an alternative spelling only when the 329 // word is hyphenated between the "ff" and old german spelling 330 // is set. 331 if (aWord.equals( "Schiffahrt" ) && 332 bIsGermanPreReform && nIndex == 4) 333 { 334 xRes = new XHyphenatedWord_impl(aWord, aLocale, 335 (short)4, "Schifffahrt", (short)5 ); 336 } 337 } 338 else if ( IsEqual( aLocale, new Locale( "en", "US", "" ) ) ) 339 { 340 // There are no alternative spellings in the English language 341 } 342 343 return xRes; 344 } 345 346 public XPossibleHyphens createPossibleHyphens( 347 String aWord, Locale aLocale, 348 PropertyValue[] aProperties ) 349 throws com.sun.star.uno.RuntimeException, 350 IllegalArgumentException 351 { 352 if (IsEqual( aLocale, new Locale() ) || aWord.length() == 0) 353 return null; 354 355 // linguistic is currently not allowed to throw exceptions 356 // thus we return null which means 'word cannot be hyphenated' 357 if (!hasLocale( aLocale )) 358 return null; 359 360 // get values of relevant properties that may be used. 361 //! The values for 'IsIgnoreControlCharacters' and 'IsUseDictionaryList' 362 //! are handled by the dispatcher! Thus there is no need to access 363 //! them here. 364 boolean bIsIgnoreControlCharacters = GetValueToUse( "IsIgnoreControlCharacters", true, aProperties ); 365 boolean bIsUseDictionaryList = GetValueToUse( "IsUseDictionaryList", true, aProperties ); 366 boolean bIsGermanPreReform = GetValueToUse( "IsGermanPreReform", false, aProperties ); 367 short nHyphMinLeading = GetValueToUse( "HyphMinLeading", (short)2, aProperties ); 368 short nHyphMinTrailing = GetValueToUse( "HyphMinTrailing", (short)2, aProperties ); 369 short nHyphMinWordLen = GetValueToUse( "HyphMinWordLength", (short)5, aProperties ); 370 371 XPossibleHyphens xRes = null; 372 373 //!! This code needs to be replaced by code calling the actual 374 //!! implementation of your hyphenator 375 if ( IsEqual( aLocale, new Locale( "de", "DE", "" ) ) ) 376 { 377 if (bIsGermanPreReform && aWord.equals( "Schiffahrt" )) 378 { 379 short aPos[] = new short[] { (short) 4 }; 380 xRes = new XPossibleHyphens_impl(aWord, aLocale, 381 "Schiff=fahrt", aPos); 382 } 383 else if (!bIsGermanPreReform && aWord.equals( "Schifffahrt" )) 384 { 385 short aPos[] = new short[] { (short) 5 }; 386 xRes = new XPossibleHyphens_impl(aWord, aLocale, 387 "Schiff=fahrt", aPos); 388 } 389 } 390 else if ( IsEqual( aLocale, new Locale( "en", "US", "" ) ) ) 391 { 392 if ( aWord.equals( "waterfall" ) ) 393 { 394 short aPos[] = new short[] 395 { (short) 1, (short) 4 }; 396 xRes = new XPossibleHyphens_impl(aWord, aLocale, 397 "wa=ter=fall", aPos); 398 } 399 else if ( aWord.equals( "driving" ) ) 400 { 401 short aPos[] = new short[] 402 { (short) 3 }; 403 xRes = new XPossibleHyphens_impl(aWord, aLocale, 404 "driv=ing", aPos); 405 } 406 } 407 408 return xRes; 409 } 410 411 //***************************** 412 //XLinguServiceEventBroadcaster 413 //***************************** 414 public boolean addLinguServiceEventListener ( 415 XLinguServiceEventListener xLstnr ) 416 throws com.sun.star.uno.RuntimeException 417 { 418 boolean bRes = false; 419 if (!bDisposing && xLstnr != null) 420 bRes = aPropChgHelper.addLinguServiceEventListener( xLstnr ); 421 return bRes; 422 } 423 424 public boolean removeLinguServiceEventListener( 425 XLinguServiceEventListener xLstnr ) 426 throws com.sun.star.uno.RuntimeException 427 { 428 boolean bRes = false; 429 if (!bDisposing && xLstnr != null) 430 bRes = aPropChgHelper.removeLinguServiceEventListener( xLstnr ); 431 return bRes; 432 } 433 434 //******************** 435 // XServiceDisplayName 436 //******************** 437 public String getServiceDisplayName( Locale aLocale ) 438 throws com.sun.star.uno.RuntimeException 439 { 440 return "Java Samples"; 441 } 442 443 //**************** 444 // XInitialization 445 //**************** 446 public void initialize( Object[] aArguments ) 447 throws com.sun.star.uno.Exception, 448 com.sun.star.uno.RuntimeException 449 { 450 int nLen = aArguments.length; 451 if (2 == nLen) 452 { 453 XPropertySet xPropSet = (XPropertySet)UnoRuntime.queryInterface( 454 XPropertySet.class, aArguments[0]); 455 // start listening to property changes 456 aPropChgHelper.AddAsListenerTo( xPropSet ); 457 } 458 } 459 460 461 //************* 462 // XServiceInfo 463 //************* 464 public boolean supportsService( String aServiceName ) 465 throws com.sun.star.uno.RuntimeException 466 { 467 String[] aServices = getSupportedServiceNames_Static(); 468 int i, nLength = aServices.length; 469 boolean bResult = false; 470 471 for( i = 0; !bResult && i < nLength; ++i ) 472 bResult = aServiceName.equals( aServices[ i ] ); 473 474 return bResult; 475 } 476 477 public String getImplementationName() 478 throws com.sun.star.uno.RuntimeException 479 { 480 return _aSvcImplName; 481 } 482 483 public String[] getSupportedServiceNames() 484 throws com.sun.star.uno.RuntimeException 485 { 486 return getSupportedServiceNames_Static(); 487 } 488 489 // __________ static things __________ 490 491 public static String _aSvcImplName = SampleHyphenator.class.getName(); 492 493 public static String[] getSupportedServiceNames_Static() 494 { 495 String[] aResult = { "com.sun.star.linguistic2.Hyphenator" }; 496 return aResult; 497 } 498 499 500 /** 501 * Returns a factory for creating the service. 502 * This method is called by the <code>JavaLoader</code> 503 * <p> 504 * @return returns a <code>XSingleServiceFactory</code> for creating the component 505 * @param implName the name of the implementation for which a service is desired 506 * @param multiFactory the service manager to be used if needed 507 * @param regKey the registryKey 508 * @see com.sun.star.comp.loader.JavaLoader 509 */ 510 public static XSingleServiceFactory __getServiceFactory( 511 String aImplName, 512 XMultiServiceFactory xMultiFactory, 513 com.sun.star.registry.XRegistryKey xRegKey ) 514 { 515 XSingleServiceFactory xSingleServiceFactory = null; 516 if( aImplName.equals( _aSvcImplName ) ) 517 { 518 xSingleServiceFactory = new OneInstanceFactory( 519 SampleHyphenator.class, _aSvcImplName, 520 getSupportedServiceNames_Static(), 521 xMultiFactory ); 522 } 523 return xSingleServiceFactory; 524 } 525 526 /** 527 * Writes the service information into the given registry key. 528 * This method is called by the <code>JavaLoader</code> 529 * <p> 530 * @return returns true if the operation succeeded 531 * @param xRegKey the registryKey 532 * @see com.sun.star.comp.loader.JavaLoader 533 */ 534 // This method not longer necessary since OOo 3.4 where the component registration 535 // was changed to passive component registration. For more details see 536 // http://wiki.services.openoffice.org/wiki/Passive_Component_Registration 537 538 // public static boolean __writeRegistryServiceInfo( 539 // com.sun.star.registry.XRegistryKey xRegKey ) 540 // { 541 // boolean bResult = true; 542 // String[] aServices = getSupportedServiceNames_Static(); 543 // int i, nLength = aServices.length; 544 // for( i = 0; i < nLength; ++i ) 545 // { 546 // bResult = bResult && com.sun.star.comp.loader.FactoryHelper.writeRegistryServiceInfo( 547 // _aSvcImplName, aServices[i], xRegKey ); 548 // } 549 // return bResult; 550 // } 551 } 552 553