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