Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 279613
Collapse All | Expand All

(-)schema/rap/settingstores.exsd (-1 / +1 lines)
Lines 111-117 Link Here
111
  <extension
111
  <extension
112
         point="org.eclipse.rap.ui.settingstores">
112
         point="org.eclipse.rap.ui.settingstores">
113
      <factory
113
      <factory
114
            class="org.eclipse.ui.internal.preferences.WorkbenchFileSettingStoreFactory"
114
            class="org.eclipse.rap.ui.internal.preferences.WorkbenchFileSettingStoreFactory"
115
            id="file">
115
            id="file">
116
      </factory>
116
      </factory>
117
      <factory
117
      <factory
(-)plugin.xml (-1 / +1 lines)
Lines 2244-2249 Link Here
2244
  <extension id="preferences" 
2244
  <extension id="preferences" 
2245
             point="org.eclipse.core.runtime.preferences">
2245
             point="org.eclipse.core.runtime.preferences">
2246
    <scope name="session" 
2246
    <scope name="session" 
2247
           class="org.eclipse.ui.internal.preferences.SessionPreferencesFactory"/>
2247
           class="org.eclipse.rap.ui.internal.preferences.SessionPreferencesFactory"/>
2248
  </extension>
2248
  </extension>
2249
</plugin>
2249
</plugin>
(-)Eclipse UI/org/eclipse/ui/internal/preferences/SessionPreferenceNodeCore.java (-183 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Innoopract Informationssysteme GmbH.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.ui.internal.preferences;
12
13
import org.eclipse.core.runtime.*;
14
import org.eclipse.core.runtime.preferences.IEclipsePreferences.*;
15
import org.eclipse.rwt.RWT;
16
import org.eclipse.rwt.internal.util.ParamCheck;
17
import org.eclipse.rwt.service.*;
18
import org.eclipse.ui.internal.WorkbenchPlugin;
19
import org.osgi.service.prefs.Preferences;
20
21
/**
22
 * This class is the link between the SessionPreferenceNode hierarchy 
23
 * (application global) the RWT setting store (session specific).
24
 */
25
final class SessionPreferenceNodeCore {
26
  
27
  private final SessionPreferencesNode node;
28
  private ListenerList prefListeners; // ListenerList is thread safe
29
  private final ListenerList nodeListeners       
30
    = new ListenerList( ListenerList.IDENTITY ); // thread safe
31
32
33
  /* tracks changes in RWT setting store and notifies the prefListeners */
34
  private SettingStoreListener rwtListener;
35
  /* true to track RWT changes */
36
  private boolean trackChanges = true;
37
  /* ignore changes to this key for a short time */
38
  private String ignoreKey;
39
  
40
  SessionPreferenceNodeCore( final SessionPreferencesNode node ) {
41
    ParamCheck.notNull( node, "node" ); //$NON-NLS-1$
42
    this.node = node;
43
  }
44
  
45
  void addPreferenceChangeListener( IPreferenceChangeListener listener ) {
46
    if( listener != null ) {
47
      getListenerList().add( listener );
48
      setTrackRWTChanges( true );
49
    }
50
  }
51
52
  void removePreferenceChangeListener( IPreferenceChangeListener listener ) {
53
    if( listener != null ) {
54
      ListenerList list = getListenerList();
55
      list.remove( listener );
56
      if( list.isEmpty() ) {
57
        setTrackRWTChanges( false );
58
      }
59
    }
60
  }
61
  
62
  void firePreferenceEvent( final String key, 
63
                            final String oldValue, 
64
                            final String newValue )
65
  {
66
    if( prefListeners != null ) {
67
      final PreferenceChangeEvent event 
68
        = new PreferenceChangeEvent( node, key, oldValue, newValue );
69
      Object[] listeners = prefListeners.getListeners();
70
      for( int i = 0; i < listeners.length; i++ ) {
71
        final IPreferenceChangeListener listener 
72
          = ( IPreferenceChangeListener )listeners[ i ];
73
        ISafeRunnable op = new ISafeRunnable() {
74
          public void handleException( final Throwable exception ) {
75
            // logged by SafeRunner
76
          }
77
          public void run() throws Exception {
78
            listener.preferenceChange( event );
79
          }
80
        };
81
        SafeRunner.run( op );
82
      }
83
    }
84
  }
85
  
86
  void clear() {
87
    if( prefListeners != null ) {
88
      prefListeners.clear();
89
      prefListeners = null;
90
      setTrackRWTChanges( false );
91
    }
92
    nodeListeners.clear();
93
  }
94
  
95
  synchronized String put( final String uniqueKey,
96
                           final String value ) {
97
    ISettingStore store = RWT.getSettingStore();
98
    String result = store.getAttribute( uniqueKey );
99
    try {
100
      ignoreKey = uniqueKey;
101
      store.setAttribute( uniqueKey, value );
102
      ignoreKey = null;
103
    } catch( SettingStoreException exc ) {
104
      String msg = "Could not persist preference: " + uniqueKey; //$NON-NLS-1$
105
      WorkbenchPlugin.log( msg, exc );
106
    }
107
    return result;
108
  }
109
  
110
  // helping methods
111
  //////////////////
112
  
113
  private synchronized ListenerList getListenerList() {
114
    if( prefListeners == null ) {
115
      prefListeners = new ListenerList( ListenerList.IDENTITY );
116
    }
117
    return prefListeners;
118
  }
119
  
120
  private synchronized void setTrackRWTChanges( final boolean doTrack ) {
121
    this.trackChanges = doTrack;
122
    if( trackChanges ) {
123
      if( rwtListener == null ) {
124
       rwtListener = new SettingStoreListener() {
125
        public void settingChanged( SettingStoreEvent event ) {
126
          if( trackChanges ) {
127
            String fullKey = event.getAttributeName();
128
            if( !fullKey.equals( ignoreKey ) ) {
129
              String absPath = node.absolutePath();
130
              if( fullKey.startsWith( absPath ) ) {
131
                String key = fullKey.substring( absPath.length() + 1 );
132
                String oldValue = event.getOldValue();
133
                String newValue = event.getNewValue();
134
                firePreferenceEvent( key, oldValue, newValue );
135
              }
136
            }
137
          }
138
        }
139
       };
140
     }
141
     RWT.getSettingStore().addSettingStoreListener( rwtListener );
142
   } else { // !trackChanges
143
     if( rwtListener != null ) {
144
       RWT.getSettingStore().removeSettingStoreListener( rwtListener );
145
     }
146
   }
147
  }
148
149
  public void addNodeChangeListener( final INodeChangeListener listener ) {
150
    nodeListeners.add( listener );
151
  }
152
153
  public void removeNodeChangeListener( final INodeChangeListener listener ) {
154
    nodeListeners.remove( listener );
155
  }
156
157
  public void fireNodeEvent( final Preferences child,
158
                             final boolean wasAdded,
159
                             final SessionPreferencesNode spn )
160
  {
161
    final NodeChangeEvent event = new NodeChangeEvent( spn, child );
162
    Object[] listeners = nodeListeners.getListeners();
163
    for( int i = 0; i < listeners.length; i++ ) {
164
      final INodeChangeListener listener 
165
        = ( INodeChangeListener )listeners[ i ];
166
      ISafeRunnable op = new ISafeRunnable() {
167
        public void handleException( final Throwable exception ) {
168
          // logged by SafeRunner
169
        }
170
        public void run() throws Exception {
171
          if( wasAdded ) {
172
            listener.added( event );
173
          } else {
174
            listener.removed( event );
175
          }
176
        }
177
      };
178
      SafeRunner.run( op );
179
    }
180
181
  }
182
  
183
}
(-)Eclipse UI/org/eclipse/ui/internal/preferences/WorkbenchFileSettingStoreFactory.java (-85 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Innoopract Informationssysteme GmbH.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.ui.internal.preferences;
12
13
14
import java.io.File;
15
16
import org.eclipse.core.runtime.IPath;
17
import org.eclipse.core.runtime.Platform;
18
import org.eclipse.rwt.RWT;
19
import org.eclipse.rwt.internal.util.ParamCheck;
20
import org.eclipse.rwt.service.*;
21
import org.eclipse.ui.PlatformUI;
22
import org.osgi.framework.Bundle;
23
24
25
/**
26
 * {@link ISettingStoreFactory} that creates {@link FileSettingStore} 
27
 * instances.
28
 * <p>
29
 * This particular implementation uses the following strategy to determine
30
 * the path for persisting the data of a FileSettingStore:
31
 * <ol>
32
 * <li>Use the directory specified by the system property 
33
 * <code>"org.eclipse.rwt.service.FileSettingStore.dir"</code>.
34
 * </li>
35
 * <li>Use a subdirectory in the state location of the  
36
 * org.eclipse.rap.ui.workbench bundle.
37
 * </li>
38
 * </ol>
39
 * The first path that can be obtained from the above choices (in the order
40
 * given above) will be used. If the path determined does not exist it will
41
 * be created.
42
 * <p>
43
 * <b>Note:</b> This setting store factory should be used in a regular
44
 * RAP deployment. For an RWT only deployment use the 
45
 * {@link RWTFileSettingStoreFactory}.
46
 * 
47
 */
48
public final class WorkbenchFileSettingStoreFactory
49
  implements ISettingStoreFactory
50
{
51
  
52
  public ISettingStore createSettingStore( final String storeId ) {
53
    ParamCheck.notNullOrEmpty( storeId, "storeId" ); //$NON-NLS-1$
54
    ISettingStore result = new FileSettingStore( getWorkDir() );
55
    try {
56
      result.loadById( storeId );
57
    } catch( SettingStoreException sse ) {
58
      String msg = String.valueOf( sse.getMessage() );
59
      RWT.getRequest().getSession().getServletContext().log( msg, sse );
60
    }
61
    return result;
62
  }
63
  
64
  //////////////////
65
  // helping methods
66
  
67
  private File getWorkDir() {
68
    File result = getWorkDirFromEnvironment();
69
    if( result == null ) {
70
      Bundle bundle = Platform.getBundle( PlatformUI.PLUGIN_ID );
71
      IPath stateLoc = Platform.getStateLocation( bundle );
72
      File parentDir = stateLoc.toFile();
73
      result = new File( parentDir, FileSettingStore.class.getName() );
74
    }
75
    if( !result.exists() ) {
76
      result.mkdirs();
77
    }
78
    return result;
79
  }
80
  
81
  private File getWorkDirFromEnvironment() {
82
    String path = System.getProperty( FileSettingStore.FILE_SETTING_STORE_DIR );
83
    return ( path != null ) ? new File( path ) : null;
84
  }
85
}
(-)Eclipse UI/org/eclipse/ui/internal/preferences/SessionPreferencesFactory.java (-27 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Innoopract Informationssysteme GmbH.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.ui.internal.preferences;
12
13
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
14
import org.eclipse.core.runtime.preferences.IScope;
15
16
/**
17
 * Creates "session" scoped preference nodes.
18
 */
19
public final class SessionPreferencesFactory implements IScope {
20
21
  public IEclipsePreferences create( final IEclipsePreferences parent, 
22
                                     final String name )
23
  {
24
    return new SessionPreferencesNode( parent, name );
25
  }
26
  
27
}
(-)Eclipse UI/org/eclipse/ui/internal/preferences/Base64.java (-1 / +3 lines)
Lines 15-21 Link Here
15
 * from base 64 encoded Strings.
15
 * from base 64 encoded Strings.
16
 *
16
 *
17
 */
17
 */
18
class Base64 {
18
// RAP [bm]: made public to allow access from org.eclipse.rap.ui
19
//class Base64 {
20
public class Base64 {
19
21
20
	private static final byte equalSign = (byte) '=';
22
	private static final byte equalSign = (byte) '=';
21
23
(-)Eclipse UI/org/eclipse/ui/internal/preferences/SessionPreferencesNode.java (-507 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Innoopract Informationssysteme GmbH.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.ui.internal.preferences;
12
13
import java.util.*;
14
15
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
16
import org.eclipse.core.runtime.preferences.IPreferenceNodeVisitor;
17
import org.eclipse.osgi.util.NLS;
18
import org.eclipse.rwt.RWT;
19
import org.eclipse.rwt.internal.util.ParamCheck;
20
import org.eclipse.rwt.service.ISettingStore;
21
import org.eclipse.rwt.service.SettingStoreException;
22
import org.osgi.service.prefs.BackingStoreException;
23
import org.osgi.service.prefs.Preferences;
24
25
/**
26
 * This node use the RWT setting store to persist its preferences.
27
 */
28
final class SessionPreferencesNode implements IEclipsePreferences {
29
30
  private static final String PATH_SEPARATOR = "/"; //$NON-NLS-1$
31
  private static final String DOUBLE_PATH_SEPARATOR = "//"; //$NON-NLS-1$
32
  private static final String TRUE  = "true"; //$NON-NLS-1$
33
  private static final String FALSE = "false"; //$NON-NLS-1$
34
  
35
  private final String name;
36
  private final IEclipsePreferences parent;
37
  private boolean isRemoved;
38
  /* cache the absolutePath once it has been computed */
39
  private String absolutePath;
40
  
41
  private final Map children = new HashMap();    // !thread safe
42
  
43
  SessionPreferencesNode( final IEclipsePreferences parent, 
44
                          final String name )
45
  {
46
    ParamCheck.notNull( parent, "parent" ); //$NON-NLS-1$
47
    ParamCheck.notNull( name, "name" ); //$NON-NLS-1$
48
    checkName( name );
49
    this.parent = parent;
50
    this.name = name;
51
  }
52
  
53
  public void accept( final IPreferenceNodeVisitor visitor )
54
    throws BackingStoreException
55
  {
56
    boolean withChildren = visitor.visit( this );
57
    if( withChildren ) {
58
      Object[] childrenArray;
59
      synchronized( this ) {
60
        childrenArray = children.values().toArray();
61
      }
62
      for( int i = 0; i < childrenArray.length; i++ ) {
63
        IEclipsePreferences child = ( IEclipsePreferences )childrenArray[ i ];
64
        child.accept( visitor );
65
      }
66
    }
67
  }
68
69
  public void addNodeChangeListener( final INodeChangeListener listener ) {
70
    checkRemoved();
71
    if( listener != null ) {
72
      getNodeCore().addNodeChangeListener( listener );
73
    }
74
  }
75
76
  public void addPreferenceChangeListener( 
77
    final IPreferenceChangeListener listener )
78
  {
79
    checkRemoved();
80
    getNodeCore().addPreferenceChangeListener( listener );
81
  }
82
83
  public Preferences node( final String path ) {
84
    checkPath( path );
85
    checkRemoved();
86
    Preferences result;
87
    if( "".equals( path ) ) { // "" //$NON-NLS-1$
88
      result = this;
89
    } else if( path.startsWith( PATH_SEPARATOR ) ) { // "/absolute/path"
90
      result = findRoot().node( path.substring( 1 ) );
91
    } else if( path.indexOf( PATH_SEPARATOR ) > 0 ) { // "foo/bar/baz"
92
      int index = path.indexOf( PATH_SEPARATOR );
93
      String nodeName = path.substring( 0, index );
94
      String rest = path.substring( index + 1, path.length() ); 
95
      result = getChild( nodeName, true ).node( rest );
96
    } else { // "foo"
97
      result = getChild( path, true );
98
    }
99
    return result;
100
  }
101
102
  public synchronized void removeNode() throws BackingStoreException {
103
    checkRemoved();
104
    // remove all preferences
105
    clear(); 
106
    // remove all children
107
    Object[] childNodes = children.values().toArray();
108
    for( int i = 0; i < childNodes.length; i++ ) {
109
      Preferences child = ( Preferences )childNodes[ i ];
110
      if( child.nodeExists( "" ) ) { // if !removed //$NON-NLS-1$
111
        child.removeNode();
112
      }
113
    }
114
    // remove from parent; this is ugly, because the interface 
115
    // Preference has no API for removing oneself from the parent.
116
    // In general the parent will be a SessionPreferencesNode.
117
    // The only case in the workbench where this is not true, is one level
118
    // below the root (i.e. at /session ), but the scope root must not
119
    // be removable (see IEclipsePreferences#removeNode())
120
    if( parent instanceof SessionPreferencesNode ) {
121
      // this means: 
122
      // (a) we know what kind of parent we have, and 
123
      // (b) we are not the scope root, since that has a 
124
      /// RootPreference as a parent
125
      SessionPreferencesNode spnParent 
126
        = ( ( SessionPreferencesNode ) parent );
127
      spnParent.children.remove( name );
128
      spnParent.fireNodeEvent( this, false );
129
130
      // the listeners are not needed anymore
131
      getNodeCore().clear();
132
      children.clear();
133
      isRemoved = true;
134
    }
135
  }
136
137
  public void removeNodeChangeListener( final INodeChangeListener listener ) {
138
    checkRemoved();
139
    if( listener != null ) {
140
      getNodeCore().removeNodeChangeListener( listener );
141
    }
142
  }
143
144
  public void removePreferenceChangeListener( 
145
    final IPreferenceChangeListener listener )
146
  {
147
    checkRemoved();
148
    getNodeCore().removePreferenceChangeListener( listener );
149
  }
150
151
  public String absolutePath() {
152
    if( absolutePath == null ) {
153
      if( parent == null ) {
154
        absolutePath = name;
155
      } else {
156
        String parentPath =  parent.absolutePath();
157
        absolutePath = parentPath.endsWith( PATH_SEPARATOR ) 
158
                     ? parentPath + name
159
                     : parentPath + PATH_SEPARATOR + name;
160
      }
161
    }
162
    return absolutePath;
163
  }
164
165
  public synchronized String[] childrenNames() {
166
    checkRemoved();
167
    Set names = children.keySet();
168
    return ( String[] )names.toArray( new String[ names.size() ] );
169
  }
170
171
  public void clear() {
172
    checkRemoved();
173
    String[] keys = internalGetKeys();
174
    for( int i = 0; i < keys.length; i++ ) {
175
      remove( keys[ i ] );
176
    }
177
  }
178
179
  public void flush() {
180
    checkRemoved();
181
    // the current implementation persists everytime the preferences 
182
    // are modified, so there's nothing to do here
183
  }
184
185
  public String get( final String key, final String def ) {
186
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
187
    checkRemoved();
188
    String result = internalGet( key );
189
    return result == null ? def : result;
190
  }
191
192
  public boolean getBoolean( final String key, final boolean def ) {
193
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
194
    checkRemoved();
195
    String value = internalGet( key );
196
    return value == null ? def : Boolean.valueOf( value ).booleanValue();
197
  }
198
199
  public byte[] getByteArray( final String key, final byte[] def ) {
200
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
201
    checkRemoved();
202
    String value = internalGet( key );
203
    return value == null ? def : Base64.decode( value.getBytes() );
204
  }
205
206
  public double getDouble( final String key, final double def ) {
207
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
208
    checkRemoved();
209
    String value = internalGet( key );
210
    double result = def;
211
    if( value != null ) {
212
      try {
213
        result = Double.parseDouble( value );
214
      } catch( NumberFormatException nfe ) {
215
        // returns def
216
      }
217
    }
218
    return result;
219
  }
220
221
  public float getFloat( final String key, final float def ) {
222
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
223
    checkRemoved();
224
    String value = internalGet( key );
225
    float result = def;
226
    if( value != null ) {
227
      try {
228
        result = Float.parseFloat( value );
229
      } catch( NumberFormatException nfe ) {
230
        // returns def
231
      }
232
    }
233
    return result;
234
  }
235
236
  public int getInt( final String key, final int def ) {
237
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
238
    checkRemoved();
239
    String value = internalGet( key );
240
    int result = def;
241
    if( value != null ) {
242
      try {
243
        result = Integer.parseInt( value );
244
      } catch( NumberFormatException nfe ) {
245
        // returns def
246
      }
247
    }
248
    return result;
249
  }
250
251
  public long getLong( final String key, final long def ) {
252
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
253
    checkRemoved();
254
    String value = internalGet( key );
255
    long result = def;
256
    if( value != null ) {
257
      try {
258
        result = Long.parseLong( value );
259
      } catch( NumberFormatException nfe ) {
260
        // returns def
261
      }
262
    }
263
    return result;
264
  }
265
266
  public String[] keys() {
267
    checkRemoved();
268
    return internalGetKeys();
269
  }
270
271
  public String name() {
272
    return name;
273
  }
274
275
  public synchronized boolean nodeExists( final String path ) 
276
    throws BackingStoreException 
277
  {
278
    boolean result;
279
    if( "".equals( path ) ) { //$NON-NLS-1$
280
      result = !isRemoved;
281
    } else {
282
      checkRemoved();
283
      checkPath( path );
284
      if( path.startsWith( PATH_SEPARATOR ) ) { // "/absolute/path"
285
        result = findRoot().nodeExists( path.substring( 1 ) );
286
      } else if( path.indexOf( PATH_SEPARATOR ) > 0 ) { // "foo/bar/baz"
287
        int index = path.indexOf( PATH_SEPARATOR );
288
        String nodeName = path.substring( 0, index );
289
        String rest = path.substring( index + 1, path.length() ); 
290
        SessionPreferencesNode child = getChild( nodeName, false );
291
        result = child == null ? false : child.nodeExists( rest );
292
      } else { // "foo"
293
        result = children.containsKey( path );
294
      }
295
    }
296
    return result;
297
  }
298
299
  public Preferences parent() {
300
    checkRemoved();
301
    return parent;
302
  }
303
304
  public void put( final String key, final String newValue ) {
305
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
306
    ParamCheck.notNull( newValue, "newValue" ); //$NON-NLS-1$
307
    checkRemoved();
308
    String oldValue = internalPut( key, newValue );
309
    if( !newValue.equals( oldValue ) ) {
310
      getNodeCore().firePreferenceEvent( key, oldValue, newValue );
311
    }
312
  }
313
314
  public void putBoolean( final String key, final boolean value ) {
315
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
316
    checkRemoved();
317
    String newValue = value ? TRUE : FALSE;
318
    String oldValue = internalPut( key, newValue );
319
    if( !newValue.equals( oldValue ) ) {
320
      getNodeCore().firePreferenceEvent( key, oldValue, newValue );
321
    }
322
  }
323
324
  public void putByteArray( final String key, final byte[] value ) {
325
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
326
    ParamCheck.notNull( value, "newValue" ); //$NON-NLS-1$
327
    checkRemoved();
328
    String newValue = new String( Base64.encode( value ) );
329
    String oldValue = internalPut( key, newValue );
330
    if( !newValue.equals( oldValue) ) {
331
      getNodeCore().firePreferenceEvent( key, oldValue, newValue );
332
    }
333
  }
334
335
  public void putDouble( final String key, final double value ) {
336
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
337
    checkRemoved();
338
    String newValue = String.valueOf( value );
339
    String oldValue = internalPut( key, newValue );
340
    if( !newValue.equals( oldValue ) ) {
341
      getNodeCore().firePreferenceEvent( key, oldValue, newValue );
342
    }
343
  }
344
345
  public void putFloat( final String key, final float value ) {
346
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
347
    checkRemoved();
348
    String newValue = String.valueOf( value );
349
    String oldValue = internalPut( key, newValue );
350
    if( !newValue.equals( oldValue ) ) {
351
      getNodeCore().firePreferenceEvent( key, oldValue, newValue );
352
    }
353
  }
354
355
  public void putInt( final String key, final int value ) {
356
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
357
    checkRemoved();
358
    String newValue = String.valueOf( value );
359
    String oldValue = internalPut( key, newValue );
360
    if( !newValue.equals( oldValue ) ) {
361
      getNodeCore().firePreferenceEvent( key, oldValue, newValue );
362
    }
363
  }
364
365
  public void putLong( final String key, final long value ) {
366
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
367
    checkRemoved();
368
    String newValue = String.valueOf( value );
369
    String oldValue = internalPut( key, newValue );
370
    if( !newValue.equals( oldValue ) ) {
371
      getNodeCore().firePreferenceEvent( key, oldValue, newValue );
372
    }
373
  }
374
375
  public void remove( final String key ) {
376
    checkRemoved();
377
    String oldValue = internalGet( key );
378
    if( oldValue != null ) {
379
      internalPut( key, null );
380
      getNodeCore().firePreferenceEvent( key, oldValue, null );
381
    }
382
  }
383
384
  public void sync() throws BackingStoreException {
385
    checkRemoved();
386
    ISettingStore store = RWT.getSettingStore();
387
    String id = store.getId();
388
    try {
389
      store.loadById( id );
390
    } catch( SettingStoreException sse ) {
391
      throw new BackingStoreException( "Failed to sync() node", sse ); //$NON-NLS-1$
392
    }
393
  }
394
  
395
  public String toString() {
396
    return absolutePath() + "@" + hashCode(); //$NON-NLS-1$
397
  }
398
  
399
  //////////////////
400
  // helping methods
401
  
402
  private void checkName( final String nodeName ) {
403
    if( nodeName.indexOf( PATH_SEPARATOR ) != -1 ) {
404
      String unboundMsg = "Name ''{0}'' cannot contain or end with ''{1}''"; //$NON-NLS-1$
405
      String msg = NLS.bind( unboundMsg, nodeName, PATH_SEPARATOR );
406
      throw new IllegalArgumentException( msg );
407
    }
408
  }
409
410
  private void checkPath( final String path ) {
411
    if( path.indexOf( DOUBLE_PATH_SEPARATOR ) != -1 ) {
412
      String unboundMsg = "''{0}'' is not allowed in path ''{1}''"; //$NON-NLS-1$
413
      String msg = NLS.bind( unboundMsg, DOUBLE_PATH_SEPARATOR, path );
414
      throw new IllegalArgumentException( msg );
415
    }
416
    if( path.length() > 1 && path.endsWith( PATH_SEPARATOR ) ) {
417
      String unboundMsg = "path ''{0}'' cannot end with ''{1}''"; //$NON-NLS-1$
418
      String msg = NLS.bind( unboundMsg, path, PATH_SEPARATOR );
419
      throw new IllegalArgumentException( msg );
420
    }
421
  }
422
  
423
  private synchronized void checkRemoved() {
424
    if( isRemoved ) {
425
      String msg = "node ''{0}'' has been removed"; //$NON-NLS-1$
426
      throw new IllegalStateException( NLS.bind( msg, this.absolutePath() ) );
427
    }
428
  }
429
  
430
  private synchronized SessionPreferencesNode createChild( 
431
    final String childName )
432
  {
433
    SessionPreferencesNode result 
434
      = new SessionPreferencesNode( this, childName );
435
    children.put( childName, result );
436
    fireNodeEvent( result, true );
437
    return result;
438
  }
439
  
440
  private synchronized SessionPreferencesNode getChild( 
441
    final String childName, 
442
    final boolean doCreate ) 
443
  {
444
    SessionPreferencesNode result 
445
      = ( SessionPreferencesNode )children.get( childName );
446
    if( result == null && doCreate ) {
447
      result = createChild( childName );
448
    }
449
    return result;
450
  }
451
  
452
  private String[] internalGetKeys() {
453
    List result = new ArrayList();
454
455
    String prefix = absolutePath() + PATH_SEPARATOR;
456
    int prefixLength = prefix.length();
457
    
458
    Enumeration attrNames = RWT.getSettingStore().getAttributeNames();
459
    while( attrNames.hasMoreElements() ) {
460
      String attr = ( String )attrNames.nextElement();
461
      if( attr.startsWith( prefix ) ) {
462
        String key = attr.substring( prefixLength );
463
        result.add( key );
464
      }
465
    }
466
    return ( String[] )result.toArray( new String[ result.size() ] );
467
  }
468
469
  private Preferences findRoot() {
470
    Preferences result = this;
471
    while( result.parent() != null ) {
472
      result = result.parent();
473
    }
474
    return result;
475
  }
476
  
477
  private String internalGet( final String key ) {
478
    ISettingStore store = RWT.getSettingStore();
479
    String uniqueKey = absolutePath() + PATH_SEPARATOR + key;
480
    return store.getAttribute( uniqueKey );
481
  }
482
483
  private synchronized String internalPut( final String key, 
484
                                           final String value ) {
485
    String uniqueKey = absolutePath() + PATH_SEPARATOR + key;
486
    return getNodeCore().put( uniqueKey, value );
487
  }
488
  
489
  private void fireNodeEvent( final Preferences child,
490
                              final boolean wasAdded ) {
491
    getNodeCore().fireNodeEvent( child, wasAdded, this );
492
  }
493
  
494
  private SessionPreferenceNodeCore getNodeCore() {
495
    SessionPreferenceNodeCore result;
496
    final String key = absolutePath();
497
    Object object = RWT.getSessionStore().getAttribute( key );
498
    if( object instanceof SessionPreferenceNodeCore ) {
499
      result = ( SessionPreferenceNodeCore )object;
500
    } else {
501
      result = new SessionPreferenceNodeCore( this );
502
      RWT.getSessionStore().setAttribute( key, result );
503
    }
504
    return result;
505
  }
506
  
507
}
(-)Eclipse UI/org/eclipse/ui/internal/preferences/SessionScope.java (-70 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Innoopract Informationssysteme GmbH.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.ui.internal.preferences;
12
13
import org.eclipse.core.runtime.IPath;
14
import org.eclipse.core.runtime.Platform;
15
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
16
import org.eclipse.core.runtime.preferences.IScopeContext;
17
import org.eclipse.rwt.RWT;
18
import org.eclipse.rwt.internal.util.ParamCheck;
19
import org.eclipse.rwt.service.FileSettingStore;
20
21
// TODO [fappel]: think about how we can provide this as API (subset rule
22
//                of RAP/RCP)
23
/**
24
 * Object representing the session scope in the Eclipse preferences
25
 * hierarchy. Can be used as a context for searching for preference
26
 * values (in the IPreferenceService APIs) or for determining the
27
 * corrent preference node to set values in the store.
28
 * <p>
29
 * Session preferences are stored on a <i>per-session</i> basis using
30
 * the underlying RWT SettingStore (see {@link RWT#getSettingStore()}. 
31
 * Preferences saved during a previous session will be retrieved, as long as
32
 * the user can identify himself with the setting store cookie. Session 
33
 * preferences are persisted using the setting store implementation
34
 * that is configured for the application (see {@link FileSettingStore}.
35
 * <p>
36
 * The path for preferences defined in the session scope hierarchy is: 
37
 * <code>/session/&lt;qualifier&gt;</code>
38
 * <p>
39
 * This class is not intented to be subclassed. It may be instantiated.
40
 *
41
 */
42
public final class SessionScope implements IScopeContext {
43
44
  /**
45
   * String constant (value of <code>"session"</code>) used for the 
46
   * scope name for the session preference scope.
47
   */
48
  public static final String SCOPE = "session"; //$NON-NLS-1$
49
  
50
  /**
51
   * Create and return a new session scope instance.
52
   */
53
  public SessionScope() {
54
    super();
55
  }
56
57
  public IPath getLocation() {
58
    return null;
59
  }
60
61
  public String getName() {
62
    return SCOPE;
63
  }
64
65
  public IEclipsePreferences getNode( String qualifier ) {
66
    ParamCheck.notNull( qualifier, "qualifier" ); //$NON-NLS-1$
67
    IEclipsePreferences root = Platform.getPreferencesService().getRootNode();
68
    return ( IEclipsePreferences ) root.node( SCOPE ).node( qualifier );
69
  }
70
}
(-)Eclipse UI/org/eclipse/ui/plugin/AbstractUIPlugin.java (-1 / +1 lines)
Lines 29-41 Link Here
29
import org.eclipse.jface.preference.IPreferenceStore;
29
import org.eclipse.jface.preference.IPreferenceStore;
30
import org.eclipse.jface.resource.ImageDescriptor;
30
import org.eclipse.jface.resource.ImageDescriptor;
31
import org.eclipse.jface.resource.ImageRegistry;
31
import org.eclipse.jface.resource.ImageRegistry;
32
import org.eclipse.rap.ui.internal.preferences.SessionScope;
32
import org.eclipse.swt.SWT;
33
import org.eclipse.swt.SWT;
33
import org.eclipse.swt.SWTError;
34
import org.eclipse.swt.SWTError;
34
import org.eclipse.swt.widgets.Display;
35
import org.eclipse.swt.widgets.Display;
35
import org.eclipse.ui.IWorkbench;
36
import org.eclipse.ui.IWorkbench;
36
import org.eclipse.ui.PlatformUI;
37
import org.eclipse.ui.PlatformUI;
37
import org.eclipse.ui.internal.WWinPluginAction;
38
import org.eclipse.ui.internal.WWinPluginAction;
38
import org.eclipse.ui.internal.preferences.SessionScope;
39
import org.eclipse.ui.internal.util.BundleUtility;
39
import org.eclipse.ui.internal.util.BundleUtility;
40
import org.eclipse.ui.preferences.ScopedPreferenceStore;
40
import org.eclipse.ui.preferences.ScopedPreferenceStore;
41
import org.osgi.framework.Bundle;
41
import org.osgi.framework.Bundle;
(-)Eclipse UI/org/eclipse/ui/internal/WorkbenchPlugin.java (-1 / +1 lines)
Lines 30-35 Link Here
30
import org.eclipse.jface.resource.ImageRegistry;
30
import org.eclipse.jface.resource.ImageRegistry;
31
import org.eclipse.jface.window.Window;
31
import org.eclipse.jface.window.Window;
32
import org.eclipse.rap.ui.internal.branding.BrandingExtension;
32
import org.eclipse.rap.ui.internal.branding.BrandingExtension;
33
import org.eclipse.rap.ui.internal.progress.JobManagerAdapter;
33
import org.eclipse.rap.ui.internal.servlet.EntryPointExtension;
34
import org.eclipse.rap.ui.internal.servlet.EntryPointExtension;
34
import org.eclipse.rap.ui.internal.servlet.HttpServiceTracker;
35
import org.eclipse.rap.ui.internal.servlet.HttpServiceTracker;
35
import org.eclipse.rwt.RWT;
36
import org.eclipse.rwt.RWT;
Lines 51-57 Link Here
51
import org.eclipse.ui.internal.intro.IntroRegistry;
52
import org.eclipse.ui.internal.intro.IntroRegistry;
52
import org.eclipse.ui.internal.misc.StatusUtil;
53
import org.eclipse.ui.internal.misc.StatusUtil;
53
import org.eclipse.ui.internal.operations.WorkbenchOperationSupport;
54
import org.eclipse.ui.internal.operations.WorkbenchOperationSupport;
54
import org.eclipse.ui.internal.progress.JobManagerAdapter;
55
import org.eclipse.ui.internal.progress.ProgressManager;
55
import org.eclipse.ui.internal.progress.ProgressManager;
56
import org.eclipse.ui.internal.registry.ActionSetRegistry;
56
import org.eclipse.ui.internal.registry.ActionSetRegistry;
57
import org.eclipse.ui.internal.registry.EditorRegistry;
57
import org.eclipse.ui.internal.registry.EditorRegistry;
(-)Eclipse UI/org/eclipse/ui/internal/Workbench.java (+2 lines)
Lines 37-42 Link Here
37
import org.eclipse.jface.viewers.ISelection;
37
import org.eclipse.jface.viewers.ISelection;
38
import org.eclipse.jface.window.*;
38
import org.eclipse.jface.window.*;
39
import org.eclipse.osgi.util.NLS;
39
import org.eclipse.osgi.util.NLS;
40
import org.eclipse.rap.ui.internal.RealmAdapterHook;
41
import org.eclipse.rap.ui.internal.SessionSingletonEventManager;
40
import org.eclipse.rwt.RWT;
42
import org.eclipse.rwt.RWT;
41
import org.eclipse.rwt.internal.branding.BrandingUtil;
43
import org.eclipse.rwt.internal.branding.BrandingUtil;
42
import org.eclipse.rwt.internal.service.ContextProvider;
44
import org.eclipse.rwt.internal.service.ContextProvider;
(-)Eclipse UI/org/eclipse/ui/preferences/ScopedPreferenceStore.java (-1 / +1 lines)
Lines 20-28 Link Here
20
import org.eclipse.jface.preference.IPersistentPreferenceStore;
20
import org.eclipse.jface.preference.IPersistentPreferenceStore;
21
import org.eclipse.jface.preference.IPreferenceStore;
21
import org.eclipse.jface.preference.IPreferenceStore;
22
import org.eclipse.jface.util.IPropertyChangeListener;
22
import org.eclipse.jface.util.IPropertyChangeListener;
23
import org.eclipse.rap.ui.internal.preferences.SessionScope;
23
import org.eclipse.rwt.RWT;
24
import org.eclipse.rwt.RWT;
24
import org.eclipse.rwt.service.ISessionStore;
25
import org.eclipse.rwt.service.ISessionStore;
25
import org.eclipse.ui.internal.preferences.SessionScope;
26
26
27
/**
27
/**
28
 * The ScopedPreferenceStore is an IPreferenceStore that uses the scopes
28
 * The ScopedPreferenceStore is an IPreferenceStore that uses the scopes
(-)Eclipse UI/org/eclipse/ui/internal/progress/WorkbenchSiteProgressService.java (+1 lines)
Lines 28-33 Link Here
28
import org.eclipse.jface.operation.IRunnableWithProgress;
28
import org.eclipse.jface.operation.IRunnableWithProgress;
29
import org.eclipse.jface.resource.ImageDescriptor;
29
import org.eclipse.jface.resource.ImageDescriptor;
30
import org.eclipse.jface.util.IPropertyChangeListener;
30
import org.eclipse.jface.util.IPropertyChangeListener;
31
import org.eclipse.rap.ui.internal.progress.ProgressUtil;
31
import org.eclipse.rwt.graphics.Graphics;
32
import org.eclipse.rwt.graphics.Graphics;
32
import org.eclipse.swt.SWT;
33
import org.eclipse.swt.SWT;
33
import org.eclipse.swt.graphics.Image;
34
import org.eclipse.swt.graphics.Image;
(-)Eclipse UI/org/eclipse/ui/internal/progress/IJobMarker.java (-20 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2002, 2008 Innoopract Informationssysteme GmbH.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.ui.internal.progress;
13
14
// RAP [fappel]: This is a helper class used to avoid a memory leak due to 
15
//               thread management.
16
//               Note that this is still under investigation.
17
//               See comment in JobManagerAdapter
18
public interface IJobMarker {
19
  boolean canBeRemoved();
20
}
(-)Eclipse UI/org/eclipse/ui/internal/progress/ProgressMonitorFocusJobDialog.java (+2 lines)
Lines 16-21 Link Here
16
import org.eclipse.core.runtime.*;
16
import org.eclipse.core.runtime.*;
17
import org.eclipse.core.runtime.jobs.*;
17
import org.eclipse.core.runtime.jobs.*;
18
import org.eclipse.jface.dialogs.IDialogConstants;
18
import org.eclipse.jface.dialogs.IDialogConstants;
19
import org.eclipse.rap.ui.internal.progress.JobCanceler;
20
import org.eclipse.rap.ui.internal.progress.ProgressUtil;
19
import org.eclipse.rwt.RWT;
21
import org.eclipse.rwt.RWT;
20
import org.eclipse.rwt.internal.lifecycle.RWTLifeCycle;
22
import org.eclipse.rwt.internal.lifecycle.RWTLifeCycle;
21
import org.eclipse.rwt.internal.service.ContextProvider;
23
import org.eclipse.rwt.internal.service.ContextProvider;
(-)Eclipse UI/org/eclipse/ui/internal/progress/ProgressAnimationProcessor.java (+1 lines)
Lines 17-22 Link Here
17
import org.eclipse.core.runtime.Assert;
17
import org.eclipse.core.runtime.Assert;
18
import org.eclipse.core.runtime.IProgressMonitor;
18
import org.eclipse.core.runtime.IProgressMonitor;
19
import org.eclipse.core.runtime.jobs.Job;
19
import org.eclipse.core.runtime.jobs.Job;
20
import org.eclipse.rap.ui.internal.progress.ProgressUtil;
20
21
21
/**
22
/**
22
 * The ProgressAnimationProcessor is the processor for the animation using the
23
 * The ProgressAnimationProcessor is the processor for the animation using the
(-)Eclipse UI/org/eclipse/ui/internal/progress/ProgressUtil.java (-34 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2002, 2008 Innoopract Informationssysteme GmbH.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.ui.internal.progress;
13
14
import org.eclipse.rwt.lifecycle.UICallBack;
15
import org.eclipse.swt.widgets.Display;
16
import org.eclipse.ui.PlatformUI;
17
18
// RAP [fappel]:
19
public final class ProgressUtil {
20
  
21
  private ProgressUtil() {
22
    // prevent instance creation
23
  }
24
  
25
  public static boolean isWorkbenchRunning( final Display display ) {
26
    final boolean[] result = new boolean[ 1 ];
27
    UICallBack.runNonUIThreadWithFakeContext( display, new Runnable() {
28
      public void run() {
29
        result[ 0 ] = PlatformUI.isWorkbenchRunning();
30
      }
31
    } );
32
    return result[ 0 ];
33
  }
34
}
(-)Eclipse UI/org/eclipse/ui/internal/progress/JobCanceler.java (-46 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2002-2006 Innoopract Informationssysteme GmbH.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.ui.internal.progress;
13
14
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
15
import org.eclipse.core.runtime.jobs.IJobChangeListener;
16
17
// RAP [fappel]: This is a helper class used to avoid a memory leak due to 
18
//               thread management.
19
//               Note that this is still under investigation.
20
//               See comment in JobManagerAdapter
21
final class JobCanceler implements IJobChangeListener {
22
23
  public void aboutToRun( IJobChangeEvent event ) {
24
    event.getJob().cancel();
25
  }
26
27
  public void awake( IJobChangeEvent event ) {
28
    event.getJob().cancel();
29
  }
30
31
  public void done( IJobChangeEvent event ) {
32
    event.getJob().cancel();
33
  }
34
35
  public void running( IJobChangeEvent event ) {
36
    event.getJob().cancel();
37
  }
38
39
  public void scheduled( IJobChangeEvent event ) {
40
    event.getJob().cancel();
41
  }
42
43
  public void sleeping( IJobChangeEvent event ) {
44
    event.getJob().cancel();
45
  }
46
}
(-)Eclipse UI/org/eclipse/ui/internal/progress/JobManagerAdapter.java (-244 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007, 2008 Innoopract Informationssysteme GmbH.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.ui.internal.progress;
12
13
import java.lang.reflect.Field;
14
import java.util.*;
15
16
import javax.servlet.http.HttpSessionBindingEvent;
17
import javax.servlet.http.HttpSessionBindingListener;
18
19
import org.eclipse.core.runtime.IProgressMonitor;
20
import org.eclipse.core.runtime.jobs.*;
21
import org.eclipse.rwt.RWT;
22
import org.eclipse.rwt.internal.lifecycle.RWTLifeCycle;
23
import org.eclipse.rwt.internal.service.ContextProvider;
24
import org.eclipse.rwt.lifecycle.UICallBack;
25
import org.eclipse.rwt.service.ISessionStore;
26
import org.eclipse.swt.widgets.Display;
27
28
// RAP [fappel]:
29
public class JobManagerAdapter
30
  extends ProgressProvider
31
  implements IJobChangeListener
32
{
33
  
34
  private static JobManagerAdapter _instance;
35
  private final Map jobs;
36
  private final ProgressManager defaultProgressManager;
37
  final Object lock;
38
39
  public static synchronized JobManagerAdapter getInstance() {
40
    if( _instance == null ) {
41
      _instance = new JobManagerAdapter();
42
    }
43
    return _instance;
44
  }
45
  
46
  
47
  private JobManagerAdapter() {
48
    // To avoid deadlocks we have to use the same synchronisation lock.
49
    // If anyone has a better idea - you're welcome.
50
    IJobManager jobManager = Job.getJobManager();
51
    Class clazz = jobManager.getClass();
52
    try {
53
      Field jobManagerLock = clazz.getDeclaredField( "lock" );
54
      jobManagerLock.setAccessible( true );
55
      lock = jobManagerLock.get( jobManager );
56
    } catch( final Throwable thr ) {
57
      String msg = "Could not initialize synchronization lock.";
58
      throw new IllegalStateException( msg );
59
    }
60
    jobs = new HashMap();
61
    defaultProgressManager = new ProgressManager();
62
    Job.getJobManager().setProgressProvider( this );
63
    Job.getJobManager().addJobChangeListener( this );
64
  }
65
  
66
  
67
  ///////////////////////////////
68
  // ProgressProvider
69
  
70
  public IProgressMonitor createMonitor( final Job job ) {
71
    ProgressManager manager = findProgressManager( job );
72
    return manager.createMonitor( job );
73
  }
74
  
75
  public IProgressMonitor createMonitor( final Job job,
76
                                         final IProgressMonitor group,
77
                                         final int ticks )
78
  {
79
    ProgressManager manager = findProgressManager( job );
80
    return manager.createMonitor( job, group, ticks );
81
  }
82
  
83
  public IProgressMonitor createProgressGroup() {
84
    return defaultProgressManager.createProgressGroup();
85
  }
86
  
87
  
88
  ///////////////////////////////
89
  // interface IJobChangeListener
90
  
91
  public void aboutToRun( final IJobChangeEvent event ) {
92
    ProgressManager manager = findProgressManager( event.getJob() );
93
    manager.changeListener.aboutToRun( event );
94
  }
95
96
  public void awake( final IJobChangeEvent event ) {
97
    ProgressManager manager = findProgressManager( event.getJob() );
98
    manager.changeListener.awake( event );
99
  }
100
101
  public void done( final IJobChangeEvent event ) {
102
    final ProgressManager[] manager = new ProgressManager[ 1 ];
103
    Display display = null;
104
    synchronized( lock ) {
105
      try {
106
        manager[ 0 ] = findProgressManager( event.getJob() );
107
        display = ( Display )jobs.get( event.getJob() );
108
        if( display != null ) {
109
          display.asyncExec( new Runnable() {
110
            public void run() {
111
              Job job = event.getJob();
112
              String id = String.valueOf( job.hashCode() );
113
              UICallBack.deactivate( id );
114
            }
115
          } );
116
        }
117
      } finally {
118
        jobs.remove( event.getJob() );
119
      }
120
    }
121
    if( display != null ) {
122
      display.asyncExec( new Runnable() {
123
        public void run() {
124
          manager[ 0 ].changeListener.done( event );
125
        }
126
      } );
127
//    } else {
128
//      manager[ 0 ].changeListener.done( event );      
129
    }
130
  }
131
132
  public void running( final IJobChangeEvent event ) {
133
    ProgressManager manager = findProgressManager( event.getJob() );
134
    manager.changeListener.running( event );
135
  }
136
137
  public void scheduled( final IJobChangeEvent event ) {
138
    ProgressManager manager;
139
    synchronized( lock ) {
140
      if( ContextProvider.hasContext() ) {
141
        jobs.put( event.getJob(), RWTLifeCycle.getSessionDisplay() );
142
        bindToSession( event.getJob() );
143
        String id = String.valueOf( event.getJob().hashCode() );
144
        UICallBack.activate( id );
145
      }
146
      manager = findProgressManager( event.getJob() );
147
    }
148
    manager.changeListener.scheduled( event );
149
  }
150
151
  public void sleeping( final IJobChangeEvent event ) {
152
    ProgressManager manager = findProgressManager( event.getJob() );
153
    manager.changeListener.sleeping( event );
154
  }
155
156
  
157
  //////////////////
158
  // helping methods
159
  
160
  private ProgressManager findProgressManager( final Job job ) {
161
    synchronized( lock ) {
162
      final ProgressManager result[] = new ProgressManager[ 1 ];
163
      Display display = ( Display )jobs.get( job );
164
      if( display != null ) {
165
        UICallBack.runNonUIThreadWithFakeContext( display, new Runnable() {
166
          public void run() {
167
            result[ 0 ] = ProgressManager.getInstance();
168
          }
169
        } );
170
        if( result[ 0 ] == null ) {
171
          String msg = "ProgressManager must not be null.";
172
          throw new IllegalStateException( msg );
173
        }
174
      } else {
175
        result[ 0 ] = defaultProgressManager;
176
      }
177
      return result[ 0 ];
178
    }
179
  }
180
  
181
  private void bindToSession( final Object keyToRemove ) {
182
    ISessionStore session = RWT.getSessionStore();
183
    HttpSessionBindingListener watchDog = new HttpSessionBindingListener() {
184
      public void valueBound( final HttpSessionBindingEvent event ) {
185
      }
186
      public void valueUnbound( final HttpSessionBindingEvent event ) {
187
        try {
188
          handleWatchDog( keyToRemove );
189
        } finally {
190
          synchronized( lock ) {
191
            jobs.remove( keyToRemove );
192
          }
193
        }
194
      }
195
196
      private void handleWatchDog( final Object keyToRemove ) {
197
        // ////////////////////////////////////////////////////////////////////
198
        // TODO [fappel]: Very ugly hack to avoid a memory leak.
199
        // As a job can not be removed from the
200
        // running set directly, I use reflection. Jobs
201
        // can be catched in the set on session timeouts.
202
        // Don't know a proper solution yet.
203
        // Note that this is still under investigation.
204
        if( keyToRemove instanceof Job ) {
205
          final Job jobToRemove = ( Job )keyToRemove;
206
          Display display = ( Display )jobs.get( jobToRemove );
207
          if( display != null ) {
208
            UICallBack.runNonUIThreadWithFakeContext( display, new Runnable() {
209
              public void run() {
210
                jobToRemove.cancel();
211
                jobToRemove.addJobChangeListener( new JobCanceler() );
212
              }
213
            } );
214
          }
215
          try {
216
            IJobManager jobManager = Job.getJobManager();
217
            Class clazz = jobManager.getClass();
218
            Field running = clazz.getDeclaredField( "running" );
219
            running.setAccessible( true );
220
            Set set = ( Set )running.get( jobManager );
221
            synchronized( lock ) {
222
              set.remove( keyToRemove );
223
              // still sometimes job get catched - use the job marker adapter
224
              // to check whether they can be eliminated
225
              Object[] runningJobs = set.toArray();
226
              for( int i = 0; i < runningJobs.length; i++ ) {
227
                Job toCheck = ( Job )runningJobs[ i ];
228
                IJobMarker marker
229
                  = ( IJobMarker )toCheck.getAdapter( IJobMarker.class );
230
                if( marker != null && marker.canBeRemoved() ) {
231
                  set.remove( toCheck );
232
                }
233
              }
234
            }
235
          } catch( final Throwable thr ) {
236
            // TODO [fappel]: exception handling
237
            thr.printStackTrace();
238
          }
239
        }
240
      }
241
    };
242
    session.setAttribute( String.valueOf( watchDog.hashCode() ), watchDog );
243
  }
244
}
(-)Eclipse UI/org/eclipse/ui/internal/progress/ProgressViewUpdater.java (+2 lines)
Lines 17-22 Link Here
17
17
18
import org.eclipse.core.runtime.*;
18
import org.eclipse.core.runtime.*;
19
import org.eclipse.core.runtime.jobs.Job;
19
import org.eclipse.core.runtime.jobs.Job;
20
import org.eclipse.rap.ui.internal.progress.JobCanceler;
21
import org.eclipse.rap.ui.internal.progress.ProgressUtil;
20
import org.eclipse.rwt.RWT;
22
import org.eclipse.rwt.RWT;
21
import org.eclipse.rwt.SessionSingletonBase;
23
import org.eclipse.rwt.SessionSingletonBase;
22
import org.eclipse.rwt.internal.lifecycle.RWTLifeCycle;
24
import org.eclipse.rwt.internal.lifecycle.RWTLifeCycle;
(-)Eclipse UI/org/eclipse/ui/internal/progress/ProgressAnimationItem.java (+1 lines)
Lines 14-19 Link Here
14
import org.eclipse.core.runtime.jobs.Job;
14
import org.eclipse.core.runtime.jobs.Job;
15
import org.eclipse.jface.action.IAction;
15
import org.eclipse.jface.action.IAction;
16
import org.eclipse.osgi.util.NLS;
16
import org.eclipse.osgi.util.NLS;
17
import org.eclipse.rap.ui.internal.progress.ProgressUtil;
17
import org.eclipse.swt.SWT;
18
import org.eclipse.swt.SWT;
18
import org.eclipse.swt.events.*;
19
import org.eclipse.swt.events.*;
19
import org.eclipse.swt.graphics.Image;
20
import org.eclipse.swt.graphics.Image;
(-)Eclipse UI/org/eclipse/ui/internal/progress/ProgressMonitorJobsDialog.java (+1 lines)
Lines 18-23 Link Here
18
import org.eclipse.jface.operation.IRunnableWithProgress;
18
import org.eclipse.jface.operation.IRunnableWithProgress;
19
import org.eclipse.jface.viewers.Viewer;
19
import org.eclipse.jface.viewers.Viewer;
20
import org.eclipse.jface.viewers.ViewerComparator;
20
import org.eclipse.jface.viewers.ViewerComparator;
21
import org.eclipse.rap.ui.internal.progress.ProgressUtil;
21
import org.eclipse.rwt.graphics.Graphics;
22
import org.eclipse.rwt.graphics.Graphics;
22
import org.eclipse.swt.SWT;
23
import org.eclipse.swt.SWT;
23
import org.eclipse.swt.events.SelectionAdapter;
24
import org.eclipse.swt.events.SelectionAdapter;
(-)Eclipse UI/org/eclipse/ui/internal/progress/ProgressManager.java (-2 / +5 lines)
Lines 24-29 Link Here
24
import org.eclipse.jface.operation.IRunnableContext;
24
import org.eclipse.jface.operation.IRunnableContext;
25
import org.eclipse.jface.operation.IRunnableWithProgress;
25
import org.eclipse.jface.operation.IRunnableWithProgress;
26
import org.eclipse.jface.resource.*;
26
import org.eclipse.jface.resource.*;
27
import org.eclipse.rap.ui.internal.progress.ProgressUtil;
27
import org.eclipse.rwt.SessionSingletonBase;
28
import org.eclipse.rwt.SessionSingletonBase;
28
import org.eclipse.swt.custom.BusyIndicator;
29
import org.eclipse.swt.custom.BusyIndicator;
29
import org.eclipse.swt.graphics.Image;
30
import org.eclipse.swt.graphics.Image;
Lines 98-104 Link Here
98
99
99
	final Object listenersKey = new Object();
100
	final Object listenersKey = new Object();
100
101
101
	IJobChangeListener changeListener;
102
	// RAP [bm]: made public to access in org.eclipse.rap.ui.*
103
	public IJobChangeListener changeListener;
102
104
103
	static final String PROGRESS_VIEW_NAME = "org.eclipse.ui.views.ProgressView"; //$NON-NLS-1$
105
	static final String PROGRESS_VIEW_NAME = "org.eclipse.ui.views.ProgressView"; //$NON-NLS-1$
104
106
Lines 360-366 Link Here
360
	/**
362
	/**
361
	 * Create a new instance of the receiver.
363
	 * Create a new instance of the receiver.
362
	 */
364
	 */
363
	ProgressManager() {
365
	// RAP [bm]: made public to access in org.eclipse.rap.ui.*
366
	public ProgressManager() {
364
// RAP [fappel]:	  
367
// RAP [fappel]:	  
365
//		Job.getJobManager().setProgressProvider(this);
368
//		Job.getJobManager().setProgressProvider(this);
366
//		Dialog.setBlockedHandler(new WorkbenchDialogBlockedHandler());
369
//		Dialog.setBlockedHandler(new WorkbenchDialogBlockedHandler());
(-)Eclipse UI/org/eclipse/ui/internal/progress/AnimationManager.java (+2 lines)
Lines 17-22 Link Here
17
17
18
import org.eclipse.core.runtime.*;
18
import org.eclipse.core.runtime.*;
19
import org.eclipse.core.runtime.jobs.Job;
19
import org.eclipse.core.runtime.jobs.Job;
20
import org.eclipse.rap.ui.internal.progress.IJobMarker;
21
import org.eclipse.rap.ui.internal.progress.JobCanceler;
20
import org.eclipse.rwt.RWT;
22
import org.eclipse.rwt.RWT;
21
import org.eclipse.rwt.SessionSingletonBase;
23
import org.eclipse.rwt.SessionSingletonBase;
22
import org.eclipse.rwt.lifecycle.UICallBack;
24
import org.eclipse.rwt.lifecycle.UICallBack;
(-)META-INF/MANIFEST.MF (+3 lines)
Lines 15-21 Link Here
15
 org.eclipse.rap.ui.interactiondesign.internal;x-friends:="org.eclipse.rap.ui.tests",
15
 org.eclipse.rap.ui.interactiondesign.internal;x-friends:="org.eclipse.rap.ui.tests",
16
 org.eclipse.rap.ui.interactiondesign.layout,
16
 org.eclipse.rap.ui.interactiondesign.layout,
17
 org.eclipse.rap.ui.interactiondesign.layout.model,
17
 org.eclipse.rap.ui.interactiondesign.layout.model,
18
 org.eclipse.rap.ui.internal;x-internal:=true,
18
 org.eclipse.rap.ui.internal.branding;x-internal:=true,
19
 org.eclipse.rap.ui.internal.branding;x-internal:=true,
20
 org.eclipse.rap.ui.internal.preferences;x-internal:=true,
21
 org.eclipse.rap.ui.internal.progress;x-internal:=true,
19
 org.eclipse.rap.ui.internal.servlet;x-internal:=true,
22
 org.eclipse.rap.ui.internal.servlet;x-internal:=true,
20
 org.eclipse.ui;ui.workbench=split;mandatory:="ui.workbench",
23
 org.eclipse.ui;ui.workbench=split;mandatory:="ui.workbench",
21
 org.eclipse.ui.about,
24
 org.eclipse.ui.about,
(-)Eclipse UI/org/eclipse/ui/progress/DeferredTreeContentManager.java (-1 / +1 lines)
Lines 15-25 Link Here
15
import org.eclipse.jface.viewers.AbstractTreeViewer;
15
import org.eclipse.jface.viewers.AbstractTreeViewer;
16
import org.eclipse.jface.viewers.ITreeContentProvider;
16
import org.eclipse.jface.viewers.ITreeContentProvider;
17
import org.eclipse.osgi.util.NLS;
17
import org.eclipse.osgi.util.NLS;
18
import org.eclipse.rap.ui.internal.progress.ProgressUtil;
18
import org.eclipse.swt.widgets.Control;
19
import org.eclipse.swt.widgets.Control;
19
import org.eclipse.swt.widgets.Display;
20
import org.eclipse.swt.widgets.Display;
20
import org.eclipse.ui.IWorkbenchPartSite;
21
import org.eclipse.ui.IWorkbenchPartSite;
21
import org.eclipse.ui.internal.progress.ProgressMessages;
22
import org.eclipse.ui.internal.progress.ProgressMessages;
22
import org.eclipse.ui.internal.progress.ProgressUtil;
23
import org.eclipse.ui.internal.util.Util;
23
import org.eclipse.ui.internal.util.Util;
24
import org.eclipse.ui.model.IWorkbenchAdapter;
24
import org.eclipse.ui.model.IWorkbenchAdapter;
25
25
(-)Eclipse UI/org/eclipse/ui/progress/WorkbenchJob.java (-1 / +1 lines)
Lines 13-20 Link Here
13
import org.eclipse.core.runtime.IStatus;
13
import org.eclipse.core.runtime.IStatus;
14
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
14
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
15
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
15
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
16
import org.eclipse.rap.ui.internal.progress.ProgressUtil;
16
import org.eclipse.swt.widgets.Display;
17
import org.eclipse.swt.widgets.Display;
17
import org.eclipse.ui.internal.progress.ProgressUtil;
18
18
19
/**
19
/**
20
 * WorkbenchJob is a type of job that implements a done listener
20
 * WorkbenchJob is a type of job that implements a done listener
(-)Eclipse UI/org/eclipse/ui/internal/util/SessionSingletonEventManager.java (-75 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2002, 2008 Innoopract Informationssysteme GmbH.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.ui.internal.util;
13
14
import org.eclipse.core.commands.common.EventManager;
15
import org.eclipse.rwt.SessionSingletonBase;
16
17
18
public class SessionSingletonEventManager extends SessionSingletonBase {
19
20
	/*
21
	 * As Workbench needs to inherit from EventManager AND SessionSingleton
22
	 * we introduced a new layer in between to fake the methods.
23
	 * As EventManager is abstract and has final methods, we use methodE()
24
	 * to delegate to the original 
25
	 */
26
	private final class EventManagerExtension extends EventManager {
27
		public synchronized final void addListenerObjectE(final Object listener) {
28
			addListenerObject( listener );
29
		}
30
31
		public synchronized final void clearListenersE() {
32
			clearListeners();
33
		}
34
35
		public final Object[] getListenersE() {
36
			return getListeners();
37
		}
38
39
		public final boolean isListenerAttachedE() {
40
			return isListenerAttached();
41
		}
42
43
		public synchronized final void removeListenerObjectE(final Object listener) {
44
			removeListenerObject( listener );
45
		}
46
	}
47
48
	private EventManagerExtension manager;
49
	
50
	public SessionSingletonEventManager() {
51
52
		manager = new EventManagerExtension();
53
	}
54
	
55
	protected synchronized final void addListenerObject(final Object listener) {
56
		manager.addListenerObjectE( listener );
57
	}
58
	
59
	protected synchronized final void clearListeners() {
60
		manager.clearListenersE();
61
	}
62
	
63
	protected final Object[] getListeners() {
64
		return manager.getListenersE();
65
	}
66
	
67
	protected final boolean isListenerAttached() {
68
		return manager.isListenerAttachedE();
69
	}
70
	
71
	protected synchronized final void removeListenerObject(final Object listener) {
72
		manager.removeListenerObjectE( listener );
73
	}
74
	
75
}
(-)Eclipse UI/org/eclipse/ui/internal/themes/WorkbenchThemeManager.java (-1 / +1 lines)
Lines 19-24 Link Here
19
import org.eclipse.jface.resource.JFaceResources;
19
import org.eclipse.jface.resource.JFaceResources;
20
import org.eclipse.jface.util.IPropertyChangeListener;
20
import org.eclipse.jface.util.IPropertyChangeListener;
21
import org.eclipse.jface.util.PropertyChangeEvent;
21
import org.eclipse.jface.util.PropertyChangeEvent;
22
import org.eclipse.rap.ui.internal.SessionSingletonEventManager;
22
import org.eclipse.swt.graphics.FontData;
23
import org.eclipse.swt.graphics.FontData;
23
import org.eclipse.swt.graphics.RGB;
24
import org.eclipse.swt.graphics.RGB;
24
import org.eclipse.ui.IWorkbenchPreferenceConstants;
25
import org.eclipse.ui.IWorkbenchPreferenceConstants;
Lines 26-32 Link Here
26
import org.eclipse.ui.internal.WorkbenchPlugin;
27
import org.eclipse.ui.internal.WorkbenchPlugin;
27
import org.eclipse.ui.internal.misc.StatusUtil;
28
import org.eclipse.ui.internal.misc.StatusUtil;
28
import org.eclipse.ui.internal.util.PrefUtil;
29
import org.eclipse.ui.internal.util.PrefUtil;
29
import org.eclipse.ui.internal.util.SessionSingletonEventManager;
30
import org.eclipse.ui.statushandlers.StatusManager;
30
import org.eclipse.ui.statushandlers.StatusManager;
31
import org.eclipse.ui.themes.ITheme;
31
import org.eclipse.ui.themes.ITheme;
32
import org.eclipse.ui.themes.IThemeManager;
32
import org.eclipse.ui.themes.IThemeManager;
(-)Eclipse UI/org/eclipse/ui/internal/registry/EditorRegistry.java (-1 / +1 lines)
Lines 44-49 Link Here
44
import org.eclipse.jface.preference.IPreferenceStore;
44
import org.eclipse.jface.preference.IPreferenceStore;
45
import org.eclipse.jface.resource.ImageDescriptor;
45
import org.eclipse.jface.resource.ImageDescriptor;
46
import org.eclipse.jface.util.SafeRunnable;
46
import org.eclipse.jface.util.SafeRunnable;
47
import org.eclipse.rap.ui.internal.SessionSingletonEventManager;
47
import org.eclipse.swt.widgets.Shell;
48
import org.eclipse.swt.widgets.Shell;
48
import org.eclipse.ui.IEditorDescriptor;
49
import org.eclipse.ui.IEditorDescriptor;
49
import org.eclipse.ui.IEditorRegistry;
50
import org.eclipse.ui.IEditorRegistry;
Lines 62-68 Link Here
62
import org.eclipse.ui.internal.WorkbenchMessages;
63
import org.eclipse.ui.internal.WorkbenchMessages;
63
import org.eclipse.ui.internal.WorkbenchPlugin;
64
import org.eclipse.ui.internal.WorkbenchPlugin;
64
import org.eclipse.ui.internal.editorsupport.ComponentSupport;
65
import org.eclipse.ui.internal.editorsupport.ComponentSupport;
65
import org.eclipse.ui.internal.util.SessionSingletonEventManager;
66
import org.eclipse.ui.internal.util.Util;
66
import org.eclipse.ui.internal.util.Util;
67
67
68
import com.ibm.icu.text.Collator;
68
import com.ibm.icu.text.Collator;
(-)Eclipse UI/org/eclipse/rap/ui/internal/servlet/EngineConfigWrapper.java (-1 / +1 lines)
Lines 17-22 Link Here
17
import java.text.MessageFormat;
17
import java.text.MessageFormat;
18
18
19
import org.eclipse.core.runtime.*;
19
import org.eclipse.core.runtime.*;
20
import org.eclipse.rap.ui.internal.preferences.WorkbenchFileSettingStoreFactory;
20
import org.eclipse.rwt.internal.*;
21
import org.eclipse.rwt.internal.*;
21
import org.eclipse.rwt.internal.engine.RWTServletContextListener;
22
import org.eclipse.rwt.internal.engine.RWTServletContextListener;
22
import org.eclipse.rwt.internal.lifecycle.*;
23
import org.eclipse.rwt.internal.lifecycle.*;
Lines 30-36 Link Here
30
import org.eclipse.rwt.service.ISettingStoreFactory;
31
import org.eclipse.rwt.service.ISettingStoreFactory;
31
import org.eclipse.ui.PlatformUI;
32
import org.eclipse.ui.PlatformUI;
32
import org.eclipse.ui.internal.WorkbenchPlugin;
33
import org.eclipse.ui.internal.WorkbenchPlugin;
33
import org.eclipse.ui.internal.preferences.WorkbenchFileSettingStoreFactory;
34
import org.osgi.framework.Bundle;
34
import org.osgi.framework.Bundle;
35
35
36
36
(-)Eclipse (+183 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Innoopract Informationssysteme GmbH.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.rap.ui.internal.preferences;
12
13
import org.eclipse.core.runtime.*;
14
import org.eclipse.core.runtime.preferences.IEclipsePreferences.*;
15
import org.eclipse.rwt.RWT;
16
import org.eclipse.rwt.internal.util.ParamCheck;
17
import org.eclipse.rwt.service.*;
18
import org.eclipse.ui.internal.WorkbenchPlugin;
19
import org.osgi.service.prefs.Preferences;
20
21
/**
22
 * This class is the link between the SessionPreferenceNode hierarchy 
23
 * (application global) the RWT setting store (session specific).
24
 */
25
final class SessionPreferenceNodeCore {
26
  
27
  private final SessionPreferencesNode node;
28
  private ListenerList prefListeners; // ListenerList is thread safe
29
  private final ListenerList nodeListeners       
30
    = new ListenerList( ListenerList.IDENTITY ); // thread safe
31
32
33
  /* tracks changes in RWT setting store and notifies the prefListeners */
34
  private SettingStoreListener rwtListener;
35
  /* true to track RWT changes */
36
  private boolean trackChanges = true;
37
  /* ignore changes to this key for a short time */
38
  private String ignoreKey;
39
  
40
  SessionPreferenceNodeCore( final SessionPreferencesNode node ) {
41
    ParamCheck.notNull( node, "node" ); //$NON-NLS-1$
42
    this.node = node;
43
  }
44
  
45
  void addPreferenceChangeListener( IPreferenceChangeListener listener ) {
46
    if( listener != null ) {
47
      getListenerList().add( listener );
48
      setTrackRWTChanges( true );
49
    }
50
  }
51
52
  void removePreferenceChangeListener( IPreferenceChangeListener listener ) {
53
    if( listener != null ) {
54
      ListenerList list = getListenerList();
55
      list.remove( listener );
56
      if( list.isEmpty() ) {
57
        setTrackRWTChanges( false );
58
      }
59
    }
60
  }
61
  
62
  void firePreferenceEvent( final String key, 
63
                            final String oldValue, 
64
                            final String newValue )
65
  {
66
    if( prefListeners != null ) {
67
      final PreferenceChangeEvent event 
68
        = new PreferenceChangeEvent( node, key, oldValue, newValue );
69
      Object[] listeners = prefListeners.getListeners();
70
      for( int i = 0; i < listeners.length; i++ ) {
71
        final IPreferenceChangeListener listener 
72
          = ( IPreferenceChangeListener )listeners[ i ];
73
        ISafeRunnable op = new ISafeRunnable() {
74
          public void handleException( final Throwable exception ) {
75
            // logged by SafeRunner
76
          }
77
          public void run() throws Exception {
78
            listener.preferenceChange( event );
79
          }
80
        };
81
        SafeRunner.run( op );
82
      }
83
    }
84
  }
85
  
86
  void clear() {
87
    if( prefListeners != null ) {
88
      prefListeners.clear();
89
      prefListeners = null;
90
      setTrackRWTChanges( false );
91
    }
92
    nodeListeners.clear();
93
  }
94
  
95
  synchronized String put( final String uniqueKey,
96
                           final String value ) {
97
    ISettingStore store = RWT.getSettingStore();
98
    String result = store.getAttribute( uniqueKey );
99
    try {
100
      ignoreKey = uniqueKey;
101
      store.setAttribute( uniqueKey, value );
102
      ignoreKey = null;
103
    } catch( SettingStoreException exc ) {
104
      String msg = "Could not persist preference: " + uniqueKey; //$NON-NLS-1$
105
      WorkbenchPlugin.log( msg, exc );
106
    }
107
    return result;
108
  }
109
  
110
  // helping methods
111
  //////////////////
112
  
113
  private synchronized ListenerList getListenerList() {
114
    if( prefListeners == null ) {
115
      prefListeners = new ListenerList( ListenerList.IDENTITY );
116
    }
117
    return prefListeners;
118
  }
119
  
120
  private synchronized void setTrackRWTChanges( final boolean doTrack ) {
121
    this.trackChanges = doTrack;
122
    if( trackChanges ) {
123
      if( rwtListener == null ) {
124
       rwtListener = new SettingStoreListener() {
125
        public void settingChanged( SettingStoreEvent event ) {
126
          if( trackChanges ) {
127
            String fullKey = event.getAttributeName();
128
            if( !fullKey.equals( ignoreKey ) ) {
129
              String absPath = node.absolutePath();
130
              if( fullKey.startsWith( absPath ) ) {
131
                String key = fullKey.substring( absPath.length() + 1 );
132
                String oldValue = event.getOldValue();
133
                String newValue = event.getNewValue();
134
                firePreferenceEvent( key, oldValue, newValue );
135
              }
136
            }
137
          }
138
        }
139
       };
140
     }
141
     RWT.getSettingStore().addSettingStoreListener( rwtListener );
142
   } else { // !trackChanges
143
     if( rwtListener != null ) {
144
       RWT.getSettingStore().removeSettingStoreListener( rwtListener );
145
     }
146
   }
147
  }
148
149
  public void addNodeChangeListener( final INodeChangeListener listener ) {
150
    nodeListeners.add( listener );
151
  }
152
153
  public void removeNodeChangeListener( final INodeChangeListener listener ) {
154
    nodeListeners.remove( listener );
155
  }
156
157
  public void fireNodeEvent( final Preferences child,
158
                             final boolean wasAdded,
159
                             final SessionPreferencesNode spn )
160
  {
161
    final NodeChangeEvent event = new NodeChangeEvent( spn, child );
162
    Object[] listeners = nodeListeners.getListeners();
163
    for( int i = 0; i < listeners.length; i++ ) {
164
      final INodeChangeListener listener 
165
        = ( INodeChangeListener )listeners[ i ];
166
      ISafeRunnable op = new ISafeRunnable() {
167
        public void handleException( final Throwable exception ) {
168
          // logged by SafeRunner
169
        }
170
        public void run() throws Exception {
171
          if( wasAdded ) {
172
            listener.added( event );
173
          } else {
174
            listener.removed( event );
175
          }
176
        }
177
      };
178
      SafeRunner.run( op );
179
    }
180
181
  }
182
  
183
}
(-)Eclipse (+70 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Innoopract Informationssysteme GmbH.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.rap.ui.internal.preferences;
12
13
import org.eclipse.core.runtime.IPath;
14
import org.eclipse.core.runtime.Platform;
15
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
16
import org.eclipse.core.runtime.preferences.IScopeContext;
17
import org.eclipse.rwt.RWT;
18
import org.eclipse.rwt.internal.util.ParamCheck;
19
import org.eclipse.rwt.service.FileSettingStore;
20
21
// TODO [fappel]: think about how we can provide this as API (subset rule
22
//                of RAP/RCP)
23
/**
24
 * Object representing the session scope in the Eclipse preferences
25
 * hierarchy. Can be used as a context for searching for preference
26
 * values (in the IPreferenceService APIs) or for determining the
27
 * corrent preference node to set values in the store.
28
 * <p>
29
 * Session preferences are stored on a <i>per-session</i> basis using
30
 * the underlying RWT SettingStore (see {@link RWT#getSettingStore()}. 
31
 * Preferences saved during a previous session will be retrieved, as long as
32
 * the user can identify himself with the setting store cookie. Session 
33
 * preferences are persisted using the setting store implementation
34
 * that is configured for the application (see {@link FileSettingStore}.
35
 * <p>
36
 * The path for preferences defined in the session scope hierarchy is: 
37
 * <code>/session/&lt;qualifier&gt;</code>
38
 * <p>
39
 * This class is not intented to be subclassed. It may be instantiated.
40
 *
41
 */
42
public final class SessionScope implements IScopeContext {
43
44
  /**
45
   * String constant (value of <code>"session"</code>) used for the 
46
   * scope name for the session preference scope.
47
   */
48
  public static final String SCOPE = "session"; //$NON-NLS-1$
49
  
50
  /**
51
   * Create and return a new session scope instance.
52
   */
53
  public SessionScope() {
54
    super();
55
  }
56
57
  public IPath getLocation() {
58
    return null;
59
  }
60
61
  public String getName() {
62
    return SCOPE;
63
  }
64
65
  public IEclipsePreferences getNode( String qualifier ) {
66
    ParamCheck.notNull( qualifier, "qualifier" ); //$NON-NLS-1$
67
    IEclipsePreferences root = Platform.getPreferencesService().getRootNode();
68
    return ( IEclipsePreferences ) root.node( SCOPE ).node( qualifier );
69
  }
70
}
(-)Eclipse (+20 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2002, 2008 Innoopract Informationssysteme GmbH.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.rap.ui.internal.progress;
13
14
// RAP [fappel]: This is a helper class used to avoid a memory leak due to 
15
//               thread management.
16
//               Note that this is still under investigation.
17
//               See comment in JobManagerAdapter
18
public interface IJobMarker {
19
  boolean canBeRemoved();
20
}
(-)Eclipse (+34 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2002, 2008 Innoopract Informationssysteme GmbH.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.rap.ui.internal.progress;
13
14
import org.eclipse.rwt.lifecycle.UICallBack;
15
import org.eclipse.swt.widgets.Display;
16
import org.eclipse.ui.PlatformUI;
17
18
// RAP [fappel]:
19
public final class ProgressUtil {
20
  
21
  private ProgressUtil() {
22
    // prevent instance creation
23
  }
24
  
25
  public static boolean isWorkbenchRunning( final Display display ) {
26
    final boolean[] result = new boolean[ 1 ];
27
    UICallBack.runNonUIThreadWithFakeContext( display, new Runnable() {
28
      public void run() {
29
        result[ 0 ] = PlatformUI.isWorkbenchRunning();
30
      }
31
    } );
32
    return result[ 0 ];
33
  }
34
}
(-)Eclipse (+46 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2002-2006 Innoopract Informationssysteme GmbH.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.rap.ui.internal.progress;
13
14
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
15
import org.eclipse.core.runtime.jobs.IJobChangeListener;
16
17
// RAP [fappel]: This is a helper class used to avoid a memory leak due to 
18
//               thread management.
19
//               Note that this is still under investigation.
20
//               See comment in JobManagerAdapter
21
public final class JobCanceler implements IJobChangeListener {
22
23
  public void aboutToRun( IJobChangeEvent event ) {
24
    event.getJob().cancel();
25
  }
26
27
  public void awake( IJobChangeEvent event ) {
28
    event.getJob().cancel();
29
  }
30
31
  public void done( IJobChangeEvent event ) {
32
    event.getJob().cancel();
33
  }
34
35
  public void running( IJobChangeEvent event ) {
36
    event.getJob().cancel();
37
  }
38
39
  public void scheduled( IJobChangeEvent event ) {
40
    event.getJob().cancel();
41
  }
42
43
  public void sleeping( IJobChangeEvent event ) {
44
    event.getJob().cancel();
45
  }
46
}
(-)Eclipse (+27 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Innoopract Informationssysteme GmbH.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.rap.ui.internal.preferences;
12
13
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
14
import org.eclipse.core.runtime.preferences.IScope;
15
16
/**
17
 * Creates "session" scoped preference nodes.
18
 */
19
public final class SessionPreferencesFactory implements IScope {
20
21
  public IEclipsePreferences create( final IEclipsePreferences parent, 
22
                                     final String name )
23
  {
24
    return new SessionPreferencesNode( parent, name );
25
  }
26
  
27
}
(-)Eclipse (+85 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Innoopract Informationssysteme GmbH.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.rap.ui.internal.preferences;
12
13
14
import java.io.File;
15
16
import org.eclipse.core.runtime.IPath;
17
import org.eclipse.core.runtime.Platform;
18
import org.eclipse.rwt.RWT;
19
import org.eclipse.rwt.internal.util.ParamCheck;
20
import org.eclipse.rwt.service.*;
21
import org.eclipse.ui.PlatformUI;
22
import org.osgi.framework.Bundle;
23
24
25
/**
26
 * {@link ISettingStoreFactory} that creates {@link FileSettingStore} 
27
 * instances.
28
 * <p>
29
 * This particular implementation uses the following strategy to determine
30
 * the path for persisting the data of a FileSettingStore:
31
 * <ol>
32
 * <li>Use the directory specified by the system property 
33
 * <code>"org.eclipse.rwt.service.FileSettingStore.dir"</code>.
34
 * </li>
35
 * <li>Use a subdirectory in the state location of the  
36
 * org.eclipse.rap.ui.workbench bundle.
37
 * </li>
38
 * </ol>
39
 * The first path that can be obtained from the above choices (in the order
40
 * given above) will be used. If the path determined does not exist it will
41
 * be created.
42
 * <p>
43
 * <b>Note:</b> This setting store factory should be used in a regular
44
 * RAP deployment. For an RWT only deployment use the 
45
 * {@link RWTFileSettingStoreFactory}.
46
 * 
47
 */
48
public final class WorkbenchFileSettingStoreFactory
49
  implements ISettingStoreFactory
50
{
51
  
52
  public ISettingStore createSettingStore( final String storeId ) {
53
    ParamCheck.notNullOrEmpty( storeId, "storeId" ); //$NON-NLS-1$
54
    ISettingStore result = new FileSettingStore( getWorkDir() );
55
    try {
56
      result.loadById( storeId );
57
    } catch( SettingStoreException sse ) {
58
      String msg = String.valueOf( sse.getMessage() );
59
      RWT.getRequest().getSession().getServletContext().log( msg, sse );
60
    }
61
    return result;
62
  }
63
  
64
  //////////////////
65
  // helping methods
66
  
67
  private File getWorkDir() {
68
    File result = getWorkDirFromEnvironment();
69
    if( result == null ) {
70
      Bundle bundle = Platform.getBundle( PlatformUI.PLUGIN_ID );
71
      IPath stateLoc = Platform.getStateLocation( bundle );
72
      File parentDir = stateLoc.toFile();
73
      result = new File( parentDir, FileSettingStore.class.getName() );
74
    }
75
    if( !result.exists() ) {
76
      result.mkdirs();
77
    }
78
    return result;
79
  }
80
  
81
  private File getWorkDirFromEnvironment() {
82
    String path = System.getProperty( FileSettingStore.FILE_SETTING_STORE_DIR );
83
    return ( path != null ) ? new File( path ) : null;
84
  }
85
}
(-)Eclipse (+245 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007, 2008 Innoopract Informationssysteme GmbH.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.rap.ui.internal.progress;
12
13
import java.lang.reflect.Field;
14
import java.util.*;
15
16
import javax.servlet.http.HttpSessionBindingEvent;
17
import javax.servlet.http.HttpSessionBindingListener;
18
19
import org.eclipse.core.runtime.IProgressMonitor;
20
import org.eclipse.core.runtime.jobs.*;
21
import org.eclipse.rwt.RWT;
22
import org.eclipse.rwt.internal.lifecycle.RWTLifeCycle;
23
import org.eclipse.rwt.internal.service.ContextProvider;
24
import org.eclipse.rwt.lifecycle.UICallBack;
25
import org.eclipse.rwt.service.ISessionStore;
26
import org.eclipse.swt.widgets.Display;
27
import org.eclipse.ui.internal.progress.ProgressManager;
28
29
// RAP [fappel]:
30
public class JobManagerAdapter
31
  extends ProgressProvider
32
  implements IJobChangeListener
33
{
34
  
35
  private static JobManagerAdapter _instance;
36
  private final Map jobs;
37
  private final ProgressManager defaultProgressManager;
38
  final Object lock;
39
40
  public static synchronized JobManagerAdapter getInstance() {
41
    if( _instance == null ) {
42
      _instance = new JobManagerAdapter();
43
    }
44
    return _instance;
45
  }
46
  
47
  
48
  private JobManagerAdapter() {
49
    // To avoid deadlocks we have to use the same synchronisation lock.
50
    // If anyone has a better idea - you're welcome.
51
    IJobManager jobManager = Job.getJobManager();
52
    Class clazz = jobManager.getClass();
53
    try {
54
      Field jobManagerLock = clazz.getDeclaredField( "lock" );
55
      jobManagerLock.setAccessible( true );
56
      lock = jobManagerLock.get( jobManager );
57
    } catch( final Throwable thr ) {
58
      String msg = "Could not initialize synchronization lock.";
59
      throw new IllegalStateException( msg );
60
    }
61
    jobs = new HashMap();
62
    defaultProgressManager = new ProgressManager();
63
    Job.getJobManager().setProgressProvider( this );
64
    Job.getJobManager().addJobChangeListener( this );
65
  }
66
  
67
  
68
  ///////////////////////////////
69
  // ProgressProvider
70
  
71
  public IProgressMonitor createMonitor( final Job job ) {
72
    ProgressManager manager = findProgressManager( job );
73
    return manager.createMonitor( job );
74
  }
75
  
76
  public IProgressMonitor createMonitor( final Job job,
77
                                         final IProgressMonitor group,
78
                                         final int ticks )
79
  {
80
    ProgressManager manager = findProgressManager( job );
81
    return manager.createMonitor( job, group, ticks );
82
  }
83
  
84
  public IProgressMonitor createProgressGroup() {
85
    return defaultProgressManager.createProgressGroup();
86
  }
87
  
88
  
89
  ///////////////////////////////
90
  // interface IJobChangeListener
91
  
92
  public void aboutToRun( final IJobChangeEvent event ) {
93
    ProgressManager manager = findProgressManager( event.getJob() );
94
    manager.changeListener.aboutToRun( event );
95
  }
96
97
  public void awake( final IJobChangeEvent event ) {
98
    ProgressManager manager = findProgressManager( event.getJob() );
99
    manager.changeListener.awake( event );
100
  }
101
102
  public void done( final IJobChangeEvent event ) {
103
    final ProgressManager[] manager = new ProgressManager[ 1 ];
104
    Display display = null;
105
    synchronized( lock ) {
106
      try {
107
        manager[ 0 ] = findProgressManager( event.getJob() );
108
        display = ( Display )jobs.get( event.getJob() );
109
        if( display != null ) {
110
          display.asyncExec( new Runnable() {
111
            public void run() {
112
              Job job = event.getJob();
113
              String id = String.valueOf( job.hashCode() );
114
              UICallBack.deactivate( id );
115
            }
116
          } );
117
        }
118
      } finally {
119
        jobs.remove( event.getJob() );
120
      }
121
    }
122
    if( display != null ) {
123
      display.asyncExec( new Runnable() {
124
        public void run() {
125
          manager[ 0 ].changeListener.done( event );
126
        }
127
      } );
128
//    } else {
129
//      manager[ 0 ].changeListener.done( event );      
130
    }
131
  }
132
133
  public void running( final IJobChangeEvent event ) {
134
    ProgressManager manager = findProgressManager( event.getJob() );
135
    manager.changeListener.running( event );
136
  }
137
138
  public void scheduled( final IJobChangeEvent event ) {
139
    ProgressManager manager;
140
    synchronized( lock ) {
141
      if( ContextProvider.hasContext() ) {
142
        jobs.put( event.getJob(), RWTLifeCycle.getSessionDisplay() );
143
        bindToSession( event.getJob() );
144
        String id = String.valueOf( event.getJob().hashCode() );
145
        UICallBack.activate( id );
146
      }
147
      manager = findProgressManager( event.getJob() );
148
    }
149
    manager.changeListener.scheduled( event );
150
  }
151
152
  public void sleeping( final IJobChangeEvent event ) {
153
    ProgressManager manager = findProgressManager( event.getJob() );
154
    manager.changeListener.sleeping( event );
155
  }
156
157
  
158
  //////////////////
159
  // helping methods
160
  
161
  private ProgressManager findProgressManager( final Job job ) {
162
    synchronized( lock ) {
163
      final ProgressManager result[] = new ProgressManager[ 1 ];
164
      Display display = ( Display )jobs.get( job );
165
      if( display != null ) {
166
        UICallBack.runNonUIThreadWithFakeContext( display, new Runnable() {
167
          public void run() {
168
            result[ 0 ] = ProgressManager.getInstance();
169
          }
170
        } );
171
        if( result[ 0 ] == null ) {
172
          String msg = "ProgressManager must not be null.";
173
          throw new IllegalStateException( msg );
174
        }
175
      } else {
176
        result[ 0 ] = defaultProgressManager;
177
      }
178
      return result[ 0 ];
179
    }
180
  }
181
  
182
  private void bindToSession( final Object keyToRemove ) {
183
    ISessionStore session = RWT.getSessionStore();
184
    HttpSessionBindingListener watchDog = new HttpSessionBindingListener() {
185
      public void valueBound( final HttpSessionBindingEvent event ) {
186
      }
187
      public void valueUnbound( final HttpSessionBindingEvent event ) {
188
        try {
189
          handleWatchDog( keyToRemove );
190
        } finally {
191
          synchronized( lock ) {
192
            jobs.remove( keyToRemove );
193
          }
194
        }
195
      }
196
197
      private void handleWatchDog( final Object keyToRemove ) {
198
        // ////////////////////////////////////////////////////////////////////
199
        // TODO [fappel]: Very ugly hack to avoid a memory leak.
200
        // As a job can not be removed from the
201
        // running set directly, I use reflection. Jobs
202
        // can be catched in the set on session timeouts.
203
        // Don't know a proper solution yet.
204
        // Note that this is still under investigation.
205
        if( keyToRemove instanceof Job ) {
206
          final Job jobToRemove = ( Job )keyToRemove;
207
          Display display = ( Display )jobs.get( jobToRemove );
208
          if( display != null ) {
209
            UICallBack.runNonUIThreadWithFakeContext( display, new Runnable() {
210
              public void run() {
211
                jobToRemove.cancel();
212
                jobToRemove.addJobChangeListener( new JobCanceler() );
213
              }
214
            } );
215
          }
216
          try {
217
            IJobManager jobManager = Job.getJobManager();
218
            Class clazz = jobManager.getClass();
219
            Field running = clazz.getDeclaredField( "running" );
220
            running.setAccessible( true );
221
            Set set = ( Set )running.get( jobManager );
222
            synchronized( lock ) {
223
              set.remove( keyToRemove );
224
              // still sometimes job get catched - use the job marker adapter
225
              // to check whether they can be eliminated
226
              Object[] runningJobs = set.toArray();
227
              for( int i = 0; i < runningJobs.length; i++ ) {
228
                Job toCheck = ( Job )runningJobs[ i ];
229
                IJobMarker marker
230
                  = ( IJobMarker )toCheck.getAdapter( IJobMarker.class );
231
                if( marker != null && marker.canBeRemoved() ) {
232
                  set.remove( toCheck );
233
                }
234
              }
235
            }
236
          } catch( final Throwable thr ) {
237
            // TODO [fappel]: exception handling
238
            thr.printStackTrace();
239
          }
240
        }
241
      }
242
    };
243
    session.setAttribute( String.valueOf( watchDog.hashCode() ), watchDog );
244
  }
245
}
(-)Eclipse (+508 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 Innoopract Informationssysteme GmbH.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Innoopract Informationssysteme GmbH - initial API and implementation
10
 ******************************************************************************/
11
package org.eclipse.rap.ui.internal.preferences;
12
13
import java.util.*;
14
15
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
16
import org.eclipse.core.runtime.preferences.IPreferenceNodeVisitor;
17
import org.eclipse.osgi.util.NLS;
18
import org.eclipse.rwt.RWT;
19
import org.eclipse.rwt.internal.util.ParamCheck;
20
import org.eclipse.rwt.service.ISettingStore;
21
import org.eclipse.rwt.service.SettingStoreException;
22
import org.eclipse.ui.internal.preferences.Base64;
23
import org.osgi.service.prefs.BackingStoreException;
24
import org.osgi.service.prefs.Preferences;
25
26
/**
27
 * This node use the RWT setting store to persist its preferences.
28
 */
29
final class SessionPreferencesNode implements IEclipsePreferences {
30
31
  private static final String PATH_SEPARATOR = "/"; //$NON-NLS-1$
32
  private static final String DOUBLE_PATH_SEPARATOR = "//"; //$NON-NLS-1$
33
  private static final String TRUE  = "true"; //$NON-NLS-1$
34
  private static final String FALSE = "false"; //$NON-NLS-1$
35
  
36
  private final String name;
37
  private final IEclipsePreferences parent;
38
  private boolean isRemoved;
39
  /* cache the absolutePath once it has been computed */
40
  private String absolutePath;
41
  
42
  private final Map children = new HashMap();    // !thread safe
43
  
44
  SessionPreferencesNode( final IEclipsePreferences parent, 
45
                          final String name )
46
  {
47
    ParamCheck.notNull( parent, "parent" ); //$NON-NLS-1$
48
    ParamCheck.notNull( name, "name" ); //$NON-NLS-1$
49
    checkName( name );
50
    this.parent = parent;
51
    this.name = name;
52
  }
53
  
54
  public void accept( final IPreferenceNodeVisitor visitor )
55
    throws BackingStoreException
56
  {
57
    boolean withChildren = visitor.visit( this );
58
    if( withChildren ) {
59
      Object[] childrenArray;
60
      synchronized( this ) {
61
        childrenArray = children.values().toArray();
62
      }
63
      for( int i = 0; i < childrenArray.length; i++ ) {
64
        IEclipsePreferences child = ( IEclipsePreferences )childrenArray[ i ];
65
        child.accept( visitor );
66
      }
67
    }
68
  }
69
70
  public void addNodeChangeListener( final INodeChangeListener listener ) {
71
    checkRemoved();
72
    if( listener != null ) {
73
      getNodeCore().addNodeChangeListener( listener );
74
    }
75
  }
76
77
  public void addPreferenceChangeListener( 
78
    final IPreferenceChangeListener listener )
79
  {
80
    checkRemoved();
81
    getNodeCore().addPreferenceChangeListener( listener );
82
  }
83
84
  public Preferences node( final String path ) {
85
    checkPath( path );
86
    checkRemoved();
87
    Preferences result;
88
    if( "".equals( path ) ) { // "" //$NON-NLS-1$
89
      result = this;
90
    } else if( path.startsWith( PATH_SEPARATOR ) ) { // "/absolute/path"
91
      result = findRoot().node( path.substring( 1 ) );
92
    } else if( path.indexOf( PATH_SEPARATOR ) > 0 ) { // "foo/bar/baz"
93
      int index = path.indexOf( PATH_SEPARATOR );
94
      String nodeName = path.substring( 0, index );
95
      String rest = path.substring( index + 1, path.length() ); 
96
      result = getChild( nodeName, true ).node( rest );
97
    } else { // "foo"
98
      result = getChild( path, true );
99
    }
100
    return result;
101
  }
102
103
  public synchronized void removeNode() throws BackingStoreException {
104
    checkRemoved();
105
    // remove all preferences
106
    clear(); 
107
    // remove all children
108
    Object[] childNodes = children.values().toArray();
109
    for( int i = 0; i < childNodes.length; i++ ) {
110
      Preferences child = ( Preferences )childNodes[ i ];
111
      if( child.nodeExists( "" ) ) { // if !removed //$NON-NLS-1$
112
        child.removeNode();
113
      }
114
    }
115
    // remove from parent; this is ugly, because the interface 
116
    // Preference has no API for removing oneself from the parent.
117
    // In general the parent will be a SessionPreferencesNode.
118
    // The only case in the workbench where this is not true, is one level
119
    // below the root (i.e. at /session ), but the scope root must not
120
    // be removable (see IEclipsePreferences#removeNode())
121
    if( parent instanceof SessionPreferencesNode ) {
122
      // this means: 
123
      // (a) we know what kind of parent we have, and 
124
      // (b) we are not the scope root, since that has a 
125
      /// RootPreference as a parent
126
      SessionPreferencesNode spnParent 
127
        = ( ( SessionPreferencesNode ) parent );
128
      spnParent.children.remove( name );
129
      spnParent.fireNodeEvent( this, false );
130
131
      // the listeners are not needed anymore
132
      getNodeCore().clear();
133
      children.clear();
134
      isRemoved = true;
135
    }
136
  }
137
138
  public void removeNodeChangeListener( final INodeChangeListener listener ) {
139
    checkRemoved();
140
    if( listener != null ) {
141
      getNodeCore().removeNodeChangeListener( listener );
142
    }
143
  }
144
145
  public void removePreferenceChangeListener( 
146
    final IPreferenceChangeListener listener )
147
  {
148
    checkRemoved();
149
    getNodeCore().removePreferenceChangeListener( listener );
150
  }
151
152
  public String absolutePath() {
153
    if( absolutePath == null ) {
154
      if( parent == null ) {
155
        absolutePath = name;
156
      } else {
157
        String parentPath =  parent.absolutePath();
158
        absolutePath = parentPath.endsWith( PATH_SEPARATOR ) 
159
                     ? parentPath + name
160
                     : parentPath + PATH_SEPARATOR + name;
161
      }
162
    }
163
    return absolutePath;
164
  }
165
166
  public synchronized String[] childrenNames() {
167
    checkRemoved();
168
    Set names = children.keySet();
169
    return ( String[] )names.toArray( new String[ names.size() ] );
170
  }
171
172
  public void clear() {
173
    checkRemoved();
174
    String[] keys = internalGetKeys();
175
    for( int i = 0; i < keys.length; i++ ) {
176
      remove( keys[ i ] );
177
    }
178
  }
179
180
  public void flush() {
181
    checkRemoved();
182
    // the current implementation persists everytime the preferences 
183
    // are modified, so there's nothing to do here
184
  }
185
186
  public String get( final String key, final String def ) {
187
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
188
    checkRemoved();
189
    String result = internalGet( key );
190
    return result == null ? def : result;
191
  }
192
193
  public boolean getBoolean( final String key, final boolean def ) {
194
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
195
    checkRemoved();
196
    String value = internalGet( key );
197
    return value == null ? def : Boolean.valueOf( value ).booleanValue();
198
  }
199
200
  public byte[] getByteArray( final String key, final byte[] def ) {
201
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
202
    checkRemoved();
203
    String value = internalGet( key );
204
    return value == null ? def : Base64.decode( value.getBytes() );
205
  }
206
207
  public double getDouble( final String key, final double def ) {
208
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
209
    checkRemoved();
210
    String value = internalGet( key );
211
    double result = def;
212
    if( value != null ) {
213
      try {
214
        result = Double.parseDouble( value );
215
      } catch( NumberFormatException nfe ) {
216
        // returns def
217
      }
218
    }
219
    return result;
220
  }
221
222
  public float getFloat( final String key, final float def ) {
223
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
224
    checkRemoved();
225
    String value = internalGet( key );
226
    float result = def;
227
    if( value != null ) {
228
      try {
229
        result = Float.parseFloat( value );
230
      } catch( NumberFormatException nfe ) {
231
        // returns def
232
      }
233
    }
234
    return result;
235
  }
236
237
  public int getInt( final String key, final int def ) {
238
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
239
    checkRemoved();
240
    String value = internalGet( key );
241
    int result = def;
242
    if( value != null ) {
243
      try {
244
        result = Integer.parseInt( value );
245
      } catch( NumberFormatException nfe ) {
246
        // returns def
247
      }
248
    }
249
    return result;
250
  }
251
252
  public long getLong( final String key, final long def ) {
253
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
254
    checkRemoved();
255
    String value = internalGet( key );
256
    long result = def;
257
    if( value != null ) {
258
      try {
259
        result = Long.parseLong( value );
260
      } catch( NumberFormatException nfe ) {
261
        // returns def
262
      }
263
    }
264
    return result;
265
  }
266
267
  public String[] keys() {
268
    checkRemoved();
269
    return internalGetKeys();
270
  }
271
272
  public String name() {
273
    return name;
274
  }
275
276
  public synchronized boolean nodeExists( final String path ) 
277
    throws BackingStoreException 
278
  {
279
    boolean result;
280
    if( "".equals( path ) ) { //$NON-NLS-1$
281
      result = !isRemoved;
282
    } else {
283
      checkRemoved();
284
      checkPath( path );
285
      if( path.startsWith( PATH_SEPARATOR ) ) { // "/absolute/path"
286
        result = findRoot().nodeExists( path.substring( 1 ) );
287
      } else if( path.indexOf( PATH_SEPARATOR ) > 0 ) { // "foo/bar/baz"
288
        int index = path.indexOf( PATH_SEPARATOR );
289
        String nodeName = path.substring( 0, index );
290
        String rest = path.substring( index + 1, path.length() ); 
291
        SessionPreferencesNode child = getChild( nodeName, false );
292
        result = child == null ? false : child.nodeExists( rest );
293
      } else { // "foo"
294
        result = children.containsKey( path );
295
      }
296
    }
297
    return result;
298
  }
299
300
  public Preferences parent() {
301
    checkRemoved();
302
    return parent;
303
  }
304
305
  public void put( final String key, final String newValue ) {
306
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
307
    ParamCheck.notNull( newValue, "newValue" ); //$NON-NLS-1$
308
    checkRemoved();
309
    String oldValue = internalPut( key, newValue );
310
    if( !newValue.equals( oldValue ) ) {
311
      getNodeCore().firePreferenceEvent( key, oldValue, newValue );
312
    }
313
  }
314
315
  public void putBoolean( final String key, final boolean value ) {
316
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
317
    checkRemoved();
318
    String newValue = value ? TRUE : FALSE;
319
    String oldValue = internalPut( key, newValue );
320
    if( !newValue.equals( oldValue ) ) {
321
      getNodeCore().firePreferenceEvent( key, oldValue, newValue );
322
    }
323
  }
324
325
  public void putByteArray( final String key, final byte[] value ) {
326
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
327
    ParamCheck.notNull( value, "newValue" ); //$NON-NLS-1$
328
    checkRemoved();
329
    String newValue = new String( Base64.encode( value ) );
330
    String oldValue = internalPut( key, newValue );
331
    if( !newValue.equals( oldValue) ) {
332
      getNodeCore().firePreferenceEvent( key, oldValue, newValue );
333
    }
334
  }
335
336
  public void putDouble( final String key, final double value ) {
337
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
338
    checkRemoved();
339
    String newValue = String.valueOf( value );
340
    String oldValue = internalPut( key, newValue );
341
    if( !newValue.equals( oldValue ) ) {
342
      getNodeCore().firePreferenceEvent( key, oldValue, newValue );
343
    }
344
  }
345
346
  public void putFloat( final String key, final float value ) {
347
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
348
    checkRemoved();
349
    String newValue = String.valueOf( value );
350
    String oldValue = internalPut( key, newValue );
351
    if( !newValue.equals( oldValue ) ) {
352
      getNodeCore().firePreferenceEvent( key, oldValue, newValue );
353
    }
354
  }
355
356
  public void putInt( final String key, final int value ) {
357
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
358
    checkRemoved();
359
    String newValue = String.valueOf( value );
360
    String oldValue = internalPut( key, newValue );
361
    if( !newValue.equals( oldValue ) ) {
362
      getNodeCore().firePreferenceEvent( key, oldValue, newValue );
363
    }
364
  }
365
366
  public void putLong( final String key, final long value ) {
367
    ParamCheck.notNull( key, "key" ); //$NON-NLS-1$
368
    checkRemoved();
369
    String newValue = String.valueOf( value );
370
    String oldValue = internalPut( key, newValue );
371
    if( !newValue.equals( oldValue ) ) {
372
      getNodeCore().firePreferenceEvent( key, oldValue, newValue );
373
    }
374
  }
375
376
  public void remove( final String key ) {
377
    checkRemoved();
378
    String oldValue = internalGet( key );
379
    if( oldValue != null ) {
380
      internalPut( key, null );
381
      getNodeCore().firePreferenceEvent( key, oldValue, null );
382
    }
383
  }
384
385
  public void sync() throws BackingStoreException {
386
    checkRemoved();
387
    ISettingStore store = RWT.getSettingStore();
388
    String id = store.getId();
389
    try {
390
      store.loadById( id );
391
    } catch( SettingStoreException sse ) {
392
      throw new BackingStoreException( "Failed to sync() node", sse ); //$NON-NLS-1$
393
    }
394
  }
395
  
396
  public String toString() {
397
    return absolutePath() + "@" + hashCode(); //$NON-NLS-1$
398
  }
399
  
400
  //////////////////
401
  // helping methods
402
  
403
  private void checkName( final String nodeName ) {
404
    if( nodeName.indexOf( PATH_SEPARATOR ) != -1 ) {
405
      String unboundMsg = "Name ''{0}'' cannot contain or end with ''{1}''"; //$NON-NLS-1$
406
      String msg = NLS.bind( unboundMsg, nodeName, PATH_SEPARATOR );
407
      throw new IllegalArgumentException( msg );
408
    }
409
  }
410
411
  private void checkPath( final String path ) {
412
    if( path.indexOf( DOUBLE_PATH_SEPARATOR ) != -1 ) {
413
      String unboundMsg = "''{0}'' is not allowed in path ''{1}''"; //$NON-NLS-1$
414
      String msg = NLS.bind( unboundMsg, DOUBLE_PATH_SEPARATOR, path );
415
      throw new IllegalArgumentException( msg );
416
    }
417
    if( path.length() > 1 && path.endsWith( PATH_SEPARATOR ) ) {
418
      String unboundMsg = "path ''{0}'' cannot end with ''{1}''"; //$NON-NLS-1$
419
      String msg = NLS.bind( unboundMsg, path, PATH_SEPARATOR );
420
      throw new IllegalArgumentException( msg );
421
    }
422
  }
423
  
424
  private synchronized void checkRemoved() {
425
    if( isRemoved ) {
426
      String msg = "node ''{0}'' has been removed"; //$NON-NLS-1$
427
      throw new IllegalStateException( NLS.bind( msg, this.absolutePath() ) );
428
    }
429
  }
430
  
431
  private synchronized SessionPreferencesNode createChild( 
432
    final String childName )
433
  {
434
    SessionPreferencesNode result 
435
      = new SessionPreferencesNode( this, childName );
436
    children.put( childName, result );
437
    fireNodeEvent( result, true );
438
    return result;
439
  }
440
  
441
  private synchronized SessionPreferencesNode getChild( 
442
    final String childName, 
443
    final boolean doCreate ) 
444
  {
445
    SessionPreferencesNode result 
446
      = ( SessionPreferencesNode )children.get( childName );
447
    if( result == null && doCreate ) {
448
      result = createChild( childName );
449
    }
450
    return result;
451
  }
452
  
453
  private String[] internalGetKeys() {
454
    List result = new ArrayList();
455
456
    String prefix = absolutePath() + PATH_SEPARATOR;
457
    int prefixLength = prefix.length();
458
    
459
    Enumeration attrNames = RWT.getSettingStore().getAttributeNames();
460
    while( attrNames.hasMoreElements() ) {
461
      String attr = ( String )attrNames.nextElement();
462
      if( attr.startsWith( prefix ) ) {
463
        String key = attr.substring( prefixLength );
464
        result.add( key );
465
      }
466
    }
467
    return ( String[] )result.toArray( new String[ result.size() ] );
468
  }
469
470
  private Preferences findRoot() {
471
    Preferences result = this;
472
    while( result.parent() != null ) {
473
      result = result.parent();
474
    }
475
    return result;
476
  }
477
  
478
  private String internalGet( final String key ) {
479
    ISettingStore store = RWT.getSettingStore();
480
    String uniqueKey = absolutePath() + PATH_SEPARATOR + key;
481
    return store.getAttribute( uniqueKey );
482
  }
483
484
  private synchronized String internalPut( final String key, 
485
                                           final String value ) {
486
    String uniqueKey = absolutePath() + PATH_SEPARATOR + key;
487
    return getNodeCore().put( uniqueKey, value );
488
  }
489
  
490
  private void fireNodeEvent( final Preferences child,
491
                              final boolean wasAdded ) {
492
    getNodeCore().fireNodeEvent( child, wasAdded, this );
493
  }
494
  
495
  private SessionPreferenceNodeCore getNodeCore() {
496
    SessionPreferenceNodeCore result;
497
    final String key = absolutePath();
498
    Object object = RWT.getSessionStore().getAttribute( key );
499
    if( object instanceof SessionPreferenceNodeCore ) {
500
      result = ( SessionPreferenceNodeCore )object;
501
    } else {
502
      result = new SessionPreferenceNodeCore( this );
503
      RWT.getSessionStore().setAttribute( key, result );
504
    }
505
    return result;
506
  }
507
  
508
}
(-)src/org/eclipse/rap/internal/design/example/builder/PerspectiveSwitcherBuilder.java (-1 / +1 lines)
Lines 17-22 Link Here
17
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
17
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
18
import org.eclipse.rap.internal.design.example.business.layoutsets.PerspectiveSwitcherInitializer;
18
import org.eclipse.rap.internal.design.example.business.layoutsets.PerspectiveSwitcherInitializer;
19
import org.eclipse.rap.ui.interactiondesign.layout.ElementBuilder;
19
import org.eclipse.rap.ui.interactiondesign.layout.ElementBuilder;
20
import org.eclipse.rap.ui.internal.preferences.SessionScope;
20
import org.eclipse.rwt.graphics.Graphics;
21
import org.eclipse.rwt.graphics.Graphics;
21
import org.eclipse.rwt.lifecycle.WidgetUtil;
22
import org.eclipse.rwt.lifecycle.WidgetUtil;
22
import org.eclipse.swt.SWT;
23
import org.eclipse.swt.SWT;
Lines 44-50 Link Here
44
import org.eclipse.ui.WorkbenchException;
45
import org.eclipse.ui.WorkbenchException;
45
import org.eclipse.ui.actions.ActionFactory;
46
import org.eclipse.ui.actions.ActionFactory;
46
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
47
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
47
import org.eclipse.ui.internal.preferences.SessionScope;
48
import org.osgi.service.prefs.BackingStoreException;
48
import org.osgi.service.prefs.BackingStoreException;
49
import org.osgi.service.prefs.Preferences;
49
import org.osgi.service.prefs.Preferences;
50
50

Return to bug 279613