[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
r5259 - in branches/gnue-appserver-featuretest: . diagrams geasarch
From: |
reinhard |
Subject: |
r5259 - in branches/gnue-appserver-featuretest: . diagrams geasarch |
Date: |
Mon, 8 Mar 2004 04:28:54 -0600 (CST) |
Author: reinhard
Date: 2004-03-08 04:28:53 -0600 (Mon, 08 Mar 2004)
New Revision: 5259
Added:
branches/gnue-appserver-featuretest/diagrams/
branches/gnue-appserver-featuretest/diagrams/CHANGELOG
branches/gnue-appserver-featuretest/diagrams/README
branches/gnue-appserver-featuretest/diagrams/geas.dia
branches/gnue-appserver-featuretest/diagrams/geor.dia
branches/gnue-appserver-featuretest/diagrams/repository_ER.dia
branches/gnue-appserver-featuretest/diagrams/usage.dia
branches/gnue-appserver-featuretest/geasBClass.py
branches/gnue-appserver-featuretest/geasTrigger.py
branches/gnue-appserver-featuretest/geasarch/
branches/gnue-appserver-featuretest/geasarch/AUTHORS
branches/gnue-appserver-featuretest/geasarch/bindings.txt
branches/gnue-appserver-featuretest/geasarch/geas-schema-compiler.dia
branches/gnue-appserver-featuretest/geasarch/geasv2arch.dia
branches/gnue-appserver-featuretest/geasarch/neilt-arch-explanation.txt
branches/gnue-appserver-featuretest/geasarch/odmg.txt
branches/gnue-appserver-featuretest/geasarch/outline.txt
Log:
Moved some stuff from trunk over here.
Added: branches/gnue-appserver-featuretest/diagrams/CHANGELOG
===================================================================
--- branches/gnue-appserver-featuretest/diagrams/CHANGELOG 2004-03-08
10:18:50 UTC (rev 5258)
+++ branches/gnue-appserver-featuretest/diagrams/CHANGELOG 2004-03-08
10:28:53 UTC (rev 5259)
@@ -0,0 +1,17 @@
+09/30/2002
+ Added more methods to geasList in geas.dia
+ Added an Entity-Relationship Diagram of the repository (meta-tables).
+07/23/2002
+ Added FSF Copyright
+07/15/2002
+ Added this file.
+ Added geasTriggerManager and derived classes to geas.dia.
+ Changed some attributes to associations between classes.
+ Reflected some changes in source code
+ fixed some types of attributes and methods that were not.
+07/01/2002
+ First release:
+ geas.dia
+ geor.dia
+ usage.dia
+ README
\ No newline at end of file
Added: branches/gnue-appserver-featuretest/diagrams/README
===================================================================
--- branches/gnue-appserver-featuretest/diagrams/README 2004-03-08 10:18:50 UTC
(rev 5258)
+++ branches/gnue-appserver-featuretest/diagrams/README 2004-03-08 10:28:53 UTC
(rev 5259)
@@ -0,0 +1,21 @@
+This directory contains the following files:
+README: this file
+geas.dia: An Uml class diagram of geas/appserver/src.
+geor.dia: An Uml class diagram of geas/appserver/src/objrepos
+usage.dia: An Uml collaboration diagram of a typical interaction between a
client app and the appserver.
+
+I'm sure that i missed a lot, any comments/suggestion are welcome
+
+Since Python is not a strogly typed language and all attributes and methods
+are public by default i adoptede the following conventions in the UML class
diagrams.
+1) Types of attributes,methods and parameters are more an hint rather than a
specification.
+ Correct UML for python requires something like: "+myAttribute:?".
+ when a type is indicated this means what is appropriate to the method/class
to behave
+ correctly.
+2) attributes initialized in the __init__ method are public (prefixed with +)
since
+ they can be accessed without checking 'hasattr'
+3) attributes not initialized in the __init__ method but mentioned elsewhere
are 'implementation' (not prefixed)
+ since their existance is not granted.
+4) 'self' is omitted everywere since it is implicit for objects.
+
+All the diagrams are under Gnu Public License.
Added: branches/gnue-appserver-featuretest/diagrams/geas.dia
===================================================================
(Binary files differ)
Property changes on: branches/gnue-appserver-featuretest/diagrams/geas.dia
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/gnue-appserver-featuretest/diagrams/geor.dia
===================================================================
(Binary files differ)
Property changes on: branches/gnue-appserver-featuretest/diagrams/geor.dia
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/gnue-appserver-featuretest/diagrams/repository_ER.dia
===================================================================
(Binary files differ)
Property changes on:
branches/gnue-appserver-featuretest/diagrams/repository_ER.dia
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/gnue-appserver-featuretest/diagrams/usage.dia
===================================================================
(Binary files differ)
Property changes on: branches/gnue-appserver-featuretest/diagrams/usage.dia
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/gnue-appserver-featuretest/geasBClass.py
===================================================================
--- branches/gnue-appserver-featuretest/geasBClass.py 2004-03-08 10:18:50 UTC
(rev 5258)
+++ branches/gnue-appserver-featuretest/geasBClass.py 2004-03-08 10:28:53 UTC
(rev 5259)
@@ -0,0 +1,136 @@
+# GNU Enterprise Application Server - List Object
+#
+# Copyright 2001-2004 Free Software Foundation
+#
+# This file is part of GNU Enterprise.
+#
+# GNU Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2, or (at your option) any later version.
+#
+# GNU Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied
+# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+# PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with program; see the file COPYING. If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place
+# - Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id: geasBClass.py 5257 2004-03-08 10:06:17Z johannes $
+
+from gnue.common.datasources import GDataSource,GConditions
+import geasInstance
+import string
+
+# =============================================================================
+# List class
+# =============================================================================
+
+class geasBClass:
+
+ # ---------------------------------------------------------------------------
+ # Initalize
+ # ---------------------------------------------------------------------------
+
+ def __init__ (self, session, classname):
+ self._session = session
+ self._classname = classname
+
+
+ def _populate (self):
+
+ if hasattr(self,"_sort"):
+ sorting = string.joinfields(self._sort,",")
+ else:
+ sorting = None
+
+ self._datasource = GDataSource.DataSourceWrapper(
+ connections=self._session._connections,
+ fields=self._prefetch,
+ init=1,
+ attributes = {
+ "name": "tmp",
+ "connection": self._session._database,
+ "table": self._classname,
+ "order_by": sorting } )
+
+ if hasattr(self,"_conditionTree"):
+ self._resultset = self._datasource.createResultSet(self._conditionTree)
+ else:
+ self._resultset = self._datasource.createResultSet()
+
+
+
+ def _firstInstance (self):
+ if self._classname!='appserver_pytrigger':
+ trigger=self._session._triggerMg.getTriggerByEvent \
+ ('%s:pre_first_inst' % self._classname)
+ if trigger!=None:
+ trigger()
+
+ if self._resultset.firstRecord () != 0:
+ return geasInstance.geasInstance (self, self._resultset.current)
+ else:
+ return None
+
+ # ---------------------------------------------------------------------------
+ # Get the next instance in the list
+ # ---------------------------------------------------------------------------
+
+ def _nextInstance (self):
+ if self._resultset.nextRecord () != 0:
+ return geasInstance.geasInstance (self, self._resultset.current)
+ else:
+ return None
+
+ # ---------------------------------------------------------------------------
+ # insert a new empty instance in the list and return it
+ # ---------------------------------------------------------------------------
+
+ def _insertNewInstance (self):
+ self._resultset.insertRecord ()
+ return geasInstance.geasInstance (self, self._resultset.current)
+
+ def load(self,obj_id_list,propertylist):
+ # method 1: build one resultset out of the whole stuff
+ # method 2: load every record one by one
+
+ # doing method 1:
+
+ # 1. build condition:
+ for i in obj_id_list:
+
+ pass
+
+ # 2. set prefetch
+ propertylist.add('gnue_id')
+ self._prefetch=propertylist
+
+ # 3. load recordset
+ self._populate()
+
+
+
+ def store(self,obj_id_list,propertylist,data):
+ for i in obj_id_list:
+ ## check for oid here
+ if 0:
+ # store record here
+ pass
+ else:
+ print "'%s' is no valid obj id" % i
+
+ def call(self,obj_id_list,methodname,parameters):
+ pass
+
+ def delete(self,obj_id_list):
+ for i in obj_id_list:
+ ## check for oid here
+ if 0:
+ # store record here
+ pass
+ else:
+ print "'%s' is no valid obj id" % i
Added: branches/gnue-appserver-featuretest/geasTrigger.py
===================================================================
--- branches/gnue-appserver-featuretest/geasTrigger.py 2004-03-08 10:18:50 UTC
(rev 5258)
+++ branches/gnue-appserver-featuretest/geasTrigger.py 2004-03-08 10:28:53 UTC
(rev 5259)
@@ -0,0 +1,132 @@
+# GNU Enterprise Application Server - Trigger Settings
+#
+# Copyright 2001-2004 Free Software Foundation
+#
+# This file is part of GNU Enterprise.
+#
+# GNU Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2, or (at your option) any later version.
+#
+# GNU Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied
+# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+# PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with program; see the file COPYING. If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place
+# - Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id: geasTrigger.py 5257 2004-03-08 10:06:17Z johannes $
+
+import string,new
+
+# =============================================================================
+# Basic Trigger Class ( abstract )
+# =============================================================================
+
+class geasTriggerManager:
+
+ # ---------------------------------------------------------------------------
+ # Initalize
+ # ---------------------------------------------------------------------------
+
+ def __init__ (self):
+ pass
+
+ # ---------------------------------------------------------------------------
+ # get named trigger X
+ # the returned trigger is an executable object, which can be called directly
+ # ---------------------------------------------------------------------------
+
+ def getTriggerByName(self, triggername):
+ return None
+
+ # ---------------------------------------------------------------------------
+ # get named trigger X
+ # the returned trigger is an executable object, which can be called directly
+ # ---------------------------------------------------------------------------
+
+ def getTriggerByEvent(self, triggerevent):
+ return None
+
+
+# =============================================================================
+# Database Authentification Agent
+# =============================================================================
+
+class geasPythonDBTriggerMg(geasTriggerManager):
+
+ # ---------------------------------------------------------------------------
+ # Initalize
+ # ---------------------------------------------------------------------------
+
+ def __init__ (self,session):
+ # creation and populating the triggerlist list should be
+ # moved here
+ self._session=session
+
+ # ---------------------------------------------------------------------------
+ # get named trigger X
+ # this trigger is an executable object, which can be called directly
+ # ---------------------------------------------------------------------------
+
+ def getTriggerByName(self, triggername):
+ triggerList = self._session.createList ("appserver_pytrigger")
+
+ triggerList.setPrefetch (["name", "event", "code"])
+ triggerList.setConditions ([['eq', ''],
+ ['field', 'name'],
+ ['const', triggername ]])
+ triggerList.populate ()
+
+ instance = triggerList.firstInstance ()
+
+ # no such trigger
+ if instance==None:
+ # log something
+ print "Trigger '%s' does not exist." % triggername
+
+ return None
+
+ code=instance.get('code')
+ # format code
+
+ ccode=compile (code,'<string>','exec')
+ myfunc=new.function(ccode, {'session':self._session}, triggername)
+
+ return myfunc
+
+ # ---------------------------------------------------------------------------
+ # get named trigger X
+ # this trigger is an executable object, which can be called directly
+ # ---------------------------------------------------------------------------
+
+ def getTriggerByEvent(self, eventname):
+ triggerList = self._session.createList ("appserver_pytrigger")
+
+ triggerList.setPrefetch (["name", "event", "code"])
+ triggerList.setConditions ([['eq', ''],
+ ['field', 'event'],
+ ['const', eventname ]])
+ triggerList.populate ()
+
+ instance = triggerList.firstInstance ()
+
+ # no such trigger
+ if instance==None:
+ # log something
+# print _("Trigger for event '%s' does not exist.") % eventname
+
+ return None
+
+ code=instance.get('code')
+ # format code
+
+ ccode=compile (code,'<string>','exec')
+ myfunc=new.function(ccode, {'session':self._session}, instance.get('name'))
+
+ return myfunc
+
Added: branches/gnue-appserver-featuretest/geasarch/AUTHORS
===================================================================
--- branches/gnue-appserver-featuretest/geasarch/AUTHORS 2004-03-08
10:18:50 UTC (rev 5258)
+++ branches/gnue-appserver-featuretest/geasarch/AUTHORS 2004-03-08
10:28:53 UTC (rev 5259)
@@ -0,0 +1 @@
+Daniel Baumann <address@hidden>
Added: branches/gnue-appserver-featuretest/geasarch/bindings.txt
===================================================================
--- branches/gnue-appserver-featuretest/geasarch/bindings.txt 2004-03-08
10:18:50 UTC (rev 5258)
+++ branches/gnue-appserver-featuretest/geasarch/bindings.txt 2004-03-08
10:28:53 UTC (rev 5259)
@@ -0,0 +1,94 @@
+C++
+===
+Introduction
+Language Design Principles
+Language Binding
+Mapping the OMDG Oject Model Into C++
+ Object and Literal
+ Structure
+ Implementation
+ Collection Classes
+ Array
+ Relationship
+ Extents
+ Keys
+ Names
+Use of C++ Langauge Features
+ Prefix
+ Name Spaces
+ Exception Handling
+ Preprocessor Indentifier
+ Implementation Extensions
+C++ ODL
+ Attribute Declarations
+ Fixed-length Types
+ d_String
+ d_Interval
+ d_Date
+ d_Time
+ d_Timestamp
+ Relationship Traversal Path Directions
+ Operation Declarations
+
+Java
+====
+Introduction
+Language Design Principles
+Language Binding
+Use of Java Language Features
+ Name Spaces and Interfaces
+ Implementation Bootstrap Object
+ Implementation Extensions
+Mapping the ODMG Object Model Into Java
+ Object and Literal
+ Structure
+ Implementation
+ Collection Interfaces
+ Array
+ Relationship
+ Extents
+ Keys
+ Names
+ Exception Handling
+Java ODL
+ Attribute Decalarations and Types
+ Relationship Traversal Path Directions
+ Operation Declarations
+
+Smalltalk
+=========
+Introduction
+Language Design Principles
+Language Binding
+Mapping the ODMG Object Model Into Smalltalk
+ Object and Literal
+ Relationship
+ Names
+ Extents
+ Keys
+ Implementation
+ Collections
+ Database Administration
+Smalltalk ODL
+ OMG IDL Binding Overview
+ Indentifiers
+ Interfaces
+ Objects
+ Operations
+ Constants
+ Types
+ Simple Types
+ Compound Types
+ Binding Examples
+ Exceptions
+ Smalltalk ODL Binding Extensions
+ Interfaces and Classes
+ Attribute Declarations
+ Relationship Declarations
+ Collections
+ Structured Literals
+
+Python
+======
+Introduction
+Language Design Principles
\ No newline at end of file
Added: branches/gnue-appserver-featuretest/geasarch/geas-schema-compiler.dia
===================================================================
--- branches/gnue-appserver-featuretest/geasarch/geas-schema-compiler.dia
2004-03-08 10:18:50 UTC (rev 5258)
+++ branches/gnue-appserver-featuretest/geasarch/geas-schema-compiler.dia
2004-03-08 10:28:53 UTC (rev 5259)
@@ -0,0 +1,763 @@
+<?xml version="1.0"?>
+<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
+ <dia:diagramdata>
+ <dia:attribute name="background">
+ <dia:color val="#ffffff"/>
+ </dia:attribute>
+ <dia:attribute name="paper">
+ <dia:composite type="paper">
+ <dia:attribute name="name">
+ <dia:string>#Letter#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="tmargin">
+ <dia:real val="2.54"/>
+ </dia:attribute>
+ <dia:attribute name="bmargin">
+ <dia:real val="2.54"/>
+ </dia:attribute>
+ <dia:attribute name="lmargin">
+ <dia:real val="2.54"/>
+ </dia:attribute>
+ <dia:attribute name="rmargin">
+ <dia:real val="2.54"/>
+ </dia:attribute>
+ <dia:attribute name="is_portrait">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="scaling">
+ <dia:real val="1"/>
+ </dia:attribute>
+ <dia:attribute name="fitto">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ <dia:attribute name="grid">
+ <dia:composite type="grid">
+ <dia:attribute name="width_x">
+ <dia:real val="1"/>
+ </dia:attribute>
+ <dia:attribute name="width_y">
+ <dia:real val="1"/>
+ </dia:attribute>
+ <dia:attribute name="visible_x">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:attribute name="visible_y">
+ <dia:int val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ <dia:attribute name="guides">
+ <dia:composite type="guides">
+ <dia:attribute name="hguides"/>
+ <dia:attribute name="vguides"/>
+ </dia:composite>
+ </dia:attribute>
+ </dia:diagramdata>
+ <dia:layer name="Background" visible="true">
+ <dia:object type="Flowchart - Box" version="0" id="O0">
+ <dia:attribute name="obj_pos">
+ <dia:point val="5.0216,5.25"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="4.9716,5.2;14.1284,7.3"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="5.0216,5.25"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="9.0568"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#ODL declarations#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font name="Courier"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="9.55,6.46714"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Box" version="0" id="O1">
+ <dia:attribute name="obj_pos">
+ <dia:point val="20.1412,4.85"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="20.0912,4.8;27.3088,7.6"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="20.1412,4.85"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="7.1176"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="2.7"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.5"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#ODL
+compiler#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font name="Courier"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="23.7,6.01714"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Terminal" version="0" id="O2">
+ <dia:attribute name="obj_pos">
+ <dia:point val="3.93153,12.4464"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="3.40753,11.9224;14.6926,14.5775"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="3.93153,12.4464"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="10.2371"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="1.60711"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="flip_horizontal">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="flip_vertical">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.353553"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Meta Objects#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font name="Courier"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="9.05006,13.4671"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Terminal" version="0" id="O3">
+ <dia:attribute name="obj_pos">
+ <dia:point val="18.2679,12.3964"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="17.7439,11.8724;29.7562,14.5275"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="18.2679,12.3964"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="10.9643"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="1.60711"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="flip_horizontal">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="flip_vertical">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.353553"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Class objects#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font name="Courier"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="23.7501,13.4171"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Flowchart - Terminal" version="0" id="O4">
+ <dia:attribute name="obj_pos">
+ <dia:point val="8.87714,18.4964"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="8.35314,17.9724;22.547,20.6275"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="8.87714,18.4964"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="13.1459"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="1.60711"/>
+ </dia:attribute>
+ <dia:attribute name="show_background">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="flip_horizontal">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="flip_vertical">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="padding">
+ <dia:real val="0.353553"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Object instances#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font name="Courier"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="15.4501,19.5171"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Standard - Text" version="0" id="O5">
+ <dia:attribute name="obj_pos">
+ <dia:point val="9.8206,7.94749"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="6.7618,7.33035;12.8294,8.13035"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Regeneration#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font name="Courier"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="9.8206,7.94749"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Standard - Text" version="0" id="O6">
+ <dia:attribute name="obj_pos">
+ <dia:point val="20.9,9.51259"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="18.376,8.89545;23.424,9.69545"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Generation#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font name="Courier"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="20.9,9.51259"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Standard - Text" version="0" id="O7">
+ <dia:attribute name="obj_pos">
+ <dia:point val="16.35,14.35"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="14.2608,13.7329;18.3892,15.3329"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Language
+binding#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font name="Courier"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="16.35,14.35"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Standard - Text" version="0" id="O8">
+ <dia:attribute name="obj_pos">
+ <dia:point val="6.2206,14.9975"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="5.101,14.3804;7.2902,15.1804"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Type#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font name="Courier"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="6.2206,14.9975"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Standard - Text" version="0" id="O9">
+ <dia:attribute name="obj_pos">
+ <dia:point val="24.9206,15.5975"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="23.5586,14.9804;26.2326,15.7804"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Class#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font name="Courier"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="24.9206,15.5975"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="UML - Note" version="0" id="O10">
+ <dia:attribute name="obj_pos">
+ <dia:point val="24.8,18.05"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="24.75,18;31.2828,19.8"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="24.8,18.05"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="6.4328"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="1.7"/>
+ </dia:attribute>
+ <dia:attribute name="text">
+ <dia:composite type="text">
+ <dia:attribute name="string">
+ <dia:string>#Python code#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="font">
+ <dia:font name="Courier"/>
+ </dia:attribute>
+ <dia:attribute name="height">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="pos">
+ <dia:point val="25.15,19.3171"/>
+ </dia:attribute>
+ <dia:attribute name="color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="alignment">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="Standard - Line" version="0" id="O11">
+ <dia:attribute name="obj_pos">
+ <dia:point val="28.6969,13.7681"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="27.967,13.7187;28.7463,18.0994"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="28.6969,13.7681"/>
+ <dia:point val="28.0164,18.05"/>
+ </dia:attribute>
+ <dia:attribute name="numcp">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O3" connection="11"/>
+ <dia:connection handle="1" to="O10" connection="1"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - Line" version="0" id="O12">
+ <dia:attribute name="obj_pos">
+ <dia:point val="14.0784,6.25"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="14.0284,5.40003;20.1912,6.99997"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="14.0784,6.25"/>
+ <dia:point val="20.1412,6.2"/>
+ </dia:attribute>
+ <dia:attribute name="numcp">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="3"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O0" connection="8"/>
+ <dia:connection handle="1" to="O1" connection="7"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - Line" version="0" id="O13">
+ <dia:attribute name="obj_pos">
+ <dia:point val="10.7562,12.4464"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="10.3862,7.50567;20.1855,13.1557"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="10.7562,12.4464"/>
+ <dia:point val="20.1412,7.55"/>
+ </dia:attribute>
+ <dia:attribute name="numcp">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:attribute name="start_arrow">
+ <dia:enum val="3"/>
+ </dia:attribute>
+ <dia:attribute name="start_arrow_length">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="start_arrow_width">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O2" connection="3"/>
+ <dia:connection handle="1" to="O1" connection="11"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - Line" version="0" id="O14">
+ <dia:attribute name="obj_pos">
+ <dia:point val="14.1686,13.25"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="14.1186,12.4001;18.3179,14.0499"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="14.1686,13.25"/>
+ <dia:point val="18.2679,13.2"/>
+ </dia:attribute>
+ <dia:attribute name="numcp">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:attribute name="start_arrow">
+ <dia:enum val="3"/>
+ </dia:attribute>
+ <dia:attribute name="start_arrow_length">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="start_arrow_width">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="3"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O2" connection="10"/>
+ <dia:connection handle="1" to="O3" connection="6"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - Line" version="0" id="O15">
+ <dia:attribute name="obj_pos">
+ <dia:point val="7.34386,14.0535"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="6.73077,13.5396;11.1064,18.5347"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="7.34386,14.0535"/>
+ <dia:point val="11.0681,18.4964"/>
+ </dia:attribute>
+ <dia:attribute name="numcp">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:attribute name="start_arrow">
+ <dia:enum val="3"/>
+ </dia:attribute>
+ <dia:attribute name="start_arrow_length">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="start_arrow_width">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O2" connection="13"/>
+ <dia:connection handle="1" to="O4" connection="0"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - Line" version="0" id="O16">
+ <dia:attribute name="obj_pos">
+ <dia:point val="19.832,18.4964"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="19.7943,13.4777;24.353,18.5341"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="19.832,18.4964"/>
+ <dia:point val="23.7501,14.0035"/>
+ </dia:attribute>
+ <dia:attribute name="numcp">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="3"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O4" connection="4"/>
+ <dia:connection handle="1" to="O3" connection="14"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - Arc" version="0" id="O17">
+ <dia:attribute name="obj_pos">
+ <dia:point val="6.0206,7.29749"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="5.53678,7.09836;7.39229,12.4948"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="6.0206,7.29749"/>
+ <dia:point val="7.34386,12.4464"/>
+ </dia:attribute>
+ <dia:attribute name="curve_distance">
+ <dia:real val="1"/>
+ </dia:attribute>
+ <dia:attribute name="start_arrow">
+ <dia:enum val="3"/>
+ </dia:attribute>
+ <dia:attribute name="start_arrow_length">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="start_arrow_width">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="1" to="O2" connection="1"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - Arc" version="0" id="O18">
+ <dia:attribute name="obj_pos">
+ <dia:point val="13.1706,7.24749"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="12.7649,6.55796;21.9658,12.4395"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="13.1706,7.24749"/>
+ <dia:point val="21.9227,12.3964"/>
+ </dia:attribute>
+ <dia:attribute name="curve_distance">
+ <dia:real val="1"/>
+ </dia:attribute>
+ <dia:attribute name="start_arrow">
+ <dia:enum val="3"/>
+ </dia:attribute>
+ <dia:attribute name="start_arrow_length">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="start_arrow_width">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="1" to="O3" connection="1"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - Line" version="0" id="O19">
+ <dia:attribute name="obj_pos">
+ <dia:point val="23.7,7.55"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="22.9501,7.5;24.5501,12.4464"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="23.7,7.55"/>
+ <dia:point val="23.7501,12.3964"/>
+ </dia:attribute>
+ <dia:attribute name="numcp">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow">
+ <dia:enum val="3"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_length">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:attribute name="end_arrow_width">
+ <dia:real val="0.8"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O1" connection="13"/>
+ <dia:connection handle="1" to="O3" connection="2"/>
+ </dia:connections>
+ </dia:object>
+ <dia:object type="Standard - Line" version="0" id="O20">
+ <dia:attribute name="obj_pos">
+ <dia:point val="10.7562,14.0535"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="10.7081,14.0054;24.8481,18.0981"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="10.7562,14.0535"/>
+ <dia:point val="24.8,18.05"/>
+ </dia:attribute>
+ <dia:attribute name="numcp">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O2" connection="15"/>
+ <dia:connection handle="1" to="O10" connection="0"/>
+ </dia:connections>
+ </dia:object>
+ </dia:layer>
+</dia:diagram>
Added: branches/gnue-appserver-featuretest/geasarch/geasv2arch.dia
===================================================================
--- branches/gnue-appserver-featuretest/geasarch/geasv2arch.dia 2004-03-08
10:18:50 UTC (rev 5258)
+++ branches/gnue-appserver-featuretest/geasarch/geasv2arch.dia 2004-03-08
10:28:53 UTC (rev 5259)
@@ -0,0 +1,198 @@
+<?xml version="1.0"?>
+<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
+ <dia:diagramdata>
+ <dia:attribute name="background">
+ <dia:color val="#ffffff"/>
+ </dia:attribute>
+ <dia:attribute name="paper">
+ <dia:composite type="paper">
+ <dia:attribute name="name">
+ <dia:string>#Letter#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="tmargin">
+ <dia:real val="2.54"/>
+ </dia:attribute>
+ <dia:attribute name="bmargin">
+ <dia:real val="2.54"/>
+ </dia:attribute>
+ <dia:attribute name="lmargin">
+ <dia:real val="2.54"/>
+ </dia:attribute>
+ <dia:attribute name="rmargin">
+ <dia:real val="2.54"/>
+ </dia:attribute>
+ <dia:attribute name="is_portrait">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="scaling">
+ <dia:real val="1"/>
+ </dia:attribute>
+ <dia:attribute name="fitto">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ <dia:attribute name="grid">
+ <dia:composite type="grid">
+ <dia:attribute name="width_x">
+ <dia:real val="1"/>
+ </dia:attribute>
+ <dia:attribute name="width_y">
+ <dia:real val="1"/>
+ </dia:attribute>
+ <dia:attribute name="visible_x">
+ <dia:int val="1"/>
+ </dia:attribute>
+ <dia:attribute name="visible_y">
+ <dia:int val="1"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ <dia:attribute name="guides">
+ <dia:composite type="guides">
+ <dia:attribute name="hguides"/>
+ <dia:attribute name="vguides"/>
+ </dia:composite>
+ </dia:attribute>
+ </dia:diagramdata>
+ <dia:layer name="Background" visible="true">
+ <dia:object type="UML - LargePackage" version="0" id="O0">
+ <dia:attribute name="obj_pos">
+ <dia:point val="2.9,3.95"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="2.85,2.1;10.4,8.5"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="2.9,3.95"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="7.45"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="4.5"/>
+ </dia:attribute>
+ <dia:attribute name="name">
+ <dia:string>#GEOR#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="stereotype">
+ <dia:string/>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="UML - LargePackage" version="0" id="O1">
+ <dia:attribute name="obj_pos">
+ <dia:point val="13.8,3.75"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="13.75,1.9;21.1,8.4"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="13.8,3.75"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="7.25"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="4.6"/>
+ </dia:attribute>
+ <dia:attribute name="name">
+ <dia:string>#GOAT#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="stereotype">
+ <dia:string/>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="UML - LargePackage" version="0" id="O2">
+ <dia:attribute name="obj_pos">
+ <dia:point val="3.1,11.1"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="3.05,9.25;11,15.8"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="3.1,11.1"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="7.85"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="4.65"/>
+ </dia:attribute>
+ <dia:attribute name="name">
+ <dia:string>#GEMA#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="stereotype">
+ <dia:string/>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="UML - LargePackage" version="0" id="O3">
+ <dia:attribute name="obj_pos">
+ <dia:point val="25.1,3.65"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="25.05,1.8;32.35,8.35"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="25.1,3.65"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="7.2"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="4.65"/>
+ </dia:attribute>
+ <dia:attribute name="name">
+ <dia:string>#GEOR#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="stereotype">
+ <dia:string/>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="UML - LargePackage" version="0" id="O4">
+ <dia:attribute name="obj_pos">
+ <dia:point val="23.8,11.35"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="23.75,9.5;35.1,16.8"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="23.8,11.35"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="11.25"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="5.4"/>
+ </dia:attribute>
+ <dia:attribute name="name">
+ <dia:string>#Security Adapter#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="stereotype">
+ <dia:string/>
+ </dia:attribute>
+ </dia:object>
+ <dia:object type="UML - LargePackage" version="0" id="O5">
+ <dia:attribute name="obj_pos">
+ <dia:point val="13.6,11.3"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="13.55,9.45;22.25,16.45"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="13.6,11.3"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="8.6"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="5.1"/>
+ </dia:attribute>
+ <dia:attribute name="name">
+ <dia:string>#GNURPC#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="stereotype">
+ <dia:string/>
+ </dia:attribute>
+ </dia:object>
+ </dia:layer>
+</dia:diagram>
Added: branches/gnue-appserver-featuretest/geasarch/neilt-arch-explanation.txt
===================================================================
--- branches/gnue-appserver-featuretest/geasarch/neilt-arch-explanation.txt
2004-03-08 10:18:50 UTC (rev 5258)
+++ branches/gnue-appserver-featuretest/geasarch/neilt-arch-explanation.txt
2004-03-08 10:28:53 UTC (rev 5259)
@@ -0,0 +1,63 @@
+
+Reinhard ask for definitions to support the drawing at:
+http://www.gnuenterprise.org/modules.php?op=modload&name=NS-My_eGallery&file=index&do=showpic&pid=31
+
+So here goes.
+
+
+GEAS v2
+--------
+Database Adapter - Adapter for each type of database that works with
+GNUe. Handles unique or special requirements of a particular
+database. This should be very similar to if not use the database
+programs in "common".
+
+SQL Schema Generator - Generate SQL for interfacing with SQL
+database. This may be unique for each database (I am not sure at
+this point) or groups of databases.
+
+Object Repository - A way to store object definitions (currently .gcd
+files). But could also be XML.
+
+Object Server - Implements business object abstraction (the model) in
+a model view controller architecture. Hides all SQL relationships,
+joins, and tables from the UI. Allows multiple table definitions for
+a single business object (new from GEASv1). Security is enforced at
+the Object Server.
+
+Remote Protocol Adapter - Implements CORBA or other RPC type protocol
+over the network.
+
+Method Language Adapter - An adapter to allow methods written in
+various languages (C, C++, Python, Objective-C etc.) (I have to add
+this to the Drawing.)
+
+
+Future Items
+------------
+Batch Schema Compilers - A one-time program that converts items in
+the object repository to SQL tables, columns, triggers, store
+procedures etc. It also compiles methods if necessary and registers
+them with the Object Server. The primary purpose of this component
+is to not burden the Object Server startup with having to sort
+through possible changes to the Object Repository.
+
+Transaction Processor - Accepts database transactions from SQL Schema
+Generator for formatting and storage. In early versions this may be
+a simple logging server. This is simple to implement and will
+off-load the file access work from the main server. When the
+Synchronization Engine is working this process will also determine
+the need to keep certain transactions. If they are not need for
+Synchronization then the transaction may not be kept (depending on
+the configuration).
+
+Synchronization Engine - Applies transactions from the Transaction
+Processor to backup databases or remote database based on the
+configuration of the Synchronization Engine. Required for CRM
+applications. This is the process or server that a remote user or
+remote database will connect to get updates.
+
+Workflow Server - A Server that defines workflow rules including
+triggers in the SQL database (if the capability exists) and or
+monitors objects to determine when to invoke methods or other data
+transformations without user interaction.
Added: branches/gnue-appserver-featuretest/geasarch/odmg.txt
===================================================================
--- branches/gnue-appserver-featuretest/geasarch/odmg.txt 2004-03-08
10:18:50 UTC (rev 5258)
+++ branches/gnue-appserver-featuretest/geasarch/odmg.txt 2004-03-08
10:28:53 UTC (rev 5259)
@@ -0,0 +1,2251 @@
+ODMG
+====
+
+ Object Model
+ ============
+ - Object Model important because it specifies kinds of semantics
+ that can be defined explicitly to an ODMS (Object Data
+ Management System)
+ - Object Model determines characteristics of objects, how objects
+ can be related to each other, and how objects can be named and
+ identified
+ - Object Definition Language (ODL) is used to specify application
+ object models and is also used to explain the constructs of the
+ Object Model defined here
+ - Object Model specifies constructs supported by ODMS:
+
+ - basic modeling primitives are the *object* and *literal*, each
+ object has a unique identifier, a literal has no identifier
+ - objects and literals can be categorized by their *types*, all
+ elements of a given type have common range of states (i.e., same
+ set of properties) and common behavior (i.e., same set of defined
+ operations), object sometimes referred to as *instance* of its
+ type
+ - behavior of object defined by set of operations, that can be
+ executed on or by the object, operations have list of input and
+ output parameters, each with specified type, each operation may also
+ return a typed result
+ - ODMS stores objects, enabling them to be shared by multiples
+ users and applications, ODMS based on *schema* defined in ODL and
+ contains instances of types defined by its schema
+ - application's object model is ODMS's (logical) schema
+ - ODMG Object Model is fundamental definition of ODMS's
+ functionality
+ - includes richer semantics than relational model, by declaring
+ relationships and operations explicitly
+
+ Types: Specifications and Implementations
+ =========================================
+ - 2 aspects to the definition of a type: an external *specification*
+ and one or more *implementations*
+ - specification defines external characteristics: *operations* that
+ can be invoked on its instances, *properties*, or state variables,
+ whose values can be accessed, and any *exceptions* that can be raised
+ by its operations
+ - *interface* definition is a specification that defines only
+ abstract behavior of an object type
+ - *class* definition is a spec that defines abstract behavior and
+ abstract state of an object type
+ - *class* is extended interface with information for ODMS schema
+ definition
+ - *literal* definition defines only abstract state of a literal type
+ - example:
+
+ interface Employee {...};
+ class Person {...};
+ struct Complex {float re; float im;};
+
+ interface Employee only defines the abstract behavior of Employee
+ objects, Class Person defines both the abstract behavior and the
+ abstract state of Person objects, the struct Complex defines only
+ the abstract state of Complex number literals, in addition to the
+ struct definition and the primitive literal 0 (boolean, char,
+ short, long, float, double, octet, and string), ODL defines
+ declarations for user-defined collection, union, and enumeration
+ literal types.
+ - can also be methods in an implementation that have no direct
+ counterpart to the operations in the type's spec, internals of an
+ implementation are not visible to the users of the object
+ - separating the specs form the implementations keeps the semantics
+ of the type from being tangled with representation details,
+ separating the specs form the implementations is a positive step
+ toward multilingual access to objects of a single type and sharing
+ of objects across heterogeneous computing environments
+
+ Subtyping and inheritance of Behavior
+ =====================================
+ - ODMG Object 1 includes inheritance-based type-subtype relationships
+ - the relationships are commonly represented in graphs; each node
+ is a type and each arc connects one type, *supertype* and another
+ type *subtype*
+ - type-subtype relationship sometimes called is-a relationship, or
+ an ISA relationship
+ - sometimes called *generalization-specialization* relationship
+ - supertype is the more general type, subtype is the more
+ specialized type
+ - e.g.,
+
+ interface Employee {...};
+ interface Professor: Employee {...};
+ interface Associate_Professor: Professor {...};
+
+ - Associate_Professor is a subtype of Professor; Professor is a
+ subtype of employee
+ - instance of the subtype is logically instance of the supertype
+ - Associate_Professor is instance is logically Professor instance
+ - Associate_Professor is special case of Professor
+ - subtype's interface can also be refined to specialize state and
+ behavior
+ - e.g, a Employee might have an operation for calculate_paycheck
+ - Salaried_Employee and Hourly_Employee might each refine that
+ behavior to specific needs
+ - polymorphic nature of object programming would enable to correct
+ behavior to be invoked at runtime, dependent on the actual type of
+ the instance
+
+ class Salaried_Employee: Employee {...};
+ class Hourly_Employee: Employee {...};
+
+ - ODMG model supports multiple inheritance of object behavior
+ - which leaves it possible to inherit operations that have the same
+ name, but different parameters from 2 interfaces
+ - ODMG disallows name overloading during inheritance
+ - ODL classes are directly instantiable, interface and types cannot
+ be directly instantiated
+ - subtyping refers to inheritance of behavior only; consequently
+ interfaces may only inherit from interfaces and classes may only
+ inherit from interfaces
+ - due to ambiguities, interfaces may not inherit from classes nor
+ may classes inherit from other classes
+
+ Inheritance of State
+ ====================
+ - ODMG Object Model defines and EXTENDS relationship for the
+ inheritance of state and behavior
+ - the EXTENDS also applies to only *object* types, only classes,
+ not literals, may inherit state
+ - EXTENDS relationship is single inheritance relationship between
+ classes whereby subordinate class inherits all properties and
+ behavior of class that it extends
+ - e.g.,
+
+ class Person
+ {
+ attribute string name;
+ attribute Date birthDate;
+ };
+
+ // in the following, the colon denotes the ISA relationship
+ // the extends denotes the EXTENDS relationship
+ class EmployeePerson extends Person: Employee
+ {
+ attribute Date hireDate;
+ attribute Currency payRate;
+ relationship Manager boss inverse manager::subordinates;
+ };
+
+ class ManagerPerson extends EmployeePerson: Manager
+ {
+ relationship set<Employee> subordinates
+ inverse Employee::boss;
+ };
+
+ - EXTENDS relationship is transitive; consequently every
+ ManagerPerson would have a name, a birthDate, a payRate, and a
+ boss
+ - note that since class EmployeePerson inherits behavior from (ISA)
+ Employee, instances of EmployeePerson and ManagerPerson would
+ all support the behavior defined within this interface
+ - only legal exception to name-overloading prohibition occurs when the same
+ property declaration occurs in a class and in one of its inherited
+ interfaces
+ - since properties declared within an interface also have a
+ procedural interface, such redundant declarations are useful
+ in situations where it is desirable to allow relationships to
+ cross distribution boundaries, yet they also constitute part of the
+ abstract state of the object
+
+ Extents
+ =======
+ - *extent* of a type is set of all instances of the type within
+ a particular ODMS
+ - if object is instance of type A, then it will of necessity be
+ a member of the extent of A
+ - if type A is subtype of type B, then extent of A is a subset
+ of the extent of B
+ - relational DBMS maintains an extent for every defined table
+ - ODMS schema designer can decide whether the system should
+ automatically maintain the extent of each type
+
+ Keys
+ ====
+ - in some cases, individual instances of a type can be uniquely
+ identified by the values they carry for some property or set of
+ properties
+ - these identifying properties are called *keys*
+ - in relational model, properties are called *candidate keys*
+ - a *simple key* consists of a single property
+ - a *compound key* consists of a set of properties
+ - the scope of uniqueness is the extent of the type; type must
+ have an extent to have a key
+
+ Objects
+ =======
+ - all objects are grouped into an enclosing module that defines a
+ name scope for the types of the model:
+
+ module ODLTypes
+ {
+ exception DatabaseClosed{};
+ exception TransactionInProgress{};
+ exception TransactionNotInProgress{};
+ exception IntegrityError{};
+ exception LockNotGranted{};
+
+ // the following interfaces and classes are defined here
+ };
+
+ Object Creation
+ ===============
+ - objects created by invoking creation operations on *factory
+ interfaces*
+ - the "new" operation causes the creation of a new instance of an
+ object of the "Object" type
+
+ interface ObjectFactory
+ {
+ Object new();
+ };
+
+ - All objects have following ODL interface which is implicitly
+ inherited by all user-defined types
+
+ interface Object
+ {
+ enum Lock_Type{read, write, upgrade};
+
+ // Obtains a specific lock on an object. If an attempt is made
+ // to get a lock on an already locked object, this operation
+ // will block until the specified lock can be acquired, some
+ // time-out threshold is exceeded, or a transaction deadlock is
+ // detected. If the time-out threshold is crossed a
+ // LockNotGranted exception is raised, If a transaction
+ // deadlock is detected, the transaction deadlock exception is raised.
+ void lock(in Lock_Type mode) raises(LockNotGranted);
+
+ // Returns TRUE if specified lock was obtained and FALSE if
+ // the lock is in conflict with an existing lock on the object
+ boolean try_lock(in Lock_type mode);
+
+ // Compares the identity of this object with another
+ boolean same_as(in Object anObject);
+
+ // Creates a new object that is equivalent to the receiver
+ // object, the new object is not the "same_as" the original object
+ Object copy();
+
+ // Explicitly deletes an object from an ODMS by removing it
+ // from memory in addition to the ODMS
+ void delete();
+ };
+
+ - default ODMG locking policy is implicit, all ODMG objects support
+ explicit locking operations
+ - IntegrityError exception is raised by operations on
+ relationships and signifies that referential integrity has
+ been violated
+ - access, creation, modification, and deletion of persistent
+ objects must be done within scope of transaction
+ - if attempted outside transaction, TransactionNotInProgress
+ exception is raised
+ - it is assumed that all operations defined on persistent objects
+ have the ability to raise the TransactionNotInProgress exception
+
+ Object Identifiers
+ ===================
+ - all objects have identifiers, an object can always be
+ distinguished from all other objects within its *storage domain*
+ - all identifiers in an ODMS are unique, relative to each other
+ - representation of the of an object referred to as an *object
+ identifier*
+ - an object retains the same identifier throughout its entire life
+ time
+ - value of an object's identifier will never change
+ - object remains the same object even if its attribute values or
+ relationships change
+ - an OID is commonly used as a means for one object to reference
+ another
+ - literals do not have their own identifiers and cannot stand
+ alone as objects; they are embedded in objects and cannot be
+ individually referenced
+ - literals values are described as being constant
+ - literals are *immutable*; objects are *mutable*
+ - changing values of attributes of an object. or the relationships
+ in which it participates, does not change the identity of the
+ object
+ - OIDs are generated by the ODMS
+ - operation "same_as" is supported, which allows any 2 objects to
+ be compared
+
+ Object Names
+ ============
+ - an object may be given one or two names that are meaningful to
+ the programmer or end user
+ - ODMS provides a function to map an object name to an object
+ - application can refer at its convenience to an object by name;
+ ODMS applies the mapping function to determine the OID that
+ locates the desired object
+ - ODMS expects names to be commonly used by applications to refer
+ to "root" objects, which provide entry points into the ODMS
+ - object name, by contrast, not a defined type interface and does
+ not correspond to an objects property values
+ - scope of uniqueness of names is an ODMS
+ - Object Model does not include a notion of hierarchical names
+ within an ODMS or of name spaces that span ODMSs
+
+ Object Lifetimes
+ ================
+ - 2 life times are supported in the Object Model:
+ - transient
+ - persistent
+ - *transient* is allocated memory that is managed by the
+ programming language runtime system
+ - when the process/procedure terminates that created the transient
+ object, the memory is deallocated
+ - *persistent* lifetime is allocated memory and storage managed by
+ the ODMS runtime system
+ - these objects continue to exist after the procedure or process
+ that creates them terminates
+ - object lifetimes are independent of type; type may have some
+ instances that are persistent and other that are transient
+ - because ODMG Object Model supports independence of type and
+ lifetime, both persistent and transient objects can be manipulated
+ using the same operations (i.e., OQL)
+
+ Atomic Objects
+ ==============
+ - an atomic object type is user-defined; there are no built-in
+ atomic object types in the ODMG Object Model
+
+ Collection Objects
+ ==================
+ - in ODMG Object Model, instances of *collection objects* are
+ composed of distinct elements, each of which can be an instance of
+ an atomic type, another collection, or a literal type
+ - *all* elements of the collection must be of the *same* type
+ - either all the same atomic type or all of the same type of
+ collection, or all of the same literal type
+ - collections supported by ODMG Object Model include:
+ - Set<t>
+ - Bag<t>
+ - List<t>
+ - Array<t>
+ - Dictionary<t,v>
+ - each of these is a type generator, parameterized by the type
+ shown within the angle bracket
+ - all the elements of a Set object are of the same type 't'
+ - all elements of a List object are of the same type 't'
+ - collections are created by invoking operations of the 'factory'
+ interfaces defined for each particular collection
+
+ interface Collection: Object
+ {
+ exception InvalidCollectionType{};
+ exception ElementNotFound{};
+
+ // Returns the number elements contained in the collection
+ unsigned long cardinality();
+
+ // These methods provide means for dynamically querying a collection to
+ // obtain its characteristics
+ boolean is_empty();
+ boolean is_ordered();
+ boolean allows_duplicates();
+
+ // These methods provide support for element management within a
collection
+ boolean contains_element(in Object element);
+ void insert_element(in Object element);
+ void remove_element(in Object element)
raises(ElementNotFound);
+
+ // These methods support the traversal of elements within a
+ // collection. Creates Iterators that support forward-only
+ // traversals on all collections and bidirectional traversals of
+ // ordered collections
+ Iterator create_iterator(in boolean stable);
+ BidirectionalIterator create_bidirectional_iterator(in boolean stable)
+
raises(InvalidCollectionType);
+
+ // These methods are used to evaluate OQL predicates upon a the
+ // contents of a collection. The boolean results of 'query' and
+ // 'exists_element' methods indicate whether any elements were
+ // found as a result of performing the OQL query
+ Object select_element(in string OQL_predicate);
+ Iterator select(in string OQL_predicate);
+ boolean query(in string OQL_predicate,
+ inout Collection result);
+ boolean exists_element(in string OQL_predicate);
+ };
+
+ - Collection objects also inherit the operations in the Object
+ interface
+ - identity comparisons are done using the 'same_as' operation
+ - a 'copy' of a Collection returns a new shallow copy of the
+ collection
+ - 'delete' operation removes the collection from the ODMS, and if
+ the collection contains literals, also deletes the contents of
+ the collection, if the collection contains objects, the
+ collection remains unchanged
+
+ - an Iterator, which is a mechanism for accessing elements of a
+ Collection object, can be created to traverse the collection
+
+ interface Iterator
+ {
+ exception NoMoreElements{};
+ exception InvalidCollectionType{};
+
+ // Determines whether an iteration is safe from changes made
+ // to the collection during iteration, a stable iterator
+ // ensures that modifications made to a collection during
+ // iteration will not effect traversal, if an iterator is not
+ // stable, the iteration only supports retrieving elements from a
+ // collection during traversal, as changes made to the collection
+ // during iteration may result in missed elements or double
+ // processing of an element
+ boolean is_stable();
+
+ boolean at_end();
+
+ // Repositions the iterator to the first element in the iteration
+ void reset();
+
+ // Retrieves the element currently pointed to by the iterator
+ Object get_element() raises(NoMoreElements);
+
+ // Increments the iterator to the next element in the iteration
+ void next_position() raises(NoMoreElements);
+
+ // This is valid only when iterating over an Array or List, it
+ // replaces the element currently pointed to by the iterator with
+ // the argument object
+ void replace_element(in Object element)
+ raises(InvalidCollectionType);
+ };
+
+ interface BidirectionalIterator: Iterator
+ {
+ boolean at_beginning();
+
+ // Decrements the iterator to the previous element in the iteration
+ void previous_position() raises(NoMoreElements);
+ };
+
+ Set Objects
+ ===========
+ - set object is an unordered collection of elements, with no
+ duplicates allowed
+ interface SetFactory: ObjectFactory
+ {
+ Set new_of_size(in long size);
+ };
+
+ class Set: Collection
+ {
+ attribute set<t> value;
+
+ // These methods return a new result Set object after applying the
+ // mathematical operation
+ Set create_union(in Set other_set);
+ Set create_intersection(in Set other_set);
+ Set create_difference(in Set other_set);
+
+ // Subsetting and supersetting boolean tests
+ boolean is_subset_of(in Set other_set);
+ boolean is_proper_subset_of(in Set other_set);
+ boolean is_superset_of(in Set other_set);
+ boolean is_proper_superset_of(in Set other_set);
+ };
+
+ - Set refines semantics of 'insert_element' operation inherited
+ from Collection supertype, if object passed as argument to the
+ 'insert_element' operation is not already a member of the set,
+ the object is added to the set, otherwise the set remains
+ unchanged
+
+ Bag Objects
+ ===========
+ - an unordered collection of objects that may contain duplicates
+
+ interface BagFactory: ObjectFactory
+ {
+ Bag new_of_size(in long size);
+ };
+
+ class Bag: Collection
+ {
+ attribute bag<t> value;
+
+ // Calculates the number of times a specific element occurs in
+ // the Bag
+ unsigned long occurrences_of(in Object element);
+
+ // These methods return a new result Bag object after applying the
+ // mathematical operation
+ Bag create_union(in Bag other_bag);
+ Bag create_intersection(in Bag other_bag);
+ Bag create_difference(in Bag other_bag);
+ };
+
+ - Bag refines semantics of 'insert_element' and 'remove_element'
+ operation inherited from Collection supertype. 'insert_element'
+ operation inserts into the 'Bag' object the element passed as an
+ argument , if the element is already a member of the bag, it is
+ inserted another time increasing the multiplicity in the
+ bag. 'remove_element' operation removes one occurrence of the
+ specified element from the bag.
+
+ List Objects
+ ============
+ - List object is ordered collection of elements
+ - the operations defined in the List interface are positional in
+ nature
+ - indexing of a List object starts at 0
+
+ interface ListFactory: ObjectFactory
+ {
+ List new_of_size(in long size);
+ };
+
+ class List: Collection
+ {
+ exception InvalidIndex{unsigned long index; };
+
+ attribute list<t> value;
+
+ void remove_element_at(in unsigned long index)
+ raises(InvalidIndex);
+
+ Object retrieve_element_at(in unsigned long index)
+ raises(InvalidIndex);
+
+ void replace_element_at(in Object element, in unsigned long index)
+ raises(InvalidIndex);
+
+ void insert_element_after(in Object element,
+ in unsigned long index)
+ raises(InvalidIndex);
+
+ void insert_element_before(in Object element,
+ in unsigned long index)
+ raises(InvalidIndex);
+
+ void insert_element_first(in Object element);
+
+ void insert_element_last(in Object element);
+
+ void remove_first_element() raises(ElementNotFound);
+
+ void remove_last_element() raises(ElementNotFound);
+
+ Object retrieve_first_element() raises(ElementNotFound);
+
+ Object retrieve_last_element() raises(ElementNotFound);
+
+ // Returns a new List object that contains other_list appended to
+ // the this list, both this and other_list remain unchanged
+ List concat(in List other_list);
+
+ // Modifies this list by appending other_list
+ void append(in List other_list);
+ };
+
+ - List refines semantics of 'insert_element' and 'remove_element'
+ operation inherited from Collection supertype. 'insert_element'
+ operation inserts the specified object at the end of the list,
+ semantics of this operation are equivalent to
+ 'insert_element_last', 'remove_element' operation removes the
+ first occurrence of the specified object from the list
+
+ Array Objects
+ =============
+ - Array object is a dynamically sized, ordered collection of
+ elements that can be located by position
+
+ interface ArrayFactory: ObjectFactory
+ {
+ Array new_of_size(in long size);
+ };
+
+ class Array: Collection
+ {
+ exception InvalidIndex{unsigned long index; };
+
+ exception InvalidSize{unsigned long size; };
+
+ attribute array<t> value;
+
+ void replace_element_at(in unsigned long index,
+ in Object element)
+ raises(InvalidIndex);
+
+ // Replaces any current element contained in the cell of the
+ // Array object identified by index with an undefined value,
+ // it does not remove the cell or change the size of the array
+ void remove_element_at(in unsigned long index)
+ raises(InvalidIndex);
+
+ Object retrieve_element_at(in unsigned long index)
+ raises(InvalidIndex);
+
+ // Enables an Array object to change the maximum number of
+ // elements it can contain. The exception InvalidSize is
+ // raised, if the value of the new_size parameter is smaller
+ // than the actual number of elements currently contained in the array
+ void resize(in unsigned long new_size)
+ raises(InvalidSize);
+ };
+
+ - Array refines semantics of 'insert_element' and 'remove_element'
+ operation inherited from Collection supertype. 'insert_element'
+ increases the size of the array by one and inserts the
+ specified object in the new position, 'remove_element' replaces
+ the first occurrence of the specified object in the array with an
+ undefined value
+
+ Dictionary Objects
+ ==================
+ - Dictionary object is an unordered sequence of key-value
+ pairs with no duplicate keys
+ - Each key-value pair is constructed as an instance of the
+ following structure:
+ struct Association {Object key; Object value; };
+
+ - iterating over a Dictionary object will result in the iteration
+ over a sequence of Associations, each 'get_element' operation
+ executed on an 'Iterator' object returns a struct of type
+ Association
+
+ interface DictionaryFactory: ObjectFactory
+ {
+ Dictionary new_of_size(in long size);
+ };
+
+ class Dictionary: Collection
+ {
+ exception DuplicateName{string key; };
+
+ exception KeyNotFound{Object key; };
+
+ attribute dictionary<t,v> value;
+
+ // These methods handle inserting, deleting, and selecting
+ // entries in a Dictionary object, respectively.
+ void bind(in Object key, in Object value)
+ raises(DuplicateName);
+ void unbind(in Object key) raises(KeyNotFound);
+ Object lookup(in Object key) raises(KeyNotFound);
+
+ // Tests for the existence of a specific key in the Dictionary object
+ boolean contains_key(in Object key);
+
+ };
+
+ - Dictionary refines semantics of 'insert_element',
+ 'remove_element', and 'contains_element' operations inherited
+ from its Collection supertype. All of these operations are valid
+ for Dictionary types when an Association is specified as the
+ argument. 'insert_element' inserts an entry into the Dictionary
+ that reflects the key-value pair contained in the Association
+ parameter. If the key already resides in the Dictionary, the
+ existing entry is replaced. 'remove_element' removes the entry
+ from the Dictionary that matches the key-value pair contained in
+ the Association passed as the argument. If a matching key-value
+ pair entry is not found in the Dictionary, the ElementNotFound
+ exception is raised. 'contain_element' operation also uses both
+ the key and the value contained in the Association argument to
+ locate a particular entry in the Dictionary object. A boolean is
+ returned specifying whether the key-value pair exists in the
+ Dictionary.
+
+ Structured Objects
+ ==================
+ - all structured objects support Object ODL interface
+ - ODMG Object Model supports the following types:
+
+ * Date
+ * Interval
+ * Time
+ * Timestamp
+
+ - these types are defined as in INCITS SQL specification by the
+ following interfaces.
+
+ Date
+ ====
+ - factory interface for creating Date objects:
+
+ interface DateFactory: ObjectFactory
+ {
+ exception InvalidDate{};
+
+ Date julian_date(in unsigned short year,
+ in unsigned short julian_day)
+ raises(InvalidDate);
+
+ Date calendar_date(in unsigned short year,
+ in unsigned short month,
+ in unsigned short day)
+ raises(InvalidDate);
+
+ boolean is_leap_year(in unsigned short year);
+
+ boolean is_valid_date(in unsigned short year,
+ in unsigned short month,
+ in unsigned short day);
+
+ unsigned short days_in_year(in unsigned short year);
+
+ unsigned short days_in_month(in unsigned short year,
+ in Date::Month month);
+
+ Date current();
+ };
+
+ - following interface defines the operations on Date objects:
+
+ class Date: Object
+ {
+ enum Weekday{Sunday, Monday, Tuesday, Wednesday,
+ Thursday, Friday, Saturday};
+
+ enum Month{January, February, March, April, May,
+ June, July, August, September, October,
+ November, December};
+
+ attribute date value;
+
+ unsigned short year();
+
+ unsigned short month();
+
+ unsigned short day();
+
+ unsigned short day_of_year();
+
+ Month month_of_year();
+
+ Weekday day_of_weeks();
+
+ boolean is_leap_year();
+
+ boolean is_equal(in Date a_date);
+
+ boolean is_greater(in Date a_date);
+
+ boolean is_greater_or_equal(in Date a_date);
+
+ boolean is_less(in Date a_date);
+
+ boolean is_less_or_equal(in Date a_date);
+
+ boolean is_between(in Date a_date, in Date b_date);
+
+ Date next(in Weekday day);
+
+ Date previous(in Weekday day);
+
+ Date add_days(in long days);
+
+ Date subtract_days(in long days);
+
+ Date subtract_date(in Date a_date);
+ };
+
+ Interval
+ ========
+ - intervals represent a duration of time and are used to perform
+ some operations on Time and Timestamp objects, Intervals are
+ created using the 'subtract_time' operation defined in the Time
+ interface
+
+ class Interval: Object
+ {
+ attribute interval value;
+
+ unsigned short day();
+
+ unsigned short hour();
+
+ unsigned short minute();
+
+ unsigned short second();
+
+ unsigned short millisecond();
+
+ boolean is_zero();
+
+ Interval plus(in Interval an_interval);
+
+ Interval minus(in Interval an_interval);
+
+ Interval product(in long val);
+
+ Interval quotient(in long val);
+
+ boolean is_equal(in Interval an_interval);
+
+ boolean is_greater(in Interval an_interval);
+
+ boolean is_greater_or_equal(in Interval an_interval);
+
+ boolean is_less(in Interval an_interval);
+
+ boolean is_less_or_equal(in Interval an_interval);
+ };
+
+ Time
+ ====
+ - Times denote specific world items which are internally stored
+ as GMT, timezones specified as number of hours to subtract form
+ local time to get GMT.
+
+ - Time factory interface:
+
+ interface TimeFactory: ObjectFactory
+ {
+ void set_default_time_zone(in TimeZone a_time_zone);
+
+ TimeZone default_time_zone();
+
+ TimeZone time_zone();
+
+ Time from_hmsm(in unsigned short hour,
+ in unsigned short minute,
+ in unsigned short second,
+ in unsigned short millisecond);
+
+ Time from_hmsmtz(in unsigned short hour,
+ in unsigned short minute,
+ in unsigned short second,
+ in unsigned short millisecond,
+ in short tzhour,
+ in short tzminute);
+
+ Time current();
+ };
+
+ - Time interface:
+
+ class Time: Object
+ {
+ attribute time value;
+
+ typedef short TimeZone;
+
+ const TimeZone GMT = 0;
+ const TimeZone GMT1 = 1;
+ const TimeZone GMT2 = 2;
+ const TimeZone GMT3 = 3;
+ const TimeZone GMT4 = 4;
+ const TimeZone GMT5 = 5;
+ const TimeZone GMT6 = 6;
+ const TimeZone GMT7 = 7;
+ const TimeZone GMT8 = 8;
+ const TimeZone GMT9 = 9;
+ const TimeZone GMT10 = 10;
+ const TimeZone GMT11 = 11;
+ const TimeZone GMT12 = 12;
+ const TimeZone GMT_1 = -1;
+ const TimeZone GMT_2 = -2;
+ const TimeZone GMT_3 = -3;
+ const TimeZone GMT_4 = -4;
+ const TimeZone GMT_5 = -5;
+ const TimeZone GMT_6 = -6;
+ const TimeZone GMT_7 = -7;
+ const TimeZone GMT_8 = -8;
+ const TimeZone GMT_9 = -9;
+ const TimeZone GMT_10 = -10;
+ const TimeZone GMT_11 = -11;
+ const TimeZone GMT_12 = -12;
+ const TimeZone USeastern = -5;
+ const TimeZone UScentral = -6;
+ const TimeZone USmountain = -7;
+ const TimeZone USpacific = -8;
+
+ unsigned short hour();
+
+ unsigned short minute();
+
+ unsigned short second();
+
+ unsigned short millisecond();
+
+ short tz_hour();
+
+ short tz_minute();
+
+ boolean is_equal(in Time a_time);
+
+ boolean is_greater(in Time a_time);
+
+ boolean is_greater_or_equal(in Time a_time);
+
+ boolean is_less(in Time a_time);
+
+ boolean is_less_or_equal(in Time a_time);
+
+ boolean is_between(in Time a_time, in Time b_time);
+
+ Time add_interval(in Interval an_interval);
+
+ Time subtract_interval(in Interval an_interval);
+
+ Interval subtract_time(in Time a_time);
+ };
+
+ Timestamp
+ =========
+ - Timestamp consists of encapsulated Date and Time
+ - Timestamp factory interface:
+
+ interface TimestampFactory: ObjectFactory
+ {
+ exception InvalidTimestamp{Date a_date, Time a_time; };
+
+ Timestamp current();
+
+ Timestamp create(in Date a_date, in Time a_time)
+ raises(InvaildTimestamp);
+ };
+
+ - Timestamp interface
+
+ class Timestamp: Object
+ {
+ attribute timestamp value;
+
+ Date get_date();
+
+ Date get_time();
+
+ unsigned short year();
+
+ unsigned short month();
+
+ unsigned short day();
+
+ unsigned short hour();
+
+ unsigned short minute();
+
+ unsigned short second();
+
+ unsigned short millisecond();
+
+ short tz_hour();
+
+ short tz_minute();
+
+ Timestamp plus(in Interval an_interval);
+
+ Timestamp substract(in Interval an_interval);
+
+ boolean is_equal(in Timestamp a_timestamp);
+
+ boolean is_greater(in Timestamp a_timestamp);
+
+ boolean is_greater_or_equal(in Timestamp a_timestamp);
+
+ boolean is_less(in Timestamp a_timestamp);
+
+ boolean is_less_or_equal(in Timestamp a_timestamp);
+
+ boolean is_between(in Timestamp a_timestamp,
+ in Timestamp b_timestamp);
+ };
+
+ Literals
+ ========
+ - standard considers each of the following aspects of literals
+
+ * types
+ * copying
+ * comparing
+ * equivalence
+
+ Literal Types
+ =============
+ - Object Model supports:
+
+ * atomic literal
+ * collection literal
+ * structured literal
+
+ Atomic Literals
+ ===============
+ - numbers and characters are examples
+ - instances of these types are not explicitly created by
+ applications, but implicitly exist
+ - ODMG Object Model supports the following types of atomic
+ literals:
+
+ * long
+ * long long
+ * short
+ * unsigned long
+ * unsigned short
+ * float
+ * double
+ * boolean
+ * octet
+ * char (character)
+ * string
+ * enum (enumeration)
+
+ - these types are also supported by OMG IDL
+
+ Collection Literals
+ ===================
+ - ODMG Object Model supports the following collection literals:
+
+ * set<t>
+ * bag<t>
+ * list<t>
+ * array<t>
+ * dictionary<t,v>
+
+ - these type generators are analogous of their collection objects
+ except they do not have OIDs
+ - their elements can be of literal or object type
+
+ Structured Literals
+ ===================
+ - structured literal or structure has fixed number of elements,
+ each of which has a variable name and can contain either literal
+ or an object.
+ - Structure types supported by ODMG Object Model include:
+
+ * date
+ * interval
+ * time
+ * timestamp
+
+ User-Defined Structures
+ =======================
+ - because object model is extensible, you can define you own structs
like:
+
+ struct Address
+ {
+ string dorm_name;
+ string room_no;
+ };
+
+ - structures may be freely composed, Object Model supports sets
+ of structures, structures of sets, arrays of structures, etc.
+ - e.g.,
+
+ struct Degree {...};
+
+ typedef list<Degree> degrees;
+
+ Copying Literals
+ ================
+ - literals do not have OIDs and therefore cannot be shared,
+ literals do have copy semantics
+ - when iterating through a collection of literals, copies of the
+ elements are returned
+ - when returning a literal-valued attribute of an object, a copy
+ of the literal value is returned
+
+ Comparing Literals
+ ==================
+ - since literals do not have OIDs (not objects) they cannot be
+ compared by identity (same_as operation)
+ - they are compared using the 'equals' equivalence operation
+ - this becomes important for collection management, e.g., when
+ inserting, removing, or testing for membership in a collection of
+ literals the 'equals' operations is used rather than the identity
+ operation 'same_as'
+
+ Literal Equivalence
+ ===================
+ - two literals, x and y, are equivalent if they have the same
+ literal type and
+
+ * are both atomic and contain the same value
+
+ * are both sets, have the same parameter type 't', and
+
+ * if 't' is a literal type, then for each element in 'x',
+ there is an element 'y' that is equivalent to it, and for each
+ element 'y', there is an element 'x' that is equivalent to
+ it
+
+ * if 't' is an Object type, then both 'x' and 'y' contain the
+ same set of OIDs
+
+ * are both bags, have the same parameter type 't', and
+
+ * if 't' is a literal type, then for each element 'x', there
+ is an element in 'y' that is equivalent to it, and for each
+ element in 'y' there is an element in 'x' that is equivalent
+ to it. In addition, for each literal appearing more than
+ once in 'x', there is an equivalent literal occurring the same
+ number of times in 'y'
+
+ * if 't' is an Object type, then both 'x' and 'y' contain the
+ same set of oids, In addition, for each oid appearing more
+ than once in 'x', there is an identical oid appearing the same
+ number of times in 'y'
+
+ * are both arrays or lists, have the same parameter type 't',
+ and for each entry 'i'
+
+ * if 't' is a literal type, then x[i] is equivalent to y[i]
+ (equal)
+
+ * if t is an object type, then x[i] is identical to y[i]
+ (same_as)
+
+ * are both dictionary literals, and when considering sets of
+ associations, the two sets are equivalent
+
+ * are both structs of the same type, and for each element 'j'
+
+ * if the element is a literal type, then x.j and y.j are
+ equivalent (equal)
+
+ * if the element is an object type, then x.j and y.j are
+ identical (same_as)
+
+ The Full Built-in Type Hierarchy
+ ================================
+ - type generators signified by angle brackets (e.g., Set<>)
+ - ODMG Object Model is strongly typed
+ - 2 objects or literals are the same type if they have been declared
+ to be instances of the same named type
+ - Type compatibility follows the subtyping relationships defined by
+ the type hierarchy (i.e, a derived type can be assigned to a variable
+ of the parent type, but no the reverse)
+ - No implicit conversions between types are provided by the Object
+ Model
+
+ NOTE: <<type>> denotes and abstract type
+
+ <<Literal_type>>
+ <<Atomic_literal>>
+ long
+ long long
+ short
+ unsigned long
+ unsigned short
+ float
+ double
+ boolean
+ octet
+ char
+ string
+ enum<>
+ <<Collection_literal>>
+ set<>
+ bag<>
+ list<>
+ array<>
+ dictionary<>
+ <<Structured_literal>>
+ date
+ time
+ timestamp
+ Interval
+ structure<>
+ <<Object_type>>
+ <<Atomic_object>>
+ <<Collection_object>>
+ Set<>
+ Bag<>
+ List<>
+ Array<>
+ Dictionary<>
+ <<Structured_object>>
+ Date
+ Time
+ Timestamp
+ Interval
+
+ Modeling State--Properties
+ ==========================
+ - class defines set of attributes through which users can access,
+ and in some cases directly manipulate, the state of the instances of
+ the class
+ - 2 kinds of properties are defined in ODMG Object Model: attribute
+ and relationship, attribute is of one type, whereas a relationship
+ is defined between 2 types, each of which must have instances which
+ are referenceable by oids
+
+ Attributes
+ ==========
+ - attribute declarations in a class define the abstract state of
+ its instances
+ - e.g., a Person might contain the following attributes:
+
+ class Person
+ {
+ attribute short age;
+ attribute string name;
+ attribute enum gender {male, female};
+ attribute Address home_address;
+ attribute set<Phone_no> phones;
+ attribute Department dept;
+ };
+
+ - a particular instance of a Person could have a specific value
+ for each of the defined attributes
+ - the value of dept above is the oid of an instance of
+ Department, attribute's value is always a literal or an object
+ - attributes are 'abstract' in a sense and can be implemented
+ as data structures or even methods, especially if they can be
+ calculated from other attributes
+
+ Relationships
+ =============
+ - ODMG Object Model supports only binary relationships, i.e.,
+ relationship between 2 types
+ - binary relationship may be one-to-one, one-to-many,
+ many-to-many, depending upon how many instances of each type
+ participate in the relationship
+ - relationships in the Object Model are similar
+ entity-relationship data modeling
+ - relationship defined explicitly by declaration of 'traversal
+ paths' that enable applications to use the logical connections
+ between the objects participating in the relationship
+ - traversal paths are declared in pairs, one for each direction of
+ the traversal of the relationship
+ - e.g., a professor teaches a course and a course is taught by a
+ professor:
+
+ class Professor
+ {
+ relationship set<Course> teaches
+ inverse Course::is_taught_by;
+ ...
+ };
+
+ and
+ class Course
+ {
+ relationship Professor is_taught_by
+ inverse Professor::teaches;
+ ...
+ };
+
+ - the fact that these traversal paths both apply to the same
+ relationship is indicated by the 'inverse' clause in both
+ declarations
+ - relationship defined by the 'teaches' and 'is_taught_by'
+ traversal paths is a one-to-many relationship between Professor
+ and Course objects, this cardinality is show in the traversal
+ path declarations
+ - Professor in stance is associated with a set of Course
+ instances via the teaches traversal path, Course instance is
+ associated with a single professor instance via the
+ 'is_taught_by' traversal path
+ - ODMS is responsible for maintaining referential integrity of
+ relationships, this means that if an object that participates
+ in a relationship is deleted then any traversal path to that
+ object must also be deleted
+ - attributes may be object based and may be used to implement
+ so-called unidirectional relationships, such constructions are
+ not considered to be true relationships in this standard,
+ relationships always guarantee referential integrity
+ - implementation of relationships is encapsulated by public
+ operations that 'form' and 'drop' members from the
+ relationship, plus public operations on the relationship target
+ classes to provide access to manage the required referential
+ integrity constraints
+ - when traversal path has cardinality "one", operations are
+ defined to form a relationship, to drop a relationship, and to
+ traverse the relationship
+ - when traversal path has cardinality "many", the object will
+ supports methods to add and remove elements form its traversal
+ path collection
+ - in order to facilitate use of ODL objects models in situations
+ where such models may cross distribution boundaries, we define
+ the relationship interface in purely procedural terms by
+ introducing a mapping rule form ODL relationships to equivalent
+ IDL constructions, each language binding will determine exact
+ manner in which these constructions are to be accessed
+ - declarations that occur within classes define abstract state
+ for accessing the relationship
+ - declarations that occur within interfaces define only the
+ operations of the relationship, not the state
+
+ Cardinality "One" Relationships
+ ===============================
+ - for relationships of cardinality one such as:
+
+ relationship X Y inverse Z;
+
+ we expand the relationship to an equivalent IDL attribute and
+ operation:
+
+ attribute Professor is_taught_by;
+ void form_X(in X target) raises(IntegrityError);
+ void drop_Y(in X target) raises(IntegrityError);
+
+ e.g., using the relationship in the Course interface from
+ before
+
+ attribute Professor is_taught_by;
+ void form_is_taught_by(in Professor aProfessor)
+ raises(IntegrityError);
+ void drop_is_taught_by(in Professor aProfessor)
+ raises(IntegrityError);
+
+ Cardinality "Many" Relationships
+ ================================
+ - for ODL relationships the cardinality "many" such as
+
+ relationship set<X> Y inverse Z;
+
+ - to convert these definitions into pure IDL, the ODL
+ collection need only be replaced by the keyword 'sequence'
+ Note the add_Y operation may raise an 'IntegrityError'
+ exception in the event the that the traversal is a set that
+ already contains a reference to the given target X, this
+ exception, if it occurs, will also be raised by the form_Y
+ operation that invoked the add_Y, e.g.
+
+ readonly attribute set<X> Y;
+ void form_Y(in X target) raises(IntegrityError);
+ void drop_Y(in X target) raises(IntegrityError);
+ void add_Y(in X target) raises(IntegrityError);
+ void remove_Y(in X target) raises(IntegrityError);
+
+ the relationship in the Professor interface from before would
+ result in:
+
+ readonly attribute set<Course> teaches;
+ void form_teaches(in Course aCourse) raises(IntegrityError);
+ void drop_teaches(in Course a Course) raises(IntegrityError);
+ void add_teaches(in Course aCourse) raises(IntegrityError);
+ void remove_teaches(in Course aCourse) raises(IntegrityError);
+
+ Modeling Behavior--Operations
+ =============================
+ - behavior specified as a set of operation signatures
+ - each signature defines the name of the operation, the name and
+ type of each of its arguments, the types of value(s) it
+ returned, and the names of any exceptions (error conditions) the
+ operation can raise
+ - ODMG Object Model specification for operations is identical to OMG
+ CORBA specifications for operations (in IDL)
+ - No notions of operations that exist independently of a type
+ in the Object Model
+ - operation name only need be unique within a single type
+ definition, thus different types can have operations with the same
+ name, these are called overloaded operations
+ - when an operations is invoked using an overloaded name, a specific
+ operation must be selected for execution
+ - this selection, sometimes called operation name resolution or
+ operations dispatching, is based on the most specific type of the
+ object supplied as the first argument of the actual call
+
+ Exception Model
+ ===============
+ - ODMG Object Model supports dynamically nested exception
+ handlers, using a termination model of exception handling
+ - operations can raise exceptions, and exceptions can communicate
+ exception results
+ - when an exception is raised, information on the cause of the
+ exception is passed back to the exception handler as properties of
+ the exception, control is as follows:
+
+ 1. The programmer declares an exception handler within scope 's'
+ capable of handling exceptions of type 't'
+ 2. An operation within a contained scope 's'' may "raise" an
+ exception of type 't'
+ 3. The exception is "caught" by the most immediately containing
+ scope that has an exception handler. the call stack is
+ automatically unwound by the runtime system out to the level
+ of the handler. memory is freed for all objects allocated in
+ intervening stack frames, any transactions begun within a
+ nested scope, that is, for an exception handler, are
+ aborted.
+ 4. when control reaches the handler, the handler may either
+ decide that it can handle the exception or pass it on
+ (re-raise it) to a containing handler
+
+ - exception handler that declares itself capable of handling
+ exceptions of type 't' will also be able to handle exceptions of
+ any subtype 't', programmer who requires more specific control
+ over exceptions of a specific subtype 't' may declare a handler
+ for this more specific subtype within a contained scope
+
+ Metadata
+ ========
+ - metadata is descriptive information about persistent objects that
+ defines the 'schema' of an ODMS
+ - metadata is used by ODMS to define structure of its object
+ storage, and at runtime, guide access to ODMS's persistent objects
+ - metadata is stored in an 'ODL Schema Repository', which is also
+ accessible to tools and applications using the same operations that
+ apply to user-defined types
+ - in OMG CORBA environments, similar metadata is stored in an IDL
+ repository
+
+ - following interfaces define the internal structure of an ODL
+ Schema Repository, these interfaces are defined in ODL using
+ 'relationships' that define the graph of interconnections between
+ 'meta objects', which are produced, for example, during ODL source
+ compilation
+ - while these relationships guarantee referential integrity of the
+ meta object graph, they do not guarantee its semantic integrity
+ or completeness
+ - in order to provide operations that programmers can use to
+ correctly construct valid schemas, several creation, addition, and
+ removal operations are defined that provide automatic linking and
+ unlinking of the required relationships and appropriate error
+ recovery in the event of semantic errors
+ - all meta object definitions defined below are in the following
+ module:
+
+ module ODLMetaObjects
+ {
+ // the following interfaces are defined here
+
+ };
+
+ Scopes
+ ======
+ - scopes define naming hierarchy for the meta objects in the
+ repository
+
+ interface Scope
+ {
+ exception DuplicateName{};
+
+ exception NameNotFound{string reason; };
+
+ // Adds meta objects to the repository
+ void bind(in string name, in MetaObject value)
+ raises(DuplicateName);
+
+ // Resolves path names within the repository
+ MetaObject resolve(in string name) raises(NameNotFound);
+
+ // Removes bindings from the repository
+ void unbind(in string name) raises(NameNotFound);
+
+ list<RepositoryObject> children();
+
+ };
+
+ Visitors
+ ========
+ - visitors provide a convenient "double dispatch" mechanism for
+ traversing the meta objects in the repository
+ - to utilize this mechanism a client must implement a
+ RepositoryObjectVisitor object that responds to the visit_... callbacks in
+ an appropriate manner
+ - then, by passing this visitor to one of the meta objects in the
+ repository, an appropriate callback will occur that may be used as
+ required by the client object
+
+ enum MetaKind {mk_attribute, mk_class, mk_collection,
+ mk_constant, mk_const_operand, mk_enumeration,
mk_exception,
+ mk_expression, mk_interface, mk_literal, mk_member,
mk_module,
+ mk_operation, mk_parameter, mk_primtive_type,
+ mk_relationship, mk_repository, mk_structure,
+ mk_type_definition, mk_union, mk_union_case};
+
+ interface RepositoryObject
+ {
+ void accept_visitor(in RepositoryObjectVisitor
a_repository_object_visitor);
+
+ Scope parent();
+
+ readonly attribute MetaKind meta_kind;
+ };
+
+ interface RepositoryObjectVisitor
+ {
+ void visit_attribute(in Attribute an_attribute);
+ void visit_class(in Class a_class);
+ void visit_collection(in Collection a_collection);
+ void visit_constant(in Constant a_constant);
+ void visit_const_operand(in ConstOperand a_const_operand);
+ void visit_enumeration(in Enumeration an_enumeration);
+ void visit_exception(in Exception an_exception);
+ void visit_expression(in Expression an_expression);
+ void visit_interface(in Interface an_interface);
+ void visit_literal(in Literal a_literal);
+ void visit_member(in Member a_member);
+ void visit_module(in Module a_module);
+ void visit_operation(in Operation an_operation);
+ void visit_parameter(in Parameter a_parameter);
+ void visit_primitive_type(in PrimitiveType a_primitive_type);
+ void visit_relationship(in Relationship a_relationship);
+ void visit_repository(in Repository a_repository);
+ void visit_structure(in Structure a_structure);
+ void visit_type_define(in TypeDefinition a_type_definition);
+ void visit_union(in Union a_union);
+ void visit_union_case(in UnionCase a_union_case);
+ };
+
+ Meta Objects
+ ============
+ - they participate in a definedIn relationship with other meta
+ objects
+ - DefiningScopes and Scopes contain meta objects and have
+ operations for creating, adding and removing meta objects
+
+ typedef string ScopedName;
+
+ interface MetaObject: RepositoryObject
+ {
+ attribute string name;
+
+ attribute string comment;
+
+ relationship DefiningScope definedIn
+ inverse DefiningScope::defines;
+
+ ScopedName absolute_name();
+ };
+
+ enum PrimitiveKind {pk_boolean, pk_char, pk_date, pk_short,
+ pk_unsigned_short, pk_time, pk_timestamp,
+ pk_long, pk_unsigned_long, pk_long_long,
+ pk_float, pk_double, pk_octet, pk_interval,
+ pk_void};
+
+ enum CollectionKind {ck_list, ck_array, ck_bag, ck_set,
+ ck_dictionary, ck_sequence, ck_string };
+
+ interface DefiningScope: Scope
+ {
+ relationship list<MetaObject> defines
+ inverse MetaObject::definedIn;
+
+ exception InvalidType{string reason; };
+ exception InvalidExpression{string reason; };
+ exception CannotRemove{string reason; };
+
+ PrimitiveType create_primitive_type(in PrimitiveKind primitive_kind);
+
+ Collection create_collection(in CollectionKind collection_kind,
+ in Operand max_size,
+ in Type sub_type);
+
+ Dictionary create_dictionary_type(in Type key_type, in Type
sub_type);
+
+ Operand create_operand(in string expression)
+ raises(InvalidExpression);
+
+ Member create_member(in string member_name, in Type
member_type);
+
+ UnionCase create_union_case(in string case_name,
+ in Type case_type,
+ in list<Operand> caseLabels)
+ raises(DuplicateName, InvalidType);
+
+ Constant add_constant(in string name, in Type type,
+ in Operand value)
+ raises(DuplicateName);
+
+ TypeDefinition add_type_definition(in string name, in Type alias)
+ raises(DuplicateName);
+
+ Enumeration add_enumeration(in string name,
+ in list<string> element_names)
+ raises(DuplicateName, InvalidType);
+
+ Structure add_structure(in string name, in list<Member> fields)
+ raises(DuplicateName, InvalidType);
+
+
+ Union add_union(in string name, in Type switch_type,
+ in list<UnionCase> cases)
+ raises(DuplicateName, InvalidType);
+
+ Exception add_exception(in string name, in Structure result)
+ raises(DuplicateName);
+
+ void remove_constant(in Constant object)
raises(CannotRemove);
+
+ void remove_type_definition(in TypeDefinition object)
+ raises(CannotRemove);
+
+ void remove_enumeration(in Enumeration object)
+ raises(CannotRemove);
+
+ void remove_structure(in Structure object)
+ raises(CannotRemove);
+
+ void remove_union(in Union object) raises(CannotRemove);
+
+ void remove_exception(in Exception object)
+ raises(CannotRemove);
+ };
+
+ Modules
+ =======
+ - modules and the schema repository itself are DefiningScopes that define
+ operations for creating modules and interfaces within themselves
+
+ interface Module: MetaObject, DefiningScope
+ {
+ Module add_module(in string name) raises(DuplicateName);
+
+ Interface add_interface(in string name, in list<Interface> inherits)
+ raises(DuplicateName);
+
+ Class add_class(in string name, in list<Interface> inherits,
+ in class extender)
+ raises(DuplicateName);
+
+ void remove_module(in Module object) raises(CannotRemove);
+
+ void remove_interface(in Interface object) raises(CannotRemove);
+
+ void remove_class(in Class object) raises(CannotRemove);
+ };
+
+ Operations
+ ==========
+ - operations model behavior that app objects support, they maintain
+ signature list of Parameters and refer to a result type, operations may
+ raise exceptions
+
+ interface Operation: MetaObject, Scope
+ {
+ relationship list<Parameter> signature
+ inverse Parameter::operation;
+
+ relationship Type result
+ inverse Type::operations;
+
+ relationship list<Exception> exceptions
+ inverse Exception:operations;
+ };
+
+ Exceptions
+ ==========
+ - operations may raise Exceptions consequently returning a different set
+ of results
+ - Exceptions refer to a Structure that defines their results and keeps
+ track of the Operations that may raise them
+
+ interface Exception: MetaObject
+ {
+ relationship Structure result
+ inverse Structure::exception_result;
+
+ relationship set<Operation> operations
+ inverse Operation::exceptions;
+ };
+
+ Constants
+ =========
+ - constants provide a mechanism for statically associating values with
+ names in the repository
+ - value is defined by the an Operand subclass that is either a literal
+ value (Literal), a reference to an another constant (ConstOperand), or
the
+ value of a constant expression (Expression)
+ - each Constant has an associated type and keeps track of the other
+ ConstOperands that refer to it in the repository
+
+ interface Constant: MetaObject
+ {
+ relationship Operand the_Value
+ inverse Operand::value_of;
+
+ relationship Type type
+ inverse Type::constants;
+
+ relationship set<ConstOperand> referenced_by
+ inverse ConstOperand::references;
+
+ relationship Enumeration enumeration
+ inverse Enumeration::elements;
+
+ // Allows constant's actual value to be computed at runtime
+ Object value();
+ };
+
+ Properties
+ ==========
+ - an abstract interface for Attribute and Relationship meta objects
+
+ interface Property: MetaObject
+ {
+ // Associated type of the property
+ relationship Type type
+ inverse Type::properties;
+ };
+
+ Attributes
+ ==========
+ - Attributes maintain simple abstract state, they may be read-only
+
+ interface Attribute: Property
+ {
+ attribute boolean is_read_only;
+ };
+
+ Relationships
+ =============
+ - relationships model bidirectional references between objects
+ - 2 relationship meta objects require to represent each traversal
+ direction in a relationship
+
+ enum Cardinality {c1_1, c1_N, cN_M};
+
+ interface Relationship: Property
+ {
+ relationship Relationship traversal
+ inverse Relationship::traversal;
+
+ // Accessor operation for manipulating traversals
+ Cardinality get_cardinality();
+ };
+
+ Types
+ =====
+ - TypeDefinitions are meta objects that define new names, aliases, for
the
+ types to which they refer
+
+ interface TypeDefinition: Type
+ {
+ relationship Type alias
+ inverse Type::type_defs;
+ };
+
+ - Type meta objects are used to represent information about datatypes,
it
+ contains many relationships which help maintain the referential
integrity
+ of the repository as a whole
+
+ interface Type: MetaObject
+ {
+ relationship set<Collection> collection
+ inverse Collection::subtype;
+
+ relationship set<Dictionary> dictionaries
+ inverse Dictionary::key_type;
+
+ relationship set<Specifier> specifiers
+ inverse Specifier::type;
+
+ relationship set<Union> unions
+ inverse Union::switch_type;
+
+ relationship set<Operation> operations
+ inverse Operation::result;
+
+ relationship set<Property> properties
+ inverse Property::type;
+
+ relationship set<Constant> constants
+ inverse Constant::type;
+
+ relationship set<TypeDefinition> type_defs
+ inverse TypeDefinition::alias;
+ };
+
+ Interfaces
+ ==========
+ - most important types in the repository, define abstract behavior
+ of application objects and contain operations for creating and
+ removing Attributes, Relationships, and Operations within
+ themselves
+ - linked in multiple-inheritance graph with other Inheritance
+ objects by two relationships, inherits and derives
+
+ interface Interface: Type, DefiningScope
+ {
+ struct ParameterSpec
+ {
+ string param_name;
+ Direction param_mode;
+ Type param_type;
+ };
+
+ relationship set<Interface> inherits
+ inverse Interface::derives;
+
+ relationship set<Interface> derives
+ inverse Interface::inherits;
+
+ exception BadParameter{string reason; };
+ exception BadRelationship{string reason; };
+
+ Attribute add_attribute(in string attr_name,
+ in Type attr_type)
+ raises(DuplicateName);
+
+ Relationship add_relationship(in string rel_name,
+ in Type rel_type,
+ in Relationship rel_traversal)
+ raises(DuplicateName, BadRelationship);
+
+ Operation add_operation(in string op_name,
+ in Type op_result,
+ in list<ParameterSpec> op_params,
+ in list<Exception> op_raises)
+ raises(DuplicateName, BadParameter);
+
+ void remove_attribute(in Attribute object)
+ raises(CannotRemove);
+
+ void remove_relationship(in Relationship)
+ raises(CannotRemove);
+
+ void remove_operation(in Operation object)
+ raises(CannotRemove);
+ };
+
+ Classes
+ =======
+ - classes are subtype of Interface whose properties define the
+ abstract state of objects stored in an ODMS
+ - classes are in a single-inheritance hierarchy where they inherit
+ state and behavior from their extender class
+ - classes may define keys and extents over its instances
+
+ interface Class: Interface
+ {
+ attribute list<string> extents;
+ attribute list<string> keys;
+
+ relationship Class extender
+ inverse Class::extensions;
+
+ relationship Class extensions
+ inverse Class::extender;
+ };
+
+ Collections
+ ===========
+ - types that aggregate variable numbers of elements of a single
+ subtype and provide different ordering, accessing, and comparison
+ behavior
+ - max size specified by constant or constant expression, if
+ unspecified is equal to literal 0
+
+ interface Collection: Type
+ {
+ readonly attribute CollectionKind collection_kind;
+
+ relationship Operand max_size
+ inverse Operand::size_of;
+
+ relationship Type subtype
+ inverse Type::collections;
+
+ boolean is_ordered();
+
+ unsigned long bound();
+ };
+
+ interface Dictionary: Collection
+ {
+ relationship Type key_type
+ inverse Type::dictionaries;
+ };
+
+ Constructed Types
+ =================
+ - elements/types that aggregate others and said to be
+ constructed from those types
+ - ScopedType is abstract interface that consolidates the
+ mechanisms for its subclasses Enumeration, Structure, and
+ Union
+ - Enumerations contain Constants, Structures contain
+ Members, and Unions contain UnionCases
+ - Unions also have a relationship to a switch_type that
+ defines the descriminator of the union
+
+ interface ScopedType: Scope, Type {};
+
+ interface Enumeration: ScopedType
+ {
+ relationship list<Constant> elements
+ inverse Constant::enumeration;
+ };
+
+ interface Structure: ScopedType
+ {
+ relationship list<Member> fields
+ inverse Member::structure_type;
+
+ relationship Exception exception_result
+ inverse Exception::result;
+ };
+
+ interface Union: ScopedType
+ {
+ relationship Type switch_type
+ inverse Type::unions;
+
+ relationship list<UnionCase> cases
+ inverse UnionCase::union_type;
+ };
+
+ Specifiers
+ ==========
+ - used to assign a name to a type in certain contexts, they consolidate
+ these elements for their subclasses
+ - Members, UnionCases, and Parameters are referenced by Structures, Unions,
+ and Operations, respectively
+
+ interface Specifier: RepositoryObject
+ {
+ attribute string name;
+
+ relationship Type type
+ inverse Type::specifiers;
+ };
+
+ interface Member: Specifier
+ {
+ relationship Structure structure_type
+ inverse Structure::fields;
+ };
+
+ interface UnionCase: Specifier
+ {
+ relationship Union union_type
+ inverse Union::cases;
+
+ relationship list<Operand> case_labels
+ inverse Operand::case_in;
+ };
+
+ enum Direction {mode_in, mode_out, mode_inout};
+
+ interface Parameter: Specifier
+ {
+ attribute Direction parameter_mode;
+
+ relationship Operation operation
+ inverse Operation::signature;
+ };
+
+ Operands
+ ========
+ - form the base type for all constants in the repository
+ - they have a value operation and maintain relationships with other
+ Constants, Collections, UnionCases, and Expressions that refer to them
+ - Literals contain a single literalValue attribute and produce their value
+ directly
+ - ConstOperands produce their value by delegating to their associated
+ constant
+ - Expressions compute their value by evaluating their operator on the
values
+ of their operands
+
+ interface Operand: RepositoryObject
+ {
+ relationship Expression operand_in
+ inverse Expression::the_operands;
+
+ relationship Constant value_of
+ inverse Constant::the_value;
+
+ relationship Collection size_of
+ inverse Collection::max_size;
+
+ relationship UnionCase case_in
+ inverse UnionCase::case_labels;
+
+ Object value();
+ };
+
+ interface Literal: Operand
+ {
+ attribute Object literal_value;
+ };
+
+ interface ConstOperand: Operand
+ {
+ relationship Constant references
+ inverse Constant::referenced_by;
+ };
+
+ interface Expression: Operand
+ {
+ attribute string operator;
+
+ relationship list<Operand> the_operands
+ inverse Operand::operand_in;
+ };
+
+ Locking and Concurrency Control
+ ===============================
+ - ODMG Object Model uses a conventional lock based approach to
+ concurrency control
+ - approach provides mechanism for enforcing shared or exclusive
+ access to objects
+ - ODMS grants a lock only if no conflicting locks exist
+ - as a result access to persistent objects is coordinated across
+ multiple transactions, and a consistent view of the ODMS is
+ maintained for each transaction
+ - ODMG Object Model supports pessimistic concurrency control as its
+ default policy, but does not preclude an ODMS from supporting a wider
+ range of concurrency control policies
+
+ Lock Types
+ ==========
+ - following locks are supported in the ODMG Object Model
+ - read
+ - write
+ - upgrade
+
+ - read locks allow shared access to an object, write locks indicate
+ exclusive access to an object
+ - readers do not conflict with other readers, but writers conflict
+ with both readers and writers
+ - upgrade locks are used to prevent a form of deadlock that occurs
+ when two processes both obtain read locks on an object and then
+ attempt to obtain a write locks on that same object, deadlock is
+ avoided by initially obtaining upgrade locks, instead of read
+ locks, for all objects that intend to be modified, avoids any
+ potential conflicts when a write lock is later obtained to modify
+ the object
+ - locks follow the same semantics as those defined in OMG
+ Concurrency Control Service
+
+ Implicit and Explicit Locking
+ =============================
+ - ODMG Object model supports both implicit and explicit locking
+ - implicit locks are locks acquired during the course of traversal
+ of an object graph
+ - e.g., read locks are obtained each time an object is accessed
+ and write locks are obtained each time an object is modified
+ - in case of implicit locks, no specific operation is executed in
+ order to obtain a lock on an object
+ - explicit locks are acquired by expressly requesting a specific
+ lock on a particular object, obtained by calling 'lock' and
+ 'try_lock' operations defined in the Object interface
+ - read and write locks can be obtained implicitly, upgrade locks
+ must be acquired explicitly via 'lock' and 'try_lock'
+
+ Lock Duration
+ =============
+ - by default all locks (read, write, and upgrade) are held until
+ the transaction is either committed or aborted, this prevents
+ dirty reads, non-repeatable reads, and phantoms.
+
+ Transaction Model
+ =================
+ - programs that use persistent objects are organized into transactions
+ - transaction management is an important ODMS functionality, fundamental to
+ data integrity, shareability, and recovery
+ - access, creation, modification, and deletion of persistent objects must
+ be done within the scope of a transaction
+ - transaction is a unit of logic for which an ODMS guarantees atomicity,
+ consistency, isolation, and durability
+ - atomicity means that the transaction either finishes or has no
+ effect at all
+ - consistency means that a transaction takes the ODMS from one
+ internally consistent state to another internally consistent state
+ - there may be time of inconsistency, however isolation guarantees
+ that no other user of the ODMS sees changes made by another
+ transaction until that transaction commits
+ - durability means that the effects of the committed transactions
+ are preserve even in the case of failures of storage media, loss of
+ memory or system crashes
+ - once a transaction commits, the ODMS guarantees that changes made
+ by the transaction are never lost
+
+ Distributed Transactions
+ ========================
+ - distributed transactions are transactions that span multiple
+ processes and/or multiple databases as described in OMG Object
+ Transaction Service and ISO XA
+ - ODMG does not define an interface for this as it is described in
+ ISO XA and used only by transaction monitors
+ - vendors are not required to support distributed transactions,
+ but if they do they must be XA-compliant
+
+ Transactions and Processes
+ ==========================
+ - ODMG Object model assumes a linear sequence of transactions
+ executing within a thread of control, i.e., there is one current
+ transaction for a thread, and that transaction is implicit in that
+ thread's operations
+ - if transaction shared by multiple threads in an address space,
+ the transaction isolation must be provided between the threads
+ (i.e., you must protect the transactions yourself via a mutex,
+ etc.)
+ - transactions run against a single logical ODMS, note a single
+ logical ODMS may be implemented as one or more physical persistent
+ stores, possibly distributed on a network
+ - in the current object model transient objects are not subject
+ to transaction semantics, which means aborting a transaction does
+ not restore the state of the modified transient objects
+
+ Transaction Operations
+ ======================
+ - TransactionFactory is used to create transactions, it is defined
+ as follows:
+
+ interface TransactionFactory
+ {
+ // Creates transaction objects
+ Transaction new();
+
+ // Returns the transaction that is associated with the thread
+ // of control, if there is no current association the current
+ // operation returns nil
+ Transaction current();
+ };
+
+ - The following operations are defined in the Transaction
+ interface:
+
+ interface Transaction
+ {
+ // After a transaction object is created, it is initially
+ // closed. An explicit 'begin' operation is required to open a
+ // transaction. If the transaction is already open, and additional
calls
+ // to 'begin' operations raise the 'TransactionInProgress' exception
+ void begin() raises(TransactionInProgress, DatabaseClosed);
+
+ // Causes all persistent objects created or modified during the
+ // transaction to be written to the ODMS and to become accessible to
+ // other Transaction objects running against that ODMS. All locks held
+ // by the Transaction object are released. Finally, it causes the
+ // Transaction object to complete and become closed. The
+ // TransactionNotInProgress exception is raised if a 'commit'
operation
+ // is executed on a closed transaction object
+ void commit() raises(TransactionNotInProgress);
+
+ // Causes the Transaction object to complete and become closed. The
ODMS
+ // is returned to the state it was in prior to the beginning of the
+ // transaction. All locks held by the Transaction object are
+ // released. The TransactionNotInProgress exception is raised if an
+ // abort operation is executed on a closed Transaction object
+ void abort() raises(TransactionNotInProgress);
+
+ // This operation is equivalent to a commit operation followed by a
+ // begin operation, except that locks held by the Transaction object
are
+ // not released, Therefore, it causes all modified objects to be
+ // committed to the ODMS, and it retains all locks held by the
+ // Transaction object The Transaction object remains open. The
+ // TransactionNotInProgress exception is raised if a checkpoint
+ // operation executed on a closed Transaction object
+ void checkpoint() raises(TransactionNotInProgress);
+
+ // ODMS operations are always executed within the context of a
+ // transaction. Therefore, to execute any operations on persistent
+ // objects, and active Transaction object must be associated with the
+ // current thread. The join operation associates the current thread
with
+ // a Transaction object. If the Transaction object is open, persistent
+ // object operations may be executed; otherwise a
TransactioNotInProgress
+ // exception is raised
+ void join() raises(TransactionNotInProgress);
+
+ // If an implementation allows multiple active Transaction objects to
+ // exist, the join and leave operations allow a thread to alternate
+ // between them. To associate the current thread with another
+ // Transaction object, simply execute a join on the new Transaction
+ // object If necessary, a leave operation is automatically executed to
+ // dissociate the current thread from its current Transaction
+ // object. Moving from one transaction object to another does not
commit
+ // or abort a Transaction object. When the current thread has no
current
+ // transaction object, the leave operation is ignored.
+ void leave() raises(TransactionNotInProgress);
+
+ // Checks to see if the transaction object is "open" or begin() has
been
+ // called.
+ boolean isOpen();
+ };
+
+ - in order to being a transaction, a Database object must be opened
+ - during the processing of a transaction, any operation executed on a
+ Database object is bound to that transaction
+ - Database object may be bound to any number of transactions
+ - all Database objects, bound to transactions in progress, must remain open
+ until those transactions have completed via either a commit or a rollback
+ - if close is called on the Database object prior to the completion of all
+ transactions, the TransactionInPogress exception is raised and the
+ Database object remains open
+
+ Database Operations
+ ===================
+ - an ODMS may manage one or more logical ODMSs, each of which may be stored
in
+ one or more physical persistent stores
+ - each logical ODMS is an instance of the type Database, which is supplied by
+ the ODMS
+ - Instances of the type Database are created using the DatabaseFactory
+ interface:
+
+ interface DatabaseFactory
+ {
+ Database new();
+ };
+
+ Once a Database object is created using new operation, it is manipulated
using
+ the Database interface:
+
+ interface Database
+ {
+ exception DatabaseOpen{};
+ exception DatabaseNotFound{};
+ exception ObjectNameNotUnique{};
+ exception ObjectNameNotFound{};
+
+ // Must be invoked, with an ODMS name as its argument, before any access
+ // can be made to the persistent objects in the ODMS. Object Model
+ // requires that a single ODMS to be open at a time. Implementations may
+ // extend this capability, including transactions that span multiple
+ // ODMSs, the close operation must be invoked when all a program has
+ // completed all access to the ODMS. When the ODMS closes, it performs
+ // necessary cleanup operations, and if a transaction is still in
+ // progress, raises the TransactionInProgress exception. Except for the
+ // open and close operations, all other Database operations must be
+ // executed within the scope of a Transaction. If not, a
+ // TransactionNotInProgress exception will be raised.
+ void open(in string odms_name) raises(DatabaseNotFound, DatabaseOpen);
+ void close() raises(DatabaseClosed, TransactionInProgress);
+
+ // A name is bound to an object using the bind operation.
+ void bind(in Object an_object, in string name)
+ raises(DatabaseClosed, ObjectNameNotUnique,
+ TransactionNotInProgress);
+
+ // Named objects may be unnamed using the unbind operation.
+ Object unbind(in string name) raises(DatabaseClosed,
+ ObjectNameNotFound,
+ TransactionNotInProgress);
+
+ // Finds the identifier of the object with the name supplied as the
+ // argument to the operation. This operation is defined on the Database
+ // type, because the scope of object names is the ODMS. The names of
+ // objects in the ODMS, the names of types in the schema, and the extents
+ // of types instantiated in the ODMS are global. They become accessible
to
+ // a program once it has opened the ODMS. Named objects are convenient
+ // entry points to the ODMS.
+ Object lookup(in string object_name) raises(DatabaseClosed,
+ ObjectNameNotFound,
+ TransactionNotInProgress);
+
+ // Accesses the root object that defines the schema of the ODMS. The
+ // schema of the ODMS is contained within a single 'Module' meta object.
+ // Meta objects contained within the schema may be located via navigation
+ // of the appropriate relationships or by using the resolve operation
+ // with a scoped name as the argument. A scoped name is defined by the
+ // syntax of the ODL and uses double colon (::) delimiters to specify a
+ // search path composed of meta object names that uniquely identify each
+ // meta object by its location within the schema. e.g., "Professor::name"
+ // resolves to the Attribute meta object that represents the name of
class
+ // Professor.
+ ODLMetaObjects::Module schema() raises(DatabaseClosed,
+ TransactionNotInProgress);
+ };
+
+ - Database type may also support operations designed for ODMS administration,
+ e.g., create, delete, move, copy, reorganize, verify, backup,
+ restore. These kinds of operations are not specified in the ODMG spec, as
+ they are considered an implementation consideration outside the scope of
the
+ Object Model
\ No newline at end of file
Added: branches/gnue-appserver-featuretest/geasarch/outline.txt
===================================================================
--- branches/gnue-appserver-featuretest/geasarch/outline.txt 2004-03-08
10:18:50 UTC (rev 5258)
+++ branches/gnue-appserver-featuretest/geasarch/outline.txt 2004-03-08
10:28:53 UTC (rev 5259)
@@ -0,0 +1,729 @@
+GNU Enterprise Application Server v2 Proposed Architecture
+
+Introduction
+ - GEAS (GNU Enterprise Application Server) is the middleware of the
+ GNU Enterprise project
+ - it acts as an Object Data Management System (ODMS), with its
+ prime goal to pull the application logic from the front end UI client and
+ back end database, thus providing a 'middle' layer
+ Purpose
+ - in 2-tier systems the application logic lies either in the front
+ end or in the database (via events (triggers) or stored procedures)
+ - main purpose of the application server is to pull application
+ logic out of both front end and back end serving as a middle layer
+ that abstracts the logic (called business rules) from the user
+ interface as well as from the database back-end
+ Goals
+ - Apart from fulfilling the main purpose as described, we have
+ defined several additional, ethical as well as technical, goals
+ - Following list by priority:
+ - Freedom: GEAS must be GPL and built with truly Free tools
+ - Stability: GEAS must be built with a high degree of stability in
+ mind as it will be used in mission-critical business applications
+ - Security: GEAS must be reasonably secure so as to not compromise
+ a business's data
+ - Maintainability: The GEAS code base must be maintainable by the
+ GEAS development team and clear enough to allow interested
+ programmers to adapt to their needs, fix bugs, or even take over
+ maintenance of part or all of GEAS
+ - Configurability: GEAS must support configuration at runtime
+ (dynamically) and a central location for configuration information
+ it must be easily configured without programming skills, be
+ configured without downtime, and in separate "layers" for various
+ levels of specification
+ - Performance: GEAS must perform reasonably well with large numbers
+ of users and/or large quantities of data
+ - Database Independence: GEAS must support a number of Database
+ systems as the backend
+ - Portability: GEAS must run on multiple Operating Systems and
+ architectures.
+ - Communication Independence: GEAS must be able to utilize various
+ communication protocols to communicate with the front end (CORBA,
+ SOAP, XMLRPC, HTTP, IRC, etc.)
+ - Language Independence: GEAS must be able to support and handle
+ business methods written in different programming languages
+ Overview
+ - UML arhcitecture diagram with some explanation
+GNUe Data Interface (GEDI)
+ - might be confused with EDI (Electronic Data Interchange)
+GNUe Methods Adapter (GEMA)
+GNUe Object Repository (GEOR)
+GNUe Object Access Translator (GOAT)
+Security Adapter (GNUe Access Control Server - GACS)
+Remote Protocol Adapter (GNURPC)
+Batch Schema Compiler (ODL compiler and/or ODLML parser)
+SQL Schema Generator
+Transaction Processor
+Synchronization Engine
+Workflow Server
+ODMG Python Binding (needs paraphrasing badly ;) )
+ Introduction
+ - here we define the python binding for the ODMG Object Model,
+ ODL, and OQL
+ - ???
+ Language Design Principles
+ - ODMG python binding based upon 2 principles: should bind to
+ python in a natural way which is consistent with principles of the
+ language, and should support language inertoperability consistent
+ with ODL specification and semantics
+ - these principles have several implications that are evident in
+ the design of the binding
+
+ 1. there is a unified type system that is shared by python and
+ the ODMS. this type system is ODL mapped into python by the
+ python binding
+
+ 2. the binding respects python syntax, meaning the python
+ language will not have to be modified to accommodate this
+ binding. ODL concepts will be represented using normal python
+ coding conventions
+
+ 3. binding respects the fact that python is dynamically
+ typed. arbitrary python objects may be stored persistently,
+ including ODL-specified objects that will obey the ODL typing
+ semantics
+
+ 4. binding respects the dynamic memory management semantics of
+ python. objects will become persistent when they are referred
+ by other persistent objects in the database and will be
+ removed when they are no longer reachable in this manner
+ (this is referred to as transitive persistence)
+
+ Language Binding
+ - ODMG binding for python is based on OMG python IDL binding
+ - as ODL is a superset of IDL, the IDL binding defines a large
+ part of the mapping required by this document
+ - section/chapter provides informal descriptions of the IDL
+ binding topics and more formally defines the python binding for
+ the ODL extensions, including relationships, literals and
+ collections
+ - ODMG python binding can be automated by an ODL compiler that
+ processes ODL declarations and generates a graph of 'meta
+ objects', which model the schema of the database (ODMS)
+ - the meta objects provide the type information that allows the
+ python binding to support the required ODL type semantics
+ - complete set of such meta objects defines the entire schema of
+ the database would serve much in the same capacity as an OMG
+ Interface Repository
+ - includes python binding for meta object interfaces defined in
+ ch. 2
+ - in such a repository, the meta objects that represent the schema
+ of the database may be programatically accesses and modified by
+ python applications (clients, etc.), through their standard
+ interfaces
+ - one such application, a 'binding generator', may be used to
+ generate python class and method skeletons from the meta objects
+ - this binding generator would resolve the type-class mapping
+ choices that are inherent in the ODMG python binding
+ - the info in the meta objects is also sufficient to 'regenerate'
+ the ODL declarations for the portions of the schema that they
+ represent
+ - the relationships between these components are illustrated in
+ Figure 1 (include geas-schema-compiler.png)
+ - a conforming implementation must support the python output of
+ this binding process; it need not provide automated tools
+
+ Mapping the ODMG Object Model Into Python
+ - although python has a powerful data model that is close to the one
+ presented in ch. 2, it remains necessary to precisely describe how
+ the concepts of the ODMG Object Model map into concrete python
+ constructions
+
+ Object and Literal
+ - an ODMG object type maps into a python object type
+ - since python has no distinct notion of literal objects, both
+ ODMG objects and ODMG literals may be implemented by the same
+ python classes (is this really true???)
+
+ Relationship
+ - this concept is not directly supported by Python and must be
+ implemented by Python methods that support a standard protocol
+ - the relationship itself is typically implemented either as an
+ object reference (one-to-one relation) or as an appropriate
+ 'Collection' subclass (one-to-many, many-to-many relations)
+ embedded as an instance variable of the object
+ - rules for defining sets of accessor methods are presented that
+ allow all relationships to be managed uniformly
+
+ Names
+ - objects may be named using methods of the Database interface
+ defined in the Python OML
+ - the root objects of a database are the named objects; root
+ objects and any objects reachable from them are persistent
+
+ Extents
+ - extents are not supported by this binding, instead users may
+ use the database naming protocol to explicitly register and access
+ named 'Collections'
+
+ Keys
+ - key declarations are not supported by this binding
+ - instead, users may use the database naming protocol to
+ explicitly register and access named Dictionaries
+
+ Implementation
+ - everything in python is implemented as an object
+ - the python language does not support the independent
+ definition of interface from implementation, all classes/object
+ types include both interface and implementation
+
+ Collections
+ - collection objects described in section 2.3.6 specify
+ collection behavior, which may be implemented using many different
+ collection representations such as hash tables, trees, chained
+ lists, and so on
+ - the python binding provides provides collection interfaces as
+ described in chapter 2 as well as emulating python sequence and
+ mapping types by implementing the special methods, providing
+ various mathematical operation methods, and the various dictionary
+ methods and mutable sequence methods (like the one in python's
+ list object) for a more complete implementation (could expand
+ here a lot further, but I am tired so it's going to have to
+ wait)
+ - provide summary of collection interfaces?!?
+
+ Python ODL
+
+ OMG IDL Binding Overview
+ - since python/ODL binding is based upon the OMG python binding,
+ we include here some descriptions of the important aspects of the
+ IDL binding that are needed in order to better understand the ODL
+ binding that follows
+
+ Using Scoped Names (IDL Namespace)
+ - python implements a module concept that is similar to the IDL
+ scoping mechanisms, except that it does not allow for nested
+ modules
+ - in addition Python requires each object to be implemented in a
+ module; globally visible objects are not supported
+ - because of these constraints, scoped names are translated into Python
using the
+ following rules:
+
+ * an IDL module mapped into a Python module, modules containing
modules are
+ mapped to packages (i.e., directories with an __init__ module
containing all
+ definitions excluding the nested modules). An implementation can
+ chose to map top-level definitions to modules in an implementation
defined
+ package, to allow concurrent installations of different ODMG
runtime
+ libraries. In that case, the implementation must provide
+ additional modules so that top-level modules can be used without
+ importing them from a package.
+
+ * for all other scopes, a Python class is introduced that
+ contains all the definitions inside this scope.
+
+ * other global definitions (except modules) appear in a module
+ whose name is implementation dependent, implementations are
+ encouraged to use the name of the IDL file when defining the
+ name of that module.
+
+ - For example,
+
+ Module M
+ {
+ struct E
+ {
+ long L;
+ };
+ module M
+ {
+ interface I
+ {
+ void import(in string what);
+ };
+ };
+ };
+
+ const string NameServer="NameServer";
+
+ would introduce a module M.py, which contains the following
+ definitions:
+
+ # since M is a package, this appears in M/__init__.py
+ class E:
+ pass # structs are discussed later
+
+ # module M/N.py
+ class I:
+ def _import(self, what):
+ pass # interfaces are discussed later
+
+ the string NameServer would be defined in another module
+ because the name of that module is not defined and
+ using global definitions for modules is discouraged
+
+ to avoid conflicts, IDL names that are also Python identifiers are
+ prefixed with an underscore ('_'), for a list of keywords, see Table
+ 1-1
+
+ Table 1-1 Python keywords
+ ------------------------------------
+ and assert break class continue
+ def del elif else except
+ exec finally for from global
+ if import in is lambda
+ not or pass print raise
+ return try while
+
+ Types
+ Simple Types
+ - because python does not require type information for
+ operation declarations, it is not necessary to introduce
+ standardized types names, unlike C or C++ mappings
+ - instead, the mapping of types to dynamic values is specified
+ here
+ - for most of the simple types, it is obvious how values of
+ these types can be created
+ - for the other types, the interface for constructing values
+ is also defined
+ - the mappings for the basic types are shown in table 1-2
+
+ Table 1-2 Basic Data Type Mappings
+ ---------------------------------------------------------
+ OMG IDL Python
+ ---------------------------------------------------------
+ octet Integer (<type 'int'>)
+ short Integer
+ long Integer
+ unsigned short Integer
+ unsigned long Long integer (<type 'long int'>)
+ long long Long integer (<type 'long int'>)
+ unsigned long long Long interger
+ float Floating Point Number (<type 'float'>)
+ double Floating Point Number
+ long double CORBA.long_double
+ boolean Interger
+ char string of length 1
+ wchar Wide string length of 1
+ Compound Types
+ Array
+ - an appropriate Python sequence type supporting the
+ 'Array' interface along with the appropriate python
+ sequence methods (e.g., __getitem__)
+
+ Enumeration
+ - an enumeration is mapped into a number of constant objects
+ in the name space where the enumeration is defined
+ - an application may only test for equivalence of two
+ enumeration values, and not assume that they behave like
+ numbers
+
+ - For example, the definition:
+
+ module M
+ {
+ enum color {red, green, blue};
+
+ interface O
+ {
+ enum Farbe {rot, gruen, blau};
+ };
+ };
+
+ introduces the objects:
+
+ import M
+ M.red, M.green, M.blue, M.O.rot, M.O.gruen, M.O.blau
+
+ Structures
+ - an IDL struct definition is mapped into a Python class or
+ type
+ - for each field in the struct, there is a corresponding
+ attribute in the class with the same name as the field
+ - the constructor of the class expects the field values, from
+ left to right
+
+ For example, the IDL definition:
+
+ struct segment {long left_limit, long right_limit};
+
+ could be used on Python statements
+
+ s=segment(-3,7)
+ print s.left_limit, s.right_limit
+
+ Unions
+ - Union types are mapped to classes with two attributes,
+ first being the descriminant _d, the second the associated
+ value _v
+ - for each branch, there is an additional attribute,
+ which can only be accessed if the branch has been set,
+ there are three possibilities:
+
+ - if the discriminant was explicitly listed in a case
+ statement, the value is of the branch associated
+ with the case
+ - if the discriminant is not explicitly listed and
+ there is a default case label, the value is of the
+ branch associated with the case label
+ - if the discriminant is not listed, and there is no
+ default, the value is None
+
+ - constructor of the class expects the discriminator and
+ the value as arguments
+ - alternatively, the union can also be constructed by
+ passing a keyword argument, with the field name of the
+ union as the key, if more than one discriminator is
+ associated with a field, the discriminator must be
+ set explicitly
+
+ Example:
+
+ union MyUnion switch(long)
+ {
+ case 1: string s;
+ default: long x;
+ };
+
+ can be accessed as
+
+ u = MyUnion(17, 42)
+ print u.x
+ u = MyUnion(s = 'string')
+ print u._d, u._v
+
+ Exceptions
+ - when error detected, exception is raised using standard Python
+ exception mechanism, which consists of deriving from
+ exceptions.Exception, the following standard exception types are
+ defined, some are raised from specific ODMG interfaces and are
+ thus subclasses of OMDGError, others may be raised in the
+ course of using persistent objects and are thus subclasses of
+ ODMGRuntimeError, and others are related to query processing
+ and are just subclasses of QueryError, which in turn is a
+ subclass of ODMGError:
+
+ class ODMGError (exceptions.Exception):
+
+ Base exception class for ODMG specific interfaces
+
+ class ODMGRuntimeError (exceptions.Exception):
+
+ Base class for exceptions raised in the course of using
+ peristent object
+
+ class QueryError (ODMGError):
+
+ Base class for exceptions rasied during query processing
+
+ class ClassNotPersistenceCapableError (ODMGRuntimeError):
+
+ Raised when the implementation cannot make the object
+ persistent because of the type of object
+
+ class DatabaseClosedError (ODMGRuntimeError):
+
+ Raised when attempting to call an operation for which a
+ database is not open but is required to be open
+
+ class DatabaseIsReadOnlyError (ODMGRuntimeError):
+
+ Raised when attempting to call a method that modifies a
+ database that is open read-only
+
+ class DatabaseNotFoundError (ODMGError):
+
+ Raised when attempting to open a database that does not exist
+
+ class DatabaseOpenError (ODMGError):
+
+ Raised when attempting to open a database that is already
+ opened
+
+ class LockNotGrantedError (ODMGRuntimeError):
+
+ Raised if a lock could not be granted. (Note that time-outs
+ and deadlock detection are implementation defined)
+
+ class NotImplementedError (ODMGRuntimeError):
+
+ Raised when an implementation does not implement an operation
+ or when the underlying implementation does not support an
+ operation
+
+ class ObjectDeletedError (ODMGRuntimeError):
+
+ Raised when accessing an object that was deleted
+
+ class ObjectNameNotFoundError (ODMGError):
+
+ Raised when attempting to get a named object whose name is not
+ found
+
+ class ObjectNameNotUniqueError (ODMGError):
+
+ Raised when attempting to bind a name to an object when the
+ name is already bound to an existing object
+
+ class ObjectNotPersistentError (ODMGRuntimeError):
+
+ Raised when deleting an object that is not persistent
+
+ class QueryInvalidError (QueryError):
+
+ Raised if the query is not a valid OQL query and thus does not
+ compile
+
+ class QueryParameterCountInvalidError (QueryError):
+
+ Raised when the number of bound parameters for a query does
+ not match the number of placeholders
+
+ class QueryParamterTypeInvalidError (QueryError):
+
+ Raised when the type of a parameter for a query is not
+ compatible with the expected parameter type
+
+ class TransactionAbortedError (ODMGRuntimeError):
+
+ Raised when the database system has asynchronously terminated
+ the user's transaction due to deadlock, resource failure, and
+ so on. In such cases the user's data is reset just as if the
+ user had called Transaction.abort.
+
+ class TransactionInProgressError (ODMGRuntimeError):
+
+ Raised when attempting to call a method within a transaction
+ that must be called when no transaction is in progress
+
+ class TransactionNotInProgressError (ODMGRuntimeError):
+
+ Raised when attempting to perform outside of a transaction an
+ operation that must be called when there is a transaction in
+ progress
+
+ Constants
+ - IDL constant definition maps to Python variable initialized
+ with the value of the constant
+
+ Operations
+ - nil object is represented by 'None'.
+ - if operation expects parameters of the IDL Object type, and
+ Python object representing an object reference might be passed
+ as an actual argument
+ - if an operation expects a parameter of an abstract interface,
+ either an object implementing that interface, or a value
+ supporting this interface may be passed as an actual argument
+ - the semantics of abstract values then define whether the
+ argument is passed by value or by reference
+ - operations of an interface map to methods available on the
+ object references
+ - parameters with a parameter attribute of 'in' or 'inout' are
+ passed from left to right to the method, skipping 'out'
+ parameters
+ - return value of a method depends on the number of 'out'
+ parameters and the return type
+ - if the operation returns a value, this value forms the first
+ 'result value'
+ - all 'inout' or 'out' parameters form consecutive 'result
+ values'
+ - the method result depends then on the number of 'result values':
+ * if there is no 'result value', the method returns 'None'
+ * if there is exactly one 'result value', it is returned as a single
+ value
+ * if there is more then one 'result value', all of them are packed
+ into a tuple, and this tuple is returned
+
+ Assuming the IDL definition:
+
+ interface I
+ {
+ oneway void stop();
+ bool more_data();
+ void get_data(out string name, out long age);
+ };
+
+ a client would write
+
+ names={}
+ while my_I.more_data():
+ name,age = my_I.get_data()
+ names[name]=age
+ my_I.stop()
+
+ - if an interface defines an 'attribute name', the attribute is mapped
+ into an opertaion _get_name, as defined
+
+ - if the attribute is not 'readonly' there is an additional operation
+ _set_name, as defined in the 'OMG IDL Syntax and Semantics' chapter,
+ "Attribute Declaration" section, of the 'Common Object Request Broker:
+ Architecture and Specification' document
+
+ Python ODL Binding Extensions
+ - section describes binding of ODMG ODL to Python
+ - ODL provides a description of the database schema as a set of
+ interfaces, including their attributes, relationships, and
+ operations
+ - Python implementations consist of a set of object classes and
+ their instances
+ - language binding provides a mapping between these domains
+
+ Interfaces and Classes
+ - in ODL, interfaces used to represent the 'abstract behavior'
+ of and object, and classes used to model the 'abstract state'
+ of objects
+ ***** to be determined *****
+ - add ODLName method that returns the name of the ODL
+ interface or class that is bound to the object in the schema
+ repository? e.g., aDate.ODLName() returns string '::Date',
+ which is name of the odl interface
+ - we may not need this because python has a namespace and I
+ only see the Smalltalk binding doing this because it does not
+ support the concept of namespaces, afaict
+ ***** to be determined *****
+ - an ODL interface maps to a Python class that raises
+ MethodNotImplementedError for the operations of the interface
+ class, all other conventions follow the IDL binding for interfaces
+ - an ODL class maps to a Python class
+
+ Attribute Declarations
+ - attribute declarations used to define pairs of accessor
+ operations that get and set attribute values
+ - Generally, there would be a one-to-one correspondence
+ between attributes defined within an ODL class and instance
+ variables defined within the corresponding Python class,
+ although this is not required
+ - ODL attributes define abstract state of their object when
+ they appear within class definitions
+ - when attributes appear within interface definitions, as in
+ IDL they are merely a convenience mechanism for introducing get
+ and set accessing operations
+ - e.g. attribute Enum Rank {full, associate, assistant} rank;
+
+ yields Python methods:
+
+ def _get_rank(self):
+
+ def _set_rank(self, aProfessorRank):
+
+ Relationship Declarations
+ - relationships define sets of accessor operations for adding
+ and removing associations between objects
+ - as with attributes relationships are a part of an object's
+ abstract state
+ - Python biding for relationships results in public methods to
+ "form" and "drop" members from the relationship, plus public
+ methods on the relationship target classes to provide access and
+ private methods to manage the required referential integrity
+ constraints
+ - we begin the relationship binding by applying the chapter 2
+ mapping rule from ODL relationships to equivalent IDL
+ constructions and then illustrate with a complete example:
+
+ Single-Valued Relationships
+
+ relationship X Y inverse Z;
+
+ we expand first to the IDL attribute and operations:
+
+ attribute X Y;
+ void form_Y(in X target) raises(IntegrityError);
+ void drop_Y(in X target) raises(IntegrityError);
+
+ which result in the following Python methods:
+
+ def Y(self):
+
+ def form_Y(self, target):
+
+ def drop_Y(self, target):
+
+ def __Y(self):
+
+ For example, from Chapter 3:
+
+ interface Course
+ {
+ ....
+ relationship Professor is_taught_by
+ inverse Professor::teaches;
+ ...
+ }
+
+ Expands into the following IDL attributes and operations:
+
+ attribute Professor is_taught_by;
+
+ void form_is_taught_by(in Professor aProfessor)
+ raises(IntegrityError);
+
+ void drop_is_taught_by(in Professor aProfessor)
+ raises(IntegrityError);
+
+ yields Python methods (on the class Course):
+
+ def form_is_taught_by(self, aProfessor):
+
+ def drop_is_taught_by(self, aProfessor):
+
+ def is_taught_by(self):
+
+ def __is_taught_by(self):
+
+ Multivalued Relationships
+ - for a multivalued relationship such as:
+
+ relationship set<X> Y inverse Z;
+
+ we expand first to the IDL attribute and operations:
+
+ readonly attribute set<X> Y;
+
+ void form_Y(in X target) raises(IntegrityError);
+
+ void drop_Y(in X target) raises(IntegrityError);
+
+ void add_Y(in X target) raises(IntegrityError);
+
+ void remove_Y(in X target) raises(IntegrityError);
+
+ which results in the following Python methods:
+
+ def Y(self):
+
+ def form_Y(self, target):
+
+ def drop_Y(self, target):
+
+ def __add_Y(self, target):
+
+ def __remove_Y(self, target):
+
+ For example:
+
+ interface Professor
+ {
+ ...
+ relationship Set<Course> teaches
+ inverse Course::is_taught_by;
+ ...
+ }
+
+ Expand into the following IDL and attributes and operations:
+
+ readonly attribute set<Course> teaches;
+
+ void form_teaches(in Course aCourse) raises(IntegrityError);
+
+ void drop_teaches(in Course aCourse) raises(IntegrityError);
+
+ void add_teaches(in Course aCourse) raises(IntegrityError);
+
+ void remove_teaches(in Course aCourse) raises(IntegrityError);
+
+ which results in the following Python methods:
+
+ def teaches(self):
+
+ def form_teaches(self, aCourse):
+
+ def drop_teaches(self, aCourse):
+
+ def __add_teaches(self, aCourse):
+
+ def __remove_teaches(self, aCourse):
+
+ Collections
+ - ch. 2 introduced several new kinds of collections that
+ extend the IDL sequence
+ - the following shows the Python interfaces/classes that this
+ binding defines for each of the collection interfaces
\ No newline at end of file
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- r5259 - in branches/gnue-appserver-featuretest: . diagrams geasarch,
reinhard <=