Skip to content

Posts from the ‘Eclipse FAQ’ Category

8
Jun

Following Eclipse Milestones

With the Galileo Release coming up, you might find yourself having a hard time updating to the latest milestones AND keeping your favorite plug-ins up-to-date.

Did you know that you can migrate your additional plug-ins from one Eclipse install to another one? This can be a huge time-saver, especially for people who like to live on the bleeding edge.

Here's how:

  1. Install a fresh copy of Eclipse. Let's assume you install Eclipse 3.5 RC4 Cocoa 64bit (you're feeling lucky)
  2. Let's further assume you've got an existing install of Eclipse 3.5 RC3 Cocoa 32bit with some additional plug-ins, like FindBugs, WindowBuilder Pro, etc.
  3. After installing, start your newly installed instance of Eclipse
  4. Select Help -> Install New Software...
  5. In the Install dialog, click the Add... button to add a new update site:
    Eclipse Install Dialog

  6. In the next dialog, click on Local... to add a local update site:
    Eclipse: Add Site

  7. using the file chooser, browse to <path_to_your_OLD_eclipse_instance>/eclipse/p2/org.eclipse.equinox.p2.engine/profileRegistry/SDKProfile.profile/ and click Choose to select that directory.
  8. Click OK to add the update site:
    Eclipse: Add Local Update Site

  9. The Install dialog will now list all plug-ins installed in the old location (i.e. your old Eclipse instance), clearly highlighting the ones that are not already installed in the new instance:
    Eclipse: Install from existing Eclipse install

  10. Check all features that you want to transport to the new location and continue the installation by clicking Next>.
  11. After confirming the license terms and clicking Finish, Eclipse will install the selected features from the old location into the new location. After the obligatory workbench restart you're good to go.

The only thing that I am wondering about is: why is there no first-class UI action (e.g. an import wizard) to do this?

5
May

Advanced WikiText

In my recent posting, I showed you how to use Mylyn WikiText to easily create documentation for your project.

In this installment, we're going to look at four things:

  1. How to create PDFs
  2. How to automate your publishing process
  3. How to split your documents to facilitate team work
  4. How to use DocBook as an intermediary format to add even more flexibility to your publishing process

Lots of stuff, so let's get started!

How to create PDFs

The WikiText documentation states you can create DocBook, HTML and Eclipse Help from Wiki markup. So, how to create PDFs? Well, there are many ways to create PDFs. If you just want to create PDFs inside the IDE, you can download the Textile-J PDF add-on for WikiText. Textile-J is the predecessor of WikiText. The reason why the PDF output is not included in WikiText is that some of the required frameworks need to transform to PDF are not yet IP-approved (see bug 258349 for more information).

To install the Textile-J PDF add-on, proceed as follows:

  1. Make sure you have WikiText 1.1.0 or better installed
  2. Add the Textile-J update site to your Update Manager: https://textile-j.dev.java.net/builds/wikitext/site
  3. Refresh the Update Manager. You should now see Textile-J WikiText PDF in the list of available features.
  4. Select Textile-J WikiText PDF and click Install
  5. Restart Eclipse as requested

You can now right-click on any wiki file (*.textile, *.mediawiki, *.confluence, *.twiki, *.tracwiki and select Textile-J -> Generate PDF from the context menu.

How to automate the process

If you want to create PDFs outside the IDE (e.g. on your CI server using ANT), you need to create a build file:

<project name="how-to-use-wikitext" default="wikitext2pdf" basedir=".">
<property name="wikitext.standalone" value="lib"/><!-- path to wikitext standalone package -->
<path id="wikitext.classpath">
<fileset dir="${wikitext.standalone}">
<include name="org.eclipse.mylyn.wikitext.*core*.jar"/>
<include name="net.java.dev.textilej.wikitext.*core*.jar"/>
<include name="net.java.dev.textilej.wikitext.*lib*.jar"/>
</fileset>
</path>
<taskdef classpathref="wikitext.classpath"
        resource="org/eclipse/mylyn/wikitext/core/util/anttask/tasks.properties" />
<taskdef classpathref="wikitext.classpath"
        resource="net/java/dev/textilej/wikitext/pdf/core/util/anttask/tasks.properties" />
<target name="wikitext2pdf" description="Generate PDF from textile">
<wikitext-to-pdf markupLanguage="Textile">
<fileset dir="${basedir}">
<include name="documentation.textile"/>
</fileset>
</wikitext-to-pdf>
</target>
</project>

By the way, there are ANT tasks for all other output formats as well, so you can automate the creation of Eclipse Help, HTML and DocBook, too:

<wikitext-to-docbook markupLanguage="Textile">
<fileset dir="${basedir}">
<include name="documentation.textile"/>
</fileset>
</wikitext-to-docbook>

How to split your documents to facilitate team work

Now that you know how to transform Wiki markup to various output formats, you might wonder how to split your Wiki files into smaller chunks so the members of your team can work on them separately. This is something which is very easy with, say, LaTeX or DocBook because they both have the concept of importing other documents. In Wikis, there usually is no such thing as importing another Wiki page - you rather link to that other page. If you're writing a documentation, this isn't sufficient, however. You really need to be able to import document fragments.

Instead of adding the notion of imports to WikiText, I decided to control the assembling of the master document by using a little bit of ANT wizardry and a text file.

The text file (named index.txt controls the order in which the document fragments ned to be glued together:

introduction.textile
grammar_language.textile
newnoteworthy.textile

The build.xml now needs to be enhanced so that it reads the control file and use this information to assemble the Wiki files in the order requested:

<target name="assemble">
<loadfile srcfile="doc/index.txt" property="inputfiles">
<filterchain>
<tokenfilter>
<replacestring from="\n" to=","/>
</tokenfilter>
</filterchain>
</loadfile>
<concat destfile="documentation.textile" append="false" fixlastline="yes">
<filelist dir="doc" files="${inputfiles}"/>
</concat>
</target>

So what happens here is that we read in the contents of the index.txt file, concatenate all file names, separated with a comma to one large line and feed that large line into the concatenate task that will then concatenate the contents of all those files in the given order so we get one big file.

After that, the big file can now be processed as usual:

<target name="generate-pdf" depends="assemble" description="Generate PDF from textile">
<wikitext-to-pdf markupLanguage="Textile">
<fileset dir="${basedir}">
<include name="documentation.textile"/>
</fileset>
</wikitext-to-pdf>
</target>

How to use DocBook to gain more flexibility

DocBook has been around for quite some years now and together with LaTeX still will give you the most flexibility when it comes to documentation engineering. I have been using both LaTeX and DocBook to write all sorts of documentation, ranging from my diploma thesis to open source project documentation and have found both the be versatile and reliable, but also quite verbose. Regarding flexibility, both give you the possibility to choose a document template / style of your liking. If none of the existing document styles match your needs, you can more or less easily create you own.

As WikiText supports creating DocBook from your Wiki files, we'll have a look at how to use this DocBook output to further process it. Here is what we need to do:

  1. Enhance our build script so it downloads the relevant DocBook files (libraries, basic styles and XSL transformations)
  2. Add targets to our build script that allow you to choose the output to be created: PDF, HTML or Eclipse Help

The whole process will look like this:

WikiTextDocBook ToolChain

Let's have a look at some crucial parts of the script.

We already saw how to assemble multiple Wiki files into one big Wiki file. The next step is to convert this file to DocBook:

<target name="wikitext2docbook" depends="assemble" description="Generate DocBook from textile">
<wikitext-to-docbook markupLanguage="Textile">
<fileset dir="${basedir}">
<include name="documentation.textile"/>
</fileset>
</wikitext-to-docbook>
</target>

After that, we need to convert the DocBook file to PDF:

<target name="docbook2pdf">
<echo>Converting article to PDF...</echo>
<delete file="${dest.dir}${file.separator}${documenat.name}.pdf"/>
<delete file="${dest.dir}${file.separator}${documenat.name}.fo"/>
<xslt in="${documenat.name}.xml"
        extension="xml"
        out="${dest.dir}${file.separator}${documenat.name}.fo"
        style="${document.stylesheet}">
<factory name="org.apache.xalan.processor.TransformerFactoryImpl">
<attribute name="http://xml.apache.org/xalan/features/optimize" value="true"/>
</factory>
<xmlcatalog>
<entity
                publicId="docbook.xsl"
                location="${docbook.dir}${file.separator}fo${file.separator}docbook.xsl"/>
</xmlcatalog>
<param name="generate.toc" expression="book toc" />
<param name="show.comments" expression="0" />
<param name="header.rule" expression="1" />
<param name="admon.graphics.extension" expression=".gif"/>
<param name="admon.textlabel" expression="0"/>
<param name="admon.graphics" expression="1"/>
</xslt>
<docbook2pdf
        source="${dest.dir}${file.separator}${documenat.name}.fo"
        target="${dest.dir}${file.separator}${documenat.name}.pdf"/>
<delete file="${dest.dir}${file.separator}${documenat.name}.fo" />
</target>

You can now control the output by supplying different stylesheets. DocBook XSLT comes with a variety of stylesheets for articles, books and online help systems. You can now easily create printed documentation AND online help from one source. DocBook XSLT supports EclipseHelp, JavaHelp, HTMLHelp (the Windows Help System) and even man pages!

So, next time you need to write documentation for a project you're working on, don't let it get you down. Instead, set up a trusty WikiText / DocBook toolchain and write down that documentation in Wiki markup in no time!

The whole build script and the sample document are available for download for free. If you need help setting up a tool chain or want to book me for consulting, drop me a line (peter dot friese at itemis dot com).

Many thanks to David Green and Steffen Pingel of WikiText and Mylyn who tirelessly fixed bugs I found, applied patches and created EA builds!

23
Apr

Getting started with WikiText

Documentation is the bane of all developers. Nobody likes to write documentation, but most people know we need it. Even more so in Open Source projects. If you don't have a decent documentation, it will be hard to find contributors which will eventually stall the projects ability to acquire new committers.

While documenting code is discussed quite controversial (see here, here, here and here), most people seem at least to agree that a high level documentation outlining the concepts of the software in question is appropriate.

The options to write high-level documentation are:

  1. Word processors like Word, OpenOffice, Pages and the like
  2. LaTeX
  3. DocBook
  4. Wikis

Using word processors for writing high-level documentation has serious drawbacks, especially when a whole team needs to contribute to the documentation. Do you remember master documents?

LaTeX is a great alternative, as it allows us to split documentation across several text files - this allows for efficient team work. Moreover, text files just cannot break and can be versioned / merged / diffed quite easily. However, LaTeX syntax is not for the faint of heart.

DocBook is great, too: it uses XML to describe documents and has a great number of transformations to about every output format you could think of (PDF, HTML, EclipseHelp, HTML Help, JavaHelp and even man pages! However, not everybody likes XML and in fact DocBook tends to be a little noisy.

So this leaves us with Wikis. They are great in many regards: you can write your documentation online, most wikis support versioning and diffing to a certain degree and most wikis have a decent collision detection that helps to work on documentation collaboratively. Thanks to offline Wiki editors for IDEs, we can even store wiki documents in local files.

Enter WikiText

WikiText is such a tool. It actually is very flexible, as it allows you to use a multitude of wiki dialects to write your documentation. It also supports a number of output formats (HTML, Eclipse Help, DITA, DocBook and FOP). What's more, it features a really nice text editor that can display Wiki markup almost in a WYSIWYG fashion. WikiText is developed and maintained by David Green.

So, without further ado, here is a quick introduction on how to install WikiText, writing your first document and transforming it to HTML.

Installing

Make sure you have a recent version of Eclipse installed. Then:

  1. Point your update manager (Help -> Install new software) to the Mylyn Update Site (http://download.eclipse.org/tools/mylyn/update/weekly/e3.4)
  2. Select the most recent version of Mylyn WikiText (as of this writing, this is WikiText 1.1.0.I20090423-1700-e3x) and install

After the obligatory Eclipse restart, you can start using the WikiText editor.

Writing your first document

  1. Create a new project (File -> Project... -> General -> Project
  2. Create a new file. We will be using the Textile wiki syntax, so let's name it HelloWorld.textile
  3. Enter some text:
    h1(#id). An HTML first-level heading
    
    Textile syntax is really simple. You can _emphasize_ text or *emphasize it even more*.
    
    Scaled images:
    !{width: 50%}images/eiffelturm.jpg!
    
    Enumerations also are very easy:
    
    * An item in a bulleted (unordered) list
    * Another item in a bulleted list
    ** Second Level
    ** Second Level Items
    *** Third level
    
    # An item in an enumerated (ordered) list
    # Another item in an enumerated list
    ## Another level in an enumerated list 
    
    Let's have more headings:
    
    h2. An HTML second-level heading
    
    Here is a table:
    
    |_. Header |_. Header |_. Header |
    | Cell 1 | Cell 2 | Cell 3 |
    | Cell 1 | Cell 2 | Cell 3 |
    
    h2. An HTML third-level heading
    
    Here is some code:
    
    bc..
    package org.eclipse.workflow;
    
    public class Workflow {
    
    }
    
    p. Here is a plain old paragraph. It needs to start with "p." to mark the end of the code block above.
    
    h4. An HTML fourth-level heading
    
    Of course, we can also have hyperlinks: "Peter's homepage":http://www.peterfriese.de 
    
    h5. An HTML fifth-level heading
    
    h6. An HTML sixth-level heading
    		
  4. Create a new subfolder images and place an image in his folder. I used this one.

You can always switch over to the preview pane, but you will notice that the source editor already does a decent job at rendering the text in a kind of WYSIWYG manner:

WikiText markup and preview

Transforming your document to HTML

In order to convert your document to a nicely rendered HTML document, just right-click on HelloWorld.textile in the package explorer and select WikiText -> Generate HTML. This will create anew file HelloWorld.html in the same directory. Double-click it to open it with a browser:

HelloWorld.html

Automating, PDF, splitting documents,...

I hope I could whet your appetite. In the next installment, I am going to show you how to automate the process of transforming WikiText documents into output documents, how to create PDF (by way of exploiting DocBook) and how to split your documents into smaller chunks so you can work on them as a team. Stay tuned!

2
Apr

How Twitter solved my P2 problems during my lunch break

Today, I wanted to migrate from Eclipse 3.5M5 to Eclipse 3.6M6 (I know, it's a bit late for that already - but then, I had been busy with #eclipsecon and preparing the Stupid Modeling Talk during the past weeks).

As of course I've got quite a number of additional bundles installed (e.g., EMF, Window Builder, Mylyn, Xpand and Xtend), I wanted to re-use them. I recalled that a while back someone (probably Chris?) blogged that it basically is possible to use an existing Eclipse installation as a local update site. However, I couldn't find the blog posting describing how to do that.

Given the fact it was about lunch time, I decided to let the #wisecrowd figure out how to solve my problem. So I twittered "desperately looking for a hint how to use an existing Eclipse install as a P2 repo. Goal:transport features from my M5 install to a fresh M6".

So, during my lunch break, the wise crowd (Kai, Ekke, Boris and Paul) sent me their opinions on the matter:

How Twitter solved my P2 problem during my lunch break

At first, it seemed like there is no solution, but in the end Paul's tweet reveals the solution I was looking for:

Add eclipse/p2/org.eclipse.equinox.p2.engine/profileRegistry/SDKProfile.profile/ as a local update site.

All of you out there who still doubt the practical use of Twitter: you really should give it another try.

14
Mar

Using Teneo, EMF and Hibernate to update and query your data

Last week I showed you how to use Teneo, EMF and Hibernate to store your data in a database.

This week, we're going to have a look at how to update the data, add more records and how to query the database for information using HQL, the Hibernate Query Language.

If you haven't done so, you might consider taking last week's tutorial in order to get your environment set up and understand the basic concepts. If you're lazy, you can as well download the code of the tutorial to get started more quickly. It is available here.

As it turns out, in order to change anything in the library database, we must first fetch the to-be-changed data, so we need to have a look at querying first.

Retrieving and updating data
Let's assume we'd want to the update the number of pages in a book, because the new edition has an additional chapter.

  1. So, first of all we need to open a session and begin a transaction:
        {
            Session session = sessionFactory.openSession();
            session.beginTransaction();
  2. Next, let's create an HQL query. We want to find any books that are written by an author by the name "A. K. Dewdney" that contain "Omnibus" in their title.
            Query query = session.createQuery(
                "SELECT book from " +
                "    Book book, " +
                "    Writer writer " +
                "WHERE " +
                "    book.title like '%Turing Omnibus%' " +
                "AND " +
                "    writer.name = 'A. K. Dewdney'");
  3. We can now execute the query and display the results:
            List books = query.list();
            Book book = books.get(0);
            System.out.println(book.getTitle());
  4. Updating the page count is pretty obvious:
            book.setPages(520);
  5. Finally, don't forget to commit the transaction and close the session:
            session.getTransaction().commit();
            session.close();
        }

Adding data
Let's now assume we want to add more books (and authors) to the library.

  1. By now, you should be pretty familiar with the pattern of opening a new session:
        {
            Session session = sessionFactory.openSession();
            session.beginTransaction();
  2. As we want to add new items to the library, we need to retrieve the library instance first of all:
            Query query = session.createQuery("from Library");
            List libraries = query.list();
            Library library = libraries.get(0);
  3. Creating a new book and its author is easy, as we just have to use the API EMF so kindly generated for us:
            Writer writer = LibraryFactory.eINSTANCE.createWriter();
            writer.setName("J.R.R. Tolkien");
            Book book = LibraryFactory.eINSTANCE.createBook();
            book.setTitle("The Hobbit");
            book.setPages(320);
            book.setAuthor(writer);
            book.setCategory(BookCategory.MYSTERY);
            library.getBooks().add(book);
            library.getWriters().add(writer);
  4. Finally, commit the transaction and close the session:
            session.getTransaction().commit();
            session.close();
        }
6
Mar

Using Teneo and EMF to store your data

Most of you know that I am working as a committer for various Eclipse-related projects (such as Xtext, Xpand and the Modeling Workflow Engine). You might not know, however, that I also work as a consultant for itemis. On one of my recent consulting assignments in Ottawa, Canada, I was asked "How can we use EMF to store our data in a database?"

Well, it turns out EMF can help a long way to store data in a database. Here is how.
Prepare your development environment

  1. Get Eclipse 3.5 M5 (click here to download)
  2. Unpack and start Eclipse
  3. Bring up the "Install New Software" dialog (Help -> Install New Software)
  4. Select Teneo EMF Hibernate Runtime and Teneo EMF Hibernate SDK, version 1.0.3
  5. Cick Finish
  6. You most probably will be asked to restart Eclipse.

Create a target definition that includes Hibernate and HSQLDB
In order to keep things simple, we will store the data in an HSQLDB database. We will use the Hibernate OR Mapper to perform the mapping between your data objects and the database. As you might guess, quite a number of libraries will be involved to get the task accomplished. Instead of creating a bunch of plug-in projects containing the respective libraries, or - even worse - copying all libraries into our project, we'll set up a target definition. Target definitions help to maintain a common set of dependencies for all developers on a team, which is a Good Thing.

  1. Create a new project library.target (File -> New -> Project... -> General -> Project)
  2. Create three folders in this project: hibernate, dependencies, hsqldb
  3. Go to the SpringSource Bundle Repository and download the following OSGi bundles:
    file save in folder
    com.springsource.org.hibernate-3.2.6.ga.jar library.target/hibernate
    com.springsource.org.apache.commons.logging-1.1.1.jar library.target/dependencies
    com.springsource.org.dom4j-1.6.1.jar library.target/dependencies
    com.springsource.org.apache.commons.collections-3.2.0.jar library.target/dependencies
    com.springsource.javax.transaction-1.1.0.jar library.target/dependencies
    com.springsource.antlr-2.7.7.jar library.target/dependencies
    com.springsource.org.hsqldb-1.8.0.9.jar library.target/hsqldb
  4. Create a new target definition library.target in this project (File -> New -> Other... -> Plug-in Development -> Target Definition)
  5. Open the target definition and add the three directories to it's contents. As the GUI does not allow you to work with relative paths, you might consider to use a text editor to paste the following text:
    <?xml version="1.0" encoding="UTF-8"?>
    <?pde version="3.5"?>
    <target description="Teneo-related stuff, mostly Hibernate" name="Library Target Definition">
        <locations>
            <location path="${eclipse_home}" type="Profile"/>
            <location path="${workspace_loc}/library.target/hibernate" type="Directory"/>
            <location path="${workspace_loc}/library.target/dependencies" type="Directory"/>
            <location path="${workspace_loc}/library.target/hsqldb" type="Directory"/>
        </locations>
    </target>
  6. Open the target definition in the Target Definition Editor and click on the Set as Target Platform hyperlink in the upper right area. This will activate the target definition. All contained bundles are now available and can be referenced as dependencies.

Create a model for your data
The data model will be based on the well-known library tutorial that ships with EMF. If you are interested in a more in-depth look, I recommend taking this tutorial. However, to shortcut things, here is the ultra-slim version of the EMF-Tutorial:

  1. Download the Rose class model and save it on your computer
  2. Create a new EMF project (File -> New -> Other... -> Eclipse Modeling Framework -> EMF Project)
    • Project name: library
    • Model importer: Rose class model
    • Browse to the Rose class model library.mdl mentioned before
    • Click on Load to load the model
    • Click Next, then Finish
  3. In the library.genmodel editor, right-click on the Library node and select Generate Model Code

Create the library main application
In order to demonstrate how to use the data model and how to perform CRUD operations with your data, we will create a simple Java class. In the good spirit of encapsulation and components, we will create a new plug-in project to host this class:

  1. Create a new Plug-in project library.main (File -> New -> Project... -> Plug-in Project)
  2. Open the manifest and add the following dependencies:
    • library (this is the bundle which contains our data model)
    • org.eclipse.emf.teneo.hibernate
    • org.eclipse.emf.ecore.xmi
    • com.springsource.org.hibernate
    • com.springsource.org.apache.commons.logging
    • com.springsource.org.dom4j
    • com.springsource.org.apache.commons.collections
    • com.springsource.javax.transaction
    • com.springsource.antlr
    • com.springsource.org.hsqldb
  3. Create a new Hibernate configuration file hibernate.properties in library.main/src and paste the following lines:
    hibernate.connection.driver_class=org.hsqldb.jdbcDriver
    # use the following line to run the embedded db:
    # hibernate.connection.url=jdbc:hsqldb:file:/some/path/on/your/computer/dbname
    # the following line will connect to a standalone (local) DB server:
    hibernate.connection.url=jdbc:hsqldb:hsql://127.0.0.1/library
    hibernate.connection.username=sa
    hibernate.connection.password=
    hibernate.dialect=org.hibernate.dialect.HSQLDialect
    hibernate.hbm2ddl.auto=true

Implement the library main application
With all the boilerplate in place, we're finally ready to write some code. We will create a new class and add some code to create an author and his book and store both in a library.

  1. Create a new class LibraryDemo, making sure it has a main method
  2. In order to use Teneo to persist our data, we first need to create a datastore and register our model package with it:
        // create the data store
        String dataStoreName = "LibraryDataStore";
        HbDataStore dataStore = HbHelper.INSTANCE.createRegisterDataStore(dataStoreName);
    
        // register the model package with the data store
        dataStore.setEPackages(new EPackage[] { LibraryPackage.eINSTANCE });
    
        // initialize the data store, which creates the tables
        dataStore.initialize();
  3. Next, we need to get hold of a session factory and request a new session form it:
        SessionFactory sessionFactory = dataStore.getSessionFactory();
        {
            Session session = sessionFactory.openSession();
            session.beginTransaction();
  4. Now, let's create a new library and save it to the session:
            // create a library
            Library library = LibraryFactory.eINSTANCE.createLibrary();
            library.setName("Developer's bookshelf");
    
            // store the library
            session.save(library);
  5. In the following part, we will create an author and his book, link them to each other and add them to the library. There is no specific Teneo aspect to this part of the code, it is just straightforward usage of the API EMF generated for your datamodel:
            // create an author
            Writer writer = LibraryFactory.eINSTANCE.createWriter();
            writer.setName("A. K. Dewdney");
    
            // create a book
            Book book = LibraryFactory.eINSTANCE.createBook();
            book.setTitle("The New Turing Omnibus");
            book.setPages(480);
            book.setCategory(BookCategory.MYSTERY); // oh well, let's hope it's not mystery to most readers!
            book.setAuthor(writer);
    
            // add book and writer to library
            library.getBooks().add(book);
            library.getWriters().add(writer);
  6. Finally, we need to commit our changes to the database and close the session:
            // commit changes to the database and close the session
            session.getTransaction().commit();
            session.close();
        }

Start the DB server and run the application

  1. Open a command line and navigate to the directory that contains hsqldb.jar
  2. Start the HSQLDB server using this command line:
    java -cp com.springsource.org.hsqldb-1.8.0.9.jar org.hsqldb.Server -database.0 file:library -dbname.0 library
  3. Finally (!) go back to Eclipse and start LibraryDemo. You should get an output similar to this one:
    Mar 6, 2009 1:50:26 PM org.eclipse.emf.teneo.hibernate.HbHelper createRegisterDataStore
    INFO: Creating emf data store and registering it under name: LibraryDataStore
    ...
    Mar 6, 2009 1:50:28 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
    INFO: schema update complete
  4. To actually see the data stored in the database, navigate to the directory containing the database and open library.log:
    CREATE USER SA PASSWORD "" ADMIN
    /*C1*/SET SCHEMA PUBLIC
    CONNECT USER SA
    ...
    INSERT INTO "library" VALUES(1,'Library',0,'Developer''s bookshelf')
    INSERT INTO "writer" VALUES(1,'Writer',0,'A. K. Dewdney',NULL,NULL,'Library','1',-2)
    INSERT INTO "book" VALUES(1,'Book',0,'The New Turing Omnibus',480,'Mystery',1,NULL,NULL,'Library','1',-3)
    DELETE FROM "writer" WHERE E_ID=1
    INSERT INTO "writer" VALUES(1,'Writer',0,'A. K. Dewdney',1,0,'Library','1',-2)
    DELETE FROM "book" WHERE E_ID=1
    INSERT INTO "book" VALUES(1,'Book',0,'The New Turing Omnibus',480,'Mystery',1,1,0,'Library','1',-3)
    INSERT INTO "writer_books" VALUES(1,1,0)
    COMMIT
    DISCONNECT

In the next installment, I will show you how to retrieve objects from the database and query the database using Hibernate Query Language (HQL).

Download the source
If you are interested in the source for the solution so far, you can download it here: (click to download).

18
Dec

Using Safari to view the Eclipse Help System (when Safari is not your system default browser)

I belong to the minority of people who love the Opera Browser. You've got to try it, it has got all sorts of nice features - e.g. you can easily create keyword-driven search shortcuts or browse the web using mouse gestures. But I digress...

Of course, I configured Opera to be the default browser on my Mac. Which is nice for surfing the web. However, I do not want the Eclipse Help system to appear in Opera - mostly because I tend to have way too many tabs open anyway. So, I'd like to open Eclipse Help in Safari. Here's what you need to do to achieve this:

  1. In Eclipse, open the preference dialog
  2. Select General -> Web Browser
  3. Click New... to add a new external web browser
  4. In the dialog box Edit External Web Browser, fill in the following details:
    Edit External Web Browser

  5. Click Ok, then Finish

Obviously, this only works on Mac OS.

10
Mar

Editors: How to open an EClassifier in the ECore editor and selecting it

I am currently working on an ECore Type Lookup Dialog that lets you look up EClassifiers in the same fashion we know from the JDT Type Lookup Dialog and the PDE Artifact Lookup Dialog.

Creating the dialog is rather easy - you just need to subclass FilteredItemsSelectionDialog. I'll blog more on this topic soon. Today, however, I wanted to document a tidbit that is not so well documented: How do I open the default editor on an EClassifier and select the EClassifier as soon as the editor has appeared.

First of all, let's find out more about the EClassifier:

EObject eObject = (EObject) object;
URI uri = EcoreUtil.getURI(eObject);
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(uri.toPlatformString(true)));

Now that we know the URI of the object of desire and the file it resides in, we can browse the EditorRegistry for the default editor that has been registered for this particular file:

 
try {
    // open default editor
    Workbench workbench = PlatformUI.getWorkbench();
    EditorDescriptor editorDescriptor = workbench.getEditorRegistry().getDefaultEditor(file.getName());

Opening the editor is a no-brainer now:

 
    WorkbenchPage page = workbench.getActiveWorkbenchWindow().getActivePage();
    EcoreEditor ecoreEditor = (EcoreEditor) page.openEditor(new FileEditorInput(file), editorDescriptor.getId());

The hard part is how to select the EClassifier in the editor we just opened. The trick is to NOT just create an IStructuredSelection containing the EClassifier. You have to make sure you use the SAME EClassifier instance that is being shown in the editor. This can be ensured by retrieving the ECLassifier from the EditingDomain of the EcoreEditor:

 
    // set selection
    EditingDomain editingDomain = ecoreEditor.getEditingDomain();
    EObject editObject = editingDomain.getResourceSet().getEObject(uri, true);
    if (editObject != null) {
        ecoreEditor.setSelectionToViewer(Collections.singleton(editObject));
    }
} catch (PartInitException e) {
    Log.logError(e);
}

That's it. As with most things in EMF, the answer can be found by browsing the EMF source code and the code of the editors and other artifacts that it generates.

10
Oct

How to filter property pages according to the project nature

Often, you need to hide property pages if a project doesn't have a specific nature. Here's how you can do that:


<extension point="org.eclipse.ui.propertyPages">
<page adaptable="false"
class="org.andromda.android.ui.ideas.AndroidProjectPropertyPage"
id="org.andromda.android.ui.ideas.AndroidProjectPropertyPage"
name="Android Project Layout"
objectClass="org.eclipse.core.resources.IProject">
<filter name="nature"
value="org.andromda.android.core.androidnature"/>
</page>
</extension>

How does it work? In order to make this work, the class you register the property page for must implement IActionFilter. Projects do not implement IActionFilter, but there is a class WorkbenchProject that does so. This class is registered with the workbench adapter manager, so it will eventually be called (if no one else supplies a suitable adapter, that is) in order to find out whether the project has an attribute named nature whose value is org.andromda.android.core.androidnature. In order to resolve attributes, IActionFilter requires clients to implement the method public boolean testAttribute(Object target, String name, String value). Here is the implementation as supplied by WorkbenchProject:


public boolean testAttribute(Object target, String name, String value) {
IProject proj = (IProject) target;
if (name.equals(NATURE)) {
try {
return proj.isAccessible() && proj.hasNature(value);
} catch (CoreException e) {
return false;
}
} else if (name.equals(OPEN)) {
value = value.toLowerCase();
return (proj.isOpen() == value.equals("true"));//$NON-NLS-1$
}
return super.testAttribute(target, name, value);
}

As you can see, WorkbenchProject will check whether the underlying project has a certain nature.