Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » [CDO] Queries related to Standalone Client - Reg.(This question is related to the implementation of a Standalone Java Client (outside the Eclipse IDE) which makes use of CDO to store the models and retrieve it.)
[CDO] Queries related to Standalone Client - Reg. [message #1785992] Mon, 23 April 2018 22:51 Go to next message
Nirmal Kanagasabai is currently offline Nirmal KanagasabaiFriend
Messages: 8
Registered: January 2018
Junior Member
Hello Team,

We have built a stand-alone modelling application which is built on top of EMF. As the application doesn't run in Eclipse IDE, I, unfortunately, cannot take advantage of the amazing 'CDO Explorer' Perspective. I might have to implement them to suit our application.

I made use of the Standalone Java Client that you provided and understood the working methodology. I thought I just had to get the resource from the repository and load it into my application.

When you said, 'the changes are automatically reflected in all the clients', I was able to visualize them in CDO Explorer. But, the question is, how does this happen when we are having a stand-alone application?

I also came across this interesting resource while reading about it:

As it was quoted by you in this video @ 21:15,

Instead of opening a new CDO Session, you ask us to do the following:

1) From the View of an input object, we have to retrieve the underlying session.
2) From there, we need to open a new transaction.
3) Using the transaction, we have to get a transactional version of the object.

I am extremely sorry if the question sounds silly. Being a newbie, I am lost mid-way reading about this and I am unable to go ahead.

Does this mean, I have to load the model differently from the database instead of transaction.getResource(path/to/the/resource)?

I will be extremely glad if you can help me out on this regard.
Re: [CDO] Queries related to Standalone Client - Reg. [message #1786000 is a reply to message #1785992] Tue, 24 April 2018 03:56 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6682
Registered: July 2009
Senior Member
Hi Nirmal,

The CDO core is indeed mostly independent of the OSGi and Eclipse cores. The main difference of a stand-alone application is that you're required to prepare CDO's IManagedContainer manually, while in Eclipse that's done through the extension registry. Here's a small example:

public class StandaloneContainerExample
{
  public static void main(String[] args) throws CommitException
  {
    // Enable logging and tracing
    OMPlatform.INSTANCE.setDebugging(true);
    OMPlatform.INSTANCE.addLogHandler(PrintLogHandler.CONSOLE);
    OMPlatform.INSTANCE.addTraceHandler(PrintTraceHandler.CONSOLE);

    // Prepare container
    IManagedContainer container = ContainerUtil.createContainer();
    Net4jUtil.prepareContainer(container); // Register Net4j factories
    TCPUtil.prepareContainer(container); // Register TCP factories
    CDONet4jUtil.prepareContainer(container); // Register CDO factories
    container.activate();

    // Create connector
    IConnector connector = TCPUtil.getConnector(container, "localhost:2036"); //$NON-NLS-1$

    // Create configuration
    CDONet4jSessionConfiguration configuration = CDONet4jUtil.createNet4jSessionConfiguration();
    configuration.setConnector(connector);
    configuration.setRepositoryName("repo1"); //$NON-NLS-1$

    // Open session
    CDOSession session = configuration.openNet4jSession();
    session.getPackageRegistry().putEPackage(CompanyPackage.eINSTANCE);

    // Open transaction
    CDOTransaction transaction = session.openTransaction();

    // Get or create resource
    CDOResource resource = transaction.getOrCreateResource("/path/to/my/resource"); //$NON-NLS-1$

    // Work with the resource and commit the transaction
    EObject object = CompanyFactory.eINSTANCE.createCompany();
    resource.getContents().add(object);
    transaction.commit();

    // Cleanup
    session.close();
    connector.close();
    container.deactivate();
  }
}


Instead of creating your own container I recommend to use IPluginContainer.INSTANCE.

The model objects that are loaded through a CDO view or transaction will always be automatically updated to reflect the current remote version. A user interface, no matter what UI technology is used, is notified about these updates through a number of mechanisms:

  1. EMF Notifications that are delivered to the Adapters that you attached to your model objects. This is the standard mechanism, which also works well with your generated item providers, which you can use independent of a specific UI technology.
  2. CDOSessionInvalidationEvents that are sent to the IListeners that you added to your CDOSession.
  3. CDOViewInvalidationEvents that are sent to the IListeners that you added to your CDOView or CDOTransaction.


Regarding the "global read-only view and multiple transactional background actions" pattern that I mentioned in the video, there's a class in CDO that nicely demonstrates what it means:

public abstract class TransactionalBackgroundAction extends LongRunningAction
{
  private final CDOObject object;

  public TransactionalBackgroundAction(IWorkbenchPage page, String text, String toolTipText, ImageDescriptor image, CDOObject object)
  {
    super(page, text, toolTipText, image);
    this.object = object;
  }

  public final CDOObject getObject()
  {
    return object;
  }

  protected CDOTransaction openTransaction(CDOObject object)
  {
    CDOView view = object.cdoView();
    CDOTransaction transaction = view.getSession().openTransaction(view.getBranch());
    CDOUtil.configureView(transaction);
    return transaction;
  }

  @Override
  protected final void doRun(IProgressMonitor progressMonitor) throws Exception
  {
    progressMonitor.beginTask(Messages.getString("TransactionalBackgroundAction_1"), 100); //$NON-NLS-1$

    CDOTransaction transaction = openTransaction(object);
    CDOObject transactionalObject = null;
    CDOCommitInfo commitInfo = null;

    try
    {
      transactionalObject = transaction.getObject(object);
      progressMonitor.worked(5);

      doRun(transaction, transactionalObject, new SubProgressMonitor(progressMonitor, 5));
      commitInfo = transaction.commit(new SubProgressMonitor(progressMonitor, 90));
    }
    finally
    {
      progressMonitor.done();
      transaction.close();
      transactionalObject = null;
    }

    if (commitInfo != null)
    {
      CDOView view = object.cdoView();
      view.waitForUpdate(commitInfo.getTimeStamp(), 5000);
      postRun(view, object);
    }
  }

  protected abstract void doRun(CDOTransaction transaction, CDOObject object, IProgressMonitor progressMonitor) throws Exception;

  protected void postRun(CDOView view, CDOObject object)
  {
  }
}


I think it's self-explanatory. If not, don't hesitate to ask ;-)

Cheers
/Eike


Re: [CDO] Queries related to Standalone Client - Reg. [message #1786052 is a reply to message #1786000] Tue, 24 April 2018 21:57 Go to previous messageGo to next message
Nirmal Kanagasabai is currently offline Nirmal KanagasabaiFriend
Messages: 8
Registered: January 2018
Junior Member
Thank you very much Eike. I will look into your valuable suggestions and incorporate them accordingly. I will get back to you in case I have any further queries.

Re: [CDO] Queries related to Standalone Client - Reg. [message #1792234 is a reply to message #1786052] Fri, 13 July 2018 05:51 Go to previous messageGo to next message
Nirmal Kanagasabai is currently offline Nirmal KanagasabaiFriend
Messages: 8
Registered: January 2018
Junior Member
Hello Eike,

I am back with some more questions on the notification of remote changes. From all the posts I came across in the forum and your response to my previous query, I realize that the 3 ways to go about are CDOSessionInvalidationEvent, CDOViewInvalidationEvent, and EMFNotification.

However, I am totally confused as to how I implement it in my application. Can you please offer sample snippets where a CDOSessionInvalidationEvent / CDOViewInvalidationEvent is dealt with like the way you did for Stand-alone client? That would help a newbie like me big time.

Also, the application that we currently have makes use of the standard EMF notifications. There are adapters that are attached to the model objects. Right now, I am able to persist and load model objects onto my standalone Java application (client). When two instances (of our application) are running and say, I add a class in one of the instances, I do not see any change happening in the other client. When I re-load the model, I find the changes in there. I understand that I am missing something but I ain't sure of what it is. Changes happening locally in the client works without any hassle.

I humbly request you to help me out on this regard.

Re: [CDO] Queries related to Standalone Client - Reg. [message #1792254 is a reply to message #1792234] Fri, 13 July 2018 09:45 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6682
Registered: July 2009
Senior Member
IMO there are only rare occasions where a CDOSessionInvalidationEvent listener would make sense. An example of a CDOViewInvalidationEvent listener can be found in org.eclipse.emf.cdo.ui.CDOEventHandler.viewListener.

To check whether and what events occur in your second client you can temporarily add this code:

transaction.getSession().addListener(new org.eclipse.net4j.util.event.EventPrinter());
transaction.addListener(new org.eclipse.net4j.util.event.EventPrinter());


Can you see invalidation events in the console now? If you see the events occuring, but your EMF adapters aren't notified, you can try one of the following:

1. session.options().setPassiveUpdateMode(PassiveUpdateMode.CHANGES);
2. transaction.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL);

Does that make any difference?


Re: [CDO] Queries related to Standalone Client - Reg. [message #1792278 is a reply to message #1792254] Fri, 13 July 2018 19:38 Go to previous messageGo to next message
Nirmal Kanagasabai is currently offline Nirmal KanagasabaiFriend
Messages: 8
Registered: January 2018
Junior Member
Hello Eike,

Thank you very much for your quick reply. I included the code snippet that you have mentioned above. Here's what I receive in my console:

P.S.: There were several ContainerEvents, CDOSessionInvalidationEvents, CDOSessionLocksChangedEvent and CDOViewAdaptersNotifiedEvents. I removed them for the sake of clarity.

ContainerEvent[source=Session36 [repo1], ADDED=Transaction 35 [MAIN]]
CDOTransactionStartedEvent[source=Transaction 35 [MAIN]]
CDOTransactionFinishedEvent[source=Transaction 35 [MAIN], cause=COMMITTED, idMappings=0]
CDOSessionInvalidationEvent[CommitInfo[2018-07-13 15:23:20.287 (1531509800287), Branch[id=0, name=MAIN], null, null, null, CommitData[newPackageUnits=0, newObjects=14, changedObjects=1, detachedObjects=0]]]
CDOSessionLocksChangedEvent[source=Session36 [TouchCORE_Repo], sender=Transaction 35 [MAIN], null]
CDOViewAdaptersNotifiedEvent[source=Transaction 6 [MAIN], timeStamp=1531509800287]
CDOViewAdaptersNotifiedEvent[source=Transaction 7 [MAIN], timeStamp=1531509800287]
CDOViewAdaptersNotifiedEvent[source=Transaction 18 [MAIN], timeStamp=1531509800287]
CDOViewAdaptersNotifiedEvent[source=Transaction 31 [MAIN], timeStamp=1531509800287]
CDOViewAdaptersNotifiedEvent[source=Transaction 14 [MAIN], timeStamp=1531509800287]
CDOTransactionFinishedEvent[source=Transaction 35 [MAIN], cause=COMMITTED, idMappings=0]

It says that the CDOViewAdapters have been notified. Does this mean that I have missed something in my client implementation that, even after receiving the notifications, the changes aren't reflected?

Here's a small snippet from my application where one of the handlers that are responsible for creating a new class is handling the EMF notification.

        aspect.eAdapters().add(new EContentAdapter() {

            private Class clazz;

            @Override
            public void notifyChanged(Notification notification) {
                if (notification.getFeature() == eINSTANCE.getStructuralView_Classes()) {
                    if (notification.getEventType() == Notification.ADD) {
                        clazz = (Class) notification.getNewValue();
                    }
                } else if (notification.getFeature() == eINSTANCE.getContainerMap_Value()) {
                    if (notification.getEventType() == Notification.ADD) {
                        ((ClassView) view.getClassViewOf(clazz)).showKeyboard();
                        ((ClassView) view.getClassViewOf(clazz)).clearNameField();
                        aspect.eAdapters().remove(this);
                    }
                }
            }
        });



I would be extremely glad if you can explain what is expected from a client implementation's perspective? I am extremely sorry if this question sounds very silly.

[Updated on: Sat, 14 July 2018 03:32]

Report message to a moderator

Re: [CDO] Queries related to Standalone Client - Reg. [message #1792368 is a reply to message #1792278] Mon, 16 July 2018 13:38 Go to previous messageGo to next message
Nirmal Kanagasabai is currently offline Nirmal KanagasabaiFriend
Messages: 8
Registered: January 2018
Junior Member
Hello Eike,

Sorry to bother you again. I would be glad if you can let me know what I am missing from a client's perspective.
As the CDOViewAdapters are getting notified, do I have to write any logic so that the Adapters listens to what has been changed and update accordingly?

Re: [CDO] Queries related to Standalone Client - Reg. [message #1793008 is a reply to message #1792368] Fri, 27 July 2018 12:52 Go to previous message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6682
Registered: July 2009
Senior Member
Sorry for my late reply.

When you say "the changes aren't reflected" do you mean that the notifyChanged() method of your adapter isn't called at all? Or do you mean that your EObjects aren't updated by CDO to reflect the new remote state?


Previous Topic:Display item deletion impacts in an editor
Next Topic:[CDO] Inefficient SQL generated for CDORepository inserts/removes
Goto Forum:
  


Current Time: Tue Apr 16 09:10:16 GMT 2024

Powered by FUDForum. Page generated in 0.26087 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top