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 283274 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java (-1508 / +1305 lines)
Lines 95-1606 Link Here
95
/**
95
/**
96
 * @author Eike Stepper
96
 * @author Eike Stepper
97
 */
97
 */
98
public abstract class CDOSessionImpl extends Container<CDOView> implements InternalCDOSession
98
public abstract class CDOSessionImpl extends Container<CDOView> implements
99
{
99
		InternalCDOSession {
100
  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_SESSION, CDOSessionImpl.class);
100
	private static final ContextTracer TRACER = new ContextTracer(
101
101
			OM.DEBUG_SESSION, CDOSessionImpl.class);
102
  private static final long NO_TIMEOUT = -1;
102
103
103
	private static final long NO_TIMEOUT = -1;
104
  private InternalCDOSessionConfiguration configuration;
104
105
105
	private InternalCDOSessionConfiguration configuration;
106
  private ExceptionHandler exceptionHandler;
106
107
107
	private ExceptionHandler exceptionHandler;
108
  private CDOSessionProtocol sessionProtocol;
108
109
109
	private CDOSessionProtocol sessionProtocol;
110
  @ExcludeFromDump
110
111
  private IListener sessionProtocolListener = new LifecycleEventAdapter()
111
	@ExcludeFromDump
112
  {
112
	private IListener sessionProtocolListener = new LifecycleEventAdapter() {
113
    @Override
113
		@Override
114
    protected void onDeactivated(ILifecycle lifecycle)
114
		protected void onDeactivated(ILifecycle lifecycle) {
115
    {
115
			CDOSessionImpl.this.deactivate();
116
      CDOSessionImpl.this.deactivate();
116
		}
117
    }
117
	};
118
  };
118
119
119
	private int sessionID;
120
  private int sessionID;
120
121
121
	private String userID;
122
  private String userID;
122
123
123
	private long lastUpdateTime;
124
  private long lastUpdateTime;
124
125
125
	@ExcludeFromDump
126
  @ExcludeFromDump
126
	private Object lastUpdateTimeLock = new Object();
127
  private Object lastUpdateTimeLock = new Object();
127
128
128
	private CDOSession.Options options = createOptions();
129
  private CDOSession.Options options = createOptions();
129
130
130
	private CDORepositoryInfo repositoryInfo;
131
  private CDORepositoryInfo repositoryInfo;
131
132
132
	private CDOFetchRuleManager ruleManager = CDOFetchRuleManager.NOOP;
133
  private CDOFetchRuleManager ruleManager = CDOFetchRuleManager.NOOP;
133
134
134
	private IRWLockManager<CDOSessionImpl, Object> lockmanager = new RWLockManager<CDOSessionImpl, Object>();
135
  private IRWLockManager<CDOSessionImpl, Object> lockmanager = new RWLockManager<CDOSessionImpl, Object>();
135
136
136
	@ExcludeFromDump
137
  @ExcludeFromDump
137
	private Set<CDOSessionImpl> singletonCollection = Collections
138
  private Set<CDOSessionImpl> singletonCollection = Collections.singleton(this);
138
			.singleton(this);
139
139
140
  private CDOAuthenticator authenticator;
140
	private CDOAuthenticator authenticator;
141
141
142
  private InternalCDORemoteSessionManager remoteSessionManager;
142
	private InternalCDORemoteSessionManager remoteSessionManager;
143
143
144
  private Set<InternalCDOView> views = new HashSet<InternalCDOView>();
144
	private Set<InternalCDOView> views = new HashSet<InternalCDOView>();
145
145
146
  /**
146
	/**
147
   * Fixes a threading problem between a committing thread and the Net4j thread that delivers incoming commit
147
	 * Fixes a threading problem between a committing thread and the Net4j
148
   * notifications. TODO This is a workaround, see Bug 294700
148
	 * thread that delivers incoming commit notifications. TODO This is a
149
   */
149
	 * workaround, see Bug 294700
150
  private Object commitLock = new Object();
150
	 */
151
151
	private Object commitLock = new Object();
152
  @ExcludeFromDump
152
153
  private QueueRunner invalidationRunner;
153
	@ExcludeFromDump
154
154
	private QueueRunner invalidationRunner;
155
  @ExcludeFromDump
155
156
  private Object invalidationRunnerLock = new Object();
156
	@ExcludeFromDump
157
157
	private Object invalidationRunnerLock = new Object();
158
  @ExcludeFromDump
158
159
  private static ThreadLocal<Boolean> invalidationRunnerActive = new InheritableThreadLocal<Boolean>();
159
	@ExcludeFromDump
160
160
	private static ThreadLocal<Boolean> invalidationRunnerActive = new InheritableThreadLocal<Boolean>();
161
  @ExcludeFromDump
161
162
  private int lastViewID;
162
	@ExcludeFromDump
163
163
	private int lastViewID;
164
  public CDOSessionImpl(InternalCDOSessionConfiguration configuration)
164
165
  {
165
	private Set<InternalCDOView> registeredLockListeners = new HashSet<InternalCDOView>();
166
    this.configuration = configuration;
166
167
  }
167
	private boolean hasRegisteredListeners;
168
168
169
  public InternalCDOSessionConfiguration getConfiguration()
169
	public CDOSessionImpl(InternalCDOSessionConfiguration configuration) {
170
  {
170
		this.configuration = configuration;
171
    return configuration;
171
	}
172
  }
172
173
173
	public InternalCDOSessionConfiguration getConfiguration() {
174
  public CDORepositoryInfo getRepositoryInfo()
174
		return configuration;
175
  {
175
	}
176
    return repositoryInfo;
176
177
  }
177
	public CDORepositoryInfo getRepositoryInfo() {
178
178
		return repositoryInfo;
179
  public void setRepositoryInfo(CDORepositoryInfo repositoryInfo)
179
	}
180
  {
180
181
    this.repositoryInfo = repositoryInfo;
181
	public void setRepositoryInfo(CDORepositoryInfo repositoryInfo) {
182
  }
182
		this.repositoryInfo = repositoryInfo;
183
183
	}
184
  public int getSessionID()
184
185
  {
185
	public int getSessionID() {
186
    return sessionID;
186
		return sessionID;
187
  }
187
	}
188
188
189
  public void setSessionID(int sessionID)
189
	public void setSessionID(int sessionID) {
190
  {
190
		this.sessionID = sessionID;
191
    this.sessionID = sessionID;
191
	}
192
  }
192
193
193
	public String getUserID() {
194
  public String getUserID()
194
		return userID;
195
  {
195
	}
196
    return userID;
196
197
  }
197
	public void setUserID(String userID) {
198
198
		this.userID = userID;
199
  public void setUserID(String userID)
199
	}
200
  {
200
201
    this.userID = userID;
201
	public ExceptionHandler getExceptionHandler() {
202
  }
202
		return exceptionHandler;
203
203
	}
204
  public ExceptionHandler getExceptionHandler()
204
205
  {
205
	public void setExceptionHandler(ExceptionHandler exceptionHandler) {
206
    return exceptionHandler;
206
		checkInactive();
207
  }
207
		this.exceptionHandler = exceptionHandler;
208
208
	}
209
  public void setExceptionHandler(ExceptionHandler exceptionHandler)
209
210
  {
210
	/**
211
    checkInactive();
211
	 * @since 2.0
212
    this.exceptionHandler = exceptionHandler;
212
	 */
213
  }
213
	public CDOSession.Options options() {
214
214
		return options;
215
  /**
215
	}
216
   * @since 2.0
216
217
   */
217
	/**
218
  public CDOSession.Options options()
218
	 * @since 2.0
219
  {
219
	 */
220
    return options;
220
	protected CDOSession.Options createOptions() {
221
  }
221
		return new OptionsImpl();
222
222
	}
223
  /**
223
224
   * @since 2.0
224
	public CDOSessionProtocol getSessionProtocol() {
225
   */
225
		return sessionProtocol;
226
  protected CDOSession.Options createOptions()
226
	}
227
  {
227
228
    return new OptionsImpl();
228
	public void setSessionProtocol(CDOSessionProtocol sessionProtocol) {
229
  }
229
		this.sessionProtocol = sessionProtocol;
230
230
	}
231
  public CDOSessionProtocol getSessionProtocol()
231
232
  {
232
	public void close() {
233
    return sessionProtocol;
233
		LifecycleUtil.deactivate(this, OMLogger.Level.DEBUG);
234
  }
234
	}
235
235
236
  public void setSessionProtocol(CDOSessionProtocol sessionProtocol)
236
	/**
237
  {
237
	 * @since 2.0
238
    this.sessionProtocol = sessionProtocol;
238
	 */
239
  }
239
	public boolean isClosed() {
240
240
		return !isActive();
241
  public void close()
241
	}
242
  {
242
243
    LifecycleUtil.deactivate(this, OMLogger.Level.DEBUG);
243
	public Object processPackage(Object value) {
244
  }
244
		CDOFactoryImpl.prepareDynamicEPackage(value);
245
245
		return value;
246
  /**
246
	}
247
   * @since 2.0
247
248
   */
248
	public EPackage[] loadPackages(CDOPackageUnit packageUnit) {
249
  public boolean isClosed()
249
		if (packageUnit.getOriginalType().isGenerated()) {
250
  {
250
			if (!options().isGeneratedPackageEmulationEnabled()) {
251
    return !isActive();
251
				throw new CDOException(MessageFormat.format(Messages
252
  }
252
						.getString("CDOSessionImpl.0"), packageUnit));
253
253
			}
254
  public Object processPackage(Object value)
254
		}
255
  {
255
256
    CDOFactoryImpl.prepareDynamicEPackage(value);
256
		return getSessionProtocol().loadPackages(packageUnit);
257
    return value;
257
	}
258
  }
258
259
259
	public void acquireAtomicRequestLock(Object key) {
260
  public EPackage[] loadPackages(CDOPackageUnit packageUnit)
260
		try {
261
  {
261
			lockmanager.lock(LockType.WRITE, key, this, RWLockManager.WAIT);
262
    if (packageUnit.getOriginalType().isGenerated())
262
		} catch (InterruptedException ex) {
263
    {
263
			throw WrappedException.wrap(ex);
264
      if (!options().isGeneratedPackageEmulationEnabled())
264
		}
265
      {
265
	}
266
        throw new CDOException(MessageFormat.format(Messages.getString("CDOSessionImpl.0"), packageUnit));
266
267
      }
267
	public void releaseAtomicRequestLock(Object key) {
268
    }
268
		lockmanager.unlock(LockType.WRITE, key, singletonCollection);
269
269
	}
270
    return getSessionProtocol().loadPackages(packageUnit);
270
271
  }
271
	/**
272
272
	 * @since 3.0
273
  public void acquireAtomicRequestLock(Object key)
273
	 */
274
  {
274
	public CDOFetchRuleManager getFetchRuleManager() {
275
    try
275
		return ruleManager;
276
    {
276
	}
277
      lockmanager.lock(LockType.WRITE, key, this, RWLockManager.WAIT);
277
278
    }
278
	/**
279
    catch (InterruptedException ex)
279
	 * @since 3.0
280
    {
280
	 */
281
      throw WrappedException.wrap(ex);
281
	public void setFetchRuleManager(CDOFetchRuleManager fetchRuleManager) {
282
    }
282
		ruleManager = fetchRuleManager;
283
  }
283
	}
284
284
285
  public void releaseAtomicRequestLock(Object key)
285
	public CDOAuthenticator getAuthenticator() {
286
  {
286
		return authenticator;
287
    lockmanager.unlock(LockType.WRITE, key, singletonCollection);
287
	}
288
  }
288
289
289
	public void setAuthenticator(CDOAuthenticator authenticator) {
290
  /**
290
		this.authenticator = authenticator;
291
   * @since 3.0
291
	}
292
   */
292
293
  public CDOFetchRuleManager getFetchRuleManager()
293
	public InternalCDORemoteSessionManager getRemoteSessionManager() {
294
  {
294
		return remoteSessionManager;
295
    return ruleManager;
295
	}
296
  }
296
297
297
	public void setRemoteSessionManager(
298
  /**
298
			InternalCDORemoteSessionManager remoteSessionManager) {
299
   * @since 3.0
299
		this.remoteSessionManager = remoteSessionManager;
300
   */
300
	}
301
  public void setFetchRuleManager(CDOFetchRuleManager fetchRuleManager)
301
302
  {
302
	/**
303
    ruleManager = fetchRuleManager;
303
	 * @since 2.0
304
  }
304
	 */
305
305
	public InternalCDOTransaction openTransaction(ResourceSet resourceSet) {
306
  public CDOAuthenticator getAuthenticator()
306
		checkActive();
307
  {
307
		InternalCDOTransaction transaction = createTransaction();
308
    return authenticator;
308
		initView(transaction, resourceSet);
309
  }
309
		return transaction;
310
310
	}
311
  public void setAuthenticator(CDOAuthenticator authenticator)
311
312
  {
312
	/**
313
    this.authenticator = authenticator;
313
	 * @since 2.0
314
  }
314
	 */
315
315
	public InternalCDOTransaction openTransaction() {
316
  public InternalCDORemoteSessionManager getRemoteSessionManager()
316
		return openTransaction(createResourceSet());
317
  {
317
	}
318
    return remoteSessionManager;
318
319
  }
319
	/**
320
320
	 * @since 2.0
321
  public void setRemoteSessionManager(InternalCDORemoteSessionManager remoteSessionManager)
321
	 */
322
  {
322
	protected InternalCDOTransaction createTransaction() {
323
    this.remoteSessionManager = remoteSessionManager;
323
		return new CDOTransactionImpl();
324
  }
324
	}
325
325
326
  /**
326
	/**
327
   * @since 2.0
327
	 * @since 2.0
328
   */
328
	 */
329
  public InternalCDOTransaction openTransaction(ResourceSet resourceSet)
329
	public InternalCDOView openView(ResourceSet resourceSet) {
330
  {
330
		checkActive();
331
    checkActive();
331
		InternalCDOView view = createView();
332
    InternalCDOTransaction transaction = createTransaction();
332
		initView(view, resourceSet);
333
    initView(transaction, resourceSet);
333
		return view;
334
    return transaction;
334
	}
335
  }
335
336
336
	/**
337
  /**
337
	 * @since 2.0
338
   * @since 2.0
338
	 */
339
   */
339
	public InternalCDOView openView() {
340
  public InternalCDOTransaction openTransaction()
340
		return openView(createResourceSet());
341
  {
341
	}
342
    return openTransaction(createResourceSet());
342
343
  }
343
	/**
344
344
	 * @since 2.0
345
  /**
345
	 */
346
   * @since 2.0
346
	protected InternalCDOView createView() {
347
   */
347
		return new CDOViewImpl();
348
  protected InternalCDOTransaction createTransaction()
348
	}
349
  {
349
350
    return new CDOTransactionImpl();
350
	public CDOAuditImpl openAudit(ResourceSet resourceSet, long timeStamp) {
351
  }
351
		checkActive();
352
352
		CDOAuditImpl audit = createAudit(timeStamp);
353
  /**
353
		initView(audit, resourceSet);
354
   * @since 2.0
354
		return audit;
355
   */
355
	}
356
  public InternalCDOView openView(ResourceSet resourceSet)
356
357
  {
357
	public CDOAuditImpl openAudit(long timeStamp) {
358
    checkActive();
358
		return openAudit(createResourceSet(), timeStamp);
359
    InternalCDOView view = createView();
359
	}
360
    initView(view, resourceSet);
360
361
    return view;
361
	/**
362
  }
362
	 * @since 2.0
363
363
	 */
364
  /**
364
	protected CDOAuditImpl createAudit(long timeStamp) {
365
   * @since 2.0
365
		return new CDOAuditImpl(timeStamp);
366
   */
366
	}
367
  public InternalCDOView openView()
367
368
  {
368
	/**
369
    return openView(createResourceSet());
369
	 * @since 2.0
370
  }
370
	 */
371
371
	public void viewDetached(InternalCDOView view) {
372
  /**
372
		// Detach viewset from the view
373
   * @since 2.0
373
		view.getViewSet().remove(view);
374
   */
374
		synchronized (views) {
375
  protected InternalCDOView createView()
375
			if (!views.remove(view)) {
376
  {
376
				return;
377
    return new CDOViewImpl();
377
			}
378
  }
378
		}
379
379
380
  public CDOAuditImpl openAudit(ResourceSet resourceSet, long timeStamp)
380
		if (isActive()) {
381
  {
381
			try {
382
    checkActive();
382
				LifecycleUtil.deactivate(view);
383
    CDOAuditImpl audit = createAudit(timeStamp);
383
			} catch (Exception ex) {
384
    initView(audit, resourceSet);
384
				throw WrappedException.wrap(ex);
385
    return audit;
385
			}
386
  }
386
		}
387
387
388
  public CDOAuditImpl openAudit(long timeStamp)
388
		fireElementRemovedEvent(view);
389
  {
389
	}
390
    return openAudit(createResourceSet(), timeStamp);
390
391
  }
391
	public CDOView getView(int viewID) {
392
392
		checkActive();
393
  /**
393
		for (InternalCDOView view : getViews()) {
394
   * @since 2.0
394
			if (view.getViewID() == viewID) {
395
   */
395
				return view;
396
  protected CDOAuditImpl createAudit(long timeStamp)
396
			}
397
  {
397
		}
398
    return new CDOAuditImpl(timeStamp);
398
399
  }
399
		return null;
400
400
	}
401
  /**
401
402
   * @since 2.0
402
	/**
403
   */
403
	 * @since 2.0
404
  public void viewDetached(InternalCDOView view)
404
	 */
405
  {
405
	public InternalCDOView[] getViews() {
406
    // Detach viewset from the view
406
		checkActive();
407
    view.getViewSet().remove(view);
407
		synchronized (views) {
408
    synchronized (views)
408
			return views.toArray(new InternalCDOView[views.size()]);
409
    {
409
		}
410
      if (!views.remove(view))
410
	}
411
      {
411
412
        return;
412
	public CDOView[] getElements() {
413
      }
413
		return getViews();
414
    }
414
	}
415
415
416
    if (isActive())
416
	@Override
417
    {
417
	public boolean isEmpty() {
418
      try
418
		checkActive();
419
      {
419
		return views.isEmpty();
420
        LifecycleUtil.deactivate(view);
420
	}
421
      }
421
422
      catch (Exception ex)
422
	/**
423
      {
423
	 * @since 2.0
424
        throw WrappedException.wrap(ex);
424
	 */
425
      }
425
	public Collection<CDOTimeStampContext> refresh() {
426
    }
426
		// If passive update is turned on we don`t need to refresh.
427
427
		// We do not throw an exception since the client could turn
428
    fireElementRemovedEvent(view);
428
		// that feature on or off without affecting their code.
429
  }
429
		checkActive();
430
430
		if (!options().isPassiveUpdateEnabled()) {
431
  public CDOView getView(int viewID)
431
			Map<CDOID, CDOIDAndVersion> allRevisions = getAllCDOIDAndVersion();
432
  {
432
433
    checkActive();
433
			try {
434
    for (InternalCDOView view : getViews())
434
				if (!allRevisions.isEmpty()) {
435
    {
435
					int initialChunkSize = options()
436
      if (view.getViewID() == viewID)
436
							.getCollectionLoadingPolicy().getInitialChunkSize();
437
      {
437
					return getSessionProtocol().syncRevisions(allRevisions,
438
        return view;
438
							initialChunkSize);
439
      }
439
				}
440
    }
440
			} catch (Exception ex) {
441
441
				throw WrappedException.wrap(ex);
442
    return null;
442
			}
443
  }
443
		}
444
444
445
  /**
445
		return Collections.emptyList();
446
   * @since 2.0
446
	}
447
   */
447
448
  public InternalCDOView[] getViews()
448
	public long getLastUpdateTime() {
449
  {
449
		synchronized (lastUpdateTimeLock) {
450
    checkActive();
450
			return lastUpdateTime;
451
    synchronized (views)
451
		}
452
    {
452
	}
453
      return views.toArray(new InternalCDOView[views.size()]);
453
454
    }
454
	public void setLastUpdateTime(long lastUpdateTime) {
455
  }
455
		synchronized (lastUpdateTimeLock) {
456
456
			this.lastUpdateTime = lastUpdateTime;
457
  public CDOView[] getElements()
457
			lastUpdateTimeLock.notifyAll();
458
  {
458
		}
459
    return getViews();
459
	}
460
  }
460
461
461
	public void waitForUpdate(long updateTime) {
462
  @Override
462
		waitForUpdate(updateTime, NO_TIMEOUT);
463
  public boolean isEmpty()
463
	}
464
  {
464
465
    checkActive();
465
	public boolean waitForUpdate(long updateTime, long timeoutMillis) {
466
    return views.isEmpty();
466
		long end = timeoutMillis == NO_TIMEOUT ? Long.MAX_VALUE : System
467
  }
467
				.currentTimeMillis()
468
468
				+ timeoutMillis;
469
  /**
469
		for (;;) {
470
   * @since 2.0
470
			synchronized (lastUpdateTimeLock) {
471
   */
471
				if (lastUpdateTime >= updateTime) {
472
  public Collection<CDOTimeStampContext> refresh()
472
					return true;
473
  {
473
				}
474
    // If passive update is turned on we don`t need to refresh.
474
475
    // We do not throw an exception since the client could turn
475
				long now = System.currentTimeMillis();
476
    // that feature on or off without affecting their code.
476
				if (now >= end) {
477
    checkActive();
477
					return false;
478
    if (!options().isPassiveUpdateEnabled())
478
				}
479
    {
479
480
      Map<CDOID, CDOIDAndVersion> allRevisions = getAllCDOIDAndVersion();
480
				try {
481
481
					lastUpdateTimeLock.wait(end - now);
482
      try
482
				} catch (InterruptedException ex) {
483
      {
483
					throw WrappedException.wrap(ex);
484
        if (!allRevisions.isEmpty())
484
				}
485
        {
485
			}
486
          int initialChunkSize = options().getCollectionLoadingPolicy().getInitialChunkSize();
486
		}
487
          return getSessionProtocol().syncRevisions(allRevisions, initialChunkSize);
487
	}
488
        }
488
489
      }
489
	/**
490
      catch (Exception ex)
490
	 * @since 3.0
491
      {
491
	 */
492
        throw WrappedException.wrap(ex);
492
	public Object resolveElementProxy(CDORevision revision,
493
      }
493
			EStructuralFeature feature, int accessIndex, int serverIndex) {
494
    }
494
		CDOCollectionLoadingPolicy policy = options()
495
495
				.getCollectionLoadingPolicy();
496
    return Collections.emptyList();
496
		return policy.resolveProxy(this, revision, feature, accessIndex,
497
  }
497
				serverIndex);
498
498
	}
499
  public long getLastUpdateTime()
499
500
  {
500
	/**
501
    synchronized (lastUpdateTimeLock)
501
	 * @since 2.0
502
    {
502
	 */
503
      return lastUpdateTime;
503
	public void handleSyncResponse(long timestamp,
504
    }
504
			Collection<CDOPackageUnit> newPackageUnits,
505
  }
505
			Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects) {
506
506
		handleCommitNotification(timestamp, newPackageUnits, dirtyOIDs,
507
  public void setLastUpdateTime(long lastUpdateTime)
507
				detachedObjects, null, null, true, false);
508
  {
508
	}
509
    synchronized (lastUpdateTimeLock)
509
510
    {
510
	/**
511
      this.lastUpdateTime = lastUpdateTime;
511
	 * @since 2.0
512
      lastUpdateTimeLock.notifyAll();
512
	 */
513
    }
513
	public void handleCommitNotification(final long timeStamp,
514
  }
514
			final Collection<CDOPackageUnit> newPackageUnits,
515
515
			Set<CDOIDAndVersion> dirtyOIDs,
516
  public void waitForUpdate(long updateTime)
516
			final Collection<CDOID> detachedObjects,
517
  {
517
			final Collection<CDORevisionDelta> deltas,
518
    waitForUpdate(updateTime, NO_TIMEOUT);
518
			InternalCDOView excludedView) {
519
  }
519
		handleCommitNotification(timeStamp, newPackageUnits, dirtyOIDs,
520
520
				detachedObjects, deltas, excludedView, options()
521
  public boolean waitForUpdate(long updateTime, long timeoutMillis)
521
						.isPassiveUpdateEnabled(), true);
522
  {
522
	}
523
    long end = timeoutMillis == NO_TIMEOUT ? Long.MAX_VALUE : System.currentTimeMillis() + timeoutMillis;
523
524
    for (;;)
524
	private void handleCommitNotification(final long timeStamp,
525
    {
525
			final Collection<CDOPackageUnit> newPackageUnits,
526
      synchronized (lastUpdateTimeLock)
526
			Set<CDOIDAndVersion> dirtyOIDs,
527
      {
527
			final Collection<CDOID> detachedObjects,
528
        if (lastUpdateTime >= updateTime)
528
			final Collection<CDORevisionDelta> deltas,
529
        {
529
			InternalCDOView excludedView, final boolean passiveUpdate,
530
          return true;
530
			final boolean async) {
531
        }
531
		try {
532
532
			synchronized (commitLock) {
533
        long now = System.currentTimeMillis();
533
				if (passiveUpdate) {
534
        if (now >= end)
534
					reviseRevisions(timeStamp, dirtyOIDs, detachedObjects,
535
        {
535
							excludedView);
536
          return false;
536
				}
537
        }
537
538
538
				final Set<CDOIDAndVersion> finalDirtyOIDs = Collections
539
        try
539
						.unmodifiableSet(dirtyOIDs);
540
        {
540
				final Collection<CDOID> finalDetachedObjects = Collections
541
          lastUpdateTimeLock.wait(end - now);
541
						.unmodifiableCollection(detachedObjects);
542
        }
542
				final boolean skipChangeSubscription = (deltas == null || deltas
543
        catch (InterruptedException ex)
543
						.size() <= 0)
544
        {
544
						&& (detachedObjects == null || detachedObjects.size() <= 0);
545
          throw WrappedException.wrap(ex);
545
546
        }
546
				for (final InternalCDOView view : getViews()) {
547
      }
547
					if (view != excludedView) {
548
    }
548
						final Runnable runnable = new Runnable() {
549
  }
549
							public void run() {
550
550
								try {
551
  /**
551
									Set<CDOObject> conflicts = null;
552
   * @since 3.0
552
									if (passiveUpdate) {
553
   */
553
										conflicts = view.handleInvalidation(
554
  public Object resolveElementProxy(CDORevision revision, EStructuralFeature feature, int accessIndex, int serverIndex)
554
												timeStamp, finalDirtyOIDs,
555
  {
555
												finalDetachedObjects);
556
    CDOCollectionLoadingPolicy policy = options().getCollectionLoadingPolicy();
556
									}
557
    return policy.resolveProxy(this, revision, feature, accessIndex, serverIndex);
557
558
  }
558
									if (!skipChangeSubscription) {
559
559
										view.handleChangeSubscription(deltas,
560
  /**
560
												detachedObjects);
561
   * @since 2.0
561
									}
562
   */
562
563
  public void handleSyncResponse(long timestamp, Collection<CDOPackageUnit> newPackageUnits,
563
									if (conflicts != null) {
564
      Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects)
564
										((InternalCDOTransaction) view)
565
  {
565
												.handleConflicts(conflicts);
566
    handleCommitNotification(timestamp, newPackageUnits, dirtyOIDs, detachedObjects, null, null, true, false);
566
									}
567
  }
567
568
568
									view.fireAdaptersNotifiedEvent(timeStamp);
569
  /**
569
								} catch (RuntimeException ex) {
570
   * @since 2.0
570
									if (!async) {
571
   */
571
										throw ex;
572
  public void handleCommitNotification(final long timeStamp, final Collection<CDOPackageUnit> newPackageUnits,
572
									}
573
      Set<CDOIDAndVersion> dirtyOIDs, final Collection<CDOID> detachedObjects,
573
574
      final Collection<CDORevisionDelta> deltas, InternalCDOView excludedView)
574
									if (view.isActive()) {
575
  {
575
										OM.LOG.error(ex);
576
    handleCommitNotification(timeStamp, newPackageUnits, dirtyOIDs, detachedObjects, deltas, excludedView, options()
576
									} else {
577
        .isPassiveUpdateEnabled(), true);
577
										OM.LOG.info(Messages
578
  }
578
												.getString("CDOSessionImpl.1"));
579
579
									}
580
  private void handleCommitNotification(final long timeStamp, final Collection<CDOPackageUnit> newPackageUnits,
580
								}
581
      Set<CDOIDAndVersion> dirtyOIDs, final Collection<CDOID> detachedObjects,
581
							}
582
      final Collection<CDORevisionDelta> deltas, InternalCDOView excludedView, final boolean passiveUpdate,
582
						};
583
      final boolean async)
583
584
  {
584
						if (async) {
585
    try
585
							QueueRunner runner = getInvalidationRunner();
586
    {
586
							runner.addWork(new Runnable() {
587
      synchronized (commitLock)
587
								public void run() {
588
      {
588
									try {
589
        if (passiveUpdate)
589
										invalidationRunnerActive.set(true);
590
        {
590
										runnable.run();
591
          reviseRevisions(timeStamp, dirtyOIDs, detachedObjects, excludedView);
591
									} finally {
592
        }
592
										invalidationRunnerActive.set(false);
593
593
									}
594
        final Set<CDOIDAndVersion> finalDirtyOIDs = Collections.unmodifiableSet(dirtyOIDs);
594
								}
595
        final Collection<CDOID> finalDetachedObjects = Collections.unmodifiableCollection(detachedObjects);
595
							});
596
        final boolean skipChangeSubscription = (deltas == null || deltas.size() <= 0)
596
						} else {
597
            && (detachedObjects == null || detachedObjects.size() <= 0);
597
							runnable.run();
598
598
						}
599
        for (final InternalCDOView view : getViews())
599
					}
600
        {
600
				}
601
          if (view != excludedView)
601
			}
602
          {
602
		} catch (RuntimeException ex) {
603
            final Runnable runnable = new Runnable()
603
			if (!async) {
604
            {
604
				throw ex;
605
              public void run()
605
			}
606
              {
606
607
                try
607
			if (isActive()) {
608
                {
608
				OM.LOG.error(ex);
609
                  Set<CDOObject> conflicts = null;
609
			} else {
610
                  if (passiveUpdate)
610
				OM.LOG.info(Messages.getString("CDOSessionImpl.2"));
611
                  {
611
			}
612
                    conflicts = view.handleInvalidation(timeStamp, finalDirtyOIDs, finalDetachedObjects);
612
		}
613
                  }
613
614
614
		setLastUpdateTime(timeStamp);
615
                  if (!skipChangeSubscription)
615
		fireInvalidationEvent(timeStamp, newPackageUnits, dirtyOIDs,
616
                  {
616
				detachedObjects, excludedView);
617
                    view.handleChangeSubscription(deltas, detachedObjects);
617
	}
618
                  }
618
619
619
	public void reviseRevisions(final long timeStamp,
620
                  if (conflicts != null)
620
			Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects,
621
                  {
621
			InternalCDOView excludedView) {
622
                    ((InternalCDOTransaction)view).handleConflicts(conflicts);
622
		InternalCDORevisionManager revisionManager = getRevisionManager();
623
                  }
623
		if (excludedView == null || timeStamp == CDORevision.UNSPECIFIED_DATE) {
624
624
			for (CDOIDAndVersion dirtyOID : dirtyOIDs) {
625
                  view.fireAdaptersNotifiedEvent(timeStamp);
625
				CDOID id = dirtyOID.getID();
626
                }
626
				int version = dirtyOID.getVersion();
627
                catch (RuntimeException ex)
627
				revisionManager.reviseVersion(id, version, timeStamp);
628
                {
628
			}
629
                  if (!async)
629
		}
630
                  {
630
631
                    throw ex;
631
		for (CDOID id : detachedObjects) {
632
                  }
632
			revisionManager.reviseLatest(id);
633
633
		}
634
                  if (view.isActive())
634
	}
635
                  {
635
636
                    OM.LOG.error(ex);
636
	public Object getCommitLock() {
637
                  }
637
		return commitLock;
638
                  else
638
	}
639
                  {
639
640
                    OM.LOG.info(Messages.getString("CDOSessionImpl.1"));
640
	private QueueRunner getInvalidationRunner() {
641
                  }
641
		synchronized (invalidationRunnerLock) {
642
                }
642
			if (invalidationRunner == null) {
643
              }
643
				invalidationRunner = createInvalidationRunner();
644
            };
644
				invalidationRunner.activate();
645
645
			}
646
            if (async)
646
		}
647
            {
647
648
              QueueRunner runner = getInvalidationRunner();
648
		return invalidationRunner;
649
              runner.addWork(new Runnable()
649
	}
650
              {
650
651
                public void run()
651
	protected QueueRunner createInvalidationRunner() {
652
                {
652
		return new QueueRunner() {
653
                  try
653
			@Override
654
                  {
654
			protected String getThreadName() {
655
                    invalidationRunnerActive.set(true);
655
				return "InvalidationRunner";
656
                    runnable.run();
656
			}
657
                  }
657
658
                  finally
658
			@Override
659
                  {
659
			public String toString() {
660
                    invalidationRunnerActive.set(false);
660
				return getThreadName();
661
                  }
661
			}
662
                }
662
		};
663
              });
663
	}
664
            }
664
665
            else
665
	/**
666
            {
666
	 * @param packageUnits
667
              runnable.run();
667
	 * @since 2.0
668
            }
668
	 */
669
          }
669
	public void fireInvalidationEvent(long timeStamp,
670
        }
670
			Collection<CDOPackageUnit> packageUnits,
671
      }
671
			Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects,
672
    }
672
			InternalCDOView excludedView) {
673
    catch (RuntimeException ex)
673
		fireEvent(new InvalidationEvent(excludedView, timeStamp, packageUnits,
674
    {
674
				dirtyOIDs, detachedObjects));
675
      if (!async)
675
	}
676
      {
676
677
        throw ex;
677
	@Override
678
      }
678
	public String toString() {
679
679
		String name = repositoryInfo == null ? "?" : repositoryInfo.getName();
680
      if (isActive())
680
		return MessageFormat.format("CDOSession[{0}, {1}]", name, sessionID);
681
      {
681
	}
682
        OM.LOG.error(ex);
682
683
      }
683
	protected ResourceSet createResourceSet() {
684
      else
684
		return new ResourceSetImpl();
685
      {
685
	}
686
        OM.LOG.info(Messages.getString("CDOSessionImpl.2"));
686
687
      }
687
	/**
688
    }
688
	 * @since 2.0
689
689
	 */
690
    setLastUpdateTime(timeStamp);
690
	protected void initView(InternalCDOView view, ResourceSet resourceSet) {
691
    fireInvalidationEvent(timeStamp, newPackageUnits, dirtyOIDs, detachedObjects, excludedView);
691
		if (TRACER.isEnabled()) {
692
  }
692
			TRACER.format("Initializing new {0} view", view.getViewType());
693
693
		}
694
  public void reviseRevisions(final long timeStamp, Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects,
694
695
      InternalCDOView excludedView)
695
		InternalCDOViewSet viewSet = SessionUtil
696
  {
696
				.prepareResourceSet(resourceSet);
697
    InternalCDORevisionManager revisionManager = getRevisionManager();
697
		synchronized (views) {
698
    if (excludedView == null || timeStamp == CDORevision.UNSPECIFIED_DATE)
698
			view.setSession(this);
699
    {
699
			view.setViewID(++lastViewID);
700
      for (CDOIDAndVersion dirtyOID : dirtyOIDs)
700
			views.add(view);
701
      {
701
		}
702
        CDOID id = dirtyOID.getID();
702
703
        int version = dirtyOID.getVersion();
703
		// Link ViewSet with View
704
        revisionManager.reviseVersion(id, version, timeStamp);
704
		view.setViewSet(viewSet);
705
      }
705
		viewSet.add(view);
706
    }
706
707
707
		try {
708
    for (CDOID id : detachedObjects)
708
			view.activate();
709
    {
709
			fireElementAddedEvent(view);
710
      revisionManager.reviseLatest(id);
710
		} catch (RuntimeException ex) {
711
    }
711
			synchronized (views) {
712
  }
712
				views.remove(view);
713
713
			}
714
  public Object getCommitLock()
714
715
  {
715
			viewSet.remove(view);
716
    return commitLock;
716
			throw ex;
717
  }
717
		}
718
718
	}
719
  private QueueRunner getInvalidationRunner()
719
720
  {
720
	@Override
721
    synchronized (invalidationRunnerLock)
721
	protected void doActivate() throws Exception {
722
    {
722
		super.doActivate();
723
      if (invalidationRunner == null)
723
		getConfiguration().activateSession(this);
724
      {
724
		checkState(sessionProtocol, "sessionProtocol");
725
        invalidationRunner = createInvalidationRunner();
725
		checkState(remoteSessionManager, "remoteSessionManager");
726
        invalidationRunner.activate();
726
		if (exceptionHandler != null) {
727
      }
727
			sessionProtocol = new DelegatingSessionProtocol(sessionProtocol);
728
    }
728
		}
729
729
730
    return invalidationRunner;
730
		EventUtil.addListener(sessionProtocol, sessionProtocolListener);
731
  }
731
	}
732
732
733
  protected QueueRunner createInvalidationRunner()
733
	@Override
734
  {
734
	protected void doDeactivate() throws Exception {
735
    return new QueueRunner()
735
		for (InternalCDOView view : views.toArray(new InternalCDOView[views
736
    {
736
				.size()])) {
737
      @Override
737
			try {
738
      protected String getThreadName()
738
				view.close();
739
      {
739
			} catch (RuntimeException ignore) {
740
        return "InvalidationRunner";
740
			}
741
      }
741
		}
742
742
743
      @Override
743
		views.clear();
744
      public String toString()
744
745
      {
745
		if (invalidationRunner != null) {
746
        return getThreadName();
746
			LifecycleUtil.deactivate(invalidationRunner, OMLogger.Level.WARN);
747
      }
747
			invalidationRunner = null;
748
    };
748
		}
749
  }
749
750
750
		EventUtil.removeListener(sessionProtocol, sessionProtocolListener);
751
  /**
751
		getConfiguration().deactivateSession(this);
752
   * @param packageUnits
752
		super.doDeactivate();
753
   * @since 2.0
753
	}
754
   */
754
755
  public void fireInvalidationEvent(long timeStamp, Collection<CDOPackageUnit> packageUnits,
755
	private Map<CDOID, CDOIDAndVersion> getAllCDOIDAndVersion() {
756
      Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects, InternalCDOView excludedView)
756
		Map<CDOID, CDOIDAndVersion> uniqueObjects = new HashMap<CDOID, CDOIDAndVersion>();
757
  {
757
		for (InternalCDOView view : getViews()) {
758
    fireEvent(new InvalidationEvent(excludedView, timeStamp, packageUnits, dirtyOIDs, detachedObjects));
758
			view.getCDOIDAndVersion(uniqueObjects, Arrays.asList(view
759
  }
759
					.getObjectsArray()));
760
760
		}
761
  @Override
761
762
  public String toString()
762
		// Need to add Revision from revisionManager since we do not have all
763
  {
763
		// objects in view.
764
    String name = repositoryInfo == null ? "?" : repositoryInfo.getName();
764
		for (CDORevision revision : getRevisionManager().getCache()
765
    return MessageFormat.format("CDOSession[{0}, {1}]", name, sessionID);
765
				.getRevisions()) {
766
  }
766
			if (!uniqueObjects.containsKey(revision.getID())) {
767
767
				uniqueObjects.put(revision.getID(), CDOIDUtil
768
  protected ResourceSet createResourceSet()
768
						.createIDAndVersion(revision.getID(), revision
769
  {
769
								.getVersion()));
770
    return new ResourceSetImpl();
770
			}
771
  }
771
		}
772
772
773
  /**
773
		return uniqueObjects;
774
   * @since 2.0
774
	}
775
   */
775
776
  protected void initView(InternalCDOView view, ResourceSet resourceSet)
776
	public static boolean isInvalidationRunnerActive() {
777
  {
777
		return invalidationRunnerActive.get();
778
    if (TRACER.isEnabled())
778
	}
779
    {
779
780
      TRACER.format("Initializing new {0} view", view.getViewType());
780
	/**
781
    }
781
	 * @author Eike Stepper
782
782
	 * @since 2.0
783
    InternalCDOViewSet viewSet = SessionUtil.prepareResourceSet(resourceSet);
783
	 */
784
    synchronized (views)
784
	protected class OptionsImpl extends Notifier implements Options {
785
    {
785
		private boolean generatedPackageEmulationEnabled = false;
786
      view.setSession(this);
786
787
      view.setViewID(++lastViewID);
787
		private boolean passiveUpdateEnabled = true;
788
      views.add(view);
788
789
    }
789
		private CDOCollectionLoadingPolicy collectionLoadingPolicy;
790
790
791
    // Link ViewSet with View
791
		public OptionsImpl() {
792
    view.setViewSet(viewSet);
792
			// TODO Remove preferences from core
793
    viewSet.add(view);
793
			int value = OM.PREF_COLLECTION_LOADING_CHUNK_SIZE.getValue();
794
794
			collectionLoadingPolicy = CDOUtil.createCollectionLoadingPolicy(
795
    try
795
					value, value);
796
    {
796
		}
797
      view.activate();
797
798
      fireElementAddedEvent(view);
798
		public IOptionsContainer getContainer() {
799
    }
799
			return CDOSessionImpl.this;
800
    catch (RuntimeException ex)
800
		}
801
    {
801
802
      synchronized (views)
802
		public boolean isGeneratedPackageEmulationEnabled() {
803
      {
803
			return generatedPackageEmulationEnabled;
804
        views.remove(view);
804
		}
805
      }
805
806
806
		public synchronized void setGeneratedPackageEmulationEnabled(
807
      viewSet.remove(view);
807
				boolean generatedPackageEmulationEnabled) {
808
      throw ex;
808
			this.generatedPackageEmulationEnabled = generatedPackageEmulationEnabled;
809
    }
809
			if (this.generatedPackageEmulationEnabled != generatedPackageEmulationEnabled) {
810
  }
810
				this.generatedPackageEmulationEnabled = generatedPackageEmulationEnabled;
811
811
				// TODO Check inconsistent state if switching off?
812
  @Override
812
813
  protected void doActivate() throws Exception
813
				IListener[] listeners = getListeners();
814
  {
814
				if (listeners != null) {
815
    super.doActivate();
815
					fireEvent(new GeneratedPackageEmulationEventImpl(),
816
    getConfiguration().activateSession(this);
816
							listeners);
817
    checkState(sessionProtocol, "sessionProtocol");
817
				}
818
    checkState(remoteSessionManager, "remoteSessionManager");
818
			}
819
    if (exceptionHandler != null)
819
		}
820
    {
820
821
      sessionProtocol = new DelegatingSessionProtocol(sessionProtocol);
821
		public boolean isPassiveUpdateEnabled() {
822
    }
822
			return passiveUpdateEnabled;
823
823
		}
824
    EventUtil.addListener(sessionProtocol, sessionProtocolListener);
824
825
  }
825
		public synchronized void setPassiveUpdateEnabled(
826
826
				boolean passiveUpdateEnabled) {
827
  @Override
827
			if (this.passiveUpdateEnabled != passiveUpdateEnabled) {
828
  protected void doDeactivate() throws Exception
828
				this.passiveUpdateEnabled = passiveUpdateEnabled;
829
  {
829
830
    for (InternalCDOView view : views.toArray(new InternalCDOView[views.size()]))
830
				// Need to refresh if we change state
831
    {
831
				Map<CDOID, CDOIDAndVersion> allRevisions = getAllCDOIDAndVersion();
832
      try
832
				if (!allRevisions.isEmpty()) {
833
      {
833
					int initialChunkSize = collectionLoadingPolicy
834
        view.close();
834
							.getInitialChunkSize();
835
      }
835
					getSessionProtocol().setPassiveUpdate(allRevisions,
836
      catch (RuntimeException ignore)
836
							initialChunkSize, passiveUpdateEnabled);
837
      {
837
				}
838
      }
838
839
    }
839
				IListener[] listeners = getListeners();
840
840
				if (listeners != null) {
841
    views.clear();
841
					fireEvent(new PassiveUpdateEventImpl(), listeners);
842
842
				}
843
    if (invalidationRunner != null)
843
			}
844
    {
844
		}
845
      LifecycleUtil.deactivate(invalidationRunner, OMLogger.Level.WARN);
845
846
      invalidationRunner = null;
846
		public CDOCollectionLoadingPolicy getCollectionLoadingPolicy() {
847
    }
847
			return collectionLoadingPolicy;
848
848
		}
849
    EventUtil.removeListener(sessionProtocol, sessionProtocolListener);
849
850
    getConfiguration().deactivateSession(this);
850
		public synchronized void setCollectionLoadingPolicy(
851
    super.doDeactivate();
851
				CDOCollectionLoadingPolicy policy) {
852
  }
852
			if (policy == null) {
853
853
				policy = CDOCollectionLoadingPolicy.DEFAULT;
854
  private Map<CDOID, CDOIDAndVersion> getAllCDOIDAndVersion()
854
			}
855
  {
855
856
    Map<CDOID, CDOIDAndVersion> uniqueObjects = new HashMap<CDOID, CDOIDAndVersion>();
856
			if (collectionLoadingPolicy != policy) {
857
    for (InternalCDOView view : getViews())
857
				collectionLoadingPolicy = policy;
858
    {
858
				IListener[] listeners = getListeners();
859
      view.getCDOIDAndVersion(uniqueObjects, Arrays.asList(view.getObjectsArray()));
859
				if (listeners != null) {
860
    }
860
					fireEvent(new CollectionLoadingPolicyEventImpl(), listeners);
861
861
				}
862
    // Need to add Revision from revisionManager since we do not have all objects in view.
862
			}
863
    for (CDORevision revision : getRevisionManager().getCache().getRevisions())
863
		}
864
    {
864
865
      if (!uniqueObjects.containsKey(revision.getID()))
865
		/**
866
      {
866
		 * @author Eike Stepper
867
        uniqueObjects.put(revision.getID(), CDOIDUtil.createIDAndVersion(revision.getID(), revision.getVersion()));
867
		 */
868
      }
868
		private final class GeneratedPackageEmulationEventImpl extends
869
    }
869
				OptionsEvent implements GeneratedPackageEmulationEvent {
870
870
			private static final long serialVersionUID = 1L;
871
    return uniqueObjects;
871
872
  }
872
			public GeneratedPackageEmulationEventImpl() {
873
873
				super(OptionsImpl.this);
874
  public static boolean isInvalidationRunnerActive()
874
			}
875
  {
875
		}
876
    return invalidationRunnerActive.get();
876
877
  }
877
		/**
878
878
		 * @author Eike Stepper
879
  /**
879
		 */
880
   * @author Eike Stepper
880
		private final class PassiveUpdateEventImpl extends OptionsEvent
881
   * @since 2.0
881
				implements PassiveUpdateEvent {
882
   */
882
			private static final long serialVersionUID = 1L;
883
  protected class OptionsImpl extends Notifier implements Options
883
884
  {
884
			public PassiveUpdateEventImpl() {
885
    private boolean generatedPackageEmulationEnabled = false;
885
				super(OptionsImpl.this);
886
886
			}
887
    private boolean passiveUpdateEnabled = true;
887
		}
888
888
889
    private CDOCollectionLoadingPolicy collectionLoadingPolicy;
889
		/**
890
890
		 * @author Eike Stepper
891
    public OptionsImpl()
891
		 */
892
    {
892
		private final class CollectionLoadingPolicyEventImpl extends
893
      // TODO Remove preferences from core
893
				OptionsEvent implements CollectionLoadingPolicyEvent {
894
      int value = OM.PREF_COLLECTION_LOADING_CHUNK_SIZE.getValue();
894
			private static final long serialVersionUID = 1L;
895
      collectionLoadingPolicy = CDOUtil.createCollectionLoadingPolicy(value, value);
895
896
    }
896
			public CollectionLoadingPolicyEventImpl() {
897
897
				super(OptionsImpl.this);
898
    public IOptionsContainer getContainer()
898
			}
899
    {
899
		}
900
      return CDOSessionImpl.this;
900
	}
901
    }
901
902
902
	/**
903
    public boolean isGeneratedPackageEmulationEnabled()
903
	 * @author Eike Stepper
904
    {
904
	 */
905
      return generatedPackageEmulationEnabled;
905
	private final class InvalidationEvent extends Event implements
906
    }
906
			CDOSessionInvalidationEvent {
907
907
		private static final long serialVersionUID = 1L;
908
    public synchronized void setGeneratedPackageEmulationEnabled(boolean generatedPackageEmulationEnabled)
908
909
    {
909
		private InternalCDOView view;
910
      this.generatedPackageEmulationEnabled = generatedPackageEmulationEnabled;
910
911
      if (this.generatedPackageEmulationEnabled != generatedPackageEmulationEnabled)
911
		private long timeStamp;
912
      {
912
913
        this.generatedPackageEmulationEnabled = generatedPackageEmulationEnabled;
913
		private Set<CDOIDAndVersion> dirtyOIDs;
914
        // TODO Check inconsistent state if switching off?
914
915
915
		private Collection<CDOID> detachedObjects;
916
        IListener[] listeners = getListeners();
916
917
        if (listeners != null)
917
		private Collection<CDOPackageUnit> newPackageUnits;
918
        {
918
919
          fireEvent(new GeneratedPackageEmulationEventImpl(), listeners);
919
		public InvalidationEvent(InternalCDOView view, long timeStamp,
920
        }
920
				Collection<CDOPackageUnit> packageUnits,
921
      }
921
				Set<CDOIDAndVersion> dirtyOIDs,
922
    }
922
				Collection<CDOID> detachedObjects) {
923
923
			super(CDOSessionImpl.this);
924
    public boolean isPassiveUpdateEnabled()
924
			this.view = view;
925
    {
925
			this.timeStamp = timeStamp;
926
      return passiveUpdateEnabled;
926
			newPackageUnits = packageUnits;
927
    }
927
			this.dirtyOIDs = dirtyOIDs;
928
928
			this.detachedObjects = detachedObjects;
929
    public synchronized void setPassiveUpdateEnabled(boolean passiveUpdateEnabled)
929
		}
930
    {
930
931
      if (this.passiveUpdateEnabled != passiveUpdateEnabled)
931
		@Override
932
      {
932
		public CDOSession getSource() {
933
        this.passiveUpdateEnabled = passiveUpdateEnabled;
933
			return (CDOSession) super.getSource();
934
934
		}
935
        // Need to refresh if we change state
935
936
        Map<CDOID, CDOIDAndVersion> allRevisions = getAllCDOIDAndVersion();
936
		public InternalCDOView getView() {
937
        if (!allRevisions.isEmpty())
937
			return view;
938
        {
938
		}
939
          int initialChunkSize = collectionLoadingPolicy.getInitialChunkSize();
939
940
          getSessionProtocol().setPassiveUpdate(allRevisions, initialChunkSize, passiveUpdateEnabled);
940
		public boolean isRemote() {
941
        }
941
			return view == null;
942
942
		}
943
        IListener[] listeners = getListeners();
943
944
        if (listeners != null)
944
		public long getTimeStamp() {
945
        {
945
			return timeStamp;
946
          fireEvent(new PassiveUpdateEventImpl(), listeners);
946
		}
947
        }
947
948
      }
948
		public Set<CDOIDAndVersion> getDirtyOIDs() {
949
    }
949
			return dirtyOIDs;
950
950
		}
951
    public CDOCollectionLoadingPolicy getCollectionLoadingPolicy()
951
952
    {
952
		public Collection<CDOID> getDetachedObjects() {
953
      return collectionLoadingPolicy;
953
			return detachedObjects;
954
    }
954
		}
955
955
956
    public synchronized void setCollectionLoadingPolicy(CDOCollectionLoadingPolicy policy)
956
		public Collection<CDOPackageUnit> getNewPackageUnits() {
957
    {
957
			return newPackageUnits;
958
      if (policy == null)
958
		}
959
      {
959
960
        policy = CDOCollectionLoadingPolicy.DEFAULT;
960
		@Override
961
      }
961
		public String toString() {
962
962
			return "CDOSessionInvalidationEvent: " + dirtyOIDs;
963
      if (collectionLoadingPolicy != policy)
963
		}
964
      {
964
	}
965
        collectionLoadingPolicy = policy;
965
966
        IListener[] listeners = getListeners();
966
	/**
967
        if (listeners != null)
967
	 * @author Eike Stepper
968
        {
968
	 */
969
          fireEvent(new CollectionLoadingPolicyEventImpl(), listeners);
969
	public class DelegatingSessionProtocol extends Lifecycle implements
970
        }
970
			CDOSessionProtocol {
971
      }
971
		private CDOSessionProtocol delegate;
972
    }
972
973
973
		@ExcludeFromDump
974
    /**
974
		private IListener delegateListener = new LifecycleEventAdapter() {
975
     * @author Eike Stepper
975
			@Override
976
     */
976
			protected void onDeactivated(ILifecycle lifecycle) {
977
    private final class GeneratedPackageEmulationEventImpl extends OptionsEvent implements
977
				DelegatingSessionProtocol.this.deactivate();
978
        GeneratedPackageEmulationEvent
978
			}
979
    {
979
		};
980
      private static final long serialVersionUID = 1L;
980
981
981
		public DelegatingSessionProtocol(CDOSessionProtocol delegate) {
982
      public GeneratedPackageEmulationEventImpl()
982
			this.delegate = delegate;
983
      {
983
			activate();
984
        super(OptionsImpl.this);
984
		}
985
      }
985
986
    }
986
		public CDOSessionProtocol getDelegate() {
987
987
			return delegate;
988
    /**
988
		}
989
     * @author Eike Stepper
989
990
     */
990
		public CDOSession getSession() {
991
    private final class PassiveUpdateEventImpl extends OptionsEvent implements PassiveUpdateEvent
991
			return (CDOSession) delegate.getSession();
992
    {
992
		}
993
      private static final long serialVersionUID = 1L;
993
994
994
		public boolean cancelQuery(int queryId) {
995
      public PassiveUpdateEventImpl()
995
			int attempt = 0;
996
      {
996
			for (;;) {
997
        super(OptionsImpl.this);
997
				try {
998
      }
998
					return delegate.cancelQuery(queryId);
999
    }
999
				} catch (Exception ex) {
1000
1000
					handleException(++attempt, ex);
1001
    /**
1001
				}
1002
     * @author Eike Stepper
1002
			}
1003
     */
1003
		}
1004
    private final class CollectionLoadingPolicyEventImpl extends OptionsEvent implements CollectionLoadingPolicyEvent
1004
1005
    {
1005
		public void changeSubscription(int viewId, List<CDOID> cdoIDs,
1006
      private static final long serialVersionUID = 1L;
1006
				boolean subscribeMode, boolean clear) {
1007
1007
			int attempt = 0;
1008
      public CollectionLoadingPolicyEventImpl()
1008
			for (;;) {
1009
      {
1009
				try {
1010
        super(OptionsImpl.this);
1010
					delegate.changeSubscription(viewId, cdoIDs, subscribeMode,
1011
      }
1011
							clear);
1012
    }
1012
					return;
1013
  }
1013
				} catch (Exception ex) {
1014
1014
					handleException(++attempt, ex);
1015
  /**
1015
				}
1016
   * @author Eike Stepper
1016
			}
1017
   */
1017
		}
1018
  private final class InvalidationEvent extends Event implements CDOSessionInvalidationEvent
1018
1019
  {
1019
		public void closeView(int viewId) {
1020
    private static final long serialVersionUID = 1L;
1020
			int attempt = 0;
1021
1021
			for (;;) {
1022
    private InternalCDOView view;
1022
				try {
1023
1023
					delegate.closeView(viewId);
1024
    private long timeStamp;
1024
					return;
1025
1025
				} catch (Exception ex) {
1026
    private Set<CDOIDAndVersion> dirtyOIDs;
1026
					handleException(++attempt, ex);
1027
1027
				}
1028
    private Collection<CDOID> detachedObjects;
1028
			}
1029
1029
		}
1030
    private Collection<CDOPackageUnit> newPackageUnits;
1030
1031
1031
		public CommitTransactionResult commitTransaction(
1032
    public InvalidationEvent(InternalCDOView view, long timeStamp, Collection<CDOPackageUnit> packageUnits,
1032
				InternalCDOCommitContext commitContext, OMMonitor monitor) {
1033
        Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects)
1033
			int attempt = 0;
1034
    {
1034
			for (;;) {
1035
      super(CDOSessionImpl.this);
1035
				try {
1036
      this.view = view;
1036
					return delegate.commitTransaction(commitContext, monitor);
1037
      this.timeStamp = timeStamp;
1037
				} catch (Exception ex) {
1038
      newPackageUnits = packageUnits;
1038
					handleException(++attempt, ex);
1039
      this.dirtyOIDs = dirtyOIDs;
1039
				}
1040
      this.detachedObjects = detachedObjects;
1040
			}
1041
    }
1041
		}
1042
1042
1043
    @Override
1043
		public CommitTransactionResult commitTransactionCancel(
1044
    public CDOSession getSource()
1044
				InternalCDOXACommitContext xaContext, OMMonitor monitor) {
1045
    {
1045
			int attempt = 0;
1046
      return (CDOSession)super.getSource();
1046
			for (;;) {
1047
    }
1047
				try {
1048
1048
					return delegate.commitTransactionCancel(xaContext, monitor);
1049
    public InternalCDOView getView()
1049
				} catch (Exception ex) {
1050
    {
1050
					handleException(++attempt, ex);
1051
      return view;
1051
				}
1052
    }
1052
			}
1053
1053
		}
1054
    public boolean isRemote()
1054
1055
    {
1055
		public CommitTransactionResult commitTransactionPhase1(
1056
      return view == null;
1056
				InternalCDOXACommitContext xaContext, OMMonitor monitor) {
1057
    }
1057
			int attempt = 0;
1058
1058
			for (;;) {
1059
    public long getTimeStamp()
1059
				try {
1060
    {
1060
					return delegate.commitTransactionPhase1(xaContext, monitor);
1061
      return timeStamp;
1061
				} catch (Exception ex) {
1062
    }
1062
					handleException(++attempt, ex);
1063
1063
				}
1064
    public Set<CDOIDAndVersion> getDirtyOIDs()
1064
			}
1065
    {
1065
		}
1066
      return dirtyOIDs;
1066
1067
    }
1067
		public CommitTransactionResult commitTransactionPhase2(
1068
1068
				InternalCDOXACommitContext xaContext, OMMonitor monitor) {
1069
    public Collection<CDOID> getDetachedObjects()
1069
			int attempt = 0;
1070
    {
1070
			for (;;) {
1071
      return detachedObjects;
1071
				try {
1072
    }
1072
					return delegate.commitTransactionPhase2(xaContext, monitor);
1073
1073
				} catch (Exception ex) {
1074
    public Collection<CDOPackageUnit> getNewPackageUnits()
1074
					handleException(++attempt, ex);
1075
    {
1075
				}
1076
      return newPackageUnits;
1076
			}
1077
    }
1077
		}
1078
1078
1079
    @Override
1079
		public CommitTransactionResult commitTransactionPhase3(
1080
    public String toString()
1080
				InternalCDOXACommitContext xaContext, OMMonitor monitor) {
1081
    {
1081
			int attempt = 0;
1082
      return "CDOSessionInvalidationEvent: " + dirtyOIDs;
1082
			for (;;) {
1083
    }
1083
				try {
1084
  }
1084
					return delegate.commitTransactionPhase3(xaContext, monitor);
1085
1085
				} catch (Exception ex) {
1086
  /**
1086
					handleException(++attempt, ex);
1087
   * @author Eike Stepper
1087
				}
1088
   */
1088
			}
1089
  public class DelegatingSessionProtocol extends Lifecycle implements CDOSessionProtocol
1089
		}
1090
  {
1090
1091
    private CDOSessionProtocol delegate;
1091
		public RepositoryTimeResult getRepositoryTime() {
1092
1092
			int attempt = 0;
1093
    @ExcludeFromDump
1093
			for (;;) {
1094
    private IListener delegateListener = new LifecycleEventAdapter()
1094
				try {
1095
    {
1095
					return delegate.getRepositoryTime();
1096
      @Override
1096
				} catch (Exception ex) {
1097
      protected void onDeactivated(ILifecycle lifecycle)
1097
					handleException(++attempt, ex);
1098
      {
1098
				}
1099
        DelegatingSessionProtocol.this.deactivate();
1099
			}
1100
      }
1100
		}
1101
    };
1101
1102
1102
		public boolean isObjectLocked(CDOView view, CDOObject object,
1103
    public DelegatingSessionProtocol(CDOSessionProtocol delegate)
1103
				LockType lockType, boolean byOthers) {
1104
    {
1104
			int attempt = 0;
1105
      this.delegate = delegate;
1105
			for (;;) {
1106
      activate();
1106
				try {
1107
    }
1107
					return delegate.isObjectLocked(view, object, lockType,
1108
1108
							byOthers);
1109
    public CDOSessionProtocol getDelegate()
1109
				} catch (Exception ex) {
1110
    {
1110
					handleException(++attempt, ex);
1111
      return delegate;
1111
				}
1112
    }
1112
			}
1113
1113
		}
1114
    public CDOSession getSession()
1114
1115
    {
1115
		public EPackage[] loadPackages(CDOPackageUnit packageUnit) {
1116
      return (CDOSession)delegate.getSession();
1116
			int attempt = 0;
1117
    }
1117
			for (;;) {
1118
1118
				try {
1119
    public boolean cancelQuery(int queryId)
1119
					return delegate.loadPackages(packageUnit);
1120
    {
1120
				} catch (Exception ex) {
1121
      int attempt = 0;
1121
					handleException(++attempt, ex);
1122
      for (;;)
1122
				}
1123
      {
1123
			}
1124
        try
1124
		}
1125
        {
1125
1126
          return delegate.cancelQuery(queryId);
1126
		public Object loadChunk(InternalCDORevision revision,
1127
        }
1127
				EStructuralFeature feature, int accessIndex, int fetchIndex,
1128
        catch (Exception ex)
1128
				int fromIndex, int toIndex) {
1129
        {
1129
			int attempt = 0;
1130
          handleException(++attempt, ex);
1130
			for (;;) {
1131
        }
1131
				try {
1132
      }
1132
					return delegate.loadChunk(revision, feature, accessIndex,
1133
    }
1133
							fetchIndex, fromIndex, toIndex);
1134
1134
				} catch (Exception ex) {
1135
    public void changeSubscription(int viewId, List<CDOID> cdoIDs, boolean subscribeMode, boolean clear)
1135
					handleException(++attempt, ex);
1136
    {
1136
				}
1137
      int attempt = 0;
1137
			}
1138
      for (;;)
1138
		}
1139
      {
1139
1140
        try
1140
		public InternalCDORevision loadRevision(CDOID id, int referenceChunk,
1141
        {
1141
				int prefetchDepth) {
1142
          delegate.changeSubscription(viewId, cdoIDs, subscribeMode, clear);
1142
			int attempt = 0;
1143
          return;
1143
			for (;;) {
1144
        }
1144
				try {
1145
        catch (Exception ex)
1145
					return delegate.loadRevision(id, referenceChunk,
1146
        {
1146
							prefetchDepth);
1147
          handleException(++attempt, ex);
1147
				} catch (Exception ex) {
1148
        }
1148
					handleException(++attempt, ex);
1149
      }
1149
				}
1150
    }
1150
			}
1151
1151
		}
1152
    public void closeView(int viewId)
1152
1153
    {
1153
		public InternalCDORevision loadRevisionByTime(CDOID id,
1154
      int attempt = 0;
1154
				int referenceChunk, int prefetchDepth, long timeStamp) {
1155
      for (;;)
1155
			int attempt = 0;
1156
      {
1156
			for (;;) {
1157
        try
1157
				try {
1158
        {
1158
					return delegate.loadRevisionByTime(id, referenceChunk,
1159
          delegate.closeView(viewId);
1159
							prefetchDepth, timeStamp);
1160
          return;
1160
				} catch (Exception ex) {
1161
        }
1161
					handleException(++attempt, ex);
1162
        catch (Exception ex)
1162
				}
1163
        {
1163
			}
1164
          handleException(++attempt, ex);
1164
		}
1165
        }
1165
1166
      }
1166
		public InternalCDORevision loadRevisionByVersion(CDOID id,
1167
    }
1167
				int referenceChunk, int prefetchDepth, int version) {
1168
1168
			int attempt = 0;
1169
    public CommitTransactionResult commitTransaction(InternalCDOCommitContext commitContext, OMMonitor monitor)
1169
			for (;;) {
1170
    {
1170
				try {
1171
      int attempt = 0;
1171
					return delegate.loadRevisionByVersion(id, referenceChunk,
1172
      for (;;)
1172
							prefetchDepth, version);
1173
      {
1173
				} catch (Exception ex) {
1174
        try
1174
					handleException(++attempt, ex);
1175
        {
1175
				}
1176
          return delegate.commitTransaction(commitContext, monitor);
1176
			}
1177
        }
1177
		}
1178
        catch (Exception ex)
1178
1179
        {
1179
		public List<InternalCDORevision> loadRevisions(Collection<CDOID> ids,
1180
          handleException(++attempt, ex);
1180
				int referenceChunk, int prefetchDepth) {
1181
        }
1181
			int attempt = 0;
1182
      }
1182
			for (;;) {
1183
    }
1183
				try {
1184
1184
					return delegate.loadRevisions(ids, referenceChunk,
1185
    public CommitTransactionResult commitTransactionCancel(InternalCDOXACommitContext xaContext, OMMonitor monitor)
1185
							prefetchDepth);
1186
    {
1186
				} catch (Exception ex) {
1187
      int attempt = 0;
1187
					handleException(++attempt, ex);
1188
      for (;;)
1188
				}
1189
      {
1189
			}
1190
        try
1190
		}
1191
        {
1191
1192
          return delegate.commitTransactionCancel(xaContext, monitor);
1192
		public List<InternalCDORevision> loadRevisionsByTime(
1193
        }
1193
				Collection<CDOID> ids, int referenceChunk, int prefetchDepth,
1194
        catch (Exception ex)
1194
				long timeStamp) {
1195
        {
1195
			int attempt = 0;
1196
          handleException(++attempt, ex);
1196
			for (;;) {
1197
        }
1197
				try {
1198
      }
1198
					return delegate.loadRevisionsByTime(ids, referenceChunk,
1199
    }
1199
							prefetchDepth, timeStamp);
1200
1200
				} catch (Exception ex) {
1201
    public CommitTransactionResult commitTransactionPhase1(InternalCDOXACommitContext xaContext, OMMonitor monitor)
1201
					handleException(++attempt, ex);
1202
    {
1202
				}
1203
      int attempt = 0;
1203
			}
1204
      for (;;)
1204
		}
1205
      {
1205
1206
        try
1206
		public InternalCDORevision verifyRevision(InternalCDORevision revision,
1207
        {
1207
				int referenceChunk) {
1208
          return delegate.commitTransactionPhase1(xaContext, monitor);
1208
			int attempt = 0;
1209
        }
1209
			for (;;) {
1210
        catch (Exception ex)
1210
				try {
1211
        {
1211
					return delegate.verifyRevision(revision, referenceChunk);
1212
          handleException(++attempt, ex);
1212
				} catch (Exception ex) {
1213
        }
1213
					handleException(++attempt, ex);
1214
      }
1214
				}
1215
    }
1215
			}
1216
1216
		}
1217
    public CommitTransactionResult commitTransactionPhase2(InternalCDOXACommitContext xaContext, OMMonitor monitor)
1217
1218
    {
1218
		public void lockObjects(CDOView view,
1219
      int attempt = 0;
1219
				Map<CDOID, CDOIDAndVersion> objects, long timeout,
1220
      for (;;)
1220
				LockType lockType) throws InterruptedException {
1221
      {
1221
			int attempt = 0;
1222
        try
1222
			for (;;) {
1223
        {
1223
				try {
1224
          return delegate.commitTransactionPhase2(xaContext, monitor);
1224
					delegate.lockObjects(view, objects, timeout, lockType);
1225
        }
1225
					return;
1226
        catch (Exception ex)
1226
				} catch (Exception ex) {
1227
        {
1227
					handleException(++attempt, ex);
1228
          handleException(++attempt, ex);
1228
				}
1229
        }
1229
			}
1230
      }
1230
		}
1231
    }
1231
1232
1232
		public void openView(int viewId, CDOCommonView.Type viewType,
1233
    public CommitTransactionResult commitTransactionPhase3(InternalCDOXACommitContext xaContext, OMMonitor monitor)
1233
				long timeStamp) {
1234
    {
1234
			int attempt = 0;
1235
      int attempt = 0;
1235
			for (;;) {
1236
      for (;;)
1236
				try {
1237
      {
1237
					delegate.openView(viewId, viewType, timeStamp);
1238
        try
1238
					return;
1239
        {
1239
				} catch (Exception ex) {
1240
          return delegate.commitTransactionPhase3(xaContext, monitor);
1240
					handleException(++attempt, ex);
1241
        }
1241
				}
1242
        catch (Exception ex)
1242
			}
1243
        {
1243
		}
1244
          handleException(++attempt, ex);
1244
1245
        }
1245
		public void query(int viewID, AbstractQueryIterator<?> queryResult) {
1246
      }
1246
			int attempt = 0;
1247
    }
1247
			for (;;) {
1248
1248
				try {
1249
    public RepositoryTimeResult getRepositoryTime()
1249
					delegate.query(viewID, queryResult);
1250
    {
1250
					return;
1251
      int attempt = 0;
1251
				} catch (Exception ex) {
1252
      for (;;)
1252
					handleException(++attempt, ex);
1253
      {
1253
				}
1254
        try
1254
			}
1255
        {
1255
		}
1256
          return delegate.getRepositoryTime();
1256
1257
        }
1257
		public boolean[] setAudit(int viewId, long timeStamp,
1258
        catch (Exception ex)
1258
				List<InternalCDOObject> invalidObjects) {
1259
        {
1259
			int attempt = 0;
1260
          handleException(++attempt, ex);
1260
			for (;;) {
1261
        }
1261
				try {
1262
      }
1262
					return delegate.setAudit(viewId, timeStamp, invalidObjects);
1263
    }
1263
				} catch (Exception ex) {
1264
1264
					handleException(++attempt, ex);
1265
    public boolean isObjectLocked(CDOView view, CDOObject object, LockType lockType, boolean byOthers)
1265
				}
1266
    {
1266
			}
1267
      int attempt = 0;
1267
		}
1268
      for (;;)
1268
1269
      {
1269
		public void setPassiveUpdate(Map<CDOID, CDOIDAndVersion> idAndVersions,
1270
        try
1270
				int initialChunkSize, boolean passiveUpdateEnabled) {
1271
        {
1271
			int attempt = 0;
1272
          return delegate.isObjectLocked(view, object, lockType, byOthers);
1272
			for (;;) {
1273
        }
1273
				try {
1274
        catch (Exception ex)
1274
					delegate.setPassiveUpdate(idAndVersions, initialChunkSize,
1275
        {
1275
							passiveUpdateEnabled);
1276
          handleException(++attempt, ex);
1276
					return;
1277
        }
1277
				} catch (Exception ex) {
1278
      }
1278
					handleException(++attempt, ex);
1279
    }
1279
				}
1280
1280
			}
1281
    public EPackage[] loadPackages(CDOPackageUnit packageUnit)
1281
		}
1282
    {
1282
1283
      int attempt = 0;
1283
		public Collection<CDOTimeStampContext> syncRevisions(
1284
      for (;;)
1284
				Map<CDOID, CDOIDAndVersion> allRevisions, int initialChunkSize) {
1285
      {
1285
			int attempt = 0;
1286
        try
1286
			for (;;) {
1287
        {
1287
				try {
1288
          return delegate.loadPackages(packageUnit);
1288
					return delegate.syncRevisions(allRevisions,
1289
        }
1289
							initialChunkSize);
1290
        catch (Exception ex)
1290
				} catch (Exception ex) {
1291
        {
1291
					handleException(++attempt, ex);
1292
          handleException(++attempt, ex);
1292
				}
1293
        }
1293
			}
1294
      }
1294
		}
1295
    }
1295
1296
1296
		public void unlockObjects(CDOView view,
1297
    public Object loadChunk(InternalCDORevision revision, EStructuralFeature feature, int accessIndex, int fetchIndex,
1297
				Collection<? extends CDOObject> objects, LockType lockType) {
1298
        int fromIndex, int toIndex)
1298
			int attempt = 0;
1299
    {
1299
			for (;;) {
1300
      int attempt = 0;
1300
				try {
1301
      for (;;)
1301
					delegate.unlockObjects(view, objects, lockType);
1302
      {
1302
					return;
1303
        try
1303
				} catch (Exception ex) {
1304
        {
1304
					handleException(++attempt, ex);
1305
          return delegate.loadChunk(revision, feature, accessIndex, fetchIndex, fromIndex, toIndex);
1305
				}
1306
        }
1306
			}
1307
        catch (Exception ex)
1307
		}
1308
        {
1308
1309
          handleException(++attempt, ex);
1309
		public List<CDORemoteSession> getRemoteSessions(
1310
        }
1310
				InternalCDORemoteSessionManager manager, boolean subscribe) {
1311
      }
1311
			int attempt = 0;
1312
    }
1312
			for (;;) {
1313
1313
				try {
1314
    public InternalCDORevision loadRevision(CDOID id, int referenceChunk, int prefetchDepth)
1314
					return delegate.getRemoteSessions(manager, subscribe);
1315
    {
1315
				} catch (Exception ex) {
1316
      int attempt = 0;
1316
					handleException(++attempt, ex);
1317
      for (;;)
1317
				}
1318
      {
1318
			}
1319
        try
1319
		}
1320
        {
1320
1321
          return delegate.loadRevision(id, referenceChunk, prefetchDepth);
1321
		public Set<Integer> sendRemoteMessage(CDORemoteSessionMessage message,
1322
        }
1322
				List<CDORemoteSession> recipients) {
1323
        catch (Exception ex)
1323
			int attempt = 0;
1324
        {
1324
			for (;;) {
1325
          handleException(++attempt, ex);
1325
				try {
1326
        }
1326
					return delegate.sendRemoteMessage(message, recipients);
1327
      }
1327
				} catch (Exception ex) {
1328
    }
1328
					handleException(++attempt, ex);
1329
1329
				}
1330
    public InternalCDORevision loadRevisionByTime(CDOID id, int referenceChunk, int prefetchDepth, long timeStamp)
1330
			}
1331
    {
1331
		}
1332
      int attempt = 0;
1332
1333
      for (;;)
1333
		public boolean unsubscribeRemoteSessions() {
1334
      {
1334
			int attempt = 0;
1335
        try
1335
			for (;;) {
1336
        {
1336
				try {
1337
          return delegate.loadRevisionByTime(id, referenceChunk, prefetchDepth, timeStamp);
1337
					return delegate.unsubscribeRemoteSessions();
1338
        }
1338
				} catch (Exception ex) {
1339
        catch (Exception ex)
1339
					handleException(++attempt, ex);
1340
        {
1340
				}
1341
          handleException(++attempt, ex);
1341
			}
1342
        }
1342
		}
1343
      }
1343
1344
    }
1344
		@Override
1345
1345
		protected void doActivate() throws Exception {
1346
    public InternalCDORevision loadRevisionByVersion(CDOID id, int referenceChunk, int prefetchDepth, int version)
1346
			super.doActivate();
1347
    {
1347
			EventUtil.addListener(delegate, delegateListener);
1348
      int attempt = 0;
1348
		}
1349
      for (;;)
1349
1350
      {
1350
		@Override
1351
        try
1351
		protected void doDeactivate() throws Exception {
1352
        {
1352
			EventUtil.removeListener(delegate, delegateListener);
1353
          return delegate.loadRevisionByVersion(id, referenceChunk, prefetchDepth, version);
1353
			LifecycleUtil.deactivate(delegate);
1354
        }
1354
			delegate = null;
1355
        catch (Exception ex)
1355
			super.doDeactivate();
1356
        {
1356
		}
1357
          handleException(++attempt, ex);
1357
1358
        }
1358
		private void handleException(int attempt, Exception exception) {
1359
      }
1359
			try {
1360
    }
1360
				getExceptionHandler().handleException(CDOSessionImpl.this,
1361
1361
						attempt, exception);
1362
    public List<InternalCDORevision> loadRevisions(Collection<CDOID> ids, int referenceChunk, int prefetchDepth)
1362
			} catch (Exception ex) {
1363
    {
1363
				throw WrappedException.wrap(ex);
1364
      int attempt = 0;
1364
			}
1365
      for (;;)
1365
		}
1366
      {
1366
1367
        try
1367
		/**
1368
        {
1368
		 * @author Juan Pedro Silva
1369
          return delegate.loadRevisions(ids, referenceChunk, prefetchDepth);
1369
		 */
1370
        }
1370
		public void subscribeRemoteLocks() {
1371
        catch (Exception ex)
1371
			getDelegate().subscribeRemoteLocks();
1372
        {
1372
		}
1373
          handleException(++attempt, ex);
1373
1374
        }
1374
		/**
1375
      }
1375
		 * @author Juan Pedro Silva
1376
    }
1376
		 */
1377
1377
		public void unsubscribeRemoteLocks() {
1378
    public List<InternalCDORevision> loadRevisionsByTime(Collection<CDOID> ids, int referenceChunk, int prefetchDepth,
1378
			getDelegate().unsubscribeRemoteLocks();
1379
        long timeStamp)
1379
		}
1380
    {
1380
	}
1381
      int attempt = 0;
1381
1382
      for (;;)
1382
	/**
1383
      {
1383
	 * @author Juan Pedro Silva
1384
        try
1384
	 */
1385
        {
1385
	public void registerLockListeners(InternalCDOView cdoView) {
1386
          return delegate.loadRevisionsByTime(ids, referenceChunk, prefetchDepth, timeStamp);
1386
		if (!hasRegisteredListeners) {
1387
        }
1387
			hasRegisteredListeners = true;
1388
        catch (Exception ex)
1388
			getSessionProtocol().subscribeRemoteLocks();
1389
        {
1389
		}
1390
          handleException(++attempt, ex);
1390
		registeredLockListeners.add(cdoView);
1391
        }
1391
	}
1392
      }
1392
1393
    }
1393
	/**
1394
1394
	 * @author Juan Pedro Silva
1395
    public InternalCDORevision verifyRevision(InternalCDORevision revision, int referenceChunk)
1395
	 */
1396
    {
1396
	public void unregisterLockListeners(InternalCDOView cdoView) {
1397
      int attempt = 0;
1397
		registeredLockListeners.remove(cdoView);
1398
      for (;;)
1398
		if (registeredLockListeners.isEmpty()) {
1399
      {
1399
			hasRegisteredListeners = false;
1400
        try
1400
			getSessionProtocol().unsubscribeRemoteLocks();
1401
        {
1401
		}
1402
          return delegate.verifyRevision(revision, referenceChunk);
1402
	}
1403
        }
1404
        catch (Exception ex)
1405
        {
1406
          handleException(++attempt, ex);
1407
        }
1408
      }
1409
    }
1410
1411
    public void lockObjects(CDOView view, Map<CDOID, CDOIDAndVersion> objects, long timeout, LockType lockType)
1412
        throws InterruptedException
1413
    {
1414
      int attempt = 0;
1415
      for (;;)
1416
      {
1417
        try
1418
        {
1419
          delegate.lockObjects(view, objects, timeout, lockType);
1420
          return;
1421
        }
1422
        catch (Exception ex)
1423
        {
1424
          handleException(++attempt, ex);
1425
        }
1426
      }
1427
    }
1428
1429
    public void openView(int viewId, CDOCommonView.Type viewType, long timeStamp)
1430
    {
1431
      int attempt = 0;
1432
      for (;;)
1433
      {
1434
        try
1435
        {
1436
          delegate.openView(viewId, viewType, timeStamp);
1437
          return;
1438
        }
1439
        catch (Exception ex)
1440
        {
1441
          handleException(++attempt, ex);
1442
        }
1443
      }
1444
    }
1445
1446
    public void query(int viewID, AbstractQueryIterator<?> queryResult)
1447
    {
1448
      int attempt = 0;
1449
      for (;;)
1450
      {
1451
        try
1452
        {
1453
          delegate.query(viewID, queryResult);
1454
          return;
1455
        }
1456
        catch (Exception ex)
1457
        {
1458
          handleException(++attempt, ex);
1459
        }
1460
      }
1461
    }
1462
1463
    public boolean[] setAudit(int viewId, long timeStamp, List<InternalCDOObject> invalidObjects)
1464
    {
1465
      int attempt = 0;
1466
      for (;;)
1467
      {
1468
        try
1469
        {
1470
          return delegate.setAudit(viewId, timeStamp, invalidObjects);
1471
        }
1472
        catch (Exception ex)
1473
        {
1474
          handleException(++attempt, ex);
1475
        }
1476
      }
1477
    }
1478
1479
    public void setPassiveUpdate(Map<CDOID, CDOIDAndVersion> idAndVersions, int initialChunkSize,
1480
        boolean passiveUpdateEnabled)
1481
    {
1482
      int attempt = 0;
1483
      for (;;)
1484
      {
1485
        try
1486
        {
1487
          delegate.setPassiveUpdate(idAndVersions, initialChunkSize, passiveUpdateEnabled);
1488
          return;
1489
        }
1490
        catch (Exception ex)
1491
        {
1492
          handleException(++attempt, ex);
1493
        }
1494
      }
1495
    }
1496
1497
    public Collection<CDOTimeStampContext> syncRevisions(Map<CDOID, CDOIDAndVersion> allRevisions, int initialChunkSize)
1498
    {
1499
      int attempt = 0;
1500
      for (;;)
1501
      {
1502
        try
1503
        {
1504
          return delegate.syncRevisions(allRevisions, initialChunkSize);
1505
        }
1506
        catch (Exception ex)
1507
        {
1508
          handleException(++attempt, ex);
1509
        }
1510
      }
1511
    }
1512
1513
    public void unlockObjects(CDOView view, Collection<? extends CDOObject> objects, LockType lockType)
1514
    {
1515
      int attempt = 0;
1516
      for (;;)
1517
      {
1518
        try
1519
        {
1520
          delegate.unlockObjects(view, objects, lockType);
1521
          return;
1522
        }
1523
        catch (Exception ex)
1524
        {
1525
          handleException(++attempt, ex);
1526
        }
1527
      }
1528
    }
1529
1530
    public List<CDORemoteSession> getRemoteSessions(InternalCDORemoteSessionManager manager, boolean subscribe)
1531
    {
1532
      int attempt = 0;
1533
      for (;;)
1534
      {
1535
        try
1536
        {
1537
          return delegate.getRemoteSessions(manager, subscribe);
1538
        }
1539
        catch (Exception ex)
1540
        {
1541
          handleException(++attempt, ex);
1542
        }
1543
      }
1544
    }
1545
1546
    public Set<Integer> sendRemoteMessage(CDORemoteSessionMessage message, List<CDORemoteSession> recipients)
1547
    {
1548
      int attempt = 0;
1549
      for (;;)
1550
      {
1551
        try
1552
        {
1553
          return delegate.sendRemoteMessage(message, recipients);
1554
        }
1555
        catch (Exception ex)
1556
        {
1557
          handleException(++attempt, ex);
1558
        }
1559
      }
1560
    }
1561
1562
    public boolean unsubscribeRemoteSessions()
1563
    {
1564
      int attempt = 0;
1565
      for (;;)
1566
      {
1567
        try
1568
        {
1569
          return delegate.unsubscribeRemoteSessions();
1570
        }
1571
        catch (Exception ex)
1572
        {
1573
          handleException(++attempt, ex);
1574
        }
1575
      }
1576
    }
1577
1578
    @Override
1579
    protected void doActivate() throws Exception
1580
    {
1581
      super.doActivate();
1582
      EventUtil.addListener(delegate, delegateListener);
1583
    }
1584
1585
    @Override
1586
    protected void doDeactivate() throws Exception
1587
    {
1588
      EventUtil.removeListener(delegate, delegateListener);
1589
      LifecycleUtil.deactivate(delegate);
1590
      delegate = null;
1591
      super.doDeactivate();
1592
    }
1593
1594
    private void handleException(int attempt, Exception exception)
1595
    {
1596
      try
1597
      {
1598
        getExceptionHandler().handleException(CDOSessionImpl.this, attempt, exception);
1599
      }
1600
      catch (Exception ex)
1601
      {
1602
        throw WrappedException.wrap(ex);
1603
      }
1604
    }
1605
  }
1606
}
1403
}
(-)src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java (-367 / +358 lines)
Lines 48-418 Link Here
48
 * @author Eike Stepper
48
 * @author Eike Stepper
49
 * @since 2.0
49
 * @since 2.0
50
 */
50
 */
51
public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, RevisionLoader
51
public interface CDOSessionProtocol extends CDOProtocol, PackageLoader,
52
{
52
		RevisionLoader {
53
  public void setPassiveUpdate(Map<CDOID, CDOIDAndVersion> idAndVersions, int initialChunkSize,
53
	public void setPassiveUpdate(Map<CDOID, CDOIDAndVersion> idAndVersions,
54
      boolean passiveUpdateEnabled);
54
			int initialChunkSize, boolean passiveUpdateEnabled);
55
55
56
  public RepositoryTimeResult getRepositoryTime();
56
	public RepositoryTimeResult getRepositoryTime();
57
57
58
  /**
58
	/**
59
   * @param revision
59
	 * @param revision
60
   * @param feature
60
	 * @param feature
61
   * @param accessIndex
61
	 * @param accessIndex
62
   *          Index of the item access at the client (with modifications)
62
	 *            Index of the item access at the client (with modifications)
63
   * @param fetchIndex
63
	 * @param fetchIndex
64
   *          Index of the item access at the server (without any modifications)
64
	 *            Index of the item access at the server (without any
65
   * @param fromIndex
65
	 *            modifications)
66
   *          Load objects at the client from fromIndex (inclusive)
66
	 * @param fromIndex
67
   * @param toIndex
67
	 *            Load objects at the client from fromIndex (inclusive)
68
   *          Load objects at the client to toIndex (inclusive)
68
	 * @param toIndex
69
   */
69
	 *            Load objects at the client to toIndex (inclusive)
70
  public Object loadChunk(InternalCDORevision revision, EStructuralFeature feature, int accessIndex, int fetchIndex,
70
	 */
71
      int fromIndex, int toIndex);
71
	public Object loadChunk(InternalCDORevision revision,
72
72
			EStructuralFeature feature, int accessIndex, int fetchIndex,
73
  public Collection<CDOTimeStampContext> syncRevisions(Map<CDOID, CDOIDAndVersion> allRevisions, int initialChunkSize);
73
			int fromIndex, int toIndex);
74
74
75
  /**
75
	public Collection<CDOTimeStampContext> syncRevisions(
76
   * @since 3.0
76
			Map<CDOID, CDOIDAndVersion> allRevisions, int initialChunkSize);
77
   */
77
78
  public void openView(int viewId, CDOCommonView.Type type, long timeStamp);
78
	/**
79
79
	 * @since 3.0
80
  public void closeView(int viewId);
80
	 */
81
81
	public void openView(int viewId, CDOCommonView.Type type, long timeStamp);
82
  public boolean[] setAudit(int viewId, long timeStamp, List<InternalCDOObject> invalidObjects);
82
83
83
	public void closeView(int viewId);
84
  public void changeSubscription(int viewId, List<CDOID> cdoIDs, boolean subscribeMode, boolean clear);
84
85
85
	public boolean[] setAudit(int viewId, long timeStamp,
86
  /**
86
			List<InternalCDOObject> invalidObjects);
87
   * @since 3.0
87
88
   */
88
	public void changeSubscription(int viewId, List<CDOID> cdoIDs,
89
  public void query(int viewID, AbstractQueryIterator<?> queryResult);
89
			boolean subscribeMode, boolean clear);
90
90
91
  public boolean cancelQuery(int queryId);
91
	/**
92
92
	 * @since 3.0
93
  /**
93
	 */
94
   * @since 3.0
94
	public void query(int viewID, AbstractQueryIterator<?> queryResult);
95
   */
95
96
  public void lockObjects(CDOView view, Map<CDOID, CDOIDAndVersion> objects, long timeout, LockType lockType)
96
	public boolean cancelQuery(int queryId);
97
      throws InterruptedException;
97
98
98
	/**
99
  /**
99
	 * @since 3.0
100
   * @since 3.0
100
	 */
101
   */
101
	public void lockObjects(CDOView view, Map<CDOID, CDOIDAndVersion> objects,
102
  public void unlockObjects(CDOView view, Collection<? extends CDOObject> objects, LockType lockType);
102
			long timeout, LockType lockType) throws InterruptedException;
103
103
104
  /**
104
	/**
105
   * @since 3.0
105
	 * @since 3.0
106
   */
106
	 */
107
  public boolean isObjectLocked(CDOView view, CDOObject object, LockType lockType, boolean byOthers);
107
	public void unlockObjects(CDOView view,
108
108
			Collection<? extends CDOObject> objects, LockType lockType);
109
  public CommitTransactionResult commitTransaction(InternalCDOCommitContext commitContext, OMMonitor monitor);
109
110
110
	/**
111
  public CommitTransactionResult commitTransactionPhase1(InternalCDOXACommitContext xaContext, OMMonitor monitor);
111
	 * @since 3.0
112
112
	 */
113
  public CommitTransactionResult commitTransactionPhase2(InternalCDOXACommitContext xaContext, OMMonitor monitor);
113
	public boolean isObjectLocked(CDOView view, CDOObject object,
114
114
			LockType lockType, boolean byOthers);
115
  public CommitTransactionResult commitTransactionPhase3(InternalCDOXACommitContext xaContext, OMMonitor monitor);
115
116
116
	public CommitTransactionResult commitTransaction(
117
  public CommitTransactionResult commitTransactionCancel(InternalCDOXACommitContext xaContext, OMMonitor monitor);
117
			InternalCDOCommitContext commitContext, OMMonitor monitor);
118
118
119
  public List<CDORemoteSession> getRemoteSessions(InternalCDORemoteSessionManager manager, boolean subscribe);
119
	public CommitTransactionResult commitTransactionPhase1(
120
120
			InternalCDOXACommitContext xaContext, OMMonitor monitor);
121
  /**
121
122
   * @since 3.0
122
	public CommitTransactionResult commitTransactionPhase2(
123
   */
123
			InternalCDOXACommitContext xaContext, OMMonitor monitor);
124
  public Set<Integer> sendRemoteMessage(CDORemoteSessionMessage message, List<CDORemoteSession> recipients);
124
125
125
	public CommitTransactionResult commitTransactionPhase3(
126
  /**
126
			InternalCDOXACommitContext xaContext, OMMonitor monitor);
127
   * @since 3.0
127
128
   */
128
	public CommitTransactionResult commitTransactionCancel(
129
  public boolean unsubscribeRemoteSessions();
129
			InternalCDOXACommitContext xaContext, OMMonitor monitor);
130
130
131
  /**
131
	public List<CDORemoteSession> getRemoteSessions(
132
   * @author Eike Stepper
132
			InternalCDORemoteSessionManager manager, boolean subscribe);
133
   */
133
134
  public final class OpenSessionResult
134
	/**
135
  {
135
	 * @since 3.0
136
    private int sessionID;
136
	 */
137
137
	public Set<Integer> sendRemoteMessage(CDORemoteSessionMessage message,
138
    private String repositoryUUID;
138
			List<CDORemoteSession> recipients);
139
139
140
    private long repositoryCreationTime;
140
	/**
141
141
	 * @since 3.0
142
    private long lastUpdateTime;
142
	 */
143
143
	public boolean unsubscribeRemoteSessions();
144
    private RepositoryTimeResult repositoryTimeResult;
144
145
145
	/**
146
    private boolean repositorySupportingAudits;
146
	 * @author Eike Stepper
147
147
	 */
148
    private List<InternalCDOPackageUnit> packageUnits = new ArrayList<InternalCDOPackageUnit>();
148
	public final class OpenSessionResult {
149
149
		private int sessionID;
150
    /**
150
151
     * @since 3.0
151
		private String repositoryUUID;
152
     */
152
153
    public OpenSessionResult(int sessionID, String repositoryUUID, long repositoryCreationTime, long lastUpdateTime,
153
		private long repositoryCreationTime;
154
        boolean repositorySupportingAudits)
154
155
    {
155
		private long lastUpdateTime;
156
      this.sessionID = sessionID;
156
157
      this.repositoryUUID = repositoryUUID;
157
		private RepositoryTimeResult repositoryTimeResult;
158
      this.repositoryCreationTime = repositoryCreationTime;
158
159
      this.lastUpdateTime = lastUpdateTime;
159
		private boolean repositorySupportingAudits;
160
      this.repositorySupportingAudits = repositorySupportingAudits;
160
161
    }
161
		private List<InternalCDOPackageUnit> packageUnits = new ArrayList<InternalCDOPackageUnit>();
162
162
163
    public int getSessionID()
163
		/**
164
    {
164
		 * @since 3.0
165
      return sessionID;
165
		 */
166
    }
166
		public OpenSessionResult(int sessionID, String repositoryUUID,
167
167
				long repositoryCreationTime, long lastUpdateTime,
168
    public String getRepositoryUUID()
168
				boolean repositorySupportingAudits) {
169
    {
169
			this.sessionID = sessionID;
170
      return repositoryUUID;
170
			this.repositoryUUID = repositoryUUID;
171
    }
171
			this.repositoryCreationTime = repositoryCreationTime;
172
172
			this.lastUpdateTime = lastUpdateTime;
173
    public long getRepositoryCreationTime()
173
			this.repositorySupportingAudits = repositorySupportingAudits;
174
    {
174
		}
175
      return repositoryCreationTime;
175
176
    }
176
		public int getSessionID() {
177
177
			return sessionID;
178
    public boolean isRepositorySupportingAudits()
178
		}
179
    {
179
180
      return repositorySupportingAudits;
180
		public String getRepositoryUUID() {
181
    }
181
			return repositoryUUID;
182
182
		}
183
    public RepositoryTimeResult getRepositoryTimeResult()
183
184
    {
184
		public long getRepositoryCreationTime() {
185
      return repositoryTimeResult;
185
			return repositoryCreationTime;
186
    }
186
		}
187
187
188
    public void setRepositoryTimeResult(RepositoryTimeResult repositoryTimeResult)
188
		public boolean isRepositorySupportingAudits() {
189
    {
189
			return repositorySupportingAudits;
190
      this.repositoryTimeResult = repositoryTimeResult;
190
		}
191
    }
191
192
192
		public RepositoryTimeResult getRepositoryTimeResult() {
193
    /**
193
			return repositoryTimeResult;
194
     * @since 3.0
194
		}
195
     */
195
196
    public long getLastUpdateTime()
196
		public void setRepositoryTimeResult(
197
    {
197
				RepositoryTimeResult repositoryTimeResult) {
198
      return lastUpdateTime;
198
			this.repositoryTimeResult = repositoryTimeResult;
199
    }
199
		}
200
200
201
    public List<InternalCDOPackageUnit> getPackageUnits()
201
		/**
202
    {
202
		 * @since 3.0
203
      return packageUnits;
203
		 */
204
    }
204
		public long getLastUpdateTime() {
205
  }
205
			return lastUpdateTime;
206
206
		}
207
  /**
207
208
   * @author Eike Stepper
208
		public List<InternalCDOPackageUnit> getPackageUnits() {
209
   */
209
			return packageUnits;
210
  public final class RepositoryTimeResult
210
		}
211
  {
211
	}
212
    private long requested;
212
213
213
	/**
214
    private long indicated;
214
	 * @author Eike Stepper
215
215
	 */
216
    private long responded;
216
	public final class RepositoryTimeResult {
217
217
		private long requested;
218
    private long confirmed;
218
219
219
		private long indicated;
220
    public RepositoryTimeResult()
220
221
    {
221
		private long responded;
222
    }
222
223
223
		private long confirmed;
224
    public long getRequested()
224
225
    {
225
		public RepositoryTimeResult() {
226
      return requested;
226
		}
227
    }
227
228
228
		public long getRequested() {
229
    public void setRequested(long requested)
229
			return requested;
230
    {
230
		}
231
      this.requested = requested;
231
232
    }
232
		public void setRequested(long requested) {
233
233
			this.requested = requested;
234
    public long getIndicated()
234
		}
235
    {
235
236
      return indicated;
236
		public long getIndicated() {
237
    }
237
			return indicated;
238
238
		}
239
    public void setIndicated(long indicated)
239
240
    {
240
		public void setIndicated(long indicated) {
241
      this.indicated = indicated;
241
			this.indicated = indicated;
242
    }
242
		}
243
243
244
    public long getResponded()
244
		public long getResponded() {
245
    {
245
			return responded;
246
      return responded;
246
		}
247
    }
247
248
248
		public void setResponded(long responded) {
249
    public void setResponded(long responded)
249
			this.responded = responded;
250
    {
250
		}
251
      this.responded = responded;
251
252
    }
252
		public long getConfirmed() {
253
253
			return confirmed;
254
    public long getConfirmed()
254
		}
255
    {
255
256
      return confirmed;
256
		public void setConfirmed(long confirmed) {
257
    }
257
			this.confirmed = confirmed;
258
258
		}
259
    public void setConfirmed(long confirmed)
259
260
    {
260
		public long getAproximateRepositoryOffset() {
261
      this.confirmed = confirmed;
261
			long latency = confirmed - requested >> 1;
262
    }
262
			long shift = confirmed - responded;
263
263
			return shift - latency;
264
    public long getAproximateRepositoryOffset()
264
		}
265
    {
265
266
      long latency = confirmed - requested >> 1;
266
		public long getAproximateRepositoryTime() {
267
      long shift = confirmed - responded;
267
			long offset = getAproximateRepositoryOffset();
268
      return shift - latency;
268
			return System.currentTimeMillis() + offset;
269
    }
269
		}
270
270
271
    public long getAproximateRepositoryTime()
271
		@Override
272
    {
272
		public String toString() {
273
      long offset = getAproximateRepositoryOffset();
273
			return MessageFormat
274
      return System.currentTimeMillis() + offset;
274
					.format(
275
    }
275
							"RepositoryTime[requested={0,date} {0,time}, indicated={1,date} {1,time}, responded={2,date} {2,time}, confirmed={3,date} {3,time}]",
276
276
							requested, indicated, responded, confirmed);
277
    @Override
277
		}
278
    public String toString()
278
	}
279
    {
279
280
      return MessageFormat
280
	/**
281
          .format(
281
	 * @author Eike Stepper
282
              "RepositoryTime[requested={0,date} {0,time}, indicated={1,date} {1,time}, responded={2,date} {2,time}, confirmed={3,date} {3,time}]",
282
	 */
283
              requested, indicated, responded, confirmed);
283
	public final class CommitTransactionResult {
284
    }
284
		private String rollbackMessage;
285
  }
285
286
286
		private long timeStamp;
287
  /**
287
288
   * @author Eike Stepper
288
		// private List<CDOIDMetaRange> metaIDRanges = new
289
   */
289
		// ArrayList<CDOIDMetaRange>();
290
  public final class CommitTransactionResult
290
291
  {
291
		private Map<CDOIDTemp, CDOID> idMappings = new HashMap<CDOIDTemp, CDOID>();
292
    private String rollbackMessage;
292
293
293
		private CDOReferenceAdjuster referenceAdjuster;
294
    private long timeStamp;
294
295
295
		private InternalCDOCommitContext commitContext;
296
    // private List<CDOIDMetaRange> metaIDRanges = new ArrayList<CDOIDMetaRange>();
296
297
297
		public CommitTransactionResult(InternalCDOCommitContext commitContext,
298
    private Map<CDOIDTemp, CDOID> idMappings = new HashMap<CDOIDTemp, CDOID>();
298
				String rollbackMessage) {
299
299
			this.rollbackMessage = rollbackMessage;
300
    private CDOReferenceAdjuster referenceAdjuster;
300
			this.commitContext = commitContext;
301
301
		}
302
    private InternalCDOCommitContext commitContext;
302
303
303
		public CommitTransactionResult(InternalCDOCommitContext commitContext,
304
    public CommitTransactionResult(InternalCDOCommitContext commitContext, String rollbackMessage)
304
				long timeStamp) {
305
    {
305
			this.timeStamp = timeStamp;
306
      this.rollbackMessage = rollbackMessage;
306
			this.commitContext = commitContext;
307
      this.commitContext = commitContext;
307
		}
308
    }
308
309
309
		public CDOReferenceAdjuster getReferenceAdjuster() {
310
    public CommitTransactionResult(InternalCDOCommitContext commitContext, long timeStamp)
310
			if (referenceAdjuster == null) {
311
    {
311
				referenceAdjuster = createReferenceAdjuster();
312
      this.timeStamp = timeStamp;
312
			}
313
      this.commitContext = commitContext;
313
314
    }
314
			return referenceAdjuster;
315
315
		}
316
    public CDOReferenceAdjuster getReferenceAdjuster()
316
317
    {
317
		public void setReferenceAdjuster(CDOReferenceAdjuster referenceAdjuster) {
318
      if (referenceAdjuster == null)
318
			this.referenceAdjuster = referenceAdjuster;
319
      {
319
		}
320
        referenceAdjuster = createReferenceAdjuster();
320
321
      }
321
		public InternalCDOCommitContext getCommitContext() {
322
322
			return commitContext;
323
      return referenceAdjuster;
323
		}
324
    }
324
325
325
		public String getRollbackMessage() {
326
    public void setReferenceAdjuster(CDOReferenceAdjuster referenceAdjuster)
326
			return rollbackMessage;
327
    {
327
		}
328
      this.referenceAdjuster = referenceAdjuster;
328
329
    }
329
		public long getTimeStamp() {
330
330
			return timeStamp;
331
    public InternalCDOCommitContext getCommitContext()
331
		}
332
    {
332
333
      return commitContext;
333
		public Map<CDOIDTemp, CDOID> getIDMappings() {
334
    }
334
			return idMappings;
335
335
		}
336
    public String getRollbackMessage()
336
337
    {
337
		public void addIDMapping(CDOIDTemp oldID, CDOID newID) {
338
      return rollbackMessage;
338
			idMappings.put(oldID, newID);
339
    }
339
		}
340
340
341
    public long getTimeStamp()
341
		// /**
342
    {
342
		// * @since 3.0
343
      return timeStamp;
343
		// */
344
    }
344
		// public List<CDOIDMetaRange> getMetaIDRanges()
345
345
		// {
346
    public Map<CDOIDTemp, CDOID> getIDMappings()
346
		// return metaIDRanges;
347
    {
347
		// }
348
      return idMappings;
348
		//
349
    }
349
		// /**
350
350
		// * @since 3.0
351
    public void addIDMapping(CDOIDTemp oldID, CDOID newID)
351
		// */
352
    {
352
		// public void addMetaIDRange(CDOIDMetaRange metaIDRange)
353
      idMappings.put(oldID, newID);
353
		// {
354
    }
354
		// metaIDRanges.add(metaIDRange);
355
355
		// }
356
    // /**
356
357
    // * @since 3.0
357
		protected PostCommitReferenceAdjuster createReferenceAdjuster() {
358
    // */
358
			return new PostCommitReferenceAdjuster(commitContext
359
    // public List<CDOIDMetaRange> getMetaIDRanges()
359
					.getTransaction(), new CDOIDMapper(idMappings));
360
    // {
360
		}
361
    // return metaIDRanges;
361
362
    // }
362
		/**
363
    //
363
		 * @author Simon McDuff
364
    // /**
364
		 */
365
    // * @since 3.0
365
		protected static class PostCommitReferenceAdjuster implements
366
    // */
366
				CDOReferenceAdjuster {
367
    // public void addMetaIDRange(CDOIDMetaRange metaIDRange)
367
			private CDOIDProvider idProvider;
368
    // {
368
369
    // metaIDRanges.add(metaIDRange);
369
			private CDOIDMapper idMapper;
370
    // }
370
371
371
			public PostCommitReferenceAdjuster(CDOIDProvider idProvider,
372
    protected PostCommitReferenceAdjuster createReferenceAdjuster()
372
					CDOIDMapper idMapper) {
373
    {
373
				this.idProvider = idProvider;
374
      return new PostCommitReferenceAdjuster(commitContext.getTransaction(), new CDOIDMapper(idMappings));
374
				this.idMapper = idMapper;
375
    }
375
			}
376
376
377
    /**
377
			public CDOIDProvider getIdProvider() {
378
     * @author Simon McDuff
378
				return idProvider;
379
     */
379
			}
380
    protected static class PostCommitReferenceAdjuster implements CDOReferenceAdjuster
380
381
    {
381
			public CDOIDMapper getIdMapper() {
382
      private CDOIDProvider idProvider;
382
				return idMapper;
383
383
			}
384
      private CDOIDMapper idMapper;
384
385
385
			public Object adjustReference(Object id) {
386
      public PostCommitReferenceAdjuster(CDOIDProvider idProvider, CDOIDMapper idMapper)
386
				if (id == null || id == CDOID.NULL) {
387
      {
387
					return id;
388
        this.idProvider = idProvider;
388
				}
389
        this.idMapper = idMapper;
389
390
      }
390
				if (idProvider != null
391
391
						&& (id instanceof CDOID || id instanceof InternalEObject)) {
392
      public CDOIDProvider getIdProvider()
392
					id = idProvider.provideCDOID(id);
393
      {
393
				}
394
        return idProvider;
394
395
      }
395
				return idMapper.adjustReference(id);
396
396
			}
397
      public CDOIDMapper getIdMapper()
397
		}
398
      {
398
	}
399
        return idMapper;
399
400
      }
400
	/**
401
401
	 * @author Juan Pedro Silva
402
      public Object adjustReference(Object id)
402
	 */
403
      {
403
	public void subscribeRemoteLocks();
404
        if (id == null || id == CDOID.NULL)
404
405
        {
405
	/**
406
          return id;
406
	 * @author Juan Pedro Silva
407
        }
407
	 */
408
408
	public void unsubscribeRemoteLocks();
409
        if (idProvider != null && (id instanceof CDOID || id instanceof InternalEObject))
410
        {
411
          id = idProvider.provideCDOID(id);
412
        }
413
414
        return idMapper.adjustReference(id);
415
      }
416
    }
417
  }
418
}
409
}
(-)src/org/eclipse/emf/spi/cdo/InternalCDOSession.java (-81 / +97 lines)
Lines 35-119 Link Here
35
 * @author Eike Stepper
35
 * @author Eike Stepper
36
 * @since 2.0
36
 * @since 2.0
37
 */
37
 */
38
public interface InternalCDOSession extends CDOSession, PackageProcessor, PackageLoader, RevisionLocker, ILifecycle
38
public interface InternalCDOSession extends CDOSession, PackageProcessor,
39
{
39
		PackageLoader, RevisionLocker, ILifecycle {
40
  /**
40
	/**
41
   * @since 3.0
41
	 * @since 3.0
42
   */
42
	 */
43
  public InternalCDOSessionConfiguration getConfiguration();
43
	public InternalCDOSessionConfiguration getConfiguration();
44
44
45
  public CDOSessionProtocol getSessionProtocol();
45
	public CDOSessionProtocol getSessionProtocol();
46
46
47
  /**
47
	/**
48
   * @since 3.0
48
	 * @since 3.0
49
   */
49
	 */
50
  public void setSessionProtocol(CDOSessionProtocol sessionProtocol);
50
	public void setSessionProtocol(CDOSessionProtocol sessionProtocol);
51
51
52
  public InternalCDOPackageRegistry getPackageRegistry();
52
	public InternalCDOPackageRegistry getPackageRegistry();
53
53
54
  /**
54
	/**
55
   * @since 3.0
55
	 * @since 3.0
56
   */
56
	 */
57
  public InternalCDORevisionManager getRevisionManager();
57
	public InternalCDORevisionManager getRevisionManager();
58
58
59
  public void setExceptionHandler(CDOSession.ExceptionHandler exceptionHandler);
59
	public void setExceptionHandler(CDOSession.ExceptionHandler exceptionHandler);
60
60
61
  /**
61
	/**
62
   * @since 3.0
62
	 * @since 3.0
63
   */
63
	 */
64
  public void setFetchRuleManager(CDOFetchRuleManager fetchRuleManager);
64
	public void setFetchRuleManager(CDOFetchRuleManager fetchRuleManager);
65
65
66
  /**
66
	/**
67
   * @since 3.0
67
	 * @since 3.0
68
   */
68
	 */
69
  public void setRepositoryInfo(CDORepositoryInfo repositoryInfo);
69
	public void setRepositoryInfo(CDORepositoryInfo repositoryInfo);
70
70
71
  /**
71
	/**
72
   * @since 3.0
72
	 * @since 3.0
73
   */
73
	 */
74
  public InternalCDORemoteSessionManager getRemoteSessionManager();
74
	public InternalCDORemoteSessionManager getRemoteSessionManager();
75
75
76
  /**
76
	/**
77
   * @since 3.0
77
	 * @since 3.0
78
   */
78
	 */
79
  public void setRemoteSessionManager(InternalCDORemoteSessionManager remoteSessionManager);
79
	public void setRemoteSessionManager(
80
80
			InternalCDORemoteSessionManager remoteSessionManager);
81
  /**
81
82
   * @since 3.0
82
	/**
83
   */
83
	 * @since 3.0
84
  public void setSessionID(int sessionID);
84
	 */
85
85
	public void setSessionID(int sessionID);
86
  public void setUserID(String userID);
86
87
87
	public void setUserID(String userID);
88
  /**
88
89
   * @since 3.0
89
	/**
90
   */
90
	 * @since 3.0
91
  public void setLastUpdateTime(long lastUpdateTime);
91
	 */
92
92
	public void setLastUpdateTime(long lastUpdateTime);
93
  public void viewDetached(InternalCDOView view);
93
94
94
	public void viewDetached(InternalCDOView view);
95
  /**
95
96
   * @since 3.0
96
	/**
97
   */
97
	 * @since 3.0
98
  public Object resolveElementProxy(CDORevision revision, EStructuralFeature feature, int accessIndex, int serverIndex);
98
	 */
99
99
	public Object resolveElementProxy(CDORevision revision,
100
  /**
100
			EStructuralFeature feature, int accessIndex, int serverIndex);
101
   * @since 3.0
101
102
   */
102
	/**
103
  public Object getCommitLock();
103
	 * @since 3.0
104
104
	 */
105
  public void handleCommitNotification(long timeStamp, Collection<CDOPackageUnit> newPackageUnits,
105
	public Object getCommitLock();
106
      Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects, Collection<CDORevisionDelta> deltas,
106
107
      InternalCDOView excludedView);
107
	public void handleCommitNotification(long timeStamp,
108
108
			Collection<CDOPackageUnit> newPackageUnits,
109
  public void handleSyncResponse(long timestamp, Collection<CDOPackageUnit> newPackageUnits,
109
			Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects,
110
      Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects);
110
			Collection<CDORevisionDelta> deltas, InternalCDOView excludedView);
111
111
112
  /**
112
	public void handleSyncResponse(long timestamp,
113
   * In some cases we need to sync without propagating event. Lock is a good example.
113
			Collection<CDOPackageUnit> newPackageUnits,
114
   * 
114
			Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects);
115
   * @since 3.0
115
116
   */
116
	/**
117
  public void reviseRevisions(final long timeStamp, Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects,
117
	 * In some cases we need to sync without propagating event. Lock is a good
118
      InternalCDOView excludedView);
118
	 * example.
119
	 * 
120
	 * @since 3.0
121
	 */
122
	public void reviseRevisions(final long timeStamp,
123
			Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects,
124
			InternalCDOView excludedView);
125
126
	/**
127
	 * @author Juan Pedro Silva
128
	 */
129
	public void registerLockListeners(InternalCDOView cdoView);
130
131
	/**
132
	 * @author Juan Pedro Silva
133
	 */
134
	public void unregisterLockListeners(InternalCDOView cdoView);
119
}
135
}
(-)src/org/eclipse/emf/cdo/view/CDOView.java (-413 / +485 lines)
Lines 27-32 Link Here
27
27
28
import org.eclipse.net4j.util.collection.CloseableIterator;
28
import org.eclipse.net4j.util.collection.CloseableIterator;
29
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
29
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
30
import org.eclipse.net4j.util.event.IListener;
30
import org.eclipse.net4j.util.event.INotifier;
31
import org.eclipse.net4j.util.event.INotifier;
31
import org.eclipse.net4j.util.options.IOptions;
32
import org.eclipse.net4j.util.options.IOptions;
32
import org.eclipse.net4j.util.options.IOptionsContainer;
33
import org.eclipse.net4j.util.options.IOptionsContainer;
Lines 43-53 Link Here
43
import java.util.concurrent.locks.ReentrantLock;
44
import java.util.concurrent.locks.ReentrantLock;
44
45
45
/**
46
/**
46
 * A read-only view to the <em>current</em> (i.e. latest) state of the object graph in the repository of the underlying
47
 * A read-only view to the <em>current</em> (i.e. latest) state of the object
47
 * {@link CDOSession session}.
48
 * graph in the repository of the underlying {@link CDOSession session}.
48
 * <p>
49
 * <p>
49
 * Objects that are accessed through this view are unchangeable for the client. Each attempt to call a mutator on one of
50
 * Objects that are accessed through this view are unchangeable for the client.
50
 * these objects or one of their reference collections will result in a {@link ReadOnlyException} being thrown
51
 * Each attempt to call a mutator on one of these objects or one of their
52
 * reference collections will result in a {@link ReadOnlyException} being thrown
51
 * immediately.
53
 * immediately.
52
 * <p>
54
 * <p>
53
 * A view is opened through API of the underlying session like this:
55
 * A view is opened through API of the underlying session like this:
Lines 58-476 Link Here
58
 *   ...
60
 *   ...
59
 * </pre>
61
 * </pre>
60
 * 
62
 * 
61
 * CDOView instances <b>must not</b> be accessed through concurrent client threads.
63
 * CDOView instances <b>must not</b> be accessed through concurrent client
64
 * threads.
62
 * <p>
65
 * <p>
63
 * Since a CDOObject, in a {@link CDOState#TRANSIENT non-TRANSIENT} state, is only meaningful in combination with its
66
 * Since a CDOObject, in a {@link CDOState#TRANSIENT non-TRANSIENT} state, is
64
 * dedicated view they must also not be accessed through concurrent client threads. Please note that at arbitrary times
67
 * only meaningful in combination with its dedicated view they must also not be
65
 * an arbitrary number of framework background threads are allowed to use and modify a CDOview and its CDOObjects.
68
 * accessed through concurrent client threads. Please note that at arbitrary
66
 * Whenever you are iterating over a number of CDOObjects and need to ensure that they are not modified by the framework
69
 * times an arbitrary number of framework background threads are allowed to use
67
 * at the same time it is strongly recommended to acquire the {@link #getLock() view lock} and protect your code
70
 * and modify a CDOview and its CDOObjects. Whenever you are iterating over a
68
 * appropriately.
71
 * number of CDOObjects and need to ensure that they are not modified by the
72
 * framework at the same time it is strongly recommended to acquire the
73
 * {@link #getLock() view lock} and protect your code appropriately.
69
 * 
74
 * 
70
 * @author Eike Stepper
75
 * @author Eike Stepper
71
 * @noimplement This interface is not intended to be implemented by clients.
76
 * @noimplement This interface is not intended to be implemented by clients.
72
 * @since 2.0
77
 * @since 2.0
73
 */
78
 */
74
public interface CDOView extends CDOCommonView, INotifier, IOptionsContainer
79
public interface CDOView extends CDOCommonView, INotifier, IOptionsContainer {
75
{
80
	/**
76
  /**
81
	 * Returns the {@link CDOSession session} this view was opened by.
77
   * Returns the {@link CDOSession session} this view was opened by.
82
	 * 
78
   * 
83
	 * @return The session this view was opened by, or <code>null</code> if this
79
   * @return The session this view was opened by, or <code>null</code> if this view is closed.
84
	 *         view is closed.
80
   * @see #close()
85
	 * @see #close()
81
   * @see #isClosed()
86
	 * @see #isClosed()
82
   * @see CDOSession#openView()
87
	 * @see CDOSession#openView()
83
   * @see CDOSession#openView(ResourceSet)
88
	 * @see CDOSession#openView(ResourceSet)
84
   * @see CDOSession#openAudit(long)
89
	 * @see CDOSession#openAudit(long)
85
   * @see CDOSession#openAudit(ResourceSet, long)
90
	 * @see CDOSession#openAudit(ResourceSet, long)
86
   * @see CDOSession#openTransaction()
91
	 * @see CDOSession#openTransaction()
87
   * @see CDOSession#openTransaction(ResourceSet)
92
	 * @see CDOSession#openTransaction(ResourceSet)
88
   */
93
	 */
89
  public CDOSession getSession();
94
	public CDOSession getSession();
90
95
91
  /**
96
	/**
92
   * Returns the {@link CDOViewSet view set} this view is associated with.
97
	 * Returns the {@link CDOViewSet view set} this view is associated with.
93
   * 
98
	 * 
94
   * @return The view set this view is associated with, never <code>null</code>.
99
	 * @return The view set this view is associated with, never
95
   * @see CDOViewSet#getViews()
100
	 *         <code>null</code>.
96
   */
101
	 * @see CDOViewSet#getViews()
97
  public CDOViewSet getViewSet();
102
	 */
98
103
	public CDOViewSet getViewSet();
99
  /**
104
100
   * Returns the {@link ResourceSet resource set} this view is associated with.
105
	/**
101
   * <p>
106
	 * Returns the {@link ResourceSet resource set} this view is associated
102
   * Same as calling <tt>getViewSet().getResourceSet()</tt>.
107
	 * with.
103
   * 
108
	 * <p>
104
   * @see CDOViewSet#getResourceSet()
109
	 * Same as calling <tt>getViewSet().getResourceSet()</tt>.
105
   */
110
	 * 
106
  public ResourceSet getResourceSet();
111
	 * @see CDOViewSet#getResourceSet()
107
112
	 */
108
  /**
113
	public ResourceSet getResourceSet();
109
   * @deprecated This API is provisional and subject to change or removal.
114
110
   */
115
	/**
111
  @Deprecated
116
	 * @deprecated This API is provisional and subject to change or removal.
112
  public URIHandler getURIHandler();
117
	 */
113
118
	@Deprecated
114
  /**
119
	public URIHandler getURIHandler();
115
   * Returns a reentrant lock that can be used to prevent the framework from writing to any object in this view (as it
120
116
   * is caused, for example, by passive updates).
121
	/**
117
   * <p>
122
	 * Returns a reentrant lock that can be used to prevent the framework from
118
   * Acquiring this lock provides a means to safely iterate over multiple model elements without being affected by
123
	 * writing to any object in this view (as it is caused, for example, by
119
   * unanticipated remote updates, like in the following example:
124
	 * passive updates).
120
   * 
125
	 * <p>
121
   * <pre>
126
	 * Acquiring this lock provides a means to safely iterate over multiple
122
   *    CDOResource resource = view.getResource(&quot;/orders/order-4711&quot;);
127
	 * model elements without being affected by unanticipated remote updates,
123
   *    PurchaseOrder order = (PurchaseOrder)resource.getContents().get(0);
128
	 * like in the following example:
124
   *    ReentrantLock lock = view.getLock();
129
	 * 
125
   *    if (!lock.tryLock(5L, TimeUnit.SECONDS))
130
	 * <pre>
126
   *    {
131
	 *    CDOResource resource = view.getResource(&quot;/orders/order-4711&quot;);
127
   *      throw new TimeoutException();
132
	 *    PurchaseOrder order = (PurchaseOrder)resource.getContents().get(0);
128
   *    }
133
	 *    ReentrantLock lock = view.getLock();
129
   *    try
134
	 *    if (!lock.tryLock(5L, TimeUnit.SECONDS))
130
   *    {
135
	 *    {
131
   *      float sum = 0;
136
	 *      throw new TimeoutException();
132
   *      for (OrderDetail detail : order.getOrderDetails())
137
	 *    }
133
   *      {
138
	 *    try
134
   *        sum += detail.getPrice();
139
	 *    {
135
   *      }
140
	 *      float sum = 0;
136
   *      System.out.println(&quot;Sum: &quot; + sum);
141
	 *      for (OrderDetail detail : order.getOrderDetails())
137
   *    }
142
	 *      {
138
   *    finally
143
	 *        sum += detail.getPrice();
139
   *    {
144
	 *      }
140
   *      lock.unlock();
145
	 *      System.out.println(&quot;Sum: &quot; + sum);
141
   *    }
146
	 *    }
142
   *  }
147
	 *    finally
143
   * </pre>
148
	 *    {
144
   * 
149
	 *      lock.unlock();
145
   * Note that this method really just returns the lock instance but does <b>not</b> acquire the lock! The above example
150
	 *    }
146
   * acquires the lock with a timeout that expires after five seconds.
151
	 *  }
147
   */
152
	 * </pre>
148
  public ReentrantLock getLock();
153
	 * 
149
154
	 * Note that this method really just returns the lock instance but does
150
  /**
155
	 * <b>not</b> acquire the lock! The above example acquires the lock with a
151
   * Returns always <code>false</code>.
156
	 * timeout that expires after five seconds.
152
   * <p>
157
	 */
153
   * This method has a special implementation in {@link CDOTransaction} as well.
158
	public ReentrantLock getLock();
154
   * 
159
155
   * @see CDOTransaction#isDirty()
160
	/**
156
   */
161
	 * Returns always <code>false</code>.
157
  public boolean isDirty();
162
	 * <p>
158
163
	 * This method has a special implementation in {@link CDOTransaction} as
159
  /**
164
	 * well.
160
   * Returns always <code>false</code>.
165
	 * 
161
   * <p>
166
	 * @see CDOTransaction#isDirty()
162
   * This method has a special implementation in {@link CDOTransaction} as well.
167
	 */
163
   * 
168
	public boolean isDirty();
164
   * @see CDOTransaction#hasConflict()
169
165
   */
170
	/**
166
  public boolean hasConflict();
171
	 * Returns always <code>false</code>.
167
172
	 * <p>
168
  /**
173
	 * This method has a special implementation in {@link CDOTransaction} as
169
   * Returns <code>true</code> if a resource with the given path exists in the repository, <code>false</code>.
174
	 * well.
170
   * 
175
	 * 
171
   * @see #getResource(String, boolean)
176
	 * @see CDOTransaction#hasConflict()
172
   */
177
	 */
173
  public boolean hasResource(String path);
178
	public boolean hasConflict();
174
179
175
  /**
180
	/**
176
   * @see ResourceSet#getResource(URI, boolean)
181
	 * Returns <code>true</code> if a resource with the given path exists in the
177
   */
182
	 * repository, <code>false</code>.
178
  public CDOResource getResource(String path, boolean loadOnDemand);
183
	 * 
179
184
	 * @see #getResource(String, boolean)
180
  /**
185
	 */
181
   * Same as {@link #getResource(String, boolean) getResource(String, true)}.
186
	public boolean hasResource(String path);
182
   * 
187
183
   * @see ResourceSet#getResource(URI, boolean)
188
	/**
184
   */
189
	 * @see ResourceSet#getResource(URI, boolean)
185
  public CDOResource getResource(String path);
190
	 */
186
191
	public CDOResource getResource(String path, boolean loadOnDemand);
187
  /**
192
188
   * Returns the resource node with the given path, or <code>null</code> if no such resource node exists.
193
	/**
189
   */
194
	 * Same as {@link #getResource(String, boolean) getResource(String, true)}.
190
  public CDOResourceNode getResourceNode(String path);
195
	 * 
191
196
	 * @see ResourceSet#getResource(URI, boolean)
192
  /**
197
	 */
193
   * Returns the root resource of the repository.
198
	public CDOResource getResource(String path);
194
   * <p>
199
195
   * The root resource is a special resource with only {@link CDOResourceNode CDOResourceNodes} in its contents list.
200
	/**
196
   * You can use it as the main entry into the new resource and folder structure.
201
	 * Returns the resource node with the given path, or <code>null</code> if no
197
   */
202
	 * such resource node exists.
198
  public CDOResource getRootResource();
203
	 */
199
204
	public CDOResourceNode getResourceNode(String path);
200
  /**
205
201
   * Returns a list of the resources in the given folder with a name equal to or starting with the value of the name
206
	/**
202
   * parameter.
207
	 * Returns the root resource of the repository.
203
   * 
208
	 * <p>
204
   * @param folder
209
	 * The root resource is a special resource with only {@link CDOResourceNode
205
   *          The folder to search in, or <code>null</code> for top level resource nodes.
210
	 * CDOResourceNodes} in its contents list. You can use it as the main entry
206
   * @param name
211
	 * into the new resource and folder structure.
207
   *          the name or prefix of the resource nodes to return.
212
	 */
208
   * @param exactMatch
213
	public CDOResource getRootResource();
209
   *          <code>true</code> if the complete name of the resource must match, <code>false</code> if only a common
214
210
   *          prefix of the name must match.
215
	/**
211
   */
216
	 * Returns a list of the resources in the given folder with a name equal to
212
  public List<CDOResourceNode> queryResources(CDOResourceFolder folder, String name, boolean exactMatch);
217
	 * or starting with the value of the name parameter.
213
218
	 * 
214
  /**
219
	 * @param folder
215
   * Returns an iterator over the resources in the given folder with a name equal to or starting with the value of the
220
	 *            The folder to search in, or <code>null</code> for top level
216
   * name parameter. The underlying query will be executed asynchronously.
221
	 *            resource nodes.
217
   * 
222
	 * @param name
218
   * @param folder
223
	 *            the name or prefix of the resource nodes to return.
219
   *          The folder to search in, or <code>null</code> for top level resource nodes.
224
	 * @param exactMatch
220
   * @param name
225
	 *            <code>true</code> if the complete name of the resource must
221
   *          the name or prefix of the resource nodes to return.
226
	 *            match, <code>false</code> if only a common prefix of the name
222
   * @param exactMatch
227
	 *            must match.
223
   *          <code>true</code> if the complete name of the resource must match, <code>false</code> if only a common
228
	 */
224
   *          prefix of the name must match.
229
	public List<CDOResourceNode> queryResources(CDOResourceFolder folder,
225
   */
230
			String name, boolean exactMatch);
226
  public CloseableIterator<CDOResourceNode> queryResourcesAsync(CDOResourceFolder folder, String name,
231
227
      boolean exactMatch);
232
	/**
228
233
	 * Returns an iterator over the resources in the given folder with a name
229
  /**
234
	 * equal to or starting with the value of the name parameter. The underlying
230
   * Returns the object for the given CDOID.
235
	 * query will be executed asynchronously.
231
   * 
236
	 * 
232
   * @param loadOnDemand
237
	 * @param folder
233
   *          whether to create and load the object, if it doesn't already exist.
238
	 *            The folder to search in, or <code>null</code> for top level
234
   * @return the object resolved by the CDOID if the id is not <code>null</code>, or <code>null</code> if there isn't
239
	 *            resource nodes.
235
   *         one and loadOnDemand is <code>false</code>.
240
	 * @param name
236
   */
241
	 *            the name or prefix of the resource nodes to return.
237
  public CDOObject getObject(CDOID id, boolean loadOnDemand);
242
	 * @param exactMatch
238
243
	 *            <code>true</code> if the complete name of the resource must
239
  /**
244
	 *            match, <code>false</code> if only a common prefix of the name
240
   * Returns the object for the given CDOID.
245
	 *            must match.
241
   * <p>
246
	 */
242
   * Same as <code>getObject(id, true)</code>.
247
	public CloseableIterator<CDOResourceNode> queryResourcesAsync(
243
   * 
248
			CDOResourceFolder folder, String name, boolean exactMatch);
244
   * @see getObject(CDOID, boolean)
249
245
   */
250
	/**
246
  public CDOObject getObject(CDOID id);
251
	 * Returns the object for the given CDOID.
247
252
	 * 
248
  /**
253
	 * @param loadOnDemand
249
   * Takes an object from a (possibly) different view and <em>contextifies</em> it for the usage with this view.
254
	 *            whether to create and load the object, if it doesn't already
250
   * <ul>
255
	 *            exist.
251
   * <li>If the given object is contained in this view it is returned unmodified.
256
	 * @return the object resolved by the CDOID if the id is not
252
   * <li>If the given object can not be cast to {@link CDOObject} it is returned unmodified.
257
	 *         <code>null</code>, or <code>null</code> if there isn't one and
253
   * <li>If the view of the given object is contained in a different session an <code>IllegalArgumentException</code> is
258
	 *         loadOnDemand is <code>false</code>.
254
   * thrown.
259
	 */
255
   * <li>If <code>null</code> is passed <code>null</code> is returned.
260
	public CDOObject getObject(CDOID id, boolean loadOnDemand);
256
   * </ul>
261
257
   */
262
	/**
258
  public <T extends EObject> T getObject(T objectFromDifferentView);
263
	 * Returns the object for the given CDOID.
259
264
	 * <p>
260
  /**
265
	 * Same as <code>getObject(id, true)</code>.
261
   * Returns <code>true</code> if an {@link CDOObject object} with the given {@link CDOID id} is currently registered in
266
	 * 
262
   * this view, <code>false</code> otherwise.
267
	 * @see getObject(CDOID, boolean)
263
   */
268
	 */
264
  public boolean isObjectRegistered(CDOID id);
269
	public CDOObject getObject(CDOID id);
265
270
266
  /**
271
	/**
267
   * Reloads the given {@link CDOObject objects} from the repository.
272
	 * Takes an object from a (possibly) different view and
268
   */
273
	 * <em>contextifies</em> it for the usage with this view.
269
  public int reload(CDOObject... objects);
274
	 * <ul>
270
275
	 * <li>If the given object is contained in this view it is returned
271
  /**
276
	 * unmodified.
272
   * Locks the given objects. Once the objects are locked, they will not be changed remotely or go in conflict state.
277
	 * <li>If the given object can not be cast to {@link CDOObject} it is
273
   * 
278
	 * returned unmodified.
274
   * @since 3.0
279
	 * <li>If the view of the given object is contained in a different session
275
   */
280
	 * an <code>IllegalArgumentException</code> is thrown.
276
  public void lockObjects(Collection<? extends CDOObject> objects, LockType lockType, long timeout)
281
	 * <li>If <code>null</code> is passed <code>null</code> is returned.
277
      throws InterruptedException;
282
	 * </ul>
278
283
	 */
279
  /**
284
	public <T extends EObject> T getObject(T objectFromDifferentView);
280
   * Unlocks the given locked objects of this view.
285
281
   */
286
	/**
282
  public void unlockObjects(Collection<? extends CDOObject> objects, LockType lockType);
287
	 * Returns <code>true</code> if an {@link CDOObject object} with the given
283
288
	 * {@link CDOID id} is currently registered in this view, <code>false</code>
284
  /**
289
	 * otherwise.
285
   * Unlocks all locked objects of this view.
290
	 */
286
   * 
291
	public boolean isObjectRegistered(CDOID id);
287
   * @since 2.0
292
288
   */
293
	/**
289
  public void unlockObjects();
294
	 * Reloads the given {@link CDOObject objects} from the repository.
290
295
	 */
291
  /**
296
	public int reload(CDOObject... objects);
292
   * @since 3.0
297
293
   */
298
	/**
294
  public void addObjectHandler(CDOObjectHandler handler);
299
	 * Locks the given objects. Once the objects are locked, they will not be
295
300
	 * changed remotely or go in conflict state.
296
  /**
301
	 * 
297
   * @since 3.0
302
	 * @since 3.0
298
   */
303
	 */
299
  public void removeObjectHandler(CDOObjectHandler handler);
304
	public void lockObjects(Collection<? extends CDOObject> objects,
300
305
			LockType lockType, long timeout) throws InterruptedException;
301
  /**
306
302
   * @since 3.0
307
	/**
303
   */
308
	 * Unlocks the given locked objects of this view.
304
  public CDOObjectHandler[] getObjectHandlers();
309
	 */
305
310
	public void unlockObjects(Collection<? extends CDOObject> objects,
306
  /**
311
			LockType lockType);
307
   * @since 2.0
312
308
   */
313
	/**
309
  public CDOQuery createQuery(String language, String queryString);
314
	 * Unlocks all locked objects of this view.
310
315
	 * 
311
  /**
316
	 * @since 2.0
312
   * @since 2.0
317
	 */
313
   */
318
	public void unlockObjects();
314
  public Options options();
319
315
320
	/**
316
  /**
321
	 * @since 3.0
317
   * @author Simon McDuff
322
	 */
318
   */
323
	public void addObjectHandler(CDOObjectHandler handler);
319
  public interface Options extends IOptions
324
320
  {
325
	/**
321
    /**
326
	 * @since 3.0
322
     */
327
	 */
323
    public static final int NO_REVISION_PREFETCHING = 1;
328
	public void removeObjectHandler(CDOObjectHandler handler);
324
329
325
    /**
330
	/**
326
     * Returns the reference type to be used in the internal object cache.
331
	 * @since 3.0
327
     * 
332
	 */
328
     * @return Either {@link ReferenceType#STRONG STRONG}, {@link ReferenceType#SOFT SOFT} or {@link ReferenceType#WEAK
333
	public CDOObjectHandler[] getObjectHandlers();
329
     *         WEAK}.
334
330
     */
335
	/**
331
    public ReferenceType getCacheReferenceType();
336
	 * @since 2.0
332
337
	 */
333
    /**
338
	public CDOQuery createQuery(String language, String queryString);
334
     * Sets the reference type to be used in the internal object cache to either {@link ReferenceType#STRONG STRONG},
339
335
     * {@link ReferenceType#SOFT SOFT} or {@link ReferenceType#WEAK WEAK}. If <code>null</code> is passed the default
340
	/**
336
     * reference type {@link ReferenceType#SOFT SOFT} is set. If the given reference type does not differ from the one
341
	 * @since 2.0
337
     * being currently set the new value is ignored and <code>false</code> is returned. Otherwise existing object
342
	 */
338
     * references are converted to the new type and <code>true</code> is returned.
343
	public Options options();
339
     */
344
340
    public boolean setCacheReferenceType(ReferenceType referenceType);
345
	/**
341
346
	 * @author Juan Pedro Silva
342
    /**
347
	 */
343
     * Returns <code>true</code> if the {@link CDOObject objects} in this view will notify their
348
	public void registerLockListeners(Collection<IListener> collToRegister);
344
     * {@link org.eclipse.emf.common.notify.Adapter adapters} about the fact that they are <em>invalidated</em> (due to
349
345
     * remote changes), <code>false</code> otherwise.
350
	/**
346
     * 
351
	 * @author Juan Pedro Silva
347
     * @see CDOInvalidationNotification
352
	 */
348
     */
353
	public void registerLockListener(IListener listenerToRegister);
349
    public boolean isInvalidationNotificationEnabled();
354
350
355
	/**
351
    /**
356
	 * @author Juan Pedro Silva
352
     * Specifies whether the {@link CDOObject objects} in this view will notify their
357
	 */
353
     * {@link org.eclipse.emf.common.notify.Adapter adapters} about the fact that they are <em>invalidated</em> (due to
358
	public void unRegisterLockListener(IListener listenerToRegister);
354
     * remote changes) or not.
359
355
     * 
360
	/**
356
     * @see CDOInvalidationNotification
361
	 * @author Juan Pedro Silva
357
     */
362
	 */
358
    public void setInvalidationNotificationEnabled(boolean enabled);
363
	public void unRegisterLockListeners(Collection<IListener> collToUnregister);
359
364
360
    /**
365
	/**
361
     * Returns the current set of {@link CDOAdapterPolicy change subscription policies}.
366
	 * @author Juan Pedro Silva
362
     * 
367
	 */
363
     * @return The current set of change subscription policies, never <code>null</code>.
368
	public void notifyRemoteLock(boolean b, String user,
364
     * @see #setChangeSubscriptionPolicy(CDOAdapterPolicy)
369
			Collection<CDOID> cdoids, LockType lockType);
365
     */
370
366
    public CDOAdapterPolicy[] getChangeSubscriptionPolicies();
371
	/**
367
372
	 * @author Simon McDuff
368
    /**
373
	 */
369
     * Adds a change subscription policy to this view.
374
	public interface Options extends IOptions {
370
     * <p>
375
		/**
371
     * To activate a policy, you must do the following: <br>
376
     */
372
     * <code>view.options().addChangeSubscriptionPolicy(CDOChangeSubscriptionPolicy.ALL);</code>
377
		public static final int NO_REVISION_PREFETCHING = 1;
373
     * <p>
378
374
     * To register an object, you must add an adapter to the object in which you are interested:<br>
379
		/**
375
     * <code>eObject.eAdapters().add(myAdapter);</code>
380
		 * Returns the reference type to be used in the internal object cache.
376
     * <p>
381
		 * 
377
     * By activating this feature, each object having at least one adapter that matches the current policy will be
382
		 * @return Either {@link ReferenceType#STRONG STRONG},
378
     * registered with the server and will be notified for each change occurring in the scope of any other transaction.
383
		 *         {@link ReferenceType#SOFT SOFT} or {@link ReferenceType#WEAK
379
     * <p>
384
		 *         WEAK}.
380
     * {@link CDOAdapterPolicy#NONE} - Ignored. <br>
385
		 */
381
     * {@link CDOAdapterPolicy#ALL} - Enabled for all adapters used.<br>
386
		public ReferenceType getCacheReferenceType();
382
     * {@link CDOAdapterPolicy#CDO} - Enabled only for adapters that implement {@link CDOAdapter}. <br>
387
383
     * Any other class that implement {@link CDOAdapterPolicy} will enable for whatever rules defined in that class.
388
		/**
384
     * <br>
389
		 * Sets the reference type to be used in the internal object cache to
385
     * <p>
390
		 * either {@link ReferenceType#STRONG STRONG},
386
     * If <code>myAdapter</code> in the above example matches the current policy, <code>eObject</code> will be
391
		 * {@link ReferenceType#SOFT SOFT} or {@link ReferenceType#WEAK WEAK}.
387
     * registered with the server and you will receive all changes from other transaction.
392
		 * If <code>null</code> is passed the default reference type
388
     * <p>
393
		 * {@link ReferenceType#SOFT SOFT} is set. If the given reference type
389
     * When the policy is changed all objects in the cache will automatically be recalculated.
394
		 * does not differ from the one being currently set the new value is
390
     * <p>
395
		 * ignored and <code>false</code> is returned. Otherwise existing object
391
     * You can subscribe to temporary objects. Even if you cannot receive notifications from other
396
		 * references are converted to the new type and <code>true</code> is
392
     * {@link CDOTransaction} for these because they are only local to you, at commit time these objects will be
397
		 * returned.
393
     * registered automatically.
398
		 */
394
     * <p>
399
		public boolean setCacheReferenceType(ReferenceType referenceType);
395
     * <b>Note:</b> It can be used with <code>CDOSession.options().setPassiveUpdate(false)</code>. In this case, it will
400
396
     * receive changes without having the objects changed.
401
		/**
397
     */
402
		 * Returns <code>true</code> if the {@link CDOObject objects} in this
398
    public void addChangeSubscriptionPolicy(CDOAdapterPolicy policy);
403
		 * view will notify their {@link org.eclipse.emf.common.notify.Adapter
399
404
		 * adapters} about the fact that they are <em>invalidated</em> (due to
400
    /**
405
		 * remote changes), <code>false</code> otherwise.
401
     * Removes a change subscription policy from this view.
406
		 * 
402
     */
407
		 * @see CDOInvalidationNotification
403
    public void removeChangeSubscriptionPolicy(CDOAdapterPolicy policy);
408
		 */
404
409
		public boolean isInvalidationNotificationEnabled();
405
    // TODO
410
406
    public CDOAdapterPolicy getStrongReferencePolicy();
411
		/**
407
412
		 * Specifies whether the {@link CDOObject objects} in this view will
408
    /**
413
		 * notify their {@link org.eclipse.emf.common.notify.Adapter adapters}
409
     * Sets the reference type to be used when an adapter is used to an object.
414
		 * about the fact that they are <em>invalidated</em> (due to remote
410
     * <p>
415
		 * changes) or not.
411
     * When <code>CDOView.setStrongReference(CDOAdapterPolicy.ALL)</code> is used, it is possible that the target object
416
		 * 
412
     * will be GC. In that case, the adapter will never received notifications. By Default the value is at
417
		 * @see CDOInvalidationNotification
413
     * <code>CDOAdapterPolicy.ALL</code>
418
		 */
414
     */
419
		public void setInvalidationNotificationEnabled(boolean enabled);
415
    public void setStrongReferencePolicy(CDOAdapterPolicy policy);
420
416
421
		/**
417
    /**
422
		 * Returns the current set of {@link CDOAdapterPolicy change
418
     * Returns the CDOStaleReferencePolicy in use.
423
		 * subscription policies}.
419
     * 
424
		 * 
420
     * @since 3.0
425
		 * @return The current set of change subscription policies, never
421
     */
426
		 *         <code>null</code>.
422
    public CDOStaleReferencePolicy getStaleReferenceBehaviour();
427
		 * @see #setChangeSubscriptionPolicy(CDOAdapterPolicy)
423
428
		 */
424
    /**
429
		public CDOAdapterPolicy[] getChangeSubscriptionPolicies();
425
     * Sets a policy on how to deal with stale references.
430
426
     * 
431
		/**
427
     * @since 3.0
432
		 * Adds a change subscription policy to this view.
428
     */
433
		 * <p>
429
    public void setStaleReferenceBehaviour(CDOStaleReferencePolicy policy);
434
		 * To activate a policy, you must do the following: <br>
430
435
		 * <code>view.options().addChangeSubscriptionPolicy(CDOChangeSubscriptionPolicy.ALL);</code>
431
    /**
436
		 * <p>
432
     * Returns the CDORevisionPrefetchingPolicy in use.
437
		 * To register an object, you must add an adapter to the object in which
433
     */
438
		 * you are interested:<br>
434
    public CDORevisionPrefetchingPolicy getRevisionPrefetchingPolicy();
439
		 * <code>eObject.eAdapters().add(myAdapter);</code>
435
440
		 * <p>
436
    /**
441
		 * By activating this feature, each object having at least one adapter
437
     * The CDORevisionPrefetchingPolicy feature of the CDOView allows CDO users to fetch many objects at a time.
442
		 * that matches the current policy will be registered with the server
438
     * <p>
443
		 * and will be notified for each change occurring in the scope of any
439
     * The difference between the CDOCollectionLoadingPolicy feature and the CDORevisionPrefetchingPolicy feature is
444
		 * other transaction.
440
     * subtle. The CDOCollectionLoadingPolicy feature determines how and when to fetch CDOIDs, while the
445
		 * <p>
441
     * CDORevisionPrefetchingPolicy feature determines how and when to resolve CDOIDs (i.e. fetch the target objects).
446
		 * {@link CDOAdapterPolicy#NONE} - Ignored. <br>
442
     * <p>
447
		 * {@link CDOAdapterPolicy#ALL} - Enabled for all adapters used.<br>
443
     * <code>view.options().setRevisionPrefetchingPolicy (CDONet4jUtil.createRevisionPrefetchingPolicy(10));</code>
448
		 * {@link CDOAdapterPolicy#CDO} - Enabled only for adapters that
444
     * <p>
449
		 * implement {@link CDOAdapter}. <br>
445
     * The end-user could provide its own implementation of the CDORevisionPrefetchingPolicy interface.
450
		 * Any other class that implement {@link CDOAdapterPolicy} will enable
446
     */
451
		 * for whatever rules defined in that class. <br>
447
    public void setRevisionPrefetchingPolicy(CDORevisionPrefetchingPolicy prefetchingPolicy);
452
		 * <p>
448
453
		 * If <code>myAdapter</code> in the above example matches the current
449
    public interface CacheReferenceTypeEvent extends IOptionsEvent
454
		 * policy, <code>eObject</code> will be registered with the server and
450
    {
455
		 * you will receive all changes from other transaction.
451
    }
456
		 * <p>
452
457
		 * When the policy is changed all objects in the cache will
453
    public interface ReferencePolicyEvent extends IOptionsEvent
458
		 * automatically be recalculated.
454
    {
459
		 * <p>
455
    }
460
		 * You can subscribe to temporary objects. Even if you cannot receive
456
461
		 * notifications from other {@link CDOTransaction} for these because
457
    /**
462
		 * they are only local to you, at commit time these objects will be
458
     * @since 3.0
463
		 * registered automatically.
459
     */
464
		 * <p>
460
    public interface StaleReferencePolicyEvent extends IOptionsEvent
465
		 * <b>Note:</b> It can be used with
461
    {
466
		 * <code>CDOSession.options().setPassiveUpdate(false)</code>. In this
462
    }
467
		 * case, it will receive changes without having the objects changed.
463
468
		 */
464
    public interface ChangeSubscriptionPoliciesEvent extends IOptionsEvent
469
		public void addChangeSubscriptionPolicy(CDOAdapterPolicy policy);
465
    {
470
466
    }
471
		/**
467
472
		 * Removes a change subscription policy from this view.
468
    public interface InvalidationNotificationEvent extends IOptionsEvent
473
		 */
469
    {
474
		public void removeChangeSubscriptionPolicy(CDOAdapterPolicy policy);
470
    }
475
471
476
		// TODO
472
    public interface RevisionPrefetchingPolicyEvent extends IOptionsEvent
477
		public CDOAdapterPolicy getStrongReferencePolicy();
473
    {
478
474
    }
479
		/**
475
  }
480
		 * Sets the reference type to be used when an adapter is used to an
481
		 * object.
482
		 * <p>
483
		 * When <code>CDOView.setStrongReference(CDOAdapterPolicy.ALL)</code> is
484
		 * used, it is possible that the target object will be GC. In that case,
485
		 * the adapter will never received notifications. By Default the value
486
		 * is at <code>CDOAdapterPolicy.ALL</code>
487
		 */
488
		public void setStrongReferencePolicy(CDOAdapterPolicy policy);
489
490
		/**
491
		 * Returns the CDOStaleReferencePolicy in use.
492
		 * 
493
		 * @since 3.0
494
		 */
495
		public CDOStaleReferencePolicy getStaleReferenceBehaviour();
496
497
		/**
498
		 * Sets a policy on how to deal with stale references.
499
		 * 
500
		 * @since 3.0
501
		 */
502
		public void setStaleReferenceBehaviour(CDOStaleReferencePolicy policy);
503
504
		/**
505
		 * Returns the CDORevisionPrefetchingPolicy in use.
506
		 */
507
		public CDORevisionPrefetchingPolicy getRevisionPrefetchingPolicy();
508
509
		/**
510
		 * The CDORevisionPrefetchingPolicy feature of the CDOView allows CDO
511
		 * users to fetch many objects at a time.
512
		 * <p>
513
		 * The difference between the CDOCollectionLoadingPolicy feature and the
514
		 * CDORevisionPrefetchingPolicy feature is subtle. The
515
		 * CDOCollectionLoadingPolicy feature determines how and when to fetch
516
		 * CDOIDs, while the CDORevisionPrefetchingPolicy feature determines how
517
		 * and when to resolve CDOIDs (i.e. fetch the target objects).
518
		 * <p>
519
		 * <code>view.options().setRevisionPrefetchingPolicy (CDONet4jUtil.createRevisionPrefetchingPolicy(10));</code>
520
		 * <p>
521
		 * The end-user could provide its own implementation of the
522
		 * CDORevisionPrefetchingPolicy interface.
523
		 */
524
		public void setRevisionPrefetchingPolicy(
525
				CDORevisionPrefetchingPolicy prefetchingPolicy);
526
527
		public interface CacheReferenceTypeEvent extends IOptionsEvent {
528
		}
529
530
		public interface ReferencePolicyEvent extends IOptionsEvent {
531
		}
532
533
		/**
534
		 * @since 3.0
535
		 */
536
		public interface StaleReferencePolicyEvent extends IOptionsEvent {
537
		}
538
539
		public interface ChangeSubscriptionPoliciesEvent extends IOptionsEvent {
540
		}
541
542
		public interface InvalidationNotificationEvent extends IOptionsEvent {
543
		}
544
545
		public interface RevisionPrefetchingPolicyEvent extends IOptionsEvent {
546
		}
547
	}
476
}
548
}
(-)src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java (-2295 / +2112 lines)
Lines 50-55 Link Here
50
import org.eclipse.emf.cdo.view.CDOViewAdaptersNotifiedEvent;
50
import org.eclipse.emf.cdo.view.CDOViewAdaptersNotifiedEvent;
51
import org.eclipse.emf.cdo.view.CDOViewEvent;
51
import org.eclipse.emf.cdo.view.CDOViewEvent;
52
import org.eclipse.emf.cdo.view.CDOViewInvalidationEvent;
52
import org.eclipse.emf.cdo.view.CDOViewInvalidationEvent;
53
import org.eclipse.emf.cdo.view.RemoteLockAcquiredEvent;
54
import org.eclipse.emf.cdo.view.RemoteLockReleasedEvent;
53
55
54
import org.eclipse.emf.internal.cdo.CDODeltaNotificationImpl;
56
import org.eclipse.emf.internal.cdo.CDODeltaNotificationImpl;
55
import org.eclipse.emf.internal.cdo.CDOInvalidationNotificationImpl;
57
import org.eclipse.emf.internal.cdo.CDOInvalidationNotificationImpl;
Lines 114-2412 Link Here
114
/**
116
/**
115
 * @author Eike Stepper
117
 * @author Eike Stepper
116
 */
118
 */
117
public class CDOViewImpl extends Lifecycle implements InternalCDOView
119
public class CDOViewImpl extends Lifecycle implements InternalCDOView {
118
{
120
	private static final ContextTracer TRACER = new ContextTracer(
119
  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_VIEW, CDOViewImpl.class);
121
			OM.DEBUG_VIEW, CDOViewImpl.class);
120
122
121
  private int viewID;
123
	private int viewID;
122
124
123
  private InternalCDOSession session;
125
	private InternalCDOSession session;
124
126
125
  private InternalCDOViewSet viewSet;
127
	private InternalCDOViewSet viewSet;
126
128
127
  private CDOURIHandler uriHandler = new CDOURIHandler(this);
129
	private CDOURIHandler uriHandler = new CDOURIHandler(this);
128
130
129
  private CDOFeatureAnalyzer featureAnalyzer = CDOFeatureAnalyzer.NOOP;
131
	private CDOFeatureAnalyzer featureAnalyzer = CDOFeatureAnalyzer.NOOP;
130
132
131
  private ConcurrentMap<CDOID, InternalCDOObject> objects;
133
	private ConcurrentMap<CDOID, InternalCDOObject> objects;
132
134
133
  private CDOStore store = new CDOStore(this);
135
	private CDOStore store = new CDOStore(this);
134
136
135
  private ReentrantLock lock = new ReentrantLock(true);
137
	private ReentrantLock lock = new ReentrantLock(true);
136
138
137
  private ReentrantLock stateLock = new ReentrantLock(true);
139
	private ReentrantLock stateLock = new ReentrantLock(true);
138
140
139
  private CDOResourceImpl rootResource;
141
	private CDOResourceImpl rootResource;
140
142
141
  private ChangeSubscriptionManager changeSubscriptionManager = createChangeSubscriptionManager();
143
	private ChangeSubscriptionManager changeSubscriptionManager = createChangeSubscriptionManager();
142
144
143
  private AdapterManager adapterPolicyManager = createAdapterManager();
145
	private AdapterManager adapterPolicyManager = createAdapterManager();
144
146
145
  private FastList<CDOObjectHandler> objectHandlers = new FastList<CDOObjectHandler>()
147
	private FastList<CDOObjectHandler> objectHandlers = new FastList<CDOObjectHandler>() {
146
  {
148
		@Override
147
    @Override
149
		protected CDOObjectHandler[] newArray(int length) {
148
    protected CDOObjectHandler[] newArray(int length)
150
			return new CDOObjectHandler[length];
149
    {
151
		}
150
      return new CDOObjectHandler[length];
152
	};
151
    }
153
152
  };
154
	private OptionsImpl options;
153
155
154
  private OptionsImpl options;
156
	@ExcludeFromDump
155
157
	private transient CDOID lastLookupID;
156
  @ExcludeFromDump
158
157
  private transient CDOID lastLookupID;
159
	@ExcludeFromDump
158
160
	private transient InternalCDOObject lastLookupObject;
159
  @ExcludeFromDump
161
160
  private transient InternalCDOObject lastLookupObject;
162
	/**
161
163
	 * @since 2.0
162
  /**
164
	 */
163
   * @since 2.0
165
	public CDOViewImpl() {
164
   */
166
		options = createOptions();
165
  public CDOViewImpl()
167
	}
166
  {
168
167
    options = createOptions();
169
	/**
168
  }
170
	 * @since 2.0
169
171
	 */
170
  /**
172
	public OptionsImpl options() {
171
   * @since 2.0
173
		return options;
172
   */
174
	}
173
  public OptionsImpl options()
175
174
  {
176
	public int getViewID() {
175
    return options;
177
		return viewID;
176
  }
178
	}
177
179
178
  public int getViewID()
180
	/**
179
  {
181
	 * @since 2.0
180
    return viewID;
182
	 */
181
  }
183
	public void setViewID(int viewId) {
182
184
		viewID = viewId;
183
  /**
185
	}
184
   * @since 2.0
186
185
   */
187
	public Type getViewType() {
186
  public void setViewID(int viewId)
188
		return Type.READONLY;
187
  {
189
	}
188
    viewID = viewId;
190
189
  }
191
	public ResourceSet getResourceSet() {
190
192
		return viewSet.getResourceSet();
191
  public Type getViewType()
193
	}
192
  {
194
193
    return Type.READONLY;
195
	/**
194
  }
196
	 * @since 2.0
195
197
	 */
196
  public ResourceSet getResourceSet()
198
	public InternalCDOViewSet getViewSet() {
197
  {
199
		return viewSet;
198
    return viewSet.getResourceSet();
200
	}
199
  }
201
200
202
	/**
201
  /**
203
	 * @since 2.0
202
   * @since 2.0
204
	 */
203
   */
205
	public void setViewSet(InternalCDOViewSet viewSet) {
204
  public InternalCDOViewSet getViewSet()
206
		this.viewSet = viewSet;
205
  {
207
		if (viewSet != null) {
206
    return viewSet;
208
			viewSet.getResourceSet().getURIConverter().getURIHandlers().add(0,
207
  }
209
					getURIHandler());
208
210
		}
209
  /**
211
	}
210
   * @since 2.0
212
211
   */
213
	/**
212
  public void setViewSet(InternalCDOViewSet viewSet)
214
	 * @since 2.0
213
  {
215
	 */
214
    this.viewSet = viewSet;
216
	public InternalCDOSession getSession() {
215
    if (viewSet != null)
217
		return session;
216
    {
218
	}
217
      viewSet.getResourceSet().getURIConverter().getURIHandlers().add(0, getURIHandler());
219
218
    }
220
	/**
219
  }
221
	 * @since 2.0
220
222
	 */
221
  /**
223
	public void setSession(InternalCDOSession session) {
222
   * @since 2.0
224
		this.session = session;
223
   */
225
	}
224
  public InternalCDOSession getSession()
226
225
  {
227
	public CDOStore getStore() {
226
    return session;
228
		checkActive();
227
  }
229
		return store;
228
230
	}
229
  /**
231
230
   * @since 2.0
232
	/**
231
   */
233
	 * @since 2.0
232
  public void setSession(InternalCDOSession session)
234
	 */
233
  {
235
	public synchronized CDOResourceImpl getRootResource() {
234
    this.session = session;
236
		checkActive();
235
  }
237
		if (rootResource == null) {
236
238
			rootResource = createRootResource();
237
  public CDOStore getStore()
239
		}
238
  {
240
239
    checkActive();
241
		return rootResource;
240
    return store;
242
	}
241
  }
243
242
244
	/**
243
  /**
245
	 * @return
244
   * @since 2.0
246
	 * @since 2.0
245
   */
247
	 */
246
  public synchronized CDOResourceImpl getRootResource()
248
	protected CDOResourceImpl createRootResource() {
247
  {
249
		return (CDOResourceImpl) getResource(CDOResourceNode.ROOT_PATH);
248
    checkActive();
250
	}
249
    if (rootResource == null)
251
250
    {
252
	/**
251
      rootResource = createRootResource();
253
	 * @since 2.0
252
    }
254
	 */
253
255
	public CDOURIHandler getURIHandler() {
254
    return rootResource;
256
		return uriHandler;
255
  }
257
	}
256
258
257
  /**
259
	/**
258
   * @return
260
	 * @since 2.0
259
   * @since 2.0
261
	 */
260
   */
262
	public ReentrantLock getLock() {
261
  protected CDOResourceImpl createRootResource()
263
		return lock;
262
  {
264
	}
263
    return (CDOResourceImpl)getResource(CDOResourceNode.ROOT_PATH);
265
264
  }
266
	/**
265
267
	 * @since 2.0
266
  /**
268
	 */
267
   * @since 2.0
269
	public ReentrantLock getStateLock() {
268
   */
270
		return stateLock;
269
  public CDOURIHandler getURIHandler()
271
	}
270
  {
272
271
    return uriHandler;
273
	/**
272
  }
274
	 * @throws InterruptedException
273
275
	 * @since 2.0
274
  /**
276
	 */
275
   * @since 2.0
277
	public void lockObjects(Collection<? extends CDOObject> objects,
276
   */
278
			LockType lockType, long timeout) throws InterruptedException {
277
  public ReentrantLock getLock()
279
		checkActive();
278
  {
280
		Map<CDOID, CDOIDAndVersion> uniqueObjects = new HashMap<CDOID, CDOIDAndVersion>();
279
    return lock;
281
		getCDOIDAndVersion(uniqueObjects, objects);
280
  }
282
		for (CDOObject object : objects) {
281
283
			CDOIDAndVersion idAndVersion = uniqueObjects.get(object.cdoID());
282
  /**
284
			if (idAndVersion == null) {
283
   * @since 2.0
285
				uniqueObjects.put(object.cdoID(), CDOIDUtil.createIDAndVersion(
284
   */
286
						object.cdoID(), CDORevision.UNSPECIFIED_VERSION));
285
  public ReentrantLock getStateLock()
287
			}
286
  {
288
		}
287
    return stateLock;
289
288
  }
290
		session.getSessionProtocol().lockObjects(this, uniqueObjects, timeout,
289
291
				lockType);
290
  /**
292
	}
291
   * @throws InterruptedException
293
292
   * @since 2.0
294
	/**
293
   */
295
	 * @since 2.0
294
  public void lockObjects(Collection<? extends CDOObject> objects, LockType lockType, long timeout)
296
	 */
295
      throws InterruptedException
297
	public void unlockObjects(Collection<? extends CDOObject> objects,
296
  {
298
			LockType lockType) {
297
    checkActive();
299
		checkActive();
298
    Map<CDOID, CDOIDAndVersion> uniqueObjects = new HashMap<CDOID, CDOIDAndVersion>();
300
		session.getSessionProtocol().unlockObjects(this, objects, lockType);
299
    getCDOIDAndVersion(uniqueObjects, objects);
301
	}
300
    for (CDOObject object : objects)
302
301
    {
303
	/**
302
      CDOIDAndVersion idAndVersion = uniqueObjects.get(object.cdoID());
304
	 * @since 2.0
303
      if (idAndVersion == null)
305
	 */
304
      {
306
	public void unlockObjects() {
305
        uniqueObjects
307
		unlockObjects(null, null);
306
            .put(object.cdoID(), CDOIDUtil.createIDAndVersion(object.cdoID(), CDORevision.UNSPECIFIED_VERSION));
308
	}
307
      }
309
308
    }
310
	/**
309
311
	 * @since 2.0
310
    session.getSessionProtocol().lockObjects(this, uniqueObjects, timeout, lockType);
312
	 */
311
  }
313
	public boolean isObjectLocked(CDOObject object, LockType lockType,
312
314
			boolean byOthers) {
313
  /**
315
		checkActive();
314
   * @since 2.0
316
		return session.getSessionProtocol().isObjectLocked(this, object,
315
   */
317
				lockType, byOthers);
316
  public void unlockObjects(Collection<? extends CDOObject> objects, LockType lockType)
318
	}
317
  {
319
318
    checkActive();
320
	/**
319
    session.getSessionProtocol().unlockObjects(this, objects, lockType);
321
	 * @since 2.0
320
  }
322
	 */
321
323
	public long getTimeStamp() {
322
  /**
324
		return UNSPECIFIED_DATE;
323
   * @since 2.0
325
	}
324
   */
326
325
  public void unlockObjects()
327
	public boolean isDirty() {
326
  {
328
		return false;
327
    unlockObjects(null, null);
329
	}
328
  }
330
329
331
	public boolean hasConflict() {
330
  /**
332
		return false;
331
   * @since 2.0
333
	}
332
   */
334
333
  public boolean isObjectLocked(CDOObject object, LockType lockType, boolean byOthers)
335
	/**
334
  {
336
	 * @since 2.0
335
    checkActive();
337
	 */
336
    return session.getSessionProtocol().isObjectLocked(this, object, lockType, byOthers);
338
	public CDOFeatureAnalyzer getFeatureAnalyzer() {
337
  }
339
		return featureAnalyzer;
338
340
	}
339
  /**
341
340
   * @since 2.0
342
	/**
341
   */
343
	 * @since 2.0
342
  public long getTimeStamp()
344
	 */
343
  {
345
	public void setFeatureAnalyzer(CDOFeatureAnalyzer featureAnalyzer) {
344
    return UNSPECIFIED_DATE;
346
		this.featureAnalyzer = featureAnalyzer == null ? CDOFeatureAnalyzer.NOOP
345
  }
347
				: featureAnalyzer;
346
348
	}
347
  public boolean isDirty()
349
348
  {
350
	/**
349
    return false;
351
	 * @since 2.0
350
  }
352
	 */
351
353
	public InternalCDOTransaction toTransaction() {
352
  public boolean hasConflict()
354
		checkActive();
353
  {
355
		if (this instanceof InternalCDOTransaction) {
354
    return false;
356
			return (InternalCDOTransaction) this;
355
  }
357
		}
356
358
357
  /**
359
		throw new ReadOnlyException(MessageFormat.format(Messages
358
   * @since 2.0
360
				.getString("CDOViewImpl.0"), this)); //$NON-NLS-1$
359
   */
361
	}
360
  public CDOFeatureAnalyzer getFeatureAnalyzer()
362
361
  {
363
	public boolean hasResource(String path) {
362
    return featureAnalyzer;
364
		checkActive();
363
  }
365
364
366
		try {
365
  /**
367
			getResourceNodeID(path);
366
   * @since 2.0
368
			return true;
367
   */
369
		} catch (Exception ex) {
368
  public void setFeatureAnalyzer(CDOFeatureAnalyzer featureAnalyzer)
370
			return false;
369
  {
371
		}
370
    this.featureAnalyzer = featureAnalyzer == null ? CDOFeatureAnalyzer.NOOP : featureAnalyzer;
372
	}
371
  }
373
372
374
	/**
373
  /**
375
	 * @since 2.0
374
   * @since 2.0
376
	 */
375
   */
377
	public CDOQuery createQuery(String language, String queryString) {
376
  public InternalCDOTransaction toTransaction()
378
		checkActive();
377
  {
379
		return new CDOQueryImpl(this, language, queryString);
378
    checkActive();
380
	}
379
    if (this instanceof InternalCDOTransaction)
381
380
    {
382
	/**
381
      return (InternalCDOTransaction)this;
383
	 * @since 2.0
382
    }
384
	 */
383
385
	public CDOResourceNode getResourceNode(String path) {
384
    throw new ReadOnlyException(MessageFormat.format(Messages.getString("CDOViewImpl.0"), this)); //$NON-NLS-1$
386
		CDOID id = getResourceNodeID(path);
385
  }
387
		if (id == null) {
386
388
			return null;
387
  public boolean hasResource(String path)
389
		}
388
  {
390
389
    checkActive();
391
		InternalCDOObject object = getObject(id);
390
392
		if (object instanceof CDOResourceNode) {
391
    try
393
			return (CDOResourceNode) object;
392
    {
394
		}
393
      getResourceNodeID(path);
395
394
      return true;
396
		return null;
395
    }
397
	}
396
    catch (Exception ex)
398
397
    {
399
	/**
398
      return false;
400
	 * @return never <code>null</code>
399
    }
401
	 * @since 2.0
400
  }
402
	 */
401
403
	public CDOID getResourceNodeID(String path) {
402
  /**
404
		if (StringUtil.isEmpty(path)) {
403
   * @since 2.0
405
			throw new IllegalArgumentException(Messages
404
   */
406
					.getString("CDOViewImpl.1")); //$NON-NLS-1$
405
  public CDOQuery createQuery(String language, String queryString)
407
		}
406
  {
408
407
    checkActive();
409
		CDOID folderID = null;
408
    return new CDOQueryImpl(this, language, queryString);
410
		if (CDOURIUtil.SEGMENT_SEPARATOR.equals(path)) {
409
  }
411
			folderID = getResourceNodeIDChecked(null, null);
410
412
		} else {
411
  /**
413
			List<String> names = CDOURIUtil.analyzePath(path);
412
   * @since 2.0
414
			for (String name : names) {
413
   */
415
				folderID = getResourceNodeIDChecked(folderID, name);
414
  public CDOResourceNode getResourceNode(String path)
416
			}
415
  {
417
		}
416
    CDOID id = getResourceNodeID(path);
418
417
    if (id == null)
419
		return folderID;
418
    {
420
	}
419
      return null;
421
420
    }
422
	/**
421
423
	 * @return never <code>null</code>
422
    InternalCDOObject object = getObject(id);
424
	 */
423
    if (object instanceof CDOResourceNode)
425
	private CDOID getResourceNodeIDChecked(CDOID folderID, String name) {
424
    {
426
		folderID = getResourceNodeID(folderID, name);
425
      return (CDOResourceNode)object;
427
		if (folderID == null) {
426
    }
428
			throw new CDOException(MessageFormat.format(Messages
427
429
					.getString("CDOViewImpl.2"), name)); //$NON-NLS-1$
428
    return null;
430
		}
429
  }
431
430
432
		return folderID;
431
  /**
433
	}
432
   * @return never <code>null</code>
434
433
   * @since 2.0
435
	/**
434
   */
436
	 * @return never <code>null</code>
435
  public CDOID getResourceNodeID(String path)
437
	 * @since 2.0
436
  {
438
	 */
437
    if (StringUtil.isEmpty(path))
439
	protected CDOResourceNode getResourceNode(CDOID folderID, String name) {
438
    {
440
		try {
439
      throw new IllegalArgumentException(Messages.getString("CDOViewImpl.1")); //$NON-NLS-1$
441
			CDOID id = getResourceNodeID(folderID, name);
440
    }
442
			return (CDOResourceNode) getObject(id);
441
443
		} catch (CDOException ex) {
442
    CDOID folderID = null;
444
			throw ex;
443
    if (CDOURIUtil.SEGMENT_SEPARATOR.equals(path))
445
		} catch (Exception ex) {
444
    {
446
			throw new CDOException(ex);
445
      folderID = getResourceNodeIDChecked(null, null);
447
		}
446
    }
448
	}
447
    else
449
448
    {
450
	/**
449
      List<String> names = CDOURIUtil.analyzePath(path);
451
	 * @since 2.0
450
      for (String name : names)
452
	 */
451
      {
453
	protected CDOID getResourceNodeID(CDOID folderID, String name) {
452
        folderID = getResourceNodeIDChecked(folderID, name);
454
		if (folderID == null) {
453
      }
455
			return getRootOrTopLevelResourceNodeID(name);
454
    }
456
		}
455
457
456
    return folderID;
458
		if (name == null) {
457
  }
459
			throw new IllegalArgumentException(Messages
458
460
					.getString("CDOViewImpl.3")); //$NON-NLS-1$
459
  /**
461
		}
460
   * @return never <code>null</code>
462
461
   */
463
		InternalCDORevision folderRevision = getLocalRevision(folderID);
462
  private CDOID getResourceNodeIDChecked(CDOID folderID, String name)
464
		EClass resourceFolderClass = EresourcePackage.eINSTANCE
463
  {
465
				.getCDOResourceFolder();
464
    folderID = getResourceNodeID(folderID, name);
466
		if (folderRevision.getEClass() != resourceFolderClass) {
465
    if (folderID == null)
467
			throw new CDOException(MessageFormat.format(Messages
466
    {
468
					.getString("CDOViewImpl.4"), folderID)); //$NON-NLS-1$
467
      throw new CDOException(MessageFormat.format(Messages.getString("CDOViewImpl.2"), name)); //$NON-NLS-1$
469
		}
468
    }
470
469
471
		EReference nodesFeature = EresourcePackage.eINSTANCE
470
    return folderID;
472
				.getCDOResourceFolder_Nodes();
471
  }
473
		EAttribute nameFeature = EresourcePackage.eINSTANCE
472
474
				.getCDOResourceNode_Name();
473
  /**
475
474
   * @return never <code>null</code>
476
		int size = folderRevision.data().size(nodesFeature);
475
   * @since 2.0
477
		for (int i = 0; i < size; i++) {
476
   */
478
			Object value = folderRevision.data().get(nodesFeature, i);
477
  protected CDOResourceNode getResourceNode(CDOID folderID, String name)
479
			value = getStore().resolveProxy(folderRevision, nodesFeature, i,
478
  {
480
					value);
479
    try
481
480
    {
482
			CDORevision childRevision = getLocalRevision((CDOID) convertObjectToID(value));
481
      CDOID id = getResourceNodeID(folderID, name);
483
			if (name.equals(childRevision.data().get(nameFeature, 0))) {
482
      return (CDOResourceNode)getObject(id);
484
				return childRevision.getID();
483
    }
485
			}
484
    catch (CDOException ex)
486
		}
485
    {
487
486
      throw ex;
488
		throw new CDOException(MessageFormat.format(Messages
487
    }
489
				.getString("CDOViewImpl.5"), name)); //$NON-NLS-1$
488
    catch (Exception ex)
490
	}
489
    {
491
490
      throw new CDOException(ex);
492
	/**
491
    }
493
	 * @since 2.0
492
  }
494
	 */
493
495
	protected CDOID getRootOrTopLevelResourceNodeID(String name) {
494
  /**
496
		CDOQuery resourceQuery = createResourcesQuery(null, name, true);
495
   * @since 2.0
497
		resourceQuery.setMaxResults(1);
496
   */
498
		List<CDOID> ids = resourceQuery.getResult(CDOID.class);
497
  protected CDOID getResourceNodeID(CDOID folderID, String name)
499
		if (ids.isEmpty()) {
498
  {
500
			if (name == null) {
499
    if (folderID == null)
501
				throw new CDOException(Messages.getString("CDOViewImpl.6")); //$NON-NLS-1$
500
    {
502
			} else {
501
      return getRootOrTopLevelResourceNodeID(name);
503
				throw new CDOException(MessageFormat.format(Messages
502
    }
504
						.getString("CDOViewImpl.7"), name)); //$NON-NLS-1$
503
505
			}
504
    if (name == null)
506
		}
505
    {
507
506
      throw new IllegalArgumentException(Messages.getString("CDOViewImpl.3")); //$NON-NLS-1$
508
		if (ids.size() > 1) {
507
    }
509
			// TODO is this still needed since the is
508
510
			// resourceQuery.setMaxResults(1) ??
509
    InternalCDORevision folderRevision = getLocalRevision(folderID);
511
			throw new ImplementationError(Messages.getString("CDOViewImpl.8")); //$NON-NLS-1$
510
    EClass resourceFolderClass = EresourcePackage.eINSTANCE.getCDOResourceFolder();
512
		}
511
    if (folderRevision.getEClass() != resourceFolderClass)
513
512
    {
514
		return ids.get(0);
513
      throw new CDOException(MessageFormat.format(Messages.getString("CDOViewImpl.4"), folderID)); //$NON-NLS-1$
515
	}
514
    }
516
515
517
	/**
516
    EReference nodesFeature = EresourcePackage.eINSTANCE.getCDOResourceFolder_Nodes();
518
	 * @since 2.0
517
    EAttribute nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name();
519
	 */
518
520
	protected InternalCDORevision getLocalRevision(CDOID id) {
519
    int size = folderRevision.data().size(nodesFeature);
521
		InternalCDORevision revision = null;
520
    for (int i = 0; i < size; i++)
522
		InternalCDOObject object = getObject(id, false);
521
    {
523
		if (object != null && object.cdoState() != CDOState.PROXY) {
522
      Object value = folderRevision.data().get(nodesFeature, i);
524
			revision = object.cdoRevision();
523
      value = getStore().resolveProxy(folderRevision, nodesFeature, i, value);
525
		}
524
526
525
      CDORevision childRevision = getLocalRevision((CDOID)convertObjectToID(value));
527
		if (revision == null) {
526
      if (name.equals(childRevision.data().get(nameFeature, 0)))
528
			revision = getRevision(id, true);
527
      {
529
		}
528
        return childRevision.getID();
530
529
      }
531
		if (revision == null) {
530
    }
532
			throw new CDOException(MessageFormat.format(Messages
531
533
					.getString("CDOViewImpl.9"), id)); //$NON-NLS-1$
532
    throw new CDOException(MessageFormat.format(Messages.getString("CDOViewImpl.5"), name)); //$NON-NLS-1$
534
		}
533
  }
535
534
536
		return revision;
535
  /**
537
	}
536
   * @since 2.0
538
537
   */
539
	/**
538
  protected CDOID getRootOrTopLevelResourceNodeID(String name)
540
	 * @since 2.0
539
  {
541
	 */
540
    CDOQuery resourceQuery = createResourcesQuery(null, name, true);
542
	public InternalCDOObject[] getObjectsArray() {
541
    resourceQuery.setMaxResults(1);
543
		synchronized (objects) {
542
    List<CDOID> ids = resourceQuery.getResult(CDOID.class);
544
			return objects.values().toArray(
543
    if (ids.isEmpty())
545
					new InternalCDOObject[objects.size()]);
544
    {
546
		}
545
      if (name == null)
547
	}
546
      {
548
547
        throw new CDOException(Messages.getString("CDOViewImpl.6")); //$NON-NLS-1$
549
	/**
548
      }
550
	 * TODO Remove me
549
      else
551
	 * 
550
      {
552
	 * @since 2.0
551
        throw new CDOException(MessageFormat.format(Messages.getString("CDOViewImpl.7"), name)); //$NON-NLS-1$
553
	 */
552
      }
554
	@Deprecated
553
    }
555
	public CDOResourceFolder getResourceFolder(String path) {
554
556
		if (path == null) {
555
    if (ids.size() > 1)
557
			return null;
556
    {
558
		}
557
      // TODO is this still needed since the is resourceQuery.setMaxResults(1) ??
559
558
      throw new ImplementationError(Messages.getString("CDOViewImpl.8")); //$NON-NLS-1$
560
		CDOResourceFolder folder = null;
559
    }
561
		StringTokenizer tokenizer = new StringTokenizer(path,
560
562
				CDOURIUtil.SEGMENT_SEPARATOR);
561
    return ids.get(0);
563
		while (tokenizer.hasMoreTokens()) {
562
  }
564
			String segment = tokenizer.nextToken();
563
565
			if (segment != null) {
564
  /**
566
				if (folder == null) {
565
   * @since 2.0
567
				} else {
566
   */
568
				}
567
  protected InternalCDORevision getLocalRevision(CDOID id)
569
			}
568
  {
570
		}
569
    InternalCDORevision revision = null;
571
570
    InternalCDOObject object = getObject(id, false);
572
		return folder;
571
    if (object != null && object.cdoState() != CDOState.PROXY)
573
	}
572
    {
574
573
      revision = object.cdoRevision();
575
	/**
574
    }
576
	 * @since 2.0
575
577
	 */
576
    if (revision == null)
578
	public CDOResource getResource(String path) {
577
    {
579
		return getResource(path, true);
578
      revision = getRevision(id, true);
580
	}
579
    }
581
580
582
	/**
581
    if (revision == null)
583
	 * @since 2.0
582
    {
584
	 */
583
      throw new CDOException(MessageFormat.format(Messages.getString("CDOViewImpl.9"), id)); //$NON-NLS-1$
585
	public CDOResource getResource(String path, boolean loadInDemand) {
584
    }
586
		checkActive();
585
587
		URI uri = CDOURIUtil.createResourceURI(this, path);
586
    return revision;
588
		return (CDOResource) getResourceSet().getResource(uri, loadInDemand);
587
  }
589
	}
588
590
589
  /**
591
	/**
590
   * @since 2.0
592
	 * @since 2.0
591
   */
593
	 */
592
  public InternalCDOObject[] getObjectsArray()
594
	public List<CDOResourceNode> queryResources(CDOResourceFolder folder,
593
  {
595
			String name, boolean exactMatch) {
594
    synchronized (objects)
596
		checkActive();
595
    {
597
		CDOQuery resourceQuery = createResourcesQuery(folder, name, exactMatch);
596
      return objects.values().toArray(new InternalCDOObject[objects.size()]);
598
		return resourceQuery.getResult(CDOResourceNode.class);
597
    }
599
	}
598
  }
600
599
601
	/**
600
  /**
602
	 * @since 2.0
601
   * TODO Remove me
603
	 */
602
   * 
604
	public CloseableIterator<CDOResourceNode> queryResourcesAsync(
603
   * @since 2.0
605
			CDOResourceFolder folder, String name, boolean exactMatch) {
604
   */
606
		checkActive();
605
  @Deprecated
607
		CDOQuery resourceQuery = createResourcesQuery(folder, name, exactMatch);
606
  public CDOResourceFolder getResourceFolder(String path)
608
		return resourceQuery.getResultAsync(CDOResourceNode.class);
607
  {
609
	}
608
    if (path == null)
610
609
    {
611
	private CDOQuery createResourcesQuery(CDOResourceFolder folder,
610
      return null;
612
			String name, boolean exactMatch) {
611
    }
613
		CDOQuery query = createQuery(
612
614
				CDOProtocolConstants.QUERY_LANGUAGE_RESOURCES, name);
613
    CDOResourceFolder folder = null;
615
		query.setParameter(
614
    StringTokenizer tokenizer = new StringTokenizer(path, CDOURIUtil.SEGMENT_SEPARATOR);
616
				CDOProtocolConstants.QUERY_LANGUAGE_RESOURCES_FOLDER_ID,
615
    while (tokenizer.hasMoreTokens())
617
				folder == null ? null : folder.cdoID());
616
    {
618
		query.setParameter(
617
      String segment = tokenizer.nextToken();
619
				CDOProtocolConstants.QUERY_LANGUAGE_RESOURCES_EXACT_MATCH,
618
      if (segment != null)
620
				exactMatch);
619
      {
621
		return query;
620
        if (folder == null)
622
	}
621
        {
623
622
        }
624
	public CDOResourceImpl getResource(CDOID resourceID) {
623
        else
625
		if (CDOIDUtil.isNull(resourceID)) {
624
        {
626
			throw new IllegalArgumentException("resourceID: " + resourceID); //$NON-NLS-1$
625
        }
627
		}
626
      }
628
627
    }
629
		return (CDOResourceImpl) getObject(resourceID);
628
630
	}
629
    return folder;
631
630
  }
632
	public InternalCDOObject newInstance(EClass eClass) {
631
633
		EObject eObject = EcoreUtil.create(eClass);
632
  /**
634
		return FSMUtil.adapt(eObject, this);
633
   * @since 2.0
635
	}
634
   */
636
635
  public CDOResource getResource(String path)
637
	public InternalCDORevision getRevision(CDOID id, boolean loadOnDemand) {
636
  {
638
		CDORevisionManager revisionManager = session.getRevisionManager();
637
    return getResource(path, true);
639
		int initialChunkSize = session.options().getCollectionLoadingPolicy()
638
  }
640
				.getInitialChunkSize();
639
641
		return (InternalCDORevision) revisionManager.getRevision(id,
640
  /**
642
				initialChunkSize, CDORevision.DEPTH_NONE, loadOnDemand);
641
   * @since 2.0
643
	}
642
   */
644
643
  public CDOResource getResource(String path, boolean loadInDemand)
645
	public void prefetchRevisions(CDOID id, int depth) {
644
  {
646
		checkArg(depth != CDORevision.DEPTH_NONE,
645
    checkActive();
647
				"Prefetch depth must not be zero");
646
    URI uri = CDOURIUtil.createResourceURI(this, path);
648
		int initialChunkSize = session.options().getCollectionLoadingPolicy()
647
    return (CDOResource)getResourceSet().getResource(uri, loadInDemand);
649
				.getInitialChunkSize();
648
  }
650
		prefetchRevisions(id, depth, initialChunkSize);
649
651
	}
650
  /**
652
651
   * @since 2.0
653
	protected void prefetchRevisions(CDOID id, int depth, int initialChunkSize) {
652
   */
654
		session.getRevisionManager().getRevision(id, initialChunkSize, depth);
653
  public List<CDOResourceNode> queryResources(CDOResourceFolder folder, String name, boolean exactMatch)
655
	}
654
  {
656
655
    checkActive();
657
	public InternalCDOObject getObject(CDOID id) {
656
    CDOQuery resourceQuery = createResourcesQuery(folder, name, exactMatch);
658
		return getObject(id, true);
657
    return resourceQuery.getResult(CDOResourceNode.class);
659
	}
658
  }
660
659
661
	/**
660
  /**
662
	 * Support recursivity and concurrency.
661
   * @since 2.0
663
	 */
662
   */
664
	public InternalCDOObject getObject(CDOID id, boolean loadOnDemand) {
663
  public CloseableIterator<CDOResourceNode> queryResourcesAsync(CDOResourceFolder folder, String name,
665
		checkActive();
664
      boolean exactMatch)
666
		if (CDOIDUtil.isNull(id)) {
665
  {
667
			return null;
666
    checkActive();
668
		}
667
    CDOQuery resourceQuery = createResourcesQuery(folder, name, exactMatch);
669
668
    return resourceQuery.getResultAsync(CDOResourceNode.class);
670
		// Since getObject could trigger a read (ONLY when we load a resource)
669
  }
671
		// we NEED to make sure the state lock is
670
672
		// active.
671
  private CDOQuery createResourcesQuery(CDOResourceFolder folder, String name, boolean exactMatch)
673
		// Always use in the following order
672
  {
674
		// 1- getStateLock().lock();
673
    CDOQuery query = createQuery(CDOProtocolConstants.QUERY_LANGUAGE_RESOURCES, name);
675
		// 2- synchronized(objects)
674
    query.setParameter(CDOProtocolConstants.QUERY_LANGUAGE_RESOURCES_FOLDER_ID, folder == null ? null : folder.cdoID());
676
		// DO NOT inverse them otherwise deadlock could occured.
675
    query.setParameter(CDOProtocolConstants.QUERY_LANGUAGE_RESOURCES_EXACT_MATCH, exactMatch);
677
676
    return query;
678
		ReentrantLock stateLock = getStateLock();
677
  }
679
		stateLock.lock();
678
680
		try {
679
  public CDOResourceImpl getResource(CDOID resourceID)
681
			synchronized (objects) {
680
  {
682
				if (id.equals(lastLookupID)) {
681
    if (CDOIDUtil.isNull(resourceID))
683
					return lastLookupObject;
682
    {
684
				}
683
      throw new IllegalArgumentException("resourceID: " + resourceID); //$NON-NLS-1$
685
684
    }
686
				// Needed for recursive call to getObject. (from
685
687
				// createObject/cleanObject/getResource/getObject)
686
    return (CDOResourceImpl)getObject(resourceID);
688
				InternalCDOObject localLookupObject = objects.get(id);
687
  }
689
				if (localLookupObject == null) {
688
690
					if (id.isMeta()) {
689
  public InternalCDOObject newInstance(EClass eClass)
691
						localLookupObject = createMetaObject((CDOIDMeta) id);
690
  {
692
					} else {
691
    EObject eObject = EcoreUtil.create(eClass);
693
						if (loadOnDemand) {
692
    return FSMUtil.adapt(eObject, this);
694
							if (id.isTemporary()) {
693
  }
695
								throw new ObjectNotFoundException(id);
694
696
							}
695
  public InternalCDORevision getRevision(CDOID id, boolean loadOnDemand)
697
696
  {
698
							localLookupObject = createObject(id);
697
    CDORevisionManager revisionManager = session.getRevisionManager();
699
						} else {
698
    int initialChunkSize = session.options().getCollectionLoadingPolicy().getInitialChunkSize();
700
							return null;
699
    return (InternalCDORevision)revisionManager.getRevision(id, initialChunkSize, CDORevision.DEPTH_NONE, loadOnDemand);
701
						}
700
  }
702
					}
701
703
702
  public void prefetchRevisions(CDOID id, int depth)
704
					// CDOResource have a special way to register to the view.
703
  {
705
					if (!CDOModelUtil.isResource(localLookupObject.eClass())) {
704
    checkArg(depth != CDORevision.DEPTH_NONE, "Prefetch depth must not be zero");
706
						registerObject(localLookupObject);
705
    int initialChunkSize = session.options().getCollectionLoadingPolicy().getInitialChunkSize();
707
					}
706
    prefetchRevisions(id, depth, initialChunkSize);
708
				}
707
  }
709
708
710
				lastLookupID = id;
709
  protected void prefetchRevisions(CDOID id, int depth, int initialChunkSize)
711
				lastLookupObject = localLookupObject;
710
  {
712
				return lastLookupObject;
711
    session.getRevisionManager().getRevision(id, initialChunkSize, depth);
713
			}
712
  }
714
		} finally {
713
715
			stateLock.unlock();
714
  public InternalCDOObject getObject(CDOID id)
716
		}
715
  {
717
	}
716
    return getObject(id, true);
718
717
  }
719
	/**
718
720
	 * @since 2.0
719
  /**
721
	 */
720
   * Support recursivity and concurrency.
722
	@SuppressWarnings("unchecked")
721
   */
723
	public <T extends EObject> T getObject(T objectFromDifferentView) {
722
  public InternalCDOObject getObject(CDOID id, boolean loadOnDemand)
724
		checkActive();
723
  {
725
		if (objectFromDifferentView instanceof CDOObject) {
724
    checkActive();
726
			CDOObject object = (CDOObject) objectFromDifferentView;
725
    if (CDOIDUtil.isNull(id))
727
			CDOView view = object.cdoView();
726
    {
728
			if (view != this) {
727
      return null;
729
				if (view.getSession() != session) {
728
    }
730
					throw new IllegalArgumentException(
729
731
							MessageFormat
730
    // Since getObject could trigger a read (ONLY when we load a resource) we NEED to make sure the state lock is
732
									.format(
731
    // active.
733
											Messages
732
    // Always use in the following order
734
													.getString("CDOViewImpl.11"), objectFromDifferentView)); //$NON-NLS-1$
733
    // 1- getStateLock().lock();
735
				}
734
    // 2- synchronized(objects)
736
735
    // DO NOT inverse them otherwise deadlock could occured.
737
				CDOID id = object.cdoID();
736
738
				objectFromDifferentView = (T) getObject(id, true);
737
    ReentrantLock stateLock = getStateLock();
739
			}
738
    stateLock.lock();
740
		}
739
    try
741
740
    {
742
		return objectFromDifferentView;
741
      synchronized (objects)
743
	}
742
      {
744
743
        if (id.equals(lastLookupID))
745
	public boolean isObjectRegistered(CDOID id) {
744
        {
746
		checkActive();
745
          return lastLookupObject;
747
		if (CDOIDUtil.isNull(id)) {
746
        }
748
			return false;
747
749
		}
748
        // Needed for recursive call to getObject. (from createObject/cleanObject/getResource/getObject)
750
749
        InternalCDOObject localLookupObject = objects.get(id);
751
		synchronized (objects) {
750
        if (localLookupObject == null)
752
			return objects.containsKey(id);
751
        {
753
		}
752
          if (id.isMeta())
754
	}
753
          {
755
754
            localLookupObject = createMetaObject((CDOIDMeta)id);
756
	public InternalCDOObject removeObject(CDOID id) {
755
          }
757
		synchronized (objects) {
756
          else
758
			if (id.equals(lastLookupID)) {
757
          {
759
				lastLookupID = null;
758
            if (loadOnDemand)
760
				lastLookupObject = null;
759
            {
761
			}
760
              if (id.isTemporary())
762
761
              {
763
			return objects.remove(id);
762
                throw new ObjectNotFoundException(id);
764
		}
763
              }
765
	}
764
766
765
              localLookupObject = createObject(id);
767
	/**
766
            }
768
	 * @return Never <code>null</code>
767
            else
769
	 */
768
            {
770
	private InternalCDOObject createMetaObject(CDOIDMeta id) {
769
              return null;
771
		if (TRACER.isEnabled()) {
770
            }
772
			TRACER.trace("Creating meta object for " + id); //$NON-NLS-1$
771
          }
773
		}
772
774
773
          // CDOResource have a special way to register to the view.
775
		InternalCDOPackageRegistry packageRegistry = session
774
          if (!CDOModelUtil.isResource(localLookupObject.eClass()))
776
				.getPackageRegistry();
775
          {
777
		InternalEObject metaInstance = packageRegistry.getMetaInstanceMapper()
776
            registerObject(localLookupObject);
778
				.lookupMetaInstance(id);
777
          }
779
		return new CDOMetaWrapper(this, metaInstance, id);
778
        }
780
	}
779
781
780
        lastLookupID = id;
782
	/**
781
        lastLookupObject = localLookupObject;
783
	 * @return Never <code>null</code>
782
        return lastLookupObject;
784
	 */
783
      }
785
	private InternalCDOObject createObject(CDOID id) {
784
    }
786
		if (TRACER.isEnabled()) {
785
    finally
787
			TRACER.trace("Creating object for " + id); //$NON-NLS-1$
786
    {
788
		}
787
      stateLock.unlock();
789
788
    }
790
		InternalCDORevision revision = getRevision(id, true);
789
  }
791
		FSMUtil.validate(id, revision);
790
792
791
  /**
793
		EClass eClass = revision.getEClass();
792
   * @since 2.0
794
		InternalCDOObject object;
793
   */
795
		if (CDOModelUtil.isResource(eClass)) {
794
  @SuppressWarnings("unchecked")
796
			object = (InternalCDOObject) newResourceInstance(revision);
795
  public <T extends EObject> T getObject(T objectFromDifferentView)
797
			// object is PROXY
796
  {
798
		} else {
797
    checkActive();
799
			object = newInstance(eClass);
798
    if (objectFromDifferentView instanceof CDOObject)
800
			// object is TRANSIENT
799
    {
801
		}
800
      CDOObject object = (CDOObject)objectFromDifferentView;
802
801
      CDOView view = object.cdoView();
803
		cleanObject(object, revision);
802
      if (view != this)
804
		return object;
803
      {
805
	}
804
        if (view.getSession() != session)
806
805
        {
807
	private CDOResource newResourceInstance(InternalCDORevision revision) {
806
          throw new IllegalArgumentException(MessageFormat.format(
808
		String path = getResourcePath(revision);
807
              Messages.getString("CDOViewImpl.11"), objectFromDifferentView)); //$NON-NLS-1$
809
		return getResource(path, true);
808
        }
810
	}
809
811
810
        CDOID id = object.cdoID();
812
	private String getResourcePath(InternalCDORevision revision) {
811
        objectFromDifferentView = (T)getObject(id, true);
813
		EAttribute nameFeature = EresourcePackage.eINSTANCE
812
      }
814
				.getCDOResourceNode_Name();
813
    }
815
814
816
		CDOID folderID = (CDOID) revision.data().getContainerID();
815
    return objectFromDifferentView;
817
		String name = (String) revision.data().get(nameFeature, 0);
816
  }
818
		if (CDOIDUtil.isNull(folderID)) {
817
819
			if (name == null) {
818
  public boolean isObjectRegistered(CDOID id)
820
				return CDOURIUtil.SEGMENT_SEPARATOR;
819
  {
821
			}
820
    checkActive();
822
821
    if (CDOIDUtil.isNull(id))
823
			return name;
822
    {
824
		}
823
      return false;
825
824
    }
826
		InternalCDOObject object = getObject(folderID, true);
825
827
		if (object instanceof CDOResourceFolder) {
826
    synchronized (objects)
828
			CDOResourceFolder folder = (CDOResourceFolder) object;
827
    {
829
			String path = folder.getPath();
828
      return objects.containsKey(id);
830
			return path + CDOURIUtil.SEGMENT_SEPARATOR + name;
829
    }
831
		}
830
  }
832
831
833
		throw new ImplementationError(MessageFormat.format(Messages
832
  public InternalCDOObject removeObject(CDOID id)
834
				.getString("CDOViewImpl.14"), object)); //$NON-NLS-1$
833
  {
835
	}
834
    synchronized (objects)
836
835
    {
837
	/**
836
      if (id.equals(lastLookupID))
838
	 * @since 2.0
837
      {
839
	 */
838
        lastLookupID = null;
840
	protected void cleanObject(InternalCDOObject object,
839
        lastLookupObject = null;
841
			InternalCDORevision revision) {
840
      }
842
		object.cdoInternalCleanup();
841
843
842
      return objects.remove(id);
844
		object.cdoInternalSetView(this);
843
    }
845
		object.cdoInternalSetRevision(revision);
844
  }
846
		object.cdoInternalSetID(revision.getID());
845
847
		object.cdoInternalSetState(CDOState.CLEAN);
846
  /**
848
847
   * @return Never <code>null</code>
849
		object.cdoInternalPostLoad();
848
   */
850
	}
849
  private InternalCDOObject createMetaObject(CDOIDMeta id)
851
850
  {
852
	public CDOID provideCDOID(Object idOrObject) {
851
    if (TRACER.isEnabled())
853
		Object shouldBeCDOID = convertObjectToID(idOrObject);
852
    {
854
		if (shouldBeCDOID instanceof CDOID) {
853
      TRACER.trace("Creating meta object for " + id); //$NON-NLS-1$
855
			CDOID id = (CDOID) shouldBeCDOID;
854
    }
856
			if (TRACER.isEnabled() && id != idOrObject) {
855
857
				TRACER
856
    InternalCDOPackageRegistry packageRegistry = session.getPackageRegistry();
858
						.format(
857
    InternalEObject metaInstance = packageRegistry.getMetaInstanceMapper().lookupMetaInstance(id);
859
								"Converted object to CDOID: {0} --> {1}", idOrObject, id); //$NON-NLS-1$
858
    return new CDOMetaWrapper(this, metaInstance, id);
860
			}
859
  }
861
860
862
			return id;
861
  /**
863
		} else if (idOrObject instanceof InternalEObject) {
862
   * @return Never <code>null</code>
864
			InternalEObject eObject = (InternalEObject) idOrObject;
863
   */
865
			String uri = EcoreUtil.getURI(eObject).toString();
864
  private InternalCDOObject createObject(CDOID id)
866
			if (eObject instanceof InternalCDOObject) {
865
  {
867
				InternalCDOObject object = (InternalCDOObject) idOrObject;
866
    if (TRACER.isEnabled())
868
				if (object.cdoView() != null && FSMUtil.isNew(object)) {
867
    {
869
					return CDOIDUtil.createTempObjectExternal(uri);
868
      TRACER.trace("Creating object for " + id); //$NON-NLS-1$
870
				}
869
    }
871
			}
870
872
871
    InternalCDORevision revision = getRevision(id, true);
873
			if (eObject.eResource() != null) {
872
    FSMUtil.validate(id, revision);
874
				return CDOIDUtil.createExternal(uri);
873
875
			}
874
    EClass eClass = revision.getEClass();
876
875
    InternalCDOObject object;
877
			throw new DanglingReferenceException(eObject);
876
    if (CDOModelUtil.isResource(eClass))
878
		}
877
    {
879
878
      object = (InternalCDOObject)newResourceInstance(revision);
880
		throw new IllegalStateException(MessageFormat.format(Messages
879
      // object is PROXY
881
				.getString("CDOViewImpl.16"), idOrObject.getClass().getName())); //$NON-NLS-1$
880
    }
882
	}
881
    else
883
882
    {
884
	public Object convertObjectToID(Object potentialObject) {
883
      object = newInstance(eClass);
885
		return convertObjectToID(potentialObject, false);
884
      // object is TRANSIENT
886
	}
885
    }
887
886
888
	/**
887
    cleanObject(object, revision);
889
	 * @since 2.0
888
    return object;
890
	 */
889
  }
891
	public Object convertObjectToID(Object potentialObject,
890
892
			boolean onlyPersistedID) {
891
  private CDOResource newResourceInstance(InternalCDORevision revision)
893
		if (potentialObject instanceof CDOID) {
892
  {
894
			return potentialObject;
893
    String path = getResourcePath(revision);
895
		}
894
    return getResource(path, true);
896
895
  }
897
		if (potentialObject instanceof InternalEObject) {
896
898
			if (potentialObject instanceof InternalCDOObject) {
897
  private String getResourcePath(InternalCDORevision revision)
899
				InternalCDOObject object = (InternalCDOObject) potentialObject;
898
  {
900
				CDOID id = getID(object, onlyPersistedID);
899
    EAttribute nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name();
901
				if (id != null) {
900
902
					return id;
901
    CDOID folderID = (CDOID)revision.data().getContainerID();
903
				}
902
    String name = (String)revision.data().get(nameFeature, 0);
904
			} else {
903
    if (CDOIDUtil.isNull(folderID))
905
				try {
904
    {
906
					InternalCDOObject object = FSMUtil
905
      if (name == null)
907
							.getLegacyAdapter(((InternalEObject) potentialObject)
906
      {
908
									.eAdapters());
907
        return CDOURIUtil.SEGMENT_SEPARATOR;
909
					if (object != null) {
908
      }
910
						CDOID id = getID(object, onlyPersistedID);
909
911
						if (id != null) {
910
      return name;
912
							return id;
911
    }
913
						}
912
914
913
    InternalCDOObject object = getObject(folderID, true);
915
						potentialObject = object;
914
    if (object instanceof CDOResourceFolder)
916
					}
915
    {
917
				} catch (Throwable ex) {
916
      CDOResourceFolder folder = (CDOResourceFolder)object;
918
					OM.LOG.warn(ex);
917
      String path = folder.getPath();
919
				}
918
      return path + CDOURIUtil.SEGMENT_SEPARATOR + name;
920
			}
919
    }
921
		}
920
922
921
    throw new ImplementationError(MessageFormat.format(Messages.getString("CDOViewImpl.14"), object)); //$NON-NLS-1$
923
		return potentialObject;
922
  }
924
	}
923
925
924
  /**
926
	// TTT public CDOIDDangling convertDanglingObjectToID(InternalCDOObject
925
   * @since 2.0
927
	// source, EStructuralFeature feature,
926
   */
928
	// InternalEObject target)
927
  protected void cleanObject(InternalCDOObject object, InternalCDORevision revision)
929
	// {
928
  {
930
	// throw new
929
    object.cdoInternalCleanup();
931
	// IllegalStateException("Dangling objects not possible outside of a transaction");
930
932
	// }
931
    object.cdoInternalSetView(this);
933
932
    object.cdoInternalSetRevision(revision);
934
	protected CDOID getID(InternalCDOObject object, boolean onlyPersistedID) {
933
    object.cdoInternalSetID(revision.getID());
935
		if (onlyPersistedID) {
934
    object.cdoInternalSetState(CDOState.CLEAN);
936
			if (FSMUtil.isTransient(object) || FSMUtil.isNew(object)) {
935
937
				return null;
936
    object.cdoInternalPostLoad();
938
			}
937
  }
939
		}
938
940
939
  public CDOID provideCDOID(Object idOrObject)
941
		CDOView view = object.cdoView();
940
  {
942
		if (view == this) {
941
    Object shouldBeCDOID = convertObjectToID(idOrObject);
943
			return object.cdoID();
942
    if (shouldBeCDOID instanceof CDOID)
944
		}
943
    {
945
944
      CDOID id = (CDOID)shouldBeCDOID;
946
		if (view != null && view.getSession() == getSession()) {
945
      if (TRACER.isEnabled() && id != idOrObject)
947
			return object.cdoID();
946
      {
948
		}
947
        TRACER.format("Converted object to CDOID: {0} --> {1}", idOrObject, id); //$NON-NLS-1$
949
948
      }
950
		return null;
949
951
	}
950
      return id;
952
951
    }
953
	public Object convertIDToObject(Object potentialID) {
952
    else if (idOrObject instanceof InternalEObject)
954
		if (potentialID instanceof CDOID) {
953
    {
955
			if (potentialID == CDOID.NULL) {
954
      InternalEObject eObject = (InternalEObject)idOrObject;
956
				return null;
955
      String uri = EcoreUtil.getURI(eObject).toString();
957
			}
956
      if (eObject instanceof InternalCDOObject)
958
957
      {
959
			CDOID id = (CDOID) potentialID;
958
        InternalCDOObject object = (InternalCDOObject)idOrObject;
960
			if (id.isExternal()) {
959
        if (object.cdoView() != null && FSMUtil.isNew(object))
961
				return getResourceSet().getEObject(
960
        {
962
						URI.createURI(id.toURIFragment()), true);
961
          return CDOIDUtil.createTempObjectExternal(uri);
963
			}
962
        }
964
963
      }
965
			InternalCDOObject result = getObject(id, true);
964
966
			if (result == null) {
965
      if (eObject.eResource() != null)
967
				throw new ImplementationError(MessageFormat.format(Messages
966
      {
968
						.getString("CDOViewImpl.17"), id)); //$NON-NLS-1$
967
        return CDOIDUtil.createExternal(uri);
969
			}
968
      }
970
969
971
			return result.cdoInternalInstance();
970
      throw new DanglingReferenceException(eObject);
972
		}
971
    }
973
972
974
		return potentialID;
973
    throw new IllegalStateException(MessageFormat.format(
975
	}
974
        Messages.getString("CDOViewImpl.16"), idOrObject.getClass().getName())); //$NON-NLS-1$
976
975
  }
977
	/**
976
978
	 * @since 2.0
977
  public Object convertObjectToID(Object potentialObject)
979
	 */
978
  {
980
	public void attachResource(CDOResourceImpl resource) {
979
    return convertObjectToID(potentialObject, false);
981
		if (!resource.isExisting()) {
980
  }
982
			throw new ReadOnlyException(MessageFormat.format(Messages
981
983
					.getString("CDOViewImpl.18"), this)); //$NON-NLS-1$
982
  /**
984
		}
983
   * @since 2.0
985
984
   */
986
		// ResourceSet.getResource(uri, true) was called!!
985
  public Object convertObjectToID(Object potentialObject, boolean onlyPersistedID)
987
		resource.cdoInternalSetView(this);
986
  {
988
		resource.cdoInternalSetState(CDOState.PROXY);
987
    if (potentialObject instanceof CDOID)
989
	}
988
    {
990
989
      return potentialObject;
991
	/**
990
    }
992
	 * @since 2.0
991
993
	 */
992
    if (potentialObject instanceof InternalEObject)
994
	public void registerProxyResource(CDOResourceImpl resource) {
993
    {
995
		URI uri = resource.getURI();
994
      if (potentialObject instanceof InternalCDOObject)
996
		String path = CDOURIUtil.extractResourcePath(uri);
995
      {
997
996
        InternalCDOObject object = (InternalCDOObject)potentialObject;
998
		try {
997
        CDOID id = getID(object, onlyPersistedID);
999
			CDOID id = getResourceNodeID(path);
998
        if (id != null)
1000
			resource.cdoInternalSetID(id);
999
        {
1001
			registerObject(resource);
1000
          return id;
1002
		} catch (Exception ex) {
1001
        }
1003
			throw new InvalidURIException(uri, ex);
1002
      }
1004
		}
1003
      else
1005
	}
1004
      {
1006
1005
        try
1007
	public void registerObject(InternalCDOObject object) {
1006
        {
1008
		if (TRACER.isEnabled()) {
1007
          InternalCDOObject object = FSMUtil.getLegacyAdapter(((InternalEObject)potentialObject).eAdapters());
1009
			TRACER.format("Registering {0}", object); //$NON-NLS-1$
1008
          if (object != null)
1010
		}
1009
          {
1011
1010
            CDOID id = getID(object, onlyPersistedID);
1012
		InternalCDOObject old;
1011
            if (id != null)
1013
		synchronized (objects) {
1012
            {
1014
			old = objects.put(object.cdoID(), object);
1013
              return id;
1015
		}
1014
            }
1016
1015
1017
		if (old != null) {
1016
            potentialObject = object;
1018
			throw new IllegalStateException(MessageFormat.format(Messages
1017
          }
1019
					.getString("CDOViewImpl.20"), object)); //$NON-NLS-1$
1018
        }
1020
		}
1019
        catch (Throwable ex)
1021
	}
1020
        {
1022
1021
          OM.LOG.warn(ex);
1023
	public void deregisterObject(InternalCDOObject object) {
1022
        }
1024
		if (TRACER.isEnabled()) {
1023
      }
1025
			TRACER.format("Deregistering {0}", object); //$NON-NLS-1$
1024
    }
1026
		}
1025
1027
1026
    return potentialObject;
1028
		removeObject(object.cdoID());
1027
  }
1029
	}
1028
1030
1029
  // TTT public CDOIDDangling convertDanglingObjectToID(InternalCDOObject source, EStructuralFeature feature,
1031
	public void remapObject(CDOID oldID) {
1030
  // InternalEObject target)
1032
		CDOID newID;
1031
  // {
1033
		synchronized (objects) {
1032
  // throw new IllegalStateException("Dangling objects not possible outside of a transaction");
1034
			InternalCDOObject object = objects.remove(oldID);
1033
  // }
1035
			newID = object.cdoID();
1034
1036
			objects.put(newID, object);
1035
  protected CDOID getID(InternalCDOObject object, boolean onlyPersistedID)
1037
		}
1036
  {
1038
1037
    if (onlyPersistedID)
1039
		if (TRACER.isEnabled()) {
1038
    {
1040
			TRACER.format("Remapping {0} --> {1}", oldID, newID); //$NON-NLS-1$
1039
      if (FSMUtil.isTransient(object) || FSMUtil.isNew(object))
1041
		}
1040
      {
1042
	}
1041
        return null;
1043
1042
      }
1044
	public void addObjectHandler(CDOObjectHandler handler) {
1043
    }
1045
		objectHandlers.add(handler);
1044
1046
	}
1045
    CDOView view = object.cdoView();
1047
1046
    if (view == this)
1048
	public void removeObjectHandler(CDOObjectHandler handler) {
1047
    {
1049
		objectHandlers.remove(handler);
1048
      return object.cdoID();
1050
	}
1049
    }
1051
1050
1052
	public CDOObjectHandler[] getObjectHandlers() {
1051
    if (view != null && view.getSession() == getSession())
1053
		return objectHandlers.get();
1052
    {
1054
	}
1053
      return object.cdoID();
1055
1054
    }
1056
	public void handleObjectStateChanged(InternalCDOObject object,
1055
1057
			CDOState oldState, CDOState newState) {
1056
    return null;
1058
		CDOObjectHandler[] handlers = getObjectHandlers();
1057
  }
1059
		if (handlers != null) {
1058
1060
			for (int i = 0; i < handlers.length; i++) {
1059
  public Object convertIDToObject(Object potentialID)
1061
				CDOObjectHandler handler = handlers[i];
1060
  {
1062
				handler.objectStateChanged(this, object, oldState, newState);
1061
    if (potentialID instanceof CDOID)
1063
			}
1062
    {
1064
		}
1063
      if (potentialID == CDOID.NULL)
1065
	}
1064
      {
1066
1065
        return null;
1067
	/**
1066
      }
1068
	 * Turns registered objects into proxies and synchronously delivers
1067
1069
	 * invalidation events to registered event listeners.
1068
      CDOID id = (CDOID)potentialID;
1070
	 * <p>
1069
      if (id.isExternal())
1071
	 * <b>Implementation note:</b> This implementation guarantees that
1070
      {
1072
	 * exceptions from listener code don't propagate up to the caller of this
1071
        return getResourceSet().getEObject(URI.createURI(id.toURIFragment()), true);
1073
	 * method. Runtime exceptions from the implementation of the
1072
      }
1074
	 * {@link CDOStateMachine} are propagated to the caller of this method but
1073
1075
	 * this should not happen in the absence of implementation errors.
1074
      InternalCDOObject result = getObject(id, true);
1076
	 * <p>
1075
      if (result == null)
1077
	 * Note that this method can block for an uncertain amount of time on the
1076
      {
1078
	 * reentrant view lock!
1077
        throw new ImplementationError(MessageFormat.format(Messages.getString("CDOViewImpl.17"), id)); //$NON-NLS-1$
1079
	 * 
1078
      }
1080
	 * @param timeStamp
1079
1081
	 *            The time stamp of the server transaction if this event was
1080
      return result.cdoInternalInstance();
1082
	 *            sent as a result of a successfully committed transaction or
1081
    }
1083
	 *            <code>LOCAL_ROLLBACK</code> if this event was sent due to a
1082
1084
	 *            local rollback.
1083
    return potentialID;
1085
	 * @param dirtyOIDs
1084
  }
1086
	 *            A set of the object IDs to be invalidated. <b>Implementation
1085
1087
	 *            note:</b> This implementation expects the dirtyOIDs set to be
1086
  /**
1088
	 *            unmodifiable. It does not wrap the set (again).
1087
   * @since 2.0
1089
	 * @since 2.0
1088
   */
1090
	 */
1089
  public void attachResource(CDOResourceImpl resource)
1091
	public Set<CDOObject> handleInvalidation(long timeStamp,
1090
  {
1092
			Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedOIDs) {
1091
    if (!resource.isExisting())
1093
		Set<CDOObject> conflicts = null;
1092
    {
1094
		Set<InternalCDOObject> dirtyObjects = new HashSet<InternalCDOObject>();
1093
      throw new ReadOnlyException(MessageFormat.format(Messages.getString("CDOViewImpl.18"), this)); //$NON-NLS-1$
1095
		Set<InternalCDOObject> detachedObjects = new HashSet<InternalCDOObject>();
1094
    }
1096
		lock.lock();
1095
1097
1096
    // ResourceSet.getResource(uri, true) was called!!
1098
		try {
1097
    resource.cdoInternalSetView(this);
1099
			conflicts = handleInvalidationWithoutNotification(dirtyOIDs,
1098
    resource.cdoInternalSetState(CDOState.PROXY);
1100
					detachedOIDs, dirtyObjects, detachedObjects);
1099
  }
1101
		} finally {
1100
1102
			lock.unlock();
1101
  /**
1103
		}
1102
   * @since 2.0
1104
1103
   */
1105
		if (options().isInvalidationNotificationEnabled()) {
1104
  public void registerProxyResource(CDOResourceImpl resource)
1106
			for (InternalCDOObject dirtyObject : dirtyObjects) {
1105
  {
1107
				if (dirtyObject.eNotificationRequired()) {
1106
    URI uri = resource.getURI();
1108
					CDOInvalidationNotificationImpl notification = new CDOInvalidationNotificationImpl(
1107
    String path = CDOURIUtil.extractResourcePath(uri);
1109
							dirtyObject);
1108
1110
					dirtyObject.eNotify(notification);
1109
    try
1111
				}
1110
    {
1112
			}
1111
      CDOID id = getResourceNodeID(path);
1113
1112
      resource.cdoInternalSetID(id);
1114
			for (InternalCDOObject detachedObject : detachedObjects) {
1113
      registerObject(resource);
1115
				if (detachedObject.eNotificationRequired()) {
1114
    }
1116
					CDOInvalidationNotificationImpl notification = new CDOInvalidationNotificationImpl(
1115
    catch (Exception ex)
1117
							detachedObject);
1116
    {
1118
					detachedObject.eNotify(notification);
1117
      throw new InvalidURIException(uri, ex);
1119
				}
1118
    }
1120
			}
1119
  }
1121
		}
1120
1122
1121
  public void registerObject(InternalCDOObject object)
1123
		fireInvalidationEvent(timeStamp, Collections
1122
  {
1124
				.unmodifiableSet(dirtyObjects), Collections
1123
    if (TRACER.isEnabled())
1125
				.unmodifiableSet(detachedObjects));
1124
    {
1126
		return conflicts;
1125
      TRACER.format("Registering {0}", object); //$NON-NLS-1$
1127
	}
1126
    }
1128
1127
1129
	public Set<CDOObject> handleInvalidationWithoutNotification(
1128
    InternalCDOObject old;
1130
			Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedOIDs,
1129
    synchronized (objects)
1131
			Set<InternalCDOObject> dirtyObjects,
1130
    {
1132
			Set<InternalCDOObject> detachedObjects) {
1131
      old = objects.put(object.cdoID(), object);
1133
		Set<CDOObject> conflicts = null;
1132
    }
1134
		for (CDOIDAndVersion dirtyOID : dirtyOIDs) {
1133
1135
			InternalCDOObject dirtyObject = null;
1134
    if (old != null)
1136
			// 258831 - Causes deadlock when introduce thread safe mechanisms in
1135
    {
1137
			// State machine.
1136
      throw new IllegalStateException(MessageFormat.format(Messages.getString("CDOViewImpl.20"), object)); //$NON-NLS-1$
1138
			synchronized (objects) {
1137
    }
1139
				dirtyObject = objects.get(dirtyOID.getID());
1138
  }
1140
			}
1139
1141
1140
  public void deregisterObject(InternalCDOObject object)
1142
			if (dirtyObject != null) {
1141
  {
1143
				CDOStateMachine.INSTANCE.invalidate(dirtyObject, dirtyOID
1142
    if (TRACER.isEnabled())
1144
						.getVersion());
1143
    {
1145
				dirtyObjects.add(dirtyObject);
1144
      TRACER.format("Deregistering {0}", object); //$NON-NLS-1$
1146
				if (dirtyObject.cdoConflict()) {
1145
    }
1147
					if (conflicts == null) {
1146
1148
						conflicts = new HashSet<CDOObject>();
1147
    removeObject(object.cdoID());
1149
					}
1148
  }
1150
1149
1151
					conflicts.add(dirtyObject);
1150
  public void remapObject(CDOID oldID)
1152
				}
1151
  {
1153
			}
1152
    CDOID newID;
1154
		}
1153
    synchronized (objects)
1155
1154
    {
1156
		for (CDOID id : detachedOIDs) {
1155
      InternalCDOObject object = objects.remove(oldID);
1157
			InternalCDOObject detachedObject = removeObject(id);
1156
      newID = object.cdoID();
1158
			if (detachedObject != null) {
1157
      objects.put(newID, object);
1159
				CDOStateMachine.INSTANCE.detachRemote(detachedObject);
1158
    }
1160
				detachedObjects.add(detachedObject);
1159
1161
				if (detachedObject.cdoConflict()) {
1160
    if (TRACER.isEnabled())
1162
					if (conflicts == null) {
1161
    {
1163
						conflicts = new HashSet<CDOObject>();
1162
      TRACER.format("Remapping {0} --> {1}", oldID, newID); //$NON-NLS-1$
1164
					}
1163
    }
1165
1164
  }
1166
					conflicts.add(detachedObject);
1165
1167
				}
1166
  public void addObjectHandler(CDOObjectHandler handler)
1168
			}
1167
  {
1169
		}
1168
    objectHandlers.add(handler);
1170
1169
  }
1171
		return conflicts;
1170
1172
	}
1171
  public void removeObjectHandler(CDOObjectHandler handler)
1173
1172
  {
1174
	/**
1173
    objectHandlers.remove(handler);
1175
	 * @since 2.0
1174
  }
1176
	 */
1175
1177
	private void fireInvalidationEvent(long timeStamp,
1176
  public CDOObjectHandler[] getObjectHandlers()
1178
			Set<? extends CDOObject> dirtyObjects,
1177
  {
1179
			Set<? extends CDOObject> detachedObjects) {
1178
    return objectHandlers.get();
1180
		if (!dirtyObjects.isEmpty() || !detachedObjects.isEmpty()) {
1179
  }
1181
			IListener[] listeners = getListeners();
1180
1182
			if (listeners != null) {
1181
  public void handleObjectStateChanged(InternalCDOObject object, CDOState oldState, CDOState newState)
1183
				fireEvent(new InvalidationEvent(timeStamp, dirtyObjects,
1182
  {
1184
						detachedObjects), listeners);
1183
    CDOObjectHandler[] handlers = getObjectHandlers();
1185
			}
1184
    if (handlers != null)
1186
		}
1185
    {
1187
	}
1186
      for (int i = 0; i < handlers.length; i++)
1188
1187
      {
1189
	public void fireAdaptersNotifiedEvent(long timeStamp) {
1188
        CDOObjectHandler handler = handlers[i];
1190
		fireEvent(new AdaptersNotifiedEvent(timeStamp));
1189
        handler.objectStateChanged(this, object, oldState, newState);
1191
	}
1190
      }
1192
1191
    }
1193
	/**
1192
  }
1194
	 * @since 2.0
1193
1195
	 */
1194
  /**
1196
	public void handleChangeSubscription(Collection<CDORevisionDelta> deltas,
1195
   * Turns registered objects into proxies and synchronously delivers invalidation events to registered event listeners.
1197
			Collection<CDOID> detachedObjects) {
1196
   * <p>
1198
		boolean policiesPresent = options().hasChangeSubscriptionPolicies();
1197
   * <b>Implementation note:</b> This implementation guarantees that exceptions from listener code don't propagate up to
1199
		if (!policiesPresent) {
1198
   * the caller of this method. Runtime exceptions from the implementation of the {@link CDOStateMachine} are propagated
1200
			return;
1199
   * to the caller of this method but this should not happen in the absence of implementation errors.
1201
		}
1200
   * <p>
1202
1201
   * Note that this method can block for an uncertain amount of time on the reentrant view lock!
1203
		if (deltas != null) {
1202
   * 
1204
			CDONotificationBuilder builder = new CDONotificationBuilder();
1203
   * @param timeStamp
1205
			for (CDORevisionDelta delta : deltas) {
1204
   *          The time stamp of the server transaction if this event was sent as a result of a successfully committed
1206
				InternalCDOObject object = changeSubscriptionManager
1205
   *          transaction or <code>LOCAL_ROLLBACK</code> if this event was sent due to a local rollback.
1207
						.getSubcribeObject(delta.getID());
1206
   * @param dirtyOIDs
1208
				if (object != null && object.eNotificationRequired()) {
1207
   *          A set of the object IDs to be invalidated. <b>Implementation note:</b> This implementation expects the
1209
					NotificationImpl notification = builder.buildNotification(
1208
   *          dirtyOIDs set to be unmodifiable. It does not wrap the set (again).
1210
							object, delta);
1209
   * @since 2.0
1211
					if (notification != null) {
1210
   */
1212
						notification.dispatch();
1211
  public Set<CDOObject> handleInvalidation(long timeStamp, Set<CDOIDAndVersion> dirtyOIDs,
1213
					}
1212
      Collection<CDOID> detachedOIDs)
1214
				}
1213
  {
1215
			}
1214
    Set<CDOObject> conflicts = null;
1216
		}
1215
    Set<InternalCDOObject> dirtyObjects = new HashSet<InternalCDOObject>();
1217
1216
    Set<InternalCDOObject> detachedObjects = new HashSet<InternalCDOObject>();
1218
		if (detachedObjects != null) {
1217
    lock.lock();
1219
			for (CDOID id : detachedObjects) {
1218
1220
				InternalCDOObject object = changeSubscriptionManager
1219
    try
1221
						.getSubcribeObject(id);
1220
    {
1222
				if (object != null && object.eNotificationRequired()) {
1221
      conflicts = handleInvalidationWithoutNotification(dirtyOIDs, detachedOIDs, dirtyObjects, detachedObjects);
1223
					NotificationImpl notification = new CDODeltaNotificationImpl(
1222
    }
1224
							object, CDONotification.DETACH_OBJECT,
1223
    finally
1225
							Notification.NO_FEATURE_ID, null, null);
1224
    {
1226
					notification.dispatch();
1225
      lock.unlock();
1227
				}
1226
    }
1228
			}
1227
1229
1228
    if (options().isInvalidationNotificationEnabled())
1230
			getChangeSubscriptionManager().handleDetachedObjects(
1229
    {
1231
					detachedObjects);
1230
      for (InternalCDOObject dirtyObject : dirtyObjects)
1232
		}
1231
      {
1233
	}
1232
        if (dirtyObject.eNotificationRequired())
1234
1233
        {
1235
	/**
1234
          CDOInvalidationNotificationImpl notification = new CDOInvalidationNotificationImpl(dirtyObject);
1236
	 * @since 2.0
1235
          dirtyObject.eNotify(notification);
1237
	 */
1236
        }
1238
	protected ChangeSubscriptionManager createChangeSubscriptionManager() {
1237
      }
1239
		return new ChangeSubscriptionManager(this);
1238
1240
	}
1239
      for (InternalCDOObject detachedObject : detachedObjects)
1241
1240
      {
1242
	/**
1241
        if (detachedObject.eNotificationRequired())
1243
	 * @since 2.0
1242
        {
1244
	 */
1243
          CDOInvalidationNotificationImpl notification = new CDOInvalidationNotificationImpl(detachedObject);
1245
	public AdapterManager getAdapterManager() {
1244
          detachedObject.eNotify(notification);
1246
		return adapterPolicyManager;
1245
        }
1247
	}
1246
      }
1248
1247
    }
1249
	/**
1248
1250
	 * @since 2.0
1249
    fireInvalidationEvent(timeStamp, Collections.unmodifiableSet(dirtyObjects), Collections
1251
	 */
1250
        .unmodifiableSet(detachedObjects));
1252
	protected AdapterManager createAdapterManager() {
1251
    return conflicts;
1253
		return new AdapterManager();
1252
  }
1254
	}
1253
1255
1254
  public Set<CDOObject> handleInvalidationWithoutNotification(Set<CDOIDAndVersion> dirtyOIDs,
1256
	/**
1255
      Collection<CDOID> detachedOIDs, Set<InternalCDOObject> dirtyObjects, Set<InternalCDOObject> detachedObjects)
1257
	 * @since 2.0
1256
  {
1258
	 */
1257
    Set<CDOObject> conflicts = null;
1259
	public void handleAddAdapter(InternalCDOObject eObject, Adapter adapter) {
1258
    for (CDOIDAndVersion dirtyOID : dirtyOIDs)
1260
		if (!FSMUtil.isNew(eObject)) {
1259
    {
1261
			subscribe(eObject, adapter);
1260
      InternalCDOObject dirtyObject = null;
1262
		}
1261
      // 258831 - Causes deadlock when introduce thread safe mechanisms in State machine.
1263
1262
      synchronized (objects)
1264
		adapterPolicyManager.attachAdapter(eObject, adapter);
1263
      {
1265
	}
1264
        dirtyObject = objects.get(dirtyOID.getID());
1266
1265
      }
1267
	/**
1266
1268
	 * @since 2.0
1267
      if (dirtyObject != null)
1269
	 */
1268
      {
1270
	public void handleRemoveAdapter(InternalCDOObject eObject, Adapter adapter) {
1269
        CDOStateMachine.INSTANCE.invalidate(dirtyObject, dirtyOID.getVersion());
1271
		if (!FSMUtil.isNew(eObject)) {
1270
        dirtyObjects.add(dirtyObject);
1272
			unsubscribe(eObject, adapter);
1271
        if (dirtyObject.cdoConflict())
1273
		}
1272
        {
1274
1273
          if (conflicts == null)
1275
		adapterPolicyManager.detachAdapter(eObject, adapter);
1274
          {
1276
	}
1275
            conflicts = new HashSet<CDOObject>();
1277
1276
          }
1278
	/**
1277
1279
	 * @since 2.0
1278
          conflicts.add(dirtyObject);
1280
	 */
1279
        }
1281
	public void subscribe(EObject eObject, Adapter adapter) {
1280
      }
1282
		changeSubscriptionManager.subscribe(eObject, adapter);
1281
    }
1283
	}
1282
1284
1283
    for (CDOID id : detachedOIDs)
1285
	/**
1284
    {
1286
	 * @since 2.0
1285
      InternalCDOObject detachedObject = removeObject(id);
1287
	 */
1286
      if (detachedObject != null)
1288
	public void unsubscribe(EObject eObject, Adapter adapter) {
1287
      {
1289
		changeSubscriptionManager.unsubscribe(eObject, adapter);
1288
        CDOStateMachine.INSTANCE.detachRemote(detachedObject);
1290
	}
1289
        detachedObjects.add(detachedObject);
1291
1290
        if (detachedObject.cdoConflict())
1292
	/**
1291
        {
1293
	 * @since 2.0
1292
          if (conflicts == null)
1294
	 */
1293
          {
1295
	public boolean hasSubscription(CDOID id) {
1294
            conflicts = new HashSet<CDOObject>();
1296
		return changeSubscriptionManager.getSubcribeObject(id) != null;
1295
          }
1297
	}
1296
1298
1297
          conflicts.add(detachedObject);
1299
	/**
1298
        }
1300
	 * @since 2.0
1299
      }
1301
	 */
1300
    }
1302
	protected ChangeSubscriptionManager getChangeSubscriptionManager() {
1301
1303
		return changeSubscriptionManager;
1302
    return conflicts;
1304
	}
1303
  }
1305
1304
1306
	/**
1305
  /**
1307
	 * Needed for {@link CDOAuditImpl#setTimeStamp(long)}.
1306
   * @since 2.0
1308
	 * 
1307
   */
1309
	 * @since 2.0
1308
  private void fireInvalidationEvent(long timeStamp, Set<? extends CDOObject> dirtyObjects,
1310
	 */
1309
      Set<? extends CDOObject> detachedObjects)
1311
	protected List<InternalCDOObject> getInvalidObjects(long timeStamp) {
1310
  {
1312
		List<InternalCDOObject> result = new ArrayList<InternalCDOObject>();
1311
    if (!dirtyObjects.isEmpty() || !detachedObjects.isEmpty())
1313
		synchronized (objects) {
1312
    {
1314
			for (InternalCDOObject object : objects.values()) {
1313
      IListener[] listeners = getListeners();
1315
				CDORevision revision = object.cdoRevision();
1314
      if (listeners != null)
1316
				if (revision == null) {
1315
      {
1317
					revision = getRevision(object.cdoID(), false);
1316
        fireEvent(new InvalidationEvent(timeStamp, dirtyObjects, detachedObjects), listeners);
1318
				}
1317
      }
1319
1318
    }
1320
				if (revision == null || !revision.isValid(timeStamp)) {
1319
  }
1321
					result.add(object);
1320
1322
				}
1321
  public void fireAdaptersNotifiedEvent(long timeStamp)
1323
			}
1322
  {
1324
		}
1323
    fireEvent(new AdaptersNotifiedEvent(timeStamp));
1325
1324
  }
1326
		return result;
1325
1327
	}
1326
  /**
1328
1327
   * @since 2.0
1329
	public int reload(CDOObject... objects) {
1328
   */
1330
		Collection<InternalCDOObject> internalObjects;
1329
  public void handleChangeSubscription(Collection<CDORevisionDelta> deltas, Collection<CDOID> detachedObjects)
1331
		// TODO Should objects.length == 0 reload *all* objects, too?
1330
  {
1332
		if (objects != null && objects.length != 0) {
1331
    boolean policiesPresent = options().hasChangeSubscriptionPolicies();
1333
			internalObjects = new ArrayList<InternalCDOObject>(objects.length);
1332
    if (!policiesPresent)
1334
			for (CDOObject object : objects) {
1333
    {
1335
				if (object instanceof InternalCDOObject) {
1334
      return;
1336
					internalObjects.add((InternalCDOObject) object);
1335
    }
1337
				}
1336
1338
			}
1337
    if (deltas != null)
1339
		} else {
1338
    {
1340
			synchronized (this.objects) {
1339
      CDONotificationBuilder builder = new CDONotificationBuilder();
1341
				internalObjects = new ArrayList<InternalCDOObject>(this.objects
1340
      for (CDORevisionDelta delta : deltas)
1342
						.values());
1341
      {
1343
			}
1342
        InternalCDOObject object = changeSubscriptionManager.getSubcribeObject(delta.getID());
1344
		}
1343
        if (object != null && object.eNotificationRequired())
1345
1344
        {
1346
		int result = internalObjects.size();
1345
          NotificationImpl notification = builder.buildNotification(object, delta);
1347
		if (result != 0) {
1346
          if (notification != null)
1348
			CDOStateMachine.INSTANCE.reload(internalObjects
1347
          {
1349
					.toArray(new InternalCDOObject[result]));
1348
            notification.dispatch();
1350
		}
1349
          }
1351
1350
        }
1352
		return result;
1351
      }
1353
	}
1352
    }
1354
1353
1355
	public void close() {
1354
    if (detachedObjects != null)
1356
		LifecycleUtil.deactivate(this, OMLogger.Level.DEBUG);
1355
    {
1357
	}
1356
      for (CDOID id : detachedObjects)
1358
1357
      {
1359
	/**
1358
        InternalCDOObject object = changeSubscriptionManager.getSubcribeObject(id);
1360
	 * @since 2.0
1359
        if (object != null && object.eNotificationRequired())
1361
	 */
1360
        {
1362
	public boolean isClosed() {
1361
          NotificationImpl notification = new CDODeltaNotificationImpl(object, CDONotification.DETACH_OBJECT,
1363
		return !isActive();
1362
              Notification.NO_FEATURE_ID, null, null);
1364
	}
1363
          notification.dispatch();
1365
1364
        }
1366
	@Override
1365
      }
1367
	public String toString() {
1366
1368
		return MessageFormat.format("CDOView({0})", viewID); //$NON-NLS-1$
1367
      getChangeSubscriptionManager().handleDetachedObjects(detachedObjects);
1369
	}
1368
    }
1370
1369
  }
1371
	public boolean isAdapterForType(Object type) {
1370
1372
		return type instanceof ResourceSet;
1371
  /**
1373
	}
1372
   * @since 2.0
1374
1373
   */
1375
	public org.eclipse.emf.common.notify.Notifier getTarget() {
1374
  protected ChangeSubscriptionManager createChangeSubscriptionManager()
1376
		return getResourceSet();
1375
  {
1377
	}
1376
    return new ChangeSubscriptionManager(this);
1378
1377
  }
1379
	public void getCDOIDAndVersion(Map<CDOID, CDOIDAndVersion> uniqueObjects,
1378
1380
			Collection<? extends CDOObject> cdoObjects) {
1379
  /**
1381
		for (CDOObject internalCDOObject : cdoObjects) {
1380
   * @since 2.0
1382
			CDORevision cdoRevision = CDOStateMachine.INSTANCE
1381
   */
1383
					.readNoLoad((InternalCDOObject) internalCDOObject);
1382
  public AdapterManager getAdapterManager()
1384
			CDOID cdoId = internalCDOObject.cdoID();
1383
  {
1385
			if (cdoRevision != null && !uniqueObjects.containsKey(cdoId)) {
1384
    return adapterPolicyManager;
1386
				int version = cdoRevision.getVersion();
1385
  }
1387
				uniqueObjects.put(cdoId, CDOIDUtil.createIDAndVersion(cdoId,
1386
1388
						version));
1387
  /**
1389
			}
1388
   * @since 2.0
1390
		}
1389
   */
1391
	}
1390
  protected AdapterManager createAdapterManager()
1392
1391
  {
1393
	/**
1392
    return new AdapterManager();
1394
	 * @since 2.0
1393
  }
1395
	 */
1394
1396
	protected OptionsImpl createOptions() {
1395
  /**
1397
		return new OptionsImpl();
1396
   * @since 2.0
1398
	}
1397
   */
1399
1398
  public void handleAddAdapter(InternalCDOObject eObject, Adapter adapter)
1400
	/**
1399
  {
1401
	 * @since 2.0
1400
    if (!FSMUtil.isNew(eObject))
1402
	 */
1401
    {
1403
	@Override
1402
      subscribe(eObject, adapter);
1404
	protected void doBeforeActivate() throws Exception {
1403
    }
1405
		super.doBeforeActivate();
1404
1406
		checkState(session, "session"); //$NON-NLS-1$
1405
    adapterPolicyManager.attachAdapter(eObject, adapter);
1407
		checkState(viewID > 0, "viewID"); //$NON-NLS-1$
1406
  }
1408
	}
1407
1409
1408
  /**
1410
	/**
1409
   * @since 2.0
1411
	 * @since 2.0
1410
   */
1412
	 */
1411
  public void handleRemoveAdapter(InternalCDOObject eObject, Adapter adapter)
1413
	@Override
1412
  {
1414
	protected void doActivate() throws Exception {
1413
    if (!FSMUtil.isNew(eObject))
1415
		session.getSessionProtocol().openView(getViewID(), getViewType(),
1414
    {
1416
				getTimeStamp());
1415
      unsubscribe(eObject, adapter);
1417
	}
1416
    }
1418
1417
1419
	/**
1418
    adapterPolicyManager.detachAdapter(eObject, adapter);
1420
	 * @since 2.0
1419
  }
1421
	 */
1420
1422
	@Override
1421
  /**
1423
	protected void doDeactivate() throws Exception {
1422
   * @since 2.0
1424
		try {
1423
   */
1425
			session.getSessionProtocol().closeView(getViewID());
1424
  public void subscribe(EObject eObject, Adapter adapter)
1426
		} catch (Exception ex) {
1425
  {
1427
			OM.LOG.error(ex);
1426
    changeSubscriptionManager.subscribe(eObject, adapter);
1428
		}
1427
  }
1429
1428
1430
		try {
1429
  /**
1431
			session.viewDetached(this);
1430
   * @since 2.0
1432
		} catch (Exception ex) {
1431
   */
1433
			OM.LOG.error(ex);
1432
  public void unsubscribe(EObject eObject, Adapter adapter)
1434
		}
1433
  {
1435
1434
    changeSubscriptionManager.unsubscribe(eObject, adapter);
1436
		session = null;
1435
  }
1437
		objects = null;
1436
1438
		store = null;
1437
  /**
1439
		viewSet = null;
1438
   * @since 2.0
1440
		changeSubscriptionManager = null;
1439
   */
1441
		featureAnalyzer = null;
1440
  public boolean hasSubscription(CDOID id)
1442
		lastLookupID = null;
1441
  {
1443
		lastLookupObject = null;
1442
    return changeSubscriptionManager.getSubcribeObject(id) != null;
1444
		options = null;
1443
  }
1445
	}
1444
1446
1445
  /**
1447
	/**
1446
   * @since 2.0
1448
	 * @author Eike Stepper
1447
   */
1449
	 */
1448
  protected ChangeSubscriptionManager getChangeSubscriptionManager()
1450
	protected abstract class Event extends org.eclipse.net4j.util.event.Event
1449
  {
1451
			implements CDOViewEvent {
1450
    return changeSubscriptionManager;
1452
		private static final long serialVersionUID = 1L;
1451
  }
1453
1452
1454
		public Event() {
1453
  /**
1455
			super(CDOViewImpl.this);
1454
   * Needed for {@link CDOAuditImpl#setTimeStamp(long)}.
1456
		}
1455
   * 
1457
1456
   * @since 2.0
1458
		@Override
1457
   */
1459
		public CDOViewImpl getSource() {
1458
  protected List<InternalCDOObject> getInvalidObjects(long timeStamp)
1460
			return (CDOViewImpl) super.getSource();
1459
  {
1461
		}
1460
    List<InternalCDOObject> result = new ArrayList<InternalCDOObject>();
1462
	}
1461
    synchronized (objects)
1463
1462
    {
1464
	/**
1463
      for (InternalCDOObject object : objects.values())
1465
	 * @author Simon McDuff
1464
      {
1466
	 * @since 2.0
1465
        CDORevision revision = object.cdoRevision();
1467
	 */
1466
        if (revision == null)
1468
	protected class AdapterManager {
1467
        {
1469
		private Set<CDOObject> objects = new HashBag<CDOObject>();
1468
          revision = getRevision(object.cdoID(), false);
1470
1469
        }
1471
		public void committedTransaction(CDOTransaction transaction,
1470
1472
				CDOCommitContext commitContext) {
1471
        if (revision == null || !revision.isValid(timeStamp))
1473
			if (options().getStrongReferencePolicy() != CDOAdapterPolicy.NONE) {
1472
        {
1474
				for (CDOObject object : commitContext.getNewObjects().values()) {
1473
          result.add(object);
1475
					attachObject(object);
1474
        }
1476
				}
1475
      }
1477
1476
    }
1478
				for (CDOObject object : commitContext.getNewResources()
1477
1479
						.values()) {
1478
    return result;
1480
					attachObject(object);
1479
  }
1481
				}
1480
1482
1481
  public int reload(CDOObject... objects)
1483
				for (CDOObject object : commitContext.getDetachedObjects()
1482
  {
1484
						.values()) {
1483
    Collection<InternalCDOObject> internalObjects;
1485
					detachObject(object);
1484
    // TODO Should objects.length == 0 reload *all* objects, too?
1486
				}
1485
    if (objects != null && objects.length != 0)
1487
			}
1486
    {
1488
		}
1487
      internalObjects = new ArrayList<InternalCDOObject>(objects.length);
1489
1488
      for (CDOObject object : objects)
1490
		protected synchronized void attachObject(CDOObject object) {
1489
      {
1491
			if (((InternalEObject) object).eNotificationRequired()) {
1490
        if (object instanceof InternalCDOObject)
1492
				CDOAdapterPolicy strongReferencePolicy = options()
1491
        {
1493
						.getStrongReferencePolicy();
1492
          internalObjects.add((InternalCDOObject)object);
1494
				int count = 0;
1493
        }
1495
				for (Adapter adapter : object.eAdapters()) {
1494
      }
1496
					if (strongReferencePolicy.isValid(object, adapter)) {
1495
    }
1497
						count++;
1496
    else
1498
					}
1497
    {
1499
				}
1498
      synchronized (this.objects)
1500
1499
      {
1501
				for (int i = 0; i < count; i++) {
1500
        internalObjects = new ArrayList<InternalCDOObject>(this.objects.values());
1502
					objects.add(object);
1501
      }
1503
				}
1502
    }
1504
			}
1503
1505
		}
1504
    int result = internalObjects.size();
1506
1505
    if (result != 0)
1507
		protected synchronized void detachObject(CDOObject object) {
1506
    {
1508
			while (objects.remove(object)) {
1507
      CDOStateMachine.INSTANCE.reload(internalObjects.toArray(new InternalCDOObject[result]));
1509
				// Do nothing
1508
    }
1510
			}
1509
1511
		}
1510
    return result;
1512
1511
  }
1513
		protected synchronized void attachAdapter(CDOObject object,
1512
1514
				Adapter adapter) {
1513
  public void close()
1515
			if (options().getStrongReferencePolicy().isValid(object, adapter)) {
1514
  {
1516
				objects.add(object);
1515
    LifecycleUtil.deactivate(this, OMLogger.Level.DEBUG);
1517
			}
1516
  }
1518
		}
1517
1519
1518
  /**
1520
		protected synchronized void detachAdapter(CDOObject object,
1519
   * @since 2.0
1521
				Adapter adapter) {
1520
   */
1522
			if (options().getStrongReferencePolicy().isValid(object, adapter)) {
1521
  public boolean isClosed()
1523
				objects.add(object);
1522
  {
1524
			}
1523
    return !isActive();
1525
		}
1524
  }
1526
1525
1527
		public synchronized void reset() {
1526
  @Override
1528
			// Keep the object in memory
1527
  public String toString()
1529
			Set<CDOObject> oldObject = objects;
1528
  {
1530
			objects = new HashBag<CDOObject>();
1529
    return MessageFormat.format("CDOView({0})", viewID); //$NON-NLS-1$
1531
			if (options().getStrongReferencePolicy() != CDOAdapterPolicy.NONE) {
1530
  }
1532
				InternalCDOObject objects[] = getObjectsArray();
1531
1533
				for (int i = 0; i < objects.length; i++) {
1532
  public boolean isAdapterForType(Object type)
1534
					InternalCDOObject object = objects[i];
1533
  {
1535
					attachObject(object);
1534
    return type instanceof ResourceSet;
1536
				}
1535
  }
1537
			}
1536
1538
1537
  public org.eclipse.emf.common.notify.Notifier getTarget()
1539
			oldObject.clear();
1538
  {
1540
		}
1539
    return getResourceSet();
1541
	};
1540
  }
1542
1541
1543
	/**
1542
  public void getCDOIDAndVersion(Map<CDOID, CDOIDAndVersion> uniqueObjects, Collection<? extends CDOObject> cdoObjects)
1544
	 * @author Simon McDuff
1543
  {
1545
	 * @since 2.0
1544
    for (CDOObject internalCDOObject : cdoObjects)
1546
	 */
1545
    {
1547
	protected static class ChangeSubscriptionManager {
1546
      CDORevision cdoRevision = CDOStateMachine.INSTANCE.readNoLoad((InternalCDOObject)internalCDOObject);
1548
		private CDOViewImpl view;
1547
      CDOID cdoId = internalCDOObject.cdoID();
1549
1548
      if (cdoRevision != null && !uniqueObjects.containsKey(cdoId))
1550
		private Map<CDOID, SubscribeEntry> subscriptions = new HashMap<CDOID, SubscribeEntry>();
1549
      {
1551
1550
        int version = cdoRevision.getVersion();
1552
		public ChangeSubscriptionManager(CDOViewImpl view) {
1551
        uniqueObjects.put(cdoId, CDOIDUtil.createIDAndVersion(cdoId, version));
1553
			this.view = view;
1552
      }
1554
		}
1553
    }
1555
1554
  }
1556
		public void committedTransaction(CDOTransaction transaction,
1555
1557
				CDOCommitContext commitContext) {
1556
  /**
1558
			handleNewObjects(commitContext.getNewResources().values());
1557
   * @since 2.0
1559
			handleNewObjects(commitContext.getNewObjects().values());
1558
   */
1560
			handleDetachedObjects(commitContext.getDetachedObjects().keySet());
1559
  protected OptionsImpl createOptions()
1561
		}
1560
  {
1562
1561
    return new OptionsImpl();
1563
		public void subscribe(EObject eObject, Adapter adapter) {
1562
  }
1564
			subscribe(eObject, adapter, 1);
1563
1565
		}
1564
  /**
1566
1565
   * @since 2.0
1567
		public void unsubscribe(EObject eObject, Adapter adapter) {
1566
   */
1568
			subscribe(eObject, adapter, -1);
1567
  @Override
1569
		}
1568
  protected void doBeforeActivate() throws Exception
1570
1569
  {
1571
		/**
1570
    super.doBeforeActivate();
1572
		 * Register to the server all objects from the active list
1571
    checkState(session, "session"); //$NON-NLS-1$
1573
		 */
1572
    checkState(viewID > 0, "viewID"); //$NON-NLS-1$
1574
		protected void notifyChangeSubcriptionPolicy() {
1573
  }
1575
			boolean policiesPresent = view.options()
1574
1576
					.hasChangeSubscriptionPolicies();
1575
  /**
1577
			synchronized (subscriptions) {
1576
   * @since 2.0
1578
				subscriptions.clear();
1577
   */
1579
				List<CDOID> cdoIDs = new ArrayList<CDOID>();
1578
  @Override
1580
				if (policiesPresent) {
1579
  protected void doActivate() throws Exception
1581
					for (InternalCDOObject cdoObject : view.getObjectsArray()) {
1580
  {
1582
						int count = getNumberOfValidAdapter(cdoObject);
1581
    session.getSessionProtocol().openView(getViewID(), getViewType(), getTimeStamp());
1583
						if (count > 0) {
1582
  }
1584
							cdoIDs.add(cdoObject.cdoID());
1583
1585
							addEntry(cdoObject.cdoID(), cdoObject, count);
1584
  /**
1586
						}
1585
   * @since 2.0
1587
					}
1586
   */
1588
				}
1587
  @Override
1589
1588
  protected void doDeactivate() throws Exception
1590
				request(cdoIDs, true, true);
1589
  {
1591
			}
1590
    try
1592
		}
1591
    {
1593
1592
      session.getSessionProtocol().closeView(getViewID());
1594
		protected void handleDetachedObjects(Collection<CDOID> detachedObjects) {
1593
    }
1595
			synchronized (subscriptions) {
1594
    catch (Exception ex)
1596
				for (CDOID id : detachedObjects) {
1595
    {
1597
					SubscribeEntry entry = subscriptions.get(id);
1596
      OM.LOG.error(ex);
1598
					if (entry != null) {
1597
    }
1599
						detachObject(id);
1598
1600
					}
1599
    try
1601
				}
1600
    {
1602
			}
1601
      session.viewDetached(this);
1603
		}
1602
    }
1604
1603
    catch (Exception ex)
1605
		protected void handleNewObjects(
1604
    {
1606
				Collection<? extends CDOObject> newObjects) {
1605
      OM.LOG.error(ex);
1607
			synchronized (subscriptions) {
1606
    }
1608
				for (CDOObject object : newObjects) {
1607
1609
					InternalCDOObject cdoDetachedObject = (InternalCDOObject) object;
1608
    session = null;
1610
					if (cdoDetachedObject != null) {
1609
    objects = null;
1611
						int count = getNumberOfValidAdapter(cdoDetachedObject);
1610
    store = null;
1612
						if (count > 0) {
1611
    viewSet = null;
1613
							subscribe(cdoDetachedObject.cdoID(),
1612
    changeSubscriptionManager = null;
1614
									cdoDetachedObject, count);
1613
    featureAnalyzer = null;
1615
						}
1614
    lastLookupID = null;
1616
					}
1615
    lastLookupObject = null;
1617
				}
1616
    options = null;
1618
			}
1617
  }
1619
		}
1618
1620
1619
  /**
1621
		protected InternalCDOObject getSubcribeObject(CDOID id) {
1620
   * @author Eike Stepper
1622
			synchronized (subscriptions) {
1621
   */
1623
				SubscribeEntry entry = subscriptions.get(id);
1622
  protected abstract class Event extends org.eclipse.net4j.util.event.Event implements CDOViewEvent
1624
				if (entry != null) {
1623
  {
1625
					return entry.getObject();
1624
    private static final long serialVersionUID = 1L;
1626
				}
1625
1627
			}
1626
    public Event()
1628
1627
    {
1629
			return null;
1628
      super(CDOViewImpl.this);
1630
		}
1629
    }
1631
1630
1632
		protected void request(List<CDOID> ids, boolean clear,
1631
    @Override
1633
				boolean subscribeMode) {
1632
    public CDOViewImpl getSource()
1634
			view.session.getSessionProtocol().changeSubscription(
1633
    {
1635
					view.getViewID(), ids, subscribeMode, clear);
1634
      return (CDOViewImpl)super.getSource();
1636
		}
1635
    }
1637
1636
  }
1638
		protected int getNumberOfValidAdapter(InternalCDOObject object) {
1637
1639
			int count = 0;
1638
  /**
1640
			if (!FSMUtil.isTransient(object) && !FSMUtil.isNew(object)) {
1639
   * @author Simon McDuff
1641
				if (object.eNotificationRequired()) {
1640
   * @since 2.0
1642
					for (Adapter adapter : object.eAdapters()) {
1641
   */
1643
						if (shouldSubscribe(object, adapter)) {
1642
  protected class AdapterManager
1644
							count++;
1643
  {
1645
						}
1644
    private Set<CDOObject> objects = new HashBag<CDOObject>();
1646
					}
1645
1647
				}
1646
    public void committedTransaction(CDOTransaction transaction, CDOCommitContext commitContext)
1648
			}
1647
    {
1649
1648
      if (options().getStrongReferencePolicy() != CDOAdapterPolicy.NONE)
1650
			return count;
1649
      {
1651
		}
1650
        for (CDOObject object : commitContext.getNewObjects().values())
1652
1651
        {
1653
		private void subscribe(EObject eObject, Adapter adapter, int adjust) {
1652
          attachObject(object);
1654
			synchronized (subscriptions) {
1653
        }
1655
				if (shouldSubscribe(eObject, adapter)) {
1654
1656
					InternalCDOObject internalCDOObject = FSMUtil.adapt(
1655
        for (CDOObject object : commitContext.getNewResources().values())
1657
							eObject, view);
1656
        {
1658
					if (internalCDOObject.cdoView() != view) {
1657
          attachObject(object);
1659
						throw new CDOException(
1658
        }
1660
								MessageFormat
1659
1661
										.format(
1660
        for (CDOObject object : commitContext.getDetachedObjects().values())
1662
												Messages
1661
        {
1663
														.getString("CDOViewImpl.27"), internalCDOObject)); //$NON-NLS-1$
1662
          detachObject(object);
1664
					}
1663
        }
1665
1664
      }
1666
					subscribe(internalCDOObject.cdoID(), internalCDOObject,
1665
    }
1667
							adjust);
1666
1668
				}
1667
    protected synchronized void attachObject(CDOObject object)
1669
			}
1668
    {
1670
		}
1669
      if (((InternalEObject)object).eNotificationRequired())
1671
1670
      {
1672
		private boolean shouldSubscribe(EObject eObject, Adapter adapter) {
1671
        CDOAdapterPolicy strongReferencePolicy = options().getStrongReferencePolicy();
1673
			for (CDOAdapterPolicy policy : view.options()
1672
        int count = 0;
1674
					.getChangeSubscriptionPolicies()) {
1673
        for (Adapter adapter : object.eAdapters())
1675
				if (policy.isValid(eObject, adapter)) {
1674
        {
1676
					return true;
1675
          if (strongReferencePolicy.isValid(object, adapter))
1677
				}
1676
          {
1678
			}
1677
            count++;
1679
1678
          }
1680
			return false;
1679
        }
1681
		}
1680
1682
1681
        for (int i = 0; i < count; i++)
1683
		private void subscribe(CDOID id, InternalCDOObject cdoObject, int adjust) {
1682
        {
1684
			boolean policiesPresent = view.options()
1683
          objects.add(object);
1685
					.hasChangeSubscriptionPolicies();
1684
        }
1686
			synchronized (subscriptions) {
1685
      }
1687
				int count = 0;
1686
    }
1688
				SubscribeEntry entry = subscriptions.get(id);
1687
1689
				if (entry == null) {
1688
    protected synchronized void detachObject(CDOObject object)
1690
					// Cannot adjust negative value
1689
    {
1691
					if (adjust < 0) {
1690
      while (objects.remove(object))
1692
						return;
1691
      {
1693
					}
1692
        // Do nothing
1694
1693
      }
1695
					// Notification need to be enable to send correct value to
1694
    }
1696
					// the server
1695
1697
					if (policiesPresent) {
1696
    protected synchronized void attachAdapter(CDOObject object, Adapter adapter)
1698
						request(Collections.singletonList(id), false, true);
1697
    {
1699
					}
1698
      if (options().getStrongReferencePolicy().isValid(object, adapter))
1700
				} else {
1699
      {
1701
					count = entry.getCount();
1700
        objects.add(object);
1702
				}
1701
      }
1703
1702
    }
1704
				count += adjust;
1703
1705
1704
    protected synchronized void detachAdapter(CDOObject object, Adapter adapter)
1706
				// Look if objects need to be unsubscribe
1705
    {
1707
				if (count <= 0) {
1706
      if (options().getStrongReferencePolicy().isValid(object, adapter))
1708
					subscriptions.remove(id);
1707
      {
1709
1708
        objects.add(object);
1710
					// Notification need to be enable to send correct value to
1709
      }
1711
					// the server
1710
    }
1712
					if (policiesPresent) {
1711
1713
						request(Collections.singletonList(id), false, false);
1712
    public synchronized void reset()
1714
					}
1713
    {
1715
				} else {
1714
      // Keep the object in memory
1716
					if (entry == null) {
1715
      Set<CDOObject> oldObject = objects;
1717
						addEntry(id, cdoObject, count);
1716
      objects = new HashBag<CDOObject>();
1718
					} else {
1717
      if (options().getStrongReferencePolicy() != CDOAdapterPolicy.NONE)
1719
						entry.setCount(count);
1718
      {
1720
					}
1719
        InternalCDOObject objects[] = getObjectsArray();
1721
				}
1720
        for (int i = 0; i < objects.length; i++)
1722
			}
1721
        {
1723
		}
1722
          InternalCDOObject object = objects[i];
1724
1723
          attachObject(object);
1725
		private void detachObject(CDOID id) {
1724
        }
1726
			subscribe(id, null, Integer.MIN_VALUE);
1725
      }
1727
		}
1726
1728
1727
      oldObject.clear();
1729
		private void addEntry(CDOID key, InternalCDOObject object, int count) {
1728
    }
1730
			subscriptions.put(key, new SubscribeEntry(object, count));
1729
  };
1731
		}
1730
1732
1731
  /**
1733
		/**
1732
   * @author Simon McDuff
1734
		 * @author Eike Stepper
1733
   * @since 2.0
1735
		 */
1734
   */
1736
		protected static final class SubscribeEntry {
1735
  protected static class ChangeSubscriptionManager
1737
			private int count;
1736
  {
1738
1737
    private CDOViewImpl view;
1739
			private InternalCDOObject object;
1738
1740
1739
    private Map<CDOID, SubscribeEntry> subscriptions = new HashMap<CDOID, SubscribeEntry>();
1741
			public SubscribeEntry(InternalCDOObject object, int count) {
1740
1742
				this.count = count;
1741
    public ChangeSubscriptionManager(CDOViewImpl view)
1743
				this.object = object;
1742
    {
1744
			}
1743
      this.view = view;
1745
1744
    }
1746
			public InternalCDOObject getObject() {
1745
1747
				return object;
1746
    public void committedTransaction(CDOTransaction transaction, CDOCommitContext commitContext)
1748
			}
1747
    {
1749
1748
      handleNewObjects(commitContext.getNewResources().values());
1750
			public int getCount() {
1749
      handleNewObjects(commitContext.getNewObjects().values());
1751
				return count;
1750
      handleDetachedObjects(commitContext.getDetachedObjects().keySet());
1752
			}
1751
    }
1753
1752
1754
			public void setCount(int count) {
1753
    public void subscribe(EObject eObject, Adapter adapter)
1755
				this.count = count;
1754
    {
1756
			}
1755
      subscribe(eObject, adapter, 1);
1757
		}
1756
    }
1758
	}
1757
1759
1758
    public void unsubscribe(EObject eObject, Adapter adapter)
1760
	/**
1759
    {
1761
	 * @author Simon McDuff
1760
      subscribe(eObject, adapter, -1);
1762
	 */
1761
    }
1763
	private final class InvalidationEvent extends Event implements
1762
1764
			CDOViewInvalidationEvent {
1763
    /**
1765
		private static final long serialVersionUID = 1L;
1764
     * Register to the server all objects from the active list
1766
1765
     */
1767
		private long timeStamp;
1766
    protected void notifyChangeSubcriptionPolicy()
1768
1767
    {
1769
		private Set<? extends CDOObject> dirtyObjects;
1768
      boolean policiesPresent = view.options().hasChangeSubscriptionPolicies();
1770
1769
      synchronized (subscriptions)
1771
		private Set<? extends CDOObject> detachedObjects;
1770
      {
1772
1771
        subscriptions.clear();
1773
		public InvalidationEvent(long timeStamp,
1772
        List<CDOID> cdoIDs = new ArrayList<CDOID>();
1774
				Set<? extends CDOObject> dirtyOIDs,
1773
        if (policiesPresent)
1775
				Set<? extends CDOObject> detachedObjects) {
1774
        {
1776
			this.timeStamp = timeStamp;
1775
          for (InternalCDOObject cdoObject : view.getObjectsArray())
1777
			dirtyObjects = dirtyOIDs;
1776
          {
1778
			this.detachedObjects = detachedObjects;
1777
            int count = getNumberOfValidAdapter(cdoObject);
1779
		}
1778
            if (count > 0)
1780
1779
            {
1781
		public long getTimeStamp() {
1780
              cdoIDs.add(cdoObject.cdoID());
1782
			return timeStamp;
1781
              addEntry(cdoObject.cdoID(), cdoObject, count);
1783
		}
1782
            }
1784
1783
          }
1785
		public Set<? extends CDOObject> getDirtyObjects() {
1784
        }
1786
			return dirtyObjects;
1785
1787
		}
1786
        request(cdoIDs, true, true);
1788
1787
      }
1789
		public Set<? extends CDOObject> getDetachedObjects() {
1788
    }
1790
			return detachedObjects;
1789
1791
		}
1790
    protected void handleDetachedObjects(Collection<CDOID> detachedObjects)
1792
1791
    {
1793
		@Override
1792
      synchronized (subscriptions)
1794
		public String toString() {
1793
      {
1795
			return "CDOViewInvalidationEvent: " + dirtyObjects; //$NON-NLS-1$
1794
        for (CDOID id : detachedObjects)
1796
		}
1795
        {
1797
	}
1796
          SubscribeEntry entry = subscriptions.get(id);
1798
1797
          if (entry != null)
1799
	/**
1798
          {
1800
	 * @author Eike Stepper
1799
            detachObject(id);
1801
	 */
1800
          }
1802
	private final class AdaptersNotifiedEvent extends Event implements
1801
        }
1803
			CDOViewAdaptersNotifiedEvent {
1802
      }
1804
		private static final long serialVersionUID = 1L;
1803
    }
1805
1804
1806
		private long timeStamp;
1805
    protected void handleNewObjects(Collection<? extends CDOObject> newObjects)
1807
1806
    {
1808
		public AdaptersNotifiedEvent(long timeStamp) {
1807
      synchronized (subscriptions)
1809
			this.timeStamp = timeStamp;
1808
      {
1810
		}
1809
        for (CDOObject object : newObjects)
1811
1810
        {
1812
		public long getTimeStamp() {
1811
          InternalCDOObject cdoDetachedObject = (InternalCDOObject)object;
1813
			return timeStamp;
1812
          if (cdoDetachedObject != null)
1814
		}
1813
          {
1815
1814
            int count = getNumberOfValidAdapter(cdoDetachedObject);
1816
		@Override
1815
            if (count > 0)
1817
		public String toString() {
1816
            {
1818
			return "CDOViewAdaptersNotifiedEvent: " + timeStamp; //$NON-NLS-1$
1817
              subscribe(cdoDetachedObject.cdoID(), cdoDetachedObject, count);
1819
		}
1818
            }
1820
	}
1819
          }
1821
1820
        }
1822
	/**
1821
      }
1823
	 * @author Eike Stepper
1822
    }
1824
	 * @since 2.0
1823
1825
	 */
1824
    protected InternalCDOObject getSubcribeObject(CDOID id)
1826
	protected class OptionsImpl extends Notifier implements Options {
1825
    {
1827
		private boolean invalidationNotificationEnabled;
1826
      synchronized (subscriptions)
1828
1827
      {
1829
		private CDORevisionPrefetchingPolicy revisionPrefetchingPolicy;
1828
        SubscribeEntry entry = subscriptions.get(id);
1830
1829
        if (entry != null)
1831
		private CDOStaleReferencePolicy staleReferencePolicy = CDOStaleReferencePolicy.EXCEPTION;
1830
        {
1832
1831
          return entry.getObject();
1833
		private HashBag<CDOAdapterPolicy> changeSubscriptionPolicies = new HashBag<CDOAdapterPolicy>();
1832
        }
1834
1833
      }
1835
		private CDOAdapterPolicy strongReferencePolicy = CDOAdapterPolicy.ALL;
1834
1836
1835
      return null;
1837
		public OptionsImpl() {
1836
    }
1838
			setCacheReferenceType(null);
1837
1839
			invalidationNotificationEnabled = OM.PREF_ENABLE_INVALIDATION_NOTIFICATION
1838
    protected void request(List<CDOID> ids, boolean clear, boolean subscribeMode)
1840
					.getValue();
1839
    {
1841
			revisionPrefetchingPolicy = CDOUtil
1840
      view.session.getSessionProtocol().changeSubscription(view.getViewID(), ids, subscribeMode, clear);
1842
					.createRevisionPrefetchingPolicy(OM.PREF_REVISION_LOADING_CHUNK_SIZE
1841
    }
1843
							.getValue());
1842
1844
		}
1843
    protected int getNumberOfValidAdapter(InternalCDOObject object)
1845
1844
    {
1846
		public CDOViewImpl getContainer() {
1845
      int count = 0;
1847
			return CDOViewImpl.this;
1846
      if (!FSMUtil.isTransient(object) && !FSMUtil.isNew(object))
1848
		}
1847
      {
1849
1848
        if (object.eNotificationRequired())
1850
		public boolean isInvalidationNotificationEnabled() {
1849
        {
1851
			return invalidationNotificationEnabled;
1850
          for (Adapter adapter : object.eAdapters())
1852
		}
1851
          {
1853
1852
            if (shouldSubscribe(object, adapter))
1854
		public void setInvalidationNotificationEnabled(boolean enabled) {
1853
            {
1855
			if (invalidationNotificationEnabled != enabled) {
1854
              count++;
1856
				invalidationNotificationEnabled = enabled;
1855
            }
1857
				IListener[] listeners = getListeners();
1856
          }
1858
				if (listeners != null) {
1857
        }
1859
					fireEvent(new InvalidationNotificationEventImpl(),
1858
      }
1860
							listeners);
1859
1861
				}
1860
      return count;
1862
			}
1861
    }
1863
		}
1862
1864
1863
    private void subscribe(EObject eObject, Adapter adapter, int adjust)
1865
		public boolean hasChangeSubscriptionPolicies() {
1864
    {
1866
			synchronized (changeSubscriptionPolicies) {
1865
      synchronized (subscriptions)
1867
				return !changeSubscriptionPolicies.isEmpty();
1866
      {
1868
			}
1867
        if (shouldSubscribe(eObject, adapter))
1869
		}
1868
        {
1870
1869
          InternalCDOObject internalCDOObject = FSMUtil.adapt(eObject, view);
1871
		public CDOAdapterPolicy[] getChangeSubscriptionPolicies() {
1870
          if (internalCDOObject.cdoView() != view)
1872
			synchronized (changeSubscriptionPolicies) {
1871
          {
1873
				return changeSubscriptionPolicies
1872
            throw new CDOException(MessageFormat.format(Messages.getString("CDOViewImpl.27"), internalCDOObject)); //$NON-NLS-1$
1874
						.toArray(new CDOAdapterPolicy[changeSubscriptionPolicies
1873
          }
1875
								.size()]);
1874
1876
			}
1875
          subscribe(internalCDOObject.cdoID(), internalCDOObject, adjust);
1877
		}
1876
        }
1878
1877
      }
1879
		public void addChangeSubscriptionPolicy(CDOAdapterPolicy policy) {
1878
    }
1880
			boolean changed = false;
1879
1881
			synchronized (changeSubscriptionPolicies) {
1880
    private boolean shouldSubscribe(EObject eObject, Adapter adapter)
1882
				if (changeSubscriptionPolicies.add(policy)) {
1881
    {
1883
					changeSubscriptionManager.notifyChangeSubcriptionPolicy();
1882
      for (CDOAdapterPolicy policy : view.options().getChangeSubscriptionPolicies())
1884
					changed = true;
1883
      {
1885
				}
1884
        if (policy.isValid(eObject, adapter))
1886
			}
1885
        {
1887
1886
          return true;
1888
			if (changed) {
1887
        }
1889
				IListener[] listeners = getListeners();
1888
      }
1890
				if (listeners != null) {
1889
1891
					fireEvent(new ChangeSubscriptionPoliciesEventImpl(),
1890
      return false;
1892
							listeners);
1891
    }
1893
				}
1892
1894
			}
1893
    private void subscribe(CDOID id, InternalCDOObject cdoObject, int adjust)
1895
		}
1894
    {
1896
1895
      boolean policiesPresent = view.options().hasChangeSubscriptionPolicies();
1897
		public void removeChangeSubscriptionPolicy(CDOAdapterPolicy policy) {
1896
      synchronized (subscriptions)
1898
			boolean changed = false;
1897
      {
1899
			synchronized (changeSubscriptionPolicies) {
1898
        int count = 0;
1900
				if (changeSubscriptionPolicies.remove(policy)
1899
        SubscribeEntry entry = subscriptions.get(id);
1901
						&& !changeSubscriptionPolicies.contains(policy)) {
1900
        if (entry == null)
1902
					changeSubscriptionManager.notifyChangeSubcriptionPolicy();
1901
        {
1903
					changed = true;
1902
          // Cannot adjust negative value
1904
				}
1903
          if (adjust < 0)
1905
			}
1904
          {
1906
1905
            return;
1907
			if (changed) {
1906
          }
1908
				IListener[] listeners = getListeners();
1907
1909
				if (listeners != null) {
1908
          // Notification need to be enable to send correct value to the server
1910
					fireEvent(new ChangeSubscriptionPoliciesEventImpl(),
1909
          if (policiesPresent)
1911
							listeners);
1910
          {
1912
				}
1911
            request(Collections.singletonList(id), false, true);
1913
			}
1912
          }
1914
		}
1913
        }
1915
1914
        else
1916
		public CDOAdapterPolicy getStrongReferencePolicy() {
1915
        {
1917
			return strongReferencePolicy;
1916
          count = entry.getCount();
1918
		}
1917
        }
1919
1918
1920
		public void setStrongReferencePolicy(CDOAdapterPolicy adapterPolicy) {
1919
        count += adjust;
1921
			if (adapterPolicy == null) {
1920
1922
				adapterPolicy = CDOAdapterPolicy.ALL;
1921
        // Look if objects need to be unsubscribe
1923
			}
1922
        if (count <= 0)
1924
1923
        {
1925
			if (strongReferencePolicy != adapterPolicy) {
1924
          subscriptions.remove(id);
1926
				strongReferencePolicy = adapterPolicy;
1925
1927
				adapterPolicyManager.reset();
1926
          // Notification need to be enable to send correct value to the server
1928
				IListener[] listeners = getListeners();
1927
          if (policiesPresent)
1929
				if (listeners != null) {
1928
          {
1930
					fireEvent(new ReferencePolicyEventImpl(), listeners);
1929
            request(Collections.singletonList(id), false, false);
1931
				}
1930
          }
1932
			}
1931
        }
1933
		}
1932
        else
1934
1933
        {
1935
		public CDORevisionPrefetchingPolicy getRevisionPrefetchingPolicy() {
1934
          if (entry == null)
1936
			return revisionPrefetchingPolicy;
1935
          {
1937
		}
1936
            addEntry(id, cdoObject, count);
1938
1937
          }
1939
		public void setRevisionPrefetchingPolicy(
1938
          else
1940
				CDORevisionPrefetchingPolicy prefetchingPolicy) {
1939
          {
1941
			if (prefetchingPolicy == null) {
1940
            entry.setCount(count);
1942
				prefetchingPolicy = CDORevisionPrefetchingPolicy.NO_PREFETCHING;
1941
          }
1943
			}
1942
        }
1944
1943
      }
1945
			if (revisionPrefetchingPolicy != prefetchingPolicy) {
1944
    }
1946
				revisionPrefetchingPolicy = prefetchingPolicy;
1945
1947
				IListener[] listeners = getListeners();
1946
    private void detachObject(CDOID id)
1948
				if (listeners != null) {
1947
    {
1949
					fireEvent(new RevisionPrefetchingPolicyEventImpl(),
1948
      subscribe(id, null, Integer.MIN_VALUE);
1950
							listeners);
1949
    }
1951
				}
1950
1952
			}
1951
    private void addEntry(CDOID key, InternalCDOObject object, int count)
1953
		}
1952
    {
1954
1953
      subscriptions.put(key, new SubscribeEntry(object, count));
1955
		public CDOStaleReferencePolicy getStaleReferenceBehaviour() {
1954
    }
1956
			return staleReferencePolicy;
1955
1957
		}
1956
    /**
1958
1957
     * @author Eike Stepper
1959
		public void setStaleReferenceBehaviour(CDOStaleReferencePolicy policy) {
1958
     */
1960
			if (policy == null) {
1959
    protected static final class SubscribeEntry
1961
				policy = CDOStaleReferencePolicy.EXCEPTION;
1960
    {
1962
			}
1961
      private int count;
1963
1962
1964
			if (staleReferencePolicy != policy) {
1963
      private InternalCDOObject object;
1965
				staleReferencePolicy = policy;
1964
1966
				IListener[] listeners = getListeners();
1965
      public SubscribeEntry(InternalCDOObject object, int count)
1967
				if (listeners != null) {
1966
      {
1968
					fireEvent(new StaleReferencePolicyEventImpl(), listeners);
1967
        this.count = count;
1969
				}
1968
        this.object = object;
1970
			}
1969
      }
1971
		}
1970
1972
1971
      public InternalCDOObject getObject()
1973
		public ReferenceType getCacheReferenceType() {
1972
      {
1974
			if (objects instanceof ReferenceValueMap.Strong<?, ?>) {
1973
        return object;
1975
				return ReferenceType.STRONG;
1974
      }
1976
			}
1975
1977
1976
      public int getCount()
1978
			if (objects instanceof ReferenceValueMap.Soft<?, ?>) {
1977
      {
1979
				return ReferenceType.SOFT;
1978
        return count;
1980
			}
1979
      }
1981
1980
1982
			if (objects instanceof ReferenceValueMap.Weak<?, ?>) {
1981
      public void setCount(int count)
1983
				return ReferenceType.WEAK;
1982
      {
1984
			}
1983
        this.count = count;
1985
1984
      }
1986
			throw new IllegalStateException(Messages
1985
    }
1987
					.getString("CDOViewImpl.29")); //$NON-NLS-1$
1986
  }
1988
		}
1987
1989
1988
  /**
1990
		public boolean setCacheReferenceType(ReferenceType referenceType) {
1989
   * @author Simon McDuff
1991
			if (referenceType == null) {
1990
   */
1992
				referenceType = ReferenceType.SOFT;
1991
  private final class InvalidationEvent extends Event implements CDOViewInvalidationEvent
1993
			}
1992
  {
1994
1993
    private static final long serialVersionUID = 1L;
1995
			ReferenceValueMap<CDOID, InternalCDOObject> newObjects;
1994
1996
			switch (referenceType) {
1995
    private long timeStamp;
1997
			case STRONG:
1996
1998
				if (objects instanceof ReferenceValueMap.Strong<?, ?>) {
1997
    private Set<? extends CDOObject> dirtyObjects;
1999
					return false;
1998
2000
				}
1999
    private Set<? extends CDOObject> detachedObjects;
2001
2000
2002
				newObjects = new ReferenceValueMap.Strong<CDOID, InternalCDOObject>();
2001
    public InvalidationEvent(long timeStamp, Set<? extends CDOObject> dirtyOIDs,
2003
				break;
2002
        Set<? extends CDOObject> detachedObjects)
2004
2003
    {
2005
			case SOFT:
2004
      this.timeStamp = timeStamp;
2006
				if (objects instanceof ReferenceValueMap.Soft<?, ?>) {
2005
      dirtyObjects = dirtyOIDs;
2007
					return false;
2006
      this.detachedObjects = detachedObjects;
2008
				}
2007
    }
2009
2008
2010
				newObjects = new ReferenceValueMap.Soft<CDOID, InternalCDOObject>();
2009
    public long getTimeStamp()
2011
				break;
2010
    {
2012
2011
      return timeStamp;
2013
			case WEAK:
2012
    }
2014
				if (objects instanceof ReferenceValueMap.Weak<?, ?>) {
2013
2015
					return false;
2014
    public Set<? extends CDOObject> getDirtyObjects()
2016
				}
2015
    {
2017
2016
      return dirtyObjects;
2018
				newObjects = new ReferenceValueMap.Weak<CDOID, InternalCDOObject>();
2017
    }
2019
				break;
2018
2020
2019
    public Set<? extends CDOObject> getDetachedObjects()
2021
			default:
2020
    {
2022
				throw new IllegalArgumentException(Messages
2021
      return detachedObjects;
2023
						.getString("CDOViewImpl.29")); //$NON-NLS-1$
2022
    }
2024
			}
2023
2025
2024
    @Override
2026
			if (objects == null) {
2025
    public String toString()
2027
				objects = newObjects;
2026
    {
2028
				IListener[] listeners = getListeners();
2027
      return "CDOViewInvalidationEvent: " + dirtyObjects; //$NON-NLS-1$
2029
				if (listeners != null) {
2028
    }
2030
					fireEvent(new CacheReferenceTypeEventImpl(), listeners);
2029
  }
2031
				}
2030
2032
2031
  /**
2033
				return true;
2032
   * @author Eike Stepper
2034
			}
2033
   */
2035
2034
  private final class AdaptersNotifiedEvent extends Event implements CDOViewAdaptersNotifiedEvent
2036
			for (Entry<CDOID, InternalCDOObject> entry : objects.entrySet()) {
2035
  {
2037
				InternalCDOObject object = entry.getValue();
2036
    private static final long serialVersionUID = 1L;
2038
				if (object != null) {
2037
2039
					newObjects.put(entry.getKey(), object);
2038
    private long timeStamp;
2040
				}
2039
2041
			}
2040
    public AdaptersNotifiedEvent(long timeStamp)
2042
2041
    {
2043
			ConcurrentMap<CDOID, InternalCDOObject> oldObjects = objects;
2042
      this.timeStamp = timeStamp;
2044
			synchronized (objects) {
2043
    }
2045
				objects = newObjects;
2044
2046
			}
2045
    public long getTimeStamp()
2047
2046
    {
2048
			oldObjects.clear();
2047
      return timeStamp;
2049
			IListener[] listeners = getListeners();
2048
    }
2050
			if (listeners != null) {
2049
2051
				fireEvent(new CacheReferenceTypeEventImpl(), listeners);
2050
    @Override
2052
			}
2051
    public String toString()
2053
2052
    {
2054
			return true;
2053
      return "CDOViewAdaptersNotifiedEvent: " + timeStamp; //$NON-NLS-1$
2055
		}
2054
    }
2056
2055
  }
2057
		/**
2056
2058
		 * @author Eike Stepper
2057
  /**
2059
		 */
2058
   * @author Eike Stepper
2060
		private final class CacheReferenceTypeEventImpl extends OptionsEvent
2059
   * @since 2.0
2061
				implements CacheReferenceTypeEvent {
2060
   */
2062
			private static final long serialVersionUID = 1L;
2061
  protected class OptionsImpl extends Notifier implements Options
2063
2062
  {
2064
			public CacheReferenceTypeEventImpl() {
2063
    private boolean invalidationNotificationEnabled;
2065
				super(OptionsImpl.this);
2064
2066
			}
2065
    private CDORevisionPrefetchingPolicy revisionPrefetchingPolicy;
2067
		}
2066
2068
2067
    private CDOStaleReferencePolicy staleReferencePolicy = CDOStaleReferencePolicy.EXCEPTION;
2069
		/**
2068
2070
		 * @author Eike Stepper
2069
    private HashBag<CDOAdapterPolicy> changeSubscriptionPolicies = new HashBag<CDOAdapterPolicy>();
2071
		 */
2070
2072
		private final class ChangeSubscriptionPoliciesEventImpl extends
2071
    private CDOAdapterPolicy strongReferencePolicy = CDOAdapterPolicy.ALL;
2073
				OptionsEvent implements ChangeSubscriptionPoliciesEvent {
2072
2074
			private static final long serialVersionUID = 1L;
2073
    public OptionsImpl()
2075
2074
    {
2076
			public ChangeSubscriptionPoliciesEventImpl() {
2075
      setCacheReferenceType(null);
2077
				super(OptionsImpl.this);
2076
      invalidationNotificationEnabled = OM.PREF_ENABLE_INVALIDATION_NOTIFICATION.getValue();
2078
			}
2077
      revisionPrefetchingPolicy = CDOUtil.createRevisionPrefetchingPolicy(OM.PREF_REVISION_LOADING_CHUNK_SIZE
2079
		}
2078
          .getValue());
2080
2079
    }
2081
		/**
2080
2082
		 * @author Eike Stepper
2081
    public CDOViewImpl getContainer()
2083
		 */
2082
    {
2084
		private final class InvalidationNotificationEventImpl extends
2083
      return CDOViewImpl.this;
2085
				OptionsEvent implements InvalidationNotificationEvent {
2084
    }
2086
			private static final long serialVersionUID = 1L;
2085
2087
2086
    public boolean isInvalidationNotificationEnabled()
2088
			public InvalidationNotificationEventImpl() {
2087
    {
2089
				super(OptionsImpl.this);
2088
      return invalidationNotificationEnabled;
2090
			}
2089
    }
2091
		}
2090
2092
2091
    public void setInvalidationNotificationEnabled(boolean enabled)
2093
		/**
2092
    {
2094
		 * @author Eike Stepper
2093
      if (invalidationNotificationEnabled != enabled)
2095
		 */
2094
      {
2096
		private final class RevisionPrefetchingPolicyEventImpl extends
2095
        invalidationNotificationEnabled = enabled;
2097
				OptionsEvent implements RevisionPrefetchingPolicyEvent {
2096
        IListener[] listeners = getListeners();
2098
			private static final long serialVersionUID = 1L;
2097
        if (listeners != null)
2099
2098
        {
2100
			public RevisionPrefetchingPolicyEventImpl() {
2099
          fireEvent(new InvalidationNotificationEventImpl(), listeners);
2101
				super(OptionsImpl.this);
2100
        }
2102
			}
2101
      }
2103
		}
2102
    }
2104
2103
2105
		/**
2104
    public boolean hasChangeSubscriptionPolicies()
2106
		 * @author Eike Stepper
2105
    {
2107
		 */
2106
      synchronized (changeSubscriptionPolicies)
2108
		private final class ReferencePolicyEventImpl extends OptionsEvent
2107
      {
2109
				implements ReferencePolicyEvent {
2108
        return !changeSubscriptionPolicies.isEmpty();
2110
			private static final long serialVersionUID = 1L;
2109
      }
2111
2110
    }
2112
			public ReferencePolicyEventImpl() {
2111
2113
				super(OptionsImpl.this);
2112
    public CDOAdapterPolicy[] getChangeSubscriptionPolicies()
2114
			}
2113
    {
2115
		}
2114
      synchronized (changeSubscriptionPolicies)
2116
2115
      {
2117
		/**
2116
        return changeSubscriptionPolicies.toArray(new CDOAdapterPolicy[changeSubscriptionPolicies.size()]);
2118
		 * @author Simon McDuff
2117
      }
2119
		 */
2118
    }
2120
		private final class StaleReferencePolicyEventImpl extends OptionsEvent
2119
2121
				implements StaleReferencePolicyEvent {
2120
    public void addChangeSubscriptionPolicy(CDOAdapterPolicy policy)
2122
			private static final long serialVersionUID = 1L;
2121
    {
2123
2122
      boolean changed = false;
2124
			public StaleReferencePolicyEventImpl() {
2123
      synchronized (changeSubscriptionPolicies)
2125
				super(OptionsImpl.this);
2124
      {
2126
			}
2125
        if (changeSubscriptionPolicies.add(policy))
2127
		}
2126
        {
2128
	}
2127
          changeSubscriptionManager.notifyChangeSubcriptionPolicy();
2129
2128
          changed = true;
2130
	/**
2129
        }
2131
	 * @author Juan Pedro Silva
2130
      }
2132
	 */
2131
2133
	private boolean hasRegisteredListeners = false;
2132
      if (changed)
2134
2133
      {
2135
	/**
2134
        IListener[] listeners = getListeners();
2136
	 * @author Juan Pedro Silva
2135
        if (listeners != null)
2137
	 */
2136
        {
2138
	protected FastList<IListener> registeredLockListeners = new FastList<IListener>() {
2137
          fireEvent(new ChangeSubscriptionPoliciesEventImpl(), listeners);
2139
		@Override
2138
        }
2140
		protected IListener[] newArray(int length) {
2139
      }
2141
			return new IListener[length];
2140
    }
2142
		}
2141
2143
2142
    public void removeChangeSubscriptionPolicy(CDOAdapterPolicy policy)
2144
		@Override
2143
    {
2145
		protected void firstElementAdded() {
2144
      boolean changed = false;
2146
			firstListenerAdded();
2145
      synchronized (changeSubscriptionPolicies)
2147
		}
2146
      {
2148
2147
        if (changeSubscriptionPolicies.remove(policy) && !changeSubscriptionPolicies.contains(policy))
2149
		@Override
2148
        {
2150
		protected void lastElementRemoved() {
2149
          changeSubscriptionManager.notifyChangeSubcriptionPolicy();
2151
			lastListenerRemoved();
2150
          changed = true;
2152
		}
2151
        }
2153
	};
2152
      }
2154
2153
2155
	/**
2154
      if (changed)
2156
	 * @author Juan Pedro Silva
2155
      {
2157
	 */
2156
        IListener[] listeners = getListeners();
2158
	public boolean hasRegisteredListeners() {
2157
        if (listeners != null)
2159
		return hasRegisteredListeners;
2158
        {
2160
	}
2159
          fireEvent(new ChangeSubscriptionPoliciesEventImpl(), listeners);
2161
2160
        }
2162
	/**
2161
      }
2163
	 * @author Juan Pedro Silva
2162
    }
2164
	 */
2163
2165
	public void registerLockListeners(Collection<IListener> collToRegister) {
2164
    public CDOAdapterPolicy getStrongReferencePolicy()
2166
		for (IListener il : collToRegister) {
2165
    {
2167
			registerListener(il);
2166
      return strongReferencePolicy;
2168
		}
2167
    }
2169
	}
2168
2170
2169
    public void setStrongReferencePolicy(CDOAdapterPolicy adapterPolicy)
2171
	/**
2170
    {
2172
	 * @author Juan Pedro Silva
2171
      if (adapterPolicy == null)
2173
	 */
2172
      {
2174
	public void registerLockListener(IListener listenerToRegister) {
2173
        adapterPolicy = CDOAdapterPolicy.ALL;
2175
		registerListener(listenerToRegister);
2174
      }
2176
	}
2175
2177
2176
      if (strongReferencePolicy != adapterPolicy)
2178
	/**
2177
      {
2179
	 * @author Juan Pedro Silva
2178
        strongReferencePolicy = adapterPolicy;
2180
	 */
2179
        adapterPolicyManager.reset();
2181
	public void unRegisterLockListener(IListener listenerToRegister) {
2180
        IListener[] listeners = getListeners();
2182
		unRegisterListener(listenerToRegister);
2181
        if (listeners != null)
2183
	}
2182
        {
2184
2183
          fireEvent(new ReferencePolicyEventImpl(), listeners);
2185
	/**
2184
        }
2186
	 * @author Juan Pedro Silva
2185
      }
2187
	 */
2186
    }
2188
	public void unRegisterLockListeners(Collection<IListener> collToUnregister) {
2187
2189
		for (IListener il : collToUnregister) {
2188
    public CDORevisionPrefetchingPolicy getRevisionPrefetchingPolicy()
2190
			unRegisterListener(il);
2189
    {
2191
		}
2190
      return revisionPrefetchingPolicy;
2192
	}
2191
    }
2193
2192
2194
	/**
2193
    public void setRevisionPrefetchingPolicy(CDORevisionPrefetchingPolicy prefetchingPolicy)
2195
	 * @author Juan Pedro Silva
2194
    {
2196
	 */
2195
      if (prefetchingPolicy == null)
2197
	protected void registerListener(IListener listenerToRegister) {
2196
      {
2198
		if (!hasRegisteredListeners) {
2197
        prefetchingPolicy = CDORevisionPrefetchingPolicy.NO_PREFETCHING;
2199
			hasRegisteredListeners = true;
2198
      }
2200
			session.registerLockListeners(this);
2199
2201
		}
2200
      if (revisionPrefetchingPolicy != prefetchingPolicy)
2202
		registeredLockListeners.add(listenerToRegister);
2201
      {
2203
	}
2202
        revisionPrefetchingPolicy = prefetchingPolicy;
2204
2203
        IListener[] listeners = getListeners();
2205
	/**
2204
        if (listeners != null)
2206
	 * @author Juan Pedro Silva
2205
        {
2207
	 */
2206
          fireEvent(new RevisionPrefetchingPolicyEventImpl(), listeners);
2208
	protected void unRegisterListener(IListener listenerToUnRegister) {
2207
        }
2209
		registeredLockListeners.remove(listenerToUnRegister);
2208
      }
2210
		if (registeredLockListeners.isEmpty()) {
2209
    }
2211
			hasRegisteredListeners = false;
2210
2212
			session.unregisterLockListeners(this);
2211
    public CDOStaleReferencePolicy getStaleReferenceBehaviour()
2213
		}
2212
    {
2214
	}
2213
      return staleReferencePolicy;
2215
2214
    }
2216
	/**
2215
2217
	 * @author Juan Pedro Silva
2216
    public void setStaleReferenceBehaviour(CDOStaleReferencePolicy policy)
2218
	 */
2217
    {
2219
	public void notifyRemoteLock(boolean b, String user,
2218
      if (policy == null)
2220
			Collection<CDOID> cdoids, LockType lockType) {
2219
      {
2221
		if (b) {
2220
        policy = CDOStaleReferencePolicy.EXCEPTION;
2222
			fireEvent(new RemoteLockAcquiredEvent(user, cdoids, lockType),
2221
      }
2223
					registeredLockListeners.get());
2222
2224
		} else {
2223
      if (staleReferencePolicy != policy)
2225
			fireEvent(new RemoteLockReleasedEvent(user, cdoids, lockType),
2224
      {
2226
					registeredLockListeners.get());
2225
        staleReferencePolicy = policy;
2227
		}
2226
        IListener[] listeners = getListeners();
2228
	}
2227
        if (listeners != null)
2228
        {
2229
          fireEvent(new StaleReferencePolicyEventImpl(), listeners);
2230
        }
2231
      }
2232
    }
2233
2234
    public ReferenceType getCacheReferenceType()
2235
    {
2236
      if (objects instanceof ReferenceValueMap.Strong<?, ?>)
2237
      {
2238
        return ReferenceType.STRONG;
2239
      }
2240
2241
      if (objects instanceof ReferenceValueMap.Soft<?, ?>)
2242
      {
2243
        return ReferenceType.SOFT;
2244
      }
2245
2246
      if (objects instanceof ReferenceValueMap.Weak<?, ?>)
2247
      {
2248
        return ReferenceType.WEAK;
2249
      }
2250
2251
      throw new IllegalStateException(Messages.getString("CDOViewImpl.29")); //$NON-NLS-1$
2252
    }
2253
2254
    public boolean setCacheReferenceType(ReferenceType referenceType)
2255
    {
2256
      if (referenceType == null)
2257
      {
2258
        referenceType = ReferenceType.SOFT;
2259
      }
2260
2261
      ReferenceValueMap<CDOID, InternalCDOObject> newObjects;
2262
      switch (referenceType)
2263
      {
2264
      case STRONG:
2265
        if (objects instanceof ReferenceValueMap.Strong<?, ?>)
2266
        {
2267
          return false;
2268
        }
2269
2270
        newObjects = new ReferenceValueMap.Strong<CDOID, InternalCDOObject>();
2271
        break;
2272
2273
      case SOFT:
2274
        if (objects instanceof ReferenceValueMap.Soft<?, ?>)
2275
        {
2276
          return false;
2277
        }
2278
2279
        newObjects = new ReferenceValueMap.Soft<CDOID, InternalCDOObject>();
2280
        break;
2281
2282
      case WEAK:
2283
        if (objects instanceof ReferenceValueMap.Weak<?, ?>)
2284
        {
2285
          return false;
2286
        }
2287
2288
        newObjects = new ReferenceValueMap.Weak<CDOID, InternalCDOObject>();
2289
        break;
2290
2291
      default:
2292
        throw new IllegalArgumentException(Messages.getString("CDOViewImpl.29")); //$NON-NLS-1$
2293
      }
2294
2295
      if (objects == null)
2296
      {
2297
        objects = newObjects;
2298
        IListener[] listeners = getListeners();
2299
        if (listeners != null)
2300
        {
2301
          fireEvent(new CacheReferenceTypeEventImpl(), listeners);
2302
        }
2303
2304
        return true;
2305
      }
2306
2307
      for (Entry<CDOID, InternalCDOObject> entry : objects.entrySet())
2308
      {
2309
        InternalCDOObject object = entry.getValue();
2310
        if (object != null)
2311
        {
2312
          newObjects.put(entry.getKey(), object);
2313
        }
2314
      }
2315
2316
      ConcurrentMap<CDOID, InternalCDOObject> oldObjects = objects;
2317
      synchronized (objects)
2318
      {
2319
        objects = newObjects;
2320
      }
2321
2322
      oldObjects.clear();
2323
      IListener[] listeners = getListeners();
2324
      if (listeners != null)
2325
      {
2326
        fireEvent(new CacheReferenceTypeEventImpl(), listeners);
2327
      }
2328
2329
      return true;
2330
    }
2331
2332
    /**
2333
     * @author Eike Stepper
2334
     */
2335
    private final class CacheReferenceTypeEventImpl extends OptionsEvent implements CacheReferenceTypeEvent
2336
    {
2337
      private static final long serialVersionUID = 1L;
2338
2339
      public CacheReferenceTypeEventImpl()
2340
      {
2341
        super(OptionsImpl.this);
2342
      }
2343
    }
2344
2345
    /**
2346
     * @author Eike Stepper
2347
     */
2348
    private final class ChangeSubscriptionPoliciesEventImpl extends OptionsEvent implements
2349
        ChangeSubscriptionPoliciesEvent
2350
    {
2351
      private static final long serialVersionUID = 1L;
2352
2353
      public ChangeSubscriptionPoliciesEventImpl()
2354
      {
2355
        super(OptionsImpl.this);
2356
      }
2357
    }
2358
2359
    /**
2360
     * @author Eike Stepper
2361
     */
2362
    private final class InvalidationNotificationEventImpl extends OptionsEvent implements InvalidationNotificationEvent
2363
    {
2364
      private static final long serialVersionUID = 1L;
2365
2366
      public InvalidationNotificationEventImpl()
2367
      {
2368
        super(OptionsImpl.this);
2369
      }
2370
    }
2371
2372
    /**
2373
     * @author Eike Stepper
2374
     */
2375
    private final class RevisionPrefetchingPolicyEventImpl extends OptionsEvent implements
2376
        RevisionPrefetchingPolicyEvent
2377
    {
2378
      private static final long serialVersionUID = 1L;
2379
2380
      public RevisionPrefetchingPolicyEventImpl()
2381
      {
2382
        super(OptionsImpl.this);
2383
      }
2384
    }
2385
2386
    /**
2387
     * @author Eike Stepper
2388
     */
2389
    private final class ReferencePolicyEventImpl extends OptionsEvent implements ReferencePolicyEvent
2390
    {
2391
      private static final long serialVersionUID = 1L;
2392
2393
      public ReferencePolicyEventImpl()
2394
      {
2395
        super(OptionsImpl.this);
2396
      }
2397
    }
2398
2399
    /**
2400
     * @author Simon McDuff
2401
     */
2402
    private final class StaleReferencePolicyEventImpl extends OptionsEvent implements StaleReferencePolicyEvent
2403
    {
2404
      private static final long serialVersionUID = 1L;
2405
2406
      public StaleReferencePolicyEventImpl()
2407
      {
2408
        super(OptionsImpl.this);
2409
      }
2410
    }
2411
  }
2412
}
2229
}
(-)src/org/eclipse/emf/cdo/view/RemoteLockEvent.java (+51 lines)
Added Link Here
1
/**
2
 * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
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
 *    Eike Stepper - initial API and implementation
10
 */
11
package org.eclipse.emf.cdo.view;
12
13
import org.eclipse.emf.cdo.common.id.CDOID;
14
15
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
16
17
import java.util.Collection;
18
19
/**
20
 * @author Eike Stepper
21
 */
22
public class RemoteLockEvent implements CDOViewEvent {
23
	private Collection<CDOID> cdoIds;
24
	private String user;
25
	private LockType lockType;
26
27
	public RemoteLockEvent(String user, Collection<CDOID> cdoIds,
28
			LockType lockType) {
29
		super();
30
		this.user = user;
31
		this.lockType = lockType;
32
		this.cdoIds = cdoIds;
33
	}
34
35
	public String getUser() {
36
		return user;
37
	}
38
39
	public LockType getLockType() {
40
		return lockType;
41
	}
42
43
	public Collection<CDOID> getCdoIds() {
44
		return cdoIds;
45
	}
46
47
	public CDOView getSource() {
48
		return null;
49
	}
50
51
}
(-)src/org/eclipse/emf/cdo/view/RemoteLockReleasedEvent.java (+27 lines)
Added Link Here
1
/**
2
 * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
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
 *    Eike Stepper - initial API and implementation
10
 */
11
package org.eclipse.emf.cdo.view;
12
13
import org.eclipse.emf.cdo.common.id.CDOID;
14
15
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
16
17
import java.util.Collection;
18
19
/**
20
 * @author Juan Pedro Silva
21
 */
22
public class RemoteLockReleasedEvent extends RemoteLockEvent {
23
	public RemoteLockReleasedEvent(String user, Collection<CDOID> cdoIds,
24
			LockType lockType) {
25
		super(user, cdoIds, lockType);
26
	}
27
}
(-)src/org/eclipse/emf/cdo/view/RemoteLockAcquiredEvent.java (+28 lines)
Added Link Here
1
/**
2
 * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
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
 *    Eike Stepper - initial API and implementation
10
 */
11
package org.eclipse.emf.cdo.view;
12
13
import org.eclipse.emf.cdo.common.id.CDOID;
14
15
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
16
17
import java.util.Collection;
18
19
/**
20
 * @author Juan Pedro Silva
21
 */
22
public class RemoteLockAcquiredEvent extends RemoteLockEvent {
23
24
	public RemoteLockAcquiredEvent(String user, Collection<CDOID> cdoIds,
25
			LockType lockType) {
26
		super(user, cdoIds, lockType);
27
	}
28
}
(-)src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java (+24 lines)
Lines 288-293 Link Here
288
    case CDOProtocolConstants.SIGNAL_REMOTE_MESSAGE_NOTIFICATION:
288
    case CDOProtocolConstants.SIGNAL_REMOTE_MESSAGE_NOTIFICATION:
289
      return new RemoteMessageNotificationIndication(this);
289
      return new RemoteMessageNotificationIndication(this);
290
290
291
      /**
292
       * @author Juan Pedro Silva
293
       */
294
    case CDOProtocolConstants.SIGNAL_REMOTE_LOCK_CHANGED_NOTIFICATION:
295
      return new RemoteLockChangedIndication(this);
296
297
      /** ----------------------------------------------------- */
298
291
    default:
299
    default:
292
      return super.createSignalReactor(signalID);
300
      return super.createSignalReactor(signalID);
293
    }
301
    }
Lines 347-350 Link Here
347
      REVISION_LOADING.stop(request);
355
      REVISION_LOADING.stop(request);
348
    }
356
    }
349
  }
357
  }
358
359
  /**
360
   * @author Juan Pedro Silva
361
   */
362
  public void unsubscribeRemoteLocks()
363
  {
364
    send(new UnsubscribeRemoteLocksRequest(this));
365
  }
366
367
  /**
368
   * @author Juan Pedro Silva
369
   */
370
  public void subscribeRemoteLocks()
371
  {
372
    send(new SubscribeRemoteLocksRequest(this));
373
  }
350
}
374
}
(-)src/org/eclipse/emf/cdo/internal/net4j/protocol/UnsubscribeRemoteLocksRequest.java (+48 lines)
Added Link Here
1
/**
2
 * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
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
 *    Eike Stepper - initial API and implementation
10
 */
11
package org.eclipse.emf.cdo.internal.net4j.protocol;
12
13
import org.eclipse.emf.cdo.common.io.CDODataInput;
14
import org.eclipse.emf.cdo.common.io.CDODataOutput;
15
import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
16
import org.eclipse.emf.cdo.internal.net4j.bundle.OM;
17
18
import org.eclipse.net4j.util.om.trace.ContextTracer;
19
20
import java.io.IOException;
21
22
/**
23
 * @author Juan Pedro Silva
24
 */
25
public class UnsubscribeRemoteLocksRequest extends CDOClientRequest<Boolean>
26
{
27
  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, UnsubscribeRemoteLocksRequest.class);
28
29
  public UnsubscribeRemoteLocksRequest(CDOClientProtocol protocol)
30
  {
31
    super(protocol, CDOProtocolConstants.SIGNAL_UNREGISTER_LOCK_LISTENER);
32
  }
33
34
  @Override
35
  protected void requesting(CDODataOutput out) throws IOException
36
  {
37
    if (TRACER.isEnabled())
38
    {
39
      TRACER.trace("Unsubscribing from Lock Notifications"); //$NON-NLS-1$
40
    }
41
  }
42
43
  @Override
44
  protected Boolean confirming(CDODataInput in) throws IOException
45
  {
46
    return in.readBoolean();
47
  }
48
}
(-)src/org/eclipse/emf/cdo/internal/net4j/protocol/RemoteLockChangedIndication.java (+94 lines)
Added Link Here
1
/**
2
 * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
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
 *    Eike Stepper - initial API and implementation
10
 */
11
package org.eclipse.emf.cdo.internal.net4j.protocol;
12
13
import org.eclipse.emf.cdo.common.id.CDOID;
14
import org.eclipse.emf.cdo.common.io.CDODataInput;
15
import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
16
import org.eclipse.emf.cdo.internal.net4j.bundle.OM;
17
import org.eclipse.emf.cdo.view.CDOView;
18
19
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
20
import org.eclipse.net4j.util.io.IORuntimeException;
21
import org.eclipse.net4j.util.om.trace.ContextTracer;
22
23
import java.io.IOException;
24
import java.util.HashSet;
25
import java.util.Set;
26
27
/**
28
 * @author Juan Pedro Silva
29
 * @see org.eclipse.emf.cdo.server.internal.net4j.protocol.LockObjectsIndication
30
 */
31
public class RemoteLockChangedIndication extends CDOClientIndication
32
{
33
  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, RemoteLockChangedIndication.class);
34
35
  private LockType lockType;
36
37
  private Set<CDOID> lockedObjects;
38
39
  private String user;
40
41
  private int sessionId;
42
43
  private boolean lock;
44
45
  public RemoteLockChangedIndication(CDOClientProtocol cdoClientProtocol)
46
  {
47
    super(cdoClientProtocol, CDOProtocolConstants.SIGNAL_REMOTE_LOCK_CHANGED_NOTIFICATION);
48
  }
49
50
  @Override
51
  protected void indicating(CDODataInput in) throws IOException
52
  {
53
    long timeStamp = in.readLong();
54
    if (TRACER.isEnabled())
55
    {
56
      TRACER.format("Read timeStamp: {0,date} {0,time}", timeStamp); //$NON-NLS-1$
57
    }
58
59
    int size = in.readInt();
60
    if (TRACER.isEnabled())
61
    {
62
      TRACER.format("Reading {0} locked IDs", size); //$NON-NLS-1$
63
    }
64
65
    lockedObjects = new HashSet<CDOID>();
66
    for (int i = 0; i < size; i++)
67
    {
68
      CDOID dirtyOID = in.readCDOID();
69
      if (TRACER.isEnabled())
70
      {
71
        TRACER.format("Read locked ID: {0}", dirtyOID); //$NON-NLS-1$
72
      }
73
74
      lockedObjects.add(dirtyOID);
75
    }
76
    lock = in.readBoolean();
77
    lockType = in.readCDOLockType();
78
    user = in.readString();
79
    try
80
    {
81
      for (CDOView cv : getSession().getViews())
82
      {
83
        if (cv.hasListeners())
84
        {
85
          cv.notifyRemoteLock(lock, user, lockedObjects, lockType);
86
        }
87
      }
88
    }
89
    catch (Exception ex) // Interrupted
90
    {
91
      throw new IORuntimeException(ex);
92
    }
93
  }
94
}
(-)src/org/eclipse/emf/cdo/internal/net4j/protocol/SubscribeRemoteLocksRequest.java (+49 lines)
Added Link Here
1
/**
2
 /**
3
 * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
4
 * All rights reserved. This program and the accompanying materials
5
 * are made available under the terms of the Eclipse Public License v1.0
6
 * which accompanies this distribution, and is available at
7
 * http://www.eclipse.org/legal/epl-v10.html
8
 * 
9
 * Contributors:
10
 *    Eike Stepper - initial API and implementation
11
 */
12
package org.eclipse.emf.cdo.internal.net4j.protocol;
13
14
import org.eclipse.emf.cdo.common.io.CDODataInput;
15
import org.eclipse.emf.cdo.common.io.CDODataOutput;
16
import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
17
import org.eclipse.emf.cdo.internal.net4j.bundle.OM;
18
19
import org.eclipse.net4j.util.om.trace.ContextTracer;
20
21
import java.io.IOException;
22
23
/**
24
 * @author Juan Pedro Silva
25
 */
26
public class SubscribeRemoteLocksRequest extends CDOClientRequest<Boolean>
27
{
28
  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, SubscribeRemoteLocksRequest.class);
29
30
  public SubscribeRemoteLocksRequest(CDOClientProtocol protocol)
31
  {
32
    super(protocol, CDOProtocolConstants.SIGNAL_REGISTER_LOCK_LISTENER);
33
  }
34
35
  @Override
36
  protected void requesting(CDODataOutput out) throws IOException
37
  {
38
    if (TRACER.isEnabled())
39
    {
40
      TRACER.trace("Subscribing to Lock Notifications"); //$NON-NLS-1$
41
    }
42
  }
43
44
  @Override
45
  protected Boolean confirming(CDODataInput in) throws IOException
46
  {
47
    return in.readBoolean();
48
  }
49
}
(-)src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java (+16 lines)
Lines 467-470 Link Here
467
467
468
    return result;
468
    return result;
469
  }
469
  }
470
471
  /**
472
   * @author Juan Pedro Silva
473
   */
474
  public void subscribeRemoteLocks()
475
  {
476
    throw new UnsupportedOperationException();
477
  }
478
479
  /**
480
   * @author Juan Pedro Silva
481
   */
482
  public void unsubscribeRemoteLocks()
483
  {
484
    throw new UnsupportedOperationException();
485
  }
470
}
486
}
(-)src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedServerSessionProtocol.java (+13 lines)
Lines 21-29 Link Here
21
import org.eclipse.emf.cdo.spi.server.InternalRepository;
21
import org.eclipse.emf.cdo.spi.server.InternalRepository;
22
import org.eclipse.emf.cdo.spi.server.InternalSession;
22
import org.eclipse.emf.cdo.spi.server.InternalSession;
23
23
24
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
24
import org.eclipse.net4j.util.lifecycle.Lifecycle;
25
import org.eclipse.net4j.util.lifecycle.Lifecycle;
25
26
26
import java.util.Arrays;
27
import java.util.Arrays;
28
import java.util.Collection;
27
import java.util.HashSet;
29
import java.util.HashSet;
28
import java.util.List;
30
import java.util.List;
29
31
Lines 77-84 Link Here
77
    throw new UnsupportedOperationException();
79
    throw new UnsupportedOperationException();
78
  }
80
  }
79
81
82
  /**
83
   * @author Juan Pedro Silva
84
   */
80
  public boolean sendRemoteMessageNotification(InternalSession sender, CDORemoteSessionMessage message)
85
  public boolean sendRemoteMessageNotification(InternalSession sender, CDORemoteSessionMessage message)
81
  {
86
  {
82
    throw new UnsupportedOperationException();
87
    throw new UnsupportedOperationException();
83
  }
88
  }
89
90
  /**
91
   * @author Juan Pedro Silva
92
   */
93
  public void sendRemoteLockNotification(boolean b, String user, Collection<CDOID> cdoids, LockType lockType)
94
  {
95
    throw new UnsupportedOperationException();
96
  }
84
}
97
}
(-)src/org/eclipse/emf/cdo/internal/server/Session.java (+10 lines)
Lines 35-40 Link Here
35
import org.eclipse.emf.cdo.spi.server.InternalView;
35
import org.eclipse.emf.cdo.spi.server.InternalView;
36
36
37
import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
37
import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
38
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
38
import org.eclipse.net4j.util.container.Container;
39
import org.eclipse.net4j.util.container.Container;
39
import org.eclipse.net4j.util.event.EventUtil;
40
import org.eclipse.net4j.util.event.EventUtil;
40
import org.eclipse.net4j.util.event.IListener;
41
import org.eclipse.net4j.util.event.IListener;
Lines 50-55 Link Here
50
51
51
import java.text.MessageFormat;
52
import java.text.MessageFormat;
52
import java.util.ArrayList;
53
import java.util.ArrayList;
54
import java.util.Collection;
53
import java.util.Collections;
55
import java.util.Collections;
54
import java.util.List;
56
import java.util.List;
55
import java.util.Set;
57
import java.util.Set;
Lines 398-401 Link Here
398
    manager = null;
400
    manager = null;
399
    super.doDeactivate();
401
    super.doDeactivate();
400
  }
402
  }
403
404
  /**
405
   * @author Juan Pedro Silva
406
   */
407
  public void notifyRemoteLock(boolean b, String user, Collection<CDOID> cdoids, LockType lockType)
408
  {
409
    getProtocol().sendRemoteLockNotification(b, user, cdoids, lockType);
410
  }
401
}
411
}
(-)src/org/eclipse/emf/cdo/internal/server/LockManager.java (+39 lines)
Lines 24-29 Link Here
24
import org.eclipse.net4j.util.container.IContainer;
24
import org.eclipse.net4j.util.container.IContainer;
25
import org.eclipse.net4j.util.event.IListener;
25
import org.eclipse.net4j.util.event.IListener;
26
26
27
import java.util.Collection;
28
27
/**
29
/**
28
 * @author Simon McDuff
30
 * @author Simon McDuff
29
 * @since 3.0
31
 * @since 3.0
Lines 91-94 Link Here
91
93
92
    super.doDeactivate();
94
    super.doDeactivate();
93
  }
95
  }
96
97
  /**
98
   * @author Juan Pedro Silva
99
   * @param lock
100
   *          : True = Lock, false = Unlock
101
   */
102
  @Override
103
  protected void notifyRemoteLockChanged(boolean b, IView sender, Collection<? extends CDOID> cdoids, LockType lockType)
104
  {
105
    for (Object il : registeredLockListeners)
106
    {
107
      ISession is = (ISession)il;
108
      is.notifyRemoteLock(b, sender.getSession().getUserID(), (Collection<CDOID>)cdoids, lockType);
109
    }
110
  }
111
112
  /**
113
   * @author Juan Pedro Silva
114
   */
115
  @Override
116
  protected void registerListener(Object listenerToRegister)
117
  {
118
    registeredLockListeners.add(listenerToRegister);
119
  }
120
121
  /**
122
   * @author Juan Pedro Silva
123
   */
124
  @Override
125
  protected void unRegisterListener(Object listenerToRegister)
126
  {
127
    registeredLockListeners.remove(listenerToRegister);
128
    if (registeredLockListeners.isEmpty())
129
    {
130
      hasListenerRegistered = false;
131
    }
132
  }
94
}
133
}
(-)src/org/eclipse/emf/cdo/server/ISession.java (+16 lines)
Lines 12-21 Link Here
12
package org.eclipse.emf.cdo.server;
12
package org.eclipse.emf.cdo.server;
13
13
14
import org.eclipse.emf.cdo.common.CDOCommonSession;
14
import org.eclipse.emf.cdo.common.CDOCommonSession;
15
import org.eclipse.emf.cdo.common.id.CDOID;
15
import org.eclipse.emf.cdo.spi.server.ISessionProtocol;
16
import org.eclipse.emf.cdo.spi.server.ISessionProtocol;
16
17
18
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
17
import org.eclipse.net4j.util.container.IContainer;
19
import org.eclipse.net4j.util.container.IContainer;
18
20
21
import java.util.Collection;
22
19
/**
23
/**
20
 * @author Eike Stepper
24
 * @author Eike Stepper
21
 */
25
 */
Lines 50-53 Link Here
50
   * @since 2.0
54
   * @since 2.0
51
   */
55
   */
52
  public ITransaction openTransaction(int viewID);
56
  public ITransaction openTransaction(int viewID);
57
58
  /**
59
   * @author Juan Pedro Silva
60
   */
61
  public String getUserID();
62
63
  /**
64
   * @author Juan Pedro Silva
65
   * @param lock
66
   *          : True = Lock, false = Unlock
67
   */
68
  public void notifyRemoteLock(boolean b, String user, Collection<CDOID> cdoids, LockType lockType);
53
}
69
}
(-)src/org/eclipse/emf/cdo/spi/server/ISessionProtocol.java (+8 lines)
Lines 19-24 Link Here
19
import org.eclipse.emf.cdo.server.ISession;
19
import org.eclipse.emf.cdo.server.ISession;
20
import org.eclipse.emf.cdo.session.remote.CDORemoteSessionMessage;
20
import org.eclipse.emf.cdo.session.remote.CDORemoteSessionMessage;
21
21
22
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
23
24
import java.util.Collection;
22
import java.util.List;
25
import java.util.List;
23
26
24
/**
27
/**
Lines 35-38 Link Here
35
  public void sendRemoteSessionNotification(byte opcode, ISession session);
38
  public void sendRemoteSessionNotification(byte opcode, ISession session);
36
39
37
  public boolean sendRemoteMessageNotification(InternalSession sender, CDORemoteSessionMessage message);
40
  public boolean sendRemoteMessageNotification(InternalSession sender, CDORemoteSessionMessage message);
41
42
  /**
43
   * @author Juan Pedro Silva
44
   */
45
  public void sendRemoteLockNotification(boolean b, String user, Collection<CDOID> cdoids, LockType lockType);
38
}
46
}
(-)src/org/eclipse/net4j/util/concurrent/RWLockManager.java (+82 lines)
Lines 19-24 Link Here
19
import java.util.Collection;
19
import java.util.Collection;
20
import java.util.Collections;
20
import java.util.Collections;
21
import java.util.HashMap;
21
import java.util.HashMap;
22
import java.util.HashSet;
22
import java.util.List;
23
import java.util.List;
23
import java.util.Map;
24
import java.util.Map;
24
import java.util.Set;
25
import java.util.Set;
Lines 94-99 Link Here
94
95
95
  private Object lockChanged = new Object();
96
  private Object lockChanged = new Object();
96
97
98
  protected boolean hasListenerRegistered;
99
100
  protected Set<Object> registeredLockListeners = new HashSet<Object>();
101
97
  /**
102
  /**
98
   * @since 3.0
103
   * @since 3.0
99
   */
104
   */
Lines 101-106 Link Here
101
      throws InterruptedException
106
      throws InterruptedException
102
  {
107
  {
103
    lock(getLockingStrategy(type), context, objectsToLock, timeout);
108
    lock(getLockingStrategy(type), context, objectsToLock, timeout);
109
    notifyRemoteLockChanged(true, context, objectsToLock, type);
104
  }
110
  }
105
111
106
  /**
112
  /**
Lines 121-126 Link Here
121
  public void unlock(LockType type, V context, Collection<? extends K> objectsToUnlock)
127
  public void unlock(LockType type, V context, Collection<? extends K> objectsToUnlock)
122
  {
128
  {
123
    unlock(getLockingStrategy(type), context, objectsToUnlock);
129
    unlock(getLockingStrategy(type), context, objectsToUnlock);
130
    notifyRemoteLockChanged(false, context, objectsToUnlock, type);
124
  }
131
  }
125
132
126
  /**
133
  /**
Lines 635-638 Link Here
635
      throw new UnsupportedOperationException();
642
      throw new UnsupportedOperationException();
636
    }
643
    }
637
  }
644
  }
645
646
  /**
647
   * @author Juan Pedro Silva
648
   */
649
  public void registerLockListeners(Collection<Object> collToRegister)
650
  {
651
    for (Object il : collToRegister)
652
    {
653
      registerListener(il);
654
    }
655
  }
656
657
  /**
658
   * @author Juan Pedro Silva
659
   */
660
  public void registerLockListener(Object listenerToRegister)
661
  {
662
    registerListener(listenerToRegister);
663
  }
664
665
  /**
666
   * @author Juan Pedro Silva
667
   */
668
  public void unRegisterLockListener(Object listenerToRegister)
669
  {
670
    unRegisterListener(listenerToRegister);
671
  }
672
673
  /**
674
   * @author Juan Pedro Silva
675
   */
676
  public void unRegisterLockListeners(Collection<Object> collToUnregister)
677
  {
678
    for (Object il : collToUnregister)
679
    {
680
      unRegisterListener(il);
681
    }
682
  }
683
684
  /**
685
   * @author Juan Pedro Silva
686
   */
687
  public boolean hasListenerRegistered()
688
  {
689
    return hasListenerRegistered;
690
  }
691
692
  /**
693
   * @author Juan Pedro Silva
694
   */
695
  protected void registerListener(Object listenerToRegister)
696
  {
697
    registeredLockListeners.add(listenerToRegister);
698
  }
699
700
  /**
701
   * @author Juan Pedro Silva
702
   */
703
  protected void unRegisterListener(Object listenerToRegister)
704
  {
705
    registeredLockListeners.remove(listenerToRegister);
706
    if (registeredLockListeners.isEmpty())
707
    {
708
      hasListenerRegistered = false;
709
    }
710
  }
711
712
  /**
713
   * @author Juan Pedro Silva
714
   * @param lock
715
   *          : True = Lock, false = Unlock
716
   */
717
  protected void notifyRemoteLockChanged(boolean b, V context, Collection<? extends K> cdoids, LockType lockType)
718
  {
719
  }
638
}
720
}
(-)src/org/eclipse/net4j/util/concurrent/IRWLockManager.java (+25 lines)
Lines 49-54 Link Here
49
  public boolean hasLockByOthers(LockType type, V context, K objectToLock);
49
  public boolean hasLockByOthers(LockType type, V context, K objectToLock);
50
50
51
  /**
51
  /**
52
   * @author Juan Pedro Silva
53
   */
54
  public void registerLockListeners(Collection<Object> collToRegister);
55
56
  /**
57
   * @author Juan Pedro Silva
58
   */
59
  public void registerLockListener(Object listenerToRegister);
60
61
  /**
62
   * @author Juan Pedro Silva
63
   */
64
  public void unRegisterLockListener(Object listenerToRegister);
65
66
  /**
67
   * @author Juan Pedro Silva
68
   */
69
  public void unRegisterLockListeners(Collection<Object> collToUnregister);
70
71
  /**
72
   * @author Juan Pedro Silva
73
   */
74
  public boolean hasListenerRegistered();
75
76
  /**
52
   * @author Simon McDuff
77
   * @author Simon McDuff
53
   */
78
   */
54
  public static enum LockType
79
  public static enum LockType
(-)src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java (+10 lines)
Lines 1277-1282 Link Here
1277
          fireDirtyPropertyChange();
1277
          fireDirtyPropertyChange();
1278
        }
1278
        }
1279
      };
1279
      };
1280
1281
      /**
1282
       *@author Juan Pedro Silva
1283
       *@see I don't like this registration here. I rather have it under an option, which is the proper place. However,
1284
       *      this is currently the way I'm using to be sure eventHandler's listeners have been registered.
1285
       *@TODO: Make the registration optional.
1286
       */
1287
      CDOView lm = getView();
1288
      lm.registerLockListeners(eventHandler.getLockListeners());
1289
1280
    }
1290
    }
1281
    catch (RuntimeException ex)
1291
    catch (RuntimeException ex)
1282
    {
1292
    {
(-)src/org/eclipse/emf/cdo/ui/CDOEventHandler.java (+66 lines)
Lines 13-18 Link Here
13
package org.eclipse.emf.cdo.ui;
13
package org.eclipse.emf.cdo.ui;
14
14
15
import org.eclipse.emf.cdo.CDOObject;
15
import org.eclipse.emf.cdo.CDOObject;
16
import org.eclipse.emf.cdo.common.id.CDOID;
16
import org.eclipse.emf.cdo.internal.ui.ItemsProcessor;
17
import org.eclipse.emf.cdo.internal.ui.ItemsProcessor;
17
import org.eclipse.emf.cdo.internal.ui.bundle.OM;
18
import org.eclipse.emf.cdo.internal.ui.bundle.OM;
18
import org.eclipse.emf.cdo.session.CDOSession;
19
import org.eclipse.emf.cdo.session.CDOSession;
Lines 21-26 Link Here
21
import org.eclipse.emf.cdo.transaction.CDOTransactionStartedEvent;
22
import org.eclipse.emf.cdo.transaction.CDOTransactionStartedEvent;
22
import org.eclipse.emf.cdo.view.CDOView;
23
import org.eclipse.emf.cdo.view.CDOView;
23
import org.eclipse.emf.cdo.view.CDOViewInvalidationEvent;
24
import org.eclipse.emf.cdo.view.CDOViewInvalidationEvent;
25
import org.eclipse.emf.cdo.view.RemoteLockAcquiredEvent;
26
import org.eclipse.emf.cdo.view.RemoteLockReleasedEvent;
24
27
25
import org.eclipse.net4j.util.container.IContainerDelta;
28
import org.eclipse.net4j.util.container.IContainerDelta;
26
import org.eclipse.net4j.util.container.IContainerEvent;
29
import org.eclipse.net4j.util.container.IContainerEvent;
Lines 36-41 Link Here
36
import org.eclipse.jface.viewers.TreeViewer;
39
import org.eclipse.jface.viewers.TreeViewer;
37
import org.eclipse.ui.PlatformUI;
40
import org.eclipse.ui.PlatformUI;
38
41
42
import java.util.ArrayList;
43
import java.util.Collection;
39
import java.util.List;
44
import java.util.List;
40
import java.util.Set;
45
import java.util.Set;
41
46
Lines 321-324 Link Here
321
  protected void viewClosed()
326
  protected void viewClosed()
322
  {
327
  {
323
  }
328
  }
329
330
  /**
331
   * @author Juan Pedro Silva
332
   */
333
  private IListener lockListener = new IListener()
334
  {
335
    public void notifyEvent(IEvent event)
336
    {
337
      if (event instanceof RemoteLockAcquiredEvent)
338
      {
339
        RemoteLockAcquiredEvent e = (RemoteLockAcquiredEvent)event;
340
        System.err.println("RemoteLockAcquiredEvent received. LockType: " + e.getLockType());
341
        if (e.getUser() != null)
342
        {
343
          System.err.println("User: " + e.getUser());
344
        }
345
        int i = 1;
346
        for (CDOID ci : e.getCdoIds())
347
        {
348
          System.err.println("CDOID: " + ci + " (" + i + ").");
349
          i++;
350
        }
351
      }
352
    }
353
  };
354
355
  /**
356
   * @author Juan Pedro Silva
357
   */
358
  private IListener unlockListener = new IListener()
359
  {
360
    public void notifyEvent(IEvent event)
361
    {
362
      if (event instanceof RemoteLockReleasedEvent)
363
      {
364
        RemoteLockReleasedEvent e = (RemoteLockReleasedEvent)event;
365
        System.err.println("RemoteLockReleasedEvent received. LockType: " + e.getLockType());
366
        if (e.getUser() != null)
367
        {
368
          System.err.println("User: " + e.getUser());
369
        }
370
        int i = 1;
371
        for (CDOID ci : e.getCdoIds())
372
        {
373
          System.err.println("CDOID: " + ci + " (" + i + ").");
374
          i++;
375
        }
376
      }
377
    }
378
  };
379
380
  /**
381
   * @author Juan Pedro Silva
382
   */
383
  public Collection<IListener> getLockListeners()
384
  {
385
    ArrayList<IListener> ail = new ArrayList<IListener>();
386
    ail.add(lockListener);
387
    ail.add(unlockListener);
388
    return ail;
389
  }
324
}
390
}
(-)src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java (+36 lines)
Lines 30-39 Link Here
30
import org.eclipse.net4j.channel.IChannel;
30
import org.eclipse.net4j.channel.IChannel;
31
import org.eclipse.net4j.signal.SignalProtocol;
31
import org.eclipse.net4j.signal.SignalProtocol;
32
import org.eclipse.net4j.signal.SignalReactor;
32
import org.eclipse.net4j.signal.SignalReactor;
33
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
33
import org.eclipse.net4j.util.io.StringCompressor;
34
import org.eclipse.net4j.util.io.StringCompressor;
34
import org.eclipse.net4j.util.io.StringIO;
35
import org.eclipse.net4j.util.io.StringIO;
35
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
36
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
36
37
38
import java.util.Collection;
37
import java.util.List;
39
import java.util.List;
38
40
39
/**
41
/**
Lines 233-240 Link Here
233
    case CDOProtocolConstants.SIGNAL_REMOTE_MESSAGE:
235
    case CDOProtocolConstants.SIGNAL_REMOTE_MESSAGE:
234
      return new RemoteMessageIndication(this);
236
      return new RemoteMessageIndication(this);
235
237
238
      /**
239
       * @author Juan Pedro Silva
240
       */
241
    case CDOProtocolConstants.SIGNAL_REGISTER_LOCK_LISTENER:
242
      return new RegisterLockListenerIndication(this);
243
244
    case CDOProtocolConstants.SIGNAL_UNREGISTER_LOCK_LISTENER:
245
      return new UnregisterLockListenerIndication(this);
246
236
    default:
247
    default:
237
      return super.createSignalReactor(signalID);
248
      return super.createSignalReactor(signalID);
238
    }
249
    }
239
  }
250
  }
251
252
  /**
253
   * @author Juan Pedro Silva True = Lock, false = Unlock
254
   * @param lock
255
   *          True = Lock, false = Unlock
256
   */
257
  public void sendRemoteLockNotification(boolean b, String user, Collection<CDOID> cdoids, LockType lockType)
258
  {
259
    try
260
    {
261
      IChannel channel = getChannel();
262
      if (LifecycleUtil.isActive(channel))
263
      {
264
        new RemoteLockChangedNotificationRequest(channel, b, user, cdoids, lockType).sendAsync();
265
      }
266
      else
267
      {
268
        OM.LOG.warn("Session channel is inactive: " + this); //$NON-NLS-1$
269
      }
270
    }
271
    catch (Exception ex)
272
    {
273
      OM.LOG.error(ex);
274
    }
275
  }
240
}
276
}
(-)src/org/eclipse/emf/cdo/server/internal/net4j/protocol/UnregisterLockListenerIndication.java (+51 lines)
Added Link Here
1
/**
2
 * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
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
 *    Eike Stepper - initial API and implementation
10
 */
11
package org.eclipse.emf.cdo.server.internal.net4j.protocol;
12
13
import org.eclipse.emf.cdo.common.io.CDODataInput;
14
import org.eclipse.emf.cdo.common.io.CDODataOutput;
15
import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
16
import org.eclipse.emf.cdo.server.internal.net4j.bundle.OM;
17
18
import org.eclipse.net4j.util.om.trace.ContextTracer;
19
20
import java.io.IOException;
21
22
/**
23
 * @author Juan Pedro Silva
24
 */
25
public class UnregisterLockListenerIndication extends CDOReadIndication
26
{
27
  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL,
28
      UnregisterLockListenerIndication.class);
29
30
  public UnregisterLockListenerIndication(CDOServerProtocol protocol)
31
  {
32
    super(protocol, CDOProtocolConstants.SIGNAL_UNREGISTER_LOCK_LISTENER);
33
  }
34
35
  @Override
36
  protected void indicating(CDODataInput in) throws IOException
37
  {
38
    if (TRACER.isEnabled())
39
    {
40
      TRACER.trace("Unregistering Lock Listener"); //$NON-NLS-1$
41
    }
42
43
    getRepository().getLockManager().unRegisterLockListener(getSession());
44
  }
45
46
  @Override
47
  protected void responding(CDODataOutput out) throws IOException
48
  {
49
    out.writeBoolean(true);
50
  }
51
}
(-)src/org/eclipse/emf/cdo/server/internal/net4j/protocol/RemoteLockChangedNotificationRequest.java (+83 lines)
Added Link Here
1
/**
2
 * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
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
 *    Eike Stepper - initial API and implementation
10
 */
11
package org.eclipse.emf.cdo.server.internal.net4j.protocol;
12
13
import org.eclipse.emf.cdo.common.id.CDOID;
14
import org.eclipse.emf.cdo.common.io.CDODataOutput;
15
import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
16
import org.eclipse.emf.cdo.server.internal.net4j.bundle.OM;
17
18
import org.eclipse.net4j.channel.IChannel;
19
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
20
import org.eclipse.net4j.util.om.trace.ContextTracer;
21
22
import java.io.IOException;
23
import java.util.Collection;
24
25
/**
26
 * @author Juan Pedro Silva
27
 */
28
public class RemoteLockChangedNotificationRequest extends CDOServerRequest
29
{
30
31
  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL,
32
      RemoteLockChangedNotificationRequest.class);
33
34
  private long timeStamp;
35
36
  private Collection<CDOID> lockedObjects;
37
38
  private LockType lockType;
39
40
  private String userID;
41
42
  private boolean lock;
43
44
  public RemoteLockChangedNotificationRequest(IChannel channel, boolean lock, String userID, Collection<CDOID> cdoids,
45
      LockType lockType)
46
  {
47
    super(channel, CDOProtocolConstants.SIGNAL_REMOTE_LOCK_CHANGED_NOTIFICATION);
48
    timeStamp = System.currentTimeMillis();
49
    this.userID = userID;
50
    this.lock = lock;
51
    lockedObjects = cdoids;
52
    this.lockType = lockType;
53
  }
54
55
  @Override
56
  protected void requesting(CDODataOutput out) throws IOException
57
  {
58
    if (TRACER.isEnabled())
59
    {
60
      TRACER.format("Writing timeStamp: {0,date} {0,time}", timeStamp); //$NON-NLS-1$
61
    }
62
63
    out.writeLong(timeStamp);
64
    if (TRACER.isEnabled())
65
    {
66
      TRACER.format("Writing {0} locked IDs", lockedObjects.size()); //$NON-NLS-1$
67
    }
68
69
    out.writeInt(lockedObjects == null ? 0 : lockedObjects.size());
70
    for (CDOID id : lockedObjects)
71
    {
72
      if (TRACER.isEnabled())
73
      {
74
        TRACER.format("Writing locked ID: {0}", id); //$NON-NLS-1$
75
      }
76
      out.writeCDOID(id);
77
    }
78
    out.writeBoolean(lock);
79
    out.writeCDOLockType(lockType);
80
    out.writeString(userID);
81
  }
82
83
}
(-)src/org/eclipse/emf/cdo/server/internal/net4j/protocol/RegisterLockListenerIndication.java (+50 lines)
Added Link Here
1
/**
2
 * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
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
 *    Eike Stepper - initial API and implementation
10
 */
11
package org.eclipse.emf.cdo.server.internal.net4j.protocol;
12
13
import org.eclipse.emf.cdo.common.io.CDODataInput;
14
import org.eclipse.emf.cdo.common.io.CDODataOutput;
15
import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
16
import org.eclipse.emf.cdo.server.internal.net4j.bundle.OM;
17
18
import org.eclipse.net4j.util.om.trace.ContextTracer;
19
20
import java.io.IOException;
21
22
/**
23
 * @author Juan Pedro Silva
24
 */
25
public class RegisterLockListenerIndication extends CDOReadIndication
26
{
27
  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, RegisterLockListenerIndication.class);
28
29
  public RegisterLockListenerIndication(CDOServerProtocol protocol)
30
  {
31
    super(protocol, CDOProtocolConstants.SIGNAL_REGISTER_LOCK_LISTENER);
32
  }
33
34
  @Override
35
  protected void indicating(CDODataInput in) throws IOException
36
  {
37
    if (TRACER.isEnabled())
38
    {
39
      TRACER.trace("Registering Lock Listener"); //$NON-NLS-1$
40
    }
41
42
    getRepository().getLockManager().registerLockListener(getSession());
43
  }
44
45
  @Override
46
  protected void responding(CDODataOutput out) throws IOException
47
  {
48
    out.writeBoolean(true);
49
  }
50
}
(-)src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java (+12 lines)
Lines 92-97 Link Here
92
  public static final short SIGNAL_REMOTE_SESSION_NOTIFICATION = 32;
92
  public static final short SIGNAL_REMOTE_SESSION_NOTIFICATION = 32;
93
93
94
  // //////////////////////////////////////////////////////////////////////
94
  // //////////////////////////////////////////////////////////////////////
95
  // Lock Notification
96
97
  /**
98
   * @author Juan Pedro Silva
99
   */
100
  public static final short SIGNAL_REGISTER_LOCK_LISTENER = 35;
101
102
  public static final short SIGNAL_UNREGISTER_LOCK_LISTENER = 36;
103
104
  public static final short SIGNAL_REMOTE_LOCK_CHANGED_NOTIFICATION = 37;
105
106
  // //////////////////////////////////////////////////////////////////////
95
  // Session Management
107
  // Session Management
96
108
97
  public static final int ERROR_REPOSITORY_NOT_FOUND = -1;
109
  public static final int ERROR_REPOSITORY_NOT_FOUND = -1;

Return to bug 283274