David Montag wrote:
Hi,
Wow, a lot of useful and interesting responses, thanks! I want to start
by clarifying that I'm not on your skill level (yet) when it comes to
these different technologies. But please bear with me, I'm learning new
> Congratulations on the summer gig. Just a few comments
> on top of Emmanuel's comments. I also agree with David's
> comments that working with Graphs is "The" challenge,
> although it's easy to understand that someone might want
> something very light weight that they can use to quickly
> persist an object to ADS. This would be a sub-use case
> of working with Graph's, so it's a good place to start experimenting.
I haven't actually got the gig yet :) I'm going to apply next week, and
then we'll see what happens. Hopefully I get it :) Ditto on the graph
stuff though.
Aha - Good luck in that case! I'm certain you'll land it.
I was not familiar with EMF, but after reading that introduction - which
by the way was really good - I think I got the basic concepts. By using
Ecore, one can create classes and objects, and persist them to - among
some formats - XMI, and vice versa.
Yes - You have this right. But let me elaborate with a concrete example on
top, just so that we cement it. This will also answer your questions below.
Suppose for example you could have an Ecore document that models an address
(Address.ecore). You might also have an XML Schema that models an address
(Address.xsd). You might even have a RDB schema that models an address
(Address.sql). All these models could be used to generate the corresponding
java code, which would be the java representation of the Address model. So if
we wanted to generate java from all of these models we would be doing:
Address.ecore > java
Address.xsd > java
Address.sql > java
The java result might be something like Address.java and Street.java, where
Street.java just has two primitives, name(String) and number (int), and the
Address.java has reference to Street (street), that is of type Street. So if
you create an Address instance manually like this:
(EMF API)
Address address = new AddressFactory.eINSTANCE.createAddress();
Street street = new AddressFactory.eINSTANCE.createStreet();
address.setStreet(street);
or
Plain old java:
Address address = new AddressImpl();
Street street = new StreetImpl();
address.setStreet(street);
Note that the address instance is now a Graph. It's a graph because address
has a reference to another object. If we had left street off of address, then
address would just be a single object. Now since the objects in this graph are
instances of EObject we can serialize them to XMI, or XML, or use the java
serialization format, and serialize the the way any java object instance would
be serialized.
EMF lets you control the serialization format in various ways, but with the LDAP DAS the primitives on the object are stored in the server using the corresponding ObjectClass definition (Which if it does not already exist, would be created by the DAS). So in this example, the Street.java class would have a corresponding ObjectClass called Street defined in ADS. The Street ObjectClass would have the LDAP attributes name and number, so when the Street object is persisted to ADS, the DAS would create an LDAP entry consisting the attributes names and values on the object. Street only has primitives, so the entry would have no references to other server entries. If the Address instance is persisted, then it would also have references to the Street instance contained on the LDAP entry.
Lets think about the same scenario for a SQL database instead. In this case we
might have two tables. An ADDRESS table and a STREET table. The Address
instance is persisted to the columns of the ADDRESS table and the Street
instance is persisted to the columns of the STREET table.
So what your DAS implementation does
is persist the objects to an ADS server instead of XMI, or am I getting
it wrong? Is it the XMI that's getting persisted to ADS?
Well the XMI in this case would just be another representation of the data contained in
the object. It's the object serialized. But in our case we have to do a little more
work, before the object can be stored in ADS. Before an EObject instance gets persisted
it is converted into an LDAP entry via the JNDI API. This is basically a list of the
attributes and corresponding values that will be "hung" on a distinguised name
within the server.
Note though that the XMI and XML in this case are basically just slightly different representations of an EObject object instance, which is either the Street instance or the Address instance.
The part that's easy to mix up here is that Ecore is XMI. However Ecore XMI
describes EClass instances. So when EClass instances are serialized to XMI,
you end up with a result that can be used to generate java classes. If you now
create instances of these classes, you end up with instance data that is also
XMI, but it's just an object that's serialized, so that it's state can be
restored later.
Let me put it a little differently. You could create EMF EClass instances, and
use them to model classes. If you serialize these instances, one possible
format would be an XML Schema document. Another would be SQL. Another would
be Ecore (XMI). This is what's tricky about thinking in terms of EMF, but it
becomes very natural after a while. I would give this article a look, as it
explains it with a lot more examples:
http://www.devx.com/Java/Article/29093
Any EObject?
An EObject is an instance of an EClass. So instead of writing a class manually
using your favorite IDE, you could write an EClass definition inside your java
class file. You could then create instances of it. Another question is why
did the Rational (IBM) guys define an EObject. The EMF API is like the general
JAVA API, but it has features added. So an EObject is for EMF what an Object
is for java. So why does EMF need an Eobject? Because it knows how to
serialize itself to XML, XMI, it supports the addition of EAnnotation
instances, it has the EClass metadata singleton reference attached to it, and
so on. Incidentally, EAnnotation instances are what would be used when doing
custom mapping of EObject instances to ObjectClasses.
Could you perhaps
also give me some pointers to interesting places in the code to look?
I would study the tests. I've been meaning finish a design guide that goes
into a lot more detail regarding the techniques that make each role within the
machinery work. I started a guide which you can find here (It's an eclipse
documentation plugin, also generated using EMF):
http://incubator.apache.org/tuscany/ldap-das-architecture-guide.html
The general concept is to use recipes (Challenge, Solution, Discussion) to break apart
each little thing that the DAS has to do to function. I personally think documenting and
driving the design like this makes a lot of sense, since it clarifies what the challenges
and solutions are, and these challenges should be as atomic and concrete as possible.
You could just drop it into your eclipse plugins directory and it will show up in eclipse
help. I used this to "guide" myself through the process of writing the DAS.
Although once I my groove on, I started coding in the hot seat, so the guide needs
updating. I think the general headings will be useful though.
The DAS is pretty small in terms of classes, so I think you'll get up to speed
pretty quickly once you have a chance to view the code. The main thing is
understanding the concepts illustrated in this article:
http://www.devx.com/Java/Article/29093
Of coarse you also have to understand JNDI, but the DAS classes use it to do
all the work, so the DAS will probably be a good grounding for this. I'm also
sure that David's Triplesec JACC stuff would help.
Good luck and let me know if you need elaboration on anything else,
- Ole