Integrating with EMF and Other Frameworks |
![]() |
CDO is an EMF persistence and collaboration layer. CDO model objects are still EMF EObjects, and CDO
resources still participate in EMF resource sets. The CDO-specific part is the context around
those objects: a session connects to a repository, a view defines the branch and
repository time that is visible, and a transaction supplies the writable view.
This chapter concentrates on integration mechanisms: resource sets, CDO URIs, view providers, EMF adapters and commands, and supported extension points. Session configuration, view semantics, transactions and notification details belong to Working with Sessions, Working with Views, Working with Transactions, and Notifications and Event Handling.
Table of Contents
Use generated EMF interfaces, EObject, Resource, ResourceSet, and
EcoreUtil with CDO objects where their contracts apply. A CDO object is not a
second, unrelated model type. It is an EMF object whose state is managed by a CDO view and backed by repository
revisions.
The important difference is context. A read-only view rejects mutations, a transaction records mutations until
commit or rollback, and a historical view exposes a different revision from a floating view. Objects can be loaded
lazily and can be invalidated by repository changes. Code that needs CDO-specific state can use
CDOUtil.getCDOObject(EObject) or CDOUtil.getView(Notifier); code that
only needs EMF behavior should remain expressed in EMF terms.
A view owns a CDO view set, and the view set owns exactly one ResourceSet. Obtain that resource set from
CDOView.getResourceSet() or pass an application-created resource set when opening the view. The same set
can contain ordinary EMF resources as well as CDO resources when the application has configured the corresponding
resource factories.
Loading through ResourceSet.getResource(URI, boolean) is the normal EMF integration point. For a resource
already associated with a view, CDOView.getResource(String) is also convenient. Do not mistake a resource
factory registration for opening a session: a connection, view, and repository context must still be supplied by a
directly opened view or by a matching view provider.
The resource set is an ownership boundary. Keep it alive while its CDO resources and objects are in use, and close the associated view or transaction before disposing the application component that owns the set. A resource that remains referenced after its view is closed is not a substitute for a live CDO view.
shows the direct pattern.
CDO has a canonical cdo://repositoryUUID/resource/path form and connection-aware forms such as cdo.net4j.tcp://host:2036/repository/resource/path. The canonical form identifies a repository by UUID and requires the resource set to be associated with a view that can resolve that repository. A connection-aware URI contains transport information and a repository name, so a matching built-in provider can open the session and view.
Connection-aware URIs can carry branch, time, transactional, and prefetch query parameters. A branch path is relative to the branch tree; time=HEAD denotes the floating current state; transactional=true requests a transaction and is not valid with a historical time. The current Net4j providers use the cdo.net4j.jvm, cdo.net4j.tcp, cdo.net4j.ssl, cdo.net4j.ws, and cdo.net4j.wss schemes.
Use CDOView.createResourceURI(String) when a view already exists. Use CDOURIData to inspect a
connection-aware URI and CDOURIUtil.extractResourcePath(URI) or CDOURIUtil.analyzePath(URI) to
normalize its resource path. Avoid hand-parsing authority and query strings, and do not introduce the deprecated
CDOURIUtil.createResourceURI(String, String) helpers into new code.
illustrates the public parser.
A CDOViewProvider adapts URI-driven EMF loading to CDO. When ResourceSet.getResource(URI, boolean)
encounters a URI, the CDOViewProviderRegistry selects matching providers by regular expression and priority.
The same selection can be requested explicitly with CDOViewProviderRegistry.provideView(URI, ResourceSet).
The selected provider returns a view associated with that resource set; the CDO resource factory then serves the
resource transparently to the EMF caller.
Built-in Net4j providers are contributed by the org.eclipse.emf.cdo.net4j plug-in. Applications should use them for the standard transport schemes and use a custom provider only when an application-specific URI scheme or repository selection policy is needed. A provider is an SPI implementation of a public interface, not a replacement for ordinary direct session and view APIs.
The registry reuses a view already present in the resource set's view set when possible. Otherwise the provider opens a view and the view set associates it with the resource set; the registry does not provide a general provider cache or transfer ownership of the session. The component that owns the view and session must close them, and must not keep using CDO resources after that lifecycle has ended.
uses an injected session so that the provider does
not hide connector and session configuration. The repository name is read from URI.authority(), without
retaining the leading colon. This corrects the former legacy provider pattern without reactivating that excluded
material.
Plug-in applications can contribute providers with the org.eclipse.emf.cdo.viewProviders extension point. Each viewProvider specifies a public implementation class, a URI regular expression, and an optional integer priority (default 500); higher priorities win when several providers match. The implementation must have a usable no-argument construction path for the extension mechanism. Programmatic registration is more suitable when the provider needs application-owned state such as an already configured session.
The extension point is declared by the CDO plug-in and its schema is schema/viewProviders.exsd. Keep the regular expression narrow enough not to capture another provider's URI space. Remove programmatically registered providers when the contributing component is disposed. Provider registration does not transfer ownership of a session, connector, view, or resource set.
Generated model APIs, EMF traversal, adapters, and utilities such as EcoreUtil
remain useful with CDO-backed objects. EMF Edit item-provider and command infrastructure can be used when the
relevant edit plug-ins and adapter factories are present. A command that mutates a CDO object must execute against
a writable CDO transaction, and the command stack's undo/redo history must not outlive the transaction context it
records.
CDO transactions are not EMF Transaction framework transactions. CDO does not require a special EditingDomain for normal client access, and an application must not assume that an EMF transactional editing domain supplies CDO commit, locking, conflict, or branch semantics. If an application uses a transactional editing framework, treat it as an additional coordination layer and verify its command and notification assumptions.
Serialization is also contextual: saving a CDO resource through its CDO resource implementation is not the same as serializing a detached object graph to an ordinary file. Use a CDO resource URI and its owning view when the intent is repository access; use ordinary EMF resources when the intent is a standalone interchange file.
Ordinary EMF adapters can be attached to CDO objects. CDO-specific adapters
and CDOAdapterPolicy change-subscription policies are available when an application needs selected remote
changes delivered to adapters. A policy controls subscription and delivery; it does not replace passive updates or
view invalidation.
Remove adapters and policies when the observing component is disposed. Do not infer that the repository is unchanged merely because an adapter did not receive a notification: objects may not be loaded or subscribed. For invalidation, subscription, and event ordering details, see Notifications and Event Handling.
An Eclipse editor or viewer can consume a CDO resource through the same EMF resource and adapter-factory contracts as other EMF resources. UI plug-ins may add selection, navigation, and editor integrations, but those facilities remain UI concerns and should not be confused with the core URI/provider mechanism described here.
CDO currently has no general-purpose adapter layer for arbitrary third-party frameworks. Integrate such a framework through its documented EMF APIs, provide the required adapter factories, and make its lifecycle follow the CDO view and resource-set lifecycle. Do not assume that a framework that accepts EMF objects also understands lazy loading, read-only views, invalidation, or CDO transactions without an integration-specific adapter.
Direct session/view APIs are the clearest choice when the application owns connection setup, view reuse, commits,
and shutdown. Use a view's resource set when an EMF-based component needs CDO resources while the application still
controls the view. Use URI and view-provider integration when a component naturally calls
ResourceSet.getResource(URI, boolean) and cannot be taught CDO session APIs; make the provider's session and
view ownership explicit.
Use adapters and listeners for observation, with the cleanup rules in Notifications and Event Handling. Use the extension point for plug-in-discoverable provider implementations and programmatic registration for application-scoped providers. In every case, close the views and sessions owned by the integration component, remove providers owned by that component, and keep resource sets and command stacks within the lifetime of their CDO view or transaction.