Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 153394 Details for
Bug 283274
Acquire a lock could notify others
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
Improved version. Working
patch_newLockNotification_30_11_09.txt (text/plain), 285.33 KB, created by
Juan Pedro Silva
on 2009-11-30 15:18:56 EST
(
hide
)
Description:
Improved version. Working
Filename:
MIME Type:
Creator:
Juan Pedro Silva
Created:
2009-11-30 15:18:56 EST
Size:
285.33 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.emf.cdo >Index: src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java,v >retrieving revision 1.51 >diff -u -r1.51 CDOSessionImpl.java >--- src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java 10 Nov 2009 08:25:25 -0000 1.51 >+++ src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java 30 Nov 2009 20:08:43 -0000 >@@ -95,1512 +95,1309 @@ > /** > * @author Eike Stepper > */ >-public abstract class CDOSessionImpl extends Container<CDOView> implements InternalCDOSession >-{ >- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_SESSION, CDOSessionImpl.class); >- >- private static final long NO_TIMEOUT = -1; >- >- private InternalCDOSessionConfiguration configuration; >- >- private ExceptionHandler exceptionHandler; >- >- private CDOSessionProtocol sessionProtocol; >- >- @ExcludeFromDump >- private IListener sessionProtocolListener = new LifecycleEventAdapter() >- { >- @Override >- protected void onDeactivated(ILifecycle lifecycle) >- { >- CDOSessionImpl.this.deactivate(); >- } >- }; >- >- private int sessionID; >- >- private String userID; >- >- private long lastUpdateTime; >- >- @ExcludeFromDump >- private Object lastUpdateTimeLock = new Object(); >- >- private CDOSession.Options options = createOptions(); >- >- private CDORepositoryInfo repositoryInfo; >- >- private CDOFetchRuleManager ruleManager = CDOFetchRuleManager.NOOP; >- >- private IRWLockManager<CDOSessionImpl, Object> lockmanager = new RWLockManager<CDOSessionImpl, Object>(); >- >- @ExcludeFromDump >- private Set<CDOSessionImpl> singletonCollection = Collections.singleton(this); >- >- private CDOAuthenticator authenticator; >- >- private InternalCDORemoteSessionManager remoteSessionManager; >- >- private Set<InternalCDOView> views = new HashSet<InternalCDOView>(); >- >- /** >- * Fixes a threading problem between a committing thread and the Net4j thread that delivers incoming commit >- * notifications. TODO This is a workaround, see Bug 294700 >- */ >- private Object commitLock = new Object(); >- >- @ExcludeFromDump >- private QueueRunner invalidationRunner; >- >- @ExcludeFromDump >- private Object invalidationRunnerLock = new Object(); >- >- @ExcludeFromDump >- private static ThreadLocal<Boolean> invalidationRunnerActive = new InheritableThreadLocal<Boolean>(); >- >- @ExcludeFromDump >- private int lastViewID; >- >- public CDOSessionImpl(InternalCDOSessionConfiguration configuration) >- { >- this.configuration = configuration; >- } >- >- public InternalCDOSessionConfiguration getConfiguration() >- { >- return configuration; >- } >- >- public CDORepositoryInfo getRepositoryInfo() >- { >- return repositoryInfo; >- } >- >- public void setRepositoryInfo(CDORepositoryInfo repositoryInfo) >- { >- this.repositoryInfo = repositoryInfo; >- } >- >- public int getSessionID() >- { >- return sessionID; >- } >- >- public void setSessionID(int sessionID) >- { >- this.sessionID = sessionID; >- } >- >- public String getUserID() >- { >- return userID; >- } >- >- public void setUserID(String userID) >- { >- this.userID = userID; >- } >- >- public ExceptionHandler getExceptionHandler() >- { >- return exceptionHandler; >- } >- >- public void setExceptionHandler(ExceptionHandler exceptionHandler) >- { >- checkInactive(); >- this.exceptionHandler = exceptionHandler; >- } >- >- /** >- * @since 2.0 >- */ >- public CDOSession.Options options() >- { >- return options; >- } >- >- /** >- * @since 2.0 >- */ >- protected CDOSession.Options createOptions() >- { >- return new OptionsImpl(); >- } >- >- public CDOSessionProtocol getSessionProtocol() >- { >- return sessionProtocol; >- } >- >- public void setSessionProtocol(CDOSessionProtocol sessionProtocol) >- { >- this.sessionProtocol = sessionProtocol; >- } >- >- public void close() >- { >- LifecycleUtil.deactivate(this, OMLogger.Level.DEBUG); >- } >- >- /** >- * @since 2.0 >- */ >- public boolean isClosed() >- { >- return !isActive(); >- } >- >- public Object processPackage(Object value) >- { >- CDOFactoryImpl.prepareDynamicEPackage(value); >- return value; >- } >- >- public EPackage[] loadPackages(CDOPackageUnit packageUnit) >- { >- if (packageUnit.getOriginalType().isGenerated()) >- { >- if (!options().isGeneratedPackageEmulationEnabled()) >- { >- throw new CDOException(MessageFormat.format(Messages.getString("CDOSessionImpl.0"), packageUnit)); >- } >- } >- >- return getSessionProtocol().loadPackages(packageUnit); >- } >- >- public void acquireAtomicRequestLock(Object key) >- { >- try >- { >- lockmanager.lock(LockType.WRITE, key, this, RWLockManager.WAIT); >- } >- catch (InterruptedException ex) >- { >- throw WrappedException.wrap(ex); >- } >- } >- >- public void releaseAtomicRequestLock(Object key) >- { >- lockmanager.unlock(LockType.WRITE, key, singletonCollection); >- } >- >- /** >- * @since 3.0 >- */ >- public CDOFetchRuleManager getFetchRuleManager() >- { >- return ruleManager; >- } >- >- /** >- * @since 3.0 >- */ >- public void setFetchRuleManager(CDOFetchRuleManager fetchRuleManager) >- { >- ruleManager = fetchRuleManager; >- } >- >- public CDOAuthenticator getAuthenticator() >- { >- return authenticator; >- } >- >- public void setAuthenticator(CDOAuthenticator authenticator) >- { >- this.authenticator = authenticator; >- } >- >- public InternalCDORemoteSessionManager getRemoteSessionManager() >- { >- return remoteSessionManager; >- } >- >- public void setRemoteSessionManager(InternalCDORemoteSessionManager remoteSessionManager) >- { >- this.remoteSessionManager = remoteSessionManager; >- } >- >- /** >- * @since 2.0 >- */ >- public InternalCDOTransaction openTransaction(ResourceSet resourceSet) >- { >- checkActive(); >- InternalCDOTransaction transaction = createTransaction(); >- initView(transaction, resourceSet); >- return transaction; >- } >- >- /** >- * @since 2.0 >- */ >- public InternalCDOTransaction openTransaction() >- { >- return openTransaction(createResourceSet()); >- } >- >- /** >- * @since 2.0 >- */ >- protected InternalCDOTransaction createTransaction() >- { >- return new CDOTransactionImpl(); >- } >- >- /** >- * @since 2.0 >- */ >- public InternalCDOView openView(ResourceSet resourceSet) >- { >- checkActive(); >- InternalCDOView view = createView(); >- initView(view, resourceSet); >- return view; >- } >- >- /** >- * @since 2.0 >- */ >- public InternalCDOView openView() >- { >- return openView(createResourceSet()); >- } >- >- /** >- * @since 2.0 >- */ >- protected InternalCDOView createView() >- { >- return new CDOViewImpl(); >- } >- >- public CDOAuditImpl openAudit(ResourceSet resourceSet, long timeStamp) >- { >- checkActive(); >- CDOAuditImpl audit = createAudit(timeStamp); >- initView(audit, resourceSet); >- return audit; >- } >- >- public CDOAuditImpl openAudit(long timeStamp) >- { >- return openAudit(createResourceSet(), timeStamp); >- } >- >- /** >- * @since 2.0 >- */ >- protected CDOAuditImpl createAudit(long timeStamp) >- { >- return new CDOAuditImpl(timeStamp); >- } >- >- /** >- * @since 2.0 >- */ >- public void viewDetached(InternalCDOView view) >- { >- // Detach viewset from the view >- view.getViewSet().remove(view); >- synchronized (views) >- { >- if (!views.remove(view)) >- { >- return; >- } >- } >- >- if (isActive()) >- { >- try >- { >- LifecycleUtil.deactivate(view); >- } >- catch (Exception ex) >- { >- throw WrappedException.wrap(ex); >- } >- } >- >- fireElementRemovedEvent(view); >- } >- >- public CDOView getView(int viewID) >- { >- checkActive(); >- for (InternalCDOView view : getViews()) >- { >- if (view.getViewID() == viewID) >- { >- return view; >- } >- } >- >- return null; >- } >- >- /** >- * @since 2.0 >- */ >- public InternalCDOView[] getViews() >- { >- checkActive(); >- synchronized (views) >- { >- return views.toArray(new InternalCDOView[views.size()]); >- } >- } >- >- public CDOView[] getElements() >- { >- return getViews(); >- } >- >- @Override >- public boolean isEmpty() >- { >- checkActive(); >- return views.isEmpty(); >- } >- >- /** >- * @since 2.0 >- */ >- public Collection<CDOTimeStampContext> refresh() >- { >- // If passive update is turned on we don`t need to refresh. >- // We do not throw an exception since the client could turn >- // that feature on or off without affecting their code. >- checkActive(); >- if (!options().isPassiveUpdateEnabled()) >- { >- Map<CDOID, CDOIDAndVersion> allRevisions = getAllCDOIDAndVersion(); >- >- try >- { >- if (!allRevisions.isEmpty()) >- { >- int initialChunkSize = options().getCollectionLoadingPolicy().getInitialChunkSize(); >- return getSessionProtocol().syncRevisions(allRevisions, initialChunkSize); >- } >- } >- catch (Exception ex) >- { >- throw WrappedException.wrap(ex); >- } >- } >- >- return Collections.emptyList(); >- } >- >- public long getLastUpdateTime() >- { >- synchronized (lastUpdateTimeLock) >- { >- return lastUpdateTime; >- } >- } >- >- public void setLastUpdateTime(long lastUpdateTime) >- { >- synchronized (lastUpdateTimeLock) >- { >- this.lastUpdateTime = lastUpdateTime; >- lastUpdateTimeLock.notifyAll(); >- } >- } >- >- public void waitForUpdate(long updateTime) >- { >- waitForUpdate(updateTime, NO_TIMEOUT); >- } >- >- public boolean waitForUpdate(long updateTime, long timeoutMillis) >- { >- long end = timeoutMillis == NO_TIMEOUT ? Long.MAX_VALUE : System.currentTimeMillis() + timeoutMillis; >- for (;;) >- { >- synchronized (lastUpdateTimeLock) >- { >- if (lastUpdateTime >= updateTime) >- { >- return true; >- } >- >- long now = System.currentTimeMillis(); >- if (now >= end) >- { >- return false; >- } >- >- try >- { >- lastUpdateTimeLock.wait(end - now); >- } >- catch (InterruptedException ex) >- { >- throw WrappedException.wrap(ex); >- } >- } >- } >- } >- >- /** >- * @since 3.0 >- */ >- public Object resolveElementProxy(CDORevision revision, EStructuralFeature feature, int accessIndex, int serverIndex) >- { >- CDOCollectionLoadingPolicy policy = options().getCollectionLoadingPolicy(); >- return policy.resolveProxy(this, revision, feature, accessIndex, serverIndex); >- } >- >- /** >- * @since 2.0 >- */ >- public void handleSyncResponse(long timestamp, Collection<CDOPackageUnit> newPackageUnits, >- Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects) >- { >- handleCommitNotification(timestamp, newPackageUnits, dirtyOIDs, detachedObjects, null, null, true, false); >- } >- >- /** >- * @since 2.0 >- */ >- public void handleCommitNotification(final long timeStamp, final Collection<CDOPackageUnit> newPackageUnits, >- Set<CDOIDAndVersion> dirtyOIDs, final Collection<CDOID> detachedObjects, >- final Collection<CDORevisionDelta> deltas, InternalCDOView excludedView) >- { >- handleCommitNotification(timeStamp, newPackageUnits, dirtyOIDs, detachedObjects, deltas, excludedView, options() >- .isPassiveUpdateEnabled(), true); >- } >- >- private void handleCommitNotification(final long timeStamp, final Collection<CDOPackageUnit> newPackageUnits, >- Set<CDOIDAndVersion> dirtyOIDs, final Collection<CDOID> detachedObjects, >- final Collection<CDORevisionDelta> deltas, InternalCDOView excludedView, final boolean passiveUpdate, >- final boolean async) >- { >- try >- { >- synchronized (commitLock) >- { >- if (passiveUpdate) >- { >- reviseRevisions(timeStamp, dirtyOIDs, detachedObjects, excludedView); >- } >- >- final Set<CDOIDAndVersion> finalDirtyOIDs = Collections.unmodifiableSet(dirtyOIDs); >- final Collection<CDOID> finalDetachedObjects = Collections.unmodifiableCollection(detachedObjects); >- final boolean skipChangeSubscription = (deltas == null || deltas.size() <= 0) >- && (detachedObjects == null || detachedObjects.size() <= 0); >- >- for (final InternalCDOView view : getViews()) >- { >- if (view != excludedView) >- { >- final Runnable runnable = new Runnable() >- { >- public void run() >- { >- try >- { >- Set<CDOObject> conflicts = null; >- if (passiveUpdate) >- { >- conflicts = view.handleInvalidation(timeStamp, finalDirtyOIDs, finalDetachedObjects); >- } >- >- if (!skipChangeSubscription) >- { >- view.handleChangeSubscription(deltas, detachedObjects); >- } >- >- if (conflicts != null) >- { >- ((InternalCDOTransaction)view).handleConflicts(conflicts); >- } >- >- view.fireAdaptersNotifiedEvent(timeStamp); >- } >- catch (RuntimeException ex) >- { >- if (!async) >- { >- throw ex; >- } >- >- if (view.isActive()) >- { >- OM.LOG.error(ex); >- } >- else >- { >- OM.LOG.info(Messages.getString("CDOSessionImpl.1")); >- } >- } >- } >- }; >- >- if (async) >- { >- QueueRunner runner = getInvalidationRunner(); >- runner.addWork(new Runnable() >- { >- public void run() >- { >- try >- { >- invalidationRunnerActive.set(true); >- runnable.run(); >- } >- finally >- { >- invalidationRunnerActive.set(false); >- } >- } >- }); >- } >- else >- { >- runnable.run(); >- } >- } >- } >- } >- } >- catch (RuntimeException ex) >- { >- if (!async) >- { >- throw ex; >- } >- >- if (isActive()) >- { >- OM.LOG.error(ex); >- } >- else >- { >- OM.LOG.info(Messages.getString("CDOSessionImpl.2")); >- } >- } >- >- setLastUpdateTime(timeStamp); >- fireInvalidationEvent(timeStamp, newPackageUnits, dirtyOIDs, detachedObjects, excludedView); >- } >- >- public void reviseRevisions(final long timeStamp, Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects, >- InternalCDOView excludedView) >- { >- InternalCDORevisionManager revisionManager = getRevisionManager(); >- if (excludedView == null || timeStamp == CDORevision.UNSPECIFIED_DATE) >- { >- for (CDOIDAndVersion dirtyOID : dirtyOIDs) >- { >- CDOID id = dirtyOID.getID(); >- int version = dirtyOID.getVersion(); >- revisionManager.reviseVersion(id, version, timeStamp); >- } >- } >- >- for (CDOID id : detachedObjects) >- { >- revisionManager.reviseLatest(id); >- } >- } >- >- public Object getCommitLock() >- { >- return commitLock; >- } >- >- private QueueRunner getInvalidationRunner() >- { >- synchronized (invalidationRunnerLock) >- { >- if (invalidationRunner == null) >- { >- invalidationRunner = createInvalidationRunner(); >- invalidationRunner.activate(); >- } >- } >- >- return invalidationRunner; >- } >- >- protected QueueRunner createInvalidationRunner() >- { >- return new QueueRunner() >- { >- @Override >- protected String getThreadName() >- { >- return "InvalidationRunner"; >- } >- >- @Override >- public String toString() >- { >- return getThreadName(); >- } >- }; >- } >- >- /** >- * @param packageUnits >- * @since 2.0 >- */ >- public void fireInvalidationEvent(long timeStamp, Collection<CDOPackageUnit> packageUnits, >- Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects, InternalCDOView excludedView) >- { >- fireEvent(new InvalidationEvent(excludedView, timeStamp, packageUnits, dirtyOIDs, detachedObjects)); >- } >- >- @Override >- public String toString() >- { >- String name = repositoryInfo == null ? "?" : repositoryInfo.getName(); >- return MessageFormat.format("CDOSession[{0}, {1}]", name, sessionID); >- } >- >- protected ResourceSet createResourceSet() >- { >- return new ResourceSetImpl(); >- } >- >- /** >- * @since 2.0 >- */ >- protected void initView(InternalCDOView view, ResourceSet resourceSet) >- { >- if (TRACER.isEnabled()) >- { >- TRACER.format("Initializing new {0} view", view.getViewType()); >- } >- >- InternalCDOViewSet viewSet = SessionUtil.prepareResourceSet(resourceSet); >- synchronized (views) >- { >- view.setSession(this); >- view.setViewID(++lastViewID); >- views.add(view); >- } >- >- // Link ViewSet with View >- view.setViewSet(viewSet); >- viewSet.add(view); >- >- try >- { >- view.activate(); >- fireElementAddedEvent(view); >- } >- catch (RuntimeException ex) >- { >- synchronized (views) >- { >- views.remove(view); >- } >- >- viewSet.remove(view); >- throw ex; >- } >- } >- >- @Override >- protected void doActivate() throws Exception >- { >- super.doActivate(); >- getConfiguration().activateSession(this); >- checkState(sessionProtocol, "sessionProtocol"); >- checkState(remoteSessionManager, "remoteSessionManager"); >- if (exceptionHandler != null) >- { >- sessionProtocol = new DelegatingSessionProtocol(sessionProtocol); >- } >- >- EventUtil.addListener(sessionProtocol, sessionProtocolListener); >- } >- >- @Override >- protected void doDeactivate() throws Exception >- { >- for (InternalCDOView view : views.toArray(new InternalCDOView[views.size()])) >- { >- try >- { >- view.close(); >- } >- catch (RuntimeException ignore) >- { >- } >- } >- >- views.clear(); >- >- if (invalidationRunner != null) >- { >- LifecycleUtil.deactivate(invalidationRunner, OMLogger.Level.WARN); >- invalidationRunner = null; >- } >- >- EventUtil.removeListener(sessionProtocol, sessionProtocolListener); >- getConfiguration().deactivateSession(this); >- super.doDeactivate(); >- } >- >- private Map<CDOID, CDOIDAndVersion> getAllCDOIDAndVersion() >- { >- Map<CDOID, CDOIDAndVersion> uniqueObjects = new HashMap<CDOID, CDOIDAndVersion>(); >- for (InternalCDOView view : getViews()) >- { >- view.getCDOIDAndVersion(uniqueObjects, Arrays.asList(view.getObjectsArray())); >- } >- >- // Need to add Revision from revisionManager since we do not have all objects in view. >- for (CDORevision revision : getRevisionManager().getCache().getRevisions()) >- { >- if (!uniqueObjects.containsKey(revision.getID())) >- { >- uniqueObjects.put(revision.getID(), CDOIDUtil.createIDAndVersion(revision.getID(), revision.getVersion())); >- } >- } >- >- return uniqueObjects; >- } >- >- public static boolean isInvalidationRunnerActive() >- { >- return invalidationRunnerActive.get(); >- } >- >- /** >- * @author Eike Stepper >- * @since 2.0 >- */ >- protected class OptionsImpl extends Notifier implements Options >- { >- private boolean generatedPackageEmulationEnabled = false; >- >- private boolean passiveUpdateEnabled = true; >- >- private CDOCollectionLoadingPolicy collectionLoadingPolicy; >- >- public OptionsImpl() >- { >- // TODO Remove preferences from core >- int value = OM.PREF_COLLECTION_LOADING_CHUNK_SIZE.getValue(); >- collectionLoadingPolicy = CDOUtil.createCollectionLoadingPolicy(value, value); >- } >- >- public IOptionsContainer getContainer() >- { >- return CDOSessionImpl.this; >- } >- >- public boolean isGeneratedPackageEmulationEnabled() >- { >- return generatedPackageEmulationEnabled; >- } >- >- public synchronized void setGeneratedPackageEmulationEnabled(boolean generatedPackageEmulationEnabled) >- { >- this.generatedPackageEmulationEnabled = generatedPackageEmulationEnabled; >- if (this.generatedPackageEmulationEnabled != generatedPackageEmulationEnabled) >- { >- this.generatedPackageEmulationEnabled = generatedPackageEmulationEnabled; >- // TODO Check inconsistent state if switching off? >- >- IListener[] listeners = getListeners(); >- if (listeners != null) >- { >- fireEvent(new GeneratedPackageEmulationEventImpl(), listeners); >- } >- } >- } >- >- public boolean isPassiveUpdateEnabled() >- { >- return passiveUpdateEnabled; >- } >- >- public synchronized void setPassiveUpdateEnabled(boolean passiveUpdateEnabled) >- { >- if (this.passiveUpdateEnabled != passiveUpdateEnabled) >- { >- this.passiveUpdateEnabled = passiveUpdateEnabled; >- >- // Need to refresh if we change state >- Map<CDOID, CDOIDAndVersion> allRevisions = getAllCDOIDAndVersion(); >- if (!allRevisions.isEmpty()) >- { >- int initialChunkSize = collectionLoadingPolicy.getInitialChunkSize(); >- getSessionProtocol().setPassiveUpdate(allRevisions, initialChunkSize, passiveUpdateEnabled); >- } >- >- IListener[] listeners = getListeners(); >- if (listeners != null) >- { >- fireEvent(new PassiveUpdateEventImpl(), listeners); >- } >- } >- } >- >- public CDOCollectionLoadingPolicy getCollectionLoadingPolicy() >- { >- return collectionLoadingPolicy; >- } >- >- public synchronized void setCollectionLoadingPolicy(CDOCollectionLoadingPolicy policy) >- { >- if (policy == null) >- { >- policy = CDOCollectionLoadingPolicy.DEFAULT; >- } >- >- if (collectionLoadingPolicy != policy) >- { >- collectionLoadingPolicy = policy; >- IListener[] listeners = getListeners(); >- if (listeners != null) >- { >- fireEvent(new CollectionLoadingPolicyEventImpl(), listeners); >- } >- } >- } >- >- /** >- * @author Eike Stepper >- */ >- private final class GeneratedPackageEmulationEventImpl extends OptionsEvent implements >- GeneratedPackageEmulationEvent >- { >- private static final long serialVersionUID = 1L; >- >- public GeneratedPackageEmulationEventImpl() >- { >- super(OptionsImpl.this); >- } >- } >- >- /** >- * @author Eike Stepper >- */ >- private final class PassiveUpdateEventImpl extends OptionsEvent implements PassiveUpdateEvent >- { >- private static final long serialVersionUID = 1L; >- >- public PassiveUpdateEventImpl() >- { >- super(OptionsImpl.this); >- } >- } >- >- /** >- * @author Eike Stepper >- */ >- private final class CollectionLoadingPolicyEventImpl extends OptionsEvent implements CollectionLoadingPolicyEvent >- { >- private static final long serialVersionUID = 1L; >- >- public CollectionLoadingPolicyEventImpl() >- { >- super(OptionsImpl.this); >- } >- } >- } >- >- /** >- * @author Eike Stepper >- */ >- private final class InvalidationEvent extends Event implements CDOSessionInvalidationEvent >- { >- private static final long serialVersionUID = 1L; >- >- private InternalCDOView view; >- >- private long timeStamp; >- >- private Set<CDOIDAndVersion> dirtyOIDs; >- >- private Collection<CDOID> detachedObjects; >- >- private Collection<CDOPackageUnit> newPackageUnits; >- >- public InvalidationEvent(InternalCDOView view, long timeStamp, Collection<CDOPackageUnit> packageUnits, >- Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects) >- { >- super(CDOSessionImpl.this); >- this.view = view; >- this.timeStamp = timeStamp; >- newPackageUnits = packageUnits; >- this.dirtyOIDs = dirtyOIDs; >- this.detachedObjects = detachedObjects; >- } >- >- @Override >- public CDOSession getSource() >- { >- return (CDOSession)super.getSource(); >- } >- >- public InternalCDOView getView() >- { >- return view; >- } >- >- public boolean isRemote() >- { >- return view == null; >- } >- >- public long getTimeStamp() >- { >- return timeStamp; >- } >- >- public Set<CDOIDAndVersion> getDirtyOIDs() >- { >- return dirtyOIDs; >- } >- >- public Collection<CDOID> getDetachedObjects() >- { >- return detachedObjects; >- } >- >- public Collection<CDOPackageUnit> getNewPackageUnits() >- { >- return newPackageUnits; >- } >- >- @Override >- public String toString() >- { >- return "CDOSessionInvalidationEvent: " + dirtyOIDs; >- } >- } >- >- /** >- * @author Eike Stepper >- */ >- public class DelegatingSessionProtocol extends Lifecycle implements CDOSessionProtocol >- { >- private CDOSessionProtocol delegate; >- >- @ExcludeFromDump >- private IListener delegateListener = new LifecycleEventAdapter() >- { >- @Override >- protected void onDeactivated(ILifecycle lifecycle) >- { >- DelegatingSessionProtocol.this.deactivate(); >- } >- }; >- >- public DelegatingSessionProtocol(CDOSessionProtocol delegate) >- { >- this.delegate = delegate; >- activate(); >- } >- >- public CDOSessionProtocol getDelegate() >- { >- return delegate; >- } >- >- public CDOSession getSession() >- { >- return (CDOSession)delegate.getSession(); >- } >- >- public boolean cancelQuery(int queryId) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.cancelQuery(queryId); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public void changeSubscription(int viewId, List<CDOID> cdoIDs, boolean subscribeMode, boolean clear) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- delegate.changeSubscription(viewId, cdoIDs, subscribeMode, clear); >- return; >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public void closeView(int viewId) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- delegate.closeView(viewId); >- return; >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public CommitTransactionResult commitTransaction(InternalCDOCommitContext commitContext, OMMonitor monitor) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.commitTransaction(commitContext, monitor); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public CommitTransactionResult commitTransactionCancel(InternalCDOXACommitContext xaContext, OMMonitor monitor) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.commitTransactionCancel(xaContext, monitor); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public CommitTransactionResult commitTransactionPhase1(InternalCDOXACommitContext xaContext, OMMonitor monitor) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.commitTransactionPhase1(xaContext, monitor); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public CommitTransactionResult commitTransactionPhase2(InternalCDOXACommitContext xaContext, OMMonitor monitor) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.commitTransactionPhase2(xaContext, monitor); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public CommitTransactionResult commitTransactionPhase3(InternalCDOXACommitContext xaContext, OMMonitor monitor) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.commitTransactionPhase3(xaContext, monitor); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public RepositoryTimeResult getRepositoryTime() >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.getRepositoryTime(); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public boolean isObjectLocked(CDOView view, CDOObject object, LockType lockType, boolean byOthers) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.isObjectLocked(view, object, lockType, byOthers); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public EPackage[] loadPackages(CDOPackageUnit packageUnit) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.loadPackages(packageUnit); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public Object loadChunk(InternalCDORevision revision, EStructuralFeature feature, int accessIndex, int fetchIndex, >- int fromIndex, int toIndex) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.loadChunk(revision, feature, accessIndex, fetchIndex, fromIndex, toIndex); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public InternalCDORevision loadRevision(CDOID id, int referenceChunk, int prefetchDepth) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.loadRevision(id, referenceChunk, prefetchDepth); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public InternalCDORevision loadRevisionByTime(CDOID id, int referenceChunk, int prefetchDepth, long timeStamp) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.loadRevisionByTime(id, referenceChunk, prefetchDepth, timeStamp); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public InternalCDORevision loadRevisionByVersion(CDOID id, int referenceChunk, int prefetchDepth, int version) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.loadRevisionByVersion(id, referenceChunk, prefetchDepth, version); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public List<InternalCDORevision> loadRevisions(Collection<CDOID> ids, int referenceChunk, int prefetchDepth) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.loadRevisions(ids, referenceChunk, prefetchDepth); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public List<InternalCDORevision> loadRevisionsByTime(Collection<CDOID> ids, int referenceChunk, int prefetchDepth, >- long timeStamp) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.loadRevisionsByTime(ids, referenceChunk, prefetchDepth, timeStamp); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public InternalCDORevision verifyRevision(InternalCDORevision revision, int referenceChunk) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.verifyRevision(revision, referenceChunk); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public void lockObjects(CDOView view, Map<CDOID, CDOIDAndVersion> objects, long timeout, LockType lockType) >- throws InterruptedException >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- delegate.lockObjects(view, objects, timeout, lockType); >- return; >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public void openView(int viewId, CDOCommonView.Type viewType, long timeStamp) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- delegate.openView(viewId, viewType, timeStamp); >- return; >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public void query(int viewID, AbstractQueryIterator<?> queryResult) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- delegate.query(viewID, queryResult); >- return; >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public boolean[] setAudit(int viewId, long timeStamp, List<InternalCDOObject> invalidObjects) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.setAudit(viewId, timeStamp, invalidObjects); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public void setPassiveUpdate(Map<CDOID, CDOIDAndVersion> idAndVersions, int initialChunkSize, >- boolean passiveUpdateEnabled) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- delegate.setPassiveUpdate(idAndVersions, initialChunkSize, passiveUpdateEnabled); >- return; >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public Collection<CDOTimeStampContext> syncRevisions(Map<CDOID, CDOIDAndVersion> allRevisions, int initialChunkSize) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.syncRevisions(allRevisions, initialChunkSize); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public void unlockObjects(CDOView view, Collection<? extends CDOObject> objects, LockType lockType) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- delegate.unlockObjects(view, objects, lockType); >- return; >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public List<CDORemoteSession> getRemoteSessions(InternalCDORemoteSessionManager manager, boolean subscribe) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.getRemoteSessions(manager, subscribe); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public Set<Integer> sendRemoteMessage(CDORemoteSessionMessage message, List<CDORemoteSession> recipients) >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.sendRemoteMessage(message, recipients); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- public boolean unsubscribeRemoteSessions() >- { >- int attempt = 0; >- for (;;) >- { >- try >- { >- return delegate.unsubscribeRemoteSessions(); >- } >- catch (Exception ex) >- { >- handleException(++attempt, ex); >- } >- } >- } >- >- @Override >- protected void doActivate() throws Exception >- { >- super.doActivate(); >- EventUtil.addListener(delegate, delegateListener); >- } >- >- @Override >- protected void doDeactivate() throws Exception >- { >- EventUtil.removeListener(delegate, delegateListener); >- LifecycleUtil.deactivate(delegate); >- delegate = null; >- super.doDeactivate(); >- } >- >- private void handleException(int attempt, Exception exception) >- { >- try >- { >- getExceptionHandler().handleException(CDOSessionImpl.this, attempt, exception); >- } >- catch (Exception ex) >- { >- throw WrappedException.wrap(ex); >- } >- } >- } >+public abstract class CDOSessionImpl extends Container<CDOView> implements >+ InternalCDOSession { >+ private static final ContextTracer TRACER = new ContextTracer( >+ OM.DEBUG_SESSION, CDOSessionImpl.class); >+ >+ private static final long NO_TIMEOUT = -1; >+ >+ private InternalCDOSessionConfiguration configuration; >+ >+ private ExceptionHandler exceptionHandler; >+ >+ private CDOSessionProtocol sessionProtocol; >+ >+ @ExcludeFromDump >+ private IListener sessionProtocolListener = new LifecycleEventAdapter() { >+ @Override >+ protected void onDeactivated(ILifecycle lifecycle) { >+ CDOSessionImpl.this.deactivate(); >+ } >+ }; >+ >+ private int sessionID; >+ >+ private String userID; >+ >+ private long lastUpdateTime; >+ >+ @ExcludeFromDump >+ private Object lastUpdateTimeLock = new Object(); >+ >+ private CDOSession.Options options = createOptions(); >+ >+ private CDORepositoryInfo repositoryInfo; >+ >+ private CDOFetchRuleManager ruleManager = CDOFetchRuleManager.NOOP; >+ >+ private IRWLockManager<CDOSessionImpl, Object> lockmanager = new RWLockManager<CDOSessionImpl, Object>(); >+ >+ @ExcludeFromDump >+ private Set<CDOSessionImpl> singletonCollection = Collections >+ .singleton(this); >+ >+ private CDOAuthenticator authenticator; >+ >+ private InternalCDORemoteSessionManager remoteSessionManager; >+ >+ private Set<InternalCDOView> views = new HashSet<InternalCDOView>(); >+ >+ /** >+ * Fixes a threading problem between a committing thread and the Net4j >+ * thread that delivers incoming commit notifications. TODO This is a >+ * workaround, see Bug 294700 >+ */ >+ private Object commitLock = new Object(); >+ >+ @ExcludeFromDump >+ private QueueRunner invalidationRunner; >+ >+ @ExcludeFromDump >+ private Object invalidationRunnerLock = new Object(); >+ >+ @ExcludeFromDump >+ private static ThreadLocal<Boolean> invalidationRunnerActive = new InheritableThreadLocal<Boolean>(); >+ >+ @ExcludeFromDump >+ private int lastViewID; >+ >+ private Set<InternalCDOView> registeredLockListeners = new HashSet<InternalCDOView>(); >+ >+ private boolean hasRegisteredListeners; >+ >+ public CDOSessionImpl(InternalCDOSessionConfiguration configuration) { >+ this.configuration = configuration; >+ } >+ >+ public InternalCDOSessionConfiguration getConfiguration() { >+ return configuration; >+ } >+ >+ public CDORepositoryInfo getRepositoryInfo() { >+ return repositoryInfo; >+ } >+ >+ public void setRepositoryInfo(CDORepositoryInfo repositoryInfo) { >+ this.repositoryInfo = repositoryInfo; >+ } >+ >+ public int getSessionID() { >+ return sessionID; >+ } >+ >+ public void setSessionID(int sessionID) { >+ this.sessionID = sessionID; >+ } >+ >+ public String getUserID() { >+ return userID; >+ } >+ >+ public void setUserID(String userID) { >+ this.userID = userID; >+ } >+ >+ public ExceptionHandler getExceptionHandler() { >+ return exceptionHandler; >+ } >+ >+ public void setExceptionHandler(ExceptionHandler exceptionHandler) { >+ checkInactive(); >+ this.exceptionHandler = exceptionHandler; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public CDOSession.Options options() { >+ return options; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ protected CDOSession.Options createOptions() { >+ return new OptionsImpl(); >+ } >+ >+ public CDOSessionProtocol getSessionProtocol() { >+ return sessionProtocol; >+ } >+ >+ public void setSessionProtocol(CDOSessionProtocol sessionProtocol) { >+ this.sessionProtocol = sessionProtocol; >+ } >+ >+ public void close() { >+ LifecycleUtil.deactivate(this, OMLogger.Level.DEBUG); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public boolean isClosed() { >+ return !isActive(); >+ } >+ >+ public Object processPackage(Object value) { >+ CDOFactoryImpl.prepareDynamicEPackage(value); >+ return value; >+ } >+ >+ public EPackage[] loadPackages(CDOPackageUnit packageUnit) { >+ if (packageUnit.getOriginalType().isGenerated()) { >+ if (!options().isGeneratedPackageEmulationEnabled()) { >+ throw new CDOException(MessageFormat.format(Messages >+ .getString("CDOSessionImpl.0"), packageUnit)); >+ } >+ } >+ >+ return getSessionProtocol().loadPackages(packageUnit); >+ } >+ >+ public void acquireAtomicRequestLock(Object key) { >+ try { >+ lockmanager.lock(LockType.WRITE, key, this, RWLockManager.WAIT); >+ } catch (InterruptedException ex) { >+ throw WrappedException.wrap(ex); >+ } >+ } >+ >+ public void releaseAtomicRequestLock(Object key) { >+ lockmanager.unlock(LockType.WRITE, key, singletonCollection); >+ } >+ >+ /** >+ * @since 3.0 >+ */ >+ public CDOFetchRuleManager getFetchRuleManager() { >+ return ruleManager; >+ } >+ >+ /** >+ * @since 3.0 >+ */ >+ public void setFetchRuleManager(CDOFetchRuleManager fetchRuleManager) { >+ ruleManager = fetchRuleManager; >+ } >+ >+ public CDOAuthenticator getAuthenticator() { >+ return authenticator; >+ } >+ >+ public void setAuthenticator(CDOAuthenticator authenticator) { >+ this.authenticator = authenticator; >+ } >+ >+ public InternalCDORemoteSessionManager getRemoteSessionManager() { >+ return remoteSessionManager; >+ } >+ >+ public void setRemoteSessionManager( >+ InternalCDORemoteSessionManager remoteSessionManager) { >+ this.remoteSessionManager = remoteSessionManager; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public InternalCDOTransaction openTransaction(ResourceSet resourceSet) { >+ checkActive(); >+ InternalCDOTransaction transaction = createTransaction(); >+ initView(transaction, resourceSet); >+ return transaction; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public InternalCDOTransaction openTransaction() { >+ return openTransaction(createResourceSet()); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ protected InternalCDOTransaction createTransaction() { >+ return new CDOTransactionImpl(); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public InternalCDOView openView(ResourceSet resourceSet) { >+ checkActive(); >+ InternalCDOView view = createView(); >+ initView(view, resourceSet); >+ return view; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public InternalCDOView openView() { >+ return openView(createResourceSet()); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ protected InternalCDOView createView() { >+ return new CDOViewImpl(); >+ } >+ >+ public CDOAuditImpl openAudit(ResourceSet resourceSet, long timeStamp) { >+ checkActive(); >+ CDOAuditImpl audit = createAudit(timeStamp); >+ initView(audit, resourceSet); >+ return audit; >+ } >+ >+ public CDOAuditImpl openAudit(long timeStamp) { >+ return openAudit(createResourceSet(), timeStamp); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ protected CDOAuditImpl createAudit(long timeStamp) { >+ return new CDOAuditImpl(timeStamp); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public void viewDetached(InternalCDOView view) { >+ // Detach viewset from the view >+ view.getViewSet().remove(view); >+ synchronized (views) { >+ if (!views.remove(view)) { >+ return; >+ } >+ } >+ >+ if (isActive()) { >+ try { >+ LifecycleUtil.deactivate(view); >+ } catch (Exception ex) { >+ throw WrappedException.wrap(ex); >+ } >+ } >+ >+ fireElementRemovedEvent(view); >+ } >+ >+ public CDOView getView(int viewID) { >+ checkActive(); >+ for (InternalCDOView view : getViews()) { >+ if (view.getViewID() == viewID) { >+ return view; >+ } >+ } >+ >+ return null; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public InternalCDOView[] getViews() { >+ checkActive(); >+ synchronized (views) { >+ return views.toArray(new InternalCDOView[views.size()]); >+ } >+ } >+ >+ public CDOView[] getElements() { >+ return getViews(); >+ } >+ >+ @Override >+ public boolean isEmpty() { >+ checkActive(); >+ return views.isEmpty(); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public Collection<CDOTimeStampContext> refresh() { >+ // If passive update is turned on we don`t need to refresh. >+ // We do not throw an exception since the client could turn >+ // that feature on or off without affecting their code. >+ checkActive(); >+ if (!options().isPassiveUpdateEnabled()) { >+ Map<CDOID, CDOIDAndVersion> allRevisions = getAllCDOIDAndVersion(); >+ >+ try { >+ if (!allRevisions.isEmpty()) { >+ int initialChunkSize = options() >+ .getCollectionLoadingPolicy().getInitialChunkSize(); >+ return getSessionProtocol().syncRevisions(allRevisions, >+ initialChunkSize); >+ } >+ } catch (Exception ex) { >+ throw WrappedException.wrap(ex); >+ } >+ } >+ >+ return Collections.emptyList(); >+ } >+ >+ public long getLastUpdateTime() { >+ synchronized (lastUpdateTimeLock) { >+ return lastUpdateTime; >+ } >+ } >+ >+ public void setLastUpdateTime(long lastUpdateTime) { >+ synchronized (lastUpdateTimeLock) { >+ this.lastUpdateTime = lastUpdateTime; >+ lastUpdateTimeLock.notifyAll(); >+ } >+ } >+ >+ public void waitForUpdate(long updateTime) { >+ waitForUpdate(updateTime, NO_TIMEOUT); >+ } >+ >+ public boolean waitForUpdate(long updateTime, long timeoutMillis) { >+ long end = timeoutMillis == NO_TIMEOUT ? Long.MAX_VALUE : System >+ .currentTimeMillis() >+ + timeoutMillis; >+ for (;;) { >+ synchronized (lastUpdateTimeLock) { >+ if (lastUpdateTime >= updateTime) { >+ return true; >+ } >+ >+ long now = System.currentTimeMillis(); >+ if (now >= end) { >+ return false; >+ } >+ >+ try { >+ lastUpdateTimeLock.wait(end - now); >+ } catch (InterruptedException ex) { >+ throw WrappedException.wrap(ex); >+ } >+ } >+ } >+ } >+ >+ /** >+ * @since 3.0 >+ */ >+ public Object resolveElementProxy(CDORevision revision, >+ EStructuralFeature feature, int accessIndex, int serverIndex) { >+ CDOCollectionLoadingPolicy policy = options() >+ .getCollectionLoadingPolicy(); >+ return policy.resolveProxy(this, revision, feature, accessIndex, >+ serverIndex); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public void handleSyncResponse(long timestamp, >+ Collection<CDOPackageUnit> newPackageUnits, >+ Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects) { >+ handleCommitNotification(timestamp, newPackageUnits, dirtyOIDs, >+ detachedObjects, null, null, true, false); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public void handleCommitNotification(final long timeStamp, >+ final Collection<CDOPackageUnit> newPackageUnits, >+ Set<CDOIDAndVersion> dirtyOIDs, >+ final Collection<CDOID> detachedObjects, >+ final Collection<CDORevisionDelta> deltas, >+ InternalCDOView excludedView) { >+ handleCommitNotification(timeStamp, newPackageUnits, dirtyOIDs, >+ detachedObjects, deltas, excludedView, options() >+ .isPassiveUpdateEnabled(), true); >+ } >+ >+ private void handleCommitNotification(final long timeStamp, >+ final Collection<CDOPackageUnit> newPackageUnits, >+ Set<CDOIDAndVersion> dirtyOIDs, >+ final Collection<CDOID> detachedObjects, >+ final Collection<CDORevisionDelta> deltas, >+ InternalCDOView excludedView, final boolean passiveUpdate, >+ final boolean async) { >+ try { >+ synchronized (commitLock) { >+ if (passiveUpdate) { >+ reviseRevisions(timeStamp, dirtyOIDs, detachedObjects, >+ excludedView); >+ } >+ >+ final Set<CDOIDAndVersion> finalDirtyOIDs = Collections >+ .unmodifiableSet(dirtyOIDs); >+ final Collection<CDOID> finalDetachedObjects = Collections >+ .unmodifiableCollection(detachedObjects); >+ final boolean skipChangeSubscription = (deltas == null || deltas >+ .size() <= 0) >+ && (detachedObjects == null || detachedObjects.size() <= 0); >+ >+ for (final InternalCDOView view : getViews()) { >+ if (view != excludedView) { >+ final Runnable runnable = new Runnable() { >+ public void run() { >+ try { >+ Set<CDOObject> conflicts = null; >+ if (passiveUpdate) { >+ conflicts = view.handleInvalidation( >+ timeStamp, finalDirtyOIDs, >+ finalDetachedObjects); >+ } >+ >+ if (!skipChangeSubscription) { >+ view.handleChangeSubscription(deltas, >+ detachedObjects); >+ } >+ >+ if (conflicts != null) { >+ ((InternalCDOTransaction) view) >+ .handleConflicts(conflicts); >+ } >+ >+ view.fireAdaptersNotifiedEvent(timeStamp); >+ } catch (RuntimeException ex) { >+ if (!async) { >+ throw ex; >+ } >+ >+ if (view.isActive()) { >+ OM.LOG.error(ex); >+ } else { >+ OM.LOG.info(Messages >+ .getString("CDOSessionImpl.1")); >+ } >+ } >+ } >+ }; >+ >+ if (async) { >+ QueueRunner runner = getInvalidationRunner(); >+ runner.addWork(new Runnable() { >+ public void run() { >+ try { >+ invalidationRunnerActive.set(true); >+ runnable.run(); >+ } finally { >+ invalidationRunnerActive.set(false); >+ } >+ } >+ }); >+ } else { >+ runnable.run(); >+ } >+ } >+ } >+ } >+ } catch (RuntimeException ex) { >+ if (!async) { >+ throw ex; >+ } >+ >+ if (isActive()) { >+ OM.LOG.error(ex); >+ } else { >+ OM.LOG.info(Messages.getString("CDOSessionImpl.2")); >+ } >+ } >+ >+ setLastUpdateTime(timeStamp); >+ fireInvalidationEvent(timeStamp, newPackageUnits, dirtyOIDs, >+ detachedObjects, excludedView); >+ } >+ >+ public void reviseRevisions(final long timeStamp, >+ Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects, >+ InternalCDOView excludedView) { >+ InternalCDORevisionManager revisionManager = getRevisionManager(); >+ if (excludedView == null || timeStamp == CDORevision.UNSPECIFIED_DATE) { >+ for (CDOIDAndVersion dirtyOID : dirtyOIDs) { >+ CDOID id = dirtyOID.getID(); >+ int version = dirtyOID.getVersion(); >+ revisionManager.reviseVersion(id, version, timeStamp); >+ } >+ } >+ >+ for (CDOID id : detachedObjects) { >+ revisionManager.reviseLatest(id); >+ } >+ } >+ >+ public Object getCommitLock() { >+ return commitLock; >+ } >+ >+ private QueueRunner getInvalidationRunner() { >+ synchronized (invalidationRunnerLock) { >+ if (invalidationRunner == null) { >+ invalidationRunner = createInvalidationRunner(); >+ invalidationRunner.activate(); >+ } >+ } >+ >+ return invalidationRunner; >+ } >+ >+ protected QueueRunner createInvalidationRunner() { >+ return new QueueRunner() { >+ @Override >+ protected String getThreadName() { >+ return "InvalidationRunner"; >+ } >+ >+ @Override >+ public String toString() { >+ return getThreadName(); >+ } >+ }; >+ } >+ >+ /** >+ * @param packageUnits >+ * @since 2.0 >+ */ >+ public void fireInvalidationEvent(long timeStamp, >+ Collection<CDOPackageUnit> packageUnits, >+ Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects, >+ InternalCDOView excludedView) { >+ fireEvent(new InvalidationEvent(excludedView, timeStamp, packageUnits, >+ dirtyOIDs, detachedObjects)); >+ } >+ >+ @Override >+ public String toString() { >+ String name = repositoryInfo == null ? "?" : repositoryInfo.getName(); >+ return MessageFormat.format("CDOSession[{0}, {1}]", name, sessionID); >+ } >+ >+ protected ResourceSet createResourceSet() { >+ return new ResourceSetImpl(); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ protected void initView(InternalCDOView view, ResourceSet resourceSet) { >+ if (TRACER.isEnabled()) { >+ TRACER.format("Initializing new {0} view", view.getViewType()); >+ } >+ >+ InternalCDOViewSet viewSet = SessionUtil >+ .prepareResourceSet(resourceSet); >+ synchronized (views) { >+ view.setSession(this); >+ view.setViewID(++lastViewID); >+ views.add(view); >+ } >+ >+ // Link ViewSet with View >+ view.setViewSet(viewSet); >+ viewSet.add(view); >+ >+ try { >+ view.activate(); >+ fireElementAddedEvent(view); >+ } catch (RuntimeException ex) { >+ synchronized (views) { >+ views.remove(view); >+ } >+ >+ viewSet.remove(view); >+ throw ex; >+ } >+ } >+ >+ @Override >+ protected void doActivate() throws Exception { >+ super.doActivate(); >+ getConfiguration().activateSession(this); >+ checkState(sessionProtocol, "sessionProtocol"); >+ checkState(remoteSessionManager, "remoteSessionManager"); >+ if (exceptionHandler != null) { >+ sessionProtocol = new DelegatingSessionProtocol(sessionProtocol); >+ } >+ >+ EventUtil.addListener(sessionProtocol, sessionProtocolListener); >+ } >+ >+ @Override >+ protected void doDeactivate() throws Exception { >+ for (InternalCDOView view : views.toArray(new InternalCDOView[views >+ .size()])) { >+ try { >+ view.close(); >+ } catch (RuntimeException ignore) { >+ } >+ } >+ >+ views.clear(); >+ >+ if (invalidationRunner != null) { >+ LifecycleUtil.deactivate(invalidationRunner, OMLogger.Level.WARN); >+ invalidationRunner = null; >+ } >+ >+ EventUtil.removeListener(sessionProtocol, sessionProtocolListener); >+ getConfiguration().deactivateSession(this); >+ super.doDeactivate(); >+ } >+ >+ private Map<CDOID, CDOIDAndVersion> getAllCDOIDAndVersion() { >+ Map<CDOID, CDOIDAndVersion> uniqueObjects = new HashMap<CDOID, CDOIDAndVersion>(); >+ for (InternalCDOView view : getViews()) { >+ view.getCDOIDAndVersion(uniqueObjects, Arrays.asList(view >+ .getObjectsArray())); >+ } >+ >+ // Need to add Revision from revisionManager since we do not have all >+ // objects in view. >+ for (CDORevision revision : getRevisionManager().getCache() >+ .getRevisions()) { >+ if (!uniqueObjects.containsKey(revision.getID())) { >+ uniqueObjects.put(revision.getID(), CDOIDUtil >+ .createIDAndVersion(revision.getID(), revision >+ .getVersion())); >+ } >+ } >+ >+ return uniqueObjects; >+ } >+ >+ public static boolean isInvalidationRunnerActive() { >+ return invalidationRunnerActive.get(); >+ } >+ >+ /** >+ * @author Eike Stepper >+ * @since 2.0 >+ */ >+ protected class OptionsImpl extends Notifier implements Options { >+ private boolean generatedPackageEmulationEnabled = false; >+ >+ private boolean passiveUpdateEnabled = true; >+ >+ private CDOCollectionLoadingPolicy collectionLoadingPolicy; >+ >+ public OptionsImpl() { >+ // TODO Remove preferences from core >+ int value = OM.PREF_COLLECTION_LOADING_CHUNK_SIZE.getValue(); >+ collectionLoadingPolicy = CDOUtil.createCollectionLoadingPolicy( >+ value, value); >+ } >+ >+ public IOptionsContainer getContainer() { >+ return CDOSessionImpl.this; >+ } >+ >+ public boolean isGeneratedPackageEmulationEnabled() { >+ return generatedPackageEmulationEnabled; >+ } >+ >+ public synchronized void setGeneratedPackageEmulationEnabled( >+ boolean generatedPackageEmulationEnabled) { >+ this.generatedPackageEmulationEnabled = generatedPackageEmulationEnabled; >+ if (this.generatedPackageEmulationEnabled != generatedPackageEmulationEnabled) { >+ this.generatedPackageEmulationEnabled = generatedPackageEmulationEnabled; >+ // TODO Check inconsistent state if switching off? >+ >+ IListener[] listeners = getListeners(); >+ if (listeners != null) { >+ fireEvent(new GeneratedPackageEmulationEventImpl(), >+ listeners); >+ } >+ } >+ } >+ >+ public boolean isPassiveUpdateEnabled() { >+ return passiveUpdateEnabled; >+ } >+ >+ public synchronized void setPassiveUpdateEnabled( >+ boolean passiveUpdateEnabled) { >+ if (this.passiveUpdateEnabled != passiveUpdateEnabled) { >+ this.passiveUpdateEnabled = passiveUpdateEnabled; >+ >+ // Need to refresh if we change state >+ Map<CDOID, CDOIDAndVersion> allRevisions = getAllCDOIDAndVersion(); >+ if (!allRevisions.isEmpty()) { >+ int initialChunkSize = collectionLoadingPolicy >+ .getInitialChunkSize(); >+ getSessionProtocol().setPassiveUpdate(allRevisions, >+ initialChunkSize, passiveUpdateEnabled); >+ } >+ >+ IListener[] listeners = getListeners(); >+ if (listeners != null) { >+ fireEvent(new PassiveUpdateEventImpl(), listeners); >+ } >+ } >+ } >+ >+ public CDOCollectionLoadingPolicy getCollectionLoadingPolicy() { >+ return collectionLoadingPolicy; >+ } >+ >+ public synchronized void setCollectionLoadingPolicy( >+ CDOCollectionLoadingPolicy policy) { >+ if (policy == null) { >+ policy = CDOCollectionLoadingPolicy.DEFAULT; >+ } >+ >+ if (collectionLoadingPolicy != policy) { >+ collectionLoadingPolicy = policy; >+ IListener[] listeners = getListeners(); >+ if (listeners != null) { >+ fireEvent(new CollectionLoadingPolicyEventImpl(), listeners); >+ } >+ } >+ } >+ >+ /** >+ * @author Eike Stepper >+ */ >+ private final class GeneratedPackageEmulationEventImpl extends >+ OptionsEvent implements GeneratedPackageEmulationEvent { >+ private static final long serialVersionUID = 1L; >+ >+ public GeneratedPackageEmulationEventImpl() { >+ super(OptionsImpl.this); >+ } >+ } >+ >+ /** >+ * @author Eike Stepper >+ */ >+ private final class PassiveUpdateEventImpl extends OptionsEvent >+ implements PassiveUpdateEvent { >+ private static final long serialVersionUID = 1L; >+ >+ public PassiveUpdateEventImpl() { >+ super(OptionsImpl.this); >+ } >+ } >+ >+ /** >+ * @author Eike Stepper >+ */ >+ private final class CollectionLoadingPolicyEventImpl extends >+ OptionsEvent implements CollectionLoadingPolicyEvent { >+ private static final long serialVersionUID = 1L; >+ >+ public CollectionLoadingPolicyEventImpl() { >+ super(OptionsImpl.this); >+ } >+ } >+ } >+ >+ /** >+ * @author Eike Stepper >+ */ >+ private final class InvalidationEvent extends Event implements >+ CDOSessionInvalidationEvent { >+ private static final long serialVersionUID = 1L; >+ >+ private InternalCDOView view; >+ >+ private long timeStamp; >+ >+ private Set<CDOIDAndVersion> dirtyOIDs; >+ >+ private Collection<CDOID> detachedObjects; >+ >+ private Collection<CDOPackageUnit> newPackageUnits; >+ >+ public InvalidationEvent(InternalCDOView view, long timeStamp, >+ Collection<CDOPackageUnit> packageUnits, >+ Set<CDOIDAndVersion> dirtyOIDs, >+ Collection<CDOID> detachedObjects) { >+ super(CDOSessionImpl.this); >+ this.view = view; >+ this.timeStamp = timeStamp; >+ newPackageUnits = packageUnits; >+ this.dirtyOIDs = dirtyOIDs; >+ this.detachedObjects = detachedObjects; >+ } >+ >+ @Override >+ public CDOSession getSource() { >+ return (CDOSession) super.getSource(); >+ } >+ >+ public InternalCDOView getView() { >+ return view; >+ } >+ >+ public boolean isRemote() { >+ return view == null; >+ } >+ >+ public long getTimeStamp() { >+ return timeStamp; >+ } >+ >+ public Set<CDOIDAndVersion> getDirtyOIDs() { >+ return dirtyOIDs; >+ } >+ >+ public Collection<CDOID> getDetachedObjects() { >+ return detachedObjects; >+ } >+ >+ public Collection<CDOPackageUnit> getNewPackageUnits() { >+ return newPackageUnits; >+ } >+ >+ @Override >+ public String toString() { >+ return "CDOSessionInvalidationEvent: " + dirtyOIDs; >+ } >+ } >+ >+ /** >+ * @author Eike Stepper >+ */ >+ public class DelegatingSessionProtocol extends Lifecycle implements >+ CDOSessionProtocol { >+ private CDOSessionProtocol delegate; >+ >+ @ExcludeFromDump >+ private IListener delegateListener = new LifecycleEventAdapter() { >+ @Override >+ protected void onDeactivated(ILifecycle lifecycle) { >+ DelegatingSessionProtocol.this.deactivate(); >+ } >+ }; >+ >+ public DelegatingSessionProtocol(CDOSessionProtocol delegate) { >+ this.delegate = delegate; >+ activate(); >+ } >+ >+ public CDOSessionProtocol getDelegate() { >+ return delegate; >+ } >+ >+ public CDOSession getSession() { >+ return (CDOSession) delegate.getSession(); >+ } >+ >+ public boolean cancelQuery(int queryId) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.cancelQuery(queryId); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public void changeSubscription(int viewId, List<CDOID> cdoIDs, >+ boolean subscribeMode, boolean clear) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ delegate.changeSubscription(viewId, cdoIDs, subscribeMode, >+ clear); >+ return; >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public void closeView(int viewId) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ delegate.closeView(viewId); >+ return; >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public CommitTransactionResult commitTransaction( >+ InternalCDOCommitContext commitContext, OMMonitor monitor) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.commitTransaction(commitContext, monitor); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public CommitTransactionResult commitTransactionCancel( >+ InternalCDOXACommitContext xaContext, OMMonitor monitor) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.commitTransactionCancel(xaContext, monitor); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public CommitTransactionResult commitTransactionPhase1( >+ InternalCDOXACommitContext xaContext, OMMonitor monitor) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.commitTransactionPhase1(xaContext, monitor); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public CommitTransactionResult commitTransactionPhase2( >+ InternalCDOXACommitContext xaContext, OMMonitor monitor) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.commitTransactionPhase2(xaContext, monitor); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public CommitTransactionResult commitTransactionPhase3( >+ InternalCDOXACommitContext xaContext, OMMonitor monitor) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.commitTransactionPhase3(xaContext, monitor); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public RepositoryTimeResult getRepositoryTime() { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.getRepositoryTime(); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public boolean isObjectLocked(CDOView view, CDOObject object, >+ LockType lockType, boolean byOthers) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.isObjectLocked(view, object, lockType, >+ byOthers); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public EPackage[] loadPackages(CDOPackageUnit packageUnit) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.loadPackages(packageUnit); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public Object loadChunk(InternalCDORevision revision, >+ EStructuralFeature feature, int accessIndex, int fetchIndex, >+ int fromIndex, int toIndex) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.loadChunk(revision, feature, accessIndex, >+ fetchIndex, fromIndex, toIndex); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public InternalCDORevision loadRevision(CDOID id, int referenceChunk, >+ int prefetchDepth) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.loadRevision(id, referenceChunk, >+ prefetchDepth); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public InternalCDORevision loadRevisionByTime(CDOID id, >+ int referenceChunk, int prefetchDepth, long timeStamp) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.loadRevisionByTime(id, referenceChunk, >+ prefetchDepth, timeStamp); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public InternalCDORevision loadRevisionByVersion(CDOID id, >+ int referenceChunk, int prefetchDepth, int version) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.loadRevisionByVersion(id, referenceChunk, >+ prefetchDepth, version); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public List<InternalCDORevision> loadRevisions(Collection<CDOID> ids, >+ int referenceChunk, int prefetchDepth) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.loadRevisions(ids, referenceChunk, >+ prefetchDepth); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public List<InternalCDORevision> loadRevisionsByTime( >+ Collection<CDOID> ids, int referenceChunk, int prefetchDepth, >+ long timeStamp) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.loadRevisionsByTime(ids, referenceChunk, >+ prefetchDepth, timeStamp); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public InternalCDORevision verifyRevision(InternalCDORevision revision, >+ int referenceChunk) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.verifyRevision(revision, referenceChunk); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public void lockObjects(CDOView view, >+ Map<CDOID, CDOIDAndVersion> objects, long timeout, >+ LockType lockType) throws InterruptedException { >+ int attempt = 0; >+ for (;;) { >+ try { >+ delegate.lockObjects(view, objects, timeout, lockType); >+ return; >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public void openView(int viewId, CDOCommonView.Type viewType, >+ long timeStamp) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ delegate.openView(viewId, viewType, timeStamp); >+ return; >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public void query(int viewID, AbstractQueryIterator<?> queryResult) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ delegate.query(viewID, queryResult); >+ return; >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public boolean[] setAudit(int viewId, long timeStamp, >+ List<InternalCDOObject> invalidObjects) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.setAudit(viewId, timeStamp, invalidObjects); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public void setPassiveUpdate(Map<CDOID, CDOIDAndVersion> idAndVersions, >+ int initialChunkSize, boolean passiveUpdateEnabled) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ delegate.setPassiveUpdate(idAndVersions, initialChunkSize, >+ passiveUpdateEnabled); >+ return; >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public Collection<CDOTimeStampContext> syncRevisions( >+ Map<CDOID, CDOIDAndVersion> allRevisions, int initialChunkSize) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.syncRevisions(allRevisions, >+ initialChunkSize); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public void unlockObjects(CDOView view, >+ Collection<? extends CDOObject> objects, LockType lockType) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ delegate.unlockObjects(view, objects, lockType); >+ return; >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public List<CDORemoteSession> getRemoteSessions( >+ InternalCDORemoteSessionManager manager, boolean subscribe) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.getRemoteSessions(manager, subscribe); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public Set<Integer> sendRemoteMessage(CDORemoteSessionMessage message, >+ List<CDORemoteSession> recipients) { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.sendRemoteMessage(message, recipients); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ public boolean unsubscribeRemoteSessions() { >+ int attempt = 0; >+ for (;;) { >+ try { >+ return delegate.unsubscribeRemoteSessions(); >+ } catch (Exception ex) { >+ handleException(++attempt, ex); >+ } >+ } >+ } >+ >+ @Override >+ protected void doActivate() throws Exception { >+ super.doActivate(); >+ EventUtil.addListener(delegate, delegateListener); >+ } >+ >+ @Override >+ protected void doDeactivate() throws Exception { >+ EventUtil.removeListener(delegate, delegateListener); >+ LifecycleUtil.deactivate(delegate); >+ delegate = null; >+ super.doDeactivate(); >+ } >+ >+ private void handleException(int attempt, Exception exception) { >+ try { >+ getExceptionHandler().handleException(CDOSessionImpl.this, >+ attempt, exception); >+ } catch (Exception ex) { >+ throw WrappedException.wrap(ex); >+ } >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void subscribeRemoteLocks() { >+ getDelegate().subscribeRemoteLocks(); >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void unsubscribeRemoteLocks() { >+ getDelegate().unsubscribeRemoteLocks(); >+ } >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void registerLockListeners(InternalCDOView cdoView) { >+ if (!hasRegisteredListeners) { >+ hasRegisteredListeners = true; >+ getSessionProtocol().subscribeRemoteLocks(); >+ } >+ registeredLockListeners.add(cdoView); >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void unregisterLockListeners(InternalCDOView cdoView) { >+ registeredLockListeners.remove(cdoView); >+ if (registeredLockListeners.isEmpty()) { >+ hasRegisteredListeners = false; >+ getSessionProtocol().unsubscribeRemoteLocks(); >+ } >+ } > } >Index: src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java,v >retrieving revision 1.28 >diff -u -r1.28 CDOSessionProtocol.java >--- src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java 3 Aug 2009 16:47:22 -0000 1.28 >+++ src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java 30 Nov 2009 20:08:45 -0000 >@@ -48,371 +48,362 @@ > * @author Eike Stepper > * @since 2.0 > */ >-public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, RevisionLoader >-{ >- public void setPassiveUpdate(Map<CDOID, CDOIDAndVersion> idAndVersions, int initialChunkSize, >- boolean passiveUpdateEnabled); >- >- public RepositoryTimeResult getRepositoryTime(); >- >- /** >- * @param revision >- * @param feature >- * @param accessIndex >- * Index of the item access at the client (with modifications) >- * @param fetchIndex >- * Index of the item access at the server (without any modifications) >- * @param fromIndex >- * Load objects at the client from fromIndex (inclusive) >- * @param toIndex >- * Load objects at the client to toIndex (inclusive) >- */ >- public Object loadChunk(InternalCDORevision revision, EStructuralFeature feature, int accessIndex, int fetchIndex, >- int fromIndex, int toIndex); >- >- public Collection<CDOTimeStampContext> syncRevisions(Map<CDOID, CDOIDAndVersion> allRevisions, int initialChunkSize); >- >- /** >- * @since 3.0 >- */ >- public void openView(int viewId, CDOCommonView.Type type, long timeStamp); >- >- public void closeView(int viewId); >- >- public boolean[] setAudit(int viewId, long timeStamp, List<InternalCDOObject> invalidObjects); >- >- public void changeSubscription(int viewId, List<CDOID> cdoIDs, boolean subscribeMode, boolean clear); >- >- /** >- * @since 3.0 >- */ >- public void query(int viewID, AbstractQueryIterator<?> queryResult); >- >- public boolean cancelQuery(int queryId); >- >- /** >- * @since 3.0 >- */ >- public void lockObjects(CDOView view, Map<CDOID, CDOIDAndVersion> objects, long timeout, LockType lockType) >- throws InterruptedException; >- >- /** >- * @since 3.0 >- */ >- public void unlockObjects(CDOView view, Collection<? extends CDOObject> objects, LockType lockType); >- >- /** >- * @since 3.0 >- */ >- public boolean isObjectLocked(CDOView view, CDOObject object, LockType lockType, boolean byOthers); >- >- public CommitTransactionResult commitTransaction(InternalCDOCommitContext commitContext, OMMonitor monitor); >- >- public CommitTransactionResult commitTransactionPhase1(InternalCDOXACommitContext xaContext, OMMonitor monitor); >- >- public CommitTransactionResult commitTransactionPhase2(InternalCDOXACommitContext xaContext, OMMonitor monitor); >- >- public CommitTransactionResult commitTransactionPhase3(InternalCDOXACommitContext xaContext, OMMonitor monitor); >- >- public CommitTransactionResult commitTransactionCancel(InternalCDOXACommitContext xaContext, OMMonitor monitor); >- >- public List<CDORemoteSession> getRemoteSessions(InternalCDORemoteSessionManager manager, boolean subscribe); >- >- /** >- * @since 3.0 >- */ >- public Set<Integer> sendRemoteMessage(CDORemoteSessionMessage message, List<CDORemoteSession> recipients); >- >- /** >- * @since 3.0 >- */ >- public boolean unsubscribeRemoteSessions(); >- >- /** >- * @author Eike Stepper >- */ >- public final class OpenSessionResult >- { >- private int sessionID; >- >- private String repositoryUUID; >- >- private long repositoryCreationTime; >- >- private long lastUpdateTime; >- >- private RepositoryTimeResult repositoryTimeResult; >- >- private boolean repositorySupportingAudits; >- >- private List<InternalCDOPackageUnit> packageUnits = new ArrayList<InternalCDOPackageUnit>(); >- >- /** >- * @since 3.0 >- */ >- public OpenSessionResult(int sessionID, String repositoryUUID, long repositoryCreationTime, long lastUpdateTime, >- boolean repositorySupportingAudits) >- { >- this.sessionID = sessionID; >- this.repositoryUUID = repositoryUUID; >- this.repositoryCreationTime = repositoryCreationTime; >- this.lastUpdateTime = lastUpdateTime; >- this.repositorySupportingAudits = repositorySupportingAudits; >- } >- >- public int getSessionID() >- { >- return sessionID; >- } >- >- public String getRepositoryUUID() >- { >- return repositoryUUID; >- } >- >- public long getRepositoryCreationTime() >- { >- return repositoryCreationTime; >- } >- >- public boolean isRepositorySupportingAudits() >- { >- return repositorySupportingAudits; >- } >- >- public RepositoryTimeResult getRepositoryTimeResult() >- { >- return repositoryTimeResult; >- } >- >- public void setRepositoryTimeResult(RepositoryTimeResult repositoryTimeResult) >- { >- this.repositoryTimeResult = repositoryTimeResult; >- } >- >- /** >- * @since 3.0 >- */ >- public long getLastUpdateTime() >- { >- return lastUpdateTime; >- } >- >- public List<InternalCDOPackageUnit> getPackageUnits() >- { >- return packageUnits; >- } >- } >- >- /** >- * @author Eike Stepper >- */ >- public final class RepositoryTimeResult >- { >- private long requested; >- >- private long indicated; >- >- private long responded; >- >- private long confirmed; >- >- public RepositoryTimeResult() >- { >- } >- >- public long getRequested() >- { >- return requested; >- } >- >- public void setRequested(long requested) >- { >- this.requested = requested; >- } >- >- public long getIndicated() >- { >- return indicated; >- } >- >- public void setIndicated(long indicated) >- { >- this.indicated = indicated; >- } >- >- public long getResponded() >- { >- return responded; >- } >- >- public void setResponded(long responded) >- { >- this.responded = responded; >- } >- >- public long getConfirmed() >- { >- return confirmed; >- } >- >- public void setConfirmed(long confirmed) >- { >- this.confirmed = confirmed; >- } >- >- public long getAproximateRepositoryOffset() >- { >- long latency = confirmed - requested >> 1; >- long shift = confirmed - responded; >- return shift - latency; >- } >- >- public long getAproximateRepositoryTime() >- { >- long offset = getAproximateRepositoryOffset(); >- return System.currentTimeMillis() + offset; >- } >- >- @Override >- public String toString() >- { >- return MessageFormat >- .format( >- "RepositoryTime[requested={0,date} {0,time}, indicated={1,date} {1,time}, responded={2,date} {2,time}, confirmed={3,date} {3,time}]", >- requested, indicated, responded, confirmed); >- } >- } >- >- /** >- * @author Eike Stepper >- */ >- public final class CommitTransactionResult >- { >- private String rollbackMessage; >- >- private long timeStamp; >- >- // private List<CDOIDMetaRange> metaIDRanges = new ArrayList<CDOIDMetaRange>(); >- >- private Map<CDOIDTemp, CDOID> idMappings = new HashMap<CDOIDTemp, CDOID>(); >- >- private CDOReferenceAdjuster referenceAdjuster; >- >- private InternalCDOCommitContext commitContext; >- >- public CommitTransactionResult(InternalCDOCommitContext commitContext, String rollbackMessage) >- { >- this.rollbackMessage = rollbackMessage; >- this.commitContext = commitContext; >- } >- >- public CommitTransactionResult(InternalCDOCommitContext commitContext, long timeStamp) >- { >- this.timeStamp = timeStamp; >- this.commitContext = commitContext; >- } >- >- public CDOReferenceAdjuster getReferenceAdjuster() >- { >- if (referenceAdjuster == null) >- { >- referenceAdjuster = createReferenceAdjuster(); >- } >- >- return referenceAdjuster; >- } >- >- public void setReferenceAdjuster(CDOReferenceAdjuster referenceAdjuster) >- { >- this.referenceAdjuster = referenceAdjuster; >- } >- >- public InternalCDOCommitContext getCommitContext() >- { >- return commitContext; >- } >- >- public String getRollbackMessage() >- { >- return rollbackMessage; >- } >- >- public long getTimeStamp() >- { >- return timeStamp; >- } >- >- public Map<CDOIDTemp, CDOID> getIDMappings() >- { >- return idMappings; >- } >- >- public void addIDMapping(CDOIDTemp oldID, CDOID newID) >- { >- idMappings.put(oldID, newID); >- } >- >- // /** >- // * @since 3.0 >- // */ >- // public List<CDOIDMetaRange> getMetaIDRanges() >- // { >- // return metaIDRanges; >- // } >- // >- // /** >- // * @since 3.0 >- // */ >- // public void addMetaIDRange(CDOIDMetaRange metaIDRange) >- // { >- // metaIDRanges.add(metaIDRange); >- // } >- >- protected PostCommitReferenceAdjuster createReferenceAdjuster() >- { >- return new PostCommitReferenceAdjuster(commitContext.getTransaction(), new CDOIDMapper(idMappings)); >- } >- >- /** >- * @author Simon McDuff >- */ >- protected static class PostCommitReferenceAdjuster implements CDOReferenceAdjuster >- { >- private CDOIDProvider idProvider; >- >- private CDOIDMapper idMapper; >- >- public PostCommitReferenceAdjuster(CDOIDProvider idProvider, CDOIDMapper idMapper) >- { >- this.idProvider = idProvider; >- this.idMapper = idMapper; >- } >- >- public CDOIDProvider getIdProvider() >- { >- return idProvider; >- } >- >- public CDOIDMapper getIdMapper() >- { >- return idMapper; >- } >- >- public Object adjustReference(Object id) >- { >- if (id == null || id == CDOID.NULL) >- { >- return id; >- } >- >- if (idProvider != null && (id instanceof CDOID || id instanceof InternalEObject)) >- { >- id = idProvider.provideCDOID(id); >- } >- >- return idMapper.adjustReference(id); >- } >- } >- } >+public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, >+ RevisionLoader { >+ public void setPassiveUpdate(Map<CDOID, CDOIDAndVersion> idAndVersions, >+ int initialChunkSize, boolean passiveUpdateEnabled); >+ >+ public RepositoryTimeResult getRepositoryTime(); >+ >+ /** >+ * @param revision >+ * @param feature >+ * @param accessIndex >+ * Index of the item access at the client (with modifications) >+ * @param fetchIndex >+ * Index of the item access at the server (without any >+ * modifications) >+ * @param fromIndex >+ * Load objects at the client from fromIndex (inclusive) >+ * @param toIndex >+ * Load objects at the client to toIndex (inclusive) >+ */ >+ public Object loadChunk(InternalCDORevision revision, >+ EStructuralFeature feature, int accessIndex, int fetchIndex, >+ int fromIndex, int toIndex); >+ >+ public Collection<CDOTimeStampContext> syncRevisions( >+ Map<CDOID, CDOIDAndVersion> allRevisions, int initialChunkSize); >+ >+ /** >+ * @since 3.0 >+ */ >+ public void openView(int viewId, CDOCommonView.Type type, long timeStamp); >+ >+ public void closeView(int viewId); >+ >+ public boolean[] setAudit(int viewId, long timeStamp, >+ List<InternalCDOObject> invalidObjects); >+ >+ public void changeSubscription(int viewId, List<CDOID> cdoIDs, >+ boolean subscribeMode, boolean clear); >+ >+ /** >+ * @since 3.0 >+ */ >+ public void query(int viewID, AbstractQueryIterator<?> queryResult); >+ >+ public boolean cancelQuery(int queryId); >+ >+ /** >+ * @since 3.0 >+ */ >+ public void lockObjects(CDOView view, Map<CDOID, CDOIDAndVersion> objects, >+ long timeout, LockType lockType) throws InterruptedException; >+ >+ /** >+ * @since 3.0 >+ */ >+ public void unlockObjects(CDOView view, >+ Collection<? extends CDOObject> objects, LockType lockType); >+ >+ /** >+ * @since 3.0 >+ */ >+ public boolean isObjectLocked(CDOView view, CDOObject object, >+ LockType lockType, boolean byOthers); >+ >+ public CommitTransactionResult commitTransaction( >+ InternalCDOCommitContext commitContext, OMMonitor monitor); >+ >+ public CommitTransactionResult commitTransactionPhase1( >+ InternalCDOXACommitContext xaContext, OMMonitor monitor); >+ >+ public CommitTransactionResult commitTransactionPhase2( >+ InternalCDOXACommitContext xaContext, OMMonitor monitor); >+ >+ public CommitTransactionResult commitTransactionPhase3( >+ InternalCDOXACommitContext xaContext, OMMonitor monitor); >+ >+ public CommitTransactionResult commitTransactionCancel( >+ InternalCDOXACommitContext xaContext, OMMonitor monitor); >+ >+ public List<CDORemoteSession> getRemoteSessions( >+ InternalCDORemoteSessionManager manager, boolean subscribe); >+ >+ /** >+ * @since 3.0 >+ */ >+ public Set<Integer> sendRemoteMessage(CDORemoteSessionMessage message, >+ List<CDORemoteSession> recipients); >+ >+ /** >+ * @since 3.0 >+ */ >+ public boolean unsubscribeRemoteSessions(); >+ >+ /** >+ * @author Eike Stepper >+ */ >+ public final class OpenSessionResult { >+ private int sessionID; >+ >+ private String repositoryUUID; >+ >+ private long repositoryCreationTime; >+ >+ private long lastUpdateTime; >+ >+ private RepositoryTimeResult repositoryTimeResult; >+ >+ private boolean repositorySupportingAudits; >+ >+ private List<InternalCDOPackageUnit> packageUnits = new ArrayList<InternalCDOPackageUnit>(); >+ >+ /** >+ * @since 3.0 >+ */ >+ public OpenSessionResult(int sessionID, String repositoryUUID, >+ long repositoryCreationTime, long lastUpdateTime, >+ boolean repositorySupportingAudits) { >+ this.sessionID = sessionID; >+ this.repositoryUUID = repositoryUUID; >+ this.repositoryCreationTime = repositoryCreationTime; >+ this.lastUpdateTime = lastUpdateTime; >+ this.repositorySupportingAudits = repositorySupportingAudits; >+ } >+ >+ public int getSessionID() { >+ return sessionID; >+ } >+ >+ public String getRepositoryUUID() { >+ return repositoryUUID; >+ } >+ >+ public long getRepositoryCreationTime() { >+ return repositoryCreationTime; >+ } >+ >+ public boolean isRepositorySupportingAudits() { >+ return repositorySupportingAudits; >+ } >+ >+ public RepositoryTimeResult getRepositoryTimeResult() { >+ return repositoryTimeResult; >+ } >+ >+ public void setRepositoryTimeResult( >+ RepositoryTimeResult repositoryTimeResult) { >+ this.repositoryTimeResult = repositoryTimeResult; >+ } >+ >+ /** >+ * @since 3.0 >+ */ >+ public long getLastUpdateTime() { >+ return lastUpdateTime; >+ } >+ >+ public List<InternalCDOPackageUnit> getPackageUnits() { >+ return packageUnits; >+ } >+ } >+ >+ /** >+ * @author Eike Stepper >+ */ >+ public final class RepositoryTimeResult { >+ private long requested; >+ >+ private long indicated; >+ >+ private long responded; >+ >+ private long confirmed; >+ >+ public RepositoryTimeResult() { >+ } >+ >+ public long getRequested() { >+ return requested; >+ } >+ >+ public void setRequested(long requested) { >+ this.requested = requested; >+ } >+ >+ public long getIndicated() { >+ return indicated; >+ } >+ >+ public void setIndicated(long indicated) { >+ this.indicated = indicated; >+ } >+ >+ public long getResponded() { >+ return responded; >+ } >+ >+ public void setResponded(long responded) { >+ this.responded = responded; >+ } >+ >+ public long getConfirmed() { >+ return confirmed; >+ } >+ >+ public void setConfirmed(long confirmed) { >+ this.confirmed = confirmed; >+ } >+ >+ public long getAproximateRepositoryOffset() { >+ long latency = confirmed - requested >> 1; >+ long shift = confirmed - responded; >+ return shift - latency; >+ } >+ >+ public long getAproximateRepositoryTime() { >+ long offset = getAproximateRepositoryOffset(); >+ return System.currentTimeMillis() + offset; >+ } >+ >+ @Override >+ public String toString() { >+ return MessageFormat >+ .format( >+ "RepositoryTime[requested={0,date} {0,time}, indicated={1,date} {1,time}, responded={2,date} {2,time}, confirmed={3,date} {3,time}]", >+ requested, indicated, responded, confirmed); >+ } >+ } >+ >+ /** >+ * @author Eike Stepper >+ */ >+ public final class CommitTransactionResult { >+ private String rollbackMessage; >+ >+ private long timeStamp; >+ >+ // private List<CDOIDMetaRange> metaIDRanges = new >+ // ArrayList<CDOIDMetaRange>(); >+ >+ private Map<CDOIDTemp, CDOID> idMappings = new HashMap<CDOIDTemp, CDOID>(); >+ >+ private CDOReferenceAdjuster referenceAdjuster; >+ >+ private InternalCDOCommitContext commitContext; >+ >+ public CommitTransactionResult(InternalCDOCommitContext commitContext, >+ String rollbackMessage) { >+ this.rollbackMessage = rollbackMessage; >+ this.commitContext = commitContext; >+ } >+ >+ public CommitTransactionResult(InternalCDOCommitContext commitContext, >+ long timeStamp) { >+ this.timeStamp = timeStamp; >+ this.commitContext = commitContext; >+ } >+ >+ public CDOReferenceAdjuster getReferenceAdjuster() { >+ if (referenceAdjuster == null) { >+ referenceAdjuster = createReferenceAdjuster(); >+ } >+ >+ return referenceAdjuster; >+ } >+ >+ public void setReferenceAdjuster(CDOReferenceAdjuster referenceAdjuster) { >+ this.referenceAdjuster = referenceAdjuster; >+ } >+ >+ public InternalCDOCommitContext getCommitContext() { >+ return commitContext; >+ } >+ >+ public String getRollbackMessage() { >+ return rollbackMessage; >+ } >+ >+ public long getTimeStamp() { >+ return timeStamp; >+ } >+ >+ public Map<CDOIDTemp, CDOID> getIDMappings() { >+ return idMappings; >+ } >+ >+ public void addIDMapping(CDOIDTemp oldID, CDOID newID) { >+ idMappings.put(oldID, newID); >+ } >+ >+ // /** >+ // * @since 3.0 >+ // */ >+ // public List<CDOIDMetaRange> getMetaIDRanges() >+ // { >+ // return metaIDRanges; >+ // } >+ // >+ // /** >+ // * @since 3.0 >+ // */ >+ // public void addMetaIDRange(CDOIDMetaRange metaIDRange) >+ // { >+ // metaIDRanges.add(metaIDRange); >+ // } >+ >+ protected PostCommitReferenceAdjuster createReferenceAdjuster() { >+ return new PostCommitReferenceAdjuster(commitContext >+ .getTransaction(), new CDOIDMapper(idMappings)); >+ } >+ >+ /** >+ * @author Simon McDuff >+ */ >+ protected static class PostCommitReferenceAdjuster implements >+ CDOReferenceAdjuster { >+ private CDOIDProvider idProvider; >+ >+ private CDOIDMapper idMapper; >+ >+ public PostCommitReferenceAdjuster(CDOIDProvider idProvider, >+ CDOIDMapper idMapper) { >+ this.idProvider = idProvider; >+ this.idMapper = idMapper; >+ } >+ >+ public CDOIDProvider getIdProvider() { >+ return idProvider; >+ } >+ >+ public CDOIDMapper getIdMapper() { >+ return idMapper; >+ } >+ >+ public Object adjustReference(Object id) { >+ if (id == null || id == CDOID.NULL) { >+ return id; >+ } >+ >+ if (idProvider != null >+ && (id instanceof CDOID || id instanceof InternalEObject)) { >+ id = idProvider.provideCDOID(id); >+ } >+ >+ return idMapper.adjustReference(id); >+ } >+ } >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void subscribeRemoteLocks(); >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void unsubscribeRemoteLocks(); > } >Index: src/org/eclipse/emf/spi/cdo/InternalCDOSession.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java,v >retrieving revision 1.26 >diff -u -r1.26 InternalCDOSession.java >--- src/org/eclipse/emf/spi/cdo/InternalCDOSession.java 10 Nov 2009 08:25:25 -0000 1.26 >+++ src/org/eclipse/emf/spi/cdo/InternalCDOSession.java 30 Nov 2009 20:08:45 -0000 >@@ -35,85 +35,101 @@ > * @author Eike Stepper > * @since 2.0 > */ >-public interface InternalCDOSession extends CDOSession, PackageProcessor, PackageLoader, RevisionLocker, ILifecycle >-{ >- /** >- * @since 3.0 >- */ >- public InternalCDOSessionConfiguration getConfiguration(); >- >- public CDOSessionProtocol getSessionProtocol(); >- >- /** >- * @since 3.0 >- */ >- public void setSessionProtocol(CDOSessionProtocol sessionProtocol); >- >- public InternalCDOPackageRegistry getPackageRegistry(); >- >- /** >- * @since 3.0 >- */ >- public InternalCDORevisionManager getRevisionManager(); >- >- public void setExceptionHandler(CDOSession.ExceptionHandler exceptionHandler); >- >- /** >- * @since 3.0 >- */ >- public void setFetchRuleManager(CDOFetchRuleManager fetchRuleManager); >- >- /** >- * @since 3.0 >- */ >- public void setRepositoryInfo(CDORepositoryInfo repositoryInfo); >- >- /** >- * @since 3.0 >- */ >- public InternalCDORemoteSessionManager getRemoteSessionManager(); >- >- /** >- * @since 3.0 >- */ >- public void setRemoteSessionManager(InternalCDORemoteSessionManager remoteSessionManager); >- >- /** >- * @since 3.0 >- */ >- public void setSessionID(int sessionID); >- >- public void setUserID(String userID); >- >- /** >- * @since 3.0 >- */ >- public void setLastUpdateTime(long lastUpdateTime); >- >- public void viewDetached(InternalCDOView view); >- >- /** >- * @since 3.0 >- */ >- public Object resolveElementProxy(CDORevision revision, EStructuralFeature feature, int accessIndex, int serverIndex); >- >- /** >- * @since 3.0 >- */ >- public Object getCommitLock(); >- >- public void handleCommitNotification(long timeStamp, Collection<CDOPackageUnit> newPackageUnits, >- Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects, Collection<CDORevisionDelta> deltas, >- InternalCDOView excludedView); >- >- public void handleSyncResponse(long timestamp, Collection<CDOPackageUnit> newPackageUnits, >- Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects); >- >- /** >- * In some cases we need to sync without propagating event. Lock is a good example. >- * >- * @since 3.0 >- */ >- public void reviseRevisions(final long timeStamp, Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects, >- InternalCDOView excludedView); >+public interface InternalCDOSession extends CDOSession, PackageProcessor, >+ PackageLoader, RevisionLocker, ILifecycle { >+ /** >+ * @since 3.0 >+ */ >+ public InternalCDOSessionConfiguration getConfiguration(); >+ >+ public CDOSessionProtocol getSessionProtocol(); >+ >+ /** >+ * @since 3.0 >+ */ >+ public void setSessionProtocol(CDOSessionProtocol sessionProtocol); >+ >+ public InternalCDOPackageRegistry getPackageRegistry(); >+ >+ /** >+ * @since 3.0 >+ */ >+ public InternalCDORevisionManager getRevisionManager(); >+ >+ public void setExceptionHandler(CDOSession.ExceptionHandler exceptionHandler); >+ >+ /** >+ * @since 3.0 >+ */ >+ public void setFetchRuleManager(CDOFetchRuleManager fetchRuleManager); >+ >+ /** >+ * @since 3.0 >+ */ >+ public void setRepositoryInfo(CDORepositoryInfo repositoryInfo); >+ >+ /** >+ * @since 3.0 >+ */ >+ public InternalCDORemoteSessionManager getRemoteSessionManager(); >+ >+ /** >+ * @since 3.0 >+ */ >+ public void setRemoteSessionManager( >+ InternalCDORemoteSessionManager remoteSessionManager); >+ >+ /** >+ * @since 3.0 >+ */ >+ public void setSessionID(int sessionID); >+ >+ public void setUserID(String userID); >+ >+ /** >+ * @since 3.0 >+ */ >+ public void setLastUpdateTime(long lastUpdateTime); >+ >+ public void viewDetached(InternalCDOView view); >+ >+ /** >+ * @since 3.0 >+ */ >+ public Object resolveElementProxy(CDORevision revision, >+ EStructuralFeature feature, int accessIndex, int serverIndex); >+ >+ /** >+ * @since 3.0 >+ */ >+ public Object getCommitLock(); >+ >+ public void handleCommitNotification(long timeStamp, >+ Collection<CDOPackageUnit> newPackageUnits, >+ Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects, >+ Collection<CDORevisionDelta> deltas, InternalCDOView excludedView); >+ >+ public void handleSyncResponse(long timestamp, >+ Collection<CDOPackageUnit> newPackageUnits, >+ Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects); >+ >+ /** >+ * In some cases we need to sync without propagating event. Lock is a good >+ * example. >+ * >+ * @since 3.0 >+ */ >+ public void reviseRevisions(final long timeStamp, >+ Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects, >+ InternalCDOView excludedView); >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void registerLockListeners(InternalCDOView cdoView); >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void unregisterLockListeners(InternalCDOView cdoView); > } >Index: src/org/eclipse/emf/cdo/view/CDOView.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java,v >retrieving revision 1.11 >diff -u -r1.11 CDOView.java >--- src/org/eclipse/emf/cdo/view/CDOView.java 20 Oct 2009 06:51:12 -0000 1.11 >+++ src/org/eclipse/emf/cdo/view/CDOView.java 30 Nov 2009 20:08:42 -0000 >@@ -27,6 +27,7 @@ > > import org.eclipse.net4j.util.collection.CloseableIterator; > import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType; >+import org.eclipse.net4j.util.event.IListener; > import org.eclipse.net4j.util.event.INotifier; > import org.eclipse.net4j.util.options.IOptions; > import org.eclipse.net4j.util.options.IOptionsContainer; >@@ -43,11 +44,12 @@ > import java.util.concurrent.locks.ReentrantLock; > > /** >- * A read-only view to the <em>current</em> (i.e. latest) state of the object graph in the repository of the underlying >- * {@link CDOSession session}. >+ * A read-only view to the <em>current</em> (i.e. latest) state of the object >+ * graph in the repository of the underlying {@link CDOSession session}. > * <p> >- * Objects that are accessed through this view are unchangeable for the client. Each attempt to call a mutator on one of >- * these objects or one of their reference collections will result in a {@link ReadOnlyException} being thrown >+ * Objects that are accessed through this view are unchangeable for the client. >+ * Each attempt to call a mutator on one of these objects or one of their >+ * reference collections will result in a {@link ReadOnlyException} being thrown > * immediately. > * <p> > * A view is opened through API of the underlying session like this: >@@ -58,419 +60,489 @@ > * ... > * </pre> > * >- * CDOView instances <b>must not</b> be accessed through concurrent client threads. >+ * CDOView instances <b>must not</b> be accessed through concurrent client >+ * threads. > * <p> >- * Since a CDOObject, in a {@link CDOState#TRANSIENT non-TRANSIENT} state, is only meaningful in combination with its >- * dedicated view they must also not be accessed through concurrent client threads. Please note that at arbitrary times >- * an arbitrary number of framework background threads are allowed to use and modify a CDOview and its CDOObjects. >- * Whenever you are iterating over a number of CDOObjects and need to ensure that they are not modified by the framework >- * at the same time it is strongly recommended to acquire the {@link #getLock() view lock} and protect your code >- * appropriately. >+ * Since a CDOObject, in a {@link CDOState#TRANSIENT non-TRANSIENT} state, is >+ * only meaningful in combination with its dedicated view they must also not be >+ * accessed through concurrent client threads. Please note that at arbitrary >+ * times an arbitrary number of framework background threads are allowed to use >+ * and modify a CDOview and its CDOObjects. Whenever you are iterating over a >+ * number of CDOObjects and need to ensure that they are not modified by the >+ * framework at the same time it is strongly recommended to acquire the >+ * {@link #getLock() view lock} and protect your code appropriately. > * > * @author Eike Stepper > * @noimplement This interface is not intended to be implemented by clients. > * @since 2.0 > */ >-public interface CDOView extends CDOCommonView, INotifier, IOptionsContainer >-{ >- /** >- * Returns the {@link CDOSession session} this view was opened by. >- * >- * @return The session this view was opened by, or <code>null</code> if this view is closed. >- * @see #close() >- * @see #isClosed() >- * @see CDOSession#openView() >- * @see CDOSession#openView(ResourceSet) >- * @see CDOSession#openAudit(long) >- * @see CDOSession#openAudit(ResourceSet, long) >- * @see CDOSession#openTransaction() >- * @see CDOSession#openTransaction(ResourceSet) >- */ >- public CDOSession getSession(); >- >- /** >- * Returns the {@link CDOViewSet view set} this view is associated with. >- * >- * @return The view set this view is associated with, never <code>null</code>. >- * @see CDOViewSet#getViews() >- */ >- public CDOViewSet getViewSet(); >- >- /** >- * Returns the {@link ResourceSet resource set} this view is associated with. >- * <p> >- * Same as calling <tt>getViewSet().getResourceSet()</tt>. >- * >- * @see CDOViewSet#getResourceSet() >- */ >- public ResourceSet getResourceSet(); >- >- /** >- * @deprecated This API is provisional and subject to change or removal. >- */ >- @Deprecated >- public URIHandler getURIHandler(); >- >- /** >- * Returns a reentrant lock that can be used to prevent the framework from writing to any object in this view (as it >- * is caused, for example, by passive updates). >- * <p> >- * Acquiring this lock provides a means to safely iterate over multiple model elements without being affected by >- * unanticipated remote updates, like in the following example: >- * >- * <pre> >- * CDOResource resource = view.getResource("/orders/order-4711"); >- * PurchaseOrder order = (PurchaseOrder)resource.getContents().get(0); >- * ReentrantLock lock = view.getLock(); >- * if (!lock.tryLock(5L, TimeUnit.SECONDS)) >- * { >- * throw new TimeoutException(); >- * } >- * try >- * { >- * float sum = 0; >- * for (OrderDetail detail : order.getOrderDetails()) >- * { >- * sum += detail.getPrice(); >- * } >- * System.out.println("Sum: " + sum); >- * } >- * finally >- * { >- * lock.unlock(); >- * } >- * } >- * </pre> >- * >- * Note that this method really just returns the lock instance but does <b>not</b> acquire the lock! The above example >- * acquires the lock with a timeout that expires after five seconds. >- */ >- public ReentrantLock getLock(); >- >- /** >- * Returns always <code>false</code>. >- * <p> >- * This method has a special implementation in {@link CDOTransaction} as well. >- * >- * @see CDOTransaction#isDirty() >- */ >- public boolean isDirty(); >- >- /** >- * Returns always <code>false</code>. >- * <p> >- * This method has a special implementation in {@link CDOTransaction} as well. >- * >- * @see CDOTransaction#hasConflict() >- */ >- public boolean hasConflict(); >- >- /** >- * Returns <code>true</code> if a resource with the given path exists in the repository, <code>false</code>. >- * >- * @see #getResource(String, boolean) >- */ >- public boolean hasResource(String path); >- >- /** >- * @see ResourceSet#getResource(URI, boolean) >- */ >- public CDOResource getResource(String path, boolean loadOnDemand); >- >- /** >- * Same as {@link #getResource(String, boolean) getResource(String, true)}. >- * >- * @see ResourceSet#getResource(URI, boolean) >- */ >- public CDOResource getResource(String path); >- >- /** >- * Returns the resource node with the given path, or <code>null</code> if no such resource node exists. >- */ >- public CDOResourceNode getResourceNode(String path); >- >- /** >- * Returns the root resource of the repository. >- * <p> >- * The root resource is a special resource with only {@link CDOResourceNode CDOResourceNodes} in its contents list. >- * You can use it as the main entry into the new resource and folder structure. >- */ >- public CDOResource getRootResource(); >- >- /** >- * Returns a list of the resources in the given folder with a name equal to or starting with the value of the name >- * parameter. >- * >- * @param folder >- * The folder to search in, or <code>null</code> for top level resource nodes. >- * @param name >- * the name or prefix of the resource nodes to return. >- * @param exactMatch >- * <code>true</code> if the complete name of the resource must match, <code>false</code> if only a common >- * prefix of the name must match. >- */ >- public List<CDOResourceNode> queryResources(CDOResourceFolder folder, String name, boolean exactMatch); >- >- /** >- * Returns an iterator over the resources in the given folder with a name equal to or starting with the value of the >- * name parameter. The underlying query will be executed asynchronously. >- * >- * @param folder >- * The folder to search in, or <code>null</code> for top level resource nodes. >- * @param name >- * the name or prefix of the resource nodes to return. >- * @param exactMatch >- * <code>true</code> if the complete name of the resource must match, <code>false</code> if only a common >- * prefix of the name must match. >- */ >- public CloseableIterator<CDOResourceNode> queryResourcesAsync(CDOResourceFolder folder, String name, >- boolean exactMatch); >- >- /** >- * Returns the object for the given CDOID. >- * >- * @param loadOnDemand >- * whether to create and load the object, if it doesn't already exist. >- * @return the object resolved by the CDOID if the id is not <code>null</code>, or <code>null</code> if there isn't >- * one and loadOnDemand is <code>false</code>. >- */ >- public CDOObject getObject(CDOID id, boolean loadOnDemand); >- >- /** >- * Returns the object for the given CDOID. >- * <p> >- * Same as <code>getObject(id, true)</code>. >- * >- * @see getObject(CDOID, boolean) >- */ >- public CDOObject getObject(CDOID id); >- >- /** >- * Takes an object from a (possibly) different view and <em>contextifies</em> it for the usage with this view. >- * <ul> >- * <li>If the given object is contained in this view it is returned unmodified. >- * <li>If the given object can not be cast to {@link CDOObject} it is returned unmodified. >- * <li>If the view of the given object is contained in a different session an <code>IllegalArgumentException</code> is >- * thrown. >- * <li>If <code>null</code> is passed <code>null</code> is returned. >- * </ul> >- */ >- public <T extends EObject> T getObject(T objectFromDifferentView); >- >- /** >- * Returns <code>true</code> if an {@link CDOObject object} with the given {@link CDOID id} is currently registered in >- * this view, <code>false</code> otherwise. >- */ >- public boolean isObjectRegistered(CDOID id); >- >- /** >- * Reloads the given {@link CDOObject objects} from the repository. >- */ >- public int reload(CDOObject... objects); >- >- /** >- * Locks the given objects. Once the objects are locked, they will not be changed remotely or go in conflict state. >- * >- * @since 3.0 >- */ >- public void lockObjects(Collection<? extends CDOObject> objects, LockType lockType, long timeout) >- throws InterruptedException; >- >- /** >- * Unlocks the given locked objects of this view. >- */ >- public void unlockObjects(Collection<? extends CDOObject> objects, LockType lockType); >- >- /** >- * Unlocks all locked objects of this view. >- * >- * @since 2.0 >- */ >- public void unlockObjects(); >- >- /** >- * @since 3.0 >- */ >- public void addObjectHandler(CDOObjectHandler handler); >- >- /** >- * @since 3.0 >- */ >- public void removeObjectHandler(CDOObjectHandler handler); >- >- /** >- * @since 3.0 >- */ >- public CDOObjectHandler[] getObjectHandlers(); >- >- /** >- * @since 2.0 >- */ >- public CDOQuery createQuery(String language, String queryString); >- >- /** >- * @since 2.0 >- */ >- public Options options(); >- >- /** >- * @author Simon McDuff >- */ >- public interface Options extends IOptions >- { >- /** >- */ >- public static final int NO_REVISION_PREFETCHING = 1; >- >- /** >- * Returns the reference type to be used in the internal object cache. >- * >- * @return Either {@link ReferenceType#STRONG STRONG}, {@link ReferenceType#SOFT SOFT} or {@link ReferenceType#WEAK >- * WEAK}. >- */ >- public ReferenceType getCacheReferenceType(); >- >- /** >- * Sets the reference type to be used in the internal object cache to either {@link ReferenceType#STRONG STRONG}, >- * {@link ReferenceType#SOFT SOFT} or {@link ReferenceType#WEAK WEAK}. If <code>null</code> is passed the default >- * reference type {@link ReferenceType#SOFT SOFT} is set. If the given reference type does not differ from the one >- * being currently set the new value is ignored and <code>false</code> is returned. Otherwise existing object >- * references are converted to the new type and <code>true</code> is returned. >- */ >- public boolean setCacheReferenceType(ReferenceType referenceType); >- >- /** >- * Returns <code>true</code> if the {@link CDOObject objects} in this view will notify their >- * {@link org.eclipse.emf.common.notify.Adapter adapters} about the fact that they are <em>invalidated</em> (due to >- * remote changes), <code>false</code> otherwise. >- * >- * @see CDOInvalidationNotification >- */ >- public boolean isInvalidationNotificationEnabled(); >- >- /** >- * Specifies whether the {@link CDOObject objects} in this view will notify their >- * {@link org.eclipse.emf.common.notify.Adapter adapters} about the fact that they are <em>invalidated</em> (due to >- * remote changes) or not. >- * >- * @see CDOInvalidationNotification >- */ >- public void setInvalidationNotificationEnabled(boolean enabled); >- >- /** >- * Returns the current set of {@link CDOAdapterPolicy change subscription policies}. >- * >- * @return The current set of change subscription policies, never <code>null</code>. >- * @see #setChangeSubscriptionPolicy(CDOAdapterPolicy) >- */ >- public CDOAdapterPolicy[] getChangeSubscriptionPolicies(); >- >- /** >- * Adds a change subscription policy to this view. >- * <p> >- * To activate a policy, you must do the following: <br> >- * <code>view.options().addChangeSubscriptionPolicy(CDOChangeSubscriptionPolicy.ALL);</code> >- * <p> >- * To register an object, you must add an adapter to the object in which you are interested:<br> >- * <code>eObject.eAdapters().add(myAdapter);</code> >- * <p> >- * By activating this feature, each object having at least one adapter that matches the current policy will be >- * registered with the server and will be notified for each change occurring in the scope of any other transaction. >- * <p> >- * {@link CDOAdapterPolicy#NONE} - Ignored. <br> >- * {@link CDOAdapterPolicy#ALL} - Enabled for all adapters used.<br> >- * {@link CDOAdapterPolicy#CDO} - Enabled only for adapters that implement {@link CDOAdapter}. <br> >- * Any other class that implement {@link CDOAdapterPolicy} will enable for whatever rules defined in that class. >- * <br> >- * <p> >- * If <code>myAdapter</code> in the above example matches the current policy, <code>eObject</code> will be >- * registered with the server and you will receive all changes from other transaction. >- * <p> >- * When the policy is changed all objects in the cache will automatically be recalculated. >- * <p> >- * You can subscribe to temporary objects. Even if you cannot receive notifications from other >- * {@link CDOTransaction} for these because they are only local to you, at commit time these objects will be >- * registered automatically. >- * <p> >- * <b>Note:</b> It can be used with <code>CDOSession.options().setPassiveUpdate(false)</code>. In this case, it will >- * receive changes without having the objects changed. >- */ >- public void addChangeSubscriptionPolicy(CDOAdapterPolicy policy); >- >- /** >- * Removes a change subscription policy from this view. >- */ >- public void removeChangeSubscriptionPolicy(CDOAdapterPolicy policy); >- >- // TODO >- public CDOAdapterPolicy getStrongReferencePolicy(); >- >- /** >- * Sets the reference type to be used when an adapter is used to an object. >- * <p> >- * When <code>CDOView.setStrongReference(CDOAdapterPolicy.ALL)</code> is used, it is possible that the target object >- * will be GC. In that case, the adapter will never received notifications. By Default the value is at >- * <code>CDOAdapterPolicy.ALL</code> >- */ >- public void setStrongReferencePolicy(CDOAdapterPolicy policy); >- >- /** >- * Returns the CDOStaleReferencePolicy in use. >- * >- * @since 3.0 >- */ >- public CDOStaleReferencePolicy getStaleReferenceBehaviour(); >- >- /** >- * Sets a policy on how to deal with stale references. >- * >- * @since 3.0 >- */ >- public void setStaleReferenceBehaviour(CDOStaleReferencePolicy policy); >- >- /** >- * Returns the CDORevisionPrefetchingPolicy in use. >- */ >- public CDORevisionPrefetchingPolicy getRevisionPrefetchingPolicy(); >- >- /** >- * The CDORevisionPrefetchingPolicy feature of the CDOView allows CDO users to fetch many objects at a time. >- * <p> >- * The difference between the CDOCollectionLoadingPolicy feature and the CDORevisionPrefetchingPolicy feature is >- * subtle. The CDOCollectionLoadingPolicy feature determines how and when to fetch CDOIDs, while the >- * CDORevisionPrefetchingPolicy feature determines how and when to resolve CDOIDs (i.e. fetch the target objects). >- * <p> >- * <code>view.options().setRevisionPrefetchingPolicy (CDONet4jUtil.createRevisionPrefetchingPolicy(10));</code> >- * <p> >- * The end-user could provide its own implementation of the CDORevisionPrefetchingPolicy interface. >- */ >- public void setRevisionPrefetchingPolicy(CDORevisionPrefetchingPolicy prefetchingPolicy); >- >- public interface CacheReferenceTypeEvent extends IOptionsEvent >- { >- } >- >- public interface ReferencePolicyEvent extends IOptionsEvent >- { >- } >- >- /** >- * @since 3.0 >- */ >- public interface StaleReferencePolicyEvent extends IOptionsEvent >- { >- } >- >- public interface ChangeSubscriptionPoliciesEvent extends IOptionsEvent >- { >- } >- >- public interface InvalidationNotificationEvent extends IOptionsEvent >- { >- } >- >- public interface RevisionPrefetchingPolicyEvent extends IOptionsEvent >- { >- } >- } >+public interface CDOView extends CDOCommonView, INotifier, IOptionsContainer { >+ /** >+ * Returns the {@link CDOSession session} this view was opened by. >+ * >+ * @return The session this view was opened by, or <code>null</code> if this >+ * view is closed. >+ * @see #close() >+ * @see #isClosed() >+ * @see CDOSession#openView() >+ * @see CDOSession#openView(ResourceSet) >+ * @see CDOSession#openAudit(long) >+ * @see CDOSession#openAudit(ResourceSet, long) >+ * @see CDOSession#openTransaction() >+ * @see CDOSession#openTransaction(ResourceSet) >+ */ >+ public CDOSession getSession(); >+ >+ /** >+ * Returns the {@link CDOViewSet view set} this view is associated with. >+ * >+ * @return The view set this view is associated with, never >+ * <code>null</code>. >+ * @see CDOViewSet#getViews() >+ */ >+ public CDOViewSet getViewSet(); >+ >+ /** >+ * Returns the {@link ResourceSet resource set} this view is associated >+ * with. >+ * <p> >+ * Same as calling <tt>getViewSet().getResourceSet()</tt>. >+ * >+ * @see CDOViewSet#getResourceSet() >+ */ >+ public ResourceSet getResourceSet(); >+ >+ /** >+ * @deprecated This API is provisional and subject to change or removal. >+ */ >+ @Deprecated >+ public URIHandler getURIHandler(); >+ >+ /** >+ * Returns a reentrant lock that can be used to prevent the framework from >+ * writing to any object in this view (as it is caused, for example, by >+ * passive updates). >+ * <p> >+ * Acquiring this lock provides a means to safely iterate over multiple >+ * model elements without being affected by unanticipated remote updates, >+ * like in the following example: >+ * >+ * <pre> >+ * CDOResource resource = view.getResource("/orders/order-4711"); >+ * PurchaseOrder order = (PurchaseOrder)resource.getContents().get(0); >+ * ReentrantLock lock = view.getLock(); >+ * if (!lock.tryLock(5L, TimeUnit.SECONDS)) >+ * { >+ * throw new TimeoutException(); >+ * } >+ * try >+ * { >+ * float sum = 0; >+ * for (OrderDetail detail : order.getOrderDetails()) >+ * { >+ * sum += detail.getPrice(); >+ * } >+ * System.out.println("Sum: " + sum); >+ * } >+ * finally >+ * { >+ * lock.unlock(); >+ * } >+ * } >+ * </pre> >+ * >+ * Note that this method really just returns the lock instance but does >+ * <b>not</b> acquire the lock! The above example acquires the lock with a >+ * timeout that expires after five seconds. >+ */ >+ public ReentrantLock getLock(); >+ >+ /** >+ * Returns always <code>false</code>. >+ * <p> >+ * This method has a special implementation in {@link CDOTransaction} as >+ * well. >+ * >+ * @see CDOTransaction#isDirty() >+ */ >+ public boolean isDirty(); >+ >+ /** >+ * Returns always <code>false</code>. >+ * <p> >+ * This method has a special implementation in {@link CDOTransaction} as >+ * well. >+ * >+ * @see CDOTransaction#hasConflict() >+ */ >+ public boolean hasConflict(); >+ >+ /** >+ * Returns <code>true</code> if a resource with the given path exists in the >+ * repository, <code>false</code>. >+ * >+ * @see #getResource(String, boolean) >+ */ >+ public boolean hasResource(String path); >+ >+ /** >+ * @see ResourceSet#getResource(URI, boolean) >+ */ >+ public CDOResource getResource(String path, boolean loadOnDemand); >+ >+ /** >+ * Same as {@link #getResource(String, boolean) getResource(String, true)}. >+ * >+ * @see ResourceSet#getResource(URI, boolean) >+ */ >+ public CDOResource getResource(String path); >+ >+ /** >+ * Returns the resource node with the given path, or <code>null</code> if no >+ * such resource node exists. >+ */ >+ public CDOResourceNode getResourceNode(String path); >+ >+ /** >+ * Returns the root resource of the repository. >+ * <p> >+ * The root resource is a special resource with only {@link CDOResourceNode >+ * CDOResourceNodes} in its contents list. You can use it as the main entry >+ * into the new resource and folder structure. >+ */ >+ public CDOResource getRootResource(); >+ >+ /** >+ * Returns a list of the resources in the given folder with a name equal to >+ * or starting with the value of the name parameter. >+ * >+ * @param folder >+ * The folder to search in, or <code>null</code> for top level >+ * resource nodes. >+ * @param name >+ * the name or prefix of the resource nodes to return. >+ * @param exactMatch >+ * <code>true</code> if the complete name of the resource must >+ * match, <code>false</code> if only a common prefix of the name >+ * must match. >+ */ >+ public List<CDOResourceNode> queryResources(CDOResourceFolder folder, >+ String name, boolean exactMatch); >+ >+ /** >+ * Returns an iterator over the resources in the given folder with a name >+ * equal to or starting with the value of the name parameter. The underlying >+ * query will be executed asynchronously. >+ * >+ * @param folder >+ * The folder to search in, or <code>null</code> for top level >+ * resource nodes. >+ * @param name >+ * the name or prefix of the resource nodes to return. >+ * @param exactMatch >+ * <code>true</code> if the complete name of the resource must >+ * match, <code>false</code> if only a common prefix of the name >+ * must match. >+ */ >+ public CloseableIterator<CDOResourceNode> queryResourcesAsync( >+ CDOResourceFolder folder, String name, boolean exactMatch); >+ >+ /** >+ * Returns the object for the given CDOID. >+ * >+ * @param loadOnDemand >+ * whether to create and load the object, if it doesn't already >+ * exist. >+ * @return the object resolved by the CDOID if the id is not >+ * <code>null</code>, or <code>null</code> if there isn't one and >+ * loadOnDemand is <code>false</code>. >+ */ >+ public CDOObject getObject(CDOID id, boolean loadOnDemand); >+ >+ /** >+ * Returns the object for the given CDOID. >+ * <p> >+ * Same as <code>getObject(id, true)</code>. >+ * >+ * @see getObject(CDOID, boolean) >+ */ >+ public CDOObject getObject(CDOID id); >+ >+ /** >+ * Takes an object from a (possibly) different view and >+ * <em>contextifies</em> it for the usage with this view. >+ * <ul> >+ * <li>If the given object is contained in this view it is returned >+ * unmodified. >+ * <li>If the given object can not be cast to {@link CDOObject} it is >+ * returned unmodified. >+ * <li>If the view of the given object is contained in a different session >+ * an <code>IllegalArgumentException</code> is thrown. >+ * <li>If <code>null</code> is passed <code>null</code> is returned. >+ * </ul> >+ */ >+ public <T extends EObject> T getObject(T objectFromDifferentView); >+ >+ /** >+ * Returns <code>true</code> if an {@link CDOObject object} with the given >+ * {@link CDOID id} is currently registered in this view, <code>false</code> >+ * otherwise. >+ */ >+ public boolean isObjectRegistered(CDOID id); >+ >+ /** >+ * Reloads the given {@link CDOObject objects} from the repository. >+ */ >+ public int reload(CDOObject... objects); >+ >+ /** >+ * Locks the given objects. Once the objects are locked, they will not be >+ * changed remotely or go in conflict state. >+ * >+ * @since 3.0 >+ */ >+ public void lockObjects(Collection<? extends CDOObject> objects, >+ LockType lockType, long timeout) throws InterruptedException; >+ >+ /** >+ * Unlocks the given locked objects of this view. >+ */ >+ public void unlockObjects(Collection<? extends CDOObject> objects, >+ LockType lockType); >+ >+ /** >+ * Unlocks all locked objects of this view. >+ * >+ * @since 2.0 >+ */ >+ public void unlockObjects(); >+ >+ /** >+ * @since 3.0 >+ */ >+ public void addObjectHandler(CDOObjectHandler handler); >+ >+ /** >+ * @since 3.0 >+ */ >+ public void removeObjectHandler(CDOObjectHandler handler); >+ >+ /** >+ * @since 3.0 >+ */ >+ public CDOObjectHandler[] getObjectHandlers(); >+ >+ /** >+ * @since 2.0 >+ */ >+ public CDOQuery createQuery(String language, String queryString); >+ >+ /** >+ * @since 2.0 >+ */ >+ public Options options(); >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void registerLockListeners(Collection<IListener> collToRegister); >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void registerLockListener(IListener listenerToRegister); >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void unRegisterLockListener(IListener listenerToRegister); >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void unRegisterLockListeners(Collection<IListener> collToUnregister); >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void notifyRemoteLock(boolean b, String user, >+ Collection<CDOID> cdoids, LockType lockType); >+ >+ /** >+ * @author Simon McDuff >+ */ >+ public interface Options extends IOptions { >+ /** >+ */ >+ public static final int NO_REVISION_PREFETCHING = 1; >+ >+ /** >+ * Returns the reference type to be used in the internal object cache. >+ * >+ * @return Either {@link ReferenceType#STRONG STRONG}, >+ * {@link ReferenceType#SOFT SOFT} or {@link ReferenceType#WEAK >+ * WEAK}. >+ */ >+ public ReferenceType getCacheReferenceType(); >+ >+ /** >+ * Sets the reference type to be used in the internal object cache to >+ * either {@link ReferenceType#STRONG STRONG}, >+ * {@link ReferenceType#SOFT SOFT} or {@link ReferenceType#WEAK WEAK}. >+ * If <code>null</code> is passed the default reference type >+ * {@link ReferenceType#SOFT SOFT} is set. If the given reference type >+ * does not differ from the one being currently set the new value is >+ * ignored and <code>false</code> is returned. Otherwise existing object >+ * references are converted to the new type and <code>true</code> is >+ * returned. >+ */ >+ public boolean setCacheReferenceType(ReferenceType referenceType); >+ >+ /** >+ * Returns <code>true</code> if the {@link CDOObject objects} in this >+ * view will notify their {@link org.eclipse.emf.common.notify.Adapter >+ * adapters} about the fact that they are <em>invalidated</em> (due to >+ * remote changes), <code>false</code> otherwise. >+ * >+ * @see CDOInvalidationNotification >+ */ >+ public boolean isInvalidationNotificationEnabled(); >+ >+ /** >+ * Specifies whether the {@link CDOObject objects} in this view will >+ * notify their {@link org.eclipse.emf.common.notify.Adapter adapters} >+ * about the fact that they are <em>invalidated</em> (due to remote >+ * changes) or not. >+ * >+ * @see CDOInvalidationNotification >+ */ >+ public void setInvalidationNotificationEnabled(boolean enabled); >+ >+ /** >+ * Returns the current set of {@link CDOAdapterPolicy change >+ * subscription policies}. >+ * >+ * @return The current set of change subscription policies, never >+ * <code>null</code>. >+ * @see #setChangeSubscriptionPolicy(CDOAdapterPolicy) >+ */ >+ public CDOAdapterPolicy[] getChangeSubscriptionPolicies(); >+ >+ /** >+ * Adds a change subscription policy to this view. >+ * <p> >+ * To activate a policy, you must do the following: <br> >+ * <code>view.options().addChangeSubscriptionPolicy(CDOChangeSubscriptionPolicy.ALL);</code> >+ * <p> >+ * To register an object, you must add an adapter to the object in which >+ * you are interested:<br> >+ * <code>eObject.eAdapters().add(myAdapter);</code> >+ * <p> >+ * By activating this feature, each object having at least one adapter >+ * that matches the current policy will be registered with the server >+ * and will be notified for each change occurring in the scope of any >+ * other transaction. >+ * <p> >+ * {@link CDOAdapterPolicy#NONE} - Ignored. <br> >+ * {@link CDOAdapterPolicy#ALL} - Enabled for all adapters used.<br> >+ * {@link CDOAdapterPolicy#CDO} - Enabled only for adapters that >+ * implement {@link CDOAdapter}. <br> >+ * Any other class that implement {@link CDOAdapterPolicy} will enable >+ * for whatever rules defined in that class. <br> >+ * <p> >+ * If <code>myAdapter</code> in the above example matches the current >+ * policy, <code>eObject</code> will be registered with the server and >+ * you will receive all changes from other transaction. >+ * <p> >+ * When the policy is changed all objects in the cache will >+ * automatically be recalculated. >+ * <p> >+ * You can subscribe to temporary objects. Even if you cannot receive >+ * notifications from other {@link CDOTransaction} for these because >+ * they are only local to you, at commit time these objects will be >+ * registered automatically. >+ * <p> >+ * <b>Note:</b> It can be used with >+ * <code>CDOSession.options().setPassiveUpdate(false)</code>. In this >+ * case, it will receive changes without having the objects changed. >+ */ >+ public void addChangeSubscriptionPolicy(CDOAdapterPolicy policy); >+ >+ /** >+ * Removes a change subscription policy from this view. >+ */ >+ public void removeChangeSubscriptionPolicy(CDOAdapterPolicy policy); >+ >+ // TODO >+ public CDOAdapterPolicy getStrongReferencePolicy(); >+ >+ /** >+ * Sets the reference type to be used when an adapter is used to an >+ * object. >+ * <p> >+ * When <code>CDOView.setStrongReference(CDOAdapterPolicy.ALL)</code> is >+ * used, it is possible that the target object will be GC. In that case, >+ * the adapter will never received notifications. By Default the value >+ * is at <code>CDOAdapterPolicy.ALL</code> >+ */ >+ public void setStrongReferencePolicy(CDOAdapterPolicy policy); >+ >+ /** >+ * Returns the CDOStaleReferencePolicy in use. >+ * >+ * @since 3.0 >+ */ >+ public CDOStaleReferencePolicy getStaleReferenceBehaviour(); >+ >+ /** >+ * Sets a policy on how to deal with stale references. >+ * >+ * @since 3.0 >+ */ >+ public void setStaleReferenceBehaviour(CDOStaleReferencePolicy policy); >+ >+ /** >+ * Returns the CDORevisionPrefetchingPolicy in use. >+ */ >+ public CDORevisionPrefetchingPolicy getRevisionPrefetchingPolicy(); >+ >+ /** >+ * The CDORevisionPrefetchingPolicy feature of the CDOView allows CDO >+ * users to fetch many objects at a time. >+ * <p> >+ * The difference between the CDOCollectionLoadingPolicy feature and the >+ * CDORevisionPrefetchingPolicy feature is subtle. The >+ * CDOCollectionLoadingPolicy feature determines how and when to fetch >+ * CDOIDs, while the CDORevisionPrefetchingPolicy feature determines how >+ * and when to resolve CDOIDs (i.e. fetch the target objects). >+ * <p> >+ * <code>view.options().setRevisionPrefetchingPolicy (CDONet4jUtil.createRevisionPrefetchingPolicy(10));</code> >+ * <p> >+ * The end-user could provide its own implementation of the >+ * CDORevisionPrefetchingPolicy interface. >+ */ >+ public void setRevisionPrefetchingPolicy( >+ CDORevisionPrefetchingPolicy prefetchingPolicy); >+ >+ public interface CacheReferenceTypeEvent extends IOptionsEvent { >+ } >+ >+ public interface ReferencePolicyEvent extends IOptionsEvent { >+ } >+ >+ /** >+ * @since 3.0 >+ */ >+ public interface StaleReferencePolicyEvent extends IOptionsEvent { >+ } >+ >+ public interface ChangeSubscriptionPoliciesEvent extends IOptionsEvent { >+ } >+ >+ public interface InvalidationNotificationEvent extends IOptionsEvent { >+ } >+ >+ public interface RevisionPrefetchingPolicyEvent extends IOptionsEvent { >+ } >+ } > } >Index: src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java,v >retrieving revision 1.44 >diff -u -r1.44 CDOViewImpl.java >--- src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java 7 Nov 2009 09:37:20 -0000 1.44 >+++ src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java 30 Nov 2009 20:08:45 -0000 >@@ -50,6 +50,8 @@ > import org.eclipse.emf.cdo.view.CDOViewAdaptersNotifiedEvent; > import org.eclipse.emf.cdo.view.CDOViewEvent; > import org.eclipse.emf.cdo.view.CDOViewInvalidationEvent; >+import org.eclipse.emf.cdo.view.RemoteLockAcquiredEvent; >+import org.eclipse.emf.cdo.view.RemoteLockReleasedEvent; > > import org.eclipse.emf.internal.cdo.CDODeltaNotificationImpl; > import org.eclipse.emf.internal.cdo.CDOInvalidationNotificationImpl; >@@ -114,2299 +116,2114 @@ > /** > * @author Eike Stepper > */ >-public class CDOViewImpl extends Lifecycle implements InternalCDOView >-{ >- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_VIEW, CDOViewImpl.class); >- >- private int viewID; >- >- private InternalCDOSession session; >- >- private InternalCDOViewSet viewSet; >- >- private CDOURIHandler uriHandler = new CDOURIHandler(this); >- >- private CDOFeatureAnalyzer featureAnalyzer = CDOFeatureAnalyzer.NOOP; >- >- private ConcurrentMap<CDOID, InternalCDOObject> objects; >- >- private CDOStore store = new CDOStore(this); >- >- private ReentrantLock lock = new ReentrantLock(true); >- >- private ReentrantLock stateLock = new ReentrantLock(true); >- >- private CDOResourceImpl rootResource; >- >- private ChangeSubscriptionManager changeSubscriptionManager = createChangeSubscriptionManager(); >- >- private AdapterManager adapterPolicyManager = createAdapterManager(); >- >- private FastList<CDOObjectHandler> objectHandlers = new FastList<CDOObjectHandler>() >- { >- @Override >- protected CDOObjectHandler[] newArray(int length) >- { >- return new CDOObjectHandler[length]; >- } >- }; >- >- private OptionsImpl options; >- >- @ExcludeFromDump >- private transient CDOID lastLookupID; >- >- @ExcludeFromDump >- private transient InternalCDOObject lastLookupObject; >- >- /** >- * @since 2.0 >- */ >- public CDOViewImpl() >- { >- options = createOptions(); >- } >- >- /** >- * @since 2.0 >- */ >- public OptionsImpl options() >- { >- return options; >- } >- >- public int getViewID() >- { >- return viewID; >- } >- >- /** >- * @since 2.0 >- */ >- public void setViewID(int viewId) >- { >- viewID = viewId; >- } >- >- public Type getViewType() >- { >- return Type.READONLY; >- } >- >- public ResourceSet getResourceSet() >- { >- return viewSet.getResourceSet(); >- } >- >- /** >- * @since 2.0 >- */ >- public InternalCDOViewSet getViewSet() >- { >- return viewSet; >- } >- >- /** >- * @since 2.0 >- */ >- public void setViewSet(InternalCDOViewSet viewSet) >- { >- this.viewSet = viewSet; >- if (viewSet != null) >- { >- viewSet.getResourceSet().getURIConverter().getURIHandlers().add(0, getURIHandler()); >- } >- } >- >- /** >- * @since 2.0 >- */ >- public InternalCDOSession getSession() >- { >- return session; >- } >- >- /** >- * @since 2.0 >- */ >- public void setSession(InternalCDOSession session) >- { >- this.session = session; >- } >- >- public CDOStore getStore() >- { >- checkActive(); >- return store; >- } >- >- /** >- * @since 2.0 >- */ >- public synchronized CDOResourceImpl getRootResource() >- { >- checkActive(); >- if (rootResource == null) >- { >- rootResource = createRootResource(); >- } >- >- return rootResource; >- } >- >- /** >- * @return >- * @since 2.0 >- */ >- protected CDOResourceImpl createRootResource() >- { >- return (CDOResourceImpl)getResource(CDOResourceNode.ROOT_PATH); >- } >- >- /** >- * @since 2.0 >- */ >- public CDOURIHandler getURIHandler() >- { >- return uriHandler; >- } >- >- /** >- * @since 2.0 >- */ >- public ReentrantLock getLock() >- { >- return lock; >- } >- >- /** >- * @since 2.0 >- */ >- public ReentrantLock getStateLock() >- { >- return stateLock; >- } >- >- /** >- * @throws InterruptedException >- * @since 2.0 >- */ >- public void lockObjects(Collection<? extends CDOObject> objects, LockType lockType, long timeout) >- throws InterruptedException >- { >- checkActive(); >- Map<CDOID, CDOIDAndVersion> uniqueObjects = new HashMap<CDOID, CDOIDAndVersion>(); >- getCDOIDAndVersion(uniqueObjects, objects); >- for (CDOObject object : objects) >- { >- CDOIDAndVersion idAndVersion = uniqueObjects.get(object.cdoID()); >- if (idAndVersion == null) >- { >- uniqueObjects >- .put(object.cdoID(), CDOIDUtil.createIDAndVersion(object.cdoID(), CDORevision.UNSPECIFIED_VERSION)); >- } >- } >- >- session.getSessionProtocol().lockObjects(this, uniqueObjects, timeout, lockType); >- } >- >- /** >- * @since 2.0 >- */ >- public void unlockObjects(Collection<? extends CDOObject> objects, LockType lockType) >- { >- checkActive(); >- session.getSessionProtocol().unlockObjects(this, objects, lockType); >- } >- >- /** >- * @since 2.0 >- */ >- public void unlockObjects() >- { >- unlockObjects(null, null); >- } >- >- /** >- * @since 2.0 >- */ >- public boolean isObjectLocked(CDOObject object, LockType lockType, boolean byOthers) >- { >- checkActive(); >- return session.getSessionProtocol().isObjectLocked(this, object, lockType, byOthers); >- } >- >- /** >- * @since 2.0 >- */ >- public long getTimeStamp() >- { >- return UNSPECIFIED_DATE; >- } >- >- public boolean isDirty() >- { >- return false; >- } >- >- public boolean hasConflict() >- { >- return false; >- } >- >- /** >- * @since 2.0 >- */ >- public CDOFeatureAnalyzer getFeatureAnalyzer() >- { >- return featureAnalyzer; >- } >- >- /** >- * @since 2.0 >- */ >- public void setFeatureAnalyzer(CDOFeatureAnalyzer featureAnalyzer) >- { >- this.featureAnalyzer = featureAnalyzer == null ? CDOFeatureAnalyzer.NOOP : featureAnalyzer; >- } >- >- /** >- * @since 2.0 >- */ >- public InternalCDOTransaction toTransaction() >- { >- checkActive(); >- if (this instanceof InternalCDOTransaction) >- { >- return (InternalCDOTransaction)this; >- } >- >- throw new ReadOnlyException(MessageFormat.format(Messages.getString("CDOViewImpl.0"), this)); //$NON-NLS-1$ >- } >- >- public boolean hasResource(String path) >- { >- checkActive(); >- >- try >- { >- getResourceNodeID(path); >- return true; >- } >- catch (Exception ex) >- { >- return false; >- } >- } >- >- /** >- * @since 2.0 >- */ >- public CDOQuery createQuery(String language, String queryString) >- { >- checkActive(); >- return new CDOQueryImpl(this, language, queryString); >- } >- >- /** >- * @since 2.0 >- */ >- public CDOResourceNode getResourceNode(String path) >- { >- CDOID id = getResourceNodeID(path); >- if (id == null) >- { >- return null; >- } >- >- InternalCDOObject object = getObject(id); >- if (object instanceof CDOResourceNode) >- { >- return (CDOResourceNode)object; >- } >- >- return null; >- } >- >- /** >- * @return never <code>null</code> >- * @since 2.0 >- */ >- public CDOID getResourceNodeID(String path) >- { >- if (StringUtil.isEmpty(path)) >- { >- throw new IllegalArgumentException(Messages.getString("CDOViewImpl.1")); //$NON-NLS-1$ >- } >- >- CDOID folderID = null; >- if (CDOURIUtil.SEGMENT_SEPARATOR.equals(path)) >- { >- folderID = getResourceNodeIDChecked(null, null); >- } >- else >- { >- List<String> names = CDOURIUtil.analyzePath(path); >- for (String name : names) >- { >- folderID = getResourceNodeIDChecked(folderID, name); >- } >- } >- >- return folderID; >- } >- >- /** >- * @return never <code>null</code> >- */ >- private CDOID getResourceNodeIDChecked(CDOID folderID, String name) >- { >- folderID = getResourceNodeID(folderID, name); >- if (folderID == null) >- { >- throw new CDOException(MessageFormat.format(Messages.getString("CDOViewImpl.2"), name)); //$NON-NLS-1$ >- } >- >- return folderID; >- } >- >- /** >- * @return never <code>null</code> >- * @since 2.0 >- */ >- protected CDOResourceNode getResourceNode(CDOID folderID, String name) >- { >- try >- { >- CDOID id = getResourceNodeID(folderID, name); >- return (CDOResourceNode)getObject(id); >- } >- catch (CDOException ex) >- { >- throw ex; >- } >- catch (Exception ex) >- { >- throw new CDOException(ex); >- } >- } >- >- /** >- * @since 2.0 >- */ >- protected CDOID getResourceNodeID(CDOID folderID, String name) >- { >- if (folderID == null) >- { >- return getRootOrTopLevelResourceNodeID(name); >- } >- >- if (name == null) >- { >- throw new IllegalArgumentException(Messages.getString("CDOViewImpl.3")); //$NON-NLS-1$ >- } >- >- InternalCDORevision folderRevision = getLocalRevision(folderID); >- EClass resourceFolderClass = EresourcePackage.eINSTANCE.getCDOResourceFolder(); >- if (folderRevision.getEClass() != resourceFolderClass) >- { >- throw new CDOException(MessageFormat.format(Messages.getString("CDOViewImpl.4"), folderID)); //$NON-NLS-1$ >- } >- >- EReference nodesFeature = EresourcePackage.eINSTANCE.getCDOResourceFolder_Nodes(); >- EAttribute nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name(); >- >- int size = folderRevision.data().size(nodesFeature); >- for (int i = 0; i < size; i++) >- { >- Object value = folderRevision.data().get(nodesFeature, i); >- value = getStore().resolveProxy(folderRevision, nodesFeature, i, value); >- >- CDORevision childRevision = getLocalRevision((CDOID)convertObjectToID(value)); >- if (name.equals(childRevision.data().get(nameFeature, 0))) >- { >- return childRevision.getID(); >- } >- } >- >- throw new CDOException(MessageFormat.format(Messages.getString("CDOViewImpl.5"), name)); //$NON-NLS-1$ >- } >- >- /** >- * @since 2.0 >- */ >- protected CDOID getRootOrTopLevelResourceNodeID(String name) >- { >- CDOQuery resourceQuery = createResourcesQuery(null, name, true); >- resourceQuery.setMaxResults(1); >- List<CDOID> ids = resourceQuery.getResult(CDOID.class); >- if (ids.isEmpty()) >- { >- if (name == null) >- { >- throw new CDOException(Messages.getString("CDOViewImpl.6")); //$NON-NLS-1$ >- } >- else >- { >- throw new CDOException(MessageFormat.format(Messages.getString("CDOViewImpl.7"), name)); //$NON-NLS-1$ >- } >- } >- >- if (ids.size() > 1) >- { >- // TODO is this still needed since the is resourceQuery.setMaxResults(1) ?? >- throw new ImplementationError(Messages.getString("CDOViewImpl.8")); //$NON-NLS-1$ >- } >- >- return ids.get(0); >- } >- >- /** >- * @since 2.0 >- */ >- protected InternalCDORevision getLocalRevision(CDOID id) >- { >- InternalCDORevision revision = null; >- InternalCDOObject object = getObject(id, false); >- if (object != null && object.cdoState() != CDOState.PROXY) >- { >- revision = object.cdoRevision(); >- } >- >- if (revision == null) >- { >- revision = getRevision(id, true); >- } >- >- if (revision == null) >- { >- throw new CDOException(MessageFormat.format(Messages.getString("CDOViewImpl.9"), id)); //$NON-NLS-1$ >- } >- >- return revision; >- } >- >- /** >- * @since 2.0 >- */ >- public InternalCDOObject[] getObjectsArray() >- { >- synchronized (objects) >- { >- return objects.values().toArray(new InternalCDOObject[objects.size()]); >- } >- } >- >- /** >- * TODO Remove me >- * >- * @since 2.0 >- */ >- @Deprecated >- public CDOResourceFolder getResourceFolder(String path) >- { >- if (path == null) >- { >- return null; >- } >- >- CDOResourceFolder folder = null; >- StringTokenizer tokenizer = new StringTokenizer(path, CDOURIUtil.SEGMENT_SEPARATOR); >- while (tokenizer.hasMoreTokens()) >- { >- String segment = tokenizer.nextToken(); >- if (segment != null) >- { >- if (folder == null) >- { >- } >- else >- { >- } >- } >- } >- >- return folder; >- } >- >- /** >- * @since 2.0 >- */ >- public CDOResource getResource(String path) >- { >- return getResource(path, true); >- } >- >- /** >- * @since 2.0 >- */ >- public CDOResource getResource(String path, boolean loadInDemand) >- { >- checkActive(); >- URI uri = CDOURIUtil.createResourceURI(this, path); >- return (CDOResource)getResourceSet().getResource(uri, loadInDemand); >- } >- >- /** >- * @since 2.0 >- */ >- public List<CDOResourceNode> queryResources(CDOResourceFolder folder, String name, boolean exactMatch) >- { >- checkActive(); >- CDOQuery resourceQuery = createResourcesQuery(folder, name, exactMatch); >- return resourceQuery.getResult(CDOResourceNode.class); >- } >- >- /** >- * @since 2.0 >- */ >- public CloseableIterator<CDOResourceNode> queryResourcesAsync(CDOResourceFolder folder, String name, >- boolean exactMatch) >- { >- checkActive(); >- CDOQuery resourceQuery = createResourcesQuery(folder, name, exactMatch); >- return resourceQuery.getResultAsync(CDOResourceNode.class); >- } >- >- private CDOQuery createResourcesQuery(CDOResourceFolder folder, String name, boolean exactMatch) >- { >- CDOQuery query = createQuery(CDOProtocolConstants.QUERY_LANGUAGE_RESOURCES, name); >- query.setParameter(CDOProtocolConstants.QUERY_LANGUAGE_RESOURCES_FOLDER_ID, folder == null ? null : folder.cdoID()); >- query.setParameter(CDOProtocolConstants.QUERY_LANGUAGE_RESOURCES_EXACT_MATCH, exactMatch); >- return query; >- } >- >- public CDOResourceImpl getResource(CDOID resourceID) >- { >- if (CDOIDUtil.isNull(resourceID)) >- { >- throw new IllegalArgumentException("resourceID: " + resourceID); //$NON-NLS-1$ >- } >- >- return (CDOResourceImpl)getObject(resourceID); >- } >- >- public InternalCDOObject newInstance(EClass eClass) >- { >- EObject eObject = EcoreUtil.create(eClass); >- return FSMUtil.adapt(eObject, this); >- } >- >- public InternalCDORevision getRevision(CDOID id, boolean loadOnDemand) >- { >- CDORevisionManager revisionManager = session.getRevisionManager(); >- int initialChunkSize = session.options().getCollectionLoadingPolicy().getInitialChunkSize(); >- return (InternalCDORevision)revisionManager.getRevision(id, initialChunkSize, CDORevision.DEPTH_NONE, loadOnDemand); >- } >- >- public void prefetchRevisions(CDOID id, int depth) >- { >- checkArg(depth != CDORevision.DEPTH_NONE, "Prefetch depth must not be zero"); >- int initialChunkSize = session.options().getCollectionLoadingPolicy().getInitialChunkSize(); >- prefetchRevisions(id, depth, initialChunkSize); >- } >- >- protected void prefetchRevisions(CDOID id, int depth, int initialChunkSize) >- { >- session.getRevisionManager().getRevision(id, initialChunkSize, depth); >- } >- >- public InternalCDOObject getObject(CDOID id) >- { >- return getObject(id, true); >- } >- >- /** >- * Support recursivity and concurrency. >- */ >- public InternalCDOObject getObject(CDOID id, boolean loadOnDemand) >- { >- checkActive(); >- if (CDOIDUtil.isNull(id)) >- { >- return null; >- } >- >- // Since getObject could trigger a read (ONLY when we load a resource) we NEED to make sure the state lock is >- // active. >- // Always use in the following order >- // 1- getStateLock().lock(); >- // 2- synchronized(objects) >- // DO NOT inverse them otherwise deadlock could occured. >- >- ReentrantLock stateLock = getStateLock(); >- stateLock.lock(); >- try >- { >- synchronized (objects) >- { >- if (id.equals(lastLookupID)) >- { >- return lastLookupObject; >- } >- >- // Needed for recursive call to getObject. (from createObject/cleanObject/getResource/getObject) >- InternalCDOObject localLookupObject = objects.get(id); >- if (localLookupObject == null) >- { >- if (id.isMeta()) >- { >- localLookupObject = createMetaObject((CDOIDMeta)id); >- } >- else >- { >- if (loadOnDemand) >- { >- if (id.isTemporary()) >- { >- throw new ObjectNotFoundException(id); >- } >- >- localLookupObject = createObject(id); >- } >- else >- { >- return null; >- } >- } >- >- // CDOResource have a special way to register to the view. >- if (!CDOModelUtil.isResource(localLookupObject.eClass())) >- { >- registerObject(localLookupObject); >- } >- } >- >- lastLookupID = id; >- lastLookupObject = localLookupObject; >- return lastLookupObject; >- } >- } >- finally >- { >- stateLock.unlock(); >- } >- } >- >- /** >- * @since 2.0 >- */ >- @SuppressWarnings("unchecked") >- public <T extends EObject> T getObject(T objectFromDifferentView) >- { >- checkActive(); >- if (objectFromDifferentView instanceof CDOObject) >- { >- CDOObject object = (CDOObject)objectFromDifferentView; >- CDOView view = object.cdoView(); >- if (view != this) >- { >- if (view.getSession() != session) >- { >- throw new IllegalArgumentException(MessageFormat.format( >- Messages.getString("CDOViewImpl.11"), objectFromDifferentView)); //$NON-NLS-1$ >- } >- >- CDOID id = object.cdoID(); >- objectFromDifferentView = (T)getObject(id, true); >- } >- } >- >- return objectFromDifferentView; >- } >- >- public boolean isObjectRegistered(CDOID id) >- { >- checkActive(); >- if (CDOIDUtil.isNull(id)) >- { >- return false; >- } >- >- synchronized (objects) >- { >- return objects.containsKey(id); >- } >- } >- >- public InternalCDOObject removeObject(CDOID id) >- { >- synchronized (objects) >- { >- if (id.equals(lastLookupID)) >- { >- lastLookupID = null; >- lastLookupObject = null; >- } >- >- return objects.remove(id); >- } >- } >- >- /** >- * @return Never <code>null</code> >- */ >- private InternalCDOObject createMetaObject(CDOIDMeta id) >- { >- if (TRACER.isEnabled()) >- { >- TRACER.trace("Creating meta object for " + id); //$NON-NLS-1$ >- } >- >- InternalCDOPackageRegistry packageRegistry = session.getPackageRegistry(); >- InternalEObject metaInstance = packageRegistry.getMetaInstanceMapper().lookupMetaInstance(id); >- return new CDOMetaWrapper(this, metaInstance, id); >- } >- >- /** >- * @return Never <code>null</code> >- */ >- private InternalCDOObject createObject(CDOID id) >- { >- if (TRACER.isEnabled()) >- { >- TRACER.trace("Creating object for " + id); //$NON-NLS-1$ >- } >- >- InternalCDORevision revision = getRevision(id, true); >- FSMUtil.validate(id, revision); >- >- EClass eClass = revision.getEClass(); >- InternalCDOObject object; >- if (CDOModelUtil.isResource(eClass)) >- { >- object = (InternalCDOObject)newResourceInstance(revision); >- // object is PROXY >- } >- else >- { >- object = newInstance(eClass); >- // object is TRANSIENT >- } >- >- cleanObject(object, revision); >- return object; >- } >- >- private CDOResource newResourceInstance(InternalCDORevision revision) >- { >- String path = getResourcePath(revision); >- return getResource(path, true); >- } >- >- private String getResourcePath(InternalCDORevision revision) >- { >- EAttribute nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name(); >- >- CDOID folderID = (CDOID)revision.data().getContainerID(); >- String name = (String)revision.data().get(nameFeature, 0); >- if (CDOIDUtil.isNull(folderID)) >- { >- if (name == null) >- { >- return CDOURIUtil.SEGMENT_SEPARATOR; >- } >- >- return name; >- } >- >- InternalCDOObject object = getObject(folderID, true); >- if (object instanceof CDOResourceFolder) >- { >- CDOResourceFolder folder = (CDOResourceFolder)object; >- String path = folder.getPath(); >- return path + CDOURIUtil.SEGMENT_SEPARATOR + name; >- } >- >- throw new ImplementationError(MessageFormat.format(Messages.getString("CDOViewImpl.14"), object)); //$NON-NLS-1$ >- } >- >- /** >- * @since 2.0 >- */ >- protected void cleanObject(InternalCDOObject object, InternalCDORevision revision) >- { >- object.cdoInternalCleanup(); >- >- object.cdoInternalSetView(this); >- object.cdoInternalSetRevision(revision); >- object.cdoInternalSetID(revision.getID()); >- object.cdoInternalSetState(CDOState.CLEAN); >- >- object.cdoInternalPostLoad(); >- } >- >- public CDOID provideCDOID(Object idOrObject) >- { >- Object shouldBeCDOID = convertObjectToID(idOrObject); >- if (shouldBeCDOID instanceof CDOID) >- { >- CDOID id = (CDOID)shouldBeCDOID; >- if (TRACER.isEnabled() && id != idOrObject) >- { >- TRACER.format("Converted object to CDOID: {0} --> {1}", idOrObject, id); //$NON-NLS-1$ >- } >- >- return id; >- } >- else if (idOrObject instanceof InternalEObject) >- { >- InternalEObject eObject = (InternalEObject)idOrObject; >- String uri = EcoreUtil.getURI(eObject).toString(); >- if (eObject instanceof InternalCDOObject) >- { >- InternalCDOObject object = (InternalCDOObject)idOrObject; >- if (object.cdoView() != null && FSMUtil.isNew(object)) >- { >- return CDOIDUtil.createTempObjectExternal(uri); >- } >- } >- >- if (eObject.eResource() != null) >- { >- return CDOIDUtil.createExternal(uri); >- } >- >- throw new DanglingReferenceException(eObject); >- } >- >- throw new IllegalStateException(MessageFormat.format( >- Messages.getString("CDOViewImpl.16"), idOrObject.getClass().getName())); //$NON-NLS-1$ >- } >- >- public Object convertObjectToID(Object potentialObject) >- { >- return convertObjectToID(potentialObject, false); >- } >- >- /** >- * @since 2.0 >- */ >- public Object convertObjectToID(Object potentialObject, boolean onlyPersistedID) >- { >- if (potentialObject instanceof CDOID) >- { >- return potentialObject; >- } >- >- if (potentialObject instanceof InternalEObject) >- { >- if (potentialObject instanceof InternalCDOObject) >- { >- InternalCDOObject object = (InternalCDOObject)potentialObject; >- CDOID id = getID(object, onlyPersistedID); >- if (id != null) >- { >- return id; >- } >- } >- else >- { >- try >- { >- InternalCDOObject object = FSMUtil.getLegacyAdapter(((InternalEObject)potentialObject).eAdapters()); >- if (object != null) >- { >- CDOID id = getID(object, onlyPersistedID); >- if (id != null) >- { >- return id; >- } >- >- potentialObject = object; >- } >- } >- catch (Throwable ex) >- { >- OM.LOG.warn(ex); >- } >- } >- } >- >- return potentialObject; >- } >- >- // TTT public CDOIDDangling convertDanglingObjectToID(InternalCDOObject source, EStructuralFeature feature, >- // InternalEObject target) >- // { >- // throw new IllegalStateException("Dangling objects not possible outside of a transaction"); >- // } >- >- protected CDOID getID(InternalCDOObject object, boolean onlyPersistedID) >- { >- if (onlyPersistedID) >- { >- if (FSMUtil.isTransient(object) || FSMUtil.isNew(object)) >- { >- return null; >- } >- } >- >- CDOView view = object.cdoView(); >- if (view == this) >- { >- return object.cdoID(); >- } >- >- if (view != null && view.getSession() == getSession()) >- { >- return object.cdoID(); >- } >- >- return null; >- } >- >- public Object convertIDToObject(Object potentialID) >- { >- if (potentialID instanceof CDOID) >- { >- if (potentialID == CDOID.NULL) >- { >- return null; >- } >- >- CDOID id = (CDOID)potentialID; >- if (id.isExternal()) >- { >- return getResourceSet().getEObject(URI.createURI(id.toURIFragment()), true); >- } >- >- InternalCDOObject result = getObject(id, true); >- if (result == null) >- { >- throw new ImplementationError(MessageFormat.format(Messages.getString("CDOViewImpl.17"), id)); //$NON-NLS-1$ >- } >- >- return result.cdoInternalInstance(); >- } >- >- return potentialID; >- } >- >- /** >- * @since 2.0 >- */ >- public void attachResource(CDOResourceImpl resource) >- { >- if (!resource.isExisting()) >- { >- throw new ReadOnlyException(MessageFormat.format(Messages.getString("CDOViewImpl.18"), this)); //$NON-NLS-1$ >- } >- >- // ResourceSet.getResource(uri, true) was called!! >- resource.cdoInternalSetView(this); >- resource.cdoInternalSetState(CDOState.PROXY); >- } >- >- /** >- * @since 2.0 >- */ >- public void registerProxyResource(CDOResourceImpl resource) >- { >- URI uri = resource.getURI(); >- String path = CDOURIUtil.extractResourcePath(uri); >- >- try >- { >- CDOID id = getResourceNodeID(path); >- resource.cdoInternalSetID(id); >- registerObject(resource); >- } >- catch (Exception ex) >- { >- throw new InvalidURIException(uri, ex); >- } >- } >- >- public void registerObject(InternalCDOObject object) >- { >- if (TRACER.isEnabled()) >- { >- TRACER.format("Registering {0}", object); //$NON-NLS-1$ >- } >- >- InternalCDOObject old; >- synchronized (objects) >- { >- old = objects.put(object.cdoID(), object); >- } >- >- if (old != null) >- { >- throw new IllegalStateException(MessageFormat.format(Messages.getString("CDOViewImpl.20"), object)); //$NON-NLS-1$ >- } >- } >- >- public void deregisterObject(InternalCDOObject object) >- { >- if (TRACER.isEnabled()) >- { >- TRACER.format("Deregistering {0}", object); //$NON-NLS-1$ >- } >- >- removeObject(object.cdoID()); >- } >- >- public void remapObject(CDOID oldID) >- { >- CDOID newID; >- synchronized (objects) >- { >- InternalCDOObject object = objects.remove(oldID); >- newID = object.cdoID(); >- objects.put(newID, object); >- } >- >- if (TRACER.isEnabled()) >- { >- TRACER.format("Remapping {0} --> {1}", oldID, newID); //$NON-NLS-1$ >- } >- } >- >- public void addObjectHandler(CDOObjectHandler handler) >- { >- objectHandlers.add(handler); >- } >- >- public void removeObjectHandler(CDOObjectHandler handler) >- { >- objectHandlers.remove(handler); >- } >- >- public CDOObjectHandler[] getObjectHandlers() >- { >- return objectHandlers.get(); >- } >- >- public void handleObjectStateChanged(InternalCDOObject object, CDOState oldState, CDOState newState) >- { >- CDOObjectHandler[] handlers = getObjectHandlers(); >- if (handlers != null) >- { >- for (int i = 0; i < handlers.length; i++) >- { >- CDOObjectHandler handler = handlers[i]; >- handler.objectStateChanged(this, object, oldState, newState); >- } >- } >- } >- >- /** >- * Turns registered objects into proxies and synchronously delivers invalidation events to registered event listeners. >- * <p> >- * <b>Implementation note:</b> This implementation guarantees that exceptions from listener code don't propagate up to >- * the caller of this method. Runtime exceptions from the implementation of the {@link CDOStateMachine} are propagated >- * to the caller of this method but this should not happen in the absence of implementation errors. >- * <p> >- * Note that this method can block for an uncertain amount of time on the reentrant view lock! >- * >- * @param timeStamp >- * The time stamp of the server transaction if this event was sent as a result of a successfully committed >- * transaction or <code>LOCAL_ROLLBACK</code> if this event was sent due to a local rollback. >- * @param dirtyOIDs >- * A set of the object IDs to be invalidated. <b>Implementation note:</b> This implementation expects the >- * dirtyOIDs set to be unmodifiable. It does not wrap the set (again). >- * @since 2.0 >- */ >- public Set<CDOObject> handleInvalidation(long timeStamp, Set<CDOIDAndVersion> dirtyOIDs, >- Collection<CDOID> detachedOIDs) >- { >- Set<CDOObject> conflicts = null; >- Set<InternalCDOObject> dirtyObjects = new HashSet<InternalCDOObject>(); >- Set<InternalCDOObject> detachedObjects = new HashSet<InternalCDOObject>(); >- lock.lock(); >- >- try >- { >- conflicts = handleInvalidationWithoutNotification(dirtyOIDs, detachedOIDs, dirtyObjects, detachedObjects); >- } >- finally >- { >- lock.unlock(); >- } >- >- if (options().isInvalidationNotificationEnabled()) >- { >- for (InternalCDOObject dirtyObject : dirtyObjects) >- { >- if (dirtyObject.eNotificationRequired()) >- { >- CDOInvalidationNotificationImpl notification = new CDOInvalidationNotificationImpl(dirtyObject); >- dirtyObject.eNotify(notification); >- } >- } >- >- for (InternalCDOObject detachedObject : detachedObjects) >- { >- if (detachedObject.eNotificationRequired()) >- { >- CDOInvalidationNotificationImpl notification = new CDOInvalidationNotificationImpl(detachedObject); >- detachedObject.eNotify(notification); >- } >- } >- } >- >- fireInvalidationEvent(timeStamp, Collections.unmodifiableSet(dirtyObjects), Collections >- .unmodifiableSet(detachedObjects)); >- return conflicts; >- } >- >- public Set<CDOObject> handleInvalidationWithoutNotification(Set<CDOIDAndVersion> dirtyOIDs, >- Collection<CDOID> detachedOIDs, Set<InternalCDOObject> dirtyObjects, Set<InternalCDOObject> detachedObjects) >- { >- Set<CDOObject> conflicts = null; >- for (CDOIDAndVersion dirtyOID : dirtyOIDs) >- { >- InternalCDOObject dirtyObject = null; >- // 258831 - Causes deadlock when introduce thread safe mechanisms in State machine. >- synchronized (objects) >- { >- dirtyObject = objects.get(dirtyOID.getID()); >- } >- >- if (dirtyObject != null) >- { >- CDOStateMachine.INSTANCE.invalidate(dirtyObject, dirtyOID.getVersion()); >- dirtyObjects.add(dirtyObject); >- if (dirtyObject.cdoConflict()) >- { >- if (conflicts == null) >- { >- conflicts = new HashSet<CDOObject>(); >- } >- >- conflicts.add(dirtyObject); >- } >- } >- } >- >- for (CDOID id : detachedOIDs) >- { >- InternalCDOObject detachedObject = removeObject(id); >- if (detachedObject != null) >- { >- CDOStateMachine.INSTANCE.detachRemote(detachedObject); >- detachedObjects.add(detachedObject); >- if (detachedObject.cdoConflict()) >- { >- if (conflicts == null) >- { >- conflicts = new HashSet<CDOObject>(); >- } >- >- conflicts.add(detachedObject); >- } >- } >- } >- >- return conflicts; >- } >- >- /** >- * @since 2.0 >- */ >- private void fireInvalidationEvent(long timeStamp, Set<? extends CDOObject> dirtyObjects, >- Set<? extends CDOObject> detachedObjects) >- { >- if (!dirtyObjects.isEmpty() || !detachedObjects.isEmpty()) >- { >- IListener[] listeners = getListeners(); >- if (listeners != null) >- { >- fireEvent(new InvalidationEvent(timeStamp, dirtyObjects, detachedObjects), listeners); >- } >- } >- } >- >- public void fireAdaptersNotifiedEvent(long timeStamp) >- { >- fireEvent(new AdaptersNotifiedEvent(timeStamp)); >- } >- >- /** >- * @since 2.0 >- */ >- public void handleChangeSubscription(Collection<CDORevisionDelta> deltas, Collection<CDOID> detachedObjects) >- { >- boolean policiesPresent = options().hasChangeSubscriptionPolicies(); >- if (!policiesPresent) >- { >- return; >- } >- >- if (deltas != null) >- { >- CDONotificationBuilder builder = new CDONotificationBuilder(); >- for (CDORevisionDelta delta : deltas) >- { >- InternalCDOObject object = changeSubscriptionManager.getSubcribeObject(delta.getID()); >- if (object != null && object.eNotificationRequired()) >- { >- NotificationImpl notification = builder.buildNotification(object, delta); >- if (notification != null) >- { >- notification.dispatch(); >- } >- } >- } >- } >- >- if (detachedObjects != null) >- { >- for (CDOID id : detachedObjects) >- { >- InternalCDOObject object = changeSubscriptionManager.getSubcribeObject(id); >- if (object != null && object.eNotificationRequired()) >- { >- NotificationImpl notification = new CDODeltaNotificationImpl(object, CDONotification.DETACH_OBJECT, >- Notification.NO_FEATURE_ID, null, null); >- notification.dispatch(); >- } >- } >- >- getChangeSubscriptionManager().handleDetachedObjects(detachedObjects); >- } >- } >- >- /** >- * @since 2.0 >- */ >- protected ChangeSubscriptionManager createChangeSubscriptionManager() >- { >- return new ChangeSubscriptionManager(this); >- } >- >- /** >- * @since 2.0 >- */ >- public AdapterManager getAdapterManager() >- { >- return adapterPolicyManager; >- } >- >- /** >- * @since 2.0 >- */ >- protected AdapterManager createAdapterManager() >- { >- return new AdapterManager(); >- } >- >- /** >- * @since 2.0 >- */ >- public void handleAddAdapter(InternalCDOObject eObject, Adapter adapter) >- { >- if (!FSMUtil.isNew(eObject)) >- { >- subscribe(eObject, adapter); >- } >- >- adapterPolicyManager.attachAdapter(eObject, adapter); >- } >- >- /** >- * @since 2.0 >- */ >- public void handleRemoveAdapter(InternalCDOObject eObject, Adapter adapter) >- { >- if (!FSMUtil.isNew(eObject)) >- { >- unsubscribe(eObject, adapter); >- } >- >- adapterPolicyManager.detachAdapter(eObject, adapter); >- } >- >- /** >- * @since 2.0 >- */ >- public void subscribe(EObject eObject, Adapter adapter) >- { >- changeSubscriptionManager.subscribe(eObject, adapter); >- } >- >- /** >- * @since 2.0 >- */ >- public void unsubscribe(EObject eObject, Adapter adapter) >- { >- changeSubscriptionManager.unsubscribe(eObject, adapter); >- } >- >- /** >- * @since 2.0 >- */ >- public boolean hasSubscription(CDOID id) >- { >- return changeSubscriptionManager.getSubcribeObject(id) != null; >- } >- >- /** >- * @since 2.0 >- */ >- protected ChangeSubscriptionManager getChangeSubscriptionManager() >- { >- return changeSubscriptionManager; >- } >- >- /** >- * Needed for {@link CDOAuditImpl#setTimeStamp(long)}. >- * >- * @since 2.0 >- */ >- protected List<InternalCDOObject> getInvalidObjects(long timeStamp) >- { >- List<InternalCDOObject> result = new ArrayList<InternalCDOObject>(); >- synchronized (objects) >- { >- for (InternalCDOObject object : objects.values()) >- { >- CDORevision revision = object.cdoRevision(); >- if (revision == null) >- { >- revision = getRevision(object.cdoID(), false); >- } >- >- if (revision == null || !revision.isValid(timeStamp)) >- { >- result.add(object); >- } >- } >- } >- >- return result; >- } >- >- public int reload(CDOObject... objects) >- { >- Collection<InternalCDOObject> internalObjects; >- // TODO Should objects.length == 0 reload *all* objects, too? >- if (objects != null && objects.length != 0) >- { >- internalObjects = new ArrayList<InternalCDOObject>(objects.length); >- for (CDOObject object : objects) >- { >- if (object instanceof InternalCDOObject) >- { >- internalObjects.add((InternalCDOObject)object); >- } >- } >- } >- else >- { >- synchronized (this.objects) >- { >- internalObjects = new ArrayList<InternalCDOObject>(this.objects.values()); >- } >- } >- >- int result = internalObjects.size(); >- if (result != 0) >- { >- CDOStateMachine.INSTANCE.reload(internalObjects.toArray(new InternalCDOObject[result])); >- } >- >- return result; >- } >- >- public void close() >- { >- LifecycleUtil.deactivate(this, OMLogger.Level.DEBUG); >- } >- >- /** >- * @since 2.0 >- */ >- public boolean isClosed() >- { >- return !isActive(); >- } >- >- @Override >- public String toString() >- { >- return MessageFormat.format("CDOView({0})", viewID); //$NON-NLS-1$ >- } >- >- public boolean isAdapterForType(Object type) >- { >- return type instanceof ResourceSet; >- } >- >- public org.eclipse.emf.common.notify.Notifier getTarget() >- { >- return getResourceSet(); >- } >- >- public void getCDOIDAndVersion(Map<CDOID, CDOIDAndVersion> uniqueObjects, Collection<? extends CDOObject> cdoObjects) >- { >- for (CDOObject internalCDOObject : cdoObjects) >- { >- CDORevision cdoRevision = CDOStateMachine.INSTANCE.readNoLoad((InternalCDOObject)internalCDOObject); >- CDOID cdoId = internalCDOObject.cdoID(); >- if (cdoRevision != null && !uniqueObjects.containsKey(cdoId)) >- { >- int version = cdoRevision.getVersion(); >- uniqueObjects.put(cdoId, CDOIDUtil.createIDAndVersion(cdoId, version)); >- } >- } >- } >- >- /** >- * @since 2.0 >- */ >- protected OptionsImpl createOptions() >- { >- return new OptionsImpl(); >- } >- >- /** >- * @since 2.0 >- */ >- @Override >- protected void doBeforeActivate() throws Exception >- { >- super.doBeforeActivate(); >- checkState(session, "session"); //$NON-NLS-1$ >- checkState(viewID > 0, "viewID"); //$NON-NLS-1$ >- } >- >- /** >- * @since 2.0 >- */ >- @Override >- protected void doActivate() throws Exception >- { >- session.getSessionProtocol().openView(getViewID(), getViewType(), getTimeStamp()); >- } >- >- /** >- * @since 2.0 >- */ >- @Override >- protected void doDeactivate() throws Exception >- { >- try >- { >- session.getSessionProtocol().closeView(getViewID()); >- } >- catch (Exception ex) >- { >- OM.LOG.error(ex); >- } >- >- try >- { >- session.viewDetached(this); >- } >- catch (Exception ex) >- { >- OM.LOG.error(ex); >- } >- >- session = null; >- objects = null; >- store = null; >- viewSet = null; >- changeSubscriptionManager = null; >- featureAnalyzer = null; >- lastLookupID = null; >- lastLookupObject = null; >- options = null; >- } >- >- /** >- * @author Eike Stepper >- */ >- protected abstract class Event extends org.eclipse.net4j.util.event.Event implements CDOViewEvent >- { >- private static final long serialVersionUID = 1L; >- >- public Event() >- { >- super(CDOViewImpl.this); >- } >- >- @Override >- public CDOViewImpl getSource() >- { >- return (CDOViewImpl)super.getSource(); >- } >- } >- >- /** >- * @author Simon McDuff >- * @since 2.0 >- */ >- protected class AdapterManager >- { >- private Set<CDOObject> objects = new HashBag<CDOObject>(); >- >- public void committedTransaction(CDOTransaction transaction, CDOCommitContext commitContext) >- { >- if (options().getStrongReferencePolicy() != CDOAdapterPolicy.NONE) >- { >- for (CDOObject object : commitContext.getNewObjects().values()) >- { >- attachObject(object); >- } >- >- for (CDOObject object : commitContext.getNewResources().values()) >- { >- attachObject(object); >- } >- >- for (CDOObject object : commitContext.getDetachedObjects().values()) >- { >- detachObject(object); >- } >- } >- } >- >- protected synchronized void attachObject(CDOObject object) >- { >- if (((InternalEObject)object).eNotificationRequired()) >- { >- CDOAdapterPolicy strongReferencePolicy = options().getStrongReferencePolicy(); >- int count = 0; >- for (Adapter adapter : object.eAdapters()) >- { >- if (strongReferencePolicy.isValid(object, adapter)) >- { >- count++; >- } >- } >- >- for (int i = 0; i < count; i++) >- { >- objects.add(object); >- } >- } >- } >- >- protected synchronized void detachObject(CDOObject object) >- { >- while (objects.remove(object)) >- { >- // Do nothing >- } >- } >- >- protected synchronized void attachAdapter(CDOObject object, Adapter adapter) >- { >- if (options().getStrongReferencePolicy().isValid(object, adapter)) >- { >- objects.add(object); >- } >- } >- >- protected synchronized void detachAdapter(CDOObject object, Adapter adapter) >- { >- if (options().getStrongReferencePolicy().isValid(object, adapter)) >- { >- objects.add(object); >- } >- } >- >- public synchronized void reset() >- { >- // Keep the object in memory >- Set<CDOObject> oldObject = objects; >- objects = new HashBag<CDOObject>(); >- if (options().getStrongReferencePolicy() != CDOAdapterPolicy.NONE) >- { >- InternalCDOObject objects[] = getObjectsArray(); >- for (int i = 0; i < objects.length; i++) >- { >- InternalCDOObject object = objects[i]; >- attachObject(object); >- } >- } >- >- oldObject.clear(); >- } >- }; >- >- /** >- * @author Simon McDuff >- * @since 2.0 >- */ >- protected static class ChangeSubscriptionManager >- { >- private CDOViewImpl view; >- >- private Map<CDOID, SubscribeEntry> subscriptions = new HashMap<CDOID, SubscribeEntry>(); >- >- public ChangeSubscriptionManager(CDOViewImpl view) >- { >- this.view = view; >- } >- >- public void committedTransaction(CDOTransaction transaction, CDOCommitContext commitContext) >- { >- handleNewObjects(commitContext.getNewResources().values()); >- handleNewObjects(commitContext.getNewObjects().values()); >- handleDetachedObjects(commitContext.getDetachedObjects().keySet()); >- } >- >- public void subscribe(EObject eObject, Adapter adapter) >- { >- subscribe(eObject, adapter, 1); >- } >- >- public void unsubscribe(EObject eObject, Adapter adapter) >- { >- subscribe(eObject, adapter, -1); >- } >- >- /** >- * Register to the server all objects from the active list >- */ >- protected void notifyChangeSubcriptionPolicy() >- { >- boolean policiesPresent = view.options().hasChangeSubscriptionPolicies(); >- synchronized (subscriptions) >- { >- subscriptions.clear(); >- List<CDOID> cdoIDs = new ArrayList<CDOID>(); >- if (policiesPresent) >- { >- for (InternalCDOObject cdoObject : view.getObjectsArray()) >- { >- int count = getNumberOfValidAdapter(cdoObject); >- if (count > 0) >- { >- cdoIDs.add(cdoObject.cdoID()); >- addEntry(cdoObject.cdoID(), cdoObject, count); >- } >- } >- } >- >- request(cdoIDs, true, true); >- } >- } >- >- protected void handleDetachedObjects(Collection<CDOID> detachedObjects) >- { >- synchronized (subscriptions) >- { >- for (CDOID id : detachedObjects) >- { >- SubscribeEntry entry = subscriptions.get(id); >- if (entry != null) >- { >- detachObject(id); >- } >- } >- } >- } >- >- protected void handleNewObjects(Collection<? extends CDOObject> newObjects) >- { >- synchronized (subscriptions) >- { >- for (CDOObject object : newObjects) >- { >- InternalCDOObject cdoDetachedObject = (InternalCDOObject)object; >- if (cdoDetachedObject != null) >- { >- int count = getNumberOfValidAdapter(cdoDetachedObject); >- if (count > 0) >- { >- subscribe(cdoDetachedObject.cdoID(), cdoDetachedObject, count); >- } >- } >- } >- } >- } >- >- protected InternalCDOObject getSubcribeObject(CDOID id) >- { >- synchronized (subscriptions) >- { >- SubscribeEntry entry = subscriptions.get(id); >- if (entry != null) >- { >- return entry.getObject(); >- } >- } >- >- return null; >- } >- >- protected void request(List<CDOID> ids, boolean clear, boolean subscribeMode) >- { >- view.session.getSessionProtocol().changeSubscription(view.getViewID(), ids, subscribeMode, clear); >- } >- >- protected int getNumberOfValidAdapter(InternalCDOObject object) >- { >- int count = 0; >- if (!FSMUtil.isTransient(object) && !FSMUtil.isNew(object)) >- { >- if (object.eNotificationRequired()) >- { >- for (Adapter adapter : object.eAdapters()) >- { >- if (shouldSubscribe(object, adapter)) >- { >- count++; >- } >- } >- } >- } >- >- return count; >- } >- >- private void subscribe(EObject eObject, Adapter adapter, int adjust) >- { >- synchronized (subscriptions) >- { >- if (shouldSubscribe(eObject, adapter)) >- { >- InternalCDOObject internalCDOObject = FSMUtil.adapt(eObject, view); >- if (internalCDOObject.cdoView() != view) >- { >- throw new CDOException(MessageFormat.format(Messages.getString("CDOViewImpl.27"), internalCDOObject)); //$NON-NLS-1$ >- } >- >- subscribe(internalCDOObject.cdoID(), internalCDOObject, adjust); >- } >- } >- } >- >- private boolean shouldSubscribe(EObject eObject, Adapter adapter) >- { >- for (CDOAdapterPolicy policy : view.options().getChangeSubscriptionPolicies()) >- { >- if (policy.isValid(eObject, adapter)) >- { >- return true; >- } >- } >- >- return false; >- } >- >- private void subscribe(CDOID id, InternalCDOObject cdoObject, int adjust) >- { >- boolean policiesPresent = view.options().hasChangeSubscriptionPolicies(); >- synchronized (subscriptions) >- { >- int count = 0; >- SubscribeEntry entry = subscriptions.get(id); >- if (entry == null) >- { >- // Cannot adjust negative value >- if (adjust < 0) >- { >- return; >- } >- >- // Notification need to be enable to send correct value to the server >- if (policiesPresent) >- { >- request(Collections.singletonList(id), false, true); >- } >- } >- else >- { >- count = entry.getCount(); >- } >- >- count += adjust; >- >- // Look if objects need to be unsubscribe >- if (count <= 0) >- { >- subscriptions.remove(id); >- >- // Notification need to be enable to send correct value to the server >- if (policiesPresent) >- { >- request(Collections.singletonList(id), false, false); >- } >- } >- else >- { >- if (entry == null) >- { >- addEntry(id, cdoObject, count); >- } >- else >- { >- entry.setCount(count); >- } >- } >- } >- } >- >- private void detachObject(CDOID id) >- { >- subscribe(id, null, Integer.MIN_VALUE); >- } >- >- private void addEntry(CDOID key, InternalCDOObject object, int count) >- { >- subscriptions.put(key, new SubscribeEntry(object, count)); >- } >- >- /** >- * @author Eike Stepper >- */ >- protected static final class SubscribeEntry >- { >- private int count; >- >- private InternalCDOObject object; >- >- public SubscribeEntry(InternalCDOObject object, int count) >- { >- this.count = count; >- this.object = object; >- } >- >- public InternalCDOObject getObject() >- { >- return object; >- } >- >- public int getCount() >- { >- return count; >- } >- >- public void setCount(int count) >- { >- this.count = count; >- } >- } >- } >- >- /** >- * @author Simon McDuff >- */ >- private final class InvalidationEvent extends Event implements CDOViewInvalidationEvent >- { >- private static final long serialVersionUID = 1L; >- >- private long timeStamp; >- >- private Set<? extends CDOObject> dirtyObjects; >- >- private Set<? extends CDOObject> detachedObjects; >- >- public InvalidationEvent(long timeStamp, Set<? extends CDOObject> dirtyOIDs, >- Set<? extends CDOObject> detachedObjects) >- { >- this.timeStamp = timeStamp; >- dirtyObjects = dirtyOIDs; >- this.detachedObjects = detachedObjects; >- } >- >- public long getTimeStamp() >- { >- return timeStamp; >- } >- >- public Set<? extends CDOObject> getDirtyObjects() >- { >- return dirtyObjects; >- } >- >- public Set<? extends CDOObject> getDetachedObjects() >- { >- return detachedObjects; >- } >- >- @Override >- public String toString() >- { >- return "CDOViewInvalidationEvent: " + dirtyObjects; //$NON-NLS-1$ >- } >- } >- >- /** >- * @author Eike Stepper >- */ >- private final class AdaptersNotifiedEvent extends Event implements CDOViewAdaptersNotifiedEvent >- { >- private static final long serialVersionUID = 1L; >- >- private long timeStamp; >- >- public AdaptersNotifiedEvent(long timeStamp) >- { >- this.timeStamp = timeStamp; >- } >- >- public long getTimeStamp() >- { >- return timeStamp; >- } >- >- @Override >- public String toString() >- { >- return "CDOViewAdaptersNotifiedEvent: " + timeStamp; //$NON-NLS-1$ >- } >- } >- >- /** >- * @author Eike Stepper >- * @since 2.0 >- */ >- protected class OptionsImpl extends Notifier implements Options >- { >- private boolean invalidationNotificationEnabled; >- >- private CDORevisionPrefetchingPolicy revisionPrefetchingPolicy; >- >- private CDOStaleReferencePolicy staleReferencePolicy = CDOStaleReferencePolicy.EXCEPTION; >- >- private HashBag<CDOAdapterPolicy> changeSubscriptionPolicies = new HashBag<CDOAdapterPolicy>(); >- >- private CDOAdapterPolicy strongReferencePolicy = CDOAdapterPolicy.ALL; >- >- public OptionsImpl() >- { >- setCacheReferenceType(null); >- invalidationNotificationEnabled = OM.PREF_ENABLE_INVALIDATION_NOTIFICATION.getValue(); >- revisionPrefetchingPolicy = CDOUtil.createRevisionPrefetchingPolicy(OM.PREF_REVISION_LOADING_CHUNK_SIZE >- .getValue()); >- } >- >- public CDOViewImpl getContainer() >- { >- return CDOViewImpl.this; >- } >- >- public boolean isInvalidationNotificationEnabled() >- { >- return invalidationNotificationEnabled; >- } >- >- public void setInvalidationNotificationEnabled(boolean enabled) >- { >- if (invalidationNotificationEnabled != enabled) >- { >- invalidationNotificationEnabled = enabled; >- IListener[] listeners = getListeners(); >- if (listeners != null) >- { >- fireEvent(new InvalidationNotificationEventImpl(), listeners); >- } >- } >- } >- >- public boolean hasChangeSubscriptionPolicies() >- { >- synchronized (changeSubscriptionPolicies) >- { >- return !changeSubscriptionPolicies.isEmpty(); >- } >- } >- >- public CDOAdapterPolicy[] getChangeSubscriptionPolicies() >- { >- synchronized (changeSubscriptionPolicies) >- { >- return changeSubscriptionPolicies.toArray(new CDOAdapterPolicy[changeSubscriptionPolicies.size()]); >- } >- } >- >- public void addChangeSubscriptionPolicy(CDOAdapterPolicy policy) >- { >- boolean changed = false; >- synchronized (changeSubscriptionPolicies) >- { >- if (changeSubscriptionPolicies.add(policy)) >- { >- changeSubscriptionManager.notifyChangeSubcriptionPolicy(); >- changed = true; >- } >- } >- >- if (changed) >- { >- IListener[] listeners = getListeners(); >- if (listeners != null) >- { >- fireEvent(new ChangeSubscriptionPoliciesEventImpl(), listeners); >- } >- } >- } >- >- public void removeChangeSubscriptionPolicy(CDOAdapterPolicy policy) >- { >- boolean changed = false; >- synchronized (changeSubscriptionPolicies) >- { >- if (changeSubscriptionPolicies.remove(policy) && !changeSubscriptionPolicies.contains(policy)) >- { >- changeSubscriptionManager.notifyChangeSubcriptionPolicy(); >- changed = true; >- } >- } >- >- if (changed) >- { >- IListener[] listeners = getListeners(); >- if (listeners != null) >- { >- fireEvent(new ChangeSubscriptionPoliciesEventImpl(), listeners); >- } >- } >- } >- >- public CDOAdapterPolicy getStrongReferencePolicy() >- { >- return strongReferencePolicy; >- } >- >- public void setStrongReferencePolicy(CDOAdapterPolicy adapterPolicy) >- { >- if (adapterPolicy == null) >- { >- adapterPolicy = CDOAdapterPolicy.ALL; >- } >- >- if (strongReferencePolicy != adapterPolicy) >- { >- strongReferencePolicy = adapterPolicy; >- adapterPolicyManager.reset(); >- IListener[] listeners = getListeners(); >- if (listeners != null) >- { >- fireEvent(new ReferencePolicyEventImpl(), listeners); >- } >- } >- } >- >- public CDORevisionPrefetchingPolicy getRevisionPrefetchingPolicy() >- { >- return revisionPrefetchingPolicy; >- } >- >- public void setRevisionPrefetchingPolicy(CDORevisionPrefetchingPolicy prefetchingPolicy) >- { >- if (prefetchingPolicy == null) >- { >- prefetchingPolicy = CDORevisionPrefetchingPolicy.NO_PREFETCHING; >- } >- >- if (revisionPrefetchingPolicy != prefetchingPolicy) >- { >- revisionPrefetchingPolicy = prefetchingPolicy; >- IListener[] listeners = getListeners(); >- if (listeners != null) >- { >- fireEvent(new RevisionPrefetchingPolicyEventImpl(), listeners); >- } >- } >- } >- >- public CDOStaleReferencePolicy getStaleReferenceBehaviour() >- { >- return staleReferencePolicy; >- } >- >- public void setStaleReferenceBehaviour(CDOStaleReferencePolicy policy) >- { >- if (policy == null) >- { >- policy = CDOStaleReferencePolicy.EXCEPTION; >- } >- >- if (staleReferencePolicy != policy) >- { >- staleReferencePolicy = policy; >- IListener[] listeners = getListeners(); >- if (listeners != null) >- { >- fireEvent(new StaleReferencePolicyEventImpl(), listeners); >- } >- } >- } >- >- public ReferenceType getCacheReferenceType() >- { >- if (objects instanceof ReferenceValueMap.Strong<?, ?>) >- { >- return ReferenceType.STRONG; >- } >- >- if (objects instanceof ReferenceValueMap.Soft<?, ?>) >- { >- return ReferenceType.SOFT; >- } >- >- if (objects instanceof ReferenceValueMap.Weak<?, ?>) >- { >- return ReferenceType.WEAK; >- } >- >- throw new IllegalStateException(Messages.getString("CDOViewImpl.29")); //$NON-NLS-1$ >- } >- >- public boolean setCacheReferenceType(ReferenceType referenceType) >- { >- if (referenceType == null) >- { >- referenceType = ReferenceType.SOFT; >- } >- >- ReferenceValueMap<CDOID, InternalCDOObject> newObjects; >- switch (referenceType) >- { >- case STRONG: >- if (objects instanceof ReferenceValueMap.Strong<?, ?>) >- { >- return false; >- } >- >- newObjects = new ReferenceValueMap.Strong<CDOID, InternalCDOObject>(); >- break; >- >- case SOFT: >- if (objects instanceof ReferenceValueMap.Soft<?, ?>) >- { >- return false; >- } >- >- newObjects = new ReferenceValueMap.Soft<CDOID, InternalCDOObject>(); >- break; >- >- case WEAK: >- if (objects instanceof ReferenceValueMap.Weak<?, ?>) >- { >- return false; >- } >- >- newObjects = new ReferenceValueMap.Weak<CDOID, InternalCDOObject>(); >- break; >- >- default: >- throw new IllegalArgumentException(Messages.getString("CDOViewImpl.29")); //$NON-NLS-1$ >- } >- >- if (objects == null) >- { >- objects = newObjects; >- IListener[] listeners = getListeners(); >- if (listeners != null) >- { >- fireEvent(new CacheReferenceTypeEventImpl(), listeners); >- } >- >- return true; >- } >- >- for (Entry<CDOID, InternalCDOObject> entry : objects.entrySet()) >- { >- InternalCDOObject object = entry.getValue(); >- if (object != null) >- { >- newObjects.put(entry.getKey(), object); >- } >- } >- >- ConcurrentMap<CDOID, InternalCDOObject> oldObjects = objects; >- synchronized (objects) >- { >- objects = newObjects; >- } >- >- oldObjects.clear(); >- IListener[] listeners = getListeners(); >- if (listeners != null) >- { >- fireEvent(new CacheReferenceTypeEventImpl(), listeners); >- } >- >- return true; >- } >- >- /** >- * @author Eike Stepper >- */ >- private final class CacheReferenceTypeEventImpl extends OptionsEvent implements CacheReferenceTypeEvent >- { >- private static final long serialVersionUID = 1L; >- >- public CacheReferenceTypeEventImpl() >- { >- super(OptionsImpl.this); >- } >- } >- >- /** >- * @author Eike Stepper >- */ >- private final class ChangeSubscriptionPoliciesEventImpl extends OptionsEvent implements >- ChangeSubscriptionPoliciesEvent >- { >- private static final long serialVersionUID = 1L; >- >- public ChangeSubscriptionPoliciesEventImpl() >- { >- super(OptionsImpl.this); >- } >- } >- >- /** >- * @author Eike Stepper >- */ >- private final class InvalidationNotificationEventImpl extends OptionsEvent implements InvalidationNotificationEvent >- { >- private static final long serialVersionUID = 1L; >- >- public InvalidationNotificationEventImpl() >- { >- super(OptionsImpl.this); >- } >- } >- >- /** >- * @author Eike Stepper >- */ >- private final class RevisionPrefetchingPolicyEventImpl extends OptionsEvent implements >- RevisionPrefetchingPolicyEvent >- { >- private static final long serialVersionUID = 1L; >- >- public RevisionPrefetchingPolicyEventImpl() >- { >- super(OptionsImpl.this); >- } >- } >- >- /** >- * @author Eike Stepper >- */ >- private final class ReferencePolicyEventImpl extends OptionsEvent implements ReferencePolicyEvent >- { >- private static final long serialVersionUID = 1L; >- >- public ReferencePolicyEventImpl() >- { >- super(OptionsImpl.this); >- } >- } >- >- /** >- * @author Simon McDuff >- */ >- private final class StaleReferencePolicyEventImpl extends OptionsEvent implements StaleReferencePolicyEvent >- { >- private static final long serialVersionUID = 1L; >- >- public StaleReferencePolicyEventImpl() >- { >- super(OptionsImpl.this); >- } >- } >- } >+public class CDOViewImpl extends Lifecycle implements InternalCDOView { >+ private static final ContextTracer TRACER = new ContextTracer( >+ OM.DEBUG_VIEW, CDOViewImpl.class); >+ >+ private int viewID; >+ >+ private InternalCDOSession session; >+ >+ private InternalCDOViewSet viewSet; >+ >+ private CDOURIHandler uriHandler = new CDOURIHandler(this); >+ >+ private CDOFeatureAnalyzer featureAnalyzer = CDOFeatureAnalyzer.NOOP; >+ >+ private ConcurrentMap<CDOID, InternalCDOObject> objects; >+ >+ private CDOStore store = new CDOStore(this); >+ >+ private ReentrantLock lock = new ReentrantLock(true); >+ >+ private ReentrantLock stateLock = new ReentrantLock(true); >+ >+ private CDOResourceImpl rootResource; >+ >+ private ChangeSubscriptionManager changeSubscriptionManager = createChangeSubscriptionManager(); >+ >+ private AdapterManager adapterPolicyManager = createAdapterManager(); >+ >+ private FastList<CDOObjectHandler> objectHandlers = new FastList<CDOObjectHandler>() { >+ @Override >+ protected CDOObjectHandler[] newArray(int length) { >+ return new CDOObjectHandler[length]; >+ } >+ }; >+ >+ private OptionsImpl options; >+ >+ @ExcludeFromDump >+ private transient CDOID lastLookupID; >+ >+ @ExcludeFromDump >+ private transient InternalCDOObject lastLookupObject; >+ >+ /** >+ * @since 2.0 >+ */ >+ public CDOViewImpl() { >+ options = createOptions(); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public OptionsImpl options() { >+ return options; >+ } >+ >+ public int getViewID() { >+ return viewID; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public void setViewID(int viewId) { >+ viewID = viewId; >+ } >+ >+ public Type getViewType() { >+ return Type.READONLY; >+ } >+ >+ public ResourceSet getResourceSet() { >+ return viewSet.getResourceSet(); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public InternalCDOViewSet getViewSet() { >+ return viewSet; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public void setViewSet(InternalCDOViewSet viewSet) { >+ this.viewSet = viewSet; >+ if (viewSet != null) { >+ viewSet.getResourceSet().getURIConverter().getURIHandlers().add(0, >+ getURIHandler()); >+ } >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public InternalCDOSession getSession() { >+ return session; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public void setSession(InternalCDOSession session) { >+ this.session = session; >+ } >+ >+ public CDOStore getStore() { >+ checkActive(); >+ return store; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public synchronized CDOResourceImpl getRootResource() { >+ checkActive(); >+ if (rootResource == null) { >+ rootResource = createRootResource(); >+ } >+ >+ return rootResource; >+ } >+ >+ /** >+ * @return >+ * @since 2.0 >+ */ >+ protected CDOResourceImpl createRootResource() { >+ return (CDOResourceImpl) getResource(CDOResourceNode.ROOT_PATH); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public CDOURIHandler getURIHandler() { >+ return uriHandler; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public ReentrantLock getLock() { >+ return lock; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public ReentrantLock getStateLock() { >+ return stateLock; >+ } >+ >+ /** >+ * @throws InterruptedException >+ * @since 2.0 >+ */ >+ public void lockObjects(Collection<? extends CDOObject> objects, >+ LockType lockType, long timeout) throws InterruptedException { >+ checkActive(); >+ Map<CDOID, CDOIDAndVersion> uniqueObjects = new HashMap<CDOID, CDOIDAndVersion>(); >+ getCDOIDAndVersion(uniqueObjects, objects); >+ for (CDOObject object : objects) { >+ CDOIDAndVersion idAndVersion = uniqueObjects.get(object.cdoID()); >+ if (idAndVersion == null) { >+ uniqueObjects.put(object.cdoID(), CDOIDUtil.createIDAndVersion( >+ object.cdoID(), CDORevision.UNSPECIFIED_VERSION)); >+ } >+ } >+ >+ session.getSessionProtocol().lockObjects(this, uniqueObjects, timeout, >+ lockType); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public void unlockObjects(Collection<? extends CDOObject> objects, >+ LockType lockType) { >+ checkActive(); >+ session.getSessionProtocol().unlockObjects(this, objects, lockType); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public void unlockObjects() { >+ unlockObjects(null, null); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public boolean isObjectLocked(CDOObject object, LockType lockType, >+ boolean byOthers) { >+ checkActive(); >+ return session.getSessionProtocol().isObjectLocked(this, object, >+ lockType, byOthers); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public long getTimeStamp() { >+ return UNSPECIFIED_DATE; >+ } >+ >+ public boolean isDirty() { >+ return false; >+ } >+ >+ public boolean hasConflict() { >+ return false; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public CDOFeatureAnalyzer getFeatureAnalyzer() { >+ return featureAnalyzer; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public void setFeatureAnalyzer(CDOFeatureAnalyzer featureAnalyzer) { >+ this.featureAnalyzer = featureAnalyzer == null ? CDOFeatureAnalyzer.NOOP >+ : featureAnalyzer; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public InternalCDOTransaction toTransaction() { >+ checkActive(); >+ if (this instanceof InternalCDOTransaction) { >+ return (InternalCDOTransaction) this; >+ } >+ >+ throw new ReadOnlyException(MessageFormat.format(Messages >+ .getString("CDOViewImpl.0"), this)); //$NON-NLS-1$ >+ } >+ >+ public boolean hasResource(String path) { >+ checkActive(); >+ >+ try { >+ getResourceNodeID(path); >+ return true; >+ } catch (Exception ex) { >+ return false; >+ } >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public CDOQuery createQuery(String language, String queryString) { >+ checkActive(); >+ return new CDOQueryImpl(this, language, queryString); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public CDOResourceNode getResourceNode(String path) { >+ CDOID id = getResourceNodeID(path); >+ if (id == null) { >+ return null; >+ } >+ >+ InternalCDOObject object = getObject(id); >+ if (object instanceof CDOResourceNode) { >+ return (CDOResourceNode) object; >+ } >+ >+ return null; >+ } >+ >+ /** >+ * @return never <code>null</code> >+ * @since 2.0 >+ */ >+ public CDOID getResourceNodeID(String path) { >+ if (StringUtil.isEmpty(path)) { >+ throw new IllegalArgumentException(Messages >+ .getString("CDOViewImpl.1")); //$NON-NLS-1$ >+ } >+ >+ CDOID folderID = null; >+ if (CDOURIUtil.SEGMENT_SEPARATOR.equals(path)) { >+ folderID = getResourceNodeIDChecked(null, null); >+ } else { >+ List<String> names = CDOURIUtil.analyzePath(path); >+ for (String name : names) { >+ folderID = getResourceNodeIDChecked(folderID, name); >+ } >+ } >+ >+ return folderID; >+ } >+ >+ /** >+ * @return never <code>null</code> >+ */ >+ private CDOID getResourceNodeIDChecked(CDOID folderID, String name) { >+ folderID = getResourceNodeID(folderID, name); >+ if (folderID == null) { >+ throw new CDOException(MessageFormat.format(Messages >+ .getString("CDOViewImpl.2"), name)); //$NON-NLS-1$ >+ } >+ >+ return folderID; >+ } >+ >+ /** >+ * @return never <code>null</code> >+ * @since 2.0 >+ */ >+ protected CDOResourceNode getResourceNode(CDOID folderID, String name) { >+ try { >+ CDOID id = getResourceNodeID(folderID, name); >+ return (CDOResourceNode) getObject(id); >+ } catch (CDOException ex) { >+ throw ex; >+ } catch (Exception ex) { >+ throw new CDOException(ex); >+ } >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ protected CDOID getResourceNodeID(CDOID folderID, String name) { >+ if (folderID == null) { >+ return getRootOrTopLevelResourceNodeID(name); >+ } >+ >+ if (name == null) { >+ throw new IllegalArgumentException(Messages >+ .getString("CDOViewImpl.3")); //$NON-NLS-1$ >+ } >+ >+ InternalCDORevision folderRevision = getLocalRevision(folderID); >+ EClass resourceFolderClass = EresourcePackage.eINSTANCE >+ .getCDOResourceFolder(); >+ if (folderRevision.getEClass() != resourceFolderClass) { >+ throw new CDOException(MessageFormat.format(Messages >+ .getString("CDOViewImpl.4"), folderID)); //$NON-NLS-1$ >+ } >+ >+ EReference nodesFeature = EresourcePackage.eINSTANCE >+ .getCDOResourceFolder_Nodes(); >+ EAttribute nameFeature = EresourcePackage.eINSTANCE >+ .getCDOResourceNode_Name(); >+ >+ int size = folderRevision.data().size(nodesFeature); >+ for (int i = 0; i < size; i++) { >+ Object value = folderRevision.data().get(nodesFeature, i); >+ value = getStore().resolveProxy(folderRevision, nodesFeature, i, >+ value); >+ >+ CDORevision childRevision = getLocalRevision((CDOID) convertObjectToID(value)); >+ if (name.equals(childRevision.data().get(nameFeature, 0))) { >+ return childRevision.getID(); >+ } >+ } >+ >+ throw new CDOException(MessageFormat.format(Messages >+ .getString("CDOViewImpl.5"), name)); //$NON-NLS-1$ >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ protected CDOID getRootOrTopLevelResourceNodeID(String name) { >+ CDOQuery resourceQuery = createResourcesQuery(null, name, true); >+ resourceQuery.setMaxResults(1); >+ List<CDOID> ids = resourceQuery.getResult(CDOID.class); >+ if (ids.isEmpty()) { >+ if (name == null) { >+ throw new CDOException(Messages.getString("CDOViewImpl.6")); //$NON-NLS-1$ >+ } else { >+ throw new CDOException(MessageFormat.format(Messages >+ .getString("CDOViewImpl.7"), name)); //$NON-NLS-1$ >+ } >+ } >+ >+ if (ids.size() > 1) { >+ // TODO is this still needed since the is >+ // resourceQuery.setMaxResults(1) ?? >+ throw new ImplementationError(Messages.getString("CDOViewImpl.8")); //$NON-NLS-1$ >+ } >+ >+ return ids.get(0); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ protected InternalCDORevision getLocalRevision(CDOID id) { >+ InternalCDORevision revision = null; >+ InternalCDOObject object = getObject(id, false); >+ if (object != null && object.cdoState() != CDOState.PROXY) { >+ revision = object.cdoRevision(); >+ } >+ >+ if (revision == null) { >+ revision = getRevision(id, true); >+ } >+ >+ if (revision == null) { >+ throw new CDOException(MessageFormat.format(Messages >+ .getString("CDOViewImpl.9"), id)); //$NON-NLS-1$ >+ } >+ >+ return revision; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public InternalCDOObject[] getObjectsArray() { >+ synchronized (objects) { >+ return objects.values().toArray( >+ new InternalCDOObject[objects.size()]); >+ } >+ } >+ >+ /** >+ * TODO Remove me >+ * >+ * @since 2.0 >+ */ >+ @Deprecated >+ public CDOResourceFolder getResourceFolder(String path) { >+ if (path == null) { >+ return null; >+ } >+ >+ CDOResourceFolder folder = null; >+ StringTokenizer tokenizer = new StringTokenizer(path, >+ CDOURIUtil.SEGMENT_SEPARATOR); >+ while (tokenizer.hasMoreTokens()) { >+ String segment = tokenizer.nextToken(); >+ if (segment != null) { >+ if (folder == null) { >+ } else { >+ } >+ } >+ } >+ >+ return folder; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public CDOResource getResource(String path) { >+ return getResource(path, true); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public CDOResource getResource(String path, boolean loadInDemand) { >+ checkActive(); >+ URI uri = CDOURIUtil.createResourceURI(this, path); >+ return (CDOResource) getResourceSet().getResource(uri, loadInDemand); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public List<CDOResourceNode> queryResources(CDOResourceFolder folder, >+ String name, boolean exactMatch) { >+ checkActive(); >+ CDOQuery resourceQuery = createResourcesQuery(folder, name, exactMatch); >+ return resourceQuery.getResult(CDOResourceNode.class); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public CloseableIterator<CDOResourceNode> queryResourcesAsync( >+ CDOResourceFolder folder, String name, boolean exactMatch) { >+ checkActive(); >+ CDOQuery resourceQuery = createResourcesQuery(folder, name, exactMatch); >+ return resourceQuery.getResultAsync(CDOResourceNode.class); >+ } >+ >+ private CDOQuery createResourcesQuery(CDOResourceFolder folder, >+ String name, boolean exactMatch) { >+ CDOQuery query = createQuery( >+ CDOProtocolConstants.QUERY_LANGUAGE_RESOURCES, name); >+ query.setParameter( >+ CDOProtocolConstants.QUERY_LANGUAGE_RESOURCES_FOLDER_ID, >+ folder == null ? null : folder.cdoID()); >+ query.setParameter( >+ CDOProtocolConstants.QUERY_LANGUAGE_RESOURCES_EXACT_MATCH, >+ exactMatch); >+ return query; >+ } >+ >+ public CDOResourceImpl getResource(CDOID resourceID) { >+ if (CDOIDUtil.isNull(resourceID)) { >+ throw new IllegalArgumentException("resourceID: " + resourceID); //$NON-NLS-1$ >+ } >+ >+ return (CDOResourceImpl) getObject(resourceID); >+ } >+ >+ public InternalCDOObject newInstance(EClass eClass) { >+ EObject eObject = EcoreUtil.create(eClass); >+ return FSMUtil.adapt(eObject, this); >+ } >+ >+ public InternalCDORevision getRevision(CDOID id, boolean loadOnDemand) { >+ CDORevisionManager revisionManager = session.getRevisionManager(); >+ int initialChunkSize = session.options().getCollectionLoadingPolicy() >+ .getInitialChunkSize(); >+ return (InternalCDORevision) revisionManager.getRevision(id, >+ initialChunkSize, CDORevision.DEPTH_NONE, loadOnDemand); >+ } >+ >+ public void prefetchRevisions(CDOID id, int depth) { >+ checkArg(depth != CDORevision.DEPTH_NONE, >+ "Prefetch depth must not be zero"); >+ int initialChunkSize = session.options().getCollectionLoadingPolicy() >+ .getInitialChunkSize(); >+ prefetchRevisions(id, depth, initialChunkSize); >+ } >+ >+ protected void prefetchRevisions(CDOID id, int depth, int initialChunkSize) { >+ session.getRevisionManager().getRevision(id, initialChunkSize, depth); >+ } >+ >+ public InternalCDOObject getObject(CDOID id) { >+ return getObject(id, true); >+ } >+ >+ /** >+ * Support recursivity and concurrency. >+ */ >+ public InternalCDOObject getObject(CDOID id, boolean loadOnDemand) { >+ checkActive(); >+ if (CDOIDUtil.isNull(id)) { >+ return null; >+ } >+ >+ // Since getObject could trigger a read (ONLY when we load a resource) >+ // we NEED to make sure the state lock is >+ // active. >+ // Always use in the following order >+ // 1- getStateLock().lock(); >+ // 2- synchronized(objects) >+ // DO NOT inverse them otherwise deadlock could occured. >+ >+ ReentrantLock stateLock = getStateLock(); >+ stateLock.lock(); >+ try { >+ synchronized (objects) { >+ if (id.equals(lastLookupID)) { >+ return lastLookupObject; >+ } >+ >+ // Needed for recursive call to getObject. (from >+ // createObject/cleanObject/getResource/getObject) >+ InternalCDOObject localLookupObject = objects.get(id); >+ if (localLookupObject == null) { >+ if (id.isMeta()) { >+ localLookupObject = createMetaObject((CDOIDMeta) id); >+ } else { >+ if (loadOnDemand) { >+ if (id.isTemporary()) { >+ throw new ObjectNotFoundException(id); >+ } >+ >+ localLookupObject = createObject(id); >+ } else { >+ return null; >+ } >+ } >+ >+ // CDOResource have a special way to register to the view. >+ if (!CDOModelUtil.isResource(localLookupObject.eClass())) { >+ registerObject(localLookupObject); >+ } >+ } >+ >+ lastLookupID = id; >+ lastLookupObject = localLookupObject; >+ return lastLookupObject; >+ } >+ } finally { >+ stateLock.unlock(); >+ } >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ @SuppressWarnings("unchecked") >+ public <T extends EObject> T getObject(T objectFromDifferentView) { >+ checkActive(); >+ if (objectFromDifferentView instanceof CDOObject) { >+ CDOObject object = (CDOObject) objectFromDifferentView; >+ CDOView view = object.cdoView(); >+ if (view != this) { >+ if (view.getSession() != session) { >+ throw new IllegalArgumentException( >+ MessageFormat >+ .format( >+ Messages >+ .getString("CDOViewImpl.11"), objectFromDifferentView)); //$NON-NLS-1$ >+ } >+ >+ CDOID id = object.cdoID(); >+ objectFromDifferentView = (T) getObject(id, true); >+ } >+ } >+ >+ return objectFromDifferentView; >+ } >+ >+ public boolean isObjectRegistered(CDOID id) { >+ checkActive(); >+ if (CDOIDUtil.isNull(id)) { >+ return false; >+ } >+ >+ synchronized (objects) { >+ return objects.containsKey(id); >+ } >+ } >+ >+ public InternalCDOObject removeObject(CDOID id) { >+ synchronized (objects) { >+ if (id.equals(lastLookupID)) { >+ lastLookupID = null; >+ lastLookupObject = null; >+ } >+ >+ return objects.remove(id); >+ } >+ } >+ >+ /** >+ * @return Never <code>null</code> >+ */ >+ private InternalCDOObject createMetaObject(CDOIDMeta id) { >+ if (TRACER.isEnabled()) { >+ TRACER.trace("Creating meta object for " + id); //$NON-NLS-1$ >+ } >+ >+ InternalCDOPackageRegistry packageRegistry = session >+ .getPackageRegistry(); >+ InternalEObject metaInstance = packageRegistry.getMetaInstanceMapper() >+ .lookupMetaInstance(id); >+ return new CDOMetaWrapper(this, metaInstance, id); >+ } >+ >+ /** >+ * @return Never <code>null</code> >+ */ >+ private InternalCDOObject createObject(CDOID id) { >+ if (TRACER.isEnabled()) { >+ TRACER.trace("Creating object for " + id); //$NON-NLS-1$ >+ } >+ >+ InternalCDORevision revision = getRevision(id, true); >+ FSMUtil.validate(id, revision); >+ >+ EClass eClass = revision.getEClass(); >+ InternalCDOObject object; >+ if (CDOModelUtil.isResource(eClass)) { >+ object = (InternalCDOObject) newResourceInstance(revision); >+ // object is PROXY >+ } else { >+ object = newInstance(eClass); >+ // object is TRANSIENT >+ } >+ >+ cleanObject(object, revision); >+ return object; >+ } >+ >+ private CDOResource newResourceInstance(InternalCDORevision revision) { >+ String path = getResourcePath(revision); >+ return getResource(path, true); >+ } >+ >+ private String getResourcePath(InternalCDORevision revision) { >+ EAttribute nameFeature = EresourcePackage.eINSTANCE >+ .getCDOResourceNode_Name(); >+ >+ CDOID folderID = (CDOID) revision.data().getContainerID(); >+ String name = (String) revision.data().get(nameFeature, 0); >+ if (CDOIDUtil.isNull(folderID)) { >+ if (name == null) { >+ return CDOURIUtil.SEGMENT_SEPARATOR; >+ } >+ >+ return name; >+ } >+ >+ InternalCDOObject object = getObject(folderID, true); >+ if (object instanceof CDOResourceFolder) { >+ CDOResourceFolder folder = (CDOResourceFolder) object; >+ String path = folder.getPath(); >+ return path + CDOURIUtil.SEGMENT_SEPARATOR + name; >+ } >+ >+ throw new ImplementationError(MessageFormat.format(Messages >+ .getString("CDOViewImpl.14"), object)); //$NON-NLS-1$ >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ protected void cleanObject(InternalCDOObject object, >+ InternalCDORevision revision) { >+ object.cdoInternalCleanup(); >+ >+ object.cdoInternalSetView(this); >+ object.cdoInternalSetRevision(revision); >+ object.cdoInternalSetID(revision.getID()); >+ object.cdoInternalSetState(CDOState.CLEAN); >+ >+ object.cdoInternalPostLoad(); >+ } >+ >+ public CDOID provideCDOID(Object idOrObject) { >+ Object shouldBeCDOID = convertObjectToID(idOrObject); >+ if (shouldBeCDOID instanceof CDOID) { >+ CDOID id = (CDOID) shouldBeCDOID; >+ if (TRACER.isEnabled() && id != idOrObject) { >+ TRACER >+ .format( >+ "Converted object to CDOID: {0} --> {1}", idOrObject, id); //$NON-NLS-1$ >+ } >+ >+ return id; >+ } else if (idOrObject instanceof InternalEObject) { >+ InternalEObject eObject = (InternalEObject) idOrObject; >+ String uri = EcoreUtil.getURI(eObject).toString(); >+ if (eObject instanceof InternalCDOObject) { >+ InternalCDOObject object = (InternalCDOObject) idOrObject; >+ if (object.cdoView() != null && FSMUtil.isNew(object)) { >+ return CDOIDUtil.createTempObjectExternal(uri); >+ } >+ } >+ >+ if (eObject.eResource() != null) { >+ return CDOIDUtil.createExternal(uri); >+ } >+ >+ throw new DanglingReferenceException(eObject); >+ } >+ >+ throw new IllegalStateException(MessageFormat.format(Messages >+ .getString("CDOViewImpl.16"), idOrObject.getClass().getName())); //$NON-NLS-1$ >+ } >+ >+ public Object convertObjectToID(Object potentialObject) { >+ return convertObjectToID(potentialObject, false); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public Object convertObjectToID(Object potentialObject, >+ boolean onlyPersistedID) { >+ if (potentialObject instanceof CDOID) { >+ return potentialObject; >+ } >+ >+ if (potentialObject instanceof InternalEObject) { >+ if (potentialObject instanceof InternalCDOObject) { >+ InternalCDOObject object = (InternalCDOObject) potentialObject; >+ CDOID id = getID(object, onlyPersistedID); >+ if (id != null) { >+ return id; >+ } >+ } else { >+ try { >+ InternalCDOObject object = FSMUtil >+ .getLegacyAdapter(((InternalEObject) potentialObject) >+ .eAdapters()); >+ if (object != null) { >+ CDOID id = getID(object, onlyPersistedID); >+ if (id != null) { >+ return id; >+ } >+ >+ potentialObject = object; >+ } >+ } catch (Throwable ex) { >+ OM.LOG.warn(ex); >+ } >+ } >+ } >+ >+ return potentialObject; >+ } >+ >+ // TTT public CDOIDDangling convertDanglingObjectToID(InternalCDOObject >+ // source, EStructuralFeature feature, >+ // InternalEObject target) >+ // { >+ // throw new >+ // IllegalStateException("Dangling objects not possible outside of a transaction"); >+ // } >+ >+ protected CDOID getID(InternalCDOObject object, boolean onlyPersistedID) { >+ if (onlyPersistedID) { >+ if (FSMUtil.isTransient(object) || FSMUtil.isNew(object)) { >+ return null; >+ } >+ } >+ >+ CDOView view = object.cdoView(); >+ if (view == this) { >+ return object.cdoID(); >+ } >+ >+ if (view != null && view.getSession() == getSession()) { >+ return object.cdoID(); >+ } >+ >+ return null; >+ } >+ >+ public Object convertIDToObject(Object potentialID) { >+ if (potentialID instanceof CDOID) { >+ if (potentialID == CDOID.NULL) { >+ return null; >+ } >+ >+ CDOID id = (CDOID) potentialID; >+ if (id.isExternal()) { >+ return getResourceSet().getEObject( >+ URI.createURI(id.toURIFragment()), true); >+ } >+ >+ InternalCDOObject result = getObject(id, true); >+ if (result == null) { >+ throw new ImplementationError(MessageFormat.format(Messages >+ .getString("CDOViewImpl.17"), id)); //$NON-NLS-1$ >+ } >+ >+ return result.cdoInternalInstance(); >+ } >+ >+ return potentialID; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public void attachResource(CDOResourceImpl resource) { >+ if (!resource.isExisting()) { >+ throw new ReadOnlyException(MessageFormat.format(Messages >+ .getString("CDOViewImpl.18"), this)); //$NON-NLS-1$ >+ } >+ >+ // ResourceSet.getResource(uri, true) was called!! >+ resource.cdoInternalSetView(this); >+ resource.cdoInternalSetState(CDOState.PROXY); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public void registerProxyResource(CDOResourceImpl resource) { >+ URI uri = resource.getURI(); >+ String path = CDOURIUtil.extractResourcePath(uri); >+ >+ try { >+ CDOID id = getResourceNodeID(path); >+ resource.cdoInternalSetID(id); >+ registerObject(resource); >+ } catch (Exception ex) { >+ throw new InvalidURIException(uri, ex); >+ } >+ } >+ >+ public void registerObject(InternalCDOObject object) { >+ if (TRACER.isEnabled()) { >+ TRACER.format("Registering {0}", object); //$NON-NLS-1$ >+ } >+ >+ InternalCDOObject old; >+ synchronized (objects) { >+ old = objects.put(object.cdoID(), object); >+ } >+ >+ if (old != null) { >+ throw new IllegalStateException(MessageFormat.format(Messages >+ .getString("CDOViewImpl.20"), object)); //$NON-NLS-1$ >+ } >+ } >+ >+ public void deregisterObject(InternalCDOObject object) { >+ if (TRACER.isEnabled()) { >+ TRACER.format("Deregistering {0}", object); //$NON-NLS-1$ >+ } >+ >+ removeObject(object.cdoID()); >+ } >+ >+ public void remapObject(CDOID oldID) { >+ CDOID newID; >+ synchronized (objects) { >+ InternalCDOObject object = objects.remove(oldID); >+ newID = object.cdoID(); >+ objects.put(newID, object); >+ } >+ >+ if (TRACER.isEnabled()) { >+ TRACER.format("Remapping {0} --> {1}", oldID, newID); //$NON-NLS-1$ >+ } >+ } >+ >+ public void addObjectHandler(CDOObjectHandler handler) { >+ objectHandlers.add(handler); >+ } >+ >+ public void removeObjectHandler(CDOObjectHandler handler) { >+ objectHandlers.remove(handler); >+ } >+ >+ public CDOObjectHandler[] getObjectHandlers() { >+ return objectHandlers.get(); >+ } >+ >+ public void handleObjectStateChanged(InternalCDOObject object, >+ CDOState oldState, CDOState newState) { >+ CDOObjectHandler[] handlers = getObjectHandlers(); >+ if (handlers != null) { >+ for (int i = 0; i < handlers.length; i++) { >+ CDOObjectHandler handler = handlers[i]; >+ handler.objectStateChanged(this, object, oldState, newState); >+ } >+ } >+ } >+ >+ /** >+ * Turns registered objects into proxies and synchronously delivers >+ * invalidation events to registered event listeners. >+ * <p> >+ * <b>Implementation note:</b> This implementation guarantees that >+ * exceptions from listener code don't propagate up to the caller of this >+ * method. Runtime exceptions from the implementation of the >+ * {@link CDOStateMachine} are propagated to the caller of this method but >+ * this should not happen in the absence of implementation errors. >+ * <p> >+ * Note that this method can block for an uncertain amount of time on the >+ * reentrant view lock! >+ * >+ * @param timeStamp >+ * The time stamp of the server transaction if this event was >+ * sent as a result of a successfully committed transaction or >+ * <code>LOCAL_ROLLBACK</code> if this event was sent due to a >+ * local rollback. >+ * @param dirtyOIDs >+ * A set of the object IDs to be invalidated. <b>Implementation >+ * note:</b> This implementation expects the dirtyOIDs set to be >+ * unmodifiable. It does not wrap the set (again). >+ * @since 2.0 >+ */ >+ public Set<CDOObject> handleInvalidation(long timeStamp, >+ Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedOIDs) { >+ Set<CDOObject> conflicts = null; >+ Set<InternalCDOObject> dirtyObjects = new HashSet<InternalCDOObject>(); >+ Set<InternalCDOObject> detachedObjects = new HashSet<InternalCDOObject>(); >+ lock.lock(); >+ >+ try { >+ conflicts = handleInvalidationWithoutNotification(dirtyOIDs, >+ detachedOIDs, dirtyObjects, detachedObjects); >+ } finally { >+ lock.unlock(); >+ } >+ >+ if (options().isInvalidationNotificationEnabled()) { >+ for (InternalCDOObject dirtyObject : dirtyObjects) { >+ if (dirtyObject.eNotificationRequired()) { >+ CDOInvalidationNotificationImpl notification = new CDOInvalidationNotificationImpl( >+ dirtyObject); >+ dirtyObject.eNotify(notification); >+ } >+ } >+ >+ for (InternalCDOObject detachedObject : detachedObjects) { >+ if (detachedObject.eNotificationRequired()) { >+ CDOInvalidationNotificationImpl notification = new CDOInvalidationNotificationImpl( >+ detachedObject); >+ detachedObject.eNotify(notification); >+ } >+ } >+ } >+ >+ fireInvalidationEvent(timeStamp, Collections >+ .unmodifiableSet(dirtyObjects), Collections >+ .unmodifiableSet(detachedObjects)); >+ return conflicts; >+ } >+ >+ public Set<CDOObject> handleInvalidationWithoutNotification( >+ Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedOIDs, >+ Set<InternalCDOObject> dirtyObjects, >+ Set<InternalCDOObject> detachedObjects) { >+ Set<CDOObject> conflicts = null; >+ for (CDOIDAndVersion dirtyOID : dirtyOIDs) { >+ InternalCDOObject dirtyObject = null; >+ // 258831 - Causes deadlock when introduce thread safe mechanisms in >+ // State machine. >+ synchronized (objects) { >+ dirtyObject = objects.get(dirtyOID.getID()); >+ } >+ >+ if (dirtyObject != null) { >+ CDOStateMachine.INSTANCE.invalidate(dirtyObject, dirtyOID >+ .getVersion()); >+ dirtyObjects.add(dirtyObject); >+ if (dirtyObject.cdoConflict()) { >+ if (conflicts == null) { >+ conflicts = new HashSet<CDOObject>(); >+ } >+ >+ conflicts.add(dirtyObject); >+ } >+ } >+ } >+ >+ for (CDOID id : detachedOIDs) { >+ InternalCDOObject detachedObject = removeObject(id); >+ if (detachedObject != null) { >+ CDOStateMachine.INSTANCE.detachRemote(detachedObject); >+ detachedObjects.add(detachedObject); >+ if (detachedObject.cdoConflict()) { >+ if (conflicts == null) { >+ conflicts = new HashSet<CDOObject>(); >+ } >+ >+ conflicts.add(detachedObject); >+ } >+ } >+ } >+ >+ return conflicts; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ private void fireInvalidationEvent(long timeStamp, >+ Set<? extends CDOObject> dirtyObjects, >+ Set<? extends CDOObject> detachedObjects) { >+ if (!dirtyObjects.isEmpty() || !detachedObjects.isEmpty()) { >+ IListener[] listeners = getListeners(); >+ if (listeners != null) { >+ fireEvent(new InvalidationEvent(timeStamp, dirtyObjects, >+ detachedObjects), listeners); >+ } >+ } >+ } >+ >+ public void fireAdaptersNotifiedEvent(long timeStamp) { >+ fireEvent(new AdaptersNotifiedEvent(timeStamp)); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public void handleChangeSubscription(Collection<CDORevisionDelta> deltas, >+ Collection<CDOID> detachedObjects) { >+ boolean policiesPresent = options().hasChangeSubscriptionPolicies(); >+ if (!policiesPresent) { >+ return; >+ } >+ >+ if (deltas != null) { >+ CDONotificationBuilder builder = new CDONotificationBuilder(); >+ for (CDORevisionDelta delta : deltas) { >+ InternalCDOObject object = changeSubscriptionManager >+ .getSubcribeObject(delta.getID()); >+ if (object != null && object.eNotificationRequired()) { >+ NotificationImpl notification = builder.buildNotification( >+ object, delta); >+ if (notification != null) { >+ notification.dispatch(); >+ } >+ } >+ } >+ } >+ >+ if (detachedObjects != null) { >+ for (CDOID id : detachedObjects) { >+ InternalCDOObject object = changeSubscriptionManager >+ .getSubcribeObject(id); >+ if (object != null && object.eNotificationRequired()) { >+ NotificationImpl notification = new CDODeltaNotificationImpl( >+ object, CDONotification.DETACH_OBJECT, >+ Notification.NO_FEATURE_ID, null, null); >+ notification.dispatch(); >+ } >+ } >+ >+ getChangeSubscriptionManager().handleDetachedObjects( >+ detachedObjects); >+ } >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ protected ChangeSubscriptionManager createChangeSubscriptionManager() { >+ return new ChangeSubscriptionManager(this); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public AdapterManager getAdapterManager() { >+ return adapterPolicyManager; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ protected AdapterManager createAdapterManager() { >+ return new AdapterManager(); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public void handleAddAdapter(InternalCDOObject eObject, Adapter adapter) { >+ if (!FSMUtil.isNew(eObject)) { >+ subscribe(eObject, adapter); >+ } >+ >+ adapterPolicyManager.attachAdapter(eObject, adapter); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public void handleRemoveAdapter(InternalCDOObject eObject, Adapter adapter) { >+ if (!FSMUtil.isNew(eObject)) { >+ unsubscribe(eObject, adapter); >+ } >+ >+ adapterPolicyManager.detachAdapter(eObject, adapter); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public void subscribe(EObject eObject, Adapter adapter) { >+ changeSubscriptionManager.subscribe(eObject, adapter); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public void unsubscribe(EObject eObject, Adapter adapter) { >+ changeSubscriptionManager.unsubscribe(eObject, adapter); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public boolean hasSubscription(CDOID id) { >+ return changeSubscriptionManager.getSubcribeObject(id) != null; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ protected ChangeSubscriptionManager getChangeSubscriptionManager() { >+ return changeSubscriptionManager; >+ } >+ >+ /** >+ * Needed for {@link CDOAuditImpl#setTimeStamp(long)}. >+ * >+ * @since 2.0 >+ */ >+ protected List<InternalCDOObject> getInvalidObjects(long timeStamp) { >+ List<InternalCDOObject> result = new ArrayList<InternalCDOObject>(); >+ synchronized (objects) { >+ for (InternalCDOObject object : objects.values()) { >+ CDORevision revision = object.cdoRevision(); >+ if (revision == null) { >+ revision = getRevision(object.cdoID(), false); >+ } >+ >+ if (revision == null || !revision.isValid(timeStamp)) { >+ result.add(object); >+ } >+ } >+ } >+ >+ return result; >+ } >+ >+ public int reload(CDOObject... objects) { >+ Collection<InternalCDOObject> internalObjects; >+ // TODO Should objects.length == 0 reload *all* objects, too? >+ if (objects != null && objects.length != 0) { >+ internalObjects = new ArrayList<InternalCDOObject>(objects.length); >+ for (CDOObject object : objects) { >+ if (object instanceof InternalCDOObject) { >+ internalObjects.add((InternalCDOObject) object); >+ } >+ } >+ } else { >+ synchronized (this.objects) { >+ internalObjects = new ArrayList<InternalCDOObject>(this.objects >+ .values()); >+ } >+ } >+ >+ int result = internalObjects.size(); >+ if (result != 0) { >+ CDOStateMachine.INSTANCE.reload(internalObjects >+ .toArray(new InternalCDOObject[result])); >+ } >+ >+ return result; >+ } >+ >+ public void close() { >+ LifecycleUtil.deactivate(this, OMLogger.Level.DEBUG); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public boolean isClosed() { >+ return !isActive(); >+ } >+ >+ @Override >+ public String toString() { >+ return MessageFormat.format("CDOView({0})", viewID); //$NON-NLS-1$ >+ } >+ >+ public boolean isAdapterForType(Object type) { >+ return type instanceof ResourceSet; >+ } >+ >+ public org.eclipse.emf.common.notify.Notifier getTarget() { >+ return getResourceSet(); >+ } >+ >+ public void getCDOIDAndVersion(Map<CDOID, CDOIDAndVersion> uniqueObjects, >+ Collection<? extends CDOObject> cdoObjects) { >+ for (CDOObject internalCDOObject : cdoObjects) { >+ CDORevision cdoRevision = CDOStateMachine.INSTANCE >+ .readNoLoad((InternalCDOObject) internalCDOObject); >+ CDOID cdoId = internalCDOObject.cdoID(); >+ if (cdoRevision != null && !uniqueObjects.containsKey(cdoId)) { >+ int version = cdoRevision.getVersion(); >+ uniqueObjects.put(cdoId, CDOIDUtil.createIDAndVersion(cdoId, >+ version)); >+ } >+ } >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ protected OptionsImpl createOptions() { >+ return new OptionsImpl(); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ @Override >+ protected void doBeforeActivate() throws Exception { >+ super.doBeforeActivate(); >+ checkState(session, "session"); //$NON-NLS-1$ >+ checkState(viewID > 0, "viewID"); //$NON-NLS-1$ >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ @Override >+ protected void doActivate() throws Exception { >+ session.getSessionProtocol().openView(getViewID(), getViewType(), >+ getTimeStamp()); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ @Override >+ protected void doDeactivate() throws Exception { >+ try { >+ session.getSessionProtocol().closeView(getViewID()); >+ } catch (Exception ex) { >+ OM.LOG.error(ex); >+ } >+ >+ try { >+ session.viewDetached(this); >+ } catch (Exception ex) { >+ OM.LOG.error(ex); >+ } >+ >+ session = null; >+ objects = null; >+ store = null; >+ viewSet = null; >+ changeSubscriptionManager = null; >+ featureAnalyzer = null; >+ lastLookupID = null; >+ lastLookupObject = null; >+ options = null; >+ } >+ >+ /** >+ * @author Eike Stepper >+ */ >+ protected abstract class Event extends org.eclipse.net4j.util.event.Event >+ implements CDOViewEvent { >+ private static final long serialVersionUID = 1L; >+ >+ public Event() { >+ super(CDOViewImpl.this); >+ } >+ >+ @Override >+ public CDOViewImpl getSource() { >+ return (CDOViewImpl) super.getSource(); >+ } >+ } >+ >+ /** >+ * @author Simon McDuff >+ * @since 2.0 >+ */ >+ protected class AdapterManager { >+ private Set<CDOObject> objects = new HashBag<CDOObject>(); >+ >+ public void committedTransaction(CDOTransaction transaction, >+ CDOCommitContext commitContext) { >+ if (options().getStrongReferencePolicy() != CDOAdapterPolicy.NONE) { >+ for (CDOObject object : commitContext.getNewObjects().values()) { >+ attachObject(object); >+ } >+ >+ for (CDOObject object : commitContext.getNewResources() >+ .values()) { >+ attachObject(object); >+ } >+ >+ for (CDOObject object : commitContext.getDetachedObjects() >+ .values()) { >+ detachObject(object); >+ } >+ } >+ } >+ >+ protected synchronized void attachObject(CDOObject object) { >+ if (((InternalEObject) object).eNotificationRequired()) { >+ CDOAdapterPolicy strongReferencePolicy = options() >+ .getStrongReferencePolicy(); >+ int count = 0; >+ for (Adapter adapter : object.eAdapters()) { >+ if (strongReferencePolicy.isValid(object, adapter)) { >+ count++; >+ } >+ } >+ >+ for (int i = 0; i < count; i++) { >+ objects.add(object); >+ } >+ } >+ } >+ >+ protected synchronized void detachObject(CDOObject object) { >+ while (objects.remove(object)) { >+ // Do nothing >+ } >+ } >+ >+ protected synchronized void attachAdapter(CDOObject object, >+ Adapter adapter) { >+ if (options().getStrongReferencePolicy().isValid(object, adapter)) { >+ objects.add(object); >+ } >+ } >+ >+ protected synchronized void detachAdapter(CDOObject object, >+ Adapter adapter) { >+ if (options().getStrongReferencePolicy().isValid(object, adapter)) { >+ objects.add(object); >+ } >+ } >+ >+ public synchronized void reset() { >+ // Keep the object in memory >+ Set<CDOObject> oldObject = objects; >+ objects = new HashBag<CDOObject>(); >+ if (options().getStrongReferencePolicy() != CDOAdapterPolicy.NONE) { >+ InternalCDOObject objects[] = getObjectsArray(); >+ for (int i = 0; i < objects.length; i++) { >+ InternalCDOObject object = objects[i]; >+ attachObject(object); >+ } >+ } >+ >+ oldObject.clear(); >+ } >+ }; >+ >+ /** >+ * @author Simon McDuff >+ * @since 2.0 >+ */ >+ protected static class ChangeSubscriptionManager { >+ private CDOViewImpl view; >+ >+ private Map<CDOID, SubscribeEntry> subscriptions = new HashMap<CDOID, SubscribeEntry>(); >+ >+ public ChangeSubscriptionManager(CDOViewImpl view) { >+ this.view = view; >+ } >+ >+ public void committedTransaction(CDOTransaction transaction, >+ CDOCommitContext commitContext) { >+ handleNewObjects(commitContext.getNewResources().values()); >+ handleNewObjects(commitContext.getNewObjects().values()); >+ handleDetachedObjects(commitContext.getDetachedObjects().keySet()); >+ } >+ >+ public void subscribe(EObject eObject, Adapter adapter) { >+ subscribe(eObject, adapter, 1); >+ } >+ >+ public void unsubscribe(EObject eObject, Adapter adapter) { >+ subscribe(eObject, adapter, -1); >+ } >+ >+ /** >+ * Register to the server all objects from the active list >+ */ >+ protected void notifyChangeSubcriptionPolicy() { >+ boolean policiesPresent = view.options() >+ .hasChangeSubscriptionPolicies(); >+ synchronized (subscriptions) { >+ subscriptions.clear(); >+ List<CDOID> cdoIDs = new ArrayList<CDOID>(); >+ if (policiesPresent) { >+ for (InternalCDOObject cdoObject : view.getObjectsArray()) { >+ int count = getNumberOfValidAdapter(cdoObject); >+ if (count > 0) { >+ cdoIDs.add(cdoObject.cdoID()); >+ addEntry(cdoObject.cdoID(), cdoObject, count); >+ } >+ } >+ } >+ >+ request(cdoIDs, true, true); >+ } >+ } >+ >+ protected void handleDetachedObjects(Collection<CDOID> detachedObjects) { >+ synchronized (subscriptions) { >+ for (CDOID id : detachedObjects) { >+ SubscribeEntry entry = subscriptions.get(id); >+ if (entry != null) { >+ detachObject(id); >+ } >+ } >+ } >+ } >+ >+ protected void handleNewObjects( >+ Collection<? extends CDOObject> newObjects) { >+ synchronized (subscriptions) { >+ for (CDOObject object : newObjects) { >+ InternalCDOObject cdoDetachedObject = (InternalCDOObject) object; >+ if (cdoDetachedObject != null) { >+ int count = getNumberOfValidAdapter(cdoDetachedObject); >+ if (count > 0) { >+ subscribe(cdoDetachedObject.cdoID(), >+ cdoDetachedObject, count); >+ } >+ } >+ } >+ } >+ } >+ >+ protected InternalCDOObject getSubcribeObject(CDOID id) { >+ synchronized (subscriptions) { >+ SubscribeEntry entry = subscriptions.get(id); >+ if (entry != null) { >+ return entry.getObject(); >+ } >+ } >+ >+ return null; >+ } >+ >+ protected void request(List<CDOID> ids, boolean clear, >+ boolean subscribeMode) { >+ view.session.getSessionProtocol().changeSubscription( >+ view.getViewID(), ids, subscribeMode, clear); >+ } >+ >+ protected int getNumberOfValidAdapter(InternalCDOObject object) { >+ int count = 0; >+ if (!FSMUtil.isTransient(object) && !FSMUtil.isNew(object)) { >+ if (object.eNotificationRequired()) { >+ for (Adapter adapter : object.eAdapters()) { >+ if (shouldSubscribe(object, adapter)) { >+ count++; >+ } >+ } >+ } >+ } >+ >+ return count; >+ } >+ >+ private void subscribe(EObject eObject, Adapter adapter, int adjust) { >+ synchronized (subscriptions) { >+ if (shouldSubscribe(eObject, adapter)) { >+ InternalCDOObject internalCDOObject = FSMUtil.adapt( >+ eObject, view); >+ if (internalCDOObject.cdoView() != view) { >+ throw new CDOException( >+ MessageFormat >+ .format( >+ Messages >+ .getString("CDOViewImpl.27"), internalCDOObject)); //$NON-NLS-1$ >+ } >+ >+ subscribe(internalCDOObject.cdoID(), internalCDOObject, >+ adjust); >+ } >+ } >+ } >+ >+ private boolean shouldSubscribe(EObject eObject, Adapter adapter) { >+ for (CDOAdapterPolicy policy : view.options() >+ .getChangeSubscriptionPolicies()) { >+ if (policy.isValid(eObject, adapter)) { >+ return true; >+ } >+ } >+ >+ return false; >+ } >+ >+ private void subscribe(CDOID id, InternalCDOObject cdoObject, int adjust) { >+ boolean policiesPresent = view.options() >+ .hasChangeSubscriptionPolicies(); >+ synchronized (subscriptions) { >+ int count = 0; >+ SubscribeEntry entry = subscriptions.get(id); >+ if (entry == null) { >+ // Cannot adjust negative value >+ if (adjust < 0) { >+ return; >+ } >+ >+ // Notification need to be enable to send correct value to >+ // the server >+ if (policiesPresent) { >+ request(Collections.singletonList(id), false, true); >+ } >+ } else { >+ count = entry.getCount(); >+ } >+ >+ count += adjust; >+ >+ // Look if objects need to be unsubscribe >+ if (count <= 0) { >+ subscriptions.remove(id); >+ >+ // Notification need to be enable to send correct value to >+ // the server >+ if (policiesPresent) { >+ request(Collections.singletonList(id), false, false); >+ } >+ } else { >+ if (entry == null) { >+ addEntry(id, cdoObject, count); >+ } else { >+ entry.setCount(count); >+ } >+ } >+ } >+ } >+ >+ private void detachObject(CDOID id) { >+ subscribe(id, null, Integer.MIN_VALUE); >+ } >+ >+ private void addEntry(CDOID key, InternalCDOObject object, int count) { >+ subscriptions.put(key, new SubscribeEntry(object, count)); >+ } >+ >+ /** >+ * @author Eike Stepper >+ */ >+ protected static final class SubscribeEntry { >+ private int count; >+ >+ private InternalCDOObject object; >+ >+ public SubscribeEntry(InternalCDOObject object, int count) { >+ this.count = count; >+ this.object = object; >+ } >+ >+ public InternalCDOObject getObject() { >+ return object; >+ } >+ >+ public int getCount() { >+ return count; >+ } >+ >+ public void setCount(int count) { >+ this.count = count; >+ } >+ } >+ } >+ >+ /** >+ * @author Simon McDuff >+ */ >+ private final class InvalidationEvent extends Event implements >+ CDOViewInvalidationEvent { >+ private static final long serialVersionUID = 1L; >+ >+ private long timeStamp; >+ >+ private Set<? extends CDOObject> dirtyObjects; >+ >+ private Set<? extends CDOObject> detachedObjects; >+ >+ public InvalidationEvent(long timeStamp, >+ Set<? extends CDOObject> dirtyOIDs, >+ Set<? extends CDOObject> detachedObjects) { >+ this.timeStamp = timeStamp; >+ dirtyObjects = dirtyOIDs; >+ this.detachedObjects = detachedObjects; >+ } >+ >+ public long getTimeStamp() { >+ return timeStamp; >+ } >+ >+ public Set<? extends CDOObject> getDirtyObjects() { >+ return dirtyObjects; >+ } >+ >+ public Set<? extends CDOObject> getDetachedObjects() { >+ return detachedObjects; >+ } >+ >+ @Override >+ public String toString() { >+ return "CDOViewInvalidationEvent: " + dirtyObjects; //$NON-NLS-1$ >+ } >+ } >+ >+ /** >+ * @author Eike Stepper >+ */ >+ private final class AdaptersNotifiedEvent extends Event implements >+ CDOViewAdaptersNotifiedEvent { >+ private static final long serialVersionUID = 1L; >+ >+ private long timeStamp; >+ >+ public AdaptersNotifiedEvent(long timeStamp) { >+ this.timeStamp = timeStamp; >+ } >+ >+ public long getTimeStamp() { >+ return timeStamp; >+ } >+ >+ @Override >+ public String toString() { >+ return "CDOViewAdaptersNotifiedEvent: " + timeStamp; //$NON-NLS-1$ >+ } >+ } >+ >+ /** >+ * @author Eike Stepper >+ * @since 2.0 >+ */ >+ protected class OptionsImpl extends Notifier implements Options { >+ private boolean invalidationNotificationEnabled; >+ >+ private CDORevisionPrefetchingPolicy revisionPrefetchingPolicy; >+ >+ private CDOStaleReferencePolicy staleReferencePolicy = CDOStaleReferencePolicy.EXCEPTION; >+ >+ private HashBag<CDOAdapterPolicy> changeSubscriptionPolicies = new HashBag<CDOAdapterPolicy>(); >+ >+ private CDOAdapterPolicy strongReferencePolicy = CDOAdapterPolicy.ALL; >+ >+ public OptionsImpl() { >+ setCacheReferenceType(null); >+ invalidationNotificationEnabled = OM.PREF_ENABLE_INVALIDATION_NOTIFICATION >+ .getValue(); >+ revisionPrefetchingPolicy = CDOUtil >+ .createRevisionPrefetchingPolicy(OM.PREF_REVISION_LOADING_CHUNK_SIZE >+ .getValue()); >+ } >+ >+ public CDOViewImpl getContainer() { >+ return CDOViewImpl.this; >+ } >+ >+ public boolean isInvalidationNotificationEnabled() { >+ return invalidationNotificationEnabled; >+ } >+ >+ public void setInvalidationNotificationEnabled(boolean enabled) { >+ if (invalidationNotificationEnabled != enabled) { >+ invalidationNotificationEnabled = enabled; >+ IListener[] listeners = getListeners(); >+ if (listeners != null) { >+ fireEvent(new InvalidationNotificationEventImpl(), >+ listeners); >+ } >+ } >+ } >+ >+ public boolean hasChangeSubscriptionPolicies() { >+ synchronized (changeSubscriptionPolicies) { >+ return !changeSubscriptionPolicies.isEmpty(); >+ } >+ } >+ >+ public CDOAdapterPolicy[] getChangeSubscriptionPolicies() { >+ synchronized (changeSubscriptionPolicies) { >+ return changeSubscriptionPolicies >+ .toArray(new CDOAdapterPolicy[changeSubscriptionPolicies >+ .size()]); >+ } >+ } >+ >+ public void addChangeSubscriptionPolicy(CDOAdapterPolicy policy) { >+ boolean changed = false; >+ synchronized (changeSubscriptionPolicies) { >+ if (changeSubscriptionPolicies.add(policy)) { >+ changeSubscriptionManager.notifyChangeSubcriptionPolicy(); >+ changed = true; >+ } >+ } >+ >+ if (changed) { >+ IListener[] listeners = getListeners(); >+ if (listeners != null) { >+ fireEvent(new ChangeSubscriptionPoliciesEventImpl(), >+ listeners); >+ } >+ } >+ } >+ >+ public void removeChangeSubscriptionPolicy(CDOAdapterPolicy policy) { >+ boolean changed = false; >+ synchronized (changeSubscriptionPolicies) { >+ if (changeSubscriptionPolicies.remove(policy) >+ && !changeSubscriptionPolicies.contains(policy)) { >+ changeSubscriptionManager.notifyChangeSubcriptionPolicy(); >+ changed = true; >+ } >+ } >+ >+ if (changed) { >+ IListener[] listeners = getListeners(); >+ if (listeners != null) { >+ fireEvent(new ChangeSubscriptionPoliciesEventImpl(), >+ listeners); >+ } >+ } >+ } >+ >+ public CDOAdapterPolicy getStrongReferencePolicy() { >+ return strongReferencePolicy; >+ } >+ >+ public void setStrongReferencePolicy(CDOAdapterPolicy adapterPolicy) { >+ if (adapterPolicy == null) { >+ adapterPolicy = CDOAdapterPolicy.ALL; >+ } >+ >+ if (strongReferencePolicy != adapterPolicy) { >+ strongReferencePolicy = adapterPolicy; >+ adapterPolicyManager.reset(); >+ IListener[] listeners = getListeners(); >+ if (listeners != null) { >+ fireEvent(new ReferencePolicyEventImpl(), listeners); >+ } >+ } >+ } >+ >+ public CDORevisionPrefetchingPolicy getRevisionPrefetchingPolicy() { >+ return revisionPrefetchingPolicy; >+ } >+ >+ public void setRevisionPrefetchingPolicy( >+ CDORevisionPrefetchingPolicy prefetchingPolicy) { >+ if (prefetchingPolicy == null) { >+ prefetchingPolicy = CDORevisionPrefetchingPolicy.NO_PREFETCHING; >+ } >+ >+ if (revisionPrefetchingPolicy != prefetchingPolicy) { >+ revisionPrefetchingPolicy = prefetchingPolicy; >+ IListener[] listeners = getListeners(); >+ if (listeners != null) { >+ fireEvent(new RevisionPrefetchingPolicyEventImpl(), >+ listeners); >+ } >+ } >+ } >+ >+ public CDOStaleReferencePolicy getStaleReferenceBehaviour() { >+ return staleReferencePolicy; >+ } >+ >+ public void setStaleReferenceBehaviour(CDOStaleReferencePolicy policy) { >+ if (policy == null) { >+ policy = CDOStaleReferencePolicy.EXCEPTION; >+ } >+ >+ if (staleReferencePolicy != policy) { >+ staleReferencePolicy = policy; >+ IListener[] listeners = getListeners(); >+ if (listeners != null) { >+ fireEvent(new StaleReferencePolicyEventImpl(), listeners); >+ } >+ } >+ } >+ >+ public ReferenceType getCacheReferenceType() { >+ if (objects instanceof ReferenceValueMap.Strong<?, ?>) { >+ return ReferenceType.STRONG; >+ } >+ >+ if (objects instanceof ReferenceValueMap.Soft<?, ?>) { >+ return ReferenceType.SOFT; >+ } >+ >+ if (objects instanceof ReferenceValueMap.Weak<?, ?>) { >+ return ReferenceType.WEAK; >+ } >+ >+ throw new IllegalStateException(Messages >+ .getString("CDOViewImpl.29")); //$NON-NLS-1$ >+ } >+ >+ public boolean setCacheReferenceType(ReferenceType referenceType) { >+ if (referenceType == null) { >+ referenceType = ReferenceType.SOFT; >+ } >+ >+ ReferenceValueMap<CDOID, InternalCDOObject> newObjects; >+ switch (referenceType) { >+ case STRONG: >+ if (objects instanceof ReferenceValueMap.Strong<?, ?>) { >+ return false; >+ } >+ >+ newObjects = new ReferenceValueMap.Strong<CDOID, InternalCDOObject>(); >+ break; >+ >+ case SOFT: >+ if (objects instanceof ReferenceValueMap.Soft<?, ?>) { >+ return false; >+ } >+ >+ newObjects = new ReferenceValueMap.Soft<CDOID, InternalCDOObject>(); >+ break; >+ >+ case WEAK: >+ if (objects instanceof ReferenceValueMap.Weak<?, ?>) { >+ return false; >+ } >+ >+ newObjects = new ReferenceValueMap.Weak<CDOID, InternalCDOObject>(); >+ break; >+ >+ default: >+ throw new IllegalArgumentException(Messages >+ .getString("CDOViewImpl.29")); //$NON-NLS-1$ >+ } >+ >+ if (objects == null) { >+ objects = newObjects; >+ IListener[] listeners = getListeners(); >+ if (listeners != null) { >+ fireEvent(new CacheReferenceTypeEventImpl(), listeners); >+ } >+ >+ return true; >+ } >+ >+ for (Entry<CDOID, InternalCDOObject> entry : objects.entrySet()) { >+ InternalCDOObject object = entry.getValue(); >+ if (object != null) { >+ newObjects.put(entry.getKey(), object); >+ } >+ } >+ >+ ConcurrentMap<CDOID, InternalCDOObject> oldObjects = objects; >+ synchronized (objects) { >+ objects = newObjects; >+ } >+ >+ oldObjects.clear(); >+ IListener[] listeners = getListeners(); >+ if (listeners != null) { >+ fireEvent(new CacheReferenceTypeEventImpl(), listeners); >+ } >+ >+ return true; >+ } >+ >+ /** >+ * @author Eike Stepper >+ */ >+ private final class CacheReferenceTypeEventImpl extends OptionsEvent >+ implements CacheReferenceTypeEvent { >+ private static final long serialVersionUID = 1L; >+ >+ public CacheReferenceTypeEventImpl() { >+ super(OptionsImpl.this); >+ } >+ } >+ >+ /** >+ * @author Eike Stepper >+ */ >+ private final class ChangeSubscriptionPoliciesEventImpl extends >+ OptionsEvent implements ChangeSubscriptionPoliciesEvent { >+ private static final long serialVersionUID = 1L; >+ >+ public ChangeSubscriptionPoliciesEventImpl() { >+ super(OptionsImpl.this); >+ } >+ } >+ >+ /** >+ * @author Eike Stepper >+ */ >+ private final class InvalidationNotificationEventImpl extends >+ OptionsEvent implements InvalidationNotificationEvent { >+ private static final long serialVersionUID = 1L; >+ >+ public InvalidationNotificationEventImpl() { >+ super(OptionsImpl.this); >+ } >+ } >+ >+ /** >+ * @author Eike Stepper >+ */ >+ private final class RevisionPrefetchingPolicyEventImpl extends >+ OptionsEvent implements RevisionPrefetchingPolicyEvent { >+ private static final long serialVersionUID = 1L; >+ >+ public RevisionPrefetchingPolicyEventImpl() { >+ super(OptionsImpl.this); >+ } >+ } >+ >+ /** >+ * @author Eike Stepper >+ */ >+ private final class ReferencePolicyEventImpl extends OptionsEvent >+ implements ReferencePolicyEvent { >+ private static final long serialVersionUID = 1L; >+ >+ public ReferencePolicyEventImpl() { >+ super(OptionsImpl.this); >+ } >+ } >+ >+ /** >+ * @author Simon McDuff >+ */ >+ private final class StaleReferencePolicyEventImpl extends OptionsEvent >+ implements StaleReferencePolicyEvent { >+ private static final long serialVersionUID = 1L; >+ >+ public StaleReferencePolicyEventImpl() { >+ super(OptionsImpl.this); >+ } >+ } >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ private boolean hasRegisteredListeners = false; >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ protected FastList<IListener> registeredLockListeners = new FastList<IListener>() { >+ @Override >+ protected IListener[] newArray(int length) { >+ return new IListener[length]; >+ } >+ >+ @Override >+ protected void firstElementAdded() { >+ firstListenerAdded(); >+ } >+ >+ @Override >+ protected void lastElementRemoved() { >+ lastListenerRemoved(); >+ } >+ }; >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public boolean hasRegisteredListeners() { >+ return hasRegisteredListeners; >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void registerLockListeners(Collection<IListener> collToRegister) { >+ for (IListener il : collToRegister) { >+ registerListener(il); >+ } >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void registerLockListener(IListener listenerToRegister) { >+ registerListener(listenerToRegister); >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void unRegisterLockListener(IListener listenerToRegister) { >+ unRegisterListener(listenerToRegister); >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void unRegisterLockListeners(Collection<IListener> collToUnregister) { >+ for (IListener il : collToUnregister) { >+ unRegisterListener(il); >+ } >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ protected void registerListener(IListener listenerToRegister) { >+ if (!hasRegisteredListeners) { >+ hasRegisteredListeners = true; >+ session.registerLockListeners(this); >+ } >+ registeredLockListeners.add(listenerToRegister); >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ protected void unRegisterListener(IListener listenerToUnRegister) { >+ registeredLockListeners.remove(listenerToUnRegister); >+ if (registeredLockListeners.isEmpty()) { >+ hasRegisteredListeners = false; >+ session.unregisterLockListeners(this); >+ } >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void notifyRemoteLock(boolean b, String user, >+ Collection<CDOID> cdoids, LockType lockType) { >+ if (b) { >+ fireEvent(new RemoteLockAcquiredEvent(user, cdoids, lockType), >+ registeredLockListeners.get()); >+ } else { >+ fireEvent(new RemoteLockReleasedEvent(user, cdoids, lockType), >+ registeredLockListeners.get()); >+ } >+ } > } >Index: src/org/eclipse/emf/cdo/view/RemoteLockEvent.java >=================================================================== >RCS file: src/org/eclipse/emf/cdo/view/RemoteLockEvent.java >diff -N src/org/eclipse/emf/cdo/view/RemoteLockEvent.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/emf/cdo/view/RemoteLockEvent.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,51 @@ >+/** >+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * Eike Stepper - initial API and implementation >+ */ >+package org.eclipse.emf.cdo.view; >+ >+import org.eclipse.emf.cdo.common.id.CDOID; >+ >+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType; >+ >+import java.util.Collection; >+ >+/** >+ * @author Eike Stepper >+ */ >+public class RemoteLockEvent implements CDOViewEvent { >+ private Collection<CDOID> cdoIds; >+ private String user; >+ private LockType lockType; >+ >+ public RemoteLockEvent(String user, Collection<CDOID> cdoIds, >+ LockType lockType) { >+ super(); >+ this.user = user; >+ this.lockType = lockType; >+ this.cdoIds = cdoIds; >+ } >+ >+ public String getUser() { >+ return user; >+ } >+ >+ public LockType getLockType() { >+ return lockType; >+ } >+ >+ public Collection<CDOID> getCdoIds() { >+ return cdoIds; >+ } >+ >+ public CDOView getSource() { >+ return null; >+ } >+ >+} >Index: src/org/eclipse/emf/cdo/view/RemoteLockReleasedEvent.java >=================================================================== >RCS file: src/org/eclipse/emf/cdo/view/RemoteLockReleasedEvent.java >diff -N src/org/eclipse/emf/cdo/view/RemoteLockReleasedEvent.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/emf/cdo/view/RemoteLockReleasedEvent.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,27 @@ >+/** >+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * Eike Stepper - initial API and implementation >+ */ >+package org.eclipse.emf.cdo.view; >+ >+import org.eclipse.emf.cdo.common.id.CDOID; >+ >+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType; >+ >+import java.util.Collection; >+ >+/** >+ * @author Juan Pedro Silva >+ */ >+public class RemoteLockReleasedEvent extends RemoteLockEvent { >+ public RemoteLockReleasedEvent(String user, Collection<CDOID> cdoIds, >+ LockType lockType) { >+ super(user, cdoIds, lockType); >+ } >+} >Index: src/org/eclipse/emf/cdo/view/RemoteLockAcquiredEvent.java >=================================================================== >RCS file: src/org/eclipse/emf/cdo/view/RemoteLockAcquiredEvent.java >diff -N src/org/eclipse/emf/cdo/view/RemoteLockAcquiredEvent.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/emf/cdo/view/RemoteLockAcquiredEvent.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,28 @@ >+/** >+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * Eike Stepper - initial API and implementation >+ */ >+package org.eclipse.emf.cdo.view; >+ >+import org.eclipse.emf.cdo.common.id.CDOID; >+ >+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType; >+ >+import java.util.Collection; >+ >+/** >+ * @author Juan Pedro Silva >+ */ >+public class RemoteLockAcquiredEvent extends RemoteLockEvent { >+ >+ public RemoteLockAcquiredEvent(String user, Collection<CDOID> cdoIds, >+ LockType lockType) { >+ super(user, cdoIds, lockType); >+ } >+} >#P org.eclipse.emf.cdo.net4j >Index: src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.net4j/src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java,v >retrieving revision 1.13 >diff -u -r1.13 CDOClientProtocol.java >--- src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java 23 Sep 2009 17:19:24 -0000 1.13 >+++ src/org/eclipse/emf/cdo/internal/net4j/protocol/CDOClientProtocol.java 30 Nov 2009 20:08:50 -0000 >@@ -288,6 +288,14 @@ > case CDOProtocolConstants.SIGNAL_REMOTE_MESSAGE_NOTIFICATION: > return new RemoteMessageNotificationIndication(this); > >+ /** >+ * @author Juan Pedro Silva >+ */ >+ case CDOProtocolConstants.SIGNAL_REMOTE_LOCK_CHANGED_NOTIFICATION: >+ return new RemoteLockChangedIndication(this); >+ >+ /** ----------------------------------------------------- */ >+ > default: > return super.createSignalReactor(signalID); > } >@@ -347,4 +355,20 @@ > REVISION_LOADING.stop(request); > } > } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void unsubscribeRemoteLocks() >+ { >+ send(new UnsubscribeRemoteLocksRequest(this)); >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void subscribeRemoteLocks() >+ { >+ send(new SubscribeRemoteLocksRequest(this)); >+ } > } >Index: src/org/eclipse/emf/cdo/internal/net4j/protocol/UnsubscribeRemoteLocksRequest.java >=================================================================== >RCS file: src/org/eclipse/emf/cdo/internal/net4j/protocol/UnsubscribeRemoteLocksRequest.java >diff -N src/org/eclipse/emf/cdo/internal/net4j/protocol/UnsubscribeRemoteLocksRequest.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/emf/cdo/internal/net4j/protocol/UnsubscribeRemoteLocksRequest.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,48 @@ >+/** >+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * Eike Stepper - initial API and implementation >+ */ >+package org.eclipse.emf.cdo.internal.net4j.protocol; >+ >+import org.eclipse.emf.cdo.common.io.CDODataInput; >+import org.eclipse.emf.cdo.common.io.CDODataOutput; >+import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; >+import org.eclipse.emf.cdo.internal.net4j.bundle.OM; >+ >+import org.eclipse.net4j.util.om.trace.ContextTracer; >+ >+import java.io.IOException; >+ >+/** >+ * @author Juan Pedro Silva >+ */ >+public class UnsubscribeRemoteLocksRequest extends CDOClientRequest<Boolean> >+{ >+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, UnsubscribeRemoteLocksRequest.class); >+ >+ public UnsubscribeRemoteLocksRequest(CDOClientProtocol protocol) >+ { >+ super(protocol, CDOProtocolConstants.SIGNAL_UNREGISTER_LOCK_LISTENER); >+ } >+ >+ @Override >+ protected void requesting(CDODataOutput out) throws IOException >+ { >+ if (TRACER.isEnabled()) >+ { >+ TRACER.trace("Unsubscribing from Lock Notifications"); //$NON-NLS-1$ >+ } >+ } >+ >+ @Override >+ protected Boolean confirming(CDODataInput in) throws IOException >+ { >+ return in.readBoolean(); >+ } >+} >Index: src/org/eclipse/emf/cdo/internal/net4j/protocol/RemoteLockChangedIndication.java >=================================================================== >RCS file: src/org/eclipse/emf/cdo/internal/net4j/protocol/RemoteLockChangedIndication.java >diff -N src/org/eclipse/emf/cdo/internal/net4j/protocol/RemoteLockChangedIndication.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/emf/cdo/internal/net4j/protocol/RemoteLockChangedIndication.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,94 @@ >+/** >+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * Eike Stepper - initial API and implementation >+ */ >+package org.eclipse.emf.cdo.internal.net4j.protocol; >+ >+import org.eclipse.emf.cdo.common.id.CDOID; >+import org.eclipse.emf.cdo.common.io.CDODataInput; >+import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; >+import org.eclipse.emf.cdo.internal.net4j.bundle.OM; >+import org.eclipse.emf.cdo.view.CDOView; >+ >+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType; >+import org.eclipse.net4j.util.io.IORuntimeException; >+import org.eclipse.net4j.util.om.trace.ContextTracer; >+ >+import java.io.IOException; >+import java.util.HashSet; >+import java.util.Set; >+ >+/** >+ * @author Juan Pedro Silva >+ * @see org.eclipse.emf.cdo.server.internal.net4j.protocol.LockObjectsIndication >+ */ >+public class RemoteLockChangedIndication extends CDOClientIndication >+{ >+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, RemoteLockChangedIndication.class); >+ >+ private LockType lockType; >+ >+ private Set<CDOID> lockedObjects; >+ >+ private String user; >+ >+ private int sessionId; >+ >+ private boolean lock; >+ >+ public RemoteLockChangedIndication(CDOClientProtocol cdoClientProtocol) >+ { >+ super(cdoClientProtocol, CDOProtocolConstants.SIGNAL_REMOTE_LOCK_CHANGED_NOTIFICATION); >+ } >+ >+ @Override >+ protected void indicating(CDODataInput in) throws IOException >+ { >+ long timeStamp = in.readLong(); >+ if (TRACER.isEnabled()) >+ { >+ TRACER.format("Read timeStamp: {0,date} {0,time}", timeStamp); //$NON-NLS-1$ >+ } >+ >+ int size = in.readInt(); >+ if (TRACER.isEnabled()) >+ { >+ TRACER.format("Reading {0} locked IDs", size); //$NON-NLS-1$ >+ } >+ >+ lockedObjects = new HashSet<CDOID>(); >+ for (int i = 0; i < size; i++) >+ { >+ CDOID dirtyOID = in.readCDOID(); >+ if (TRACER.isEnabled()) >+ { >+ TRACER.format("Read locked ID: {0}", dirtyOID); //$NON-NLS-1$ >+ } >+ >+ lockedObjects.add(dirtyOID); >+ } >+ lock = in.readBoolean(); >+ lockType = in.readCDOLockType(); >+ user = in.readString(); >+ try >+ { >+ for (CDOView cv : getSession().getViews()) >+ { >+ if (cv.hasListeners()) >+ { >+ cv.notifyRemoteLock(lock, user, lockedObjects, lockType); >+ } >+ } >+ } >+ catch (Exception ex) // Interrupted >+ { >+ throw new IORuntimeException(ex); >+ } >+ } >+} >Index: src/org/eclipse/emf/cdo/internal/net4j/protocol/SubscribeRemoteLocksRequest.java >=================================================================== >RCS file: src/org/eclipse/emf/cdo/internal/net4j/protocol/SubscribeRemoteLocksRequest.java >diff -N src/org/eclipse/emf/cdo/internal/net4j/protocol/SubscribeRemoteLocksRequest.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/emf/cdo/internal/net4j/protocol/SubscribeRemoteLocksRequest.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,49 @@ >+/** >+ /** >+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * Eike Stepper - initial API and implementation >+ */ >+package org.eclipse.emf.cdo.internal.net4j.protocol; >+ >+import org.eclipse.emf.cdo.common.io.CDODataInput; >+import org.eclipse.emf.cdo.common.io.CDODataOutput; >+import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; >+import org.eclipse.emf.cdo.internal.net4j.bundle.OM; >+ >+import org.eclipse.net4j.util.om.trace.ContextTracer; >+ >+import java.io.IOException; >+ >+/** >+ * @author Juan Pedro Silva >+ */ >+public class SubscribeRemoteLocksRequest extends CDOClientRequest<Boolean> >+{ >+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, SubscribeRemoteLocksRequest.class); >+ >+ public SubscribeRemoteLocksRequest(CDOClientProtocol protocol) >+ { >+ super(protocol, CDOProtocolConstants.SIGNAL_REGISTER_LOCK_LISTENER); >+ } >+ >+ @Override >+ protected void requesting(CDODataOutput out) throws IOException >+ { >+ if (TRACER.isEnabled()) >+ { >+ TRACER.trace("Subscribing to Lock Notifications"); //$NON-NLS-1$ >+ } >+ } >+ >+ @Override >+ protected Boolean confirming(CDODataInput in) throws IOException >+ { >+ return in.readBoolean(); >+ } >+} >#P org.eclipse.emf.cdo.server >Index: src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java,v >retrieving revision 1.20 >diff -u -r1.20 EmbeddedClientSessionProtocol.java >--- src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java 23 Sep 2009 17:19:33 -0000 1.20 >+++ src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java 30 Nov 2009 20:08:52 -0000 >@@ -467,4 +467,20 @@ > > return result; > } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void subscribeRemoteLocks() >+ { >+ throw new UnsupportedOperationException(); >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void unsubscribeRemoteLocks() >+ { >+ throw new UnsupportedOperationException(); >+ } > } >Index: src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedServerSessionProtocol.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedServerSessionProtocol.java,v >retrieving revision 1.8 >diff -u -r1.8 EmbeddedServerSessionProtocol.java >--- src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedServerSessionProtocol.java 18 Jul 2009 23:00:48 -0000 1.8 >+++ src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedServerSessionProtocol.java 30 Nov 2009 20:08:52 -0000 >@@ -21,9 +21,11 @@ > import org.eclipse.emf.cdo.spi.server.InternalRepository; > import org.eclipse.emf.cdo.spi.server.InternalSession; > >+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType; > import org.eclipse.net4j.util.lifecycle.Lifecycle; > > import java.util.Arrays; >+import java.util.Collection; > import java.util.HashSet; > import java.util.List; > >@@ -77,8 +79,19 @@ > throw new UnsupportedOperationException(); > } > >+ /** >+ * @author Juan Pedro Silva >+ */ > public boolean sendRemoteMessageNotification(InternalSession sender, CDORemoteSessionMessage message) > { > throw new UnsupportedOperationException(); > } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void sendRemoteLockNotification(boolean b, String user, Collection<CDOID> cdoids, LockType lockType) >+ { >+ throw new UnsupportedOperationException(); >+ } > } >Index: src/org/eclipse/emf/cdo/internal/server/Session.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java,v >retrieving revision 1.85 >diff -u -r1.85 Session.java >--- src/org/eclipse/emf/cdo/internal/server/Session.java 23 Sep 2009 17:19:33 -0000 1.85 >+++ src/org/eclipse/emf/cdo/internal/server/Session.java 30 Nov 2009 20:08:51 -0000 >@@ -35,6 +35,7 @@ > import org.eclipse.emf.cdo.spi.server.InternalView; > > import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump; >+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType; > import org.eclipse.net4j.util.container.Container; > import org.eclipse.net4j.util.event.EventUtil; > import org.eclipse.net4j.util.event.IListener; >@@ -50,6 +51,7 @@ > > import java.text.MessageFormat; > import java.util.ArrayList; >+import java.util.Collection; > import java.util.Collections; > import java.util.List; > import java.util.Set; >@@ -398,4 +400,12 @@ > manager = null; > super.doDeactivate(); > } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void notifyRemoteLock(boolean b, String user, Collection<CDOID> cdoids, LockType lockType) >+ { >+ getProtocol().sendRemoteLockNotification(b, user, cdoids, lockType); >+ } > } >Index: src/org/eclipse/emf/cdo/internal/server/LockManager.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/LockManager.java,v >retrieving revision 1.7 >diff -u -r1.7 LockManager.java >--- src/org/eclipse/emf/cdo/internal/server/LockManager.java 7 Jul 2009 06:48:14 -0000 1.7 >+++ src/org/eclipse/emf/cdo/internal/server/LockManager.java 30 Nov 2009 20:08:51 -0000 >@@ -24,6 +24,8 @@ > import org.eclipse.net4j.util.container.IContainer; > import org.eclipse.net4j.util.event.IListener; > >+import java.util.Collection; >+ > /** > * @author Simon McDuff > * @since 3.0 >@@ -91,4 +93,41 @@ > > super.doDeactivate(); > } >+ >+ /** >+ * @author Juan Pedro Silva >+ * @param lock >+ * : True = Lock, false = Unlock >+ */ >+ @Override >+ protected void notifyRemoteLockChanged(boolean b, IView sender, Collection<? extends CDOID> cdoids, LockType lockType) >+ { >+ for (Object il : registeredLockListeners) >+ { >+ ISession is = (ISession)il; >+ is.notifyRemoteLock(b, sender.getSession().getUserID(), (Collection<CDOID>)cdoids, lockType); >+ } >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ @Override >+ protected void registerListener(Object listenerToRegister) >+ { >+ registeredLockListeners.add(listenerToRegister); >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ @Override >+ protected void unRegisterListener(Object listenerToRegister) >+ { >+ registeredLockListeners.remove(listenerToRegister); >+ if (registeredLockListeners.isEmpty()) >+ { >+ hasListenerRegistered = false; >+ } >+ } > } >Index: src/org/eclipse/emf/cdo/server/ISession.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ISession.java,v >retrieving revision 1.20 >diff -u -r1.20 ISession.java >--- src/org/eclipse/emf/cdo/server/ISession.java 7 Jul 2009 06:48:14 -0000 1.20 >+++ src/org/eclipse/emf/cdo/server/ISession.java 30 Nov 2009 20:08:52 -0000 >@@ -12,10 +12,14 @@ > package org.eclipse.emf.cdo.server; > > import org.eclipse.emf.cdo.common.CDOCommonSession; >+import org.eclipse.emf.cdo.common.id.CDOID; > import org.eclipse.emf.cdo.spi.server.ISessionProtocol; > >+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType; > import org.eclipse.net4j.util.container.IContainer; > >+import java.util.Collection; >+ > /** > * @author Eike Stepper > */ >@@ -50,4 +54,16 @@ > * @since 2.0 > */ > public ITransaction openTransaction(int viewID); >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public String getUserID(); >+ >+ /** >+ * @author Juan Pedro Silva >+ * @param lock >+ * : True = Lock, false = Unlock >+ */ >+ public void notifyRemoteLock(boolean b, String user, Collection<CDOID> cdoids, LockType lockType); > } >Index: src/org/eclipse/emf/cdo/spi/server/ISessionProtocol.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/ISessionProtocol.java,v >retrieving revision 1.4 >diff -u -r1.4 ISessionProtocol.java >--- src/org/eclipse/emf/cdo/spi/server/ISessionProtocol.java 18 Jul 2009 10:42:57 -0000 1.4 >+++ src/org/eclipse/emf/cdo/spi/server/ISessionProtocol.java 30 Nov 2009 20:08:52 -0000 >@@ -19,6 +19,9 @@ > import org.eclipse.emf.cdo.server.ISession; > import org.eclipse.emf.cdo.session.remote.CDORemoteSessionMessage; > >+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType; >+ >+import java.util.Collection; > import java.util.List; > > /** >@@ -35,4 +38,9 @@ > public void sendRemoteSessionNotification(byte opcode, ISession session); > > public boolean sendRemoteMessageNotification(InternalSession sender, CDORemoteSessionMessage message); >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void sendRemoteLockNotification(boolean b, String user, Collection<CDOID> cdoids, LockType lockType); > } >#P org.eclipse.net4j.util >Index: src/org/eclipse/net4j/util/concurrent/RWLockManager.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.net4j/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/concurrent/RWLockManager.java,v >retrieving revision 1.12 >diff -u -r1.12 RWLockManager.java >--- src/org/eclipse/net4j/util/concurrent/RWLockManager.java 10 Jul 2009 07:50:55 -0000 1.12 >+++ src/org/eclipse/net4j/util/concurrent/RWLockManager.java 30 Nov 2009 20:08:53 -0000 >@@ -19,6 +19,7 @@ > import java.util.Collection; > import java.util.Collections; > import java.util.HashMap; >+import java.util.HashSet; > import java.util.List; > import java.util.Map; > import java.util.Set; >@@ -94,6 +95,10 @@ > > private Object lockChanged = new Object(); > >+ protected boolean hasListenerRegistered; >+ >+ protected Set<Object> registeredLockListeners = new HashSet<Object>(); >+ > /** > * @since 3.0 > */ >@@ -101,6 +106,7 @@ > throws InterruptedException > { > lock(getLockingStrategy(type), context, objectsToLock, timeout); >+ notifyRemoteLockChanged(true, context, objectsToLock, type); > } > > /** >@@ -121,6 +127,7 @@ > public void unlock(LockType type, V context, Collection<? extends K> objectsToUnlock) > { > unlock(getLockingStrategy(type), context, objectsToUnlock); >+ notifyRemoteLockChanged(false, context, objectsToUnlock, type); > } > > /** >@@ -635,4 +642,79 @@ > throw new UnsupportedOperationException(); > } > } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void registerLockListeners(Collection<Object> collToRegister) >+ { >+ for (Object il : collToRegister) >+ { >+ registerListener(il); >+ } >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void registerLockListener(Object listenerToRegister) >+ { >+ registerListener(listenerToRegister); >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void unRegisterLockListener(Object listenerToRegister) >+ { >+ unRegisterListener(listenerToRegister); >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void unRegisterLockListeners(Collection<Object> collToUnregister) >+ { >+ for (Object il : collToUnregister) >+ { >+ unRegisterListener(il); >+ } >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public boolean hasListenerRegistered() >+ { >+ return hasListenerRegistered; >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ protected void registerListener(Object listenerToRegister) >+ { >+ registeredLockListeners.add(listenerToRegister); >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ protected void unRegisterListener(Object listenerToRegister) >+ { >+ registeredLockListeners.remove(listenerToRegister); >+ if (registeredLockListeners.isEmpty()) >+ { >+ hasListenerRegistered = false; >+ } >+ } >+ >+ /** >+ * @author Juan Pedro Silva >+ * @param lock >+ * : True = Lock, false = Unlock >+ */ >+ protected void notifyRemoteLockChanged(boolean b, V context, Collection<? extends K> cdoids, LockType lockType) >+ { >+ } > } >Index: src/org/eclipse/net4j/util/concurrent/IRWLockManager.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.net4j/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/concurrent/IRWLockManager.java,v >retrieving revision 1.3 >diff -u -r1.3 IRWLockManager.java >--- src/org/eclipse/net4j/util/concurrent/IRWLockManager.java 10 Jul 2009 07:50:54 -0000 1.3 >+++ src/org/eclipse/net4j/util/concurrent/IRWLockManager.java 30 Nov 2009 20:08:53 -0000 >@@ -49,6 +49,31 @@ > public boolean hasLockByOthers(LockType type, V context, K objectToLock); > > /** >+ * @author Juan Pedro Silva >+ */ >+ public void registerLockListeners(Collection<Object> collToRegister); >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void registerLockListener(Object listenerToRegister); >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void unRegisterLockListener(Object listenerToRegister); >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public void unRegisterLockListeners(Collection<Object> collToUnregister); >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public boolean hasListenerRegistered(); >+ >+ /** > * @author Simon McDuff > */ > public static enum LockType >#P org.eclipse.emf.cdo.ui >Index: src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java,v >retrieving revision 1.105 >diff -u -r1.105 CDOEditor.java >--- src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java 10 Nov 2009 09:23:36 -0000 1.105 >+++ src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java 30 Nov 2009 20:08:56 -0000 >@@ -1277,6 +1277,16 @@ > fireDirtyPropertyChange(); > } > }; >+ >+ /** >+ *@author Juan Pedro Silva >+ *@see I don't like this registration here. I rather have it under an option, which is the proper place. However, >+ * this is currently the way I'm using to be sure eventHandler's listeners have been registered. >+ *@TODO: Make the registration optional. >+ */ >+ CDOView lm = getView(); >+ lm.registerLockListeners(eventHandler.getLockListeners()); >+ > } > catch (RuntimeException ex) > { >Index: src/org/eclipse/emf/cdo/ui/CDOEventHandler.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOEventHandler.java,v >retrieving revision 1.17 >diff -u -r1.17 CDOEventHandler.java >--- src/org/eclipse/emf/cdo/ui/CDOEventHandler.java 31 Mar 2009 11:39:57 -0000 1.17 >+++ src/org/eclipse/emf/cdo/ui/CDOEventHandler.java 30 Nov 2009 20:08:57 -0000 >@@ -13,6 +13,7 @@ > package org.eclipse.emf.cdo.ui; > > import org.eclipse.emf.cdo.CDOObject; >+import org.eclipse.emf.cdo.common.id.CDOID; > import org.eclipse.emf.cdo.internal.ui.ItemsProcessor; > import org.eclipse.emf.cdo.internal.ui.bundle.OM; > import org.eclipse.emf.cdo.session.CDOSession; >@@ -21,6 +22,8 @@ > import org.eclipse.emf.cdo.transaction.CDOTransactionStartedEvent; > import org.eclipse.emf.cdo.view.CDOView; > import org.eclipse.emf.cdo.view.CDOViewInvalidationEvent; >+import org.eclipse.emf.cdo.view.RemoteLockAcquiredEvent; >+import org.eclipse.emf.cdo.view.RemoteLockReleasedEvent; > > import org.eclipse.net4j.util.container.IContainerDelta; > import org.eclipse.net4j.util.container.IContainerEvent; >@@ -36,6 +39,8 @@ > import org.eclipse.jface.viewers.TreeViewer; > import org.eclipse.ui.PlatformUI; > >+import java.util.ArrayList; >+import java.util.Collection; > import java.util.List; > import java.util.Set; > >@@ -321,4 +326,65 @@ > protected void viewClosed() > { > } >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ private IListener lockListener = new IListener() >+ { >+ public void notifyEvent(IEvent event) >+ { >+ if (event instanceof RemoteLockAcquiredEvent) >+ { >+ RemoteLockAcquiredEvent e = (RemoteLockAcquiredEvent)event; >+ System.err.println("RemoteLockAcquiredEvent received. LockType: " + e.getLockType()); >+ if (e.getUser() != null) >+ { >+ System.err.println("User: " + e.getUser()); >+ } >+ int i = 1; >+ for (CDOID ci : e.getCdoIds()) >+ { >+ System.err.println("CDOID: " + ci + " (" + i + ")."); >+ i++; >+ } >+ } >+ } >+ }; >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ private IListener unlockListener = new IListener() >+ { >+ public void notifyEvent(IEvent event) >+ { >+ if (event instanceof RemoteLockReleasedEvent) >+ { >+ RemoteLockReleasedEvent e = (RemoteLockReleasedEvent)event; >+ System.err.println("RemoteLockReleasedEvent received. LockType: " + e.getLockType()); >+ if (e.getUser() != null) >+ { >+ System.err.println("User: " + e.getUser()); >+ } >+ int i = 1; >+ for (CDOID ci : e.getCdoIds()) >+ { >+ System.err.println("CDOID: " + ci + " (" + i + ")."); >+ i++; >+ } >+ } >+ } >+ }; >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public Collection<IListener> getLockListeners() >+ { >+ ArrayList<IListener> ail = new ArrayList<IListener>(); >+ ail.add(lockListener); >+ ail.add(unlockListener); >+ return ail; >+ } > } >#P org.eclipse.emf.cdo.server.net4j >Index: src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java,v >retrieving revision 1.11 >diff -u -r1.11 CDOServerProtocol.java >--- src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java 3 Aug 2009 16:47:59 -0000 1.11 >+++ src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java 30 Nov 2009 20:08:58 -0000 >@@ -30,10 +30,12 @@ > import org.eclipse.net4j.channel.IChannel; > import org.eclipse.net4j.signal.SignalProtocol; > import org.eclipse.net4j.signal.SignalReactor; >+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType; > import org.eclipse.net4j.util.io.StringCompressor; > import org.eclipse.net4j.util.io.StringIO; > import org.eclipse.net4j.util.lifecycle.LifecycleUtil; > >+import java.util.Collection; > import java.util.List; > > /** >@@ -233,8 +235,42 @@ > case CDOProtocolConstants.SIGNAL_REMOTE_MESSAGE: > return new RemoteMessageIndication(this); > >+ /** >+ * @author Juan Pedro Silva >+ */ >+ case CDOProtocolConstants.SIGNAL_REGISTER_LOCK_LISTENER: >+ return new RegisterLockListenerIndication(this); >+ >+ case CDOProtocolConstants.SIGNAL_UNREGISTER_LOCK_LISTENER: >+ return new UnregisterLockListenerIndication(this); >+ > default: > return super.createSignalReactor(signalID); > } > } >+ >+ /** >+ * @author Juan Pedro Silva True = Lock, false = Unlock >+ * @param lock >+ * True = Lock, false = Unlock >+ */ >+ public void sendRemoteLockNotification(boolean b, String user, Collection<CDOID> cdoids, LockType lockType) >+ { >+ try >+ { >+ IChannel channel = getChannel(); >+ if (LifecycleUtil.isActive(channel)) >+ { >+ new RemoteLockChangedNotificationRequest(channel, b, user, cdoids, lockType).sendAsync(); >+ } >+ else >+ { >+ OM.LOG.warn("Session channel is inactive: " + this); //$NON-NLS-1$ >+ } >+ } >+ catch (Exception ex) >+ { >+ OM.LOG.error(ex); >+ } >+ } > } >Index: src/org/eclipse/emf/cdo/server/internal/net4j/protocol/UnregisterLockListenerIndication.java >=================================================================== >RCS file: src/org/eclipse/emf/cdo/server/internal/net4j/protocol/UnregisterLockListenerIndication.java >diff -N src/org/eclipse/emf/cdo/server/internal/net4j/protocol/UnregisterLockListenerIndication.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/emf/cdo/server/internal/net4j/protocol/UnregisterLockListenerIndication.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,51 @@ >+/** >+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * Eike Stepper - initial API and implementation >+ */ >+package org.eclipse.emf.cdo.server.internal.net4j.protocol; >+ >+import org.eclipse.emf.cdo.common.io.CDODataInput; >+import org.eclipse.emf.cdo.common.io.CDODataOutput; >+import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; >+import org.eclipse.emf.cdo.server.internal.net4j.bundle.OM; >+ >+import org.eclipse.net4j.util.om.trace.ContextTracer; >+ >+import java.io.IOException; >+ >+/** >+ * @author Juan Pedro Silva >+ */ >+public class UnregisterLockListenerIndication extends CDOReadIndication >+{ >+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, >+ UnregisterLockListenerIndication.class); >+ >+ public UnregisterLockListenerIndication(CDOServerProtocol protocol) >+ { >+ super(protocol, CDOProtocolConstants.SIGNAL_UNREGISTER_LOCK_LISTENER); >+ } >+ >+ @Override >+ protected void indicating(CDODataInput in) throws IOException >+ { >+ if (TRACER.isEnabled()) >+ { >+ TRACER.trace("Unregistering Lock Listener"); //$NON-NLS-1$ >+ } >+ >+ getRepository().getLockManager().unRegisterLockListener(getSession()); >+ } >+ >+ @Override >+ protected void responding(CDODataOutput out) throws IOException >+ { >+ out.writeBoolean(true); >+ } >+} >Index: src/org/eclipse/emf/cdo/server/internal/net4j/protocol/RemoteLockChangedNotificationRequest.java >=================================================================== >RCS file: src/org/eclipse/emf/cdo/server/internal/net4j/protocol/RemoteLockChangedNotificationRequest.java >diff -N src/org/eclipse/emf/cdo/server/internal/net4j/protocol/RemoteLockChangedNotificationRequest.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/emf/cdo/server/internal/net4j/protocol/RemoteLockChangedNotificationRequest.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,83 @@ >+/** >+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * Eike Stepper - initial API and implementation >+ */ >+package org.eclipse.emf.cdo.server.internal.net4j.protocol; >+ >+import org.eclipse.emf.cdo.common.id.CDOID; >+import org.eclipse.emf.cdo.common.io.CDODataOutput; >+import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; >+import org.eclipse.emf.cdo.server.internal.net4j.bundle.OM; >+ >+import org.eclipse.net4j.channel.IChannel; >+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType; >+import org.eclipse.net4j.util.om.trace.ContextTracer; >+ >+import java.io.IOException; >+import java.util.Collection; >+ >+/** >+ * @author Juan Pedro Silva >+ */ >+public class RemoteLockChangedNotificationRequest extends CDOServerRequest >+{ >+ >+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, >+ RemoteLockChangedNotificationRequest.class); >+ >+ private long timeStamp; >+ >+ private Collection<CDOID> lockedObjects; >+ >+ private LockType lockType; >+ >+ private String userID; >+ >+ private boolean lock; >+ >+ public RemoteLockChangedNotificationRequest(IChannel channel, boolean lock, String userID, Collection<CDOID> cdoids, >+ LockType lockType) >+ { >+ super(channel, CDOProtocolConstants.SIGNAL_REMOTE_LOCK_CHANGED_NOTIFICATION); >+ timeStamp = System.currentTimeMillis(); >+ this.userID = userID; >+ this.lock = lock; >+ lockedObjects = cdoids; >+ this.lockType = lockType; >+ } >+ >+ @Override >+ protected void requesting(CDODataOutput out) throws IOException >+ { >+ if (TRACER.isEnabled()) >+ { >+ TRACER.format("Writing timeStamp: {0,date} {0,time}", timeStamp); //$NON-NLS-1$ >+ } >+ >+ out.writeLong(timeStamp); >+ if (TRACER.isEnabled()) >+ { >+ TRACER.format("Writing {0} locked IDs", lockedObjects.size()); //$NON-NLS-1$ >+ } >+ >+ out.writeInt(lockedObjects == null ? 0 : lockedObjects.size()); >+ for (CDOID id : lockedObjects) >+ { >+ if (TRACER.isEnabled()) >+ { >+ TRACER.format("Writing locked ID: {0}", id); //$NON-NLS-1$ >+ } >+ out.writeCDOID(id); >+ } >+ out.writeBoolean(lock); >+ out.writeCDOLockType(lockType); >+ out.writeString(userID); >+ } >+ >+} >Index: src/org/eclipse/emf/cdo/server/internal/net4j/protocol/RegisterLockListenerIndication.java >=================================================================== >RCS file: src/org/eclipse/emf/cdo/server/internal/net4j/protocol/RegisterLockListenerIndication.java >diff -N src/org/eclipse/emf/cdo/server/internal/net4j/protocol/RegisterLockListenerIndication.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/emf/cdo/server/internal/net4j/protocol/RegisterLockListenerIndication.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,50 @@ >+/** >+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * Eike Stepper - initial API and implementation >+ */ >+package org.eclipse.emf.cdo.server.internal.net4j.protocol; >+ >+import org.eclipse.emf.cdo.common.io.CDODataInput; >+import org.eclipse.emf.cdo.common.io.CDODataOutput; >+import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; >+import org.eclipse.emf.cdo.server.internal.net4j.bundle.OM; >+ >+import org.eclipse.net4j.util.om.trace.ContextTracer; >+ >+import java.io.IOException; >+ >+/** >+ * @author Juan Pedro Silva >+ */ >+public class RegisterLockListenerIndication extends CDOReadIndication >+{ >+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, RegisterLockListenerIndication.class); >+ >+ public RegisterLockListenerIndication(CDOServerProtocol protocol) >+ { >+ super(protocol, CDOProtocolConstants.SIGNAL_REGISTER_LOCK_LISTENER); >+ } >+ >+ @Override >+ protected void indicating(CDODataInput in) throws IOException >+ { >+ if (TRACER.isEnabled()) >+ { >+ TRACER.trace("Registering Lock Listener"); //$NON-NLS-1$ >+ } >+ >+ getRepository().getLockManager().registerLockListener(getSession()); >+ } >+ >+ @Override >+ protected void responding(CDODataOutput out) throws IOException >+ { >+ out.writeBoolean(true); >+ } >+} >#P org.eclipse.emf.cdo.common >Index: src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java,v >retrieving revision 1.15 >diff -u -r1.15 CDOProtocolConstants.java >--- src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java 27 Jul 2009 07:09:40 -0000 1.15 >+++ src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java 30 Nov 2009 20:08:59 -0000 >@@ -92,6 +92,18 @@ > public static final short SIGNAL_REMOTE_SESSION_NOTIFICATION = 32; > > // ////////////////////////////////////////////////////////////////////// >+ // Lock Notification >+ >+ /** >+ * @author Juan Pedro Silva >+ */ >+ public static final short SIGNAL_REGISTER_LOCK_LISTENER = 35; >+ >+ public static final short SIGNAL_UNREGISTER_LOCK_LISTENER = 36; >+ >+ public static final short SIGNAL_REMOTE_LOCK_CHANGED_NOTIFICATION = 37; >+ >+ // ////////////////////////////////////////////////////////////////////// > // Session Management > > public static final int ERROR_REPOSITORY_NOT_FOUND = -1;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 283274
:
151848
|
151850
|
152326
| 153394