HOWTO Using auxiliary LDAP classes in WebObjects
HOWTO Using auxiliary LDAP classes in WebObjects
- Subject: HOWTO Using auxiliary LDAP classes in WebObjects
- From: Benjamin J Doherty <email@hidden>
- Date: Thu, 1 Dec 2005 08:26:43 -0600
On Nov 30, 2005, at 8:04 AM, Benjamin J Doherty wrote:
However, I believe I'm closer to my goal of being able to use
auxiliary classes. Here's my method:
[...]
How do I create records with both objectClasses inetOrgPerson and
posixAccount? This is speculative now, and I will report more
later. If you've got cautionary tales, please tell me so I don't
repeat your mistakes. I've discovered that I can make the
objectClass property in EOF visible to the server side. It's type
also needs to be NSArray instead of String. What I can say is that
THIS DOES NOT CAUSE MY APP TO CRASH. Yay! But now EOF won't
generate the objectClass automatically, so I need to create it
myself in the business logic.
Success! Hooray!
You can use auxiliary classes in WebObjects. You can edit the
objectClass attribute on a live enterprise object!
Here are my steps to start using auxiliary classes. For this example,
our scenario is that we want to be able to create/update/delete LDAP
entries for employees located at ou=People,dc=domain,dc=com which all
need to be inetOrgPerson and posixAccount.
1. In EOModeler, set up the inheritance hierarchy for the LDAP
object class "entities" that you'll be using. For example:
Top -> Person -> OrganizationalPerson -> inetOrgPerson
This may not be necessary, but it's helpful for many reasons and I
think it's just right to do this.
2. In the Top entity, make the objectClass attribute into a server
side property. Make it a client side property if you're using
JavaClient. Also make its Java Class into NSArray instead of
String. You don't need any factory methods, so just ignore the
warnings or turn them off. Make sure that these changes have
cascaded to all your objects. If you're using JavaClient, you'll need
to set the client side property on all your objects manually.
3. In EOModeler, copy and paste the definition of the inetOrgPerson
entity to create a new entity. Rename it to "Staff." Make sure all
your inheritance is set correctly.
4. Select all the attributes in the posixClass definition and paste
them into inetOrgPerson. You can weed out the duplicates before you
copy or after you paste. If you wait until after you paste, the dupes
are named objectClass1, userPassword1, etc.
5. Set a custom java class for the Staff entity.
Also set a java class for posixAccount even though you'll never
instantiate it.
If you're not using EOGenerator or something like it, start.
****
Let's review. Your definition of "Staff" should look like this:
Name: Staff
Table: inetOrgPerson
Java Class: com.domain.directory.Staff
Java Client Class: com.domain.directory.Staff
Parent: inetOrgPerson
If you get into an area where you need to deal with LDAP entries that
are in different parts of your tree, you will need to use multiple
EOModels and you won't be able to set up this kind of inheritance in
EOModeler because EOF will complain that you're trying to do a deep
fetch on entities in two separate databases. So your entities'
definitions will need to be the same but without a "parent." In this
case (and probably in most cases) you also want to set a java class
name for the superclasses as well--especially for the immediate
superclass inetOrgPerson.
****
6. Generate your java classes for the EO model.
If you're unable to specify a parent for your "Staff" entity for the
reason I stated above, you can effectively do it in your Java source
for Staff.java by specifying that:
public class Staff extends inetOrgPerson
But then you will need to have a java class source generated for
inetOrgPerson too! And you'll want to remove all the methods that are
n inheri from inetOrgPerson. ed
7. Modify the posixAccount.java source file and make it into an
interface. If you're using EOGenerator, you may want to do
some copying and pasting across the gap, but it's not difficult and
need not be detailed here. Here's an excerpt of what my
posixAccount.java looks like:
public interface posixAccount {
public String cn();
/*
public String cn() {
return (String)storedValueForKey("cn");
}
*/
public void setCn(String aValue);
/*
public void setCn(String aValue) {
takeStoredValueForKey(aValue, "cn");
}
*/
I keep the classy-bits as comments in the source file so that I
can just cut and paste the real methods into my implementations.
However, I could also just copy and paste the contents of the
_posixAccount.java file.
If someone is asking "what if I want to create a posixAccount
object?" then you need to remember some LDAP facts. You always need a
structural class in an LDAP entry. If you're going to work with any
auxiliary class, you're ALWAYS going to be doing it in the context of
a larger object with a structural class. This is why all auxiliary
classes should be considered as "interfaces" in Java EOF and why you
modeled the Staff entity from inetOrgPerson, a structural class.
7. Modify the Staff.java source file to implement the interface.
Remember to avoid duplicating method names! PosixAccount and
inetOrgPerson have overlapping attributes.
8. Because you've exposed objectClass in your model, WebObjects
seems to take that as an indicator that you don't want it changing it
for you. You MUST manually set the objectClass for new objects if
you're using auxiliary classes, but you will also need to do this
even if you're going to use simple structural LDAP classes in
WebObjects in the same model.
This code hasn't been tested thoroughly. Don't laugh at me if it's
goofy! I'm not a trained programmer.
public class Staff extends InetOrgPerson implements posixAccount {
public Staff() {
super();
}
public void awakeFromInsertion(EOEditingContext context) {
super.awakeFromInsertion(context);
NSMutableArray objectClass = objectClass() == null ? new
NSMutableArray() : objectClass().mutableClone();
if (!objectClass.contains("inetOrgPerson")) {
objectClass.addObject(new String("inetOrgPerson"));
}
if (!objectClass.contains("posixAccount")) {
objectClass.addObject(new String("posixAccount"));
}
setObjectClass(objectClass);
}
9. Gloat to your colleagues that you have an elegant solution while
they were going to do a LDAP-kludge by making all their EOF entities
into LDAP structural classes in the schema. Pshaw... aren't they
backwards!
I bet there's a lot of cool things that can be done now that we could
add and remove auxiliary classes after the object has already been
created and inserted in the directory.
Before you get excited about modifying your objectClass, you should
know that you should NOT try to set the objectClass throughout your
inheritance hierarchy. If inetOrgPerson sets its objectClass to
inetOrgPerson, that's it. You can't also set it to
organizationalPerson and then to Person too. LDAP will complain. You
can't have multiple structural classes. The tricky part about LDAP is
that if you decide one day to filter the directory with
(objectClass=Person), you'll get all of Person's attributes from all
of Person's descendants. So even if cn=Billy
Boy,ou=Staff,dc=domain,dc=dom is an inetOrgPerson, he'll still show
up when you look for all Person or OrganizationalPerson entries.
Not clear? All wrong? Improvements? Share.
Cheers,
Benjamin Doherty
Chicago
email@hidden
Attachment:
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden