1 #LyX 1.3 created this file. For more info see http://www.lyx.org/
14 \use_numerical_citations 0
15 \paperorientation portrait
18 \paragraph_separation indent
20 \quotes_language english
24 \paperpagestyle default
36 Protocol A Protocol for introspection on relational objects.
40 Presentations A Mewa-like
46 http://www.adrian-lienhard.ch/files/mewa.pdf
55 http://common-lisp.net/project/ucw/
64 LISP-ON-LINES (LOL) is a framework for rapid development of complex data-driven
75 First we start with the data model.
76 The Meta Model Protocol (MMP) is used to provide information on the data
77 objects and how they relate to one another.
78 Its is currently implemented as a layer over CLSQL
87 , although support is planned for other backends (CLOS, Elephant[4], whatever).
90 The MMP shares its definition syntax with CLSQL's Object Oriented Data Definitio
97 http://clsql.b9.com/manual/ref-ooddl.html
103 Shouldn't this footnote be a bibliographical entry ? or something like that
111 The macro to define view-classes is named DEF-VIEW-CLASS/META, and takes
112 the same arguments as DEF-VIEW-CLASS from CLSQL.
113 For the purposes of this simple example, we will only need two functions
114 from the MMP beyond what CLSQL provides : LIST-SLOTS and LIST-SLOT-TYPES[5].
117 We'll define a simple class to hold a user.
120 (def-view-class/meta user ()
123 ((userid :initarg :userid :accessor userid :type integer :db-kind :key)
126 (username :initarg :username :accessor username :type string :db-kind
130 (password :initarg :password :accessor password :type string :db-kind
136 STYLE-WARNING: redefining META-MODEL.METADATA (USER) in DEFMETHOD
139 #<CLSQL-SYS::STANDARD-DB-CLASS USER>
144 (defparameter user (make-instance 'user :userid 1
150 :password "p@ssw0rd"))
160 LISP-ON-LINES> (list-slots user)
163 (USERID USERNAME PASSWORD)
166 LISP-ON-LINES> (list-slot-types user)
169 ((USERID INTEGER) (USERNAME STRING) (PASSWORD STRING))
172 ; compiling file "/tmp/fileQQsHyN" (written 03 JUN 2005 03:20:06 PM):
175 ; /tmp/fileQQsHyN.fasl written
178 ; compilation finished in 0:00:00
185 (default-attributes user)
188 ((userid integer :label "User ID" :slot-name 'userid)
191 (username string :label "User name" :slot-name 'username)
194 (password string :label "Password" :slot-name 'password))
199 LISP-ON-LINES> (set-default-attributes user)
202 ((USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
205 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
208 (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD))
211 LISP-ON-LINES> (find-class-attributes user)
214 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
217 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
220 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
226 LISP-ON-LINES> ;;;; note that the mewa functions (find-attribute, set-attribute
227 etc) can take either an instance, or a class-name as a symbol , ie :
233 LISP-ON-LINES> (find-class-attributes 'user)
236 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
239 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
242 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
248 LISP-ON-LINES> (find-class-attributes (make-instance 'user))
251 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
254 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
257 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
266 Using that information, we have enough to create an interface to the object.
267 UncommonWeb includes a powerful presentation system, but it is not quite
268 dynamic enough for our needs.
269 Mewa defines an approach to presentations that suits our purposes, but
270 the paper is written from a smalltalk point of view.
271 A mixture of the two , Mewa Presentations(MP), is described here.
274 MP introduces to UCW the concept of attributes.
275 an attribute is essentially a named version of the defpresentation slot-like
280 (defpresentation person-editor (object-presentation)
283 ((string :label "First Name" :slot-name 'first-name :max-length 30)))
286 the (string :label "First Name" ...) form is an attribute definiton.
287 Attributes are accessed through FIND-ATTIRIBUTES, and are composed at run
288 time (where the current system is done at compile time) to display the
290 This allows a very flexible system of displaying objects which is reminiscent
292 I discovered this, rather than invent or design it, so there are some rough
293 edges, but its a good start.
296 Its much easier to show this then to tell.
297 Lets present our user class.
298 Currently in UCW, you'd define a presentation as such :
301 (defpresentation user-presentation (object-presentation)
304 ((INTEGER :LABEL "USERID" :SLOT-NAME USERID)
307 (STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
310 (STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)))
313 which could be presented using PRESENT-OBJECT :
316 (present-object user :using 'user-presentation)
319 The equiv approach using mewa presentations is actually longer and more
320 verbose(!) but it serves to demonstrate how the MP system works.
323 Mewa Presentations adds a set of attributes to a class, keyed off the class
325 Attributes are inherited, so if you define an attribute on T, you can use
329 MP stores named attributes keyed on a class name.
330 to achieve the same functionality as the above using mp would look like
334 LISP-ON-LINES> (setf (find-attribute 'user :viewer) '(mewa-object-presentation
335 :attributes (userid username password) :global-properties (:editablep nil)))
338 (:VIEWER MEWA-OBJECT-PRESENTATION
344 (USERID USERNAME PASSWORD)
353 LISP-ON-LINES> (setf (find-attribute 'user 'userid) '(INTEGER :LABEL "USERID"
357 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
360 LISP-ON-LINES> (setf (find-attribute 'user 'username) '(STRING :LABEL "USERNAME"
361 :SLOT-NAME USERNAME))
364 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
367 LISP-ON-LINES> (setf (find-attribute 'user 'password) '(STRING :LABEL "USERNAME"
368 :SLOT-NAME PASSWORD))
371 (PASSWORD STRING :LABEL "USERNAME" :SLOT-NAME PASSWORD)
374 LISP-ON-LINES> (find-class-attributes 'user)
377 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
380 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
383 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
386 (:VIEWER MEWA-OBJECT-PRESENTATION
392 (USERID USERNAME PASSWORD)
404 this is all turned into a UCW presentation at runtime using MAKE-PRESENTATION
408 (defmethod render-on ((res response) (e presentations-index))
414 As you'll see, nothing is exported from the LISP-ON-LINES package.
418 if you wish to use LOL in your own package (or in UCW-USER or whatever),
421 you simply need to use the MEWA and META-MODEL packages"
424 (<ucw:render-component :component (lisp-on-lines::make-presentation lisp-on-line
425 s::user :type :viewer)))
428 SET-ATTRIBUTE can be used in place of (setf (find-attribute)) when you want
429 to "inherit" the properties of an existing attribute definition :
432 LISP-ON-LINES> (set-attribute 'user 'password '(string :label "password:
433 (must be at leat 8 chars)"))
442 "password: (must be at leat 8 chars)"
451 Now we want to create a presentation with which to edit the username.
452 we will use the existing attributes on a subclass of mewa-object-presetation
456 LISP-ON-LINES> (defcomponent user-editor (mewa-object-presentation)
465 :attributes '((username :label "Enter your New Username") password)
468 :global-properties '(:editablep t)))
474 LISP-ON-LINES> (setf (find-attribute 'user :editor) '(user-editor))
477 (:EDITOR USER-EDITOR)
483 which we then can display below our earlier example :
486 (defmethod render-on ((res response) (e presentations-index))
492 As you'll see, nothing is exported from the LISP-ON-LINES package.
496 if you wish to use LOL in your own package (or in UCW-USER or whatever),
499 you simply need to use the MEWA and META-MODEL packages"
502 (<ucw:render-component :component (lisp-on-lines::make-presentation lisp-on-line
503 s::user :type :viewer))
506 (<ucw:render-component :component (lisp-on-lines::make-presentation lisp-on-line
507 s::user :type :editor)))
510 that should give you some idea on how it works ..
511 ask me when you get confused :)