001 /* 002 * Copyright 2002-2004 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 005 * use this file except in compliance with the License. You may obtain a copy of 006 * the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 013 * License for the specific language governing permissions and limitations under 014 * the License. 015 */ 016 package org.springframework.richclient.settings; 017 018 import java.beans.PropertyChangeListener; 019 import java.beans.PropertyChangeSupport; 020 import java.util.Arrays; 021 import java.util.HashMap; 022 import java.util.HashSet; 023 import java.util.Map; 024 import java.util.Set; 025 026 import org.springframework.core.enums.LabeledEnum; 027 import org.springframework.richclient.util.ClassUtils; 028 import org.springframework.util.Assert; 029 import org.springframework.util.ObjectUtils; 030 import org.springframework.util.StringUtils; 031 032 /** 033 * Abstract <code>Settings</code> implementation. 034 * 035 * @author Peter De Bruycker 036 */ 037 public abstract class AbstractSettings implements Settings { 038 039 private PropertyChangeSupport listeners = new PropertyChangeSupport( this ); 040 041 private Map defaults = new HashMap(); 042 043 private Map children = new HashMap(); 044 045 private String name; 046 047 private Settings parent; 048 049 public AbstractSettings( Settings parent, String name ) { 050 this.name = name; 051 this.parent = parent; 052 } 053 054 public boolean contains( String key ) { 055 return internalContains( key ) || defaults.containsKey( key ); 056 } 057 058 protected abstract boolean internalContains( String key ); 059 060 /** 061 * Should return the names of the child settings initially in this settings instance, 062 * i.e. the children that were stored in the backend. 063 * 064 * @return the names of the child settings 065 */ 066 protected abstract String[] internalGetChildSettings(); 067 068 /* 069 * (non-Javadoc) 070 * 071 * @see org.springframework.richclient.settings.Settings#setString(java.lang.String, 072 * java.lang.String) 073 */ 074 public void setString( String key, String value ) { 075 Assert.notNull( key, "Key cannot be null" ); 076 077 String old = getString( key ); 078 internalSet( key, value ); 079 afterSet( key, old, value ); 080 081 } 082 083 protected abstract Settings internalCreateChild( String key ); 084 085 public String[] getChildSettings() { 086 if( !childSettingsLoaded ) { 087 childSettingsLoaded = true; 088 childSettingNames.addAll( Arrays.asList( internalGetChildSettings() ) ); 089 } 090 return (String[]) childSettingNames.toArray( new String[childSettingNames.size()] ); 091 } 092 093 private boolean childSettingsLoaded = false; 094 095 private Set childSettingNames = new HashSet(); 096 097 public Settings getSettings( String name ) { 098 if( !children.containsKey( name ) ) { 099 children.put( name, internalCreateChild( name ) ); 100 childSettingNames.add( name ); 101 } 102 return (Settings) children.get( name ); 103 } 104 105 protected abstract void internalSet( String key, String value ); 106 107 /** 108 * Return null if no value found for key 109 */ 110 protected abstract String internalGet( String key ); 111 112 /* 113 * (non-Javadoc) 114 * 115 * @see org.springframework.richclient.settings.Settings#getString(java.lang.String) 116 */ 117 public String getString( String key ) { 118 Assert.notNull( key, "Key cannot be null" ); 119 120 String value = internalGet( key ); 121 if( !StringUtils.hasText( value ) ) { 122 return getDefaultString( key ); 123 } 124 return value; 125 } 126 127 /* 128 * (non-Javadoc) 129 * 130 * @see org.springframework.richclient.settings.Settings#setDefaultString(java.lang.String, 131 * java.lang.String) 132 */ 133 public void setDefaultString( String key, String value ) { 134 Assert.notNull( key, "Key cannot be null" ); 135 136 defaults.put( key, value ); 137 } 138 139 /* 140 * (non-Javadoc) 141 * 142 * @see org.springframework.richclient.settings.Settings#getDefaultString(java.lang.String) 143 */ 144 public String getDefaultString( String key ) { 145 Assert.notNull( key, "Key cannot be null" ); 146 147 if( !defaults.containsKey( key ) ) { 148 return ""; 149 } 150 return (String) defaults.get( key ); 151 152 } 153 154 /* 155 * (non-Javadoc) 156 * 157 * @see org.springframework.richclient.settings.Settings#setInt(java.lang.String, int) 158 */ 159 public void setInt( String key, int value ) { 160 Assert.notNull( key, "Key cannot be null" ); 161 162 int old = getInt( key ); 163 internalSet( key, String.valueOf( value ) ); 164 afterSet( key, new Integer( old ), new Integer( value ) ); 165 } 166 167 /* 168 * (non-Javadoc) 169 * 170 * @see org.springframework.richclient.settings.Settings#getInt(java.lang.String) 171 */ 172 public int getInt( String key ) { 173 Assert.notNull( key, "Key cannot be null" ); 174 175 String value = internalGet( key ); 176 if( !StringUtils.hasText( value ) ) { 177 return getDefaultInt( key ); 178 } 179 return Integer.parseInt( value ); 180 } 181 182 /* 183 * (non-Javadoc) 184 * 185 * @see org.springframework.richclient.settings.Settings#setDefaultInt(java.lang.String, 186 * int) 187 */ 188 public void setDefaultInt( String key, int value ) { 189 Assert.notNull( key, "Key cannot be null" ); 190 191 defaults.put( key, String.valueOf( value ) ); 192 } 193 194 /* 195 * (non-Javadoc) 196 * 197 * @see org.springframework.richclient.settings.Settings#getDefaultInt(java.lang.String) 198 */ 199 public int getDefaultInt( String key ) { 200 Assert.notNull( key, "Key cannot be null" ); 201 202 if( !defaults.containsKey( key ) ) { 203 return 0; 204 } 205 return Integer.parseInt( (String) defaults.get( key ) ); 206 207 } 208 209 /* 210 * (non-Javadoc) 211 * 212 * @see org.springframework.richclient.settings.Settings#setDefaultLong(java.lang.String, 213 * long) 214 */ 215 public void setDefaultLong( String key, long value ) { 216 Assert.notNull( key, "Key cannot be null" ); 217 218 defaults.put( key, String.valueOf( value ) ); 219 } 220 221 /* 222 * (non-Javadoc) 223 * 224 * @see org.springframework.richclient.settings.Settings#getDefaultLong(java.lang.String) 225 */ 226 public long getDefaultLong( String key ) { 227 Assert.notNull( key, "Key cannot be null" ); 228 229 if( !defaults.containsKey( key ) ) { 230 return 0L; 231 } 232 return Long.parseLong( (String) defaults.get( key ) ); 233 234 } 235 236 /* 237 * (non-Javadoc) 238 * 239 * @see org.springframework.richclient.settings.Settings#setFloat(java.lang.String, 240 * float) 241 */ 242 public void setFloat( String key, float value ) { 243 Assert.notNull( key, "Key cannot be null" ); 244 245 float old = getFloat( key ); 246 internalSet( key, String.valueOf( value ) ); 247 afterSet( key, new Float( old ), new Float( value ) ); 248 } 249 250 /* 251 * (non-Javadoc) 252 * 253 * @see org.springframework.richclient.settings.Settings#getFloat(java.lang.String) 254 */ 255 public float getFloat( String key ) { 256 Assert.notNull( key, "Key cannot be null" ); 257 258 String value = internalGet( key ); 259 if( !StringUtils.hasText( value ) ) { 260 return getDefaultFloat( key ); 261 } 262 return Float.parseFloat( value ); 263 } 264 265 /* 266 * (non-Javadoc) 267 * 268 * @see org.springframework.richclient.settings.Settings#setDefaultFloat(java.lang.String, 269 * float) 270 */ 271 public void setDefaultFloat( String key, float value ) { 272 Assert.notNull( key, "Key cannot be null" ); 273 274 defaults.put( key, String.valueOf( value ) ); 275 } 276 277 /* 278 * (non-Javadoc) 279 * 280 * @see org.springframework.richclient.settings.Settings#getDefaultFloat(java.lang.String) 281 */ 282 public float getDefaultFloat( String key ) { 283 Assert.notNull( key, "Key cannot be null" ); 284 285 if( !defaults.containsKey( key ) ) { 286 return 0.0f; 287 } 288 return Float.parseFloat( (String) defaults.get( key ) ); 289 290 } 291 292 /* 293 * (non-Javadoc) 294 * 295 * @see org.springframework.richclient.settings.Settings#setDouble(java.lang.String, 296 * double) 297 */ 298 public void setDouble( String key, double value ) { 299 Assert.notNull( key, "Key cannot be null" ); 300 301 double old = getDouble( key ); 302 internalSet( key, String.valueOf( value ) ); 303 afterSet( key, new Double( old ), new Double( value ) ); 304 } 305 306 /* 307 * (non-Javadoc) 308 * 309 * @see org.springframework.richclient.settings.Settings#getDouble(java.lang.String) 310 */ 311 public double getDouble( String key ) { 312 Assert.notNull( key, "Key cannot be null" ); 313 314 String value = internalGet( key ); 315 if( !StringUtils.hasText( value ) ) { 316 return getDefaultDouble( key ); 317 } 318 return Double.parseDouble( value ); 319 } 320 321 /* 322 * (non-Javadoc) 323 * 324 * @see org.springframework.richclient.settings.Settings#setDefaultDouble(java.lang.String, 325 * double) 326 */ 327 public void setDefaultDouble( String key, double value ) { 328 Assert.notNull( key, "Key cannot be null" ); 329 330 defaults.put( key, String.valueOf( value ) ); 331 } 332 333 /* 334 * (non-Javadoc) 335 * 336 * @see org.springframework.richclient.settings.Settings#getDefaultDouble(java.lang.String) 337 */ 338 public double getDefaultDouble( String key ) { 339 Assert.notNull( key, "Key cannot be null" ); 340 341 if( !defaults.containsKey( key ) ) { 342 return 0.0; 343 } 344 return Double.parseDouble( (String) defaults.get( key ) ); 345 346 } 347 348 /* 349 * (non-Javadoc) 350 * 351 * @see org.springframework.richclient.settings.Settings#setBoolean(java.lang.String, 352 * boolean) 353 */ 354 public void setBoolean( String key, boolean value ) { 355 Assert.notNull( key, "Key cannot be null" ); 356 357 boolean old = getBoolean( key ); 358 internalSet( key, String.valueOf( value ) ); 359 afterSet( key, Boolean.valueOf( old ), Boolean.valueOf( value ) ); 360 } 361 362 /* 363 * (non-Javadoc) 364 * 365 * @see org.springframework.richclient.settings.Settings#getBoolean(java.lang.String) 366 */ 367 public boolean getBoolean( String key ) { 368 Assert.notNull( key, "Key cannot be null" ); 369 370 String value = internalGet( key ); 371 if( !StringUtils.hasText( value ) ) { 372 return getDefaultBoolean( key ); 373 } 374 return Boolean.valueOf( value ).booleanValue(); 375 } 376 377 /* 378 * (non-Javadoc) 379 * 380 * @see org.springframework.richclient.settings.Settings#setDefaultBoolean(java.lang.String, 381 * boolean) 382 */ 383 public void setDefaultBoolean( String key, boolean value ) { 384 Assert.notNull( key, "Key cannot be null" ); 385 386 if( value ) { 387 defaults.put( key, String.valueOf( value ) ); 388 } else { 389 defaults.remove( key ); 390 } 391 removeIfDefault( key ); 392 } 393 394 /* 395 * (non-Javadoc) 396 * 397 * @see org.springframework.richclient.settings.Settings#getDefaultBoolean(java.lang.String) 398 */ 399 public boolean getDefaultBoolean( String key ) { 400 Assert.notNull( key, "Key cannot be null" ); 401 402 if( !defaults.containsKey( key ) ) { 403 return false; 404 } 405 return Boolean.valueOf( (String) defaults.get( key ) ).booleanValue(); 406 } 407 408 /* 409 * (non-Javadoc) 410 * 411 * @see org.springframework.richclient.settings.Settings#setLabeledEnum(java.lang.String, 412 * org.springframework.enums.LabeledEnum) 413 */ 414 public void setLabeledEnum( String key, LabeledEnum value ) { 415 Assert.notNull( key, "Key cannot be null" ); 416 417 LabeledEnum old = getLabeledEnum( key ); 418 internalSet( key, enumToString( value ) ); 419 afterSet( key, old, value ); 420 } 421 422 private LabeledEnum stringToEnum( String s ) { 423 if( s == null || s.trim().equals( "" ) ) { 424 return null; 425 } 426 return (LabeledEnum) ClassUtils.getFieldValue( s ); 427 } 428 429 private String enumToString( LabeledEnum e ) { 430 return e == null ? "" : ClassUtils.getClassFieldNameWithValue( e.getClass(), e ); 431 } 432 433 /* 434 * (non-Javadoc) 435 * 436 * @see org.springframework.richclient.settings.Settings#getLabeledEnum(java.lang.String) 437 */ 438 public LabeledEnum getLabeledEnum( String key ) { 439 Assert.notNull( key, "Key cannot be null" ); 440 441 String value = internalGet( key ); 442 if( !StringUtils.hasText( value ) ) { 443 return getDefaultLabeledEnum( key ); 444 } 445 return stringToEnum( value ); 446 } 447 448 /* 449 * (non-Javadoc) 450 * 451 * @see org.springframework.richclient.settings.Settings#setDefaultLabeledEnum(java.lang.String, 452 * org.springframework.enums.LabeledEnum) 453 */ 454 public void setDefaultLabeledEnum( String key, LabeledEnum value ) { 455 Assert.notNull( key, "Key cannot be null" ); 456 457 defaults.put( key, enumToString( value ) ); 458 } 459 460 /* 461 * (non-Javadoc) 462 * 463 * @see org.springframework.richclient.settings.Settings#getDefaultLabeledEnum(java.lang.String) 464 */ 465 public LabeledEnum getDefaultLabeledEnum( String key ) { 466 Assert.notNull( key, "Key cannot be null" ); 467 return stringToEnum( (String) defaults.get( key ) ); 468 } 469 470 public boolean isDefault( String key ) { 471 Assert.notNull( key, "Key cannot be null" ); 472 473 return internalGet( key ) == null || ObjectUtils.nullSafeEquals( internalGet( key ), defaults.get( key ) ); 474 } 475 476 /* 477 * (non-Javadoc) 478 * 479 * @see org.springframework.richclient.settings.Settings#getDefaultKeys() 480 */ 481 public String[] getDefaultKeys() { 482 return (String[]) defaults.keySet().toArray( new String[0] ); 483 } 484 485 /* 486 * (non-Javadoc) 487 * 488 * @see org.springframework.richclient.settings.Settings#getAllKeys() 489 */ 490 public String[] getAllKeys() { 491 Set keys = new HashSet(); 492 keys.addAll( Arrays.asList( getKeys() ) ); 493 keys.addAll( defaults.keySet() ); 494 495 return (String[]) keys.toArray( new String[0] ); 496 } 497 498 /* 499 * (non-Javadoc) 500 * 501 * @see org.springframework.richclient.settings.Settings#getName() 502 */ 503 public String getName() { 504 return name; 505 } 506 507 /* 508 * (non-Javadoc) 509 * 510 * @see org.springframework.richclient.settings.Settings#getParent() 511 */ 512 public Settings getParent() { 513 return parent; 514 } 515 516 /* 517 * (non-Javadoc) 518 * 519 * @see org.springframework.richclient.settings.Settings#addPropertyChangeListener(java.beans.PropertyChangeListener) 520 */ 521 public void addPropertyChangeListener( PropertyChangeListener l ) { 522 listeners.addPropertyChangeListener( l ); 523 } 524 525 /* 526 * (non-Javadoc) 527 * 528 * @see org.springframework.richclient.settings.Settings#addPropertyChangeListener(java.lang.String, 529 * java.beans.PropertyChangeListener) 530 */ 531 public void addPropertyChangeListener( String key, PropertyChangeListener l ) { 532 listeners.addPropertyChangeListener( key, l ); 533 } 534 535 /* 536 * (non-Javadoc) 537 * 538 * @see org.springframework.richclient.settings.Settings#removePropertyChangeListener(java.beans.PropertyChangeListener) 539 */ 540 public void removePropertyChangeListener( PropertyChangeListener l ) { 541 listeners.removePropertyChangeListener( l ); 542 } 543 544 /* 545 * (non-Javadoc) 546 * 547 * @see org.springframework.richclient.settings.Settings#removePropertyChangeListener(java.lang.String, 548 * java.beans.PropertyChangeListener) 549 */ 550 public void removePropertyChangeListener( String key, PropertyChangeListener l ) { 551 listeners.removePropertyChangeListener( key, l ); 552 } 553 554 private void afterSet( String key, Object oldValue, Object newValue ) { 555 removeIfDefault( key ); 556 firePropertyChange( key, oldValue, newValue ); 557 } 558 559 private void firePropertyChange( String key, Object oldValue, Object newValue ) { 560 listeners.firePropertyChange( key, oldValue, newValue ); 561 } 562 563 protected abstract void internalRemove( String key ); 564 565 private void removeIfDefault( String key ) { 566 if( isDefault( key ) ) { 567 internalRemove( key ); 568 } 569 } 570 571 public void remove( String key ) { 572 if( contains( key ) ) { 573 internalRemove( key ); 574 } 575 } 576 577 /* 578 * (non-Javadoc) 579 * 580 * @see org.springframework.richclient.settings.Settings#setLong(java.lang.String, 581 * long) 582 */ 583 public void setLong( String key, long value ) { 584 Assert.notNull( key, "Key cannot be null" ); 585 586 long old = getLong( key ); 587 internalSet( key, String.valueOf( value ) ); 588 afterSet( key, new Long( old ), new Long( value ) ); 589 } 590 591 /* 592 * (non-Javadoc) 593 * 594 * @see org.springframework.richclient.settings.Settings#getLong(java.lang.String) 595 */ 596 public long getLong( String key ) { 597 Assert.notNull( key, "Key cannot be null" ); 598 599 String value = internalGet( key ); 600 if( !StringUtils.hasText( value ) ) { 601 return getDefaultLong( key ); 602 } 603 return Long.parseLong( value ); 604 } 605 606 public boolean isRoot() { 607 return getParent() == null; 608 } 609 610 public void removeSettings() { 611 internalRemoveSettings(); 612 if( getParent() instanceof AbstractSettings ) { 613 ((AbstractSettings) getParent()).childSettingNames.remove( getName() ); 614 } 615 } 616 617 protected abstract void internalRemoveSettings(); 618 }