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 }