Right now, there is no "merging" going on in the raw data exported through the data model. Local IM contacts are represented like: online-desktop:/o/global onlineBuddies: [online-desktop:/o/pidgin-buddy/xmpp otaylor redhat com, ...] online-desktop:/o/pidgin-buddy/aim.owenwtaylor protocol: aim name: owenwtaylor alias: Owen Taylor status: available icon: data:image/png;base64;iVBOR.... isOnline: 1 And there is separate data provided by the server: http://online.g.o/o/user/61m76k3hGbRRFS name: Owen homeUrl: http://mugshot.org/person?who=/o/user/61m76k3hGbRRFS aim: owenwtaylor That can be merged together by the application. But this is bad in several ways. First: we need complex code in every application to do the merging. Second, when you do the coding in the applications, you have to write a new custom API for it rather than using the standard data model API. What we'd really want to have is the merging happening in the data model engine, so we just have extra properties. online-desktop:/o/pidgin-buddy/aim.owenwtaylor [...] user: http://online.g.o/o/user/61m76k3hGbRRFS And: http://online.g.o/o/user/61m76k3hGbRRFS [...] aimBuddy: online-desktop:/o/pidgin-buddy/aim.owenwtaylor I started to do this manually for the special case, but it got really hairy to deal with all the cases ... local contacts being added and removed, remote contacts being added and removed, and so forth. So I came to the conclusion that the easier thing would be to add a generic mechanism. The basic idea is that you define a property as a query. We define the <class>#<property> http://online.g.o/p/o/user#aimBuddy as: select source from online-desktop:/p/o/buddy source where and target.protocol = 'aim' and target.aim = source.name (Without any implication of putting a SQL parser into the data model engine! I'm just using sql to approximate the meaning.) Issues: * The set of objects of a particular class in the client's memory is non-deterministic. It depends on what has been queried. So whether online-desktop:/p/o/buddy#user points to a online.g.o user depends not on whether we've happened to query that user's AIM address or not. In general, I think this is acceptable ... if we always query your contacts, we'll generally know about all the online.gnome.org users you *expect* to know about. We could also do explicit queries to the server based on the the IM contacts we see. A data model operation like: getUsersByAim(aim='owenwtaylor,johndoe532341,...') * The queries we want aren't entirely simple. Just the other side of the one above would have to be: online-desktop:/p/o/buddy#user: select source from http://online.g.o/p/o/user source where (source.protocol = 'aim' and target.name = source.aim) or (source.protocol = 'xmpp' and target.name = source.xmpp) * The behavior we want for online-desktop:/p/o/buddy#user is actually even more complex than the above. We want: - The online.g.o user if one exists - A synthetically created user based on the contact data if the online.g.o doesn't exist Which would imply even more complexity in how the query is specified. The answer to both this point and the one above be the same: to go in between the original idea of writing code to update the data model and the full idea of expressing the property contents in a declarative fashion. * Along with query specification, maintaining indices, and doing updates to computed property values as data comes in, there is another fairly tricky thing that needs to be written: fetches that traverse local and remote data. If someone says: getResource('online-desktop:/o/global' 'onlineBuddies [name;user [name;email;photoUrl]]') Then we have to look locally to find the user resources, then go remotely to get the name/email/photoUrl for the user resources if we don't already have them. It could get even more complex: 'onlineBuddies user contacts aimBuddy' Where we look locally, then look remotely, then look locally again. So that's more code to write. But we've actually already run into this problem with the online-desktop:/o/global#self property, so it's not additional work. There's quite a bit more that needs to be figured out about actual implementation, but I think I'll stop here so there's some chance that someone else will actually work through the above and give me feedback. - Owen
Attachment:
signature.asc
Description: This is a digitally signed message part