+ #if( $back )
+ Go back.
+ #else
+ Use your browser''s Back button to go back.
+ #end
+
+
+
+#if( $except )
+
+#end'),
+ (6, 'user.agreement',
+'Text of this agreement is to be determined.'),
+ (12, 'confirm.message',
+'Welcome to the Venice Web Communities System! In order to fully activate your
+account after you register or change your E-mail address, you must provide a
+confirmation number to the system. Please enter this number into the "Confirm
+E-mail Address" dialog on the system when indicated.
+
+Your confirmation number for your account "$username" is $confnum.
+
+Access the E-mail verification dialog at .
+
+Thank you, and enjoy the Venice Web Communities System!
+
+-- The Management'),
+ (12, 'password.change.message',
+'The password for your account "$username" has been changed. The new
+password is "$password".
+
+You should log into Venice immediately and change the password to something
+else. You can change the password for your account, once you are logged in,
+by clicking on the "Profile" link in the top bar.
+
+If you did NOT request a password change on your account, please notify the
+system administrator IMMEDIATELY.
+
+-- The Management'),
+ (12, 'reminder.message',
+'Here is the password reminder for your account "$username" as you requested:
+
+$reminder
+
+If this reminder is not sufficient for you to remember what your password is,
+then the system can change your password for you. To do so, please visit
+the following URL:
+
+http://localhost/venice/passrecovery/$uid/$auth
+
+Your password will be changed and a new password will be E-mailed to you
+at this address.
+
+If you did NOT request a password reminder, then this message was sent
+by someone attempting to access your account without your knowledge. Do
+not panic! Nothing has happened to your account or password yet, but
+please do notify the system administrator.
+
+-- The Management');
+
+# Initial users setup
+# (UID 1 and 2)
+INSERT INTO users (uid, username, email, is_anon, nospam, created) VALUES
+ (1, 'Anonymous_Honyak', 'nobody@localhost', 1, 1, '2002-12-15 12:00:00'),
+ (2, 'Administrator', 'root@localhost', 0, 0, '2002-12-26 18:00:00');
+
+# Set up properties for Anonymous_Honyak.
+INSERT INTO userprop (uid, nsid, prop_name, prop_value) VALUES
+ (1, 10, 'timezone', '_TZ:UTC' ),
+ (1, 10, 'locale', '_LOC:en_US'),
+ (1, 10, 'admin.flags', '_OS:A' ),
+ (1, 11, 'privacy', '_OS:' ),
+ (1, 11, 'name.given', '!Anonymous'),
+ (1, 11, 'name.family', '!Honyak' ),
+ (1, 11, 'locality', '!Nowhere' ),
+ (1, 11, 'region', '!XX' ),
+ (1, 11, 'postal.code', '!00000' ),
+ (1, 11, 'country', '_CTRY:US' );
+
+# Add authentication for Administrator (no password by default)
+INSERT INTO userauth (uid, nsid, method, source_data, auth_data) VALUES
+ (2, 3, 'default.hash.password', '', '');
+
+# Set up properties for Administrator.
+INSERT INTO userprop (uid, nsid, prop_name, prop_value) VALUES
+ (2, 10, 'timezone', '_TZ:UTC' ),
+ (2, 10, 'locale', '_LOC:en_US' ),
+ (2, 10, 'admin.flags', '_OS:' ),
+ (2, 11, 'privacy', '_OS:' ),
+ (2, 11, 'name.given', '!System' ),
+ (2, 11, 'name.family', '!Administrator'),
+ (2, 11, 'locality', '!Nowhere' ),
+ (2, 11, 'region', '!XX' ),
+ (2, 11, 'postal.code', '!00000' ),
+ (2, 11, 'country', '_CTRY:US' );
+
+# Create a group for site administrators.
+# (GID 1)
+INSERT INTO groups (gid, groupname) VALUES (1, 'Site_Administration');
+INSERT INTO groupmembers (gid, uid) VALUES (1, 2);
+
+# Create an ACL for the site administrator group. The ACL is owned by Administrator
+# and grants "add" and "remove" permissions to Administrator only.
+# (ACL 1, ACE 1)
+INSERT INTO acl (aclid, aclname) VALUES (1, 'Site_Administration');
+INSERT INTO aclowner (aclid, ownerid, flags) VALUES (1, 2, 0);
+INSERT INTO ace (aceid, pri, flags) VALUES (1, 2, 0);
+INSERT INTO acldata (aclid, seq, aceid) VALUES (1, 0, 1);
+INSERT INTO acedata (aceid, perm_nsid, perm_name) VALUES
+ (1, 4, 'add.member' ),
+ (1, 4, 'remove.member');
+UPDATE groups SET gaclid = 1 WHERE gid = 1;
+
+# Create the "all users" group.
+# (GID 2)
+INSERT INTO groups (gid, groupname) VALUES (2, 'All_Users');
+INSERT INTO groupmembers (gid, uid) VALUES (2, 2);
+
+# Create the "all verified users" group.
+# (GID 3)
+INSERT INTO groups (gid, groupname) VALUES (3, 'Verified_Users');
+INSERT INTO groupmembers (gid, uid) VALUES (3, 2);
+
+# Create the global ACL. This ACL is owned by the Administrator and grants
+# permissions to the site administration group and to the Administrator specifically.
+# (ACL 2, ACEs 2 and 3)
+INSERT INTO acl (aclid, aclname) VALUES (2, 'Global_Permissions');
+INSERT INTO aclowner (aclid, ownerid, flags) VALUES (2, 2, 0);
+INSERT INTO ace (aceid, pri, flags) VALUES (2, 1, 1);
+INSERT INTO acldata (aclid, seq, aceid) VALUES (2, 0, 2);
+INSERT INTO acedata (aceid, perm_nsid, perm_name) VALUES
+ (2, 1, 'set.property' ),
+ (2, 1, 'set.block' ),
+ (2, 2, 'set.property' ),
+ (2, 3, 'edit.all' ),
+ (2, 3, 'bypass.email.verify'),
+ (2, 3, 'view.all' ),
+ (2, 5, 'set.property' ),
+ (2, 5, 'set.block' ),
+ (2, 6, 'set.property' ),
+ (2, 6, 'set.block' ),
+ (2, 7, 'set.property' ),
+ (2, 10, 'set.property' ),
+ (2, 10, 'remove.property' ),
+ (2, 11, 'set.property' ),
+ (2, 11, 'remove.property' ),
+ (2, 12, 'set.property' ),
+ (2, 12, 'set.block' );
+INSERT INTO ace (aceid, pri, flags) VALUES (3, 2, 0);
+INSERT INTO acldata (aclid, seq, aceid) VALUES (2, 1, 3);
+INSERT INTO acedata (aceid, perm_nsid, perm_name) VALUES
+ (3, 1, 'remove.property'),
+ (3, 1, 'remove.block' ),
+ (3, 2, 'remove.property'),
+ (3, 5, 'remove.property'),
+ (3, 5, 'remove.block' ),
+ (3, 6, 'remove.property'),
+ (3, 6, 'remove.block' ),
+ (3, 7, 'remove.property'),
+ (3, 12, 'remove.property'),
+ (3, 12, 'remove.block' );
+
+# Create the entries in the global security table.
+INSERT INTO globalsec (admin_uid, admin_gid, global_aclid, alluser_gid, verified_gid)
+ VALUES (2, 1, 2, 2, 3);
+
+# Insert some audit event type records.
+INSERT INTO auditevent (eventid, event_nsid, event_name, descr) VALUES
+ (1, 8, 'system.startup', 'Venice Server Startup' ),
+ (2, 8, 'system.shutdown', 'Venice Server Shutdown' ),
+ (3, 9, 'login.ok', 'Successful User Login' ),
+ (4, 9, 'login.fail', 'Failed User Login' ),
+ (5, 9, 'verify.ok', 'Successful E-Mail Address Verification'),
+ (6, 9, 'verify.fail', 'Failed E-Mail Address Verification' ),
+ (7, 9, 'resend.confirm.email', 'Re-Sent E-Mail Confirmation Message' ),
+ (8, 9, 'send.confirm.email', 'Sent E-Mail Confirmation Message' ),
+ (9, 9, 'user.created', 'New User Created' );
+
+# Insert some image types.
+INSERT INTO imagetype (typecode, nsid, name) VALUES
+ (1, 11, 'user.photo');
+
+#### following this line is initialization of Venice-specific tables ####
+
+# Create the "global" menu.
+INSERT INTO menus (menuid, menu_nsid, menu_name, title, subtitle)
+ VALUES (1, 1, 'fixed.menu', 'About This Site', NULL);
+INSERT INTO menuitems (menuid, sequence, itemtype, text, linktype, link) VALUES
+ (1, 0, 'TEXT', 'Documentation', 'ABSOLUTE', 'TODO' ),
+ (1, 1, 'TEXT', 'About Venice', 'FRAME', 'about-venice.html');
+UPDATE menuitems SET enable = 0 WHERE menuid = 1 AND sequence = 0;
+
diff --git a/conf/web-test.xml b/conf/web-test.xml
new file mode 100644
index 0000000..24e3bda
--- /dev/null
+++ b/conf/web-test.xml
@@ -0,0 +1,117 @@
+
+
+
+
+ Dynamo Test Application
+ This is an application used to test components of the Dynamo framework.
+
+
+
+
+ logging.config
+ WEB-INF/logging.xml
+
+ The path and file name of the Log4J logger configuration file, relative to the application root.
+
+
+
+
+ dynamo.config
+ WEB-INF/dynamo.xml
+
+ The path and file name of the base Dynamo configuration file, relative to the application root.
+ The default, if not specified, is "WEB-INF/dynamo.xml".
+
+
+
+
+
+
+ ScriptExec
+ Executes a scripting file as a servlet.
+ com.silverwrist.dynamo.servlet.ScriptExecServlet
+
+ remove.extension
+ vs
+
+ The extension which is used in the servlet mapping to distinguish scripts to execute. This
+ extension is removed from the servlet path to create the script name.
+
+
+
+ script.prefix
+ /scripts
+
+ The resource prefix to use for scripts. This is prepended to the servlet path to create the
+ script name which is executed.
+
+
+
+
+
+ XmlRpc
+ Executes XML-RPC requests.
+ com.silverwrist.dynamo.xmlrpc.XmlRpcServlet
+
+ subsystem.object
+ xmlrpc
+
+ The object name of the XML-RPC subsystem object. Must match the name configured for the
+ com.silverwrist.dynamo.xmlrpc.XmlRpcSubSystem object in dynamo.xml.
+
+
+
+
+
+ TestServlet1
+ Servlet test 1
+ com.silverwrist.dynamo.test.TestServlet1
+
+
+
+ TestServlet2
+ Servlet test 2
+ com.silverwrist.dynamo.test.TestServlet2
+
+
+
+
+
+ ScriptExec
+ *.vs
+
+
+
+ XmlRpc
+ /RPC2
+
+
+
+ TestServlet1
+ /test1
+
+
+
+ TestServlet2
+ /test2
+
+
+
diff --git a/conf/web-venice.xml b/conf/web-venice.xml
new file mode 100644
index 0000000..47c8132
--- /dev/null
+++ b/conf/web-venice.xml
@@ -0,0 +1,218 @@
+
+
+
+
+ Venice Web Communities System
+
+ Venice Web Communities System (TODO: fill out description)
+
+
+
+
+
+ logging.config
+ WEB-INF/logging.xml
+
+ The path and file name of the Log4J logger configuration file, relative to the application root.
+
+
+
+
+ dynamo.config
+ WEB-INF/dynamo.xml
+
+ The path and file name of the base Dynamo configuration file, relative to the application root.
+ The default, if not specified, is "WEB-INF/dynamo.xml".
+
+
+
+
+
+
+ ScriptExec
+ Executes a scripting file as a servlet.
+ com.silverwrist.dynamo.servlet.ScriptExecServlet
+
+ remove.extension
+ vs
+
+ The extension which is used in the servlet mapping to distinguish scripts to execute. This
+ extension is removed from the servlet path to create the script name.
+
+
+
+ script.prefix
+ /scripts
+
+ The resource prefix to use for scripts. This is prepended to the servlet path to create the
+ script name which is executed.
+
+
+
+
+
+ XmlRpc
+ Executes XML-RPC requests.
+ com.silverwrist.dynamo.xmlrpc.XmlRpcServlet
+
+ subsystem.object
+ xmlrpc
+
+ The object name of the XML-RPC subsystem object. Must match the name configured for the
+ com.silverwrist.dynamo.xmlrpc.XmlRpcSubSystem object in dynamo.xml.
+
+
+
+
+
+ Remapper
+ Remaps URLs to other URLs programmatically.
+ com.silverwrist.dynamo.servlet.RemapperServlet
+
+ data.object
+ remapper
+
+ The object name of the remapper data object. Must match the name configured for the
+ com.silverwrist.dynamo.servlet.RemapperData object in dynamo.xml.
+
+
+
+
+
+ Image
+ Serves up images from the ImageStore.
+ com.silverwrist.dynamo.servlet.ImageServlet
+
+ image.store
+ images
+
+ The object name of the image store object. Must match the name configured for the
+ com.silverwrist.dynamo.db.ImageStoreObject object in dynamo.xml.
+
+
+
+
+
+ StyleSheet
+ Serves up CSS stylesheets for use by the frame.
+ com.silverwrist.venice.frame.StyleSheetServlet
+
+
+
+ Frame
+ Frames static pages within the outer Venice frame.
+ com.silverwrist.venice.servlet.FrameServlet
+
+ content.prefix
+ static
+
+ The prefix to apply to the static content path before retrieving it. Interpreted
+ relative to the Web application root (i.e. where Web content normally gets linked from).
+
+
+
+ cache.hard.limit
+ 5
+
+ Maximum number of documents that will be hard-cached by this servlet. Must be at least 1.
+
+
+
+ cache.soft.limit
+ 10
+
+ Maximum number of documents that will be soft-cached by this servlet. Will always be at least
+ twice the number of hard-cached documents.
+
+
+
+
+
+ PasswordRecovery
+ Used to access the password recovery feature; changes user passwords.
+ com.silverwrist.venice.session.PasswordRecoveryServlet
+
+
+
+ User
+ Displays user profiles.
+ com.silverwrist.venice.servlet.UserServlet
+
+
+
+
+
+ ScriptExec
+ *.vs
+
+
+
+ XmlRpc
+ /RPC2
+
+
+
+ Remapper
+ /verifyemail
+
+
+
+ Image
+ /imagedata/*
+
+
+
+ StyleSheet
+ /stylesheet-base.css
+
+
+
+ StyleSheet
+ /stylesheet-advanced.css
+
+
+
+ Frame
+ /frame/*
+
+
+
+ PasswordRecovery
+ /passrecovery/*
+
+
+
+ User
+ /user/*
+
+
+
+
+ 60
+
+
+
+
+ default.jsp
+ index.html
+
+
+
diff --git a/docs/buttons/.gitignore b/docs/buttons/.gitignore
new file mode 100644
index 0000000..5c165d9
--- /dev/null
+++ b/docs/buttons/.gitignore
@@ -0,0 +1 @@
+.xvpics
diff --git a/docs/buttons/bn_blank80.png b/docs/buttons/bn_blank80.png
new file mode 100644
index 0000000000000000000000000000000000000000..100bbd64e9063a1e9bb0cdfe6a99e9b41f069453
GIT binary patch
literal 4362
zcmV+l5%ungP)87gcuA;HqZk&)|V3ULd43K~c
z40s2gf)`+bcm&2wJYWDq7Dxz?jB)7b>QH^}x%cEh@4Pny!y9}{Yklx<{`yz{{4f4&
zdG+GW=dTyb^*r|Hu6_Re1;%t3W{Q(@AloQVw^N5(7KR`
zOey1?C4|lMAh>YeQA#1=2!$AvnpFf5K}Z=-F$gK7$d9K3C6r)5nRMP1Wj#-QmY2p_
z001QzVlFuL-gWH-Lh3x^)aPXtd~DlGp64k=1c48sT3lTYkDQCkbAU1a{f9sL=c0bbDcn9jZmw^uvTnPP;i$D^
zjOF!a|M02ERtN^C6~eeZAFHZqyCLIrn)RYuwCyE^m;hAsD1`_yWLfTfa!vz)tT72D
zMrlld5|ZT-L%iERN?CA*5#ceqvTEAPv8oqJD}*t{7!saIqP6b3mhx;Kt(35=Ywtqe
zbzE>taE!@0lUK|Bd=Nrj+P111jFUA6VuA@9+A}3YWVs8;TlKWJ_z!-IefPKjB&f@z
z)OvF*xd?znH_gg2f}73r$2XsFQDF?tJYvGS^Kr3QUD{qU@_)3KbMOHotfqle7E_Wk
z^DbCtAizfJ1QG-=0f-SS$^s^^-|sljIL8Q42xHx>PKRC9ER@y=0g6Zjq{!JgjYHoP
z!mS02hN^D7^W!)&&KM=$hY(y*uZGJp%k%T)QrAm@lQo7=1|S~WGa*>W%=r+VL6D8p
zjK25%?*VXX`@X0a7-2|rHJq$Vxs=W3t^3bEq%=ne>uErkp7)QTU6hy8
z$yoycoQ9qe5@O_xhY+>VDL`j!NCBh-0iXnDGV{jl_d7~C#sDFfK&3L|kX@|S-uYQ6#u-M?Sr>vUn{{{E3n|-6S5^y>G$|%J`WFffa
zdb8brnHNQh2@y;Q)i#y|*IJFkz(uCD;T$)swbRx*O9%lVdglR1WwX8Lgn2eikso$X&Zq?NG;~sMgee!o7-x)j)~DzbNGU}^Fr|zTl46|Z
ziE)7uAeb7Xn#Jn=%P*vmF(g7MhPWS9CdjPj_Hv<2%(Fr;ELIycn|Yo90L~g`973>c
z*6ne}xHzBALP$c8GlmH{O9Y8h}fPU>e$@Y@9aD
z=J^Nz^Pgo|rv#j8A>^n1<6?Dn*q=!9#)f5GpU-Uwo)DqtS#pLjVLThhIRqa9h|&8H
zLkJK;N+`w%#Hh8#5T)oTrN-#hYQ25W
znH+~Mrr>=7DI^F1_~ma2#yC2!jR624grtzp`}JnM-QMSUZj9lANAD(W>$1>Bx92lN
zM5`Gi&@4B>xxTvykp*jwHk4pOWp~;WLNDh_QPcoLt2Lo)nv@zl!8xIPnpAK$cz|KF
z&R1nY7@LOP7>58rKmGTAc=7y|F?MtN>Tv%_mX(wiUU!(t!_!06EO$=_P7uVbDT>qa
zY>dH}P2&LNvs$gT+iji~*4nbF
zgR{e=%ObPhjl+Nt@z!937OSfi<1|irQGytZv4S&1*wmd7BB$f2C~E{$a1J7(jhp*c
zZ~-BnW)-}%#xsf&M1pfn+1&SPHk1+ky>IF7|KT4WpHAzm+s7|I_AYVJjO`YY{Cs$*
z>gICpIYBX@D$kFHqjQ#0sr5`TrkrzG&Ql*^K$sDNtoI;AjEN9Agb}0=6Y$PL2#car
zN?%=HJv=-VWf6R+n#Nl@X;&4Qb51KALx{l>LYAAW=>5=jMP0#^hJFy7AxzacAWXWh
zZ<-}Y0RmuMa6XLfImTUGAH4Hi#yaO?cRpq^lR^&DY>kQDQ_AwZ
zzz{)1yfx!6GA-bVxxjPal5r+*u?7zY*Xxu|cCkDp1I&)T8jl+st5>&NXjh9E?d
zQW*O_FH4@4)7V+7F_oMXM6l7`J0)b!8BQ@_LZ+c7gk_oRy5aeY=lAz-q|BYu&2p{h
zX;ymCG+HYFQQx(M5K2j2*1_4K@0aThLTK!#7%gEuItvl*x=v;}BRGWML+}C2Lst|<
zmSz1odGD>(c~QtLBLqWC07$39L1q$T91}<}?hX@r{o^0xx8ImmnEJ=8y6cYjSy2wN
zMbQnzcz65k>G3JWm={e
As is well-known, the Venice Web Communities System was originally founded for the purpose of providing
+ code on which the new Electric Minds server could be run. To this
+ end, it was designed along the lines of the CommunityWare platform, by Durand Communications, on which
+ Electric Minds was run for several years. (CommunityWare formed the nucleus of the WebbMe portal system
+ as well.) To that end, the original design goals of Venice looked like this:
+
+
A replacement for the CommunityWare/WebbMe conferencing system
+
Java/JSP/servlets implementation running under Apache Tomcat, MySQL backend
+
Multiple communities hosted per server, each with multiple conferences
+ (and other features); users logged into one server can join multiple communities
+
Conferencing functionality similar to CW/WebbMe:
+
+
Linear topics composed of HTML messages
+
View topics by new messages/unread/all messages/hidden topics/archived topics
+
Topics can be deleted/archived/made read-only by the conference host
+
Topics can be hidden from a user's personal view
+
Individual posts can be "hidden" or "scribbled" by owner or conference host
+
Posts can be previewed, with spellchecking and HTML formatting
+
Files can be "attached" to posts (up to 1 Mb in size)
+
+
+
Enhancements to existing conference features:
+
+
Full text search of posts within a conference
+
Conference-level "bozo filters"
+
Individual posts can be "nuked" without a trace by the conference host
+
+
+
Later, replace other CW/WebbMe functions:
+
+
Activity logs
+
Instant messaging and chat (use Jabber)
+
Calendaring
+
Newsletters via e-mail
+
+
+
Features from CW/WebbMe we won't do:
+
+
Web hosting
+
Web-based email
+
+
+
Blue sky features:
+
+
Output uses XML and gets formatted into [X]HTML via XSLT; "themeable"/"skinnable" interface
+
Conferencing/other functionality available via XML-RPC or SOAP calls
+
News page creation (see Slash, Squishdot, Scoop)
+
Member trust metrics (see Slashdot "karma," Scoop "mojo," Advogato distributed trust metric)
+ (Feature indefinitely shelved at the request of the EMinds community)
+
User diary pages (see Advogato, Kuro5hin)
+
Moderated discussions (see Slash, Scoop)
+
Collaborative database facility (see Wiki, Everything2)
+
Content management/distributed publishing
+
+
+
+
Evolution of The Original Venice Code
+
As time went on and the Venice code was put to use on Electric Minds and elsewhere, gradually, the enhanced
+ feature set described in "Enhancements," above, was implemented, as well as some additional enhancements (user
+ photos in posts, some limited customization capabilities). This was in response to the needs of Electric Minds
+ and other communities
+
Perhaps the biggest change, however, was a changeover from the original UI front end, which used a great many
+ "magic servlets," to a generalized system which employed a scripting engine built into Venice (actually, the
+ Bean Scripting Framework, which supports many different scripting languages), so that UI-level operations could
+ be written as scripts and executed directly by means of a single servlet. The JSP-based display front ends, too,
+ were updated, making heavy use of JSP tag libraries to minimize the amount of embedded code on a page.
+
A partial XML-RPC API was also implemented, and the "mailgate" program was written to take advantage of this,
+ providing a gateway from a mailing list to a Venice conferencing topic, with some success.
+
Dynamo - The Next Leap Forward
+
Currently, the Venice code is being rewritten to be even more modular than before, carrying the advantages
+ of the modularized, scriptable UI into other aspects of the code. As part of this effort, the lower-level
+ support elements of the application are being factored out into a code framework referred to as "Dynamo" (for
+ "DYNAMic Objects"). The goals of the new Dynamo-based Venice are as follows:
+
+
Even greater modularity than the original Venice, including dynamically-loadable modules. One should
+ be able to add a new service to Venice simply by dropping a JAR file into a directory on the server and
+ performing an installation process from within Venice's administrative UI.
+
Replacement of the JSP front-ends, which involve a high degree of overhead as well as the need to employ
+ external access protection to prevent them from being invoked directly by an end-user. Instead, a solution
+ based on the Velocity template system will be employed.
+
Refactoring of database access, to eventually allow the use of databases other than MySQL, especially
+ ones which employ stored procedures.
+
Improved search capabilities for posts, possibly employing the Lucene full-text search engine.
+
Shifting of configuration information from XML configuration files to the database, where it can be
+ modified without bringing down the server. A new "property" storage system will be employed for much of
+ this information.
+
Replacement of the original Venice security model, which employed a somewhat-confusing system of "security
+ levels." Instead, a more modern ACL-based system will be employed, for greater granularity.
+
Replacement of the front-page publishing model to allow people other than administrators to "publish"
+ posts there. Instead, a system of "channels" will be created, with each channel having its own ACL
+ to permit other people to access it.
+
+ Venice identifiers are used for user IDs, community aliases, and conference aliases (and maybe other unique
+ identifiers in the future). A valid Venice ID consists of characters from the following character set
+ only:
+
+
Alphanumerics [A-Z, a-z, and 0-9]
+
Dash [-]
+
Underscore [_]
+
Tilde [~]
+
Asterisk [*]
+
Apostrophe [']
+
Dollar sign [$]
+
+ All characters are represented in the ISO 8859-1 character set. Also note that all Venice identifiers
+ are case-insensitive.
+ Rationale
+ The character set was defined starting with the list of characters allowable in URL path components
+ ("pchar" as defined in RFC 2396, section 3.3, page 14), so that Venice IDs would be usable as "path
+ information" in a URL.
+ The ampersand [&] was eliminated because of its possible confusion with a URL parameter separator, and
+ because it requires HTML escaping.
+ The at sign [@] was eliminated because of possible confusion with email addresses and Jabber IDs.
+ The plus sign [+] was eliminated because of possible confusion with a URL-encoded space character.
+ The comma [,] was eliminated because of its possible interpretation as a separator character.
+ The equals sign [=] was eliminated because of its possible confusion with a URL parameter/value
+ separator.
+ The colon [:] was withheld to provide for a possible future "namespace" expansion (as in XML
+ namespaces).
+ The parentheses [(, )] were eliminated because of possible confusion with user link syntax in
+ conferencing.
+ The period [.] was eliminated because of possible confusion with post link syntax in conferencing.
+ The exclamation point [!] was eliminated because of possible confusion with extended post link syntax in
+ conferencing.
+
+
+
diff --git a/docs/user-acl-truth-table.sxc b/docs/user-acl-truth-table.sxc
new file mode 100644
index 0000000000000000000000000000000000000000..46e2d4cff1e8027eb4919c213d4d71900b852b19
GIT binary patch
literal 6612
zcma)B2|SeD_gD5ITZ2(yj3u(njGgSuF!nWMU&ay!W316wA|Y#$wPY##P9b}ih>%3t
zw-B;rjlZe4-sSVY|IhC}pShp8_kPd0=X}q7?sJ~|=%^DC0SU-Xua_FB`~-g~6sP}f
z-OyMR8Y|%I>av<)>NciE(>dAy^y@~OZsF^P^IEAn6`FxOZ1=_x%eup)q#8E#unJ9q
z$>SmiN~9XtWCnFX%R;rx!2x%*a-wMjW^>ZETjEE~C+mFd0w(YAXSojteoZK@?s{1GzI*v!#8(VD9G7;YktKX-biQWHn3&dYkT2i8B
zWLRdm>TP;*yrWv1?fV64T%s~PH==e^{Hj<+Z-;|?LuR}7_nRI_fqqs@%$Wu=@GkVo
zH}I%=MiesK!cLn{wa^hz#>h+ZVesY=N5ggux{Wb*M6#cfVRof+8Y?Z4`fO`-l64=6
zdCWB={*|;_ndVbwoevMcy>QJ4XrVOAB=patY05P&(&=kxI%5mCOg+Z7@=KL
zRvH|o>_4@`Vkc`8bqgc&d}jZNNb0@I%MJ6w3+JzBwSl`kJUbkEp{smTTd{{-{%KcR
z?8gknyYl>B7!-?{Fc=Xu5|+n2gCsv2D2k*roTnSU;HCQ{)!>PLnuzkIPMKvK|+WnG;eHGXRW#?
zaW9DH)8Jf{_@!djXvCO#+P?VC<-;P?uO=CX?cX)fsg547b4S8c7b%!tzUSC0QvW&{
zH&uzG+ejjMQW4gGTSnhi*LDJ4NNpXqc7;T}DAx(0v>crlb
zjXbKoscI-w=y^9uGMRu?b;JO!m^5GrH`zIfnnQ+)obI|+Fc!N}or
zp9sseG|Qq`{x1}F>$X)Y<<#BsJ`KAAQPkk|^eHj#Wg9RmYhw{zaR*Zwk9*9r9lh>$
z>wfQR?Nyb0{r&yMqol|zLP{>4&@+?_JfXytBs`(#C|P(y2`L5WLw$}&{BgV4+joUv
zf+Wdm8K^e;U}#-S%3o_&S6q3SQset;v#1t0ZEiF
z6$1>ELn#XL&7q`%JvZ1o^BeUU00#z|Uy>K_$1Jpc+s>-sJ&==a5))?DA~fF7*SpXNezmNH&5xoABVh?lfRJzI7?~H7T!uvgc(RojAAy3TRh+J
zTw0YGn4?tyZnipA-$;7qmkAza!7c3f@Gco%(ve?&4EE9^J`-L-qc{yX`{HwV3UwH7
z*9z6FHtTf4v9KKO!hL58Qjo@}dLLM`RlJ~avsIknhvupHK2lPUS%LWDA0Q=X*=1@N
zHVgzfiN;$Y#A>m#_~68Ed6;PDM#5TVPzwhN7SsYkl?AncQFseb?m;cNHgY>RLi|OL
zKHAN1@r@9(?YX&`SNV+JheQs(4=03F$;n^OIb_8X2{59uDpO_Rvx2F5S`&t|%Yug+{WvY-qpk}KC!PDx8`DAcl3H7N1
z9W7@_k|R&UaPHtO*J-fuVJM-Fi^@zlb1`Sl8J}G5^|_zC9sEEZyvM2*CI?7NYLx@1
zM?d)-ZLDhjwxbmRh)rsh2P8+Itq$>dbXOT6zvl$d!@lAM;2>d4OUOEew+j4NWm3ZQ
zJup1A)lnoYE00VUc>EHUQ|8FSmjiPYvSANXQJ)5fsUzZ@0g9T|RjI8y`nS0wM@|JG
zix>PnQa1;8LEEX%i&Tx(`W>B@;#+faVR5Zba?9dcALo|Ew`S+M$F*{1chQsgEHk;9
zOY32~xiQMEgZ@Y+Kf|0>dVC-&Al4f)*~Jqo0R8AEd(w0aUxzwc6#$`0zg=*#n2Wp}
zb`)Kcz{*o+0}R7yg`PT)%80Y#U+9?(b2)i&F=5Dl>$D7VWPcwfY>ocyEVVy=fsGTN?JS<~%H{_=5>%v4Hs^hm6g
z;VNND6F5iKGktiR>FKR?#;I+3*@VD7RvmRxvWgG@iv}41LC;MB0-gU%LI9^ph$q(1
z1?7p)L57V@+-5~-ZmpNcQ;F#dFEg^#xq&3lO>#BUB%tcDE8C)fwH_;yXu3IuP;dA(!XZy{{8536iI^D<74j
zCuNSjcKfV*IAh)l+v~tgEY@vme+(d4)`_A|oQ5(gWSdMDO
zNOf#Y1fHdWEg;GxklK8G=AlSfeo>0pCB+#jJw7NC
z2E7(sX-86bn}_S8gzp)lq^7l*XrTDHk4y~l9QNlp4Gh!70yaCT`_APJL`sZ^n~*QY
z2CA$RG@X1Avpcioz1yre@xj>u9l|{$o*Ehux^?t+)Iyt~s0$lE_!7i#E$`ySbMLyt
zc7_+b5*hb2Q!;T2agyt^Pps2GIx%*b!u};9{(kQe&Nwb&jhr~a$SQ6dV)_76HOYGO
zhqkIW6H#%wujoEh*=X+OFB3wN?1`jz3~d%~14exirFw$gDX5f-vu1Jy2i3BYh8~|e
zc5=Y!DS37`^?9M;Z?t7T&mniX35haRW6X0O);$E=SB-*emBpo8aAx$^Ds)jIUfkUH
z_)P--O?xf;QhBNfyN=b4D4B)ur$SA)A!7F2M_ztlfSR=-ICd9&l#6*`Yok3Uy(7_u
z%-0m>75x6$x$~kywaI?1-MIyqMf8%h{KJ6Mm?ZU4OyGQwwCca4M%wG396vH9*zgiS_
zgGbS2Sq7
z$thaqj3e1=r7i51$2I1O_)S%WYWSFqN{Vv|cRmg+mMrt|_GHNdxSlQ^kPlz!I-k$!
zn2$Aw*WRq#BtAcAiRyi1mX4j6mBA%N-#z)DA|d+4qii+0wr$&bGt>dmI4A&$9litS
zk&%(mx4G;<)Y%tb+9b>!TE5RMpnJUke1b9?y6l?eF}fQAu?#c{7NyyoSJTmSU|#ct
z1}`FprWLloeIqS|HEWHODWIG_zeK0ctvT~fYwT<|+2a;@Z})y;wXm@0YbbfER-wgN
z<@~t9@9Cu~iuoue*;WsyT(*yJv(!y*1)26%hx>3DRfS#uWZoFM;R!?fTb$57_0aRi
zaa`?1ma9r5lKGs2)e{oteT0tdj$qOlz}#}YPE1-O>+{*>bA58+R1H%a-)$jf7Ti{Q
zh5C|wFLy(iHukr-pJ3{sL#`*c+z*&b$=_xBh^Gh#Bfc4;W_BjoN>5J0r)BXwXYtPU
z<+H>D1fPJvc24|T8~*iel!a`%o{)e5|2y4U30zTFYy7?`C3{+dy-^rXCpWY-1TFxB
zfKg~$H#;Y^gEYj@0KqQ~k(B{Ru_>UKKEAENj<1Ys~3^k*9a{wd(=;)HhojrZ~K5%3ZEVGmqFLIV0@
z^cU35_BYPm3*+(wWoHXTxuEd=c|zd=aOf{A-r3*if3pG)fc)a;|I4-b)%!q<`x
zC^QOVjdjDw{GByCLjrIxw}uni%a=zA`VX)a8$Z9ko}#EQ+|pD`R8+{^QUj@FXl#kp
zGEmmAwDfee_CZ@(V=ZCgP&gb46SRa2Ns5R`3JdY`|1q&G24#&s4LHA@H5Mgv%AX)V
zT##Q-)Bq+Z2@{qSl=x%LzvHCrY$g9iKuAndL{tj;Yw)LQC_5+Y=@R0%^|L*FLdyvL
zq3|Ewf5+N+osw~Cm5h#okdUUJxc)zcevkhY^YTPt`0Y^kPH2=J_y1F=;-k9c)R29u%RC6Rr$@#wWXA$%;2=rp|~V2
z4kRJNIAC5M$sON?vY^?oRcLyeX+~jLh#NmL#}(~_uOjYBOA`z1&%nhfknP%ftrDN}
za=k5Ij5u>nD*;(;>7@I1v`l8AY+f2c`NwupwR9l5R|s`(a*C<^PU$TF%0wy)#8PtD
z-ZhX13yxNq#QOvF)d~*e%oBdTs~S!;_bhj|q-5XpFVxMeHu+5I0`dJ`%U%{krFP@p?&m4{N6waw@i_?v|II*Uq&gWW;PDc(d!i
zZ(5#eV_?EUpj8W3Wv#ddX8hw0xr={v;|
z)j0kAio%^wPh<~qL^2pZ7@KEZFgs4gckcTXFOE9B=9;msk=8zVw`}RAvLR@ZFM!my
zCsy`yrTL8Cd%uz~E4P<>MSZK;Dw9cCc^PSXD0=Da4VzR~Jw_9)
zF&|p1M?m7a+U*|c>2cZ~3PJ#I%;PHCt8P^2It)P`b9?!G9?$4xv?iVCuIxA}=<+D(
z9)Cw{*!u*l$|}|%GacvX3Ohnglk%|FoAW7rmS0RRjx6ku={n5-&H7urto#zKsHxtl
zzy-BA;+$gSMus}0+suQp4q0uEW1MNk(_lm$ZOqNyW}eGw=K~`$stHz>Hk$*4DM*mk
zjXs%FJvSX@G>^Wq&ya46_iltB>)Z3A4X(`grqwWah&V~zb3430n;023K*I%(NOsLjG%^*5l9Ch;<
zYPd=e`G=4*Pj{rM@~Xz213dY>?0bYOMRw}N9FbZBO#&Nt(8sewcONnPNqQ(o_zYRC
zW(ovDp)vNaYaSS}yrq7@IOtG+d0wOd8;x+*>!o!9v1>aAtT^AWODleO`+HBOy;@j5
z8BYqYk)8{^B<#yKV<#+_E7G+NGwCzW(E9=~TNm#54jMlocR``8ZPVtxq*2EvY
zw)|H5@xAcyaFP<(0^IblC-C-FLQbDlTbxW@$>3J1aP`$7P)^v1VotPyX?8-%750lA
z8#l58ExO=(GmRGu`rk4x^xuYqfHpgVmW2C*+Wsocg^!N2v#-mGP*ZgL}RwN&1ft$*PSGOc?WTAR
z1*f2FZ-y6AZKjzJ);U_*Od8LPwN-e5Zqk~k?*~79TAW|(wVMqjmbzty@#sK%O6|g@C$Rqn+$go<9!RiwDbZw83adre11iO`snQzLT42!h#HVHYxS1yOWy`Bc;rnuI|v!SA}6bOJv_!D
zByO-i!0RHWz2s@}rQi_;dfmxOF>_={{{EfX{@9ElvhvSe44T>WuS#Sg3x)!Xd39Fo
zYfbXa+rSYs#b&oRG_MaVo3bV|e5v@S;9v7){CUEkCG0dw{_}Lh($
literal 0
HcmV?d00001
diff --git a/drivers/.gitignore b/drivers/.gitignore
new file mode 100644
index 0000000..b3b3865
--- /dev/null
+++ b/drivers/.gitignore
@@ -0,0 +1 @@
+mysql-connector-java-3.0.7-stable-bin.jar
diff --git a/drivers/README.drivers b/drivers/README.drivers
new file mode 100644
index 0000000..eb651f5
--- /dev/null
+++ b/drivers/README.drivers
@@ -0,0 +1,6 @@
+This is the directory where JDBC drivers get placed.
+
+MySQL
+-----
+Store the file "mysql-connector-java-3.0.7-stable-bin.jar" in this directory.
+
diff --git a/resources/dynamo-test-module/res1.txt b/resources/dynamo-test-module/res1.txt
new file mode 100644
index 0000000..f7513f6
--- /dev/null
+++ b/resources/dynamo-test-module/res1.txt
@@ -0,0 +1 @@
+If you're reading this, we loaded the resource successfully!
diff --git a/src/baseutil/com/silverwrist/util/AnyCharMatcher.java b/src/baseutil/com/silverwrist/util/AnyCharMatcher.java
new file mode 100644
index 0000000..a454c0f
--- /dev/null
+++ b/src/baseutil/com/silverwrist/util/AnyCharMatcher.java
@@ -0,0 +1,160 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.util;
+
+/**
+ * A class which performs the equivalent of String.indexOf(char), but using
+ * multiple characters. It locates the first instance within a string of any of
+ * the specified characters.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public final class AnyCharMatcher
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private char[] charset; // the set of characters to look for
+ private int[] locs; // a temporary array used for locations
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a new character matcher that matches the specified characters.
+ *
+ * @param charset The set of characters to be matched by this object, expressed as a character array.
+ */
+ public AnyCharMatcher(char[] charset)
+ {
+ this.charset = charset;
+ this.locs = new int[charset.length];
+
+ } // end constructor
+
+ /**
+ * Creates a new character matcher that matches the specified characters.
+ *
+ * @param charset The set of characters to be matched by this object, expressed as a string.
+ */
+ public AnyCharMatcher(String charset)
+ {
+ this.charset = charset.toCharArray();
+ this.locs = new int[charset.length()];
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Returns the offset within the string of the first instance of any character in this
+ * character set.
+ *
+ * @param str The string to look through. If this parameter is null,
+ * the method returns -1.
+ * @return The 0-based index of the first instance of any character from this character
+ * matcher within str. If str contains no instances of
+ * any character from this character matcher, -1 is returned.
+ */
+ public final int get(String str)
+ {
+ if (str==null)
+ return -1;
+ int numindexes = 0;
+ int i;
+ for (i=0; i=0)
+ locs[numindexes++] = tmp;
+
+ } // end for
+
+ if (numindexes==0)
+ return -1; // no characters found
+ else if (numindexes==1)
+ return locs[0]; // only one found
+
+ int rc = locs[0];
+ for (i=1; inull
,
+ * the method returns -1.
+ * @return The 0-based index of the last instance of any character from this character
+ * matcher within str. If str contains no instances of
+ * any character from this character matcher, -1 is returned.
+ */
+ public final int getLast(String str)
+ {
+ if (str==null)
+ return -1;
+
+ int numindexes = 0;
+ int i;
+ for (i=0; i=0)
+ locs[numindexes++] = tmp;
+
+ } // end for
+
+ if (numindexes==0)
+ return -1; // no characters found
+ else if (numindexes==1)
+ return locs[0]; // only one found
+
+ int rc = locs[0];
+ int limit = str.length() - 1;
+ for (i=1; irc)
+ rc = locs[i]; // this is now the highest
+
+ } // end for
+
+ return rc;
+
+ } // end getLast
+
+} // end class AnyCharMatcher
diff --git a/src/baseutil/com/silverwrist/util/BooleanValues.properties b/src/baseutil/com/silverwrist/util/BooleanValues.properties
new file mode 100644
index 0000000..cf97455
--- /dev/null
+++ b/src/baseutil/com/silverwrist/util/BooleanValues.properties
@@ -0,0 +1,19 @@
+# The contents of this file are subject to the Mozilla Public License Version 1.1
+# (the "License"); you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at .
+#
+# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+# WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+# language governing rights and limitations under the License.
+#
+# The Original Code is the Venice Web Communities System.
+#
+# The Initial Developer of the Original Code is Eric J. Bowersox ,
+# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+# Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+#
+# Contributor(s):
+# ---------------------------------------------------------------------------------
+# This file has been localized for the en_US locale
+values.true=1|true|yes|on
+values.false=0|false|no|off
diff --git a/src/baseutil/com/silverwrist/util/Country.java b/src/baseutil/com/silverwrist/util/Country.java
new file mode 100644
index 0000000..72e4016
--- /dev/null
+++ b/src/baseutil/com/silverwrist/util/Country.java
@@ -0,0 +1,159 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2001-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.util;
+
+/**
+ * A utility class used by International that stores a country code and name pair.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ * @see International
+ */
+public final class Country implements Comparable
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private String m_code; // the country code
+ private String m_name; // the country name
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a new Country object.
+ *
+ * @param code The country code.
+ * @param name The country name.
+ */
+ Country(String code, String name)
+ {
+ m_code = code.trim().toUpperCase();
+ m_name = name.trim();
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class Object
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Indicates whether some other object is "equal to" this one.
+ *
+ * @param o The reference object with which to compare.
+ * @return true if this object is the same as the o argument; false otherwise.
+ */
+ public boolean equals(Object o)
+ {
+ if ((o==null) || !(o instanceof Country))
+ return false;
+ if (this==(Country)o)
+ return true;
+ Country other = (Country)o;
+ return m_code.equals(other.m_code);
+
+ } // end equals
+
+ /**
+ * Returns a hash code value for the object. This method is supported for the benefit of hashtables such as those
+ * provided by java.util.Hashtable.
+ *
+ * @return A hash code value for this object.
+ */
+ public int hashCode()
+ {
+ return m_code.hashCode();
+
+ } // end hashCode
+
+ /**
+ * Returns a string representation of the object. In general, the toString method returns a string
+ * that "textually represents" this object.
+ *
+ * @return A string representation of the object.
+ */
+ public String toString()
+ {
+ return m_name + " [" + m_code + "]";
+
+ } // end toString
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface Comparable
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Compares this object with the specified object for order. Returns a negative integer, zero, or a positive
+ * integer as this object is less than, equal to, or greater than the specified object. Country
+ * objects are compared on their country name.
+ *
+ * @param o The Object to be compared.
+ * @return A negative integer, zero, or a positive integer as this object is less than, equal to, or greater than
+ * the specified object.
+ * @exception java.lang.ClassCastException If the specified object's type prevents it from being compared to
+ * this Object.
+ */
+ public int compareTo(Object o)
+ {
+ if (o==null)
+ return 1;
+ if (o instanceof Country)
+ { // compare country names
+ Country c = (Country)o;
+ return m_name.compareTo(c.m_name);
+
+ } // end if
+
+ return m_name.compareTo(o.toString());
+
+ } // end compareTo
+
+ /*--------------------------------------------------------------------------------
+ * External getters
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Returns the 2-letter country code for this country.
+ *
+ * @return The 2-letter country code for this country.
+ */
+ public final String getCode()
+ {
+ return m_code;
+
+ } // end code
+
+ /**
+ * Returns the name of this country.
+ *
+ * @return The name of this country.
+ */
+ public final String getName()
+ {
+ return m_name;
+
+ } // end name
+
+} // end class Country
diff --git a/src/baseutil/com/silverwrist/util/HardSoftCache.java b/src/baseutil/com/silverwrist/util/HardSoftCache.java
new file mode 100644
index 0000000..41a7a9b
--- /dev/null
+++ b/src/baseutil/com/silverwrist/util/HardSoftCache.java
@@ -0,0 +1,329 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.util;
+
+import java.lang.ref.*;
+import java.util.*;
+
+/**
+ * A class implementing a memory-sensitive cache. The cache is an LRU cache which uses two size limits,
+ * the soft limit and the hard limit. The soft limit dictates the maximum size of the
+ * cache; all elements in the cache have SoftReferences to them, which allows the JVM to expel
+ * them from memory if necessary. However, the most recent elements in the cache, up to the hard limit,
+ * have ordinary references on them, which prevents them from being expelled. Therefore, under low memory
+ * conditions, all elements in the cache may be discarded except for the most recent ones.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public class HardSoftCache
+{
+ /*--------------------------------------------------------------------------------
+ * Internal class to hold the hard hash entries
+ *--------------------------------------------------------------------------------
+ */
+
+ private static class HardHashMap extends LinkedHashMap
+ {
+ /*====================================================================
+ * Attributes
+ *====================================================================
+ */
+
+ private int m_maxsize; // maximum size of the cache
+
+ /*====================================================================
+ * Constructor
+ *====================================================================
+ */
+
+ private HardHashMap(int capacity)
+ {
+ super(capacity+2,0.95F,true);
+ m_maxsize = capacity;
+
+ } // end constructor
+
+ /*====================================================================
+ * Overrides from class LinkedHashMap
+ *====================================================================
+ */
+
+ protected boolean removeEldestEntry(Map.Entry eldest)
+ {
+ return (this.size()>m_maxsize);
+
+ } // end removeEldestEntry
+
+ } // end class HardHashMap
+
+ /*--------------------------------------------------------------------------------
+ * Internal class to hold the soft hash entries
+ *--------------------------------------------------------------------------------
+ */
+
+ private static class SoftHashMap extends LinkedHashMap
+ {
+ /*====================================================================
+ * Attributes
+ *====================================================================
+ */
+
+ private int m_maxsize; // maximum size of the cache
+
+ /*====================================================================
+ * Constructor
+ *====================================================================
+ */
+
+ private SoftHashMap(int capacity)
+ {
+ super(capacity+2,0.95F,true);
+ m_maxsize = capacity;
+
+ } // end constructor
+
+ /*====================================================================
+ * Overrides from class HashMap
+ *====================================================================
+ */
+
+ public Object put(Object key, Object value)
+ {
+ SoftReference newref = new SoftReference(value);
+ Reference r = (Reference)(super.put(key,newref));
+ Object rc = null;
+ if (r!=null)
+ { // get the old object
+ rc = r.get();
+ r.clear();
+
+ } // end if
+
+ return rc;
+
+ } // end put
+
+ public void putAll(Map t)
+ {
+ Iterator it = t.entrySet().iterator();
+ while (it.hasNext())
+ { // run each item through our modified put()
+ Map.Entry ntry = (Map.Entry)(it.next());
+ this.put(ntry.getKey(),ntry.getValue());
+
+ } // end while
+
+ } // end putAll
+
+ public Object remove(Object key)
+ {
+ Reference r = (Reference)(super.remove(key));
+ Object rc = null;
+ if (r!=null)
+ { // get the old object
+ rc = r.get();
+ r.clear();
+
+ } // end if
+
+ return rc;
+
+ } // end remove
+
+ /*====================================================================
+ * Overrides from class LinkedHashMap
+ *====================================================================
+ */
+
+ public void clear()
+ {
+ Iterator it = this.values().iterator();
+ while (it.hasNext())
+ { // dump all the references we contain
+ Reference r = (Reference)(it.next());
+ r.clear();
+
+ } // end while
+
+ super.clear();
+
+ } // end clear
+
+ public Object get(Object key)
+ {
+ Reference r = (Reference)(super.get(key));
+ if (r==null)
+ return null;
+ Object rc = r.get();
+ if (rc==null)
+ { // reference has been dumped - remove it from the map
+ super.remove(key);
+ r.clear();
+
+ } // end if
+
+ return rc;
+
+ } // end get
+
+ protected boolean removeEldestEntry(Map.Entry eldest)
+ {
+ if (this.size()<=m_maxsize)
+ return false;
+ Reference r = (Reference)(eldest.getValue());
+ r.clear();
+ return true;
+
+ } // end removeEldestEntry
+
+ } // end class SoftHashMap
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private HardHashMap m_hard_map; // the "hard map"
+ private SoftHashMap m_soft_map; // the "soft map"
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a new cache object.
+ *
+ * @param hard_limit The "hard limit" for this cache. Has a minimum value of 1.
+ * @param soft_limit The "soft limit" for this cache. Has a minimum value of 2 times the value of the
+ * "hard limit."
+ */
+ public HardSoftCache(int hard_limit, int soft_limit)
+ {
+ // Pre-condition the input parameters.
+ if (hard_limit<1)
+ hard_limit = 1;
+ if (soft_limit<(hard_limit * 2))
+ soft_limit = hard_limit * 2;
+ m_hard_map = new HardHashMap(hard_limit);
+ m_soft_map = new SoftHashMap(soft_limit);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Returns the value to which this cache maps the specified key. Returns null if the cache
+ * contains no mapping for this key.
+ *
+ * @param key The key whose associated value is to be returned.
+ * @return The value to which this cache maps the specified key.
+ */
+ public synchronized Object get(Object key)
+ {
+ if (key==null)
+ throw new NullPointerException("HardSoftCache.get");
+ Object hard_rc = m_hard_map.get(key);
+ Object soft_rc = m_soft_map.get(key);
+ return ((hard_rc!=null) ? hard_rc : soft_rc);
+
+ } // end get
+
+ /**
+ * Associates the specified value with the specified key in this cache. If the cache previously contained a
+ * mapping for this key, the old value is replaced.
+ *
+ * @param key The key with which the specified value is to be associated.
+ * @param value The value to be associated with the specified key.
+ */
+ public synchronized void put(Object key, Object value)
+ {
+ if (key==null)
+ throw new NullPointerException("HardSoftCache.put(key)");
+ if (value==null)
+ throw new NullPointerException("HardSoftCache.put(value)");
+ m_hard_map.put(key,value);
+ m_soft_map.put(key,value);
+
+ } // end put
+
+ /**
+ * Removes the mapping for this key from this cache if present.
+ *
+ * @param key The key whose mapping is to be removed from the map.
+ */
+ public synchronized void remove(Object key)
+ {
+ if (key==null)
+ throw new NullPointerException("HardSoftCache.remove");
+ m_hard_map.remove(key);
+ m_soft_map.remove(key);
+
+ } // end remove
+
+ /**
+ * Returns the number of key-value mappings in this cache.
+ *
+ * @return The number of key-value mappings in this cache.
+ */
+ public synchronized int size()
+ {
+ return m_soft_map.size();
+
+ } // end size
+
+ /**
+ * Returns true if this cache contains no key-value mappings.
+ *
+ * @return true if this cache contains no key-value mappings.
+ */
+ public synchronized boolean isEmpty()
+ {
+ return m_hard_map.isEmpty();
+
+ } // end isEmpty
+
+ /**
+ * Removes all mappings from this cache.
+ */
+ public synchronized void clear()
+ {
+ m_hard_map.clear();
+ m_soft_map.clear();
+
+ } // end clear
+
+ /**
+ * Returns true if this cache contains a mapping for the specified key.
+ *
+ * @param key The key whose presence in this cache is to be tested.
+ * @return true if this cache contains a mapping for the specified key.
+ */
+ public synchronized boolean containsKey(Object key)
+ {
+ if (key==null)
+ throw new NullPointerException("HardSoftCache.containsKey");
+ return (m_soft_map.get(key)!=null);
+
+ } // end containsKey
+
+} // end class HardSoftCache
diff --git a/src/baseutil/com/silverwrist/util/IOUtils.java b/src/baseutil/com/silverwrist/util/IOUtils.java
new file mode 100644
index 0000000..d8edcf1
--- /dev/null
+++ b/src/baseutil/com/silverwrist/util/IOUtils.java
@@ -0,0 +1,378 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.util;
+
+import java.io.*;
+
+/**
+ * A collection of IO-related static methods which are useful in various contexts.
+ * Some of the concepts in this class have been borrowed from Apache Jakarta Avalon Excalibur 4.0.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public class IOUtils
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * The default buffer size to use for copying, if none is specified.
+ */
+ public static int DEFAULT_BUFSIZE = 4096;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * IOUtils instances should NOT be constructed in standard programming.
+ * Instead, the class should be used as IOUtils.shutdown(stm);.
+ * This constructor is public to permit tools that require a JavaBean instance
+ * to operate.
+ */
+ public IOUtils()
+ { // do nothing
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * External static operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Closes an input stream cleanly, without throwing an exception.
+ *
+ * @param stm The stream to be closed.
+ * @see java.io.InputStream#close()
+ */
+ public static void shutdown(InputStream stm)
+ {
+ try
+ { // close the stream
+ stm.close();
+
+ } // end try
+ catch (IOException e)
+ { // throw away the exception
+ } // end catch
+
+ } // end shutdown
+
+ /**
+ * Closes an output stream cleanly, without throwing an exception.
+ *
+ * @param stm The stream to be closed.
+ * @see java.io.OutputStream#close()
+ */
+ public static void shutdown(OutputStream stm)
+ {
+ try
+ { // close the stream
+ stm.close();
+
+ } // end try
+ catch (IOException e)
+ { // throw away the exception
+ } // end catch
+
+ } // end shutdown
+
+ /**
+ * Closes an input reader cleanly, without throwing an exception.
+ *
+ * @param stm The stream to be closed.
+ * @see java.io.Reader#close()
+ */
+ public static void shutdown(Reader rdr)
+ {
+ try
+ { // close the stream
+ rdr.close();
+
+ } // end try
+ catch (IOException e)
+ { // throw away the exception
+ } // end catch
+
+ } // end shutdown
+
+ /**
+ * Closes an output reader cleanly, without throwing an exception.
+ *
+ * @param stm The stream to be closed.
+ * @see java.io.Writer#close()
+ */
+ public static void shutdown(Writer wr)
+ {
+ try
+ { // close the stream
+ wr.close();
+
+ } // end try
+ catch (IOException e)
+ { // throw away the exception
+ } // end catch
+
+ } // end shutdown
+
+ /**
+ * Copies the contents of the given input stream to the given output stream.
+ *
+ * @param input The stream to copy binary data from.
+ * @param output The stream to copy binary data to.
+ * @param bufsize The size of the buffer to allocate for copying.
+ * @exception java.io.IOException If an exception occurred while reading or writing data.
+ */
+ public static void copy(InputStream input, OutputStream output, int bufsize) throws IOException
+ {
+ byte[] buffer = new byte[bufsize];
+ int rd = input.read(buffer);
+ while (rd>=0)
+ { // simple read-write loop to shove data out the door
+ if (rd>0)
+ output.write(buffer,0,rd);
+ rd = input.read(buffer);
+
+ } // end while
+
+ } // end copy
+
+ /**
+ * Copies the contents of the given input stream to the given output stream. Uses a default
+ * buffer size.
+ *
+ * @param input The stream to copy binary data from.
+ * @param output The stream to copy binary data to.
+ * @exception java.io.IOException If an exception occurred while reading or writing data.
+ * @see #DEFAULT_BUFSIZE
+ * @see #copy(java.io.InputStream,java.io.OutputStream,int)
+ */
+ public static void copy(InputStream input, OutputStream output) throws IOException
+ {
+ copy(input,output,DEFAULT_BUFSIZE);
+
+ } // end copy
+
+ /**
+ * Takes the contents of an input stream and returns it as an array of bytes.
+ *
+ * @param input The stream to load binary data from.
+ * @param bufsize The size of the buffer to allocate for copying.
+ * @return A new byte array containing the contents of the specified input stream.
+ * @exception java.io.IOException If an exception occurred while reading data.
+ * @see #copy(java.io.InputStream,java.io.OutputStream,int)
+ */
+ public static byte[] load(InputStream input, int bufsize) throws IOException
+ {
+ ByteArrayOutputStream stm = new ByteArrayOutputStream();
+ try
+ { // copy the data to the input stream
+ copy(input,stm,bufsize);
+ return stm.toByteArray();
+
+ } // end try
+ finally
+ { // close our byte array stream before we go
+ shutdown(stm);
+
+ } // end finally
+
+ } // end load
+
+ /**
+ * Takes the contents of an input stream and returns it as an array of bytes. Uses a default
+ * buffer size.
+ *
+ * @param input The stream to load binary data from.
+ * @return A new byte array containing the contents of the specified input stream.
+ * @exception java.io.IOException If an exception occurred while reading data.
+ * @see #DEFAULT_BUFSIZE
+ * @see #load(java.io.InputStream,int)
+ */
+ public static byte[] load(InputStream input) throws IOException
+ {
+ return load(input,DEFAULT_BUFSIZE);
+
+ } // end load
+
+ /**
+ * Takes the contents of a binary file and returns it as an array of bytes.
+ *
+ * @param file The file to load binary data from.
+ * @param bufsize The size of the buffer to allocate for copying.
+ * @return A new byte array containing the contents of the specified file.
+ * @exception java.io.IOException If an exception occurred while reading data.
+ * @see #load(java.io.InputStream,int)
+ */
+ public static byte[] loadBinary(File file, int bufsize) throws IOException
+ {
+ FileInputStream stm = new FileInputStream(file);
+ try
+ { // now just load from the stream
+ return load(stm,bufsize);
+
+ } // end try
+ finally
+ { // close the file before we leave
+ shutdown(stm);
+
+ } // end finally
+
+ } // end loadBinary
+
+ /**
+ * Takes the contents of a binary file and returns it as an array of bytes. Uses a default
+ * buffer size.
+ *
+ * @param file The file to load binary data from.
+ * @return A new byte array containing the contents of the specified file.
+ * @exception java.io.IOException If an exception occurred while reading data.
+ * @see #DEFAULT_BUFSIZE
+ * @see #loadBinary(java.io.File,int)
+ */
+ public static byte[] loadBinary(File file) throws IOException
+ {
+ return loadBinary(file,DEFAULT_BUFSIZE);
+
+ } // end loadBinary
+
+ /**
+ * Copies the contents of the given input reader to the given output writer.
+ *
+ * @param input The reader to copy character data from.
+ * @param output The writer to copy character data to.
+ * @param bufsize The size of the buffer to allocate for copying.
+ * @exception java.io.IOException If an exception occurred while reading or writing data.
+ */
+ public static void copy(Reader input, Writer output, int bufsize) throws IOException
+ {
+ char[] buffer = new char[bufsize];
+ int rd = input.read(buffer);
+ while (rd>=0)
+ { // simple read-write loop to shove data out the door
+ if (rd>0)
+ output.write(buffer,0,rd);
+ rd = input.read(buffer);
+
+ } // end while
+
+ } // end copy
+
+ /**
+ * Copies the contents of the given input reader to the given output writer. Uses a default
+ * buffer size.
+ *
+ * @param input The reader to copy character data from.
+ * @param output The writer to copy character data to.
+ * @exception java.io.IOException If an exception occurred while reading or writing data.
+ * @see #DEFAULT_BUFSIZE
+ * @see #copy(java.io.Reader,java.io.Writer,int)
+ */
+ public static void copy(Reader input, Writer output) throws IOException
+ {
+ copy(input,output,DEFAULT_BUFSIZE);
+
+ } // end copy
+
+ /**
+ * Takes the contents of an input reader and returns it as a StringBuffer.
+ *
+ * @param input The reader to copy character data from.
+ * @param bufsize The size of the buffer to allocate for copying.
+ * @return A new StringBuffer containing the contents of the specified reader.
+ * @exception java.io.IOException If an exception occurred while reading data.
+ * @see #copy(java.io.Reader,java.io.Writer,int)
+ */
+ public static StringBuffer load(Reader input, int bufsize) throws IOException
+ {
+ StringWriter wr = new StringWriter();
+ try
+ { // copy from reader to StringWriter
+ copy(input,wr,bufsize);
+ return wr.getBuffer();
+
+ } // end try
+ finally
+ { // make sure and close the StringWriter before we go
+ shutdown(wr);
+
+ } // end finally
+
+ } // end load
+
+ /**
+ * Takes the contents of an input reader and returns it as a StringBuffer. Uses a
+ * default buffer size.
+ *
+ * @param input The reader to copy character data from.
+ * @return A new StringBuffer containing the contents of the specified reader.
+ * @exception java.io.IOException If an exception occurred while reading data.
+ * @see #DEFAULT_BUFSIZE
+ * @see #load(java.io.Reader,int)
+ */
+ public static StringBuffer load(Reader input) throws IOException
+ {
+ return load(input,DEFAULT_BUFSIZE);
+
+ } // end load
+
+ /**
+ * Takes the contents of a text file and returns it as a StringBuffer.
+ *
+ * @param file The file to copy text from.
+ * @param bufsize The size of the buffer to allocate for copying.
+ * @return A new StringBuffer containing the contents of the specified text file.
+ * @exception java.io.IOException If an exception occurred while reading data.
+ * @see #load(java.io.Reader,int)
+ */
+ public static StringBuffer loadText(File file, int bufsize) throws IOException
+ {
+ FileReader rdr = new FileReader(file);
+ try
+ { // load from the string reader
+ return load(rdr,bufsize);
+
+ } // end try
+ finally
+ { // make sure and close the reader before we go
+ shutdown(rdr);
+
+ } // end finally
+
+ } // end load
+
+ /**
+ * Takes the contents of a text file and returns it as a StringBuffer.
+ *
+ * @param file The file to copy text from.
+ * @return A new StringBuffer containing the contents of the specified text file.
+ * @exception java.io.IOException If an exception occurred while reading data.
+ * @see #DEFAULT_BUFSIZE
+ * @see #loadText(java.io.File,int)
+ */
+ public static StringBuffer loadText(File file) throws IOException
+ {
+ return loadText(file,DEFAULT_BUFSIZE);
+
+ } // end load
+
+} // end class IOUtils
diff --git a/src/baseutil/com/silverwrist/util/International.java b/src/baseutil/com/silverwrist/util/International.java
new file mode 100644
index 0000000..14f2a81
--- /dev/null
+++ b/src/baseutil/com/silverwrist/util/International.java
@@ -0,0 +1,267 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.util;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * A class which centralizes a number of "international" resources, such as locales,
+ * country lists, and language lists.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public class International
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static International self = new International(); // me
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private List country_list = null; // list of Country objects
+ private Map country_map = null; // mapping from codes to Country objects
+ private List language_list = null; // list of Language objects
+ private Map language_map = null; // mapping from codes to Language objects
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a new instance of the International object. Only one instance
+ * of this object is ever created.
+ */
+ private International()
+ { // do nothing
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Loads the internal list of countries from a resource file.
+ *
+ * @exception RuntimeException If an I/O error occurred while loading the country list.
+ */
+ private synchronized void loadCountryList()
+ {
+ if ((country_list!=null) || (country_map!=null))
+ return; // already loaded
+
+ // Create temporary list and map to hold read data.
+ ArrayList tmp_list = new ArrayList();
+ HashMap tmp_map = new HashMap();
+
+ try
+ { // Load the country properties file.
+ BufferedReader data =
+ new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("countries.properties")));
+ String l; // temporary line
+ while ((l = data.readLine())!=null)
+ { // read lines from the properties file
+ l = l.trim();
+ if ((l.length()==0) || (l.startsWith("#")))
+ continue; // blank line or comment line
+ int pos = l.indexOf('=');
+ if (pos<0)
+ continue; // no properties - just forget this line
+ Country c = new Country(l.substring(0,pos),l.substring(pos+1));
+ tmp_list.add(c);
+ tmp_map.put(c.getCode(),c);
+
+ } // end while
+
+ } // end try
+ catch (IOException e)
+ { // IO error loading country properties...
+ throw new RuntimeException("Error loading country.properties: " + e.getMessage());
+
+ } // end catch
+
+ // Set up the lists, which are considered "unmodifiable."
+ tmp_list.trimToSize();
+ country_list = Collections.unmodifiableList(tmp_list);
+ country_map = Collections.unmodifiableMap(tmp_map);
+
+ } // end loadCountryList
+
+ /**
+ * Loads the internal list of languages from a resource file.
+ *
+ * @exception RuntimeException If an I/O error occurred while loading the language list.
+ */
+ private synchronized void loadLanguageList()
+ {
+ if ((language_list!=null) || (language_map!=null))
+ return; // already loaded
+
+ // Create temporary list and map to hold read data.
+ ArrayList tmp_list = new ArrayList();
+ HashMap tmp_map = new HashMap();
+
+ try
+ { // Load the language properties file.
+ BufferedReader data =
+ new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("languages.properties")));
+ String l; // temporary line
+ while ((l = data.readLine())!=null)
+ { // read lines from the properties file
+ l = l.trim();
+ if ((l.length()==0) || (l.startsWith("#")))
+ continue; // blank line or comment line
+ int pos = l.indexOf('=');
+ if (pos<0)
+ continue; // no properties - just forget this line
+ Language lng = new Language(l.substring(0,pos),l.substring(pos+1));
+ tmp_list.add(lng);
+ tmp_map.put(lng.getCode(),lng);
+
+ } // end while
+
+ } // end try
+ catch (IOException e)
+ { // IO error loading language properties...
+ throw new RuntimeException("Error loading language.properties: " + e.getMessage());
+
+ } // end catch
+
+ // Set up the lists, which are considered "unmodifiable."
+ tmp_list.trimToSize();
+ language_list = Collections.unmodifiableList(tmp_list);
+ language_map = Collections.unmodifiableMap(tmp_map);
+
+ } // end loadLanguageList
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Returns the list of defined countries.
+ *
+ * @return The list of Country objects that are currently defined.
+ */
+ public List getCountryList()
+ {
+ loadCountryList();
+ return country_list;
+
+ } // end getCountryList
+
+ /**
+ * Returns the Country object with the specified code.
+ *
+ * @param code The country code to match.
+ * @return The matching Country object, or null if no country matched.
+ */
+ public Country getCountryForCode(String code)
+ {
+ if (code==null)
+ return null;
+ loadCountryList();
+ return (Country)(country_map.get(code.trim().toUpperCase()));
+
+ } // end getCountryForCode
+
+ /**
+ * Returns the list of defined languages.
+ *
+ * @return The list of Language objects that are currently defined.
+ */
+ public List getLanguageList()
+ {
+ loadLanguageList();
+ return language_list;
+
+ } // end getLanguageList
+
+ /**
+ * Returns the Language object with the specified code.
+ *
+ * @param code The language code to match.
+ * @return The matching Language object, or null if no language matched.
+ */
+ public Language getLanguageForCode(String code)
+ {
+ if (code==null)
+ return null;
+ loadLanguageList();
+ return (Language)(language_map.get(code.trim()));
+
+ } // end getLanguageForCode
+
+ /**
+ * Creates a Locale from a standard descriptor string.
+ *
+ * @param streq The string equivalent of the Locale to be created.
+ * @return The corresponding Locale, or the default Locale if the parameter is
+ * null or the empty string.
+ */
+ public Locale createLocale(String streq)
+ {
+ if ((streq==null) || (streq.length()==0))
+ return Locale.getDefault(); // no locale
+ int p1 = streq.indexOf('_');
+ if (p1<0)
+ return new Locale(streq,""); // language but no country specified
+ String x_lang = streq.substring(0,p1);
+ int p2 = streq.indexOf('_',p1+1);
+ if (p2<0)
+ { // there's only one underscore - figure out what part the last part is
+ String lastpart = streq.substring(p1+1);
+ if (lastpart.length()==2)
+ return new Locale(x_lang,lastpart); // language + country
+ else
+ return new Locale(x_lang,"",lastpart); // language + country(null) + variant
+
+ } // end if
+
+ // do all three variants
+ return new Locale(x_lang,streq.substring(p1+1,p2),streq.substring(p2+1));
+
+ } // end createLocale
+
+ /*--------------------------------------------------------------------------------
+ * External static operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Returns the singleton instance of the International object.
+ *
+ * @return The singleton instance of the International object.
+ */
+ public static International get()
+ {
+ return self;
+
+ } // end get()
+
+} // end class International
diff --git a/src/baseutil/com/silverwrist/util/Language.java b/src/baseutil/com/silverwrist/util/Language.java
new file mode 100644
index 0000000..fa9fb53
--- /dev/null
+++ b/src/baseutil/com/silverwrist/util/Language.java
@@ -0,0 +1,159 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2001-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.util;
+
+/**
+ * A utility class used by International that stores a language code and name pair.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ * @see International
+ */
+public final class Language implements Comparable
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private String m_code; // the language code
+ private String m_name; // the language name
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a new Language object.
+ *
+ * @param code The language code.
+ * @param name The language name.
+ */
+ Language(String code, String name)
+ {
+ m_code = code.trim();
+ m_name = name.trim();
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class Object
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Indicates whether some other object is "equal to" this one.
+ *
+ * @param o The reference object with which to compare.
+ * @return true if this object is the same as the o argument; false otherwise.
+ */
+ public boolean equals(Object o)
+ {
+ if ((o==null) || !(o instanceof Language))
+ return false;
+ if (this==(Language)o)
+ return true;
+ Language other = (Language)o;
+ return m_code.equals(other.m_code);
+
+ } // end equals
+
+ /**
+ * Returns a hash code value for the object. This method is supported for the benefit of hashtables such as those
+ * provided by java.util.Hashtable.
+ *
+ * @return A hash code value for this object.
+ */
+ public int hashCode()
+ {
+ return m_code.hashCode();
+
+ } // end hashCode
+
+ /**
+ * Returns a string representation of the object. In general, the toString method returns a string
+ * that "textually represents" this object.
+ *
+ * @return A string representation of the object.
+ */
+ public String toString()
+ {
+ return m_name + " [" + m_code + "]";
+
+ } // end toString
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface Comparable
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Compares this object with the specified object for order. Returns a negative integer, zero, or a positive
+ * integer as this object is less than, equal to, or greater than the specified object. Language
+ * objects are compared on their language name.
+ *
+ * @param o The Object to be compared.
+ * @return A negative integer, zero, or a positive integer as this object is less than, equal to, or greater than
+ * the specified object.
+ * @exception java.lang.ClassCastException If the specified object's type prevents it from being compared to
+ * this Object.
+ */
+ public int compareTo(Object o)
+ {
+ if (o==null)
+ return 1;
+ if (o instanceof Language)
+ { // compare country names
+ Language c = (Language)o;
+ return m_name.compareTo(c.m_name);
+
+ } // end if
+
+ return m_name.compareTo(o.toString());
+
+ } // end compareTo
+
+ /*--------------------------------------------------------------------------------
+ * External getters
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Returns the RFC 1766 language code for this language.
+ *
+ * @return The RFC 1766 language code for this language.
+ */
+ public final String getCode()
+ {
+ return m_code;
+
+ } // end code
+
+ /**
+ * Returns the name of this language.
+ *
+ * @return The name of this language.
+ */
+ public final String getName()
+ {
+ return m_name;
+
+ } // end name
+
+} // end class Language
diff --git a/src/baseutil/com/silverwrist/util/MySQLUtils.java b/src/baseutil/com/silverwrist/util/MySQLUtils.java
new file mode 100644
index 0000000..3838530
--- /dev/null
+++ b/src/baseutil/com/silverwrist/util/MySQLUtils.java
@@ -0,0 +1,120 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.util;
+
+import java.sql.*;
+import org.apache.log4j.Logger;
+
+/**
+ * A class containing miscellaneous public methods useful when working with MySQL databases. All
+ * public methods of {@link com.silverwrist.util.SQLUtils SQLUtils} are also accessible through this class.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public class MySQLUtils extends SQLUtils
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static Logger logger = Logger.getLogger(MySQLUtils.class);
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * MySQLUtils instances should NOT be constructed in standard programming.
+ * Instead, the class should be used as MySQLUtils.shutdown(statement);.
+ * This constructor is public to permit tools that require a JavaBean instance
+ * to operate.
+ */
+ public MySQLUtils()
+ {
+ super();
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Unlocks all database tables that were previously locked. Executes the MySQL statement "UNLOCK TABLES;".
+ *
+ * @param conn The connection on which one or more tables were previously locked.
+ */
+ public static final void unlockTables(Connection conn)
+ {
+ Statement stmt = null;
+ try
+ { // do the update
+ stmt = conn.createStatement();
+ stmt.executeUpdate("UNLOCK TABLES;");
+
+ } // end try
+ catch (SQLException e)
+ { // warn if there was an error here
+ logger.warn("DB error in unlockTables()",e);
+
+ } // end catch
+ finally
+ { // shutdown the statement before we go
+ shutdown(stmt);
+
+ } // end finally
+
+ } // end unlockTables
+
+ /**
+ * Gets the ID of the most recent insert made to a table with an AUTO_INCREMENT column. This assumes that the
+ * column is of integer type. Executes the MySQL statement "SELECT LAST_INSERT_ID();" and returns the value
+ * that that statement returns.
+ *
+ * @param conn Database connection on which to perform the operation.
+ * @return The value of the last inserted ID on this connection.
+ * @exception java.sql.SQLException If an error occurred in the execution, or if the SELECT statement returned
+ * no rows (which it should not do).
+ */
+ public static final int getLastInsertInt(Connection conn) throws SQLException
+ {
+ Statement stmt = null;
+ ResultSet rs = null;
+ try
+ { // perform the operation
+ stmt = conn.createStatement();
+ rs = stmt.executeQuery("SELECT LAST_INSERT_ID();");
+ if (!(rs.next()))
+ throw new SQLException("internal error - getLastInsertInt SELECT should have returned OK");
+ return rs.getInt(1);
+
+ } // end try
+ finally
+ { // shut down the objects before we go
+ shutdown(rs);
+ shutdown(stmt);
+
+ } // end finally
+
+ } // end getLastInsertInt
+
+} // end class MySQLUtils
diff --git a/src/baseutil/com/silverwrist/util/OptionSet.java b/src/baseutil/com/silverwrist/util/OptionSet.java
new file mode 100644
index 0000000..2ff9564
--- /dev/null
+++ b/src/baseutil/com/silverwrist/util/OptionSet.java
@@ -0,0 +1,424 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2001-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.util;
+
+import java.util.BitSet;
+
+/**
+ * A variant of the BitSet that can express itself as a character string. Each
+ * character in the resulting string represents a flag that is "set." Up to 91 flags can be
+ * specified per OptionSet.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ * @see java.util.BitSet
+ */
+public class OptionSet extends BitSet
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ // The alphabet to use to store individual flags.
+ private static final String ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+ + "!#$%&()*+,-./:;<=>?@[]^_`{|}~";
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a new OptionSet. All bits are initially false.
+ */
+ public OptionSet()
+ {
+ super();
+
+ } // end constructor
+
+ /**
+ * Creates an OptionSet whose initial size is large enough to explicitly represent bits with
+ * indices in the range 0 through nbits-1. All bits are initially false. The maximum
+ * size of the OptionSet is 91.
+ *
+ * @param nbits The initial size of the bit set.
+ * @exception java.lang.NegativeArraySizeException If the specified initial size is negative.
+ */
+ public OptionSet(int nbits)
+ {
+ super(Math.min(nbits,ALPHA.length()));
+
+ } // end constructor
+
+ /**
+ * Creates an OptionSet from an array of characters representing "set" options.
+ *
+ * @param options The options to be set in the new OptionSet.
+ */
+ public OptionSet(char[] options)
+ {
+ super(); // initialize all bits to 0
+ for (int i=0; i=0)
+ super.set(ndx);
+
+ } // end for
+
+ } // end constructor
+
+ /**
+ * Creates an OptionSet from a string of characters representing "set" options.
+ *
+ * @param options The options to be set in the new OptionSet.
+ */
+ public OptionSet(String options)
+ {
+ this(options.toCharArray());
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Internal functions
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Returns a StringBuffer representing the current state of this OptionSet,
+ * with one character in it for each bit that is set.
+ *
+ * @return A StringBuffer containing the current state of the OptionSet.
+ */
+ private StringBuffer asStringBuffer()
+ {
+ StringBuffer b = new StringBuffer();
+ for (int i=0; ifalse.
+ *
+ * @param bitIndex The index of the bit to be cleared.
+ * @exception java.lang.IndexOutOfBoundsException If the specified index is negative or greater than the
+ * maximum option for an OptionSet.
+ */
+ public void clear(int bitIndex)
+ {
+ if (bitIndex>=ALPHA.length())
+ throw new IndexOutOfBoundsException();
+ super.clear(bitIndex);
+
+ } // end clear
+
+ /**
+ * Sets the bits from the specified fromIndex (inclusive) to the specified toIndex
+ * (exclusive) to false.
+ *
+ * @param fromIndex Index of the first bit to be cleared.
+ * @param toIndex Index after the last bit to be cleared.
+ * @exception java.lang.IndexOutOfBoundException If fromIndex is negative, or fromIndex
+ * is greater than the maximum option for an OptionSet, or toIndex is negative,
+ * or toIndex is greater than the maximum option for an OptionSet, or
+ * fromIndex is larger than toIndex.
+ */
+ public void clear(int fromIndex, int toIndex)
+ {
+ if ((fromIndex>=ALPHA.length()) || (toIndex>ALPHA.length()))
+ throw new IndexOutOfBoundsException();
+ super.clear(fromIndex,toIndex);
+
+ } // end clear
+
+ /**
+ * Cloning this OptionSet produces a new OptionSet that is equal to it. The clone of the
+ * option set is another option set that has exactly the same bits set to true as this option set and the same
+ * current size.
+ *
+ * @return A clone of this option set.
+ */
+ public Object clone()
+ {
+ OptionSet rc = new OptionSet(this.size());
+ for (int i=this.nextSetBit(0); i>=0; i=this.nextSetBit(i+1))
+ rc.set(i);
+ return rc;
+
+ } // end clone
+
+ /**
+ * Sets the bit at the specified index to to the complement of its current value.
+ *
+ * @param bitIndex The index of the bit to flip.
+ * @exception java.lang.IndexOutOfBoundsException If the specified index is negative or greater than the
+ * maximum option for an OptionSet.
+ */
+ public void flip(int bitIndex)
+ {
+ if (bitIndex>=ALPHA.length())
+ throw new IndexOutOfBoundsException();
+ super.flip(bitIndex);
+
+ } // end flip
+
+ /**
+ * Sets the bits from the specified fromIndex (inclusive) to the specified toIndex
+ * (exclusive) to the complement of their current values.
+ *
+ * @param fromIndex Index of the first bit to be flipped.
+ * @param toIndex Index after the last bit to be flipped.
+ * @exception java.lang.IndexOutOfBoundException If fromIndex is negative, or fromIndex
+ * is greater than the maximum option for an OptionSet, or toIndex is negative,
+ * or toIndex is greater than the maximum option for an OptionSet, or
+ * fromIndex is larger than toIndex.
+ */
+ public void flip(int fromIndex, int toIndex)
+ {
+ if ((fromIndex>=ALPHA.length()) || (toIndex>ALPHA.length()))
+ throw new IndexOutOfBoundsException();
+ super.flip(fromIndex,toIndex);
+
+ } // end flip
+
+ /**
+ * Returns the value of the bit with the specified index. The value is true if the bit with
+ * the index bitIndex is currently set in this OptionSet; otherwise, the result
+ * is false.
+ *
+ * @param bitIndex The bit index.
+ * @return The value of the bit with the specified index.
+ * @exception java.lang.IndexOutOfBoundsException If the specified index is negative or greater than the
+ * maximum option for an OptionSet.
+ */
+ public boolean get(int bitIndex)
+ {
+ if (bitIndex>=ALPHA.length())
+ throw new IndexOutOfBoundsException();
+ return super.get(bitIndex);
+
+ } // end get
+
+ /**
+ * Returns a new OptionSet composed of bits from this OptionSet from
+ * fromIndex (inclusive) to toIndex (exclusive).
+ *
+ * @param fromIndex Index of the first bit to be included.
+ * @param toIndex Index after the last bit to be included.
+ * @return A new OptionSet from a range of this OptionSet.
+ * @exception java.lang.IndexOutOfBoundException If fromIndex is negative, or fromIndex
+ * is greater than the maximum option for an OptionSet, or toIndex is negative,
+ * or toIndex is greater than the maximum option for an OptionSet, or
+ * fromIndex is larger than toIndex.
+ */
+ public BitSet get(int fromIndex, int toIndex)
+ {
+ if ((fromIndex>=ALPHA.length()) || (toIndex>ALPHA.length()))
+ throw new IndexOutOfBoundsException();
+ BitSet tmp = super.get(fromIndex,toIndex);
+ OptionSet rc = new OptionSet(tmp.size());
+ for (int i=tmp.nextSetBit(0); i>=0; i=tmp.nextSetBit(i+1))
+ rc.set(i);
+ return rc;
+
+ } // end get
+
+ /**
+ * Sets the bit specified by the index to true.
+ *
+ * @param bitIndex The index of the bit to be set.
+ * @exception java.lang.IndexOutOfBoundsException If the specified index is negative or greater than the
+ * maximum option for an OptionSet.
+ */
+ public void set(int bitIndex)
+ {
+ if (bitIndex>=ALPHA.length())
+ throw new IndexOutOfBoundsException();
+ super.set(bitIndex);
+
+ } // end set
+
+ /**
+ * Sets the bit specified by the index to the specified value.
+ *
+ * @param bitIndex The index of the bit to be set.
+ * @param value A boolean value to set.
+ * @exception java.lang.IndexOutOfBoundsException If the specified index is negative or greater than the
+ * maximum option for an OptionSet.
+ */
+ public void set(int bitIndex, boolean value)
+ {
+ if (bitIndex>=ALPHA.length())
+ throw new IndexOutOfBoundsException();
+ super.set(bitIndex,value);
+
+ } // end set
+
+ /**
+ * Sets the bits from the specified fromIndex (inclusive) to the specified toIndex
+ * (exclusive) to true.
+ *
+ * @param fromIndex Index of the first bit to be set.
+ * @param toIndex Index after the last bit to be set.
+ * @exception java.lang.IndexOutOfBoundException If fromIndex is negative, or fromIndex
+ * is greater than the maximum option for an OptionSet, or toIndex is negative,
+ * or toIndex is greater than the maximum option for an OptionSet, or
+ * fromIndex is larger than toIndex.
+ */
+ public void set(int fromIndex, int toIndex)
+ {
+ if ((fromIndex>=ALPHA.length()) || (toIndex>ALPHA.length()))
+ throw new IndexOutOfBoundsException();
+ super.set(fromIndex,toIndex);
+
+ } // end set
+
+ /**
+ * Sets the bits from the specified fromIndex (inclusive) to the specified toIndex
+ * (exclusive) to the specified value.
+ *
+ * @param fromIndex Index of the first bit to be set.
+ * @param toIndex Index after the last bit to be set.
+ * @param value A boolean value to set.
+ * @exception java.lang.IndexOutOfBoundException If fromIndex is negative, or fromIndex
+ * is greater than the maximum option for an OptionSet, or toIndex is negative,
+ * or toIndex is greater than the maximum option for an OptionSet, or
+ * fromIndex is larger than toIndex.
+ */
+ public void set(int fromIndex, int toIndex, boolean value)
+ {
+ if ((fromIndex>=ALPHA.length()) || (toIndex>ALPHA.length()))
+ throw new IndexOutOfBoundsException();
+ super.set(fromIndex,toIndex,value);
+
+ } // end set
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Sets the value of the specified bit in the OptionSet to a specified Boolean
+ * value, and returns an indication of whether that value was changed.
+ *
+ * @param ndx The index of the bit to be assigned.
+ * @param val true to set the corresponding bit, false to clear it.
+ * @return true if the value of the bit in the OptionSet was changed by this
+ * operation, false if not.
+ * @exception java.lang.IndexOutOfBoundsException If the specified index is negative or greater than the
+ * maximum option for an OptionSet.
+ */
+ public boolean assign(int ndx, boolean val)
+ {
+ if (ndx>=ALPHA.length())
+ throw new IndexOutOfBoundsException();
+ boolean old = super.get(ndx);
+ super.set(ndx,val);
+ return (old!=val);
+
+ } // end assign
+
+ /**
+ * Resets the state of this OptionSet from an array of characters representing "set" options.
+ *
+ * @param options The options to be set in the new OptionSet. All options not specified will
+ * be cleared.
+ */
+ public void assign(char[] options)
+ {
+ super.clear();
+
+ for (int i=0; i=0)
+ super.set(ndx);
+
+ } // end for
+
+ } // end assign
+
+ /**
+ * Resets the state of this OptionSet from a string of characters representing "set" options.
+ *
+ * @param options The options to be set in the new OptionSet. All options not specified will
+ * be cleared.
+ */
+ public void assign(String options)
+ {
+ if (options!=null)
+ assign(options.toCharArray());
+
+ } // end assign
+
+ /**
+ * Returns a character array representing the current state of this OptionSet,
+ * with one character in it for each bit that is set.
+ *
+ * @return A character array containing the current state of the OptionSet.
+ */
+ public char[] asCharArray()
+ {
+ return asStringBuffer().toString().toCharArray();
+
+ } // end asCharArray
+
+ /**
+ * Returns a string representing the current state of this OptionSet,
+ * with one character in it for each bit that is set.
+ *
+ * @return A string containing the current state of the OptionSet.
+ */
+ public String asString()
+ {
+ return asStringBuffer().toString();
+
+ } // end asString
+
+ /*--------------------------------------------------------------------------------
+ * External static operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Returns the character associated with a specific "option index" by all OptionSet instances.
+ *
+ * @param index The index of the character to retrieve.
+ * @return The character associated with that index.
+ * @exception java.lang.IndexOutOfBoundsException If the specified index is out of range.
+ */
+ public static final char getOptionChar(int index)
+ {
+ if ((index<0) || (index>=ALPHA.length()))
+ throw new IndexOutOfBoundsException();
+ return ALPHA.charAt(index);
+
+ } // end getOptionChar
+
+} // end class OptionSet
diff --git a/src/baseutil/com/silverwrist/util/SQLUtils.java b/src/baseutil/com/silverwrist/util/SQLUtils.java
new file mode 100644
index 0000000..95f949f
--- /dev/null
+++ b/src/baseutil/com/silverwrist/util/SQLUtils.java
@@ -0,0 +1,127 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.util;
+
+import java.sql.*;
+
+/**
+ * A class containing miscellaneous public methods useful when working with SQL databases.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public class SQLUtils
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * SQLUtils instances should NOT be constructed in standard programming.
+ * Instead, the class should be used as SQLUtils.shutdown(statement);.
+ * This constructor is public to permit tools that require a JavaBean instance
+ * to operate.
+ */
+ public SQLUtils()
+ { // do nothing
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Closes a ResultSet cleanly, without throwing an exception.
+ *
+ * @param rs The ResultSet to be closed.
+ * @see java.sql.ResultSet#close()
+ */
+ public static final void shutdown(ResultSet rs)
+ {
+ try
+ { // close the ResultSet
+ if (rs!=null)
+ rs.close();
+
+ } // end try
+ catch (SQLException e)
+ { // ignore any SQL errors
+ } // end catch
+
+ } // end shutdown
+
+ /**
+ * Closes a Statement cleanly, without throwing an exception.
+ *
+ * @param rs The Statement to be closed.
+ * @see java.sql.Statement#close()
+ */
+ public static final void shutdown(Statement stmt)
+ {
+ try
+ { // close the Statement
+ if (stmt!=null)
+ stmt.close();
+
+ } // end try
+ catch (SQLException e)
+ { // ignore any SQL errors
+ } // end catch
+
+ } // end shutdown
+
+ /**
+ * Closes a Connection cleanly, without throwing an exception.
+ *
+ * @param rs The Connection to be closed.
+ * @see java.sql.Connection#close()
+ */
+ public static final void shutdown(Connection conn)
+ {
+ try
+ { // close the Connection
+ if (conn!=null)
+ conn.close();
+
+ } // end try
+ catch (SQLException e)
+ { // ignore any SQL errors
+ } // end catch
+
+ } // end shutdown
+
+ /**
+ * Fetches the return count from a query such as "SELECT COUNT(*) FROM ...". All such queries will always
+ * return at least one row, with the count.
+ *
+ * @param rs The ResultSet returned from the query execution.
+ * @param column The column index in which the return value may be found.
+ * @return The value of that column (usually, the count you were querying for).
+ * @exception java.sql.SQLException If there was no returned row, or there was a data type mismatch on the column.
+ */
+ public static final int getReturnCountInt(ResultSet rs, int column) throws SQLException
+ {
+ if (!(rs.next()))
+ throw new SQLException("expected return count row, not present");
+ return rs.getInt(column);
+
+ } // end getReturnCountInt
+
+} // end class SQLUtils
diff --git a/src/baseutil/com/silverwrist/util/StringUtils.java b/src/baseutil/com/silverwrist/util/StringUtils.java
new file mode 100644
index 0000000..a5da575
--- /dev/null
+++ b/src/baseutil/com/silverwrist/util/StringUtils.java
@@ -0,0 +1,349 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.util;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.*;
+import org.apache.log4j.Logger;
+
+/**
+ * Common string utilities. Inherits from the org.apache.commons.lang.StringUtils
+ * class, so it contains everything that contains.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public class StringUtils extends org.apache.commons.lang.StringUtils
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static Logger logger = Logger.getLogger(StringUtils.class);
+
+ private static final char[] HTML_ENCODE_CHARS = { '"', '&', '<', '>' };
+
+ private static final String VAR_START = "${";
+ private static final String VAR_END = "}";
+
+ private static final Set TRUE_STRINGS;
+ private static final Set FALSE_STRINGS;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * StringUtils instances should NOT be constructed in standard programming.
+ * Instead, the class should be used as StringUtils.trim(" foo ");.
+ * This constructor is public to permit tools that require a JavaBean instance
+ * to operate.
+ */
+ public StringUtils()
+ {
+ super();
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Performs HTML encoding of an arbitrary string. When a string is HTML encoded, the double-quote ("),
+ * ampersand (&), less-than (<), and greater-than (>) characters are transformed to their HTML
+ * entity equivalents; all other characters are left untouched.
+ *
+ * @param str The string to be HTML-encoded. May be null.
+ * @return The HTML-encoded equivalent of str. If str is
+ * null, returns null.
+ */
+ public static final String encodeHTML(String str)
+ {
+ if (str==null)
+ return null; // safety feature
+ AnyCharMatcher nhc = new AnyCharMatcher(HTML_ENCODE_CHARS);
+ int ndx = nhc.get(str);
+ if (ndx<0)
+ return str; // trivial short-circuit case
+ StringBuffer buf = new StringBuffer();
+ while (ndx>=0)
+ { // append the matched "head" and then the encoded character
+ if (ndx>0)
+ buf.append(str.substring(0,ndx));
+ switch (str.charAt(ndx++))
+ {
+ case '"':
+ buf.append(""");
+ break;
+
+ case '&':
+ buf.append("&");
+ break;
+
+ case '<':
+ buf.append("<");
+ break;
+
+ case '>':
+ buf.append(">");
+ break;
+
+ } // end switch
+
+ if (ndx==str.length())
+ return buf.toString(); // munched the entire string - all done!
+ str = str.substring(ndx);
+ ndx = nhc.get(str);
+
+ } // end while
+
+ buf.append(str); // append the unmatched tail
+ return buf.toString();
+
+ } // end encodeHTML
+
+ /**
+ * Translates a string into application/x-www-form-urlencoded format, using a UTF-8 encoding.
+ *
+ * @param s The string to be encoded. May be null.
+ * @return The translated string value, or null if null was passed in.
+ */
+ public static final String encodeURL(String s)
+ {
+ try
+ { // the old URLEncoder.encode(str) method is deprecated as of JDK1.4, use the new one
+ return ((s==null) ? null : URLEncoder.encode(s,"UTF-8"));
+
+ } // end try
+ catch (UnsupportedEncodingException e)
+ { // this should never happen, but we gotta catch it anyway
+ logger.fatal("WTF? encodeURL doesn't support UTF-8? You're crazy!");
+ return null;
+
+ } // end catch
+
+ } // end encodeURL
+
+ /**
+ * Returns true if the given string is a representation of a Boolean true value.
+ * Values that represent a valid Boolean true value include "true", "yes", "on", and "1".
+ *
+ * @param test The string to be tested.
+ * @return true if the string represents a Boolean true value, false if not.
+ */
+ public static final boolean isBooleanTrue(String test)
+ {
+ if (test==null)
+ return false;
+ return TRUE_STRINGS.contains(test.trim().toLowerCase());
+
+ } // end isBooleanTrue
+
+ /**
+ * Returns true if the given string is a representation of a Boolean false value.
+ * Values that represent a valid Boolean false value include "false", "no", "off", and "0".
+ *
+ * @param test The string to be tested.
+ * @return true if the string represents a Boolean false value, false if not.
+ */
+ public static final boolean isBooleanFalse(String test)
+ {
+ if (test==null)
+ return false;
+ return FALSE_STRINGS.contains(test.trim().toLowerCase());
+
+ } // end isBooleanTrue
+
+ /**
+ * Replaces variable substitutions in a string. Variable substitutions are strings of the form
+ * ${varname}. The varname names are looked up in the supplied
+ * Map, and the values of variables in that map are substituted.
+ * Only variable names that exist in the Map are replaced; other variable strings
+ * in the supplied string are left untouched. Variable substitution values may themselves contain
+ * variables; those variables are recursively replaced. (Caution: The code cannot
+ * detect variable substitutions that contain themselves, or two variables that contain each other.
+ * Avoid these situations.)
+ *
+ * @param base The string to be operated on. If this parameter is null, the
+ * method will return null.
+ * @param vars The mapping of variable name to value substitutions. If this parameter is
+ * null or an empty map, no substitutions will be performed on
+ * base.
+ * @return The base string with all variable substitutions made as detailed above.
+ */
+ public static final String replaceAllVariables(String base, Map vars)
+ {
+ if ((base==null) || (vars==null) || vars.isEmpty())
+ return base; // safety feature
+
+ String work = base;
+ boolean did_replace = false;
+ boolean retest = true;
+ do
+ { // main loop for replacing all variables
+ did_replace = false;
+ Iterator it = vars.keySet().iterator();
+ while (it.hasNext())
+ { // variable start is there...
+ if (retest)
+ { // only perform this test on the first iteration and after we know we've replaced a variable
+ if (work.indexOf(VAR_START)<0)
+ return work; // no more variables in text - all done!
+ retest = false;
+
+ } // end if
+
+ // get variable name and see if it's present
+ String vname = it.next().toString();
+ String var_full = VAR_START + vname + VAR_END;
+ if (work.indexOf(var_full)>=0)
+ { // OK, this variable is in place
+ work = replace(work,var_full,vars.get(vname).toString());
+ did_replace = true;
+ retest = true;
+
+ } // end if
+
+ } // end while
+
+ } while (did_replace); // end do
+
+ return work; // all done!
+
+ } // end replaceAllVariables
+
+ /**
+ * Splits the provided text into a list, based on a given separator. The separator is not included in the
+ * returned String list. The maximum number of splits to perfom can be controlled.
+ *
+ * @param text The string to parse.
+ * @param separator Character used as the delimiter.
+ * @param limit The maximum number of elements to include in the list. A zero or negative value implies no limit.
+ * @return A list of parsed Strings.
+ */
+ public static final List split1List(String text, char separator, int limit)
+ {
+ if (text==null)
+ return Collections.EMPTY_LIST;
+ if (limit<=0)
+ limit = Integer.MAX_VALUE;
+ ArrayList rc = new ArrayList();
+ String work = text;
+ int p = work.indexOf(separator);
+ while ((work.length()>0) && (p>=0) && (--limit>0))
+ { // add elements to the ArrayList
+ if (p==0)
+ rc.add("");
+ else
+ rc.add(work.substring(0,p));
+ work = work.substring(p+1);
+ p = work.indexOf(separator);
+
+ } // end while
+
+ rc.add(work);
+ rc.trimToSize();
+ return rc;
+
+ } // end split1list
+
+ /**
+ * Splits the provided text into a list, based on a given separator. The separator is not included in the
+ * returned String list.
+ *
+ * @param text The string to parse.
+ * @param separator Character used as the delimiter.
+ * @return A list of parsed Strings.
+ */
+ public static final List split1List(String text, char separator)
+ {
+ return split1List(text,separator,0);
+
+ } // end split1list
+
+ /**
+ * Splits the provided text into a list, based on a given separator. The separator is not included in the
+ * returned String array. The maximum number of splits to perfom can be controlled.
+ *
+ * @param text The string to parse.
+ * @param separator Character used as the delimiter.
+ * @param limit The maximum number of elements to include in the list. A zero or negative value implies no limit.
+ * @return An array of parsed Strings.
+ */
+ public static final String[] split1(String text, char separator, int limit)
+ {
+ List tmp = split1List(text,separator,limit);
+ String[] rc = new String[tmp.size()];
+ tmp.toArray(rc);
+ return rc;
+
+ } // end split1
+
+ /**
+ * Splits the provided text into a list, based on a given separator. The separator is not included in the
+ * returned String array.
+ *
+ * @param text The string to parse.
+ * @param separator Character used as the delimiter.
+ * @return An array of parsed Strings.
+ */
+ public static final String[] split1(String text, char separator)
+ {
+ return split1(text,separator,0);
+
+ } // end split1
+
+ /*--------------------------------------------------------------------------------
+ * Static initializer
+ *--------------------------------------------------------------------------------
+ */
+
+ static
+ { // get the boolean values resource
+ ResourceBundle bv = ResourceBundle.getBundle("com.silverwrist.util.BooleanValues");
+
+ // Load the Boolean "true" values.
+ String[] values = split(bv.getString("values.true"),"|");
+ HashSet tmp = new HashSet();
+ for (int i=0; i.
+#
+# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+# WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+# language governing rights and limitations under the License.
+#
+# The Original Code is the Venice Web Communities System.
+#
+# The Initial Developer of the Original Code is Eric J. Bowersox ,
+# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+# Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+#
+# Contributor(s):
+# -------------------------------------------------------------------------------------
+# This list of countries is taken from the ISO 3166 standard list of country names and
+# 2-letter codes . When adding new
+# entries to this file, make sure and add it in sorted order by country NAME! You can
+# re-sort the country entries with "sort -t = -k 2 input > output", but then make sure
+# the "XX=(unknown)" entry appears first!
+XX=(unknown)
+AF=Afghanistan
+AL=Albania
+DZ=Algeria
+AS=American Samoa
+AD=Andorra
+AO=Angola
+AI=Anguilla
+AQ=Antarctica
+AG=Antigua and Barbuda
+AR=Argentina
+AM=Armenia
+AW=Aruba
+AU=Australia
+AT=Austria
+AZ=Azerbaijan
+BS=Bahamas
+BH=Bahrain
+BD=Bangladesh
+BB=Barbados
+BY=Belarus
+BE=Belgium
+BZ=Belize
+BJ=Benin
+BM=Bermuda
+BT=Bhutan
+BO=Bolivia
+BA=Bosnia and Herzegovina
+BW=Botswana
+BV=Bouvet Island
+BR=Brazil
+IO=British Indian Ocean Territory
+BN=Brunei Darussalam
+BG=Bulgaria
+BF=Burkina Faso
+BI=Burundi
+KH=Cambodia
+CM=Cameroon
+CA=Canada
+CV=Cape Verde
+KY=Cayman Islands
+CF=Central African Republic
+TD=Chad
+CL=Chile
+CN=China
+CX=Chrismas Island
+CC=Cocos (Keeling) Islands
+CO=Colombia
+KM=Comoros
+CG=Congo
+CD=Congo (Democratic Republic of)
+CK=Cook Islands
+CR=Costa Rica
+CI=Cote D''Ivoire
+HR=Croatia
+CU=Cuba
+CY=Cyprus
+CZ=Czech Republic
+DK=Denmark
+DJ=Djibouti
+DM=Dominica
+DO=Dominican Republic
+TP=East Timor
+EC=Ecuador
+EG=Egypt
+SV=El Salvador
+GQ=Equatorial Guinea
+ER=Eritrea
+EE=Estonia
+ET=Ethiopia
+FK=Falkland Islands (Malvinas)
+FO=Faroe Islands
+FJ=Fiji
+FI=Finland
+FR=France
+GF=French Guiana
+PF=French Polynesia
+TF=French Southern Territories
+GA=Gabon
+GM=Gambia
+GE=Georgia
+DE=Germany
+GH=Ghana
+GI=Gibraltar
+GR=Greece
+GL=Greenland
+GD=Grenada
+GP=Guadeloupe
+GU=Guam
+GT=Guatemala
+GN=Guinea
+GW=Guinea-Bissau
+GY=Guyana
+HT=Haiti
+HM=Heard Island and McDonald Islands
+VA=Holy See (Vatican City State)
+HN=Honduras
+HK=Hong Kong
+HU=Hungary
+IS=Iceland
+IN=India
+ID=Indonesia
+IR=Iran (Islamic Republic of)
+IQ=Iraq
+IE=Ireland
+IL=Israel
+IT=Italy
+JM=Jamaica
+JP=Japan
+JO=Jordan
+KZ=Kazakhstan
+KE=Kenya
+KI=Kiribati
+KP=Korea (Democratic People's Republic of)
+KR=Korea (Republic of)
+KW=Kuwait
+KG=Kyrgyzstan
+LA=Lao People's Democratic Republic
+LV=Latvia
+LB=Lebanon
+LS=Lesotho
+LR=Liberia
+LY=Libyan Arab Jamahirya
+LI=Liechtenstein
+LT=Lithuania
+LU=Luxembourg
+MO=Macau
+MK=Macedonia (Former Yugoslav Republic of)
+MG=Madagascar
+MW=Malawi
+MY=Malaysia
+MV=Maldives
+ML=Mali
+MT=Malta
+MH=Marshall Islands
+MQ=Martinique
+MR=Mauritania
+MU=Mauritius
+YT=Mayotte
+MX=Mexico
+FM=Micronesia (Federated States of)
+MD=Moldova, Republic of
+MC=Monaco
+MN=Mongolia
+MS=Montserrat
+MA=Morocco
+MZ=Mozambique
+MM=Myanmar
+NA=Namibia
+NR=Nauru
+NP=Nepal
+NL=Netherlands
+AN=Netherlands Antillies
+NC=New Caledonia
+NZ=New Zealand
+NI=Nicaragua
+NE=Niger
+NG=Nigeria
+NU=Niue
+NF=Norfolk Island
+MP=Northern Mariana Islands'),
+NO=Norway
+OM=Oman
+PK=Pakistan
+PW=Palau
+PS=Palestinian Territory, Occupied
+PA=Panama
+PG=Papua New Guinea
+PY=Paraguay
+PE=Peru
+PH=Phillipines
+PN=Pitcairn
+PL=Poland
+PT=Portugal
+PR=Puerto Rico
+QA=Qatar
+RE=Reunion
+RO=Romania
+RU=Russian Federation
+RW=Rwanda
+SH=Saint Helena
+KN=Saint Kitts and Nevis
+LC=Saint Lucia
+PM=Saint Pierre and Miquelon
+VC=Saint Vincent and The Grenadines
+WS=Samoa
+SM=San Marino
+ST=Sao Tome and Principe
+SA=Saudi Arabia
+SN=Senegal
+SC=Seychelles
+SL=Sierra Leone
+SG=Singapore
+SK=Slovakia
+SI=Slovenia
+SB=Solomon Islands
+SO=Somalia
+ZA=South Africa
+GS=South Georgia and the South Sandwich Islands
+ES=Spain
+LK=Sri Lanka
+SD=Sudan
+SR=Suriname
+SJ=Svalbard and Jan Mayen
+SZ=Swaziland
+SE=Sweden
+CH=Switzerland
+SY=Syrian Arab Republic
+TW=Taiwan (Province of China)
+TJ=Tajikistan
+TZ=Tanzania, United Republic of
+TH=Thailand
+TG=Togo
+TK=Tokelau
+TO=Tonga
+TT=Trinidad and Tobago
+TN=Tunisia
+TR=Turkey
+TM=Turkmenistan
+TC=Turks and Caicos Islands
+TV=Tuvalu
+UG=Uganda
+UA=Ukraine
+AE=United Arab Emirates
+GB=United Kingdom
+US=United States
+UM=United States Minor Outlying Islands
+UY=Uruguay
+UZ=Uzbekistan
+VU=Vanatu
+VE=Venezuela
+VN=Viet Nam
+VG=Virgin Islands (British)
+VI=Virgin Islands (U.S.)
+WF=Wallis and Futuna
+EH=Western Sahara
+YE=Yemen
+YU=Yugoslavia
+ZM=Zambia
+ZW=Zimbabwe
diff --git a/src/baseutil/com/silverwrist/util/image/ImageNormalizer.java b/src/baseutil/com/silverwrist/util/image/ImageNormalizer.java
new file mode 100644
index 0000000..bc72afd
--- /dev/null
+++ b/src/baseutil/com/silverwrist/util/image/ImageNormalizer.java
@@ -0,0 +1,272 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.util.image;
+
+import java.awt.RenderingHints;
+import java.awt.image.*;
+import java.awt.image.renderable.ParameterBlock;
+import java.io.*;
+import java.util.*;
+import javax.imageio.*;
+import javax.imageio.stream.*;
+import javax.media.jai.*;
+
+/**
+ * A class that performs "normalization" on an image to fit within a bounding box of a specified pixel
+ * size. "Normalized" images are scaled down proportionally to fit the bounding box, then centered over
+ * a black backdrop (so the image will be "letterboxed" if it has a larger H:V aspect ratio than the bounding
+ * box, or "pillarboxed" if it has a smaller H:V aspect ratio than the bounding box).
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public class ImageNormalizer
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * ImageNormalizer instances should NOT be constructed in standard programming.
+ * Instead, the class should be used as ImageNormalizer.normalizeImage(...);.
+ * This constructor is public to permit tools that require a JavaBean instance
+ * to operate.
+ */
+ public ImageNormalizer()
+ {
+ super();
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * "Normalizes" an image to fit within a bounding box of a specified pixel size. "Normalized" images are
+ * scaled down proportionally to fit the bounding box, then centered over a black backdrop (so the image
+ * will be "letterboxed" if it has a larger H:V aspect ratio than the bounding box, or "pillarboxed" if it
+ * has a smaller H:V aspect ratio than the bounding box).
+ *
+ * @param image_data Raw image data from the input, in any ImageIO-recognized format.
+ * @param width The width of the bounding box to use to normalize the image.
+ * @param height The height of the bounding box to use to normalize the image.
+ * @param output_type The desired MIME type for output (such as "image/jpeg").
+ * @return The normalized image data as a byte array.
+ * @exception com.silverwrist.util.image.ImageNormalizerException An error occurred in the image data or
+ * the image transformation process.
+ * @see ImageNormalizerException
+ */
+ public static byte[] normalizeImage(InputStream image_data, int width, int height, String output_type)
+ throws ImageNormalizerException
+ {
+ PlanarImage img1; // initial image
+ try
+ { // get an image input stream for the image
+ ImageInputStream iistm = ImageIO.createImageInputStream(image_data);
+
+ // create the "ImageRead" operation to load the image; it will autodetect the
+ // image format and create an appropriate ImageReader
+ ParameterBlock pb = new ParameterBlock();
+ pb.add(iistm);
+ pb.add(new Integer(0));
+ pb.add(Boolean.FALSE);
+ pb.add(Boolean.FALSE);
+ RenderedOp rop = JAI.create("ImageRead",pb);
+ img1 = rop.getRendering();
+
+ } // end try
+ catch (IOException e)
+ { // try to create the ImageInputStream
+ throw new ImageNormalizerException("Unable to load image",e);
+
+ } // end catch
+ catch (RuntimeException re)
+ { // unable to get the rendering here!
+ throw new ImageNormalizerException("Image data not a valid image format",re);
+
+ } // end catch
+
+ try
+ { // Compute the scaling factors required to get the image down to the appropriate size, then choose
+ // the smaller of the two to use as the final scaling factor. Note that we always scale DOWN,
+ // not UP.
+ Float scale_width = null, scale_height = null;
+ if (img1.getWidth()>width)
+ scale_width = new Float((float)width / (float)(img1.getWidth()));
+ if (img1.getHeight()>height)
+ scale_height = new Float((float)height / (float)(img1.getHeight()));
+ Float scale = null;
+ if (scale_width!=null)
+ { // we can scale by width, how about height?
+ if (scale_height!=null)
+ { // yes, height too...pick the smaller of the two
+ if (scale_width.floatValue()ImageNormalizer, which reads an image from one file,
+ * normalizes it, and writes it to a second file.
+ *
+ * @param args Command-line arguments. The first of these should be the name of the input file, and the
+ * second should be the name of the output file.
+ * @return (Exit code) 0 on success, 1 on error.
+ */
+ public static void main(String[] args)
+ {
+ if (args.length<2)
+ { // make sure we have 2 arguments
+ System.out.println("Usage: ImageNormalizer input-file output-file");
+ System.exit(1);
+
+ } // end if
+
+ try
+ { // very simple, very easy
+ FileInputStream instm = new FileInputStream(args[0]);
+ byte[] outdata = normalizeImage(instm,100,100,"image/jpeg");
+ instm.close();
+ FileOutputStream outstm = new FileOutputStream(args[1]);
+ outstm.write(outdata);
+ outstm.close();
+ System.out.println(args[0] + " => " + args[1]);
+
+ } // end try
+ catch (Exception e)
+ { // dump exception on error
+ e.printStackTrace();
+ System.exit(1);
+
+ } // end catch
+
+ System.exit(0);
+
+ } // end main
+
+} // end class ImageNormalizer
diff --git a/src/baseutil/com/silverwrist/util/image/ImageNormalizerException.java b/src/baseutil/com/silverwrist/util/image/ImageNormalizerException.java
new file mode 100644
index 0000000..3737256
--- /dev/null
+++ b/src/baseutil/com/silverwrist/util/image/ImageNormalizerException.java
@@ -0,0 +1,77 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.util.image;
+
+/**
+ * Indicates an error in the image normalization process.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ * @see com.silverwrist.util.image.ImageNormalizer#normalizeImage(java.io.InputStream,int,int,java.lang.String)
+ */
+public class ImageNormalizerException extends Exception
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a new ImageNormalizerException.
+ */
+ public ImageNormalizerException()
+ {
+ super();
+
+ } // end constructor
+
+ /**
+ * Constructs a new ImageNormalizerException.
+ *
+ * @param message Message for the exception.
+ */
+ public ImageNormalizerException(String message)
+ {
+ super(message);
+
+ } // end constructor
+
+ /**
+ * Constructs a new ImageNormalizerException.
+ *
+ * @param t The exception to be wrapped by this one.
+ */
+ public ImageNormalizerException(Throwable t)
+ {
+ super(t);
+
+ } // end constructor
+
+ /**
+ * Constructs a new ImageNormalizerException.
+ *
+ * @param message Message for the exception.
+ * @param t The exception to be wrapped by this one.
+ */
+ public ImageNormalizerException(String message, Throwable t)
+ {
+ super(message,t);
+
+ } // end constructor
+
+} // end class ImageNormalizerException
diff --git a/src/baseutil/com/silverwrist/util/languages.properties b/src/baseutil/com/silverwrist/util/languages.properties
new file mode 100644
index 0000000..f9d0e97
--- /dev/null
+++ b/src/baseutil/com/silverwrist/util/languages.properties
@@ -0,0 +1,254 @@
+# The contents of this file are subject to the Mozilla Public License Version 1.1
+# (the "License"); you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at .
+#
+# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+# WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+# language governing rights and limitations under the License.
+#
+# The Original Code is the Venice Web Communities System.
+#
+# The Initial Developer of the Original Code is Eric J. Bowersox ,
+# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+# Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+#
+# Contributor(s):
+# -------------------------------------------------------------------------------------
+# This list of languages is styled on RFC 1766, based on ISO 639 language code listings,
+# from , and ISO 3166 country code listings,
+# from . Language variants by country taken
+# from WINNT.H header file, Microsoft Windows Platform SDK. Additional language codes
+# (i- names and expanded zh- names) from IANA, .
+# Changes to Indonesian, Hebrew, and Yiddish noted from Java 2 SDK documentation.
+# When adding new entries to this file, make sure and add it in sorted order by language NAME!
+# You can re-sort the language entries with "sort -t = -k 2 input > output", but then make sure
+# the "i-default=(unknown)" entry appears first!
+i-default=(unknown)
+ab=Abkhazian
+aa=Afar
+af=Afrikaans
+sq=Albanian
+am=Amharic
+i-ami=Amis
+ar=Arabic
+ar-DZ=Arabic (Algeria)
+ar-BH=Arabic (Bahrain)
+ar-EG=Arabic (Egypt)
+ar-IQ=Arabic (Iraq)
+ar-JO=Arabic (Jordan)
+ar-KW=Arabic (Kuwait)
+ar-LB=Arabic (Lebanon)
+ar-LY=Arabic (Libya)
+ar-MA=Arabic (Morocco)
+ar-OM=Arabic (Oman)
+ar-QA=Arabic (Qatar)
+ar-SA=Arabic (Saudi Arabia)
+ar-SY=Arabic (Syria)
+ar-TN=Arabic (Tunisia)
+ar-AE=Arabic (U.A.E.)
+ar-YE=Arabic (Yemen)
+hy=Armenian
+as=Assamese
+ay=Aymara
+az=Azerbaijani
+ba=Bashkir
+eu=Basque
+bn=Bengali
+bh=Bihari
+bi=Bislama
+br=Breton
+bg=Bulgarian
+i-bnn=Bunun
+my=Burmese
+be=Byelorussian
+km=Cambodian
+ca=Catalan
+zh=Chinese
+zh-yue=Chinese (Cantonese)
+zh-gan=Chinese (Gan)
+zh-hakka=Chinese (Hakka)
+zh-HK=Chinese (Hong Kong)
+zh-xiang=Chinese (Hunan)
+zh-guoyu=Chinese (Mandarin)
+zh-wuu=Chinese (Shanghai)
+zh-CN=Chinese (Simplified)
+zh-SG=Chinese (Singapore)
+zh-min=Chinese (Taiwanese)
+zh-TW=Chinese (Traditional)
+co=Corsican
+hr=Croatian
+cs=Czech
+da=Danish
+nl=Dutch
+nl-BE=Dutch (Belgian)
+dz=Dzongkha
+en=English
+en-AU=English (Australian)
+en-BZ=English (Belize)
+en-CA=English (Canadian)
+en-caribbean=English (Caribbean)
+en-IE=English (Irish)
+en-JM=English (Jamaica)
+en-NZ=English (New Zealand)
+en-scouse=English (Scouse)
+en-ZA=English (South Africa)
+en-TT=English (Trinidad)
+en-GB=English (United Kingdom)
+en-US=English (United States)
+eo=Esperanto
+et=Estonian
+fo=Faeroese
+fj=Fiji
+fi=Finnish
+fr=French
+fr-BE=French (Belgian)
+fr-CA=French (Canadian)
+fr-LU=French (Luxembourg)
+fr-CH=French (Swiss)
+fy=Frisian
+gl=Gallegan
+ka=Georgian
+de=German
+de-AT=German (Austria)
+de-LI=German (Liechtenstein)
+de-LU=German (Luxembourg)
+de-CH=German (Swiss)
+el=Greek
+kl=Greenlandic
+gn=Guarani
+gu=Gujarati
+i-hak=Hakka
+ha=Hausa
+he=Hebrew
+hi=Hindi
+hu=Hungarian
+is=Icelandic
+id=Indonesian
+ia=Interlingua
+ie=Interlingue
+iu=Inuktitut
+ik=Inupiak
+ga=Irish
+it=Italian
+it-CH=Italian (Swiss)
+ja=Japanese
+jw=Javanese
+kn=Kannada
+ks=Kashmiri
+km=Khmer
+kk=Kazakh
+rw=Kinyarwanda
+ky=Kirghiz
+rn=Kirundi
+i-klingon=Klingon
+ko=Korean
+ko-johab=Korean (Johab)
+ku=Kurdish
+oc=Langue d'Oc
+lo=Lao
+la=Latin
+lv=Latvian
+ln=Lingala
+lt=Lithuanian
+i-lux=Luxembourgish
+mk=Macedonian
+mg=Malagasy
+ms=Malay
+ml=Maltese
+mi=Maori
+mr=Marathi
+i-mingo=Mingo
+mo=Moldavian
+mn=Mongolian
+na=Nauru
+i-navajo=Navajo
+ne=Nepali
+no=Norwegian
+no-bok=Norwegian (Bokmal)
+no-nyn=Norwegian (Nynorsk)
+oc=Occitan
+or=Oriya
+om=Oromo
+i-pwn=Paiwan
+pa=Panjabi
+ps=Pashto
+fa=Persian
+pl=Polish
+pt=Portuguese
+pt-BR=Portuguese (Brazilian)
+ps=Pushto
+qu=Quechua
+rm=Rhaeto-Romance
+ro=Romanian
+rn=Rundi
+ru=Russian
+sm=Samoan
+sg=Sango
+sa=Sanskrit
+gd=Scots Gaelic
+sr-cyrillic=Serbian (Cyrillic)
+sr=Serbian (Latin)
+sh=Serbo-Croatian
+st=Sesotho
+sn=Shona
+sd=Sindhi
+si=Singhalese
+ss=Siswant
+sk=Slovak
+sl=Slovenian
+so=Somali
+st=Sotho
+es-AR=Spanish (Argentina)
+es-BO=Spanish (Bolivia)
+es-ES=Spanish (Castilian)
+es-CL=Spanish (Chile)
+es-CO=Spanish (Colombia)
+es-CR=Spanish (Costa Rica)
+es-DO=Spanish (Dominican Republic)
+es-EC=Spanish (Ecuador)
+es-SV=Spanish (El Salvador)
+es-GT=Spanish (Guatemala)
+es-HN=Spanish (Honduras)
+es-MX=Spanish (Mexican)
+es=Spanish (Modern)
+es-NI=Spanish (Nicaragua)
+es-PA=Spanish (Panama)
+es-PY=Spanish (Paraguay)
+es-PE=Spanish (Peru)
+es-PR=Spanish (Puerto Rico)
+es-UY=Spanish (Uruguay)
+es-VE=Spanish (Venezuela)
+su=Sudanese
+sw=Swahili
+sv=Swedish
+sv-FI=Swedish (Finland)
+tl=Tagalog
+tg=Tajik
+ta=Tamil
+i-tao=Tao
+tt=Tatar
+i-tay=Tayal
+te=Tegulu
+th=Thai
+bo=Tibetan
+ti=Tigrinya
+to=Tonga
+ts=Tsonga
+i-tsu=Tsou
+tn=Tswana
+tr=Turkish
+tk=Turkmen
+tw=Twi
+ug=Uighur
+uk=Ukrainian
+ur=Urdu
+uz=Uzbek
+vi=Vietnamese
+vo=Volapuk
+cy=Welsh
+wo=Wolof
+xh=Xhosa
+yi=Yiddish
+yo=Yoruba
+za=Zhuang
+zu=Zulu
diff --git a/src/baseutil/com/silverwrist/util/xml/DOMElementHelper.java b/src/baseutil/com/silverwrist/util/xml/DOMElementHelper.java
new file mode 100644
index 0000000..0a17517
--- /dev/null
+++ b/src/baseutil/com/silverwrist/util/xml/DOMElementHelper.java
@@ -0,0 +1,489 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.util.xml;
+
+import org.w3c.dom.*;
+import com.silverwrist.util.StringUtils;
+
+/**
+ * A class which wraps around the DOM Element class, providing some
+ * additional functionality. Written to DOM Level 2.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ * @see org.w3c.dom.Element
+ */
+public final class DOMElementHelper
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private Element m_elt; // element housed by this helper class
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a new DOMElementHelper to wrap a specific Element.
+ *
+ * @param elt The Element to be wrapped.
+ */
+ public DOMElementHelper(Element elt)
+ {
+ m_elt = elt;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Internal static operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Returns the content of all text nodes underneath a specified Element, concatenated
+ * together into a single string.
+ *
+ * @param e The Element to extract text from.
+ * @return The text content under this Element node. If the specified Element
+ * has no text nodes underneath it, returns null.
+ */
+ private static final String getTextOfElement(Element e)
+ {
+ NodeList kids = e.getChildNodes();
+ if (kids==null)
+ return null; // no text?
+
+ StringBuffer b = null;
+ for (int i=0; iElement, expressed as an integer.
+ *
+ * @param e The Element to extract text from.
+ * @return An Integer object containing the value of the specified element. If
+ * the Element has no text, or if the text cannot be expressed as an integer,
+ * returns null.
+ */
+ private static final Integer getIntegerFromElement(Element e)
+ {
+ try
+ { // extract the text and create an Integer around it
+ String s = getTextOfElement(e);
+ return ((s==null) ? null : new Integer(s.trim()));
+
+ } // end try
+ catch (NumberFormatException nfe)
+ { // value cannot be parsed as an integer
+ return null;
+
+ } // end catch
+
+ } // end getIntegerFromElement
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Returns the Element wrapped by this object.
+ *
+ * @return See above.
+ */
+ public final Element getElement()
+ {
+ return m_elt;
+
+ } // end getElement
+
+ /**
+ * Searches for the first sub-element of the wrapped Element with the given name.
+ *
+ * @param name Name of the sub-element to search for.
+ * @return The first sub-element of the wrapped Element with the specified name.
+ * If the Element has no child Elements with the given name,
+ * the method returns null.
+ */
+ public final Element getSubElement(String name)
+ {
+ NodeList kids = m_elt.getChildNodes();
+ if (kids==null)
+ return null; // no children?
+ for (int i=0; iElement with the given name.
+ *
+ * @param namespaceURI Namespace URI for the sub-element to search for.
+ * @param name Name of the sub-element to search for.
+ * @return The first sub-element of the wrapped Element with the specified URI/name.
+ * If the Element has no child Elements with the given URI/name,
+ * the method returns null.
+ */
+ public final Element getSubElementNS(String namespaceURI, String name)
+ {
+ NodeList kids = m_elt.getChildNodes();
+ if (kids==null)
+ return null; // no children?
+ for (int i=0; iElement, concatenated
+ * together into a single string.
+ *
+ * @return The text content under the wrapped Element node. If the wrapped Element
+ * has not text nodes underneath it, returns null.
+ */
+ public final String getElementText()
+ {
+ return getTextOfElement(m_elt);
+
+ } // end getElementText
+
+ /**
+ * Returns the value of the text of the wrapped Element, expressed as an integer.
+ *
+ * @return An Integer object containing the value of the wrapped element. If
+ * the Element has no text, or if the text cannot be expressed as an integer,
+ * returns null.
+ */
+ public final Integer getElementInt()
+ {
+ return getIntegerFromElement(m_elt);
+
+ } // end getElementInt
+
+ /**
+ * Returns the content of all text nodes underneath the first sub-element of the wrapped
+ * Element, with the given name, concatenated together into a single string.
+ *
+ * @param name The name of the sub-element to search for.
+ * @return The text content under the specified sub-element of the wrapped Element node.
+ * If the wrapped Element does not have a sub-element with the given name, or
+ * that sub-element has no text nodes underneath it, returns null.
+ */
+ public final String getSubElementText(String name)
+ {
+ Element se = getSubElement(name);
+ return ((se==null) ? null : getTextOfElement(se));
+
+ } // end getSubElementText
+
+ /**
+ * Returns the content of all text nodes underneath the first sub-element of the wrapped
+ * Element, with the given name, concatenated together into a single string.
+ *
+ * @param namespaceURI Namespace URI for the sub-element to search for.
+ * @param name The name of the sub-element to search for.
+ * @return The text content under the specified sub-element of the wrapped Element node.
+ * If the wrapped Element does not have a sub-element with the given URI/name, or
+ * that sub-element has no text nodes underneath it, returns null.
+ */
+ public final String getSubElementTextNS(String namespaceURI, String name)
+ {
+ Element se = getSubElementNS(namespaceURI,name);
+ return ((se==null) ? null : getTextOfElement(se));
+
+ } // end getSubElementTextNS
+
+ /**
+ * Returns the value of the text underneath the first sub-element of the wrapped
+ * Element, with the given name, expressed as an integer.
+ *
+ * @param name The name of the sub-element to search for.
+ * @return An Integer object containing the value of the specified element. If
+ * the wrapped Element does not have a sub-element with the given name, or that
+ * sub-element has no text, or if the text cannot be expressed as an integer, returns
+ * null.
+ */
+ public final Integer getSubElementInt(String name)
+ {
+ Element se = getSubElement(name);
+ return ((se==null) ? null : getIntegerFromElement(se));
+
+ } // end getSubElementInt
+
+ /**
+ * Returns the value of the text underneath the first sub-element of the wrapped
+ * Element, with the given name, expressed as an integer.
+ *
+ * @param namespaceURI Namespace URI for the sub-element to search for.
+ * @param name The name of the sub-element to search for.
+ * @return An Integer object containing the value of the specified element. If
+ * the wrapped Element does not have a sub-element with the given URI/name, or that
+ * sub-element has no text, or if the text cannot be expressed as an integer, returns
+ * null.
+ */
+ public final Integer getSubElementIntNS(String namespaceURI, String name)
+ {
+ Element se = getSubElementNS(namespaceURI,name);
+ return ((se==null) ? null : getIntegerFromElement(se));
+
+ } // end getSubElementIntNS
+
+ /**
+ * Determines whether the wrapped Element has a sub-element with the given name.
+ *
+ * @param name Name of the sub-element to search for.
+ * @return true if the wrapped Element has a sub-element with the
+ * specified name, false if not.
+ */
+ public final boolean hasChildElement(String name)
+ {
+ return (getSubElement(name)!=null);
+
+ } // end hasChildElement
+
+ /**
+ * Determines whether the wrapped Element has a sub-element with the given name.
+ *
+ * @param namespaceURI Namespace URI for the sub-element to search for.
+ * @param name Name of the sub-element to search for.
+ * @return true if the wrapped Element has a sub-element with the
+ * specified name, false if not.
+ */
+ public final boolean hasChildElementNS(String namespaceURI, String name)
+ {
+ return (getSubElementNS(namespaceURI,name)!=null);
+
+ } // end hasChildElementNS
+
+ /**
+ * Determines whether the wrapped Element has an attribute with the given name.
+ *
+ * @param name Name of the attribute to search for.
+ * @return true if the wrapped Element has an attribute with the
+ * specified name, false if not.
+ */
+ public final boolean hasAttribute(String name)
+ {
+ return m_elt.hasAttribute(name);
+
+ } // end hasAttribute
+
+ /**
+ * Determines whether the wrapped Element has an attribute with the given name.
+ *
+ * @param namespaceURI Namespace URI for the attribute to search for.
+ * @param name Name of the attribute to search for.
+ * @return true if the wrapped Element has an attribute with the
+ * specified URI/name, false if not.
+ */
+ public final boolean hasAttributeNS(String namespaceURI, String name)
+ {
+ return m_elt.hasAttributeNS(namespaceURI,name);
+
+ } // end hasAttributeNS
+
+ /**
+ * Returns the value of a specified attribute of the wrapped Element, expressed as
+ * an integer.
+ *
+ * @param name Name of the attribute to search for.
+ * @return An Integer object containing the value of the specified attribute. If
+ * the wrapped Element has no such attribute, or if the attribute's value
+ * cannot be expressed as an integer, returns null.
+ */
+ public final Integer getAttributeInt(String name)
+ {
+ String tmp = m_elt.getAttribute(name);
+ if (StringUtils.isEmpty(tmp))
+ return null;
+ try
+ { // convert to an Integer
+ return new Integer(tmp.trim());
+
+ } // end try
+ catch (NumberFormatException nfe)
+ { // return a null value on error
+ return null;
+
+ } // end catch
+
+ } // end getAttributeInt
+
+ /**
+ * Returns the value of a specified attribute of the wrapped Element, expressed as
+ * an integer.
+ *
+ * @param namespaceURI Namespace URI for the attribute to search for.
+ * @param name Name of the attribute to search for.
+ * @return An Integer object containing the value of the specified attribute. If
+ * the wrapped Element has no such attribute, or if the attribute's value
+ * cannot be expressed as an integer, returns null.
+ */
+ public final Integer getAttributeIntNS(String namespaceURI, String name)
+ {
+ String tmp = m_elt.getAttributeNS(namespaceURI,name);
+ if (StringUtils.isEmpty(tmp))
+ return null;
+ try
+ { // convert to an Integer
+ return new Integer(tmp.trim());
+
+ } // end try
+ catch (NumberFormatException nfe)
+ { // return a null value on error
+ return null;
+
+ } // end catch
+
+ } // end getAttributeInt
+
+ /**
+ * Returns the value of a specified attribute of the wrapped Element, expressed as
+ * a Boolean. Uses the Boolean string methods on {@link com.silverwrist.util.StringUtils StringUtils} to
+ * determine the state of the attribute value.
+ *
+ * @param name Name of the attribute to search for.
+ * @return Boolean.TRUE if the attribute value represents a "true" Boolean value;
+ * Boolean.FALSE if the attribute value represents a "false" Boolean value; null
+ * otherwise.
+ * @see com.silverwrist.util.StringUtils#isBooleanTrue(java.lang.String)
+ * @see com.silverwrist.util.StringUtils#isBooleanFalse(java.lang.String)
+ */
+ public final Boolean getAttributeBoolean(String name)
+ {
+ String tmp = m_elt.getAttribute(name);
+ if (StringUtils.isBooleanTrue(tmp))
+ return Boolean.TRUE;
+ else if (StringUtils.isBooleanFalse(tmp))
+ return Boolean.FALSE;
+ else
+ return null;
+
+ } // end getAttributeBoolean
+
+ /**
+ * Returns the value of a specified attribute of the wrapped Element, expressed as
+ * a Boolean. Uses the Boolean string methods on {@link com.silverwrist.util.StringUtils StringUtils} to
+ * determine the state of the attribute value.
+ *
+ * @param namespaceURI Namespace URI for the attribute to search for.
+ * @param name Name of the attribute to search for.
+ * @return Boolean.TRUE if the attribute value represents a "true" Boolean value;
+ * Boolean.FALSE if the attribute value represents a "false" Boolean value; null
+ * otherwise.
+ * @see com.silverwrist.util.StringUtils#isBooleanTrue(java.lang.String)
+ * @see com.silverwrist.util.StringUtils#isBooleanFalse(java.lang.String)
+ */
+ public final Boolean getAttributeBooleanNS(String namespaceURI, String name)
+ {
+ String tmp = m_elt.getAttributeNS(namespaceURI,name);
+ if (StringUtils.isBooleanTrue(tmp))
+ return Boolean.TRUE;
+ else if (StringUtils.isBooleanFalse(tmp))
+ return Boolean.FALSE;
+ else
+ return null;
+
+ } // end getAttributeBooleanNS
+
+ /**
+ * Returns the value of a specified attribute of the wrapped Element, expressed as
+ * a Boolean. Uses the Boolean string methods on {@link com.silverwrist.util.StringUtils StringUtils} to
+ * determine the state of the attribute value.
+ *
+ * @param name Name of the attribute to search for.
+ * @param default_val Default value for the attribute.
+ * @return Boolean.TRUE if the attribute value represents a "true" Boolean value;
+ * Boolean.FALSE if the attribute value represents a "false" Boolean value; the
+ * Boolean object corresponding to default_val if the attribute is missing;
+ * null otherwise.
+ * @see com.silverwrist.util.StringUtils#isBooleanTrue(java.lang.String)
+ * @see com.silverwrist.util.StringUtils#isBooleanFalse(java.lang.String)
+ */
+ public final Boolean getAttributeBoolean(String name, boolean default_val)
+ {
+ if (this.hasAttribute(name))
+ return this.getAttributeBoolean(name);
+ else
+ return (default_val ? Boolean.TRUE : Boolean.FALSE);
+
+ } // end getAttributeBoolean
+
+ /**
+ * Returns the value of a specified attribute of the wrapped Element, expressed as
+ * a Boolean. Uses the Boolean string methods on {@link com.silverwrist.util.StringUtils StringUtils} to
+ * determine the state of the attribute value.
+ *
+ * @param namespaceURI Namespace URI for the attribute to search for.
+ * @param name Name of the attribute to search for.
+ * @param default_val Default value for the attribute.
+ * @return Boolean.TRUE if the attribute value represents a "true" Boolean value;
+ * Boolean.FALSE if the attribute value represents a "false" Boolean value; the
+ * Boolean object corresponding to default_val if the attribute is missing;
+ * null otherwise.
+ * @see com.silverwrist.util.StringUtils#isBooleanTrue(java.lang.String)
+ * @see com.silverwrist.util.StringUtils#isBooleanFalse(java.lang.String)
+ */
+ public final Boolean getAttributeBooleanNS(String namespaceURI, String name, boolean default_val)
+ {
+ if (this.hasAttributeNS(namespaceURI,name))
+ return this.getAttributeBooleanNS(namespaceURI,name);
+ else
+ return (default_val ? Boolean.TRUE : Boolean.FALSE);
+
+ } // end getAttributeBooleanNS
+
+} // end class DOMElementHelper
diff --git a/src/baseutil/com/silverwrist/util/xml/XMLLoadException.java b/src/baseutil/com/silverwrist/util/xml/XMLLoadException.java
new file mode 100644
index 0000000..9dd7c32
--- /dev/null
+++ b/src/baseutil/com/silverwrist/util/xml/XMLLoadException.java
@@ -0,0 +1,155 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.util.xml;
+
+import org.w3c.dom.*;
+
+/**
+ * An exception type thrown by the {@link com.silverwrist.util.xml.XMLLoader XMLLoader} when it encounters
+ * a parse error, value error, or other erroneous condition. It contains a reference to the node in the DOM
+ * tree where the error occured, if such is possible to determine.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public class XMLLoadException extends Exception
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private Node m_locus = null; // locus of the error
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a new XMLLoadException.
+ */
+ public XMLLoadException()
+ {
+ super();
+
+ } // end constructor
+
+ /**
+ * Constructs a new XMLLoadException.
+ *
+ * @param msg The error message to be thrown.
+ */
+ public XMLLoadException(String msg)
+ {
+ super(msg);
+
+ } // end constructor
+
+ /**
+ * Constructs a new XMLLoadException.
+ *
+ * @param inner The exception wrapped by this XMLLoadException.
+ */
+ public XMLLoadException(Throwable inner)
+ {
+ super(inner);
+
+ } // end constructor
+
+ /**
+ * Constructs a new XMLLoadException.
+ *
+ * @param msg The error message to be thrown.
+ * @param inner The exception wrapped by this XMLLoadException.
+ */
+ public XMLLoadException(String msg, Throwable inner)
+ {
+ super(msg,inner);
+
+ } // end constructor
+
+ /**
+ * Constructs a new XMLLoadException.
+ *
+ * @param locus The Node in the DOM tree where the error occurred.
+ */
+ public XMLLoadException(Node locus)
+ {
+ super("Error in <" + locus.getNodeName() + "/> section of input");
+ m_locus = locus;
+
+ } // end constructor
+
+ /**
+ * Constructs a new XMLLoadException.
+ *
+ * @param msg The error message to be thrown.
+ * @param locus The Node in the DOM tree where the error occurred.
+ */
+ public XMLLoadException(String msg, Node locus)
+ {
+ super("Error in <" + locus.getNodeName() + "/> section of input - " + msg);
+ m_locus = locus;
+
+ } // end constructor
+
+ /**
+ * Constructs a new XMLLoadException.
+ *
+ * @param inner The exception wrapped by this XMLLoadException.
+ * @param locus The Node in the DOM tree where the error occurred.
+ */
+ public XMLLoadException(Throwable inner, Node locus)
+ {
+ super("Error in <" + locus.getNodeName() + "/> section of input - " + inner.getMessage(),inner);
+ m_locus = locus;
+
+ } // end constructor
+
+ /**
+ * Constructs a new XMLLoadException.
+ *
+ * @param msg The error message to be thrown.
+ * @param inner The exception wrapped by this XMLLoadException.
+ * @param locus The Node in the DOM tree where the error occurred.
+ */
+ public XMLLoadException(String msg, Throwable inner, Node locus)
+ {
+ super("Error in <" + locus.getNodeName() + "/> section of input - " + msg,inner);
+ m_locus = locus;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Returns the locus of the error contained in this exception.
+ *
+ * @return The Node that indicates wherre in the DOM tree the error occurred.
+ */
+ public Node getLocus()
+ {
+ return m_locus;
+
+ } // end getLocus
+
+} // end class XMLLoadException
diff --git a/src/baseutil/com/silverwrist/util/xml/XMLLoader.java b/src/baseutil/com/silverwrist/util/xml/XMLLoader.java
new file mode 100644
index 0000000..9886ba6
--- /dev/null
+++ b/src/baseutil/com/silverwrist/util/xml/XMLLoader.java
@@ -0,0 +1,824 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.util.xml;
+
+import java.io.*;
+import java.util.*;
+import javax.xml.parsers.*;
+import org.apache.log4j.Logger;
+import org.w3c.dom.*;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import com.silverwrist.util.StringUtils;
+
+/**
+ * A simple class which is commonly used for the loading of XML documents as configuration files. Various
+ * methods on this object load XML documents as DOM trees and extract portions of the information therein.
+ * It is implemented as a Singleton.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public class XMLLoader
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static Logger logger = Logger.getLogger(XMLLoader.class);
+
+ private static XMLLoader self = null; // our singleton instance
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Internal constructor for XMLLoader. Only one instance is ever constructed.
+ */
+ private XMLLoader()
+ { // do nothing
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Parses an XML document into a DOM tree.
+ *
+ * @param stm The XML document to be parsed, expressed as an InputStream.
+ * @param namespacing true if we want this XML document parsed in a namespace-aware fashion,
+ * false if not.
+ * @return The Document that results from parsing the XML document.
+ * @exception java.io.IOException If there was an I/O error reading from the XML document.
+ * @exception com.silverwrist.util.xml.XMLLoaderException If there was a parse error in the XML, or other error
+ * accessing the XML parser.
+ */
+ public final Document load(InputStream stm, boolean namespacing) throws IOException, XMLLoadException
+ {
+ try
+ { // create a simple DOM parser by using the Java XML parsing API
+ DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();
+ fac.setNamespaceAware(namespacing);
+ fac.setValidating(false);
+ DocumentBuilder parser = fac.newDocumentBuilder();
+ if (parser.isNamespaceAware()!=namespacing)
+ throw new XMLLoadException("XML parser namespacing parameter is not consistent");
+
+ // access the config file and parse it into our config data tree
+ return parser.parse(stm);
+
+ } // end try
+ catch (FactoryConfigurationError fce)
+ { // if the document builder factory could not be created
+ throw new XMLLoadException("XML parser factory could not be created - " + fce.getMessage());
+
+ } // end catch
+ catch (ParserConfigurationException pce)
+ { // if the XML parser itself could not be created
+ throw new XMLLoadException("XML parser could not be created - " + pce.getMessage(),pce);
+
+ } // end catch
+ catch (SAXException se)
+ { // if the XML parser choked on our document
+ if (se instanceof SAXParseException)
+ { // we have a detailed message - make a proper exception
+ SAXParseException spe = (SAXParseException)se;
+ throw new XMLLoadException("Error in XML data: " + spe.getMessage() + " at line "
+ + spe.getLineNumber() + ", column " + spe.getColumnNumber(),spe);
+
+ } // end if
+ else
+ { // generic exception - just send up a simple error message
+ throw new XMLLoadException("Error in XML data - " + se.getMessage(),se);
+
+ } // end else
+
+ } // end catch
+
+ } // end load
+
+ /**
+ * Parses an XML document into a DOM tree.
+ *
+ * @param stm The XML document to be parsed, expressed as a File object.
+ * @param namespacing true if we want this XML document parsed in a namespace-aware fashion,
+ * false if not.
+ * @return The Document that results from parsing the XML document.
+ * @exception java.io.IOException If there was an I/O error reading from the XML document.
+ * @exception com.silverwrist.util.xml.XMLLoaderException If there was a parse error in the XML, or other error
+ * accessing the XML parser.
+ */
+ public final Document load(File file, boolean namespacing) throws IOException, XMLLoadException
+ {
+ return this.load(new FileInputStream(file),namespacing);
+
+ } // end load
+
+ /**
+ * Gets the root element of a parsed XML DOM tree, and verifies that it matches a specific name.
+ *
+ * @param doc The document to get the root element of.
+ * @param expected_name The expected name of the root element.
+ * @return The root Element of the document,
+ * @exception com.silverwrist.util.XMLLoadException If the root element of the document does not match the
+ * expected_name.
+ */
+ public final Element getRootElement(Document doc, String expected_name) throws XMLLoadException
+ {
+ Element rc = doc.getDocumentElement();
+ if (rc.getTagName().equals(expected_name))
+ return rc; // we're OK
+ throw new XMLLoadException("expected <" + expected_name + "/> root element",rc);
+
+ } // end getRootElement
+
+ /**
+ * Gets the root element of a parsed XML DOM tree, and verifies that it matches a specific name.
+ *
+ * @param doc The document to get the root element of.
+ * @param expected_namespace The expected namespace for the root element of the document.
+ * @param expected_name The expected name of the root element.
+ * @return The root Element of the document,
+ * @exception com.silverwrist.util.XMLLoadException If the root element of the document does not match the
+ * expected_namespace and expected_name.
+ */
+ public final Element getRootElementNS(Document doc, String expected_namespace,
+ String expected_name) throws XMLLoadException
+ {
+ Element rc = doc.getDocumentElement();
+ if (rc.getNamespaceURI().equals(expected_namespace) && rc.getTagName().equals(expected_name))
+ return rc; // we're OK
+ throw new XMLLoadException("expected <" + expected_namespace + ":" + expected_name + "/> root element",rc);
+
+ } // end getRootElementNS
+
+ /**
+ * Gets the text contained in an Element wrapped in a
+ * {@link com.silverwrist.util.xml.DOMElementHelper DOMElementHelper}.
+ *
+ * @param h The DOMElementHelper to extract the text from.
+ * @return The text contained in the element.
+ * @exception com.silverwrist.util.XMLLoadException If there is no text contained in the element.
+ */
+ public final String getText(DOMElementHelper h) throws XMLLoadException
+ {
+ String rc = h.getElementText();
+ if (rc!=null)
+ return rc; // we're OK
+ throw new XMLLoadException("no text found under element",h.getElement());
+
+ } // end getText
+
+ /**
+ * Gets the text contained in an Element.
+ *
+ * @param elt The Element to extract the text from.
+ * @return The text contained in the element.
+ * @exception com.silverwrist.util.XMLLoadException If there is no text contained in the element.
+ */
+ public final String getText(Element elt) throws XMLLoadException
+ {
+ return getText(new DOMElementHelper(elt));
+
+ } // end getText
+
+ /**
+ * Gets the text contained in a named sub-element of an Element wrapped in a
+ * {@link com.silverwrist.util.xml.DOMElementHelper DOMElementHelper}.
+ *
+ * @param h The DOMElementHelper to extract the text from.
+ * @param elt_name The name of the sub-element to look for text in.
+ * @return The text contained in the sub-element.
+ * @exception com.silverwrist.util.XMLLoadException If the sub-element is not found, or there is no text
+ * contained in the sub-element.
+ */
+ public final String getSubElementText(DOMElementHelper h, String elt_name) throws XMLLoadException
+ {
+ String rc = h.getSubElementText(elt_name);
+ if (rc!=null)
+ return rc; // we're OK
+ throw new XMLLoadException("sublement <" + elt_name + "/> not found",h.getElement());
+
+ } // end getSubElementText
+
+ /**
+ * Gets the text contained in a named sub-element of an Element.
+ *
+ * @param elt The Element to extract the text from.
+ * @param subelt_name The name of the sub-element to look for text in.
+ * @return The text contained in the sub-element.
+ * @exception com.silverwrist.util.XMLLoadException If the sub-element is not found, or there is no text
+ * contained in the sub-element.
+ */
+ public final String getSubElementText(Element elt, String subelt_name) throws XMLLoadException
+ {
+ return getSubElementText(new DOMElementHelper(elt),subelt_name);
+
+ } // end getSubElementText
+
+ /**
+ * Gets the text contained in a named sub-element of an Element wrapped in a
+ * {@link com.silverwrist.util.xml.DOMElementHelper DOMElementHelper}.
+ *
+ * @param h The DOMElementHelper to extract the text from.
+ * @param namespace The namespace URI of the sub-element to look for text in.
+ * @param elt_name The name of the sub-element to look for text in.
+ * @return The text contained in the sub-element.
+ * @exception com.silverwrist.util.XMLLoadException If the sub-element is not found, or there is no text
+ * contained in the sub-element.
+ */
+ public final String getSubElementTextNS(DOMElementHelper h, String namespace, String elt_name)
+ throws XMLLoadException
+ {
+ String rc = h.getSubElementTextNS(namespace,elt_name);
+ if (rc!=null)
+ return rc; // we're OK
+ throw new XMLLoadException("sublement <" + namespace + ":" + elt_name + "/> not found",h.getElement());
+
+ } // end getSubElementTextNS
+
+ /**
+ * Gets the text contained in a named sub-element of an Element.
+ *
+ * @param elt The Element to extract the text from.
+ * @param namespace The namespace URI of the sub-element to look for text in.
+ * @param subelt_name The name of the sub-element to look for text in.
+ * @return The text contained in the sub-element.
+ * @exception com.silverwrist.util.XMLLoadException If the sub-element is not found, or there is no text
+ * contained in the sub-element.
+ */
+ public final String getSubElementTextNS(Element elt, String namespace, String subelt_name)
+ throws XMLLoadException
+ {
+ return getSubElementTextNS(new DOMElementHelper(elt),namespace,subelt_name);
+
+ } // end getSubElementTextNS
+
+ /**
+ * Gets a named sub-element of an Element wrapped in a
+ * {@link com.silverwrist.util.xml.DOMElementHelper DOMElementHelper}.
+ *
+ * @param h The DOMElementHelper to extract the sub-element from.
+ * @param name The name of the sub-element to look for.
+ * @return The sub-element.
+ * @exception com.silverwrist.util.XMLLoadException If the sub-element is not found.
+ */
+ public final Element getSubElement(DOMElementHelper h, String name) throws XMLLoadException
+ {
+ Element rc = h.getSubElement(name);
+ if (rc!=null)
+ return rc; // we're OK
+ throw new XMLLoadException("sublement <" + name + "/> not found",h.getElement());
+
+ } // end getSubElement
+
+ /**
+ * Gets a named sub-element of an Element.
+ *
+ * @param sect The Element to extract the sub-element from.
+ * @param name The name of the sub-element to look for.
+ * @return The sub-element.
+ * @exception com.silverwrist.util.XMLLoadException If the sub-element is not found.
+ */
+ public final Element getSubElement(Element sect, String name) throws XMLLoadException
+ {
+ return getSubElement(new DOMElementHelper(sect),name);
+
+ } // end getSubElement
+
+ /**
+ * Gets a named sub-element of an Element wrapped in a
+ * {@link com.silverwrist.util.xml.DOMElementHelper DOMElementHelper}.
+ *
+ * @param h The DOMElementHelper to extract the sub-element from.
+ * @param namespace The namespace URI of the sub-element to look for.
+ * @param name The name of the sub-element to look for.
+ * @return The sub-element.
+ * @exception com.silverwrist.util.XMLLoadException If the sub-element is not found.
+ */
+ public final Element getSubElementNS(DOMElementHelper h, String namespace, String name)
+ throws XMLLoadException
+ {
+ Element rc = h.getSubElementNS(namespace,name);
+ if (rc!=null)
+ return rc; // we're OK
+ throw new XMLLoadException("sublement <" + namespace + ":" + name + "/> not found",h.getElement());
+
+ } // end getSubElementNS
+
+ /**
+ * Gets a named sub-element of an Element.
+ *
+ * @param sect The Element to extract the sub-element from.
+ * @param namespace The namespace URI of the sub-element to look for.
+ * @param name The name of the sub-element to look for.
+ * @return The sub-element.
+ * @exception com.silverwrist.util.XMLLoadException If the sub-element is not found.
+ */
+ public final Element getSubElementNS(Element sect, String namespace, String name) throws XMLLoadException
+ {
+ return getSubElementNS(new DOMElementHelper(sect),namespace,name);
+
+ } // end getSubElementNS
+
+ /**
+ * Returns all sub-elements of an Element element that have a specific name.
+ *
+ * @param sect The Element to extract the sub-elements from.
+ * @param name The name of the sub-elements to look for.
+ * @return A java.util.List containing all the sub-elements of the given Element with
+ * the specified name. If there are no matching sub-elements, an empty list is returned.
+ */
+ public final List getMatchingSubElements(Element sect, String name)
+ {
+ ArrayList rc = new ArrayList();
+ NodeList nl = sect.getChildNodes();
+ for (int i=0; iElement element that have a specific name.
+ *
+ * @param sect The Element to extract the sub-elements from.
+ * @param namespace The namespace URI of the sub-elements to look for.
+ * @param name The name of the sub-elements to look for.
+ * @return A java.util.List containing all the sub-elements of the given Element with
+ * the specified namespace and name. If there are no matching sub-elements, an empty list is returned.
+ */
+ public final List getMatchingSubElementsNS(Element sect, String namespace, String name)
+ {
+ ArrayList rc = new ArrayList();
+ NodeList nl = sect.getChildNodes();
+ for (int i=0; iNode to test the name of.
+ * @param name The name to test the node against.
+ * @param enclosing_sect The Element that contains this node as a child, used in constructing
+ * the exception if the test fails.
+ * @exception com.silverwrist.util.xml.XMLLoadException If the name of the node does not match.
+ */
+ public final void verifyNodeName(Node n, String name, Element enclosing_sect) throws XMLLoadException
+ {
+ if (n.getNodeName().equals(name))
+ return;
+ throw new XMLLoadException("node <" + n.getNodeName() + "/> should be <" + name + "/>",enclosing_sect);
+
+ } // end verifyNodeName
+
+ /**
+ * Checks to make sure that the name of a given node is what we expect, and throws an
+ * {@link com.silverwrist.util.xml.XMLLoadException XMLLoadException} if it isn't.
+ *
+ * @param n The Node to test the name of.
+ * @param name The name to test the node against.
+ * @exception com.silverwrist.util.xml.XMLLoadException If the name of the node does not match.
+ */
+ public final void verifyNodeName(Node n, String name) throws XMLLoadException
+ {
+ verifyNodeName(n,name,(Element)(n.getParentNode()));
+
+ } // end verifyNodeName
+
+ /**
+ * Checks to make sure that the name of a given node is what we expect, and throws an
+ * {@link com.silverwrist.util.xml.XMLLoadException XMLLoadException} if it isn't.
+ *
+ * @param n The Node to test the name of.
+ * @param namespace The namespace URI to test the node against.
+ * @param name The name to test the node against.
+ * @param enclosing_sect The Element that contains this node as a child, used in constructing
+ * the exception if the test fails.
+ * @exception com.silverwrist.util.xml.XMLLoadException If the name of the node does not match.
+ */
+ public final void verifyNodeNameNS(Node n, String namespace, String name, Element enclosing_sect)
+ throws XMLLoadException
+ {
+ if (n.getNamespaceURI().equals(namespace) && n.getNodeName().equals(name))
+ return;
+ throw new XMLLoadException("node <" + n.getNamespaceURI() + ":" + n.getNodeName() + "/> should be <"
+ + namespace + ":" + name + "/>",enclosing_sect);
+
+ } // end verifyNodeNameNS
+
+ /**
+ * Checks to make sure that the name of a given node is what we expect, and throws an
+ * {@link com.silverwrist.util.xml.XMLLoadException XMLLoadException} if it isn't.
+ *
+ * @param n The Node to test the name of.
+ * @param namespace The namespace URI to test the node against.
+ * @param name The name to test the node against.
+ * @exception com.silverwrist.util.xml.XMLLoadException If the name of the node does not match.
+ */
+ public final void verifyNodeNameNS(Node n, String namespace, String name) throws XMLLoadException
+ {
+ verifyNodeNameNS(n,namespace,name,(Element)(n.getParentNode()));
+
+ } // end verifyNodeNameNS
+
+ /**
+ * Checks to make sure that the name of a given tag element is what we expect, and throws an
+ * {@link com.silverwrist.util.xml.XMLLoadException XMLLoadException} if it isn't.
+ *
+ * @param tag The Element to test the name of.
+ * @param name The name to test the element against.
+ * @exception com.silverwrist.util.xml.XMLLoadException If the name of the element does not match.
+ */
+ public final void verifyTagName(Element tag, String name) throws XMLLoadException
+ {
+ if (tag.getTagName().equals(name))
+ return;
+ throw new XMLLoadException("expected <" + name + "/> element",tag);
+
+ } // end verifyTagName
+
+ /**
+ * Checks to make sure that the name of a given tag element is what we expect, and throws an
+ * {@link com.silverwrist.util.xml.XMLLoadException XMLLoadException} if it isn't.
+ *
+ * @param tag The Element to test the name of.
+ * @param namespace The namespace URI to test the element against.
+ * @param name The name to test the element against.
+ * @exception com.silverwrist.util.xml.XMLLoadException If the name of the element does not match.
+ */
+ public final void verifyTagNameNS(Element tag, String namespace, String name) throws XMLLoadException
+ {
+ if (tag.getNamespaceURI().equals(namespace) && tag.getTagName().equals(name))
+ return;
+ throw new XMLLoadException("expected <" + namespace + ":" + name + "/> element",tag);
+
+ } // end verifyTagNameNS
+
+ /**
+ * Gets the value of an attribute on an Element.
+ *
+ * @param elt The Element to retrieve the attribute from.
+ * @param attr_name The name of the attribute to retrieve.
+ * @return The attribute value.
+ * @exception com.silverwrist.util.xml.XMLLoadException If the attribute did not exist on the element.
+ */
+ public final String getAttribute(Element elt, String attr_name) throws XMLLoadException
+ {
+ String rc = elt.getAttribute(attr_name);
+ if (!(StringUtils.isEmpty(rc)))
+ return rc;
+ throw new XMLLoadException("no " + attr_name + "= attribute found",elt);
+
+ } // end getAttribute
+
+ /**
+ * Gets the value of an attribute on an Element.
+ *
+ * @param elt The Element to retrieve the attribute from.
+ * @param attr_name The name of the attribute to retrieve.
+ * @param default_val The default value of the attribute.
+ * @return The attribute value, or the value of default_val if the attribute didn't exist.
+ */
+ public final String getAttribute(Element elt, String attr_name, String default_val)
+ {
+ String rc = elt.getAttribute(attr_name);
+ return (StringUtils.isEmpty(rc) ? default_val : rc);
+
+ } // end getAttribute
+
+ /**
+ * Gets the value of an attribute on an Element.
+ *
+ * @param elt The Element to retrieve the attribute from.
+ * @param namespace The namespace URI of the attribute to retrieve.
+ * @param attr_name The name of the attribute to retrieve.
+ * @return The attribute value.
+ * @exception com.silverwrist.util.xml.XMLLoadException If the attribute did not exist on the element.
+ */
+ public final String getAttributeNS(Element elt, String namespace, String attr_name) throws XMLLoadException
+ {
+ String rc = elt.getAttributeNS(namespace,attr_name);
+ if (!(StringUtils.isEmpty(rc)))
+ return rc;
+ throw new XMLLoadException("no " + namespace + ":" + attr_name + "= attribute found",elt);
+
+ } // end getAttributeNS
+
+ /**
+ * Gets the value of an attribute on an Element.
+ *
+ * @param elt The Element to retrieve the attribute from.
+ * @param namespace The namespace URI of the attribute to retrieve.
+ * @param attr_name The name of the attribute to retrieve.
+ * @param default_val The default value of the attribute.
+ * @return The attribute value, or the value of default_val if the attribute didn't exist.
+ */
+ public final String getAttributeNS(Element elt, String namespace, String attr_name, String default_val)
+ {
+ String rc = elt.getAttributeNS(namespace,attr_name);
+ return (StringUtils.isEmpty(rc) ? default_val : rc);
+
+ } // end getAttributeNS
+
+ /**
+ * Gets the value of an attribute on an Element, expressed as an integer.
+ *
+ * @param elt The Element to retrieve the attribute from.
+ * @param attr_name The name of the attribute to retrieve.
+ * @return The attribute value.
+ * @exception com.silverwrist.util.xml.XMLLoadException If the attribute did not exist on the element, or
+ * it could not be parsed as an integer.
+ */
+ public final int getAttributeInt(Element elt, String attr_name) throws XMLLoadException
+ {
+ String tmp = elt.getAttribute(attr_name);
+ if (StringUtils.isEmpty(tmp))
+ { // the attribute is not present
+ throw new XMLLoadException("no " + attr_name + "= attribute found",elt);
+
+ } // end if
+
+ try
+ { // parse out the integer value
+ return Integer.parseInt(tmp.trim());
+
+ } // end try
+ catch (NumberFormatException nfe)
+ { // but it's not a valid integer - throw something else!
+ throw new XMLLoadException(attr_name + "= attribute value is not a valid integer",elt);
+
+ } // end catch
+
+ } // end getAttributeInt
+
+ /**
+ * Gets the value of an attribute on an Element, expressed as an integer.
+ *
+ * @param elt The Element to retrieve the attribute from.
+ * @param attr_name The name of the attribute to retrieve.
+ * @param default_val The default value of the attribute.
+ * @return The attribute value, or the value of default_val if the attribute didn't exist.
+ * @exception com.silverwrist.util.xml.XMLLoadException If the attribute could not be parsed as an integer.
+ */
+ public final int getAttributeInt(Element elt, String attr_name, int default_val) throws XMLLoadException
+ {
+ String tmp = elt.getAttribute(attr_name);
+ if (StringUtils.isEmpty(tmp))
+ return default_val; // the attribute is not present
+
+ try
+ { // parse out the integer value
+ return Integer.parseInt(tmp.trim());
+
+ } // end try
+ catch (NumberFormatException nfe)
+ { // but it's not a valid integer - throw something else!
+ throw new XMLLoadException(attr_name + "= attribute value is not a valid integer",elt);
+
+ } // end catch
+
+ } // end getAttributeInt
+
+ /**
+ * Gets the value of an attribute on an Element, expressed as an integer.
+ *
+ * @param elt The Element to retrieve the attribute from.
+ * @param namespace The namespace URI of the attribute to retrieve.
+ * @param attr_name The name of the attribute to retrieve.
+ * @return The attribute value.
+ * @exception com.silverwrist.util.xml.XMLLoadException If the attribute did not exist on the element, or
+ * it could not be parsed as an integer.
+ */
+ public final int getAttributeIntNS(Element elt, String namespace, String attr_name) throws XMLLoadException
+ {
+ String tmp = elt.getAttributeNS(namespace,attr_name);
+ if (StringUtils.isEmpty(tmp))
+ { // the attribute is not present
+ throw new XMLLoadException("no " + namespace + ":" + attr_name + "= attribute found",elt);
+
+ } // end if
+
+ try
+ { // parse out the integer value
+ return Integer.parseInt(tmp.trim());
+
+ } // end try
+ catch (NumberFormatException nfe)
+ { // but it's not a valid integer - throw something else!
+ throw new XMLLoadException(namespace + ":" + attr_name + "= attribute value is not a valid integer",elt);
+
+ } // end catch
+
+ } // end getAttributeIntNS
+
+ /**
+ * Gets the value of an attribute on an Element, expressed as an integer.
+ *
+ * @param elt The Element to retrieve the attribute from.
+ * @param namespace The namespace URI of the attribute to retrieve.
+ * @param attr_name The name of the attribute to retrieve.
+ * @param default_val The default value of the attribute.
+ * @return The attribute value, or the value of default_val if the attribute didn't exist.
+ * @exception com.silverwrist.util.xml.XMLLoadException If the attribute could not be parsed as an integer.
+ */
+ public final int getAttributeIntNS(Element elt, String namespace, String attr_name, int default_val)
+ throws XMLLoadException
+ {
+ String tmp = elt.getAttributeNS(namespace,attr_name);
+ if (StringUtils.isEmpty(tmp))
+ return default_val; // the attribute is not present
+
+ try
+ { // parse out the integer value
+ return Integer.parseInt(tmp.trim());
+
+ } // end try
+ catch (NumberFormatException nfe)
+ { // but it's not a valid integer - throw something else!
+ throw new XMLLoadException(namespace + ":" + attr_name + "= attribute value is not a valid integer",elt);
+
+ } // end catch
+
+ } // end getAttributeIntNS
+
+ /**
+ * Gets the value of an attribute on an Element, expressed as a Boolean. Uses the Boolean string
+ * methods on {@link com.silverwrist.util.StringUtils StringUtils} to determine the state of the attribute value.
+ *
+ * @param elt The Element to retrieve the attribute from.
+ * @param attr_name The name of the attribute to retrieve.
+ * @return The attribute value.
+ * @exception com.silverwrist.util.xml.XMLLoadException If the attribute did not exist on the element, or
+ * it could not be parsed as a Boolean.
+ * @see com.silverwrist.util.StringUtils#isBooleanTrue(java.lang.String)
+ * @see com.silverwrist.util.StringUtils#isBooleanFalse(java.lang.String)
+ */
+ public final boolean getAttributeBoolean(Element elt, String attr_name)
+ throws XMLLoadException
+ {
+ String tmp = elt.getAttribute(attr_name);
+ if (StringUtils.isEmpty(tmp))
+ throw new XMLLoadException("no " + attr_name + "= attribute found",elt);
+ if (StringUtils.isBooleanTrue(tmp))
+ return true;
+ if (StringUtils.isBooleanFalse(tmp))
+ return false;
+ throw new XMLLoadException(attr_name + "= attribute value is not a valid Boolean",elt);
+
+ } // end getAttributeBoolean
+
+ /**
+ * Gets the value of an attribute on an Element, expressed as a Boolean. Uses the Boolean string
+ * methods on {@link com.silverwrist.util.StringUtils StringUtils} to determine the state of the attribute value.
+ *
+ * @param elt The Element to retrieve the attribute from.
+ * @param attr_name The name of the attribute to retrieve.
+ * @param default_val The default value of the attribute.
+ * @return The attribute value, or the value of default_val if the attribute didn't exist.
+ * @exception com.silverwrist.util.xml.XMLLoadException If the attribute could not be parsed as a Boolean.
+ * @see com.silverwrist.util.StringUtils#isBooleanTrue(java.lang.String)
+ * @see com.silverwrist.util.StringUtils#isBooleanFalse(java.lang.String)
+ */
+ public final boolean getAttributeBoolean(Element elt, String attr_name, boolean default_val)
+ throws XMLLoadException
+ {
+ String tmp = elt.getAttribute(attr_name);
+ if (StringUtils.isEmpty(tmp))
+ return default_val;
+ if (StringUtils.isBooleanTrue(tmp))
+ return true;
+ if (StringUtils.isBooleanFalse(tmp))
+ return false;
+ throw new XMLLoadException(attr_name + "= attribute value is not a valid Boolean",elt);
+
+ } // end getAttributeBoolean
+
+ /**
+ * Gets the value of an attribute on an Element, expressed as a Boolean. Uses the Boolean string
+ * methods on {@link com.silverwrist.util.StringUtils StringUtils} to determine the state of the attribute value.
+ *
+ * @param elt The Element to retrieve the attribute from.
+ * @param namespace The namespace URI of the attribute to retrieve.
+ * @param attr_name The name of the attribute to retrieve.
+ * @param default_val The default value of the attribute.
+ * @return The attribute value, or the value of default_val if the attribute didn't exist.
+ * @exception com.silverwrist.util.xml.XMLLoadException If the attribute could not be parsed as a Boolean.
+ * @see com.silverwrist.util.StringUtils#isBooleanTrue(java.lang.String)
+ * @see com.silverwrist.util.StringUtils#isBooleanFalse(java.lang.String)
+ */
+ public final boolean getAttributeBooleanNS(Element elt, String namespace, String attr_name,
+ boolean default_val) throws XMLLoadException
+ {
+ String tmp = elt.getAttributeNS(namespace,attr_name);
+ if (StringUtils.isEmpty(tmp))
+ return default_val;
+ if (StringUtils.isBooleanTrue(tmp))
+ return true;
+ if (StringUtils.isBooleanFalse(tmp))
+ return false;
+ throw new XMLLoadException(namespace + ":" + attr_name + "= attribute value is not a valid Boolean",elt);
+
+ } // end getAttributeBooleanNS
+
+ /**
+ * Checks to make sure that the value of a given attribute is what we expect, and throws an
+ * {@link com.silverwrist.util.xml.XMLLoadException XMLLoadException} if it isn't.
+ *
+ * @param elt The Element to test the attribute of.
+ * @param attr_name The name of the attribute to test.
+ * @param attr_value The value to test the attribute against.
+ * @exception com.silverwrist.util.xml.XMLLoadException If the attribute does not exist, or its value does not match.
+ */
+ public final void verifyAttributeValue(Element elt, String attr_name, String attr_value)
+ throws XMLLoadException
+ {
+ String tmp = this.getAttribute(elt,attr_name);
+ if (!(tmp.equals(attr_value)))
+ throw new XMLLoadException("attribute " + attr_name + "= should be '" + attr_value + "', but is '"
+ + tmp + "'",elt);
+
+ } // end verifyAttributeValue
+
+ /**
+ * Checks to make sure that the value of a given attribute is what we expect, and throws an
+ * {@link com.silverwrist.util.xml.XMLLoadException XMLLoadException} if it isn't.
+ *
+ * @param elt The Element to test the attribute of.
+ * @param namespace The namespace URI of the attribute to test.
+ * @param attr_name The name of the attribute to test.
+ * @param attr_value The value to test the attribute against.
+ * @exception com.silverwrist.util.xml.XMLLoadException If the attribute does not exist, or its value does not match.
+ */
+ public final void verifyAttributeValueNS(Element elt, String namespace, String attr_name, String attr_value)
+ throws XMLLoadException
+ {
+ String tmp = this.getAttributeNS(elt,namespace,attr_name);
+ if (!(tmp.equals(attr_value)))
+ throw new XMLLoadException("attribute " + namespace + ":" + attr_name + "= should be '" + attr_value
+ + "', but is '" + tmp + "'",elt);
+
+ } // end verifyAttributeValueNS
+
+ /*--------------------------------------------------------------------------------
+ * External static operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Gets the Singleton instance of the XMLLoader object.
+ *
+ * @return The Singleton instance of the XMLLoader object.
+ */
+ public static final synchronized XMLLoader get()
+ {
+ if (self==null)
+ self = new XMLLoader();
+ return self;
+
+ } // end get
+
+} // end class XMLLoader
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/BrowserFlag.java b/src/dynamo-framework/com/silverwrist/dynamo/BrowserFlag.java
new file mode 100644
index 0000000..691856f
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/BrowserFlag.java
@@ -0,0 +1,189 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo;
+
+import java.util.*;
+import org.apache.commons.lang.enum.*;
+
+/**
+ * A type-safe enumerated type that indicates the capabilities of a browser. These objects are returned
+ * in a set by the {@link com.silverwrist.dynamo.iface.BrowserData#getBrowserFlags() BrowserData.getBrowserFlags()}
+ * method.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public final class BrowserFlag extends Enum
+{
+ /*--------------------------------------------------------------------------------
+ * The actual enumeration values
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Indicates that the browser supports frames (the <FRAMESET> and <FRAME> tags).
+ */
+ public static final BrowserFlag FRAMES = new BrowserFlag("FRAMES");
+
+ /**
+ * Indicates that the browser supports in-line frames (the <IFRAME> tag).
+ */
+ public static final BrowserFlag IFRAMES = new BrowserFlag("IFRAMES");
+
+ /**
+ * Indicates that the browser supports tables.
+ */
+ public static final BrowserFlag TABLES = new BrowserFlag("TABLES");
+
+ /**
+ * Indicates that the browser supports cookies.
+ */
+ public static final BrowserFlag COOKIES = new BrowserFlag("COOKIES");
+
+ /**
+ * Indicates that the browser supports background sounds (the <BGSOUND> tag).
+ */
+ public static final BrowserFlag BACKGROUND_SOUNDS = new BrowserFlag("BACKGROUND_SOUNDS");
+
+ /**
+ * Indicates that the browser supports client-side scripting using Visual Basic Script.
+ */
+ public static final BrowserFlag VBSCRIPT = new BrowserFlag("VBSCRIPT");
+
+ /**
+ * Indicates that the browser supports client-side scripting using JavaScript (JScript).
+ */
+ public static final BrowserFlag JAVASCRIPT = new BrowserFlag("JAVASCRIPT");
+
+ /**
+ * Indicates that the browser supports client-side Java applets.
+ */
+ public static final BrowserFlag JAVA_APPLETS = new BrowserFlag("JAVA_APPLETS");
+
+ /**
+ * Indicates that the browser supports client-side ActiveX controls.
+ */
+ public static final BrowserFlag ACTIVEX_CONTROLS = new BrowserFlag("ACTIVEX_CONTROLS");
+
+ /**
+ * Indicates that the browser supports CDF.
+ */
+ public static final BrowserFlag CDF = new BrowserFlag("CDF");
+
+ /**
+ * Indicates that this browser is an America Online client.
+ */
+ public static final BrowserFlag AOL = new BrowserFlag("AOL");
+
+ /**
+ * Indicates that this browser is a beta version.
+ */
+ public static final BrowserFlag BETA = new BrowserFlag("BETA");
+
+ /**
+ * Indicates that the browser is running on a 16-bit Windows operating system.
+ */
+ public static final BrowserFlag WIN16 = new BrowserFlag("WIN16");
+
+ /**
+ * Indicates that this browser is not a browser at all, but a "crawler," which may be used to index the
+ * site's content by a search engine, or for other (nefarious) purposes.
+ */
+ public static final BrowserFlag CRAWLER = new BrowserFlag("CRAWLER");
+
+ /**
+ * Indicates that this browser is not a browser at all, but a "stripper," which is copying the HTML of the
+ * site to another location. This may or may not be benign.
+ */
+ public static final BrowserFlag STRIPPER = new BrowserFlag("STRIPPER");
+
+ /**
+ * Indicates that the browser is a cellphone or other handheld device, possibly supporting
+ * Wireless Access Protocol (WAP).
+ */
+ public static final BrowserFlag WAP = new BrowserFlag("WAP");
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Internal constructor which creates a new element of this enumerated type.
+ *
+ * @param name The name of the BrowserFlag to be created.
+ */
+ private BrowserFlag(String name)
+ {
+ super(name);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Standard static method implementations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Gets a BrowserFlag by name.
+ *
+ * @param name The name of the BrowserFlag to get; may be null.
+ * @return The BrowserFlag object, or null if the BrowserFlag does not exist.
+ */
+ public static BrowserFlag getEnum(String name)
+ {
+ return (BrowserFlag)getEnum(BrowserFlag.class,name);
+
+ } // end getEnum
+
+ /**
+ * Gets the Map of BrowserFlag objects by name.
+ *
+ * @return The BrowserFlag object Map.
+ */
+ public static Map getEnumMap()
+ {
+ return getEnumMap(BrowserFlag.class);
+
+ } // end getEnumMap
+
+ /**
+ * Gets the List of BrowserFlag objects, in the order in which the objects are listed
+ * in the code above.
+ *
+ * @return The BrowserFlag object List.
+ */
+ public static List getEnumList()
+ {
+ return getEnumList(BrowserFlag.class);
+
+ } // end getEnumList
+
+ /**
+ * Gets an iterator over all BrowserFlag objects, in the order in which the objects are listed
+ * in the code above.
+ *
+ * @return The BrowserFlag object iterator.
+ */
+ public static Iterator iterator()
+ {
+ return iterator(BrowserFlag.class);
+
+ } // end iterator
+
+} // end class BrowserFlag
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/DynamoVersion.java b/src/dynamo-framework/com/silverwrist/dynamo/DynamoVersion.java
new file mode 100644
index 0000000..b5a3744
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/DynamoVersion.java
@@ -0,0 +1,33 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo;
+
+/**
+ * Class that holds the Dynamo version number.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public final class DynamoVersion
+{
+ /**
+ * The current version number of the Dynamo framework.
+ */
+ public static final String VERSION = "0.05";
+
+} // end class DynamoVersion
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/HttpStatusCode.java b/src/dynamo-framework/com/silverwrist/dynamo/HttpStatusCode.java
new file mode 100644
index 0000000..68d09cd
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/HttpStatusCode.java
@@ -0,0 +1,482 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo;
+
+import java.util.*;
+import org.apache.commons.lang.enum.*;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * A type-safe enumerated type that encapsulates the HTTP status codes. We use an enumerated type here
+ * so that it can be extended to support additional status codes (the ones defined, say, by WebDAV)
+ * without affecting HttpServletResponse.
+ *
The descriptions of the status codes are taken from the HTTP 1.1 Specification,
+ * RFC 2616.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public class HttpStatusCode extends ValuedEnum
+{
+ /*--------------------------------------------------------------------------------
+ * The actual enumeration values
+ *--------------------------------------------------------------------------------
+ */
+
+ // N.B.: We copy the status codes here to allow extending them independent of the codes
+ // listed in HttpServletResponse, but we point to the originals in HttpServletResponse
+ // to maintain compatibility.
+
+ /**
+ * 100 Continue. The client SHOULD continue with its request. This interim response is used to
+ * inform the client that the initial part of the request has been received and has not yet been rejected
+ * by the server. The client SHOULD continue by sending the remainder of the request or, if the request
+ * has already been completed, ignore this response. The server MUST send a final response after the
+ * request has been completed.
+ */
+ public static final HttpStatusCode I_CONTINUE =
+ new HttpStatusCode("I_CONTINUE",HttpServletResponse.SC_CONTINUE);
+
+ /**
+ * 101 Switching Protocols. The server understands and is willing to comply with the client's request,
+ * via the Upgrade message header field, for a change in the application protocol being used on this connection.
+ * The server will switch protocols to those defined by the response's Upgrade header field immediately after
+ * the empty line which terminates the 101 response.
+ */
+ public static final HttpStatusCode I_SWITCH =
+ new HttpStatusCode("I_SWITCH",HttpServletResponse.SC_SWITCHING_PROTOCOLS);
+
+ /**
+ * 200 OK. The request has succeeded. The information returned with the response is dependent on
+ * the method used in the request. (Default status code)
+ */
+ public static final HttpStatusCode S_OK =
+ new HttpStatusCode("S_OK",HttpServletResponse.SC_OK);
+
+ /**
+ * 201 Created. The request has been fulfilled and resulted in a new resource being created. The
+ * newly created resource can be referenced by the URI(s) returned in the entity of the response, with
+ * the most specific URI for the resource given by a Location header field. The response SHOULD include
+ * an entity containing a list of resource characteristics and location(s) from which the user or user
+ * agent can choose the one most appropriate. The entity format is specified by the media type given in
+ * the Content-Type header field. The origin server MUST create the resource before returning the 201
+ * status code. If the action cannot be carried out immediately, the server SHOULD respond with 202
+ * (Accepted) response instead.
+ */
+ public static final HttpStatusCode S_CREATED =
+ new HttpStatusCode("S_CREATED",HttpServletResponse.SC_CREATED);
+
+ /**
+ * 202 Accepted. The request has been accepted for processing, but the processing has not been
+ * completed. The request might or might not eventually be acted upon, as it might be disallowed when
+ * processing actually takes place.
+ */
+ public static final HttpStatusCode S_ACCEPTED =
+ new HttpStatusCode("S_ACCEPTED",HttpServletResponse.SC_ACCEPTED);
+
+ /**
+ * 203 Non-Authoritative Information. The returned metainformation in the entity-header is not the
+ * definitive set as available from the origin server, but is gathered from a local or a third-party copy.
+ * The set presented MAY be a subset or superset of the original version. For example, including local
+ * annotation information about the resource might result in a superset of the metainformation known by
+ * the origin server. Use of this response code is not required and is only appropriate when the response
+ * would otherwise be 200 (OK).
+ */
+ public static final HttpStatusCode S_NONAUTHORITATIVE =
+ new HttpStatusCode("S_NONAUTHORITATIVE",HttpServletResponse.SC_NON_AUTHORITATIVE_INFORMATION);
+
+ /**
+ * 204 No Content. The server has fulfilled the request but does not need to return an entity-body,
+ * and might want to return updated metainformation. The response MAY include new or updated metainformation
+ * in the form of entity-headers, which if present SHOULD be associated with the requested variant. If the
+ * client is a user agent, it SHOULD NOT change its document view from that which caused the request to be
+ * sent. This response is primarily intended to allow input for actions to take place without causing a
+ * change to the user agent's active document view, although any new or updated metainformation SHOULD be
+ * applied to the document currently in the user agent's active view.
+ */
+ public static final HttpStatusCode S_NODATA =
+ new HttpStatusCode("S_NODATA",HttpServletResponse.SC_NO_CONTENT);
+
+ /**
+ * 205 Reset Content. The server has fulfilled the request and the user agent SHOULD reset the document
+ * view which caused the request to be sent. This response is primarily intended to allow input for actions
+ * to take place via user input, followed by a clearing of the form in which the input is given so that the
+ * user can easily initiate another input action.
+ */
+ public static final HttpStatusCode S_RESET =
+ new HttpStatusCode("S_RESET",HttpServletResponse.SC_RESET_CONTENT);
+
+ /**
+ * 206 Partial Content. The server has fulfilled the partial GET request for the resource. The
+ * request MUST have included a Range header field indicating the desired range, and MAY have included
+ * an If-Range header field to make the request conditional.
+ */
+ public static final HttpStatusCode S_PARTIAL =
+ new HttpStatusCode("S_PARTIAL",HttpServletResponse.SC_PARTIAL_CONTENT);
+
+ /**
+ * 300 Multiple Choices. The requested resource corresponds to any one of a set of representations,
+ * each with its own specific location, and agent-driven negotiation information is being provided so that
+ * the user (or user agent) can select a preferred representation and redirect its request to that location.
+ */
+ public static final HttpStatusCode S_CHOICE =
+ new HttpStatusCode("S_CHOICE",HttpServletResponse.SC_MULTIPLE_CHOICES);
+
+ /**
+ * 301 Moved Permanently. The requested resource has been assigned a new permanent URI and any future
+ * references to this resource SHOULD use one of the returned URIs. Clients with link editing capabilities
+ * ought to automatically re-link references to the Request-URI to one or more of the new references returned
+ * by the server, where possible.
+ */
+ public static final HttpStatusCode S_MOVED =
+ new HttpStatusCode("S_MOVED",HttpServletResponse.SC_MOVED_PERMANENTLY);
+
+ /**
+ * 302 Moved Temporarily (Redirect). The requested resource resides temporarily under a different URI.
+ * Since the redirection might be altered on occasion, the client SHOULD continue to use the Request-URI for
+ * future requests.
+ */
+ public static final HttpStatusCode S_REDIRECT =
+ new HttpStatusCode("S_REDIRECT",HttpServletResponse.SC_MOVED_TEMPORARILY);
+
+ /**
+ * 303 See Other. The response to the request can be found under a different URI and SHOULD be
+ * retrieved using a GET method on that resource. This method exists primarily to allow the output of a
+ * POST-activated script to redirect the user agent to a selected resource. The new URI is not a
+ * substitute reference for the originally requested resource.
+ */
+ public static final HttpStatusCode S_SEE_OTHER =
+ new HttpStatusCode("S_SEE_OTHER",HttpServletResponse.SC_SEE_OTHER);
+
+ /**
+ * 304 Not Modified. If the client has performed a conditional GET request and access is allowed,
+ * but the document has not been modified, the server SHOULD respond with this status code.
+ */
+ public static final HttpStatusCode S_NOTMODIFIED =
+ new HttpStatusCode("S_NOTMODIFIED",HttpServletResponse.SC_NOT_MODIFIED);
+
+ /**
+ * 305 Use Proxy. The requested resource MUST be accessed through the proxy given by the Location
+ * field. The Location field gives the URI of the proxy. The recipient is expected to repeat this single
+ * request via the proxy.
+ */
+ public static final HttpStatusCode S_USE_PROXY =
+ new HttpStatusCode("S_USEPROXY",HttpServletResponse.SC_USE_PROXY);
+
+ /**
+ * 307 Temporary Redirect. The requested resource resides temporarily under a different URI.
+ * Since the redirection MAY be altered on occasion, the client SHOULD continue to use the Request-URI
+ * for future requests.
+ */
+ public static final HttpStatusCode S_REDIRECT_TEMP =
+ new HttpStatusCode("S_REDIRECT_TEMP",HttpServletResponse.SC_TEMPORARY_REDIRECT);
+
+ /**
+ * 400 Bad Request. The request could not be understood by the server due to malformed syntax. The
+ * client SHOULD NOT repeat the request without modifications.
+ */
+ public static final HttpStatusCode E_BAD_REQUEST =
+ new HttpStatusCode("E_BAD_REQUEST",HttpServletResponse.SC_BAD_REQUEST);
+
+ /**
+ * 401 Unauthorized. The request requires user authentication. The response MUST include a
+ * WWW-Authenticate header field containing a challenge applicable to the requested resource. The client
+ * MAY repeat the request with a suitable Authorization header field. If the request already included
+ * Authorization credentials, then the 401 response indicates that authorization has been refused for those
+ * credentials. If the 401 response contains the same challenge as the prior response, and the user agent
+ * has already attempted authentication at least once, then the user SHOULD be presented the entity that
+ * was given in the response, since that entity might include relevant diagnostic information.
+ */
+ public static final HttpStatusCode E_AUTH =
+ new HttpStatusCode("E_AUTH",HttpServletResponse.SC_UNAUTHORIZED);
+
+ /**
+ * 402 Payment Required. This code is reserved for future use.
+ */
+ public static final HttpStatusCode E_PAYMENT =
+ new HttpStatusCode("E_PAYMENT",HttpServletResponse.SC_PAYMENT_REQUIRED);
+
+ /**
+ * 403 Forbidden. The server understood the request, but is refusing to fulfill it. Authorization
+ * will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server
+ * wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the
+ * refusal in the entity. If the server does not wish to make this information available to the client,
+ * the status code 404 (Not Found) can be used instead.
+ */
+ public static final HttpStatusCode E_FORBIDDEN =
+ new HttpStatusCode("E_FORBIDDEN",HttpServletResponse.SC_FORBIDDEN);
+
+ /**
+ * 404 Not Found. The server has not found anything matching the Request-URI. No indication is given
+ * of whether the condition is temporary or permanent. The 410 (Gone) status code SHOULD be used if the
+ * server knows, through some internally configurable mechanism, that an old resource is permanently
+ * unavailable and has no forwarding address. This status code is commonly used when the server does not
+ * wish to reveal exactly why the request has been refused, or when no other response is applicable.
+ */
+ public static final HttpStatusCode E_NOTFOUND =
+ new HttpStatusCode("E_NOTFOUND",HttpServletResponse.SC_NOT_FOUND);
+
+ /**
+ * 405 Method Not Allowed. The method specified in the Request-Line is not allowed for the resource
+ * identified by the Request-URI. The response MUST include an Allow header containing a list of valid
+ * methods for the requested resource.
+ */
+ public static final HttpStatusCode E_METHOD =
+ new HttpStatusCode("E_METHOD",HttpServletResponse.SC_METHOD_NOT_ALLOWED);
+
+ /**
+ * 406 Not Acceptable. The resource identified by the request is only capable of generating response
+ * entities which have content characteristics not acceptable according to the accept headers sent in the request.
+ */
+ public static final HttpStatusCode E_NOTACCEPTABLE =
+ new HttpStatusCode("E_NOTACCEPTABLE",HttpServletResponse.SC_NOT_ACCEPTABLE);
+
+ /**
+ * 407 Proxy Authentication Required. This code is similar to 401 (Unauthorized), but indicates that
+ * the client must first authenticate itself with the proxy. The proxy MUST return a Proxy-Authenticate
+ * header field containing a challenge applicable to the proxy for the requested resource. The client MAY
+ * repeat the request with a suitable Proxy-Authorization header field.
+ */
+ public static final HttpStatusCode E_PROXY_AUTH =
+ new HttpStatusCode("E_PROXY_AUTH",HttpServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED);
+
+ /**
+ * 408 Request Timeout. The client did not produce a request within the time that the server was
+ * prepared to wait. The client MAY repeat the request without modifications at any later time.
+ */
+ public static final HttpStatusCode E_TIMEOUT =
+ new HttpStatusCode("E_TIMEOUT",HttpServletResponse.SC_REQUEST_TIMEOUT);
+
+ /**
+ * 409 Conflict. The request could not be completed due to a conflict with the current state of the
+ * resource. This code is only allowed in situations where it is expected that the user might be able to
+ * resolve the conflict and resubmit the request. The response body SHOULD include enough information for
+ * the user to recognize the source of the conflict. Ideally, the response entity would include enough
+ * information for the user or user agent to fix the problem; however, that might not be possible and is
+ * not required.
+ */
+ public static final HttpStatusCode E_CONFLICT =
+ new HttpStatusCode("E_CONFLICT",HttpServletResponse.SC_CONFLICT);
+
+ /**
+ * 410 Gone. The requested resource is no longer available at the server and no forwarding address
+ * is known. This condition is expected to be considered permanent. Clients with link editing capabilities
+ * SHOULD delete references to the Request-URI after user approval. If the server does not know, or has no
+ * facility to determine, whether or not the condition is permanent, the status code 404 (Not Found) SHOULD
+ * be used instead.
+ */
+ public static final HttpStatusCode E_GONE =
+ new HttpStatusCode("E_GONE",HttpServletResponse.SC_GONE);
+
+ /**
+ * 411 Length Required. The server refuses to accept the request without a defined Content-Length.
+ * The client MAY repeat the request if it adds a valid Content-Length header field containing the length
+ * of the message-body in the request message.
+ */
+ public static final HttpStatusCode E_NOLENGTH =
+ new HttpStatusCode("E_NOLENGTH",HttpServletResponse.SC_LENGTH_REQUIRED);
+
+ /**
+ * 412 Precondition Failed. The precondition given in one or more of the request-header fields
+ * evaluated to false when it was tested on the server. This response code allows the client to place
+ * preconditions on the current resource metainformation (header field data) and thus prevent the
+ * requested method from being applied to a resource other than the one intended.
+ */
+ public static final HttpStatusCode E_PRECONDITION =
+ new HttpStatusCode("E_PRECONDITION",HttpServletResponse.SC_PRECONDITION_FAILED);
+
+ /**
+ * 413 Request Entity Too Large. The server is refusing to process a request because the request
+ * entity is larger than the server is willing or able to process. The server MAY close the connection to
+ * prevent the client from continuing the request. If the condition is temporary, the server SHOULD include
+ * a Retry-After header field to indicate that it is temporary and after what time the client MAY try again.
+ */
+ public static final HttpStatusCode E_ENTITYTOOBIG =
+ new HttpStatusCode("E_ENTITYTOOBIG",HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE);
+
+ /**
+ * 414 Request URI Too Long. The server is refusing to service the request because the Request-URI is
+ * longer than the server is willing to interpret. This rare condition is only likely to occur when a client
+ * has improperly converted a POST request to a GET request with long query information, when the client has
+ * descended into a URI "black hole" of redirection (e.g., a redirected URI prefix that points to a suffix of
+ * itself), or when the server is under attack by a client attempting to exploit security holes present in
+ * some servers using fixed-length buffers for reading or manipulating the Request-URI.
+ */
+ public static final HttpStatusCode E_URITOOLONG =
+ new HttpStatusCode("E_URITOOLONG",HttpServletResponse.SC_REQUEST_URI_TOO_LONG);
+
+ /**
+ * 415 Media Type Not Supported. The server is refusing to service the request because the entity of
+ * the request is in a format not supported by the requested resource for the requested method.
+ */
+ public static final HttpStatusCode E_BAD_TYPE =
+ new HttpStatusCode("E_BAD_TYPE",HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
+
+ /**
+ * 416 Requested Range Not Satisfiable. A server SHOULD return a response with this status code if
+ * a request included a Range request-header field, and none of the range-specifier values in this field
+ * overlap the current extent of the selected resource, and the request did not include an If-Range
+ * request-header field. (For byte-ranges, this means that the first-byte-pos of all of the byte-range-spec
+ * values were greater than the current length of the selected resource.) When this status code is returned
+ * for a byte-range request, the response SHOULD include a Content-Range entity-header field specifying the
+ * current length of the selected resource. This response MUST NOT use the multipart/byteranges content-type.
+ */
+ public static final HttpStatusCode E_BAD_RANGE =
+ new HttpStatusCode("E_BAD_RANGE",HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
+
+ /**
+ * 417 Expectation Failed. The expectation given in an Expect request-header field could not be met by
+ * this server, or, if the server is a proxy, the server has unambiguous evidence that the request could not
+ * be met by the next-hop server.
+ */
+ public static final HttpStatusCode E_EXPECTATION =
+ new HttpStatusCode("E_EXPECTATION",HttpServletResponse.SC_EXPECTATION_FAILED);
+
+ /**
+ * 500 Internal Server Error. The server encountered an unexpected condition which prevented it
+ * from fulfilling the request.
+ */
+ public static final HttpStatusCode E_INTERNAL =
+ new HttpStatusCode("E_INTERNAL",HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+
+ /**
+ * 501 Not Implemented. The server does not support the functionality required to fulfill the request.
+ * This is the appropriate response when the server does not recognize the request method and is not capable
+ * of supporting it for any resource.
+ */
+ public static final HttpStatusCode E_NOTIMPL =
+ new HttpStatusCode("E_NOTIMPL",HttpServletResponse.SC_NOT_IMPLEMENTED);
+
+ /**
+ * 502 Bad Gateway. The server, while acting as a gateway or proxy, received an invalid response from
+ * the upstream server it accessed in attempting to fulfill the request.
+ */
+ public static final HttpStatusCode E_BAD_GATEWAY =
+ new HttpStatusCode("E_BAD_GATEWAY",HttpServletResponse.SC_BAD_GATEWAY);
+
+ /**
+ * 503 Service Unavailable. The server is currently unable to handle the request due to a temporary
+ * overloading or maintenance of the server. The implication is that this is a temporary condition which will
+ * be alleviated after some delay. If known, the length of the delay MAY be indicated in a Retry-After header.
+ * If no Retry-After is given, the client SHOULD handle the response as it would for a 500 response.
+ */
+ public static final HttpStatusCode E_UNAVAILABLE =
+ new HttpStatusCode("E_UNAVAILABLE",HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+
+ /**
+ * 504 Gateway Timeout. The server, while acting as a gateway or proxy, did not receive a timely
+ * response from the upstream server specified by the URI (e.g. HTTP, FTP, LDAP) or some other auxiliary
+ * server (e.g. DNS) it needed to access in attempting to complete the request.
+ */
+ public static final HttpStatusCode E_GATEWAY_TIMEOUT =
+ new HttpStatusCode("E_GATEWAY_TIMEOUT",HttpServletResponse.SC_GATEWAY_TIMEOUT);
+
+ /**
+ * 505 HTTP Version Not Supported. The server does not support, or refuses to support, the HTTP
+ * protocol version that was used in the request message. The server is indicating that it is unable or
+ * unwilling to complete the request using the same major version as the client, other than with this
+ * error message. The response SHOULD contain an entity describing why that version is not supported and
+ * what other protocols are supported by that server.
+ */
+ public static final HttpStatusCode E_BAD_VERSION =
+ new HttpStatusCode("E_BAD_VERSION",HttpServletResponse.SC_HTTP_VERSION_NOT_SUPPORTED);
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Internal constructor which creates a new element of this enumerated type.
+ *
+ * @param name The name of the HttpStatusCode to be created.
+ * @param value The numeric value to assign to the HttpStatusCode.
+ */
+ private HttpStatusCode(String name, int value)
+ {
+ super(name,value);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Standard static method implementations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Gets a HttpStatusCode by name.
+ *
+ * @param name The name of the HttpStatusCode to get; may be null.
+ * @return The HttpStatusCode object, or null if the HttpStatusCode
+ * does not exist.
+ */
+ public static HttpStatusCode getEnum(String name)
+ {
+ return (HttpStatusCode)getEnum(HttpStatusCode.class,name);
+
+ } // end getEnum
+
+ /**
+ * Gets a HttpStatusCode by numeric value.
+ *
+ * @param code The numeric value of the HttpStatusCode to get.
+ * @return The HttpStatusCode object, or null if the HttpStatusCode
+ * does not exist.
+ */
+ public static HttpStatusCode getEnum(int code)
+ {
+ return (HttpStatusCode)getEnum(HttpStatusCode.class,code);
+
+ } // end getEnum
+
+ /**
+ * Gets the Map of HttpStatusCode objects by name.
+ *
+ * @return The HttpStatusCode object Map.
+ */
+ public static Map getEnumMap()
+ {
+ return getEnumMap(HttpStatusCode.class);
+
+ } // end getEnumMap
+
+ /**
+ * Gets the List of HttpStatusCode objects, in the order in which the objects are listed
+ * in the code above.
+ *
+ * @return The HttpStatusCode object List.
+ */
+ public static List getEnumList()
+ {
+ return getEnumList(HttpStatusCode.class);
+
+ } // end getEnumList
+
+ /**
+ * Gets an iterator over all HttpStatusCode objects, in the order in which the objects are listed
+ * in the code above.
+ *
+ * @return The HttpStatusCode object iterator.
+ */
+ public static Iterator iterator()
+ {
+ return iterator(HttpStatusCode.class);
+
+ } // end iterator
+
+} // end class HttpStatusCode
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/Namespaces.java b/src/dynamo-framework/com/silverwrist/dynamo/Namespaces.java
new file mode 100644
index 0000000..99c9f53
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/Namespaces.java
@@ -0,0 +1,77 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo;
+
+/**
+ * Contains various namespaces which are used to designate objects in the global
+ * {@link com.silverwrist.dynamo.iface.ObjectProvider ObjectProvider} and other contexts.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public interface Namespaces
+{
+ /**
+ * Namespace used for objects provided by the application substrate object.
+ */
+ public static final String SUBSTRATE_NAMESPACE =
+ "http://www.silverwrist.com/NS/dynamo/2002/11/29/substrate.objects";
+
+ /**
+ * Namespace used to retrieve servlet initialization parameters.
+ */
+ public static final String SERVLET_INIT_NAMESPACE =
+ "http://www.silverwrist.com/NS/dynamo/2002/12/22/servlet.init.params";
+
+ /**
+ * Namespace used to retrieve servlet context initialization parameters.
+ */
+ public static final String SERVLET_CONTEXT_NAMESPACE =
+ "http://www.silverwrist.com/NS/dynamo/2002/12/22/servlet.context.params";
+
+ /**
+ * Namespace under which the database connections are stored.
+ */
+ public static final String DATABASE_CONNECTIONS_NAMESPACE =
+ "http://www.silverwrist.com/NS/dynamo/2002/12/08/database.connections";
+
+ /**
+ * Namespace under which the Dynamo objects are stored.
+ */
+ public static final String DYNAMO_OBJECT_NAMESPACE =
+ "http://www.silverwrist.com/NS/dynamo/2002/12/07/dynamo.objects";
+
+ /**
+ * Namespace under which the Dynamo application-level objects are stored.
+ */
+ public static final String DYNAMO_APPLICATION_NAMESPACE =
+ "http://www.silverwrist.com/NS/dynamo/2002/12/08/dynamo.application";
+
+ /**
+ * Namespace used to retrieve user information for mail messages.
+ */
+ public static final String DYNAMO_USER_INFO_NAMESPACE =
+ "http://www.silverwrist.com/NS/dynamo/2002/12/13/user.information";
+
+ /**
+ * Namespace used to designate group permissions.
+ */
+ public static final String GROUP_PERMISSIONS_NAMESPACE =
+ "http://www.silverwrist.com/NS/dynamo/2002/12/27/group.permissions";
+
+} // end interface Namespaces
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/RequestType.java b/src/dynamo-framework/com/silverwrist/dynamo/RequestType.java
new file mode 100644
index 0000000..1b954d2
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/RequestType.java
@@ -0,0 +1,142 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo;
+
+import java.util.*;
+import org.apache.commons.lang.enum.*;
+
+/**
+ * A type-safe enumerated type that indicates the type of a {@link com.silverwrist.dynamo.iface.Request Request}
+ * that comes in from the framework. It is also used to indicate the type of a
+ * {@link com.silverwrist.dynamo.iface.SessionInfo SessionInfo} object.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public final class RequestType extends Enum
+{
+ /*--------------------------------------------------------------------------------
+ * The actual enumeration values
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * A "null" request type, only used to label certain sessions.
+ *
+ * @see com.silverwrist.dynamo.util.NullSessionInfo
+ */
+ public static final RequestType _NULL = new RequestType("_NULL");
+
+ /**
+ * This RequestType is used to label the {@link com.silverwrist.dynamo.iface.Request Request} passed
+ * along with the event that is fired when the application starts up.
+ *
+ * @see com.silverwrist.dynamo.event.ApplicationEvent
+ */
+ public static final RequestType _APPLICATION = new RequestType("_APPLICATION");
+
+ /**
+ * This RequestType is used to label the {@link com.silverwrist.dynamo.iface.Request Request} passed
+ * along with the event that is fired when a new session is created.
+ *
+ * @see com.silverwrist.dynamo.event.SessionInfoEvent
+ */
+ public static final RequestType _SESSION = new RequestType("_SESSION");
+
+ /**
+ * Designates a {@link com.silverwrist.dynamo.iface.Request Request} or
+ * {@link com.silverwrist.dynamo.iface.SessionInfo SessionInfo} associated with standard HTTP requests.
+ */
+ public static final RequestType HTTP = new RequestType("HTTP");
+
+ /**
+ * Designates a {@link com.silverwrist.dynamo.iface.Request Request} or
+ * {@link com.silverwrist.dynamo.iface.SessionInfo SessionInfo} associated with XML-RPC requests, usually
+ * transmitted over HTTP.
+ */
+ public static final RequestType XMLRPC = new RequestType("XMLRPC");
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Internal constructor which creates a new element of this enumerated type.
+ *
+ * @param name The name of the RequestType to be created.
+ */
+ private RequestType(String name)
+ {
+ super(name);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Standard static method implementations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Gets a RequestType by name.
+ *
+ * @param name The name of the RequestType to get; may be null.
+ * @return The RequestType object, or null if the RequestType does not exist.
+ */
+ public static RequestType getEnum(String name)
+ {
+ return (RequestType)getEnum(RequestType.class,name);
+
+ } // end getEnum
+
+ /**
+ * Gets the Map of RequestType objects by name.
+ *
+ * @return The RequestType object Map.
+ */
+ public static Map getEnumMap()
+ {
+ return getEnumMap(RequestType.class);
+
+ } // end getEnumMap
+
+ /**
+ * Gets the List of RequestType objects, in the order in which the objects are listed
+ * in the code above.
+ *
+ * @return The RequestType object List.
+ */
+ public static List getEnumList()
+ {
+ return getEnumList(RequestType.class);
+
+ } // end getEnumList
+
+ /**
+ * Gets an iterator over all RequestType objects, in the order in which the objects are listed
+ * in the code above.
+ *
+ * @return The RequestType object iterator.
+ */
+ public static Iterator iterator()
+ {
+ return iterator(RequestType.class);
+
+ } // end iterator
+
+} // end class RequestType
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/UserInfoNamespace.java b/src/dynamo-framework/com/silverwrist/dynamo/UserInfoNamespace.java
new file mode 100644
index 0000000..7156b06
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/UserInfoNamespace.java
@@ -0,0 +1,64 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo;
+
+/**
+ * Describes the attributes used by the Dynamo mail component to retrieve user information. Also contains
+ * the name for the default authenticator and default user permissons.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public interface UserInfoNamespace
+{
+ /**
+ * The property namespace that contains the user information.
+ */
+ public static final String NAMESPACE = Namespaces.DYNAMO_USER_INFO_NAMESPACE;
+
+ /**
+ * Property name designating the user's full name.
+ */
+ public static final String ATTR_FULLNAME = "full.name";
+
+ /**
+ * Property name designating the user E-mail address.
+ */
+ public static final String ATTR_EMAIL_ADDRESS = "email.address";
+
+ /**
+ * Property name designating the numeric user ID.
+ */
+ public static final String ATTR_ID = "user.id";
+
+ /**
+ * Property name designating the user name.
+ */
+ public static final String ATTR_USERNAME = "user.name";
+
+ /**
+ * Used to designate the default hash password authenticator.
+ */
+ public static final String AUTH_DEFAULT = "default.hash.password";
+
+ /**
+ * The permission that allows user information to be edited.
+ */
+ public static final String PERM_EDIT_ALL = "edit.all";
+
+} // end interface UserInfoNamespace
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/Verb.java b/src/dynamo-framework/com/silverwrist/dynamo/Verb.java
new file mode 100644
index 0000000..a4ee2b1
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/Verb.java
@@ -0,0 +1,132 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo;
+
+import java.util.*;
+import org.apache.commons.lang.enum.*;
+
+/**
+ * A type-safe enumerated type that indicates the action of a {@link com.silverwrist.dynamo.iface.Request Request}
+ * that comes in from the framework. Verb objects correspond roughly to HTTP methods.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public final class Verb extends Enum
+{
+ /*--------------------------------------------------------------------------------
+ * The actual enumeration values
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Indicates a request to delete a resource identified by a URI. Corresponds to HTTP DELETE method.
+ */
+ public static final Verb DELETE = new Verb("DELETE"); // (standard)
+
+ /**
+ * Indicates a request to retrieve a resource identified by a URI. Corresponds to HTTP GET method.
+ */
+ public static final Verb GET = new Verb("GET"); // (standard)
+
+ /**
+ * Indicates a request to interact with a resource identified by a URI. Corresponds to HTTP POST method.
+ * All XML-RPC requests use this verb.
+ */
+ public static final Verb POST = new Verb("POST"); // (standard)
+
+ /**
+ * Indicates a request to overwrite a resource identified by a URI. Corresponds to HTTP PUT method.
+ */
+ public static final Verb PUT = new Verb("PUT"); // (standard)
+
+ /**
+ * Indicates a request to get the last modification time of a resource identified by a URI. Often associated
+ * with a HTTP GET method.
+ */
+ public static final Verb _LASTMOD = new Verb("_LASTMOD"); // extended for getLastModified
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Internal constructor which creates a new element of this enumerated type.
+ *
+ * @param name The name of the Verb to be created.
+ */
+ private Verb(String name)
+ {
+ super(name);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Standard static method implementations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Gets a Verb by name.
+ *
+ * @param name The name of the Verb to get; may be null.
+ * @return The Verb object, or null if the Verb does not exist.
+ */
+ public static Verb getEnum(String name)
+ {
+ return (Verb)getEnum(Verb.class,name);
+
+ } // end getEnum
+
+ /**
+ * Gets the Map of Verb objects by name.
+ *
+ * @return The Verb object Map.
+ */
+ public static Map getEnumMap()
+ {
+ return getEnumMap(Verb.class);
+
+ } // end getEnumMap
+
+ /**
+ * Gets the List of Verb objects, in the order in which the objects are listed
+ * in the code above.
+ *
+ * @return The Verb object List.
+ */
+ public static List getEnumList()
+ {
+ return getEnumList(Verb.class);
+
+ } // end getEnumList
+
+ /**
+ * Gets an iterator over all Verb objects, in the order in which the objects are listed
+ * in the code above.
+ *
+ * @return The Verb object iterator.
+ */
+ public static Iterator iterator()
+ {
+ return iterator(Verb.class);
+
+ } // end iterator
+
+} // end class Verb
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/WebConstants.java b/src/dynamo-framework/com/silverwrist/dynamo/WebConstants.java
new file mode 100644
index 0000000..fc173ba
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/WebConstants.java
@@ -0,0 +1,134 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo;
+
+/**
+ * Contains the names of various application, session, and request attributes and initialization parameters
+ * used by the Dynamo servlet interface.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public interface WebConstants
+{
+ /**
+ * Prefix for all Dynamo-specific application (ServletContext) attributes.
+ */
+ public static final String APPLICATION_PREFIX = "com.silverwrist.dynamo.";
+
+ /**
+ * Application attribute that records whether or not logging has been initiated.
+ */
+ public static final String LOGGING_ATTRIBUTE = APPLICATION_PREFIX + "LoggingStarted";
+
+ /**
+ * Application attribute that holds the Dynamo
+ * {@link com.silverwrist.dynamo.app.ApplicationContainer ApplicationContainer} object.
+ */
+ public static final String APPLICATION_ATTRIBUTE = APPLICATION_PREFIX + "app.ApplicationContainer";
+
+ /**
+ * Application attribute used to store the {@link com.silverwrist.dynamo.iface.MIMETypeMapper MIMETypeMapper}
+ * object created to tap into the servlet container's MIME type maps.
+ */
+ public static final String SERVLET_MAPPER_ATTRIBUTE = APPLICATION_PREFIX + "servlet.MIMETypeMapper";
+
+ /**
+ * Servlet context initialization parameter that tells Dynamo where to find the logging configuration file.
+ */
+ public static final String LOGGING_INIT_PARAM = "logging.config";
+
+ /**
+ * Servlet context initialization parameter that tells Dynamo where to find the Dynamo XML configuration file.
+ */
+ public static final String CONFIG_INIT_PARAM = "dynamo.config";
+
+ /**
+ * Prefix for all Dynamo-specific session (HttpSession) attributes.
+ */
+ public static final String SESSION_PREFIX = "com.silverwrist.dynamo.";
+
+ /**
+ * Session attribute used to store the HTTP-specific {@link com.silverwrist.dynamo.iface.SessionInfo SessionInfo}
+ * object.
+ */
+ public static final String SESSION_PARAM = SESSION_PREFIX + "session";
+
+ /**
+ * Session attribute used to store the connection-specific
+ * {@link com.silverwrist.dynamo.iface.BrowserData BrowserData} object.
+ */
+ public static final String SESSION_BROWSER_DATA_PARAM = SESSION_PREFIX + "browser.data";
+
+ /**
+ * Prefix for all Dynamo-specific request (ServletRequest) attributes.
+ */
+ public static final String REQUEST_PREFIX = "com.silverwrist.dynamo.";
+
+ /**
+ * Request attribute which stores the per-request
+ * {@link com.silverwrist.dynamo.iface.SessionInfoProvider SessionInfoProvider} object.
+ */
+ public static final String REQUEST_SESSION_PROVIDER_ATTR = REQUEST_PREFIX + "session.provider";
+
+ /**
+ * Request attribute which contains a reference to a new HTTP session that must be initialized.
+ */
+ public static final String REQUEST_SESSIONINIT_ATTR = REQUEST_PREFIX + "HTTPsession.init";
+
+ /**
+ * Request attribute which contains a reference to the connection-specific
+ * {@link com.silverwrist.dynamo.iface.BrowserData BrowserData} object.
+ */
+ public static final String REQUEST_BROWSER_DATA_ATTR = REQUEST_PREFIX + "browser.data";
+
+ /**
+ * Request attribute which contains a reference to the set of all cookies currently defined
+ * on the connection.
+ */
+ public static final String REQUEST_COOKIESET_ATTR = REQUEST_PREFIX + "browser.cookieset";
+
+ /**
+ * Request attribute containing a list of all new cookies set on the output, which cannot be set until
+ * the start of the output phase.
+ */
+ public static final String REQUEST_NEWCOOKIEHOLDER_ATTR = REQUEST_PREFIX + "browser.NewCookieHolder";
+
+ /**
+ * Request attribute containing a list of all new headers set on the output, which cannot be set until
+ * the start of the output phase.
+ */
+ public static final String REQUEST_NEWHEADERHOLDER_ATTR = REQUEST_PREFIX + "servlet.NewHeaderHolder";
+
+ /**
+ * Request attribute containing a backreference to the {@link com.silverwrist.dynamo.iface.Request Request}
+ * object for the current request.
+ */
+ public static final String REQUEST_SELF_ATTR = REQUEST_PREFIX + "request.self";
+
+ /**
+ * The HTTP header which requests a page only if it's been modified since a specific time.
+ */
+ public static final String HDR_IF_MODIFIED_SINCE = "If-Modified-Since";
+
+ /**
+ * The HTTP header which returns when a page was last modified.
+ */
+ public static final String HDR_LAST_MODIFIED = "Last-Modified";
+
+} // end interface WebConstants
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationContainer.java b/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationContainer.java
new file mode 100644
index 0000000..436ab23
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationContainer.java
@@ -0,0 +1,1292 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.app;
+
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import org.apache.commons.collections.*;
+import org.apache.log4j.Logger;
+import org.w3c.dom.*;
+import com.silverwrist.util.*;
+import com.silverwrist.util.xml.*;
+import com.silverwrist.dynamo.DynamoVersion;
+import com.silverwrist.dynamo.Namespaces;
+import com.silverwrist.dynamo.event.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.script.ScriptController;
+import com.silverwrist.dynamo.util.*;
+
+/**
+ * The main "engine" class of the Dynamo framework, which holds most of the service providers and other
+ * classes registered (usually by the defined {@link com.silverwrist.dynamo.iface.Application Application} class).
+ * Exactly one of these is created per Dynamo instance; for Dynamo Web applications, a reference to it is saved
+ * in the servlet context attributes. It is also responsible for reading and parsing the Dynamo XML configuration
+ * file and instantiating components defined therein.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public class ApplicationContainer
+ implements ResourceProvider, ResourceProviderManager, RendererRegistration, ObjectProvider,
+ EventListenerRegistration, OutputObjectFilterRegistration, QueryRenderer, PostDynamicUpdate,
+ RenderImmediate, RequestPreprocessorRegistration, ExceptionTranslatorRegistration
+{
+ /*--------------------------------------------------------------------------------
+ * Internal class recording renderer registrations and providing a
+ * "shutdown hook"
+ *--------------------------------------------------------------------------------
+ */
+
+ private class RegisteredRenderer implements ComponentShutdown
+ {
+ /*====================================================================
+ * Attributes
+ *====================================================================
+ */
+
+ private Renderer m_renderer;
+ private HashSet m_known_classes;
+
+ /*====================================================================
+ * Constructors
+ *====================================================================
+ */
+
+ RegisteredRenderer(Class klass, Renderer renderer)
+ {
+ m_renderer = renderer;
+ m_known_classes = new HashSet();
+ m_known_classes.add(klass);
+
+ } // end constructor
+
+ RegisteredRenderer(DynamicClass dclass, Renderer renderer)
+ {
+ m_renderer = renderer;
+ m_known_classes = new HashSet();
+ m_known_classes.add(dclass);
+
+ } // end constructor
+
+ /*====================================================================
+ * Implementations from interface ComponentShutdown
+ *====================================================================
+ */
+
+ public synchronized void shutdown()
+ {
+ Iterator it = m_known_classes.iterator();
+ while (it.hasNext())
+ { // remove all class rendering entries registered with this "event"
+ Object obj = it.next();
+ if (obj instanceof Class)
+ m_class_renderers.remove(obj);
+ else if (obj instanceof DynamicClass)
+ m_class_renderers.remove(obj);
+
+ } // end while
+
+ m_known_classes.clear();
+
+ } // end shutdown
+
+ /*====================================================================
+ * External operations
+ *====================================================================
+ */
+
+ public Renderer getRenderer()
+ {
+ return m_renderer;
+
+ } // end getRenderer
+
+ public synchronized void add(Class klass)
+ {
+ m_known_classes.add(klass);
+
+ } // end add
+
+ public synchronized void add(DynamicClass dclass)
+ {
+ m_known_classes.add(dclass);
+
+ } // end add
+
+ } // end class RegisteredRenderer
+
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static Logger logger = Logger.getLogger(ApplicationContainer.class);
+
+ private static final String[] SUBSTRATE_MAP_KEYS =
+ { ApplicationSubstrate.OBJ_BASE_PATH, ApplicationSubstrate.OBJ_CODE_PATH,
+ ApplicationSubstrate.OBJ_CLASSES_PATH, ApplicationSubstrate.OBJ_LIBS_PATH
+ };
+
+ private static final ApplicationListener[] APP_LISTENER_TEMPLATE = new ApplicationListener[0];
+ private static final SessionInfoListener[] SESSION_LISTENER_TEMPLATE = new SessionInfoListener[0];
+
+ private static final String TEMPLATE_CLASSNAME = "$$$BLORT$$$";
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private int m_refs; // reference count
+ private ApplicationSubstrate m_substrate; // application substrate object
+ private File m_resource_base; // base directory for resources
+ private Vector m_resource_providers = new Vector(); // resource providers
+ private LinkedList m_shutdown_list = new LinkedList(); // list of objects to shut down
+ private HashMap m_connections = new HashMap(); // list of connection pools
+ private HashMap m_objects = new HashMap(); // list of base objects
+ private Application m_application = null; // the application object
+ private Hashtable m_class_renderers = new Hashtable(); // renderers for static classes
+ private Hashtable m_dclass_renderers = new Hashtable(); // renderers for dynamic classes
+ private Vector m_application_listeners = new Vector(); // application event listeners
+ private Vector m_session_listeners = new Vector(); // session event listeners
+ private BackgroundProcessor m_background; // background processor
+ private ScriptController m_script_ctrl; // script controller
+ private ApplicationServiceManager m_app_sm; // application service manager
+ private PropertySerializationSupport m_pss; // property serialization support
+ private Set m_known_sessions; // known sessions
+ private String m_identity; // server identity
+ private Map m_rewrite_rules; // URL rewriting rules
+ private Vector m_output_filters = new Vector(); // output filters
+ private HashMap m_update_listeners = new HashMap(); // update listeners
+ private Vector m_request_preprocessors = new Vector(); // request preprocessors
+ private Vector m_exception_xlators = new Vector(); // exception translators
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates the application container.
+ *
+ * @param config_file A reference to the Dynamo XML configuration file.
+ * @param substrate A reference to the {@link com.silverwrist.dynamo.iface.ApplicationSubstrate ApplicationSubstrate}
+ * object, which provides certain services and object references to the
+ * ApplicationContainer. (Usually, this will be specific to the Dynamo application
+ * type, for example, Web application.)
+ * @exception com.silverwrist.dynamo.except.ConfigException If there is an error in the configuration which will
+ * not allow Dynamo to be initialized.
+ */
+ public ApplicationContainer(File config_file, ApplicationSubstrate substrate) throws ConfigException
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("new ApplicationContainer - config file is " + config_file.getAbsolutePath());
+ substrate.initialize();
+ m_substrate = substrate;
+ m_refs = 1;
+ m_app_sm = new ApplicationServiceManager();
+ m_pss = new PropertySerializationSupport();
+ m_known_sessions = Collections.synchronizedSet(new HashSet());
+ XMLLoader loader = XMLLoader.get();
+
+ // Initialize the init services and runtime services with defaults.
+ m_app_sm.addInitService(ResourceProvider.class,(ResourceProvider)this);
+ m_app_sm.addInitService(ResourceProviderManager.class,(ResourceProviderManager)this);
+ m_app_sm.addInitService(RendererRegistration.class,(RendererRegistration)this);
+ m_app_sm.addInitService(ObjectProvider.class,(ObjectProvider)this);
+ m_app_sm.addInitService(EventListenerRegistration.class,(EventListenerRegistration)this);
+ m_app_sm.addInitService(OutputObjectFilterRegistration.class,(OutputObjectFilterRegistration)this);
+ m_app_sm.addInitService(PropertySerializer.class,(PropertySerializer)m_pss);
+ m_app_sm.addInitService(PropertySerializerRegistration.class,(PropertySerializerRegistration)m_pss);
+ m_app_sm.addInitService(PostDynamicUpdate.class,(PostDynamicUpdate)this);
+ m_app_sm.addInitService(RequestPreprocessorRegistration.class,(RequestPreprocessorRegistration)this);
+ m_app_sm.addInitService(ExceptionTranslatorRegistration.class,(ExceptionTranslatorRegistration)this);
+
+ m_app_sm.addRuntimeService(ResourceProvider.class,(ResourceProvider)this);
+ m_app_sm.addRuntimeService(ObjectProvider.class,(ObjectProvider)this);
+ m_app_sm.addRuntimeService(EventListenerRegistration.class,(EventListenerRegistration)this);
+ m_app_sm.addRuntimeService(PropertySerializer.class,(PropertySerializer)m_pss);
+ m_app_sm.addRuntimeService(PostDynamicUpdate.class,(PostDynamicUpdate)this);
+ m_app_sm.addRuntimeService(RenderImmediate.class,(RenderImmediate)this);
+
+ m_app_sm.addOutputService(ResourceProvider.class,(ResourceProvider)this);
+ m_app_sm.addOutputService(ObjectProvider.class,(ObjectProvider)this);
+ m_app_sm.addOutputService(QueryRenderer.class,(QueryRenderer)this);
+
+ // Create initialization services interface object.
+ ServiceProvider init_svcs = m_app_sm.createInitServices();
+
+ try
+ { // load the configuration file
+ Document config_doc = loader.load(config_file,false);
+ Element root = loader.getRootElement(config_doc,"configuration");
+
+ // get the element and process it
+ Element control = loader.getSubElement(root,"control");
+ processControlSection(control);
+ m_shutdown_list.addFirst(m_background);
+ m_app_sm.addInitService(BackgroundScheduler.class,m_background);
+ m_app_sm.addRuntimeService(BackgroundScheduler.class,m_background);
+
+ // initialize some default renderers
+ m_shutdown_list.addFirst(registerRenderer(DataItem.class,new DataItemRenderer()));
+ m_shutdown_list.addFirst(registerRenderer(java.util.List.class,new ListRenderer()));
+
+ // initialize the scripting engine
+ m_script_ctrl = new ScriptController();
+ m_script_ctrl.initialize(control,init_svcs);
+ m_shutdown_list.addFirst(m_script_ctrl);
+
+ // add the scripting engine's services so they can be used by external components
+ m_app_sm.addInitService(ScriptEngineConfig.class,m_script_ctrl);
+ m_app_sm.addRuntimeService(ScriptExecute.class,m_script_ctrl);
+
+ // get all database connection configurations
+ List l = loader.getMatchingSubElements(root,"dbconnection");
+ Iterator it = l.iterator();
+ Element elt;
+ while (it.hasNext())
+ { // get each element in turn
+ elt = (Element)(it.next());
+ DBConnectionPool pool = (DBConnectionPool)createNamedObject(elt,init_svcs,DBConnectionPool.class,
+ "no.notDBPool");
+ m_connections.put(pool.getName(),pool);
+
+ } // end while
+
+ m_app_sm.addInitService(HookServiceProviders.class,m_app_sm);
+
+ // Sort the "object" definitions by priority order to determine in what order to instantiate them.
+ l = loader.getMatchingSubElements(root,"object");
+ if (!(l.isEmpty()))
+ { // copy elements into binary heap
+ it = l.iterator();
+ BinaryHeap prioheap = new BinaryHeap(l.size());
+ while (it.hasNext())
+ { // sort elements by priority
+ elt = (Element)(it.next());
+ prioheap.insert(new HeapContents(elt));
+
+ } // end while
+
+ while (prioheap.size()>0)
+ { // now remove and instantiate the elements
+ HeapContents hc = (HeapContents)(prioheap.remove());
+ NamedObject nobj = createNamedObject(hc.getElement(),init_svcs,null,null);
+ m_objects.put(nobj.getName(),nobj);
+
+ } // end while
+
+ } // end if
+
+ // Find the application definition and initialize the application.
+ elt = loader.getSubElement(root,"application");
+ m_application = (Application)createNamedObject(elt,init_svcs,Application.class,"no.notApp");
+
+ } // end try
+ catch (IOException e)
+ { // unable to read config file - send back a ConfigException
+ logger.fatal("ApplicationContainer config read failed",e);
+ ConfigException ce = new ConfigException(ApplicationContainer.class,"ApplicationContainerMessages",
+ "creation.ioError",e);
+ ce.setParameter(0,config_file.getAbsolutePath());
+ throw ce;
+
+ } // end catch
+ catch (XMLLoadException e)
+ { // XML loader failed - send back a ConfigException
+ logger.fatal("ApplicationContainer config load failed",e);
+ throw new ConfigException(e);
+
+ } // end catch
+
+ // Create the "server identity" string.
+ StringBuffer buf = new StringBuffer();
+ String app_id = m_application.getIdentity();
+ if (app_id!=null)
+ buf.append(app_id).append(' ');
+ buf.append("Dynamo/").append(DynamoVersion.VERSION);
+ m_identity = buf.toString();
+ logger.info("Server: " + m_identity);
+
+ // Fire the "application initialized" events.
+ ApplicationListener[] listeners =
+ (ApplicationListener[])(m_application_listeners.toArray(APP_LISTENER_TEMPLATE));
+ if (listeners.length>0)
+ { // call the event handlers...
+ if (logger.isDebugEnabled())
+ logger.debug("ApplicationContainer: " + listeners.length + " init handler(s) to call");
+ ApplicationEventRequest req = new ApplicationEventRequest(m_app_sm.createRuntimeServices(),true);
+ ApplicationEvent evt = new ApplicationEvent(req,m_application);
+ for (int i=0; iComponentInitialize associated with the object, or null
+ * if there is no such instance.
+ */
+ private static final ComponentInitialize getComponentInitialize(Object obj)
+ {
+ if (obj instanceof ComponentInitialize)
+ return (ComponentInitialize)obj;
+ if (obj instanceof ServiceProvider)
+ { // it may be a service provider interface
+ try
+ { // look for ComponentInitialize as a service
+ ServiceProvider sp = (ServiceProvider)obj;
+ ComponentInitialize rc = (ComponentInitialize)(sp.queryService(ComponentInitialize.class));
+ return rc;
+
+ } // end try
+ catch (NoSuchServiceException e)
+ { // do nothing here
+ } // end catch
+
+ } // end if
+
+ return null; // no dice!
+
+ } // end getComponentInitialize
+
+ /**
+ * Finds an instance of the {@link com.silverwrist.dynamo.iface.ComponentShutdown ComponentShutdown} interface
+ * associated with the given object, either through implementation of the interface, or by querying its
+ * {@link com.silverwrist.dynamo.iface.ServiceProvider ServiceProvider} implementation.
+ *
+ * @param obj The object to be queried.
+ * @return The instance of ComponentShutdown associated with the object, or null
+ * if there is no such instance.
+ */
+ private static final ComponentShutdown getComponentShutdown(Object obj)
+ {
+ if (obj instanceof ComponentShutdown)
+ return (ComponentShutdown)obj;
+ if (obj instanceof ServiceProvider)
+ { // it may be a service provider interface
+ try
+ { // look for ComponentShutdown as a service
+ ServiceProvider sp = (ServiceProvider)obj;
+ ComponentShutdown rc = (ComponentShutdown)(sp.queryService(ComponentShutdown.class));
+ return rc;
+
+ } // end try
+ catch (NoSuchServiceException e)
+ { // do nothing here
+ } // end catch
+
+ } // end if
+
+ return null; // no dice!
+
+ } // end getComponentShutdown
+
+ /**
+ * Destroys all data associated with this ApplicationContainer.
+ */
+ private final synchronized void destroy()
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("ApplicationContainer.destroy(): " + m_known_sessions.size() + " sessions to shutdown");
+ Iterator it = m_known_sessions.iterator();
+ while (it.hasNext())
+ { // shut down each session
+ ComponentShutdown cs = (ComponentShutdown)(it.next());
+ cs.shutdown();
+
+ } // end while
+
+ m_known_sessions.clear();
+
+ // Fire the "application exiting" events.
+ ApplicationListener[] listeners =
+ (ApplicationListener[])(m_application_listeners.toArray(APP_LISTENER_TEMPLATE));
+ if (logger.isDebugEnabled())
+ logger.debug("ApplicationContainer.destroy(): " + listeners.length + " exit handlers to call");
+ if (listeners.length>0)
+ { // call the event handlers...
+ ApplicationEventRequest req = new ApplicationEventRequest(m_app_sm.createRuntimeServices(),false);
+ ApplicationEvent evt = new ApplicationEvent(req,m_application);
+ for (int i=0; i0)
+ { // shut down all components in reverse order of creation
+ ComponentShutdown sd = (ComponentShutdown)(m_shutdown_list.removeFirst());
+ sd.shutdown();
+
+ } // end while
+
+ if (logger.isDebugEnabled())
+ logger.debug("ApplicationContainer.destroy(): clearing internal data structures");
+ m_connections.clear();
+ m_objects.clear();
+ m_class_renderers.clear();
+ m_dclass_renderers.clear();
+ m_application = null;
+ m_resource_providers.clear();
+ m_application_listeners.clear();
+ m_session_listeners.clear();
+
+ if (logger.isDebugEnabled())
+ logger.debug("ApplicationContainer.destroy(): terminating substrate");
+ m_substrate.terminate();
+ m_substrate = null;
+
+ } // end destroy
+
+ private final Map getSubstrateReplaceMap()
+ {
+ HashMap rc = new HashMap();
+ for (int i=0; imax_munch)
+ { // found one that munches more...save it
+ wrp = tmp;
+ max_munch = test;
+
+ } // end if
+
+ } // end while
+
+ } // end synchronized block
+
+ return wrp;
+
+ } // end locateResourceProvider
+
+ private final InputStream getResourceInternal(ComponentResName crn) throws IOException
+ {
+ File res_file = new File(m_resource_base,crn.getStringValue(0,false));
+ if (!(res_file.exists()) || res_file.isDirectory() || !(res_file.canRead()))
+ throw new NoSuchResourceException(crn.getStringValue(0,true));
+ return new FileInputStream(res_file);
+
+ } // end getResourceInternal
+
+ private final long getResourceModTimeInternal(ComponentResName crn)
+ {
+ File res_file = new File(m_resource_base,crn.getStringValue(0,false));
+ if (!(res_file.exists()) || res_file.isDirectory() || !(res_file.canRead()))
+ return 0;
+ return res_file.lastModified();
+
+ } // end getResourceModTimeInternal
+
+ private final RegisteredRenderer searchDClassRenderers(DynamicClass dclass)
+ {
+ return (RegisteredRenderer)(m_dclass_renderers.get(dclass));
+
+ } // end searchDClassRenderer
+
+ private final RegisteredRenderer searchArrayRenderers(Class klass, String template)
+ {
+ if (klass.isPrimitive() || (klass==Object.class))
+ return null; // should have been picked up already
+
+ // look at this level for the class member
+ RegisteredRenderer rc = null;
+ try
+ { // load the array class corresponding to the right depth, then check the renderer map
+ Class tmp = Class.forName(StringUtils.replace(template,TEMPLATE_CLASSNAME,klass.getName()));
+ rc = (RegisteredRenderer)(m_class_renderers.get(tmp));
+ if (rc!=null)
+ return rc;
+
+ } // end try
+ catch (ClassNotFoundException e)
+ { // this class was not found, so it can't be present
+ rc = null;
+
+ } // end catch
+
+ // Try all interfaces implemented by the object.
+ Class[] ifaces = klass.getInterfaces();
+ for (int i=0; iObjectProvider.
+ *
+ * @param namespace The namespace to interpret the name relative to.
+ * @param name The name of the object to be retrieved.
+ * @return The object reference specified.
+ */
+ public Object getObject(String namespace, String name)
+ {
+ if (namespace.equals(Namespaces.SUBSTRATE_NAMESPACE))
+ return m_substrate.getObject(namespace,name);
+
+ if (namespace.equals(Namespaces.DATABASE_CONNECTIONS_NAMESPACE))
+ { // get a database connection
+ Object rc = m_connections.get(name);
+ if (rc!=null)
+ return rc;
+
+ } // end if
+
+ if (namespace.equals(Namespaces.DYNAMO_OBJECT_NAMESPACE))
+ { // get an object
+ Object rc = m_objects.get(name);
+ if (rc!=null)
+ return rc;
+
+ } // end if
+
+ if (namespace.equals(Namespaces.DYNAMO_APPLICATION_NAMESPACE))
+ { // return one of the application data elements
+ if (name.equals("application"))
+ return m_application;
+ else if (name.equals("identity"))
+ return m_identity;
+ else if (name.equals("__container__"))
+ return this;
+
+ } // end if
+
+ throw new NoSuchObjectException("ApplicationContainer",namespace,name);
+
+ } // end getObject
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface EventListenerRegistration
+ *--------------------------------------------------------------------------------
+ */
+
+ public ComponentShutdown registerApplicationListener(ApplicationListener listener)
+ {
+ m_application_listeners.add(listener);
+ return new ShutdownVectorRemove(m_application_listeners,listener);
+
+ } // end registerApplicationListener
+
+ public ComponentShutdown registerSessionInfoListener(SessionInfoListener listener)
+ {
+ m_session_listeners.add(listener);
+ return new ShutdownVectorRemove(m_session_listeners,listener);
+
+ } // end registerSessionInfoListener
+
+ public synchronized ComponentShutdown registerDynamicUpdateListener(Class event_type,
+ DynamicUpdateListener listener)
+ {
+ if (!(DynamicUpdateEvent.class.isAssignableFrom(event_type)))
+ throw new IllegalArgumentException("event type is not valid");
+ Vector vec = (Vector)(m_update_listeners.get(event_type));
+ if (vec==null)
+ { // creatr vector for this event type
+ vec = new Vector();
+ m_update_listeners.put(event_type,vec);
+
+ } // end if
+
+ vec.add(listener);
+ return new ShutdownVectorRemove(vec,listener);
+
+ } // end registerDynamicUpdateListener
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface OutputObjectFilterRegistration
+ *--------------------------------------------------------------------------------
+ */
+
+ public ComponentShutdown registerOutputObjectFilter(OutputObjectFilter filter)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Registering new OutputObjectFilter: " + filter);
+ m_output_filters.add(filter);
+ return new ShutdownVectorRemove(m_output_filters,filter);
+
+ } // end registerOutputObjectFilter
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface QueryRenderer
+ *--------------------------------------------------------------------------------
+ */
+
+ public Renderer getRendererForObject(Object obj)
+ {
+ RegisteredRenderer rc = null;
+ if (obj instanceof DynamicObject)
+ { // this is a dynamic object - search by its dynamic class first
+ DynamicClass dclass = ((DynamicObject)obj).getDClass();
+ rc = (RegisteredRenderer)(m_dclass_renderers.get(dclass));
+ if (rc==null)
+ { // search for ancestor class, "snap" reference if possible
+ rc = searchDClassRenderers(dclass);
+ if (rc!=null)
+ { // add this class to the mapping
+ m_dclass_renderers.put(dclass,rc);
+ rc.add(dclass);
+
+ } // end if
+
+ } // end if
+
+ if (rc!=null)
+ return rc.getRenderer();
+
+ } // end if
+
+ Class klass = obj.getClass();
+ rc = (RegisteredRenderer)(m_class_renderers.get(klass));
+ if (rc==null)
+ { // search for ancestor class, "snap" reference if possible
+ rc = searchClassRenderers(klass);
+ if (rc!=null)
+ { // found it - add this class to the mapping
+ m_class_renderers.put(klass,rc);
+ rc.add(klass);
+
+ } // end if
+
+ } // end if
+
+ return ((rc==null) ? null : rc.getRenderer());
+
+ } // end getRendererForObject
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface PostDynamicUpdate
+ *--------------------------------------------------------------------------------
+ */
+
+ public void postUpdate(DynamicUpdateEvent event)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("PostDynamicUpdate: posting an event of type " + event.getClass().getName());
+ Class klass = event.getClass();
+ for (;;)
+ { // get the event listeners
+ Vector vec = (Vector)(m_update_listeners.get(klass));
+ if (vec!=null)
+ { // call the event handlers
+ Iterator it = vec.iterator();
+ while (it.hasNext())
+ ((DynamicUpdateListener)(it.next())).updateReceived(event);
+
+ } // end if
+
+ if (klass==DynamicUpdateEvent.class)
+ break;
+
+ klass = klass.getSuperclass();
+
+ } // end for (ever)
+
+ } // end postUpdate
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface RenderImmediate
+ *--------------------------------------------------------------------------------
+ */
+
+ public String renderTextObject(Object obj) throws IOException, RenderingException
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("RenderImmediate rendering an object of type " + obj.getClass().getName());
+ BufferTextRenderControl control = new BufferTextRenderControl(wrapOutputServices(null));
+ control.renderSubObject(obj);
+ return control.getData();
+
+ } // end renderTextObject
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface RequestPreprocessorRegistration
+ *--------------------------------------------------------------------------------
+ */
+
+ public ComponentShutdown registerRequestPreprocessor(RequestPreprocessor rp)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Registering new RequestPreprocessor: " + rp);
+ m_request_preprocessors.add(rp);
+ return new ShutdownVectorRemove(m_request_preprocessors,rp);
+
+ } // end registerRequestPreprocessor
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ExceptionTranslatorRegistration
+ *--------------------------------------------------------------------------------
+ */
+
+ public ComponentShutdown registerExceptionTranslator(ExceptionTranslator xlat)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Registering new ExceptionTranslator: " + xlat);
+ m_exception_xlators.add(xlat);
+ return new ShutdownVectorRemove(m_exception_xlators,xlat);
+
+ } // end registerExceptionTranslator
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Adds a reference to the reference count of the ApplicationContainer. Each servlet
+ * or other initializing component that attempts to initialize the ApplicationContainer
+ * increases its reference count by 1.
+ */
+ public synchronized void addRef()
+ {
+ ++m_refs;
+ if (logger.isDebugEnabled())
+ logger.debug("ApplicationContainer.addRef(): refcount now " + m_refs);
+
+ } // end addRef
+
+ /**
+ * Removes a reference from the reference count of the ApplicationContainer. Each servlet that
+ * references the ApplicationContainer and is destroyed decreases the reference count by 1.
+ * When the reference count reaches 0, the ApplicationContainer is destroyed.
+ *
+ * @return true if the ApplicationContainer was destroyed, false if not.
+ */
+ public synchronized boolean release()
+ {
+ if (--m_refs==0)
+ { // clean up this stuff
+ if (logger.isDebugEnabled())
+ logger.debug("ApplicationContainer.release(): refcount now 0 - destroying!");
+ destroy();
+ return true;
+
+ } // end if
+
+ if (logger.isDebugEnabled())
+ logger.debug("ApplicationContainer.release(): refcount now " + m_refs);
+
+ return false;
+
+ } // end release
+
+ /**
+ * Returns the instance of the {@link com.silverwrist.dynamo.iface.Application Application} object defined in
+ * the Dynamo XML configuration file and instantiated when the ApplicationContainer was created.
+ *
+ * @return The Application object.
+ */
+ public Application getApplication()
+ {
+ return m_application;
+
+ } // end getApplication
+
+ public ServiceProvider getInitServices()
+ {
+ return m_app_sm.createInitServices();
+
+ } // end getInitServices
+
+ public ServiceProvider wrapServices(ServiceProvider sp)
+ {
+ return m_app_sm.createRuntimeServices(sp);
+
+ } // end wrapServices
+
+ public ServiceProvider wrapOutputServices(ServiceProvider sp)
+ {
+ return m_app_sm.createOutputServices(sp);
+
+ } // end wrapOutputServices
+
+ /**
+ * Returns a list of all registered {@link com.silverwrist.dynamo.event.SessionInfoListener SessionInfoListener}
+ * objects.
+ *
+ * @return A list of all registered SessionInfoListener objects.
+ */
+ public SessionInfoListener[] getSessionListeners()
+ {
+ return (SessionInfoListener[])(m_session_listeners.toArray(SESSION_LISTENER_TEMPLATE));
+
+ } // end getSessionListeners
+
+ /**
+ * Adds a session to our list of known sessions, which will be shut down when the application container
+ * is itself destroyed.
+ *
+ * @param link The link to the session.
+ */
+ public void addSessionLink(ComponentShutdown link)
+ {
+ m_known_sessions.add(link);
+
+ } // end addSessionLink
+
+ /**
+ * Removes a session from our list of known sessions, so it will no longer be automatically shut down
+ * when the application container is itself destroyed.
+ *
+ * @param link The link to the session.
+ */
+ public void removeSessionLink(ComponentShutdown link)
+ {
+ m_known_sessions.remove(link);
+
+ } // end removeSessionLink
+
+ public void setServerHeader(HttpServletResponse resp)
+ {
+ resp.setHeader("Server",m_identity);
+
+ } // end setServerHeader
+
+ public Map getRewriteRuleMap()
+ {
+ return m_rewrite_rules;
+
+ } // end getRewriteRuleMap
+
+ public Object filterOutput(Object out, Request r) throws RenderingException
+ {
+ Object rc = out;
+ for (int i=(m_output_filters.size()-1); i>=0; i--)
+ { // look for new objects that filter this one
+ OutputObjectFilter filt = (OutputObjectFilter)(m_output_filters.get(i));
+ Object tmp_rc = filt.filterObject(rc,r);
+ if (tmp_rc!=null)
+ rc = tmp_rc;
+
+ } // end for
+
+ return rc;
+
+ } // end filterOutput
+
+ public void preprocessRequest(Request r)
+ {
+ for (int i=(m_request_preprocessors.size()-1); i>=0; i--)
+ { // preprocess the request, if we have any preprocessors installed
+ RequestPreprocessor rp = (RequestPreprocessor)(m_request_preprocessors.get(i));
+ rp.preprocessRequest(r);
+
+ } // end for
+
+ } // end preprocessRequest
+
+ public Object translateException(Request r, Exception e)
+ {
+ for (int i=(m_exception_xlators.size()-1); i>=0; i--)
+ { // try to translate exceptions
+ ExceptionTranslator xlat = (ExceptionTranslator)(m_exception_xlators.get(i));
+ Object o = xlat.translateException(r,e);
+ if (o!=null)
+ return o; // found a translation
+
+ } // end for
+
+ return e; // return the exception itself as a last resort
+
+ } // end translateException
+
+ public String translateSubstratePathName(String input)
+ {
+ return StringUtils.replaceAllVariables(input,getSubstrateReplaceMap());
+
+ } // end translateSubstratePathName
+
+} // end class ApplicationContainer
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationContainerMessages.properties b/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationContainerMessages.properties
new file mode 100644
index 0000000..17f1c65
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationContainerMessages.properties
@@ -0,0 +1,27 @@
+# The contents of this file are subject to the Mozilla Public License Version 1.1
+# (the "License"); you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at .
+#
+# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+# WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+# language governing rights and limitations under the License.
+#
+# The Original Code is the Venice Web Communities System.
+#
+# The Initial Developer of the Original Code is Eric J. Bowersox ,
+# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+# Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+#
+# Contributor(s):
+# ---------------------------------------------------------------------------------
+# This file has been localized for the en_US locale
+creation.ioError=Unable to read from configuration file {0}.
+no.classNotFound=The object class {0} was not found.
+no.createError=Unable to create new object of class {0}.
+no.notDynamo=The object class {0} is not a valid Dynamo NamedObject,
+no.notDBPool=The object class {0} is not a valid Dynamo database connection pool.
+no.notApp=The object class {0} is not a valid Dynamo application.
+resource.rootErr=The resource root directory {0} does not exist.
+mountRP.badName=Invalid mount path for resources: {0}
+mountRP.already=Resource provider already mounted on path {0}.
+registerRenderer.already=Renderer already registered for class {0}.
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationServiceManager.java b/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationServiceManager.java
new file mode 100644
index 0000000..00125f3
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationServiceManager.java
@@ -0,0 +1,675 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.app;
+
+import java.util.*;
+import org.apache.log4j.Logger;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+class ApplicationServiceManager implements HookServiceProviders
+{
+ /*--------------------------------------------------------------------------------
+ * Internal class implementing initialization services
+ *--------------------------------------------------------------------------------
+ */
+
+ private class InitServices extends BaseDelegatingServiceProvider
+ {
+ /*====================================================================
+ * Constructors
+ *====================================================================
+ */
+
+ InitServices()
+ {
+ super("Initialization Services");
+
+ } // end constructor
+
+ InitServices(ServiceProvider sp)
+ {
+ super("Initialization Services",sp);
+
+ } // end constructor
+
+ /*====================================================================
+ * Overrides from class BaseDelegatingServiceProvider
+ *====================================================================
+ */
+
+ /**
+ * Queries this object for a specified service.
+ *
+ * @param klass The class of the object that should be returned as a service.
+ * @return A service object. The service object is guaranteed to be of the class
+ * specified by klass; that is, if queryService(klass)
+ * yields some object x, then the expression klass.isInstance(x)
+ * is true.
+ * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in
+ * the specified class.
+ */
+ public Object queryService(Class klass)
+ {
+ Object rc = m_init_service_cache.get(klass);
+ if (rc!=null) // found in the cache!
+ return rc;
+
+ for (int i=(m_init_service_hooks.size()-1); i>=0; i--)
+ { // call the hooks
+ try
+ { // get hooks in reverse order of installation and try them
+ ServiceProvider sp = (ServiceProvider)(m_init_service_hooks.get(i));
+ rc = sp.queryService(klass);
+ m_init_service_cache.put(klass,rc);
+ return rc;
+
+ } // end try
+ catch (NoSuchServiceException e)
+ { // cycle around and keep trying
+ } // end catch
+
+ } // end for
+
+ rc = m_init_services.get(klass);
+ if (rc!=null)
+ { // cache the service
+ m_init_service_cache.put(klass,rc);
+ return rc;
+
+ } // end if
+
+ return super.queryService(klass);
+
+ } // end queryService
+
+ /**
+ * Queries this object for a specified service.
+ *
+ * @param klass The class of the object that should be returned as a service.
+ * @param serviceid ID for the service to be requested, to further discriminate between requests.
+ * @return A service object. The service object is guaranteed to be of the class
+ * specified by klass; that is, if queryService(klass)
+ * yields some object x, then the expression klass.isInstance(x)
+ * is true.
+ * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in
+ * the specified class.
+ */
+ public Object queryService(Class klass, String serviceid)
+ {
+ ServiceKey key = new ServiceKey(klass,serviceid);
+ Object rc = m_init_service_cache.get(key);
+ if (rc!=null)
+ return rc;
+
+ for (int i=(m_init_service_hooks.size()-1); i>=0; i--)
+ { // call the hooks
+ try
+ { // get hooks in reverse order of installation and try them
+ ServiceProvider sp = (ServiceProvider)(m_init_service_hooks.get(i));
+ rc = sp.queryService(klass,serviceid);
+ m_init_service_cache.put(key,rc);
+ return rc;
+
+ } // end try
+ catch (NoSuchServiceException e)
+ { // cycle around and keep trying
+ } // end catch
+
+ } // end for
+
+ try
+ { // call through to superclass
+ return super.queryService(klass,serviceid);
+
+ } // end try
+ catch (NoSuchServiceException e)
+ { // OK, try it without the service ID
+ rc = queryService(klass);
+ m_init_service_cache.put(key,rc);
+ return rc;
+
+ } // end catch
+
+ } // end queryService
+
+ } // end class InitServices
+
+ /*--------------------------------------------------------------------------------
+ * Internal class implementing runtime services
+ *--------------------------------------------------------------------------------
+ */
+
+ private class RuntimeServices extends BaseDelegatingServiceProvider
+ {
+ /*====================================================================
+ * Constructors
+ *====================================================================
+ */
+
+ RuntimeServices()
+ {
+ super("Application Services");
+
+ } // end constructor
+
+ RuntimeServices(ServiceProvider sp)
+ {
+ super("Application Services",sp);
+
+ } // end constructor
+
+ /*====================================================================
+ * Overrides from class BaseDelegatingServiceProvider
+ *====================================================================
+ */
+
+ /**
+ * Queries this object for a specified service.
+ *
+ * @param klass The class of the object that should be returned as a service.
+ * @return A service object. The service object is guaranteed to be of the class
+ * specified by klass; that is, if queryService(klass)
+ * yields some object x, then the expression klass.isInstance(x)
+ * is true.
+ * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in
+ * the specified class.
+ */
+ public Object queryService(Class klass)
+ {
+ Object rc = m_runtime_service_cache.get(klass);
+ if (rc!=null)
+ return rc;
+
+ for (int i=(m_runtime_service_hooks.size()-1); i>=0; i--)
+ { // call the hooks
+ try
+ { // get hooks in reverse order of installation and try them
+ ServiceProvider sp = (ServiceProvider)(m_runtime_service_hooks.get(i));
+ rc = sp.queryService(klass);
+ m_runtime_service_cache.put(klass,rc);
+ return rc;
+
+ } // end try
+ catch (NoSuchServiceException e)
+ { // cycle around and keep trying
+ } // end catch
+
+ } // end for
+
+ rc = m_runtime_services.get(klass);
+ if (rc!=null)
+ { // cache the service
+ m_runtime_service_cache.put(klass,rc);
+ return rc;
+
+ } // end if
+
+ return super.queryService(klass);
+
+ } // end queryService
+
+ /**
+ * Queries this object for a specified service.
+ *
+ * @param klass The class of the object that should be returned as a service.
+ * @param serviceid ID for the service to be requested, to further discriminate between requests.
+ * @return A service object. The service object is guaranteed to be of the class
+ * specified by klass; that is, if queryService(klass)
+ * yields some object x, then the expression klass.isInstance(x)
+ * is true.
+ * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in
+ * the specified class.
+ */
+ public Object queryService(Class klass, String serviceid)
+ {
+ ServiceKey key = new ServiceKey(klass,serviceid);
+ Object rc = m_runtime_service_cache.get(key);
+ if (rc!=null)
+ return rc;
+
+ for (int i=(m_runtime_service_hooks.size()-1); i>=0; i--)
+ { // call the hooks
+ try
+ { // get hooks in reverse order of installation and try them
+ ServiceProvider sp = (ServiceProvider)(m_runtime_service_hooks.get(i));
+ rc = sp.queryService(klass,serviceid);
+ m_runtime_service_cache.put(key,rc);
+ return rc;
+
+ } // end try
+ catch (NoSuchServiceException e)
+ { // cycle around and keep trying
+ } // end catch
+
+ } // end for
+
+ try
+ { // call through to superclass
+ return super.queryService(klass,serviceid);
+
+ } // end try
+ catch (NoSuchServiceException e)
+ { // OK, try it without the service ID
+ rc = queryService(klass);
+ m_runtime_service_cache.put(key,rc);
+ return rc;
+
+ } // end catch
+
+ } // end queryService
+
+ } // end class RuntimeServices
+
+ /*--------------------------------------------------------------------------------
+ * Internal class implementing output services
+ *--------------------------------------------------------------------------------
+ */
+
+ private class OutputServices extends BaseDelegatingServiceProvider
+ {
+ /*====================================================================
+ * Constructors
+ *====================================================================
+ */
+
+ OutputServices()
+ {
+ super("Application Output Services");
+
+ } // end constructor
+
+ OutputServices(ServiceProvider sp)
+ {
+ super("Application Output Services",sp);
+
+ } // end constructor
+
+ /*====================================================================
+ * Overrides from class BaseDelegatingServiceProvider
+ *====================================================================
+ */
+
+ /**
+ * Queries this object for a specified service.
+ *
+ * @param klass The class of the object that should be returned as a service.
+ * @return A service object. The service object is guaranteed to be of the class
+ * specified by klass; that is, if queryService(klass)
+ * yields some object x, then the expression klass.isInstance(x)
+ * is true.
+ * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in
+ * the specified class.
+ */
+ public Object queryService(Class klass)
+ {
+ Object rc = m_output_service_cache.get(klass);
+ if (rc!=null)
+ return rc;
+
+ for (int i=(m_output_service_hooks.size()-1); i>=0; i--)
+ { // call the hooks
+ try
+ { // get hooks in reverse order of installation and try them
+ ServiceProvider sp = (ServiceProvider)(m_output_service_hooks.get(i));
+ rc = sp.queryService(klass);
+ m_output_service_cache.put(klass,rc);
+ return rc;
+
+ } // end try
+ catch (NoSuchServiceException e)
+ { // cycle around and keep trying
+ } // end catch
+
+ } // end for
+
+ rc = m_output_services.get(klass);
+ if (rc!=null)
+ { // cache the service
+ m_output_service_cache.put(klass,rc);
+ return rc;
+
+ } // end if
+
+ return super.queryService(klass);
+
+ } // end queryService
+
+ /**
+ * Queries this object for a specified service.
+ *
+ * @param klass The class of the object that should be returned as a service.
+ * @param serviceid ID for the service to be requested, to further discriminate between requests.
+ * @return A service object. The service object is guaranteed to be of the class
+ * specified by klass; that is, if queryService(klass)
+ * yields some object x, then the expression klass.isInstance(x)
+ * is true.
+ * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in
+ * the specified class.
+ */
+ public Object queryService(Class klass, String serviceid)
+ {
+ ServiceKey key = new ServiceKey(klass,serviceid);
+ Object rc = m_output_service_cache.get(key);
+ if (rc!=null)
+ return rc;
+
+ for (int i=(m_output_service_hooks.size()-1); i>=0; i--)
+ { // call the hooks
+ try
+ { // get hooks in reverse order of installation and try them
+ ServiceProvider sp = (ServiceProvider)(m_output_service_hooks.get(i));
+ rc = sp.queryService(klass,serviceid);
+ m_output_service_cache.put(key,rc);
+ return rc;
+
+ } // end try
+ catch (NoSuchServiceException e)
+ { // cycle around and keep trying
+ } // end catch
+
+ } // end for
+
+ try
+ { // call through to superclass
+ return super.queryService(klass,serviceid);
+
+ } // end try
+ catch (NoSuchServiceException e)
+ { // OK, try it without the service ID
+ rc = queryService(klass);
+ m_output_service_cache.put(key,rc);
+ return rc;
+
+ } // end catch
+
+ } // end queryService
+
+ } // end class OutputServices
+
+ /*--------------------------------------------------------------------------------
+ * Internal class implementing removal of init service hook
+ *--------------------------------------------------------------------------------
+ */
+
+ private class RemoveInitServiceHook implements ComponentShutdown
+ {
+ /*====================================================================
+ * Attributes
+ *====================================================================
+ */
+
+ private ServiceProvider m_sp;
+
+ /*====================================================================
+ * Constructor
+ *====================================================================
+ */
+
+ RemoveInitServiceHook(ServiceProvider sp)
+ {
+ m_sp = sp;
+
+ } // end constructor
+
+ /*====================================================================
+ * Implementations from interface ComponentShutdown
+ *====================================================================
+ */
+
+ public void shutdown()
+ {
+ m_init_service_hooks.remove(m_sp);
+ m_init_service_cache.clear();
+
+ } // end shutdown
+
+ } // end class RemoveInitServiceHook
+
+ /*--------------------------------------------------------------------------------
+ * Internal class implementing removal of runtime service hook
+ *--------------------------------------------------------------------------------
+ */
+
+ private class RemoveRuntimeServiceHook implements ComponentShutdown
+ {
+ /*====================================================================
+ * Attributes
+ *====================================================================
+ */
+
+ private ServiceProvider m_sp;
+
+ /*====================================================================
+ * Constructor
+ *====================================================================
+ */
+
+ RemoveRuntimeServiceHook(ServiceProvider sp)
+ {
+ m_sp = sp;
+
+ } // end constructor
+
+ /*====================================================================
+ * Implementations from interface ComponentShutdown
+ *====================================================================
+ */
+
+ public void shutdown()
+ {
+ m_runtime_service_hooks.remove(m_sp);
+ m_runtime_service_cache.clear();
+
+ } // end shutdown
+
+ } // end class RemoveRuntimeServiceHook
+
+ /*--------------------------------------------------------------------------------
+ * Internal class implementing removal of output service hook
+ *--------------------------------------------------------------------------------
+ */
+
+ private class RemoveOutputServiceHook implements ComponentShutdown
+ {
+ /*====================================================================
+ * Attributes
+ *====================================================================
+ */
+
+ private ServiceProvider m_sp;
+
+ /*====================================================================
+ * Constructor
+ *====================================================================
+ */
+
+ RemoveOutputServiceHook(ServiceProvider sp)
+ {
+ m_sp = sp;
+
+ } // end constructor
+
+ /*====================================================================
+ * Implementations from interface ComponentShutdown
+ *====================================================================
+ */
+
+ public void shutdown()
+ {
+ m_output_service_hooks.remove(m_sp);
+ m_output_service_cache.clear();
+
+ } // end shutdown
+
+ } // end class RemoveOutputServiceHook
+
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static Logger logger = Logger.getLogger(ApplicationServiceManager.class);
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private Hashtable m_init_services = new Hashtable(); // initializing services
+ private Vector m_init_service_hooks = new Vector(); // hooks for initializing services
+ private Hashtable m_init_service_cache = new Hashtable(); // cache of init services
+ private Hashtable m_runtime_services = new Hashtable(); // runtime services
+ private Vector m_runtime_service_hooks = new Vector(); // hooks for runtime services
+ private Hashtable m_runtime_service_cache = new Hashtable(); // cache of runtime services
+ private Hashtable m_output_services = new Hashtable(); // output services
+ private Vector m_output_service_hooks = new Vector(); // hooks for output services
+ private Hashtable m_output_service_cache = new Hashtable(); // cache of output services
+ private InitServices m_solo_init = null; // only one "null" init service
+ private RuntimeServices m_solo_runtime = null; // only one "null" runtime service
+ private OutputServices m_solo_output = null; // only one "null" output service
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ ApplicationServiceManager()
+ { // do nothing
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface HookServiceProviders
+ *--------------------------------------------------------------------------------
+ */
+
+ public ServiceProvider getCurrentInitServices()
+ {
+ return createInitServices();
+
+ } // end getCurrentInitServices
+
+ public ServiceProvider getCurrentRuntimeServices()
+ {
+ return createRuntimeServices();
+
+ } // end getCurrentRuntimeServices
+
+ public ServiceProvider getCurrentOutputServices()
+ {
+ return createOutputServices();
+
+ } // end getCurrentOutputServices
+
+ public ComponentShutdown hookInitServiceProvider(ServiceProvider sp)
+ {
+ m_init_service_hooks.add(sp);
+ m_init_service_cache.clear();
+ return new RemoveInitServiceHook(sp);
+
+ } // end hookInitServiceProvider
+
+ public ComponentShutdown hookRuntimeServiceProvider(ServiceProvider sp)
+ {
+ m_runtime_service_hooks.add(sp);
+ m_runtime_service_cache.clear();
+ return new RemoveRuntimeServiceHook(sp);
+
+ } // end hookRuntimeServiceProvider
+
+ public ComponentShutdown hookOutputServiceProvider(ServiceProvider sp)
+ {
+ m_output_service_hooks.add(sp);
+ m_output_service_cache.clear();
+ return new RemoveOutputServiceHook(sp);
+
+ } // end hookOutputServiceProvider
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ void addInitService(Class klass, Object svc)
+ {
+ m_init_services.put(klass,svc);
+
+ } // end addInitService
+
+ void addRuntimeService(Class klass, Object svc)
+ {
+ m_runtime_services.put(klass,svc);
+
+ } // end addRuntimeService
+
+ void addOutputService(Class klass, Object svc)
+ {
+ m_output_services.put(klass,svc);
+
+ } // end addRuntimeService
+
+ ServiceProvider createInitServices()
+ {
+ if (m_solo_init==null)
+ m_solo_init = new InitServices();
+ return m_solo_init;
+
+ } // end createInitServices
+
+ ServiceProvider createInitServices(ServiceProvider sp)
+ {
+ if (sp==null)
+ return createInitServices();
+ return new InitServices(sp);
+
+ } // end createRuntimeServices
+
+ ServiceProvider createRuntimeServices()
+ {
+ if (m_solo_runtime==null)
+ m_solo_runtime = new RuntimeServices();
+ return m_solo_runtime;
+
+ } // end createRuntimeServices
+
+ ServiceProvider createRuntimeServices(ServiceProvider sp)
+ {
+ if (sp==null)
+ return createRuntimeServices();
+ return new RuntimeServices(sp);
+
+ } // end createRuntimeServices
+
+ ServiceProvider createOutputServices()
+ {
+ if (m_solo_output==null)
+ m_solo_output = new OutputServices();
+ return m_solo_output;
+
+ } // end createOutputServices
+
+ ServiceProvider createOutputServices(ServiceProvider sp)
+ {
+ if (sp==null)
+ return createOutputServices();
+ return new OutputServices(sp);
+
+ } // end createOutputServices
+
+} // end class ApplicationServiceManager
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/BackgroundProcessor.java b/src/dynamo-framework/com/silverwrist/dynamo/app/BackgroundProcessor.java
new file mode 100644
index 0000000..d44f228
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/app/BackgroundProcessor.java
@@ -0,0 +1,490 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.app;
+
+import java.util.*;
+import org.apache.log4j.Logger;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+/**
+ * A class used internally by the {@link com.silverwrist.dynamo.app.ApplicationContainer ApplicationContainer}
+ * to handle background execution of tasks. It implements the
+ * {@link com.silverwrist.dynamo.iface.BackgroundScheduler BackgroundScheduler} service.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+class BackgroundProcessor implements BackgroundScheduler, ComponentShutdown
+{
+ /*--------------------------------------------------------------------------------
+ * Internal thread class for scheduling normal-priority background tasks
+ *--------------------------------------------------------------------------------
+ */
+
+ private class NormalPriorityThread extends Thread
+ {
+ /*====================================================================
+ * Constructor
+ *====================================================================
+ */
+
+ NormalPriorityThread(int index)
+ {
+ super("BG-Normal-" + index);
+ setPriority(NORM_PRIORITY);
+
+ } // end constructor
+
+ /*====================================================================
+ * Overrides from class Thread
+ *====================================================================
+ */
+
+ public void run()
+ {
+ while (m_running)
+ { // get tasks then execute them
+ BackgroundTask task = null;
+ synchronized (m_normal_sync)
+ { // test and remove from normal queue
+ boolean get_task = true;
+ while (get_task && m_normal_queue.isEmpty())
+ { // nothing to run right now...
+ try
+ { // sleep waiting for a new background task
+ m_normal_sync.wait();
+
+ } // end try
+ catch (InterruptedException e)
+ { // don't bother getting a task
+ get_task = false;
+
+ } // end catch
+
+ } // end if
+
+ if (get_task)
+ task = (BackgroundTask)(m_normal_queue.removeFirst());
+
+ } // end synchronized block
+
+ if (task!=null)
+ { // found a task to run, now execute it
+ try
+ { // run the task
+ task.run(m_services);
+ task = null;
+
+ } // end try
+ catch (Exception e)
+ { // whoops! don't let this stop us
+ logger.warn("BackgroundTask threw exception",e);
+
+ } // end catch
+
+ } // end if
+
+ } // end while
+
+ } // end run
+
+ } // end class NormalPriorityThread
+
+ /*--------------------------------------------------------------------------------
+ * Internal thread class for scheduling low-priority background tasks
+ *--------------------------------------------------------------------------------
+ */
+
+ private class LowPriorityThread extends Thread
+ {
+ /*====================================================================
+ * Constructor
+ *====================================================================
+ */
+
+ LowPriorityThread(int index)
+ {
+ super("BG-Low-" + index);
+ setPriority(MIN_PRIORITY);
+
+ } // end constructor
+
+ /*====================================================================
+ * Overrides from class Thread
+ *====================================================================
+ */
+
+ public void run()
+ {
+ while (m_running)
+ { // get tasks then execute them
+ BackgroundTask task = null;
+ synchronized (m_lp_sync)
+ { // test and remove from normal queue
+ boolean get_task = true;
+ while (get_task && m_lp_queue.isEmpty())
+ { // nothing to run right now...
+ try
+ { // sleep waiting for a new background task
+ m_lp_sync.wait();
+
+ } // end try
+ catch (InterruptedException e)
+ { // don't bother getting a task
+ get_task = false;
+
+ } // end catch
+
+ } // end if
+
+ // Get the task we waited for.
+ if (get_task)
+ task = (BackgroundTask)(m_lp_queue.removeFirst());
+
+ } // end synchronized block
+
+ if (task!=null)
+ { // found a task to run, now execute it
+ try
+ { // run the task
+ task.run(m_services);
+ task = null;
+
+ } // end try
+ catch (Exception e)
+ { // whoops! don't let this stop us
+ logger.warn("BackgroundTask threw exception",e);
+
+ } // end catch
+
+ } // end if
+
+ } // end while
+
+ } // end run
+
+ } // end class LowPriorityThread
+
+ /*--------------------------------------------------------------------------------
+ * Internal class for timer operations
+ *--------------------------------------------------------------------------------
+ */
+
+ private class MyTimerTask extends TimerTask implements ComponentShutdown
+ {
+ /*====================================================================
+ * Attributes
+ *====================================================================
+ */
+
+ private BackgroundTask m_task;
+
+ /*====================================================================
+ * Constructor
+ *====================================================================
+ */
+
+ MyTimerTask(BackgroundTask task)
+ {
+ super();
+ m_task = task;
+
+ } // end constructor
+
+ /*====================================================================
+ * Overrides from class TimerTask
+ *====================================================================
+ */
+
+ public void run()
+ {
+ try
+ { // run the task
+ m_task.run(m_services);
+
+ } // end try
+ catch (Exception e)
+ { // whoops! don't let this stop us
+ logger.warn("BackgroundTask threw exception",e);
+
+ } // end catch
+
+ } // end run
+
+ /*====================================================================
+ * Implementations from interface ComponentShutdown
+ *====================================================================
+ */
+
+ /**
+ * Shuts down the component associated with this interface, in a component-specific manner.
+ */
+ public void shutdown()
+ {
+ cancel();
+
+ } // end shutdown
+
+ } // end class MyTimerTask
+
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static Logger logger = Logger.getLogger(BackgroundProcessor.class);
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private ServiceProvider m_services;
+ private volatile boolean m_running = true;
+ private Object m_normal_sync = new Object();
+ private LinkedList m_normal_queue = new LinkedList();
+ private Thread[] m_normal_threads;
+ private Object m_lp_sync = new Object();
+ private LinkedList m_lp_queue = new LinkedList();
+ private Thread[] m_lp_threads;
+ private Timer m_timer;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs the instance of the BackgroundProcessor internal to the
+ * {@link com.silverwrist.dynamo.app.ApplicationContainer ApplicationContainer}.
+ *
+ * @param num_normal_threads Number of "normal" threads in our runtime thread pool.
+ * @param num_lp_threads Number of "low priority" threads in our runtime thread pool.
+ * @param services The {@link com.silverwrist.dynamo.iface.ServiceProvider ServiceProvider} to be supplied
+ * to all {@link com.silverwrist.dynamo.iface.BackgroundTask BackgroundTask}s.
+ */
+ BackgroundProcessor(int num_norm_threads, int num_lp_threads, ServiceProvider services)
+ {
+ m_services = new SingletonServiceProvider("BackgroundProcessor",services,BackgroundScheduler.class,this);
+
+ // Create the normal priority background threads.
+ m_normal_threads = new Thread[num_norm_threads];
+ int i;
+ for (i=0; itrue, the task is handled by a pool of low-priority threads
+ * instead of by a pool of normal-priority threads. Low-priority threads will generally
+ * execute only after normal-priority threads, but are not guaranteed to.
+ */
+ public void runTaskLater(BackgroundTask task, boolean low_priority)
+ {
+ if (low_priority)
+ { // add to low priority queue
+ synchronized (m_lp_sync)
+ { // add item and notify a thread to wake up
+ m_lp_queue.addLast(task);
+ m_lp_sync.notify();
+
+ } // end synchronized block
+
+ } // end if
+ else
+ { // add to normal queue
+ synchronized (m_normal_sync)
+ { // add item and notify a thread to wake up
+ m_normal_queue.addLast(task);
+ m_normal_sync.notify();
+
+ } // end synchronized block
+
+ } // end else
+
+ } // end runTaskLater
+
+ /**
+ * Schedule a task to be run on a one-shot basis after a delay.
+ *
+ * @param task The task to be scheduled to run.
+ * @param delay The delay, in milliseconds, before this task is to be run. The actual delay may be longer
+ * than this.
+ * @return An instance of a {@link com.silverwrist.dynamo.iface.ComponentShutdown ComponentShutdown} object,
+ * whose {@link com.silverwrist.dynamo.iface.ComponentShutdown#shutdown() shutdown()} method may be
+ * called to abort the execution of this task at any time before it is actually run. If this is called
+ * after the task is run, it has no effect.
+ */
+ public ComponentShutdown runTaskAfter(BackgroundTask task, long delay)
+ {
+ MyTimerTask my_task = new MyTimerTask(task);
+ m_timer.schedule(my_task,delay);
+ return my_task;
+
+ } // end runTaskAfter
+
+ /**
+ * Schedule a task to be run on a one-shot basis at a certain time.
+ *
+ * @param task The task to be scheduled to run.
+ * @param when The date/time at which the task is to be run. The actual task start time may be any time
+ * after this.
+ * @return An instance of a {@link com.silverwrist.dynamo.iface.ComponentShutdown ComponentShutdown} object,
+ * whose {@link com.silverwrist.dynamo.iface.ComponentShutdown#shutdown() shutdown()} method may be
+ * called to abort the execution of this task at any time before it is actually run. If this is called
+ * after the task is run, it has no effect.
+ */
+ public ComponentShutdown runTaskAt(BackgroundTask task, Date when)
+ {
+ MyTimerTask my_task = new MyTimerTask(task);
+ m_timer.schedule(my_task,when);
+ return my_task;
+
+ } // end runTaskAt
+
+ /**
+ * Schedule a task to be run periodically, after a delay.
+ *
+ * @param task The task to be scheduled to run.
+ * @param delay The delay, in milliseconds, before this task is to be run for the first time. The actual
+ * delay may be longer than this.
+ * @param period The time, in milliseconds, between successive executions of the task. The task will be
+ * scheduled for repeated execution, delaying at least this long between executions.
+ * @return An instance of a {@link com.silverwrist.dynamo.iface.ComponentShutdown ComponentShutdown} object,
+ * whose {@link com.silverwrist.dynamo.iface.ComponentShutdown#shutdown() shutdown()} method may be
+ * called to abort the periodic execution of this task at any time.
+ */
+ public ComponentShutdown runTaskPeriodic(BackgroundTask task, long delay, long period)
+ {
+ MyTimerTask my_task = new MyTimerTask(task);
+ m_timer.schedule(my_task,delay,period);
+ return my_task;
+
+ } // end runTaskPeriodic
+
+ /**
+ * Schedule a task to be run periodically, beginning at a specified time.
+ *
+ * @param task The task to be scheduled to run.
+ * @param when The date/time at which the task is to be run for the first time. The actual task start time
+ * may be any time after this.
+ * @param period The time, in milliseconds, between successive executions of the task. The task will be
+ * scheduled for repeated execution, delaying at least this long between executions.
+ * @return An instance of a {@link com.silverwrist.dynamo.iface.ComponentShutdown ComponentShutdown} object,
+ * whose {@link com.silverwrist.dynamo.iface.ComponentShutdown#shutdown() shutdown()} method may be
+ * called to abort the periodic execution of this task at any time.
+ */
+ public ComponentShutdown runTaskPeriodic(BackgroundTask task, Date start, long period)
+ {
+ MyTimerTask my_task = new MyTimerTask(task);
+ m_timer.schedule(my_task,start,period);
+ return my_task;
+
+ } // end runTaskPeriodic
+
+ /**
+ * Schedule a task to be run periodically, after a delay.
+ *
+ * @param task The task to be scheduled to run.
+ * @param delay The delay, in milliseconds, before this task is to be run for the first time. The actual
+ * delay may be longer than this.
+ * @param period The time, in milliseconds, between successive executions of the task. The task will be
+ * scheduled for repeated execution, with the task being started with roughly this many
+ * milliseconds between each start attempt. If execution is delayed, this task will try to
+ * "catch up" by scheduling executions more frequently.
+ * @return An instance of a {@link com.silverwrist.dynamo.iface.ComponentShutdown ComponentShutdown} object,
+ * whose {@link com.silverwrist.dynamo.iface.ComponentShutdown#shutdown() shutdown()} method may be
+ * called to abort the periodic execution of this task at any time.
+ */
+ public ComponentShutdown runTaskFixedRate(BackgroundTask task, long delay, long period)
+ {
+ MyTimerTask my_task = new MyTimerTask(task);
+ m_timer.scheduleAtFixedRate(my_task,delay,period);
+ return my_task;
+
+ } // end runTaskFixedRate
+
+ /**
+ * Schedule a task to be run periodically, beginning at a specified time.
+ *
+ * @param task The task to be scheduled to run.
+ * @param when The date/time at which the task is to be run for the first time. The actual task start time
+ * may be any time after this.
+ * @param period The time, in milliseconds, between successive executions of the task. The task will be
+ * scheduled for repeated execution, with the task being started with roughly this many
+ * milliseconds between each start attempt. If execution is delayed, this task will try to
+ * "catch up" by scheduling executions more frequently.
+ * @return An instance of a {@link com.silverwrist.dynamo.iface.ComponentShutdown ComponentShutdown} object,
+ * whose {@link com.silverwrist.dynamo.iface.ComponentShutdown#shutdown() shutdown()} method may be
+ * called to abort the periodic execution of this task at any time.
+ */
+ public ComponentShutdown runTaskFixedRate(BackgroundTask task, Date start, long period)
+ {
+ MyTimerTask my_task = new MyTimerTask(task);
+ m_timer.scheduleAtFixedRate(my_task,start,period);
+ return my_task;
+
+ } // end runTaskFixedRate
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ComponentShutdown
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Shuts down the BackgroundProcessor, stopping all its associated threads and tasks.
+ */
+ public void shutdown()
+ {
+ m_timer.cancel();
+ m_running = false;
+ int i;
+ for (i=0; i.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.app;
+
+import com.silverwrist.util.*;
+import com.silverwrist.dynamo.except.*;
+
+class ComponentResName
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private String[] m_components;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ ComponentResName(String resource_path)
+ {
+ if (!(resource_path.startsWith("/")))
+ throw new NoSuchResourceException(resource_path);
+ m_components = StringUtils.split(resource_path.substring(1),"/");
+ if ((m_components==null) || (m_components.length==0))
+ throw new NoSuchResourceException(resource_path);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class Object
+ *--------------------------------------------------------------------------------
+ */
+
+ public boolean equals(Object obj)
+ {
+ if ((obj==null) || !(obj instanceof ComponentResName))
+ return false;
+ ComponentResName other = (ComponentResName)obj;
+ if (m_components.length!=other.m_components.length)
+ return false;
+ return (getMatchCount(other)==m_components.length);
+
+ } // end equals
+
+ public int hashCode()
+ {
+ int rc = 0;
+ for (int i=0; i.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.app;
+
+import java.util.*;
+import org.w3c.dom.*;
+import com.silverwrist.util.xml.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+
+public class ConnectionManager implements NamedObject, ComponentInitialize, ComponentShutdown
+{
+ /*--------------------------------------------------------------------------------
+ * Internal class implementing the initialization service hook
+ *--------------------------------------------------------------------------------
+ */
+
+ private class InitService implements ServiceProvider, ConnectionFrontEnd, ConnectionBackEnd
+ {
+ /*====================================================================
+ * Constructor
+ *====================================================================
+ */
+
+ InitService()
+ { // do nothing
+ } // end constructor
+
+ /*====================================================================
+ * Implementations from interface ServiceProvider
+ *====================================================================
+ */
+
+ /**
+ * Queries this object for a specified service.
+ *
+ * @param klass The class of the object that should be returned as a service.
+ * @return A service object. The service object is guaranteed to be of the class
+ * specified by klass; that is, if queryService(klass)
+ * yields some object x, then the expression klass.isInstance(x)
+ * is true.
+ * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in
+ * the specified class.
+ */
+ public Object queryService(Class klass)
+ {
+ if (klass==ConnectionFrontEnd.class)
+ return (ConnectionFrontEnd)this;
+ if (klass==ConnectionBackEnd.class)
+ return (ConnectionBackEnd)this;
+ throw new NoSuchServiceException("ConnectionManager.InitService",klass);
+
+ } // end queryService
+
+ /**
+ * Queries this object for a specified service.
+ *
+ * @param klass The class of the object that should be returned as a service.
+ * @param serviceid ID for the service to be requested, to further discriminate between requests.
+ * @return A service object. The service object is guaranteed to be of the class
+ * specified by klass; that is, if queryService(klass)
+ * yields some object x, then the expression klass.isInstance(x)
+ * is true.
+ * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in
+ * the specified class.
+ */
+ public Object queryService(Class klass, String serviceid)
+ {
+ if (klass==ConnectionFrontEnd.class)
+ return (ConnectionFrontEnd)this;
+ if (klass==ConnectionBackEnd.class)
+ return (ConnectionBackEnd)this;
+ throw new NoSuchServiceException("ConnectionManager.InitService",klass,serviceid);
+
+ } // end queryService
+
+ /*====================================================================
+ * Implementations from interface ConnectionFrontEnd
+ *====================================================================
+ */
+
+ public Object getInterface(String connection_point, Class expected_class) throws ConfigException
+ {
+ return getConnectionPoint(connection_point).getInterface(expected_class);
+
+ } // end getInterface
+
+ /*====================================================================
+ * Implementations from interface ConnectionBackEnd
+ *====================================================================
+ */
+
+ public void connectObject(String connection_point, Object object) throws ConfigException
+ {
+ getConnectionPoint(connection_point).connectObject(object);
+
+ } // end connectObject
+
+ } // end class InitService
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private String m_name;
+ private Hashtable m_connection_points = new Hashtable();
+ private ComponentShutdown m_shutdown_hook;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public ConnectionManager()
+ { // do nothing
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
+
+ private final ConnectionPoint getConnectionPoint(String name) throws ConfigException
+ {
+ ConnectionPoint rc = (ConnectionPoint)(m_connection_points.get(name));
+ if (rc!=null)
+ return rc;
+ ConfigException ce = new ConfigException(ConnectionPoint.class,"ConnectionMessages","cpoint.notFound");
+ ce.setParameter(0,name);
+ throw ce;
+
+ } // end getConnectionPoint
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface NamedObject
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getName()
+ {
+ return m_name;
+
+ } // end getName
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ComponentInitialize
+ *--------------------------------------------------------------------------------
+ */
+
+ public void initialize(Element config_root, ServiceProvider services) throws ConfigException
+ {
+ XMLLoader loader = XMLLoader.get();
+ try
+ { // verify the right node name
+ loader.verifyNodeName(config_root,"object");
+
+ // get the object's name
+ m_name = loader.getAttribute(config_root,"name");
+
+ // get the connection points list and try to load them
+ List l = loader.getMatchingSubElements(config_root,"connection-point");
+ Iterator it = l.iterator();
+ while (it.hasNext())
+ { // create the connection points
+ Element elt = (Element)(it.next());
+ ConnectionPoint cpoint = new ConnectionPoint(elt);
+ m_connection_points.put(cpoint.getName(),cpoint);
+
+ } // end while
+
+ } // end try
+ catch (XMLLoadException e)
+ { // error loading XML config data
+ throw new ConfigException(e);
+
+ } // end catch
+
+ // Hook the init service provider to provide our services.
+ HookServiceProviders hooker = (HookServiceProviders)(services.queryService(HookServiceProviders.class));
+ m_shutdown_hook = hooker.hookInitServiceProvider(new InitService());
+
+ } // end initialize
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ComponentShutdown
+ *--------------------------------------------------------------------------------
+ */
+
+ public void shutdown()
+ {
+ m_shutdown_hook.shutdown();
+
+ Iterator it = m_connection_points.values().iterator();
+ while (it.hasNext())
+ { // shut down those connection points
+ ComponentShutdown cs = (ComponentShutdown)(it.next());
+ cs.shutdown();
+
+ } // end while
+
+ m_connection_points.clear();
+
+ } // end shutdown
+
+} // end class ConnectionManager
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/ConnectionMessages.properties b/src/dynamo-framework/com/silverwrist/dynamo/app/ConnectionMessages.properties
new file mode 100644
index 0000000..e0b4242
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/app/ConnectionMessages.properties
@@ -0,0 +1,23 @@
+# The contents of this file are subject to the Mozilla Public License Version 1.1
+# (the "License"); you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at .
+#
+# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+# WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+# language governing rights and limitations under the License.
+#
+# The Original Code is the Venice Web Communities System.
+#
+# The Initial Developer of the Original Code is Eric J. Bowersox ,
+# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+# Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+#
+# Contributor(s):
+# ---------------------------------------------------------------------------------
+# This file has been localized for the en_US locale
+cpoint.noInterface=Unable to find the connection point interface class "{0}".
+cpoint.notValid=The connection point class "{0}" is not a valid interface.
+iface.type=Connection point "{0}"'s interface type {1} cannot be assigned to the desired type {2}.
+connect.already=The connection point "{0}" has already been connected.
+connect.wrongType=The connection point "{0}" expects to connect to an object of type {1}.
+cpoint.notFound=No connection point "{0}" defined.
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/ConnectionPoint.java b/src/dynamo-framework/com/silverwrist/dynamo/app/ConnectionPoint.java
new file mode 100644
index 0000000..91d35e3
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/app/ConnectionPoint.java
@@ -0,0 +1,179 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.app;
+
+import java.lang.reflect.*;
+import org.w3c.dom.*;
+import com.silverwrist.util.xml.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+
+class ConnectionPoint implements NamedObject, InvocationHandler, ComponentShutdown
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private String m_name; // name of this connection point
+ private Class m_interface; // interface associated with this connection point
+ private Object m_proxy_obj; // proxy object that provides the "head end" of the cpoint
+ private Object m_target_obj = null; // object on the "tail end" of the cpoint
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ ConnectionPoint(Element config) throws ConfigException
+ {
+ XMLLoader loader = XMLLoader.get();
+ String iface_name = null;
+ try
+ { // verify the right node name
+ loader.verifyNodeName(config,"connection-point");
+
+ // get the connection point's name
+ m_name = loader.getAttribute(config,"name");
+
+ // get the interface represented by this proxy
+ iface_name = loader.getAttribute(config,"interface");
+ m_interface = Class.forName(iface_name);
+ if (!(m_interface.isInterface()))
+ { // the class name does not specify an interface
+ ConfigException ce = new ConfigException(ConnectionPoint.class,"ConnectionMessages",
+ "cpoint.notValid");
+ ce.setParameter(0,iface_name);
+ throw ce;
+
+ } // end if
+
+ // Create the proxy object.
+ Class[] arg = new Class[1];
+ arg[0] = m_interface;
+ m_proxy_obj = Proxy.newProxyInstance(m_interface.getClassLoader(),arg,this);
+
+ } // end try
+ catch (XMLLoadException e)
+ { // error loading XML config data
+ throw new ConfigException(e);
+
+ } // end catch
+ catch (ClassNotFoundException e)
+ { // unable to find the interface
+ ConfigException ce = new ConfigException(ConnectionPoint.class,"ConnectionMessages",
+ "cpoint.noInterface",e);
+ ce.setParameter(0,iface_name);
+ throw ce;
+
+ } // end catch
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface NamedObject
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getName()
+ {
+ return m_name;
+
+ } // end getName
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface InvocationHandler
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ if (m_target_obj==null)
+ throw new ProxyException(new NullPointerException("target not yet connected for " + m_name + "/"
+ + m_interface.getName()));
+ try
+ { // invoke the method on the real target!
+ return method.invoke(m_target_obj,args);
+
+ } // end try
+ catch (IllegalAccessException e)
+ { // turn into the runtime ProxyException
+ throw new ProxyException(e);
+
+ } // end catch
+ catch (InvocationTargetException e)
+ { // "unwrap" this exception type and throw it
+ throw e.getCause();
+
+ } // end catch
+
+ } // end invoke
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ComponentShutdown
+ *--------------------------------------------------------------------------------
+ */
+
+ public void shutdown()
+ {
+ m_proxy_obj = null;
+ m_target_obj = null;
+
+ } // end shutdown
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ Object getInterface(Class expected_class) throws ConfigException
+ {
+ if (expected_class.isAssignableFrom(m_interface))
+ return m_proxy_obj;
+ ConfigException ce = new ConfigException(ConnectionPoint.class,"ConnectionMessages","iface.type");
+ ce.setParameter(0,m_name);
+ ce.setParameter(1,m_interface.getName());
+ ce.setParameter(2,expected_class.getName());
+ throw ce;
+
+ } // end getInterface
+
+ synchronized void connectObject(Object obj) throws ConfigException
+ {
+ if (m_target_obj!=null)
+ { // this connection point has already been connected
+ ConfigException ce = new ConfigException(ConnectionPoint.class,"ConnectionMessages","connect.already");
+ ce.setParameter(0,m_name);
+ throw ce;
+
+ } // end if
+
+ if (!(m_interface.isInstance(obj)))
+ { // the object is of the wrong type
+ ConfigException ce = new ConfigException(ConnectionPoint.class,"ConnectionMessages","connect.wrongType");
+ ce.setParameter(0,m_name);
+ ce.setParameter(1,m_interface.getName());
+ throw ce;
+
+ } // end if
+
+ m_target_obj = obj;
+
+ } // end connectObject
+
+} // end class ConnectionPoint
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/DataItemRenderer.java b/src/dynamo-framework/com/silverwrist/dynamo/app/DataItemRenderer.java
new file mode 100644
index 0000000..5790572
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/app/DataItemRenderer.java
@@ -0,0 +1,52 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.app;
+
+import java.io.*;
+import com.silverwrist.util.*;
+import com.silverwrist.dynamo.except.RenderingException;
+import com.silverwrist.dynamo.iface.*;
+
+class DataItemRenderer implements BinaryRenderer
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ DataItemRenderer()
+ { // do nothing
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface BinaryRenderer
+ *--------------------------------------------------------------------------------
+ */
+
+ public void render(Object obj, BinaryRenderControl control) throws IOException, RenderingException
+ {
+ DataItem di = (DataItem)obj;
+ control.setContentType(di.getMimeType());
+ control.setContentLength(di.getSize());
+ OutputStream stm = control.getStream();
+ IOUtils.copy(di.getDataStream(),stm);
+ stm.flush();
+
+ } // end render
+
+} // end class DataItemRenderer
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/HeapContents.java b/src/dynamo-framework/com/silverwrist/dynamo/app/HeapContents.java
new file mode 100644
index 0000000..e1a07a3
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/app/HeapContents.java
@@ -0,0 +1,88 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.app;
+
+import org.w3c.dom.Element;
+import com.silverwrist.util.xml.*;
+
+class HeapContents implements Comparable
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ Element m_elt; // element we're sorting
+ int m_priority; // its priority
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ HeapContents(Element elt) throws XMLLoadException
+ {
+ m_elt = elt;
+ m_priority = XMLLoader.get().getAttributeInt(elt,"priority",0);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class Object
+ *--------------------------------------------------------------------------------
+ */
+
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof HeapContents))
+ return false;
+ HeapContents other = (HeapContents)o;
+ return (m_priority==other.m_priority);
+
+ } // end equals
+
+ public int hashCode()
+ {
+ return m_priority;
+
+ } // end hashCode
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface Comparable
+ *--------------------------------------------------------------------------------
+ */
+
+ public int compareTo(Object o)
+ {
+ HeapContents other = (HeapContents)o; // may throw ClassCastException
+ return m_priority - other.m_priority;
+
+ } // end compareTo
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ Element getElement()
+ {
+ return m_elt;
+
+ } // end getElement
+
+} // end class HeapContents
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/ListRenderer.java b/src/dynamo-framework/com/silverwrist/dynamo/app/ListRenderer.java
new file mode 100644
index 0000000..4075d2e
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/app/ListRenderer.java
@@ -0,0 +1,50 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.app;
+
+import java.io.IOException;
+import java.util.*;
+import com.silverwrist.dynamo.except.RenderingException;
+import com.silverwrist.dynamo.iface.*;
+
+class ListRenderer implements TextRenderer
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ ListRenderer()
+ { // do nothing
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface TextRenderer
+ *--------------------------------------------------------------------------------
+ */
+
+ public void render(Object obj, TextRenderControl control) throws IOException, RenderingException
+ {
+ List list = (List)obj;
+ Iterator it = list.iterator();
+ while (it.hasNext())
+ control.renderSubObject(it.next());
+
+ } // end render
+
+} // end class ListRenderer
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/PropertySerializationSupport.java b/src/dynamo-framework/com/silverwrist/dynamo/app/PropertySerializationSupport.java
new file mode 100644
index 0000000..bcff801
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/app/PropertySerializationSupport.java
@@ -0,0 +1,270 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.app;
+
+import java.text.*;
+import java.util.*;
+import com.silverwrist.util.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+class PropertySerializationSupport implements PropertySerializer, PropertySerializerRegistration
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final Map SIMPLE_TYPE_SERIALIZE;
+
+ private static final DateFormat s_iso8601;
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private static Vector m_extern_calls = new Vector();
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ PropertySerializationSupport()
+ { // do nothing
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
+
+ private final String builtinSerialize(Object value)
+ {
+ String prefix = (String)(SIMPLE_TYPE_SERIALIZE.get(value.getClass()));
+ if (prefix!=null)
+ return prefix + value.toString();
+
+ if (value instanceof Boolean)
+ return (((Boolean)value).booleanValue() ? "Y" : "Z");
+
+ if (value instanceof java.util.Date)
+ return "T" + s_iso8601.format((java.util.Date)value);
+
+ if (value instanceof TimeZone)
+ return "_TZ:" + ((TimeZone)value).getID();
+
+ if (value instanceof Language)
+ return "_LANG:" + ((Language)value).getCode();
+
+ if (value instanceof Country)
+ return "_CTRY:" + ((Country)value).getCode();
+
+ if (value instanceof OptionSet)
+ return "_OS:" + ((OptionSet)value).asString();
+
+ return null;
+
+ } // end builtInSerialize
+
+ private final Object extendedDecode(String s)
+ {
+ if (s.startsWith("_LOC:"))
+ { // need to break down
+ s = s.substring(5);
+ int p = s.indexOf('_');
+ if (p>=0)
+ { // language + country, maybe + variant
+ String language = s.substring(0,p);
+ s = s.substring(p+1);
+ p = s.indexOf('_');
+ if (p>=0)
+ return new Locale(language,s.substring(0,p),s.substring(p+1));
+ else
+ return new Locale(language,s);
+
+ } // end if
+ else // just language
+ return new Locale(s);
+
+ } // end if
+ else if (s.startsWith("_TZ:"))
+ return TimeZone.getTimeZone(s.substring(4));
+ else if (s.startsWith("_LANG:"))
+ return International.get().getLanguageForCode(s.substring(6));
+ else if (s.startsWith("_CTRY:"))
+ return International.get().getCountryForCode(s.substring(6));
+ else if (s.startsWith("_OS:"))
+ return new OptionSet(s.substring(4));
+ else
+ return null;
+
+ } // end extendedDecode
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface PropertySerializer
+ *--------------------------------------------------------------------------------
+ */
+
+ public String serializeProperty(Object value)
+ {
+ if (value==null)
+ return null;
+
+ String rc = builtinSerialize(value);
+ if (rc!=null)
+ return rc;
+
+ Iterator it = m_extern_calls.iterator();
+ while (it.hasNext())
+ { // try the external serializers
+ PropertySerializer psz = (PropertySerializer)(it.next());
+ rc = psz.serializeProperty(value);
+ if (rc!=null)
+ return "." + rc;
+
+ } // end while
+
+ return null; // cannot serialize
+
+ } // end serializeProperty
+
+ public Object deserializeProperty(String value)
+ {
+ if (value==null)
+ return null;
+
+ try
+ { // the first character is the flag...
+ switch (value.charAt(0))
+ {
+ case 'B':
+ return new Byte(value.substring(1));
+
+ case 'C':
+ return new Character(value.charAt(1));
+
+ case 'D':
+ return new Double(value.substring(1));
+
+ case 'F':
+ return new Float(value.substring(1));
+
+ case 'I':
+ return new Integer(value.substring(1));
+
+ case 'J':
+ return new Long(value.substring(1));
+
+ case 'S':
+ return new Short(value.substring(1));
+
+ case 'T':
+ return s_iso8601.parse(value.substring(1));
+
+ case 'Y':
+ return Boolean.TRUE;
+
+ case 'Z':
+ return Boolean.FALSE;
+
+ case '!':
+ return value.substring(1);
+
+ case '_':
+ return extendedDecode(value);
+
+ case '.':
+ { // run through the external decoders
+ String s = value.substring(1);
+ Iterator it = m_extern_calls.iterator();
+ while (it.hasNext())
+ { // try the external serializers
+ PropertySerializer psz = (PropertySerializer)(it.next());
+ Object rc = psz.deserializeProperty(s);
+ if (rc!=null)
+ return rc;
+
+ } // end while
+
+ } // end case
+ break;
+
+ default:
+ break;
+
+ } // end switch
+
+ } // end try
+ catch (ParseException e)
+ { // if we threw this, we're h0s3d anyway
+ return null;
+
+ } // end catch
+
+ return null;
+
+ } // end deserializeProperty
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface PropertySerializerRegistration
+ *--------------------------------------------------------------------------------
+ */
+
+ public ComponentShutdown registerPropertySerializer(PropertySerializer psz)
+ {
+ m_extern_calls.add(psz);
+ return new ShutdownVectorRemove(m_extern_calls,psz);
+
+ } // end registerPropertySerializer
+
+ /*--------------------------------------------------------------------------------
+ * Static initializer
+ *--------------------------------------------------------------------------------
+ */
+
+ static
+ {
+ HashMap tmp = new HashMap();
+ tmp.put(Byte.class,"B");
+ tmp.put(Byte.TYPE,"B");
+ tmp.put(Character.class,"C");
+ tmp.put(Character.TYPE,"C");
+ tmp.put(Double.class,"D");
+ tmp.put(Double.TYPE,"D");
+ tmp.put(Float.class,"F");
+ tmp.put(Float.TYPE,"F");
+ tmp.put(Integer.class,"I");
+ tmp.put(Integer.TYPE,"I");
+ tmp.put(Long.class,"J");
+ tmp.put(Long.TYPE,"J");
+ tmp.put(Short.class,"S");
+ tmp.put(Short.TYPE,"S");
+ tmp.put(String.class,"!");
+ tmp.put(StringBuffer.class,"!");
+ tmp.put(Locale.class,"_LOC:");
+ SIMPLE_TYPE_SERIALIZE = Collections.unmodifiableMap(tmp);
+
+ SimpleDateFormat iso = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
+ iso.setCalendar(new GregorianCalendar(new SimpleTimeZone(0,"UTC")));
+ s_iso8601 = iso;
+
+ } // end static initializer
+
+} // end class PropertySerializationSupport
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/RewriteRule.java b/src/dynamo-framework/com/silverwrist/dynamo/app/RewriteRule.java
new file mode 100644
index 0000000..bea9837
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/app/RewriteRule.java
@@ -0,0 +1,71 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.app;
+
+import org.w3c.dom.*;
+import com.silverwrist.util.xml.*;
+
+public class RewriteRule
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private String m_name;
+ private boolean m_encode;
+ private String m_template;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ RewriteRule(Element elt) throws XMLLoadException
+ {
+ XMLLoader loader = XMLLoader.get();
+ m_name = loader.getAttribute(elt,"type").trim().toUpperCase();
+ m_encode = loader.getAttributeBoolean(elt,"encode");
+ m_template = loader.getText(elt);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Public getters
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getName()
+ {
+ return m_name;
+
+ } // end getName
+
+ public boolean getEncode()
+ {
+ return m_encode;
+
+ } // end getEncode
+
+ public String getTemplate()
+ {
+ return m_template;
+
+ } // end getTemplate
+
+} // end class RewriteRule
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/ServiceKey.java b/src/dynamo-framework/com/silverwrist/dynamo/app/ServiceKey.java
new file mode 100644
index 0000000..1eeeddb
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/app/ServiceKey.java
@@ -0,0 +1,62 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.app;
+
+class ServiceKey
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private Class m_class;
+ private String m_serviceid;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ ServiceKey(Class klass, String serviceid)
+ {
+ m_class = klass;
+ m_serviceid = serviceid;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class Object
+ *--------------------------------------------------------------------------------
+ */
+
+ public boolean equals(Object obj)
+ {
+ if ((obj==null) || !(obj instanceof ServiceKey))
+ return false;
+ ServiceKey other = (ServiceKey)obj;
+ return (m_class==other.m_class) && m_serviceid.equals(other.m_serviceid);
+
+ } // end equals
+
+ public int hashCode()
+ {
+ return m_class.hashCode() ^ m_serviceid.hashCode();
+
+ } // end hashCode
+
+} // end class ServiceKey
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/WrappedResourceProvider.java b/src/dynamo-framework/com/silverwrist/dynamo/app/WrappedResourceProvider.java
new file mode 100644
index 0000000..c2346be
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/app/WrappedResourceProvider.java
@@ -0,0 +1,98 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.app;
+
+import java.io.InputStream;
+import java.io.IOException;
+import com.silverwrist.dynamo.except.NoSuchResourceException;
+import com.silverwrist.dynamo.iface.ResourceProvider;
+
+class WrappedResourceProvider
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private ComponentResName m_mount_point;
+ private ResourceProvider m_provider;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ WrappedResourceProvider(ComponentResName mount_point, ResourceProvider provider)
+ {
+ m_mount_point = mount_point;
+ m_provider = provider;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class Object
+ *--------------------------------------------------------------------------------
+ */
+
+ public boolean equals(Object obj)
+ {
+ if ((obj==null) || !(obj instanceof WrappedResourceProvider))
+ return false;
+ WrappedResourceProvider other = (WrappedResourceProvider)obj;
+ return m_mount_point.equals(other.m_mount_point);
+
+ } // end equals
+
+ public int hashCode()
+ {
+ return m_mount_point.hashCode();
+
+ } // end hashCode
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ int getMatchCount(ComponentResName crn)
+ {
+ int rc = m_mount_point.getMatchCount(crn);
+ if (rc!=m_mount_point.getComponentCount())
+ return -1;
+ return rc;
+
+ } // end getMatchCount
+
+ InputStream getResource(ComponentResName crn) throws IOException
+ {
+ if (m_mount_point.getMatchCount(crn)!=m_mount_point.getComponentCount())
+ throw new NoSuchResourceException(crn.getStringValue(0,true));
+ return m_provider.getResource(crn.getStringValue(m_mount_point.getComponentCount(),true));
+
+ } // end getResource
+
+ long getResourceModTime(ComponentResName crn)
+ {
+ if (m_mount_point.getMatchCount(crn)!=m_mount_point.getComponentCount())
+ return 0;
+ return m_provider.getResourceModTime(crn.getStringValue(m_mount_point.getComponentCount(),true));
+
+ } // end getResourceModTime
+
+} // end class WrappedResourceProvider
+
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/DBUtilitiesImpl.java b/src/dynamo-framework/com/silverwrist/dynamo/db/DBUtilitiesImpl.java
new file mode 100644
index 0000000..17c032c
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/DBUtilitiesImpl.java
@@ -0,0 +1,141 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.lang.reflect.*;
+import java.sql.*;
+import com.silverwrist.util.*;
+import com.silverwrist.dynamo.iface.DBUtilities;
+
+abstract class DBUtilitiesImpl implements DBUtilities
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final Class[] ARGS_TYPE = new Class[0];
+ private static final Object[] ARGS = new Object[0];
+
+ private static final String SQL_WILDCARD_CHARS = "%_'";
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ protected DBUtilitiesImpl()
+ { // do nothing
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface DBUtilities
+ *--------------------------------------------------------------------------------
+ */
+
+ public String encodeString(String data)
+ {
+ if (data==null)
+ return null; // safety feature
+ int ndx = data.indexOf('\'');
+ if (ndx<0)
+ return data;
+ StringBuffer buf = new StringBuffer();
+ while (ndx>=0)
+ { // convert each single quote mark to a pair of them
+ if (ndx>0)
+ buf.append(data.substring(0,ndx));
+ buf.append("''");
+ data = data.substring(ndx+1);
+ ndx = data.indexOf('\'');
+
+ } // end while
+
+ buf.append(data);
+ return buf.toString();
+
+ } // end encodeString
+
+ public String encodeStringWildcards(String data)
+ {
+ if (data==null)
+ return null; // safety feature
+ AnyCharMatcher nhc = new AnyCharMatcher(SQL_WILDCARD_CHARS);
+ int ndx = nhc.get(data);
+ if (ndx<0)
+ return data; // trivial short-circuit case
+ StringBuffer buf = new StringBuffer();
+ while (ndx>=0)
+ { // append the matched "head" and then the encoded character
+ if (ndx>0)
+ buf.append(data.substring(0,ndx));
+ switch (data.charAt(ndx++))
+ {
+ case '%':
+ buf.append("\\%");
+ break;
+
+ case '_':
+ buf.append("\\_");
+ break;
+
+ case '\'':
+ buf.append("\'\'");
+ break;
+
+ } // end switch
+
+ if (ndx==data.length())
+ return buf.toString(); // munched the entire string - all done!
+ data = data.substring(ndx);
+ ndx = nhc.get(data);
+
+ } // end while
+
+ buf.append(data); // append the unmatched tail
+ return buf.toString();
+
+ } // end encodeStringWildcards
+
+ /*--------------------------------------------------------------------------------
+ * Abstract declarations from interface DBUtilities
+ *--------------------------------------------------------------------------------
+ */
+
+ public abstract java.util.Date getDateTime(ResultSet rs, String column) throws SQLException;
+
+ public abstract java.util.Date getDateTime(ResultSet rs, int column) throws SQLException;
+
+ public abstract void setDateTime(PreparedStatement stmt, int index, java.util.Date date) throws SQLException;
+
+ public abstract void testDatabase(Connection conn) throws SQLException;
+
+ /*--------------------------------------------------------------------------------
+ * External static operations
+ *--------------------------------------------------------------------------------
+ */
+
+ public static DBUtilities get(String type) throws Exception
+ {
+ String impl_class_name = DBUtilitiesImpl.class.getName() + "_" + type.toLowerCase();
+ Method m = Class.forName(impl_class_name).getMethod("get",ARGS_TYPE);
+ return (DBUtilities)(m.invoke(null,ARGS));
+
+ } // end get
+
+} // end class DBUtilitiesImpl
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/DBUtilitiesImpl_mysql.java b/src/dynamo-framework/com/silverwrist/dynamo/db/DBUtilitiesImpl_mysql.java
new file mode 100644
index 0000000..9a8971e
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/DBUtilitiesImpl_mysql.java
@@ -0,0 +1,201 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.sql.*;
+import java.util.*;
+import com.silverwrist.util.SQLUtils;
+import com.silverwrist.dynamo.iface.DBUtilities;
+
+public class DBUtilitiesImpl_mysql extends DBUtilitiesImpl
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static DBUtilitiesImpl_mysql _self = null;
+
+ // used to convert dates and times to UTC for sending to SQL
+ private static SimpleTimeZone utc = new SimpleTimeZone(0,"UTC");
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ private DBUtilitiesImpl_mysql()
+ {
+ super();
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Converts a date-and-time string (an SQL DATETIME value) to a standard Java date.
+ *
+ * @param dstr The date-and-time string to convert, presumed to be in UTC.
+ * @return The converted date and time.
+ * @exception java.sql.SQLException The date and time string was in an invalid format.
+ */
+ private static final java.util.Date convertDateTimeString(String dstr) throws SQLException
+ {
+ if (dstr==null)
+ return null; // null values are the same
+
+ try
+ { // do almost the reverse process of formatting it into a string
+ GregorianCalendar cal = new GregorianCalendar(utc);
+ cal.set(Calendar.YEAR,Integer.parseInt(dstr.substring(0,4)));
+ cal.set(Calendar.MONTH,Integer.parseInt(dstr.substring(5,7)) - 1 + Calendar.JANUARY);
+ cal.set(Calendar.DAY_OF_MONTH,Integer.parseInt(dstr.substring(8,10)));
+ cal.set(Calendar.HOUR_OF_DAY,Integer.parseInt(dstr.substring(11,13)));
+ cal.set(Calendar.MINUTE,Integer.parseInt(dstr.substring(14,16)));
+ cal.set(Calendar.SECOND,Integer.parseInt(dstr.substring(17,19)));
+ return cal.getTime();
+
+ } // end try
+ catch (NumberFormatException e)
+ { // the NumberFormatException becomes an SQLException
+ throw new SQLException("invalid DATETIME field format");
+
+ } // end catch
+
+ } // end convertDateString
+
+ /**
+ * Encodes a date as an SQL date/time string, expressed in UTC.
+ *
+ * @param d The date to be encoded.
+ * @return The string equivalent of that date.
+ */
+ private static final String encodeDate(java.util.Date d)
+ {
+ // Break down the date as a UTC value.
+ GregorianCalendar cal = new GregorianCalendar(utc);
+ cal.setTime(d);
+
+ // Create the two string buffers converting the date.
+ StringBuffer rc = new StringBuffer();
+ StringBuffer conv = new StringBuffer();
+ String c;
+
+ // Encode the year first.
+ conv.append("0000").append(cal.get(Calendar.YEAR));
+ c = conv.toString();
+ rc.append(c.substring(c.length()-4)).append('-');
+
+ // Now the month...
+ conv.setLength(0);
+ conv.append("00").append(cal.get(Calendar.MONTH) - Calendar.JANUARY + 1);
+ c = conv.toString();
+ rc.append(c.substring(c.length()-2)).append('-');
+
+ // And the day...
+ conv.setLength(0);
+ conv.append("00").append(cal.get(Calendar.DAY_OF_MONTH));
+ c = conv.toString();
+ rc.append(c.substring(c.length()-2)).append(' ');
+
+ // And the hour...
+ conv.setLength(0);
+ conv.append("00").append(cal.get(Calendar.HOUR_OF_DAY));
+ c = conv.toString();
+ rc.append(c.substring(c.length()-2)).append(':');
+
+ // And the minute...
+ conv.setLength(0);
+ conv.append("00").append(cal.get(Calendar.MINUTE));
+ c = conv.toString();
+ rc.append(c.substring(c.length()-2)).append(':');
+
+ // And the second...
+ conv.setLength(0);
+ conv.append("00").append(cal.get(Calendar.SECOND));
+ c = conv.toString();
+ rc.append(c.substring(c.length()-2));
+
+ // This is the resulting date/time value.
+ return rc.toString();
+
+ } // end encodeDate
+
+ /*--------------------------------------------------------------------------------
+ * Abstract implementations from class DBUtilitiesImpl
+ *--------------------------------------------------------------------------------
+ */
+
+ public java.util.Date getDateTime(ResultSet rs, String column) throws SQLException
+ {
+ return convertDateTimeString(rs.getString(column));
+
+ } // end getDateTime
+
+ public java.util.Date getDateTime(ResultSet rs, int column) throws SQLException
+ {
+ return convertDateTimeString(rs.getString(column));
+
+ } // end getDateTime
+
+ public void setDateTime(PreparedStatement stmt, int index, java.util.Date date) throws SQLException
+ {
+ stmt.setString(index,encodeDate(date));
+
+ } // end setDateTime
+
+ public void testDatabase(Connection conn) throws SQLException
+ {
+ Statement stmt = null;
+ ResultSet rs = null;
+ try
+ { // execute a simple SQL statement
+ stmt = conn.createStatement();
+ rs = stmt.executeQuery("SELECT 1;");
+ if (!rs.next())
+ throw new SQLException("MySQL database test failed(1)");
+ if (rs.getInt(1)!=1)
+ throw new SQLException("MySQL database test failed(2)");
+
+ } // end try
+ finally
+ { // close down statement and result set
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end testDatabase
+
+ /*--------------------------------------------------------------------------------
+ * External static operations
+ *--------------------------------------------------------------------------------
+ */
+
+ public static DBUtilities get()
+ {
+ if (_self==null)
+ _self = new DBUtilitiesImpl_mysql();
+ return _self;
+
+ } // end get
+
+} // end class DBUtilitiesImpl_mysql
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/DatabaseConnectionPool.java b/src/dynamo-framework/com/silverwrist/dynamo/db/DatabaseConnectionPool.java
new file mode 100644
index 0000000..a3298af
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/DatabaseConnectionPool.java
@@ -0,0 +1,652 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.sql.*;
+import java.util.*;
+import org.apache.log4j.Logger;
+import org.w3c.dom.*;
+import com.silverwrist.util.xml.*;
+import com.silverwrist.dynamo.Namespaces;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+
+/**
+ * A simple pooling system for JDBC connections, which allows connections to be kept in a pool until
+ * they're needed, avoiding the overhead of opening and closing connections for each transaction, or
+ * keeping one database connection open for each user.
+ * Based on some code from Marty Hall's Core Servlets and Java Server Pages (Prentice Hall/
+ * Sun Microsystems, 2000).
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public class DatabaseConnectionPool implements DBConnectionPool, ComponentInitialize, ComponentShutdown
+{
+ /*--------------------------------------------------------------------------------
+ * Internal background thread object
+ *--------------------------------------------------------------------------------
+ */
+
+ private class BackgroundThread extends Thread
+ {
+ /*====================================================================
+ * Constructor
+ *====================================================================
+ */
+
+ BackgroundThread()
+ {
+ super("DatabaseConnectionPool_bkgd_" + (s_thread_counter++));
+
+ } // end constructor
+
+ /*====================================================================
+ * Overrides from class Thread
+ *====================================================================
+ */
+
+ public void run()
+ {
+ try
+ { // attempt to create another connection in the background
+ Connection c = makeNewConnection();
+ synchronized (DatabaseConnectionPool.this)
+ { // we've got a new available connection - let everyone know
+ if (logger.isDebugEnabled())
+ logger.debug("created new connection in the background");
+ m_avail_connections.addElement(c);
+ m_pending = false;
+ DatabaseConnectionPool.this.notifyAll();
+
+ } // end synchronized block
+
+ } // end try
+ catch (Exception e)
+ { // caught an SQLException or an OutOfMemory exception
+ logger.warn("background connection thread caught exception",e);
+ // ditch this new connection and wait until an existing one frees up
+
+ } // end catch
+
+ } // end run
+
+ } // end BackgroundThread
+
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static Logger logger = Logger.getLogger(DatabaseConnectionPool.class);
+
+ private static final Map INFER_TYPE_MAP; // used to infer database type from JDBC driver classname
+
+ private static int s_thread_counter = 1; // counter for data pool threads
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private String m_name; // name of connection pool
+ private String m_dbtype; // database type
+ private String m_driver; // name of JDBC driver class
+ private String m_url; // URL for JDBC connection
+ private String m_username; // username for JDBC connection
+ private String m_password; // password for JDBC connection
+ private int m_max_conns; // maximum number of possible connections
+ private boolean m_wait_if_busy; // do we wait for a connection if none is available?
+ private boolean m_pending = false; // pending connection being created?
+ private Vector m_avail_connections = null; // connections which are available for use
+ private Vector m_busy_connections = null; // connections which are currently in use
+ private DBUtilities m_util_object; // utilities object
+ private PropertySerializer m_psz; // property serializer object
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a new DatabaseCOnnectionPool object. Commonly called at initialization time,
+ * when the objects are created from the Dynamo XML configuration file.
+ */
+ public DatabaseConnectionPool()
+ { // do nothing
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a standard database exception.
+ *
+ * @param message The message ID from the "DatabaseMessages" bundle to load.
+ * @return The new exception object.
+ */
+ private static final DatabaseException newException(String message)
+ {
+ return new DatabaseException(DatabaseConnectionPool.class,"DatabaseMessages",message);
+
+ } // end newException
+
+ /**
+ * Creates a standard database exception.
+ *
+ * @param message The message ID from the "DatabaseMessages" bundle to load.
+ * @param inner The exception to wrap in the new
+ * {@link com.silverwrist.dynamo.except.DatabaseException DatabaseException} object.
+ * @return The new exception object.
+ */
+ private static final DatabaseException newException(String message, Throwable inner)
+ {
+ return new DatabaseException(DatabaseConnectionPool.class,"DatabaseMessages",message,inner);
+
+ } // end newException
+
+ /**
+ * Closes all database connections in the specified vector.
+ *
+ * @param vconn Vector of connections to be closed.
+ */
+ private static final void closeConnections(Vector vconn)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("closeConnections(" + vconn.size() + " to be closed)");
+
+ for (int i=0; iklass; that is, if queryService(klass)
+ * yields some object x, then the expression klass.isInstance(x)
+ * is true.
+ * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in
+ * the specified class.
+ */
+ public Object queryService(Class klass)
+ {
+ if (klass==DBUtilities.class)
+ return m_util_object;
+ if (klass==PropertySerializer.class)
+ return m_psz;
+ if (klass==DBConnectionPool.class)
+ return (DBConnectionPool)this;
+ throw new NoSuchServiceException("DatabaseConnectionPool",klass);
+
+ } // end queryService
+
+ /**
+ * Queries this object for a specified service.
+ *
+ * @param klass The class of the object that should be returned as a service.
+ * @param serviceid ID for the service to be requested, to further discriminate between requests.
+ * @return A service object. The service object is guaranteed to be of the class
+ * specified by klass; that is, if queryService(klass)
+ * yields some object x, then the expression klass.isInstance(x)
+ * is true.
+ * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in
+ * the specified class.
+ */
+ public Object queryService(Class klass, String serviceid)
+ {
+ return this.queryService(klass);
+
+ } // end queryService
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface DBConnectionPool
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Returns a simple string identifying the database type. This is commonly used in database operations
+ * classes to create classnames that are dynamically loaded.
+ *
+ * @return The database identifier.
+ */
+ public String getDatabaseType()
+ {
+ return m_dbtype;
+
+ } // end getDatabaseType
+
+ /**
+ * Returns the number of connections currently being managed by this connection pool.
+ *
+ * @return The number of connections currently being managed by this connection pool.
+ */
+ public int numConnections()
+ {
+ if (m_busy_connections==null)
+ return 0;
+ int rc = m_avail_connections.size() + m_busy_connections.size();
+ if (logger.isDebugEnabled())
+ logger.debug("numConnections() => " + rc);
+ return rc;
+
+ } // end numConnections
+
+ /**
+ * Obtains a database connection object from the connection pool.
+ *
+ * @return The Connection object.
+ * @exception com.silverwrist.dynamo.except.DatabaseException If a connection could not be obtained.
+ */
+ public synchronized Connection getConnection() throws DatabaseException
+ {
+ if (m_busy_connections==null)
+ throw newException("dbx.notInitialized");
+
+ for (;;)
+ { // loop until we get a connection or throw an exception
+ if (m_avail_connections.isEmpty())
+ { // no connections available - we may need to make a new one
+ if (logger.isDebugEnabled())
+ logger.debug("no connections available - looking to get one");
+ if ((numConnections() < m_max_conns) && !m_pending)
+ makeBackgroundConnection(); // try to create a new connection
+ else if (!m_wait_if_busy)
+ { // don't want to wait? tough, we're h0sed!
+ logger.error("exhausted maximum connection limit (" + m_max_conns + ")");
+ throw newException("dbx.connectionLimit");
+
+ } // end else if
+
+ // Wait for the background connect attempt to finish, or for
+ // someone to return a connection.
+ try
+ { // park the thread here until we know what's up
+ wait();
+
+ } // end try
+ catch (InterruptedException e)
+ { // do nothing
+ } // end catch
+
+ // now fall through the loop and try again
+
+ } // end if
+ else
+ { // pull the last connection off the available list...
+ int ndx = m_avail_connections.size() - 1;
+ Connection rc = (Connection)(m_avail_connections.elementAt(ndx));
+ m_avail_connections.removeElementAt(ndx);
+ try
+ { // see if this is a good connection or not...
+ if (rc.isClosed())
+ { // this connection is closed - discard it, and notify any waiters that a slot
+ // has opened up
+ if (logger.isDebugEnabled())
+ logger.debug("discarding closed connection");
+ notifyAll();
+ rc = null;
+ // fall out to the end of the loop and try again
+
+ } // end if
+ else
+ { // this connection is OK - return it
+ m_busy_connections.addElement(rc);
+ return rc;
+
+ } // end else
+
+ } // end try
+ catch (SQLException e)
+ { // if isClosed() throws a SQLException, the connection is somehow broken
+ logger.warn("connection is borked, discarding",e);
+ notifyAll();
+ rc = null;
+ // fall out to the end of the loop and try again
+
+ } // end catch
+
+ } // end else (at least one connection available)
+
+ } // end for (ever)
+
+ } // end getConnection
+
+ /**
+ * Returns a database connection object to the connection pool.
+ *
+ * @param conn The Connection object to be released.
+ * @exception com.silverwrist.dynamo.except.DatabaseException If there was an error returning the connection.
+ */
+ public synchronized void releaseConnection(Connection conn) throws DatabaseException
+ {
+ if (m_busy_connections==null)
+ throw newException("dbx.notInitialized");
+
+ if (conn!=null)
+ { // move from one vector to another
+ m_busy_connections.removeElement(conn);
+ m_avail_connections.addElement(conn);
+ notifyAll(); // wake up! Got a new connection for you!
+
+ } // end if
+
+ } // end releaseConnection
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ComponentInitialize
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Initialize the database connection.
+ *
+ * @param config_root Pointer to the <dbconnection/> section of the Dynamo XML configuration file that
+ * configures this database connection. This is to be considered "read-only" by the component.
+ * @param services An implementation of {@link com.silverwrist.dynamo.iface.ServiceProvider ServiceProvider}
+ * which provides initialization services to the component. This will include an implementation
+ * of {@link com.silverwrist.dynamo.iface.ObjectProvider ObjectProvider} which may be used to
+ * get information about other objects previously initialized by the application.
+ * @exception com.silverwrist.dynamo.except.ConfigException If an error is encountered in the component
+ * configuration.
+ */
+ public void initialize(Element config_root, ServiceProvider services) throws ConfigException
+ {
+ XMLLoader loader = XMLLoader.get();
+ try
+ { // verify the right node name
+ loader.verifyNodeName(config_root,"dbconnection");
+
+ // get the object's name
+ m_name = loader.getAttribute(config_root,"name");
+
+ // get the various settings
+ DOMElementHelper h = new DOMElementHelper(config_root);
+ m_dbtype = h.getSubElementText("dbtype");
+ if (logger.isDebugEnabled() && (m_dbtype!=null))
+ logger.debug("DatabaseConnectionPool specified database type: " + m_dbtype);
+
+ m_driver = loader.getSubElementText(h,"driver");
+ if (logger.isDebugEnabled())
+ logger.debug("DatabaseConnectionPool driver: " + m_driver);
+
+ // If the database type is not known, try to infer it from the driver name.
+ if (m_dbtype==null)
+ m_dbtype = (String)(INFER_TYPE_MAP.get(m_driver));
+ if (m_dbtype==null)
+ { // wasn't specified, can't infer it - we are HOSED!
+ ConfigException ce = new ConfigException(DatabaseConnectionPool.class,"DatabaseMessages",
+ "config.inferType");
+ ce.setParameter(0,m_driver);
+ throw ce;
+
+ } // end if
+ else if (logger.isDebugEnabled())
+ logger.debug("DatabaseConnectionPool inferred database type: " + m_dbtype);
+
+ m_url = loader.getSubElementText(h,"uri");
+ if (logger.isDebugEnabled())
+ logger.debug("DatabaseConnectionPool URI: " + m_url);
+
+ m_username = loader.getSubElementText(h,"username");
+ if (logger.isDebugEnabled())
+ logger.debug("DatabaseConnectionPool user name: " + m_username);
+
+ m_password = loader.getSubElementText(h,"password");
+
+ Element elt = loader.getSubElement(h,"connections");
+ int initial_conn = loader.getAttributeInt(elt,"initial",0);
+ if (initial_conn<0)
+ throw new ConfigException(DatabaseConnectionPool.class,"DatabaseMessages","config.initialConn");
+ if (logger.isDebugEnabled())
+ logger.debug("DatabaseConnectionPool initial connections: " + initial_conn);
+
+ m_max_conns = loader.getAttributeInt(elt,"max");
+ if (m_max_conns<0)
+ throw new ConfigException(DatabaseConnectionPool.class,"DatabaseMessages","config.maxConn");
+ if (logger.isDebugEnabled())
+ logger.debug("DatabaseConnectionPool maximum connections: " + m_max_conns);
+
+ m_wait_if_busy = loader.getAttributeBoolean(elt,"busywait",true);
+ if (logger.isDebugEnabled())
+ logger.debug("DatabaseConnectionPool wait if busy: " + m_wait_if_busy);
+
+ if (initial_conn>m_max_conns)
+ { // fix initial value if above maximum
+ if (logger.isDebugEnabled())
+ logger.debug("N.B.: reducing configured initial connections");
+ initial_conn = m_max_conns;
+
+ } // end if
+
+ try
+ { // get the appropriate utilities object
+ m_util_object = DBUtilitiesImpl.get(m_dbtype);
+
+ } // end if
+ catch (Exception e)
+ { // the utilities are not implemented
+ ConfigException ce = new ConfigException(DatabaseConnectionPool.class,"DatabaseMessages",
+ "utils.impl",e);
+ ce.setParameter(0,m_dbtype);
+ throw ce;
+
+ } // end catch
+
+ // Get the master property serializer so we can offer it as a service.
+ m_psz = (PropertySerializer)(services.queryService(PropertySerializer.class));
+
+ // Create the vectors that hold connections.
+ m_avail_connections = new Vector(initial_conn);
+ m_busy_connections = new Vector();
+
+ // Populate the "available connection" vector.
+ for (int i=0; iConnection objects.
+ */
+ public void shutdown()
+ {
+ closeConnections(m_avail_connections);
+ m_avail_connections = null;
+ closeConnections(m_busy_connections);
+ m_busy_connections = null;
+
+ } // end shutdown
+
+ /*--------------------------------------------------------------------------------
+ * Static initializer
+ *--------------------------------------------------------------------------------
+ */
+
+ static
+ { // Create the database type inference map.
+ HashMap map = new HashMap();
+ map.put("com.mysql.jdbc.Driver","mysql");
+ map.put("org.gjt.mm.mysql.Driver","mysql");
+ INFER_TYPE_MAP = Collections.unmodifiableMap(map);
+
+ } // end static initializer
+
+} // end class DatabaseConnectionPool
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/DatabaseMessages.properties b/src/dynamo-framework/com/silverwrist/dynamo/db/DatabaseMessages.properties
new file mode 100644
index 0000000..6ca3d36
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/DatabaseMessages.properties
@@ -0,0 +1,58 @@
+# The contents of this file are subject to the Mozilla Public License Version 1.1
+# (the "License"); you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at .
+#
+# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+# WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+# language governing rights and limitations under the License.
+#
+# The Original Code is the Venice Web Communities System.
+#
+# The Initial Developer of the Original Code is Eric J. Bowersox ,
+# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+# Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+#
+# Contributor(s):
+# ---------------------------------------------------------------------------------
+# This file has been localized for the en_US locale
+dbx.notInitialized=The connection pool object has not been initialized
+dbx.classNotFound=Can't find JDBC driver class: {0}
+dbx.illegalAccess=Can't access JDBC driver class: {0}
+dbx.instantiation=Can't create JDBC driver class: {0}
+dbx.sqlMakeNewConn=Can't create new database connection
+dbx.connectionLimit=Connection limit reached
+dbx.testfail=Test failed on database {0} (url {1}): {2}
+config.inferType=Database type was not specified, and unable to infer it from JDBC driver name "{0}".
+config.initialConn=Invalid initial connections parameter
+config.maxConn=Invalid maximum connections parameter
+config.create=Unable to create initial database connections
+utils.impl=Database utilities are not implemented for database type "{0}".
+load.opsClass=Unable to load {2} class for database "{1}": {0}
+general=Database access failure: {0}
+nsCache.notFound=Unknown namespace ID seen; possible internal error.
+property.serialize=The value of property "{0}" could not be serialized.
+property.deserialize=The value of property "{0}" could not be deserialized.
+ose.setProperty=Unable to set the value of property "{1}" in namespace "{0}".
+ose.removeProperty=Unable to remove the value of property "{1}" in namespace "{0}".
+ose.getNamespaces=Unable to enumerate the namespaces in this ObjectStore.
+ose.getNames=Unable to enumerate the object names in namespace "{0}".
+auth.register=Authenticator already registered for namespace "{0}", name "{1}".
+auth.notFound=No authenticator registered for namespace "{0}", name "{1}".
+auth.noUserData=User cannot authenticate with authenticator namespace "{0}", name "{1}".
+ose.setBlock=Unable to set the value of block "{1}" in namespace "{0}".
+ose.removeBlock=Unable to remove the value of block "{1}" in namespace "{0}".
+sec.changeUser=You are not permitted to change the attributes of user "{0}".
+sec.needSec=You cannot perform this operation on a group without specifying a user making the change.
+sec.setGroupProperty=You are not permitted to set property values for group "{0}".
+sec.removeGroupProperty=You are not permitted to remove property values from group "{0}".
+sec.addGroupMember=You are not permitted to add members to group "{0}".
+sec.removeGroupMember=You are not permitted to remove members from group "{0}".
+sec.setGroupAcl=You are not permitted to change the access control list of group "{0}".
+sec.setGlobalProperty=You are not permitted to set the global property.
+sec.removeGlobalProperty=You are not permitted to remove the global property.
+sec.setGlobalBlock=You are not permitted to set the global block.
+sec.removeGlobalBlock=You are not permitted to remove the global block.
+img.loadFail=Failed to load image {0} due to I/O error.
+img.badOwner=Invalid owner for new image.
+img.notOwner=You are not the owner of image {0}.
+img.normalize=Image normalization of {0} failed: {1}.
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/DefaultHashAuthenticator.java b/src/dynamo-framework/com/silverwrist/dynamo/db/DefaultHashAuthenticator.java
new file mode 100644
index 0000000..b0767b3
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/DefaultHashAuthenticator.java
@@ -0,0 +1,111 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.security.MessageDigest;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+
+class DefaultHashAuthenticator implements Authenticator
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ DefaultHashAuthenticator()
+ { // do nothing
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * IMplementations from interface Authenticator
+ *--------------------------------------------------------------------------------
+ */
+
+ public boolean authenticate(String stored_data, String input_data) throws AuthenticationException
+ {
+ return stored_data.equals(hashPassword(input_data));
+
+ } // end authenticate
+
+ public String processInputData(String input_data) throws AuthenticationException
+ {
+ return hashPassword(input_data);
+
+ } // end processInputData
+
+ /*--------------------------------------------------------------------------------
+ * External static operations
+ *--------------------------------------------------------------------------------
+ */
+
+ public static final String hashPassword(String password)
+ {
+ if ((password!=null) && (password.length()>0))
+ { // hash the password and save the hash value
+ MessageDigest hasher;
+
+ try
+ { // get a hasher implementing the Secure Hashing Algorithm
+ hasher = MessageDigest.getInstance("SHA");
+
+ } // end try
+ catch (java.security.NoSuchAlgorithmException e)
+ { // SHA should be a standard algorithm...if it isn't, we're h0sed
+ throw new RuntimeException("HOSED JRE - SHA should be a standard algorithm");
+
+ } // end catch
+
+ try
+ { // update the hasher with the UTF-8 bytes of the password
+ hasher.update(password.getBytes("UTF8"));
+
+ } // end try
+ catch (java.io.UnsupportedEncodingException e)
+ { // WTF? How can the JRE NOT know about UTF-8? HOW?!?
+ throw new RuntimeException("HOSED JRE - UTF-8 encoding should be supported");
+
+ } // end catch
+
+ // Retrieve the raw hash value (should be 160 bits, or 20 bytes)
+ byte[] raw_hash = hasher.digest();
+
+ // Convert the hash value to a hexadecimal string (40 chars in length)
+ StringBuffer hash_buf = new StringBuffer(raw_hash.length * 2);
+ StringBuffer tmp_buf = new StringBuffer();
+ String tmp;
+ for (int i=0; i.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.util.*;
+import com.silverwrist.util.*;
+import com.silverwrist.dynamo.event.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.security.SecurityReferenceMonitor;
+import com.silverwrist.dynamo.util.*;
+
+class GlobalBlocksObject implements SecureObjectStore
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private GlobalBlocksOps m_ops; // operations object
+ private NamespaceCache m_ns_cache; // namespace cache
+ private SecurityReferenceMonitor m_srm; // security reference monitor
+ private PostDynamicUpdate m_post; // where we post dynamic events
+ private HardSoftCache m_cache; // our cache
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ GlobalBlocksObject(DBConnectionPool pool, NamespaceCache ns_cache, SecurityReferenceMonitor srm,
+ PostDynamicUpdate post, int hard_limit, int soft_limit) throws ConfigException
+ {
+ m_ops = GlobalBlocksOps.get(pool);
+ m_ns_cache = ns_cache;
+ m_srm = srm;
+ m_post = post;
+ m_cache = new HardSoftCache(hard_limit,soft_limit);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
+
+ private final void testPermission(DynamoUser caller, String perm_namespace, String perm_name,
+ String fail_message) throws DatabaseException, DynamoSecurityException
+ {
+ if (caller.equals(m_srm.getAdminUser()))
+ return; // Administrator can do anything
+ if (m_srm.getGlobalAcl().testPermission(caller,perm_namespace,perm_name))
+ return; // we have the right permission in the ACL
+ throw new DynamoSecurityException(GroupObject.class,"DatabaseMessages",fail_message);
+
+ } // end testPermission
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ObjectProvider
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Retrieves an object from this ObjectProvider.
+ *
+ * @param namespace The namespace to interpret the name relative to.
+ * @param name The name of the object to be retrieved.
+ * @return The object reference specified.
+ */
+ public Object getObject(String namespace, String name)
+ {
+ try
+ { // convert the namespace name to an ID here
+ PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name);
+ Object rc = null;
+ synchronized (this)
+ { // start by looking in the block cache
+ rc = m_cache.get(key);
+ if (rc==null)
+ { // no use - need to try the database
+ rc = m_ops.getBlock(key);
+ if (rc!=null)
+ m_cache.put(key,rc);
+
+ } // end if
+
+ } // end synchronized block
+
+ if (rc==null)
+ throw new NoSuchObjectException(this.toString(),namespace,name);
+ return rc;
+
+ } // end try
+ catch (DatabaseException e)
+ { // translate into our NoSuchObjectException but retain the DatabaseException
+ throw new NoSuchObjectException(this.toString(),namespace,name,e);
+
+ } // end catch
+
+ } // end getObject
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface SecureObjectStore
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object setObject(DynamoUser caller, String namespace, String name, Object value)
+ throws DatabaseException, DynamoSecurityException
+ {
+ testPermission(caller,namespace,"set.block","sec.setGlobalBlock");
+ Object rc = null;
+ // convert the namespace name to an ID here
+ PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name);
+ synchronized (this)
+ { // start by setting the database value
+ rc = m_ops.putBlock(key,value.toString());
+
+ // and cache it, too
+ m_cache.put(key,value.toString());
+
+ } // end synchronized block
+
+ m_post.postUpdate(new GlobalBlockUpdateEvent(this,namespace,name));
+ return rc;
+
+ } // end setObject
+
+ public Object removeObject(DynamoUser caller, String namespace, String name)
+ throws DatabaseException, DynamoSecurityException
+ {
+ testPermission(caller,namespace,"remove.block","sec.removeGlobalBlock");
+ Object rc = null;
+ // convert the namespace name to an ID here
+ PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name);
+ synchronized (this)
+ { // start by killing the database value
+ rc = m_ops.removeBlock(key);
+
+ // and remove the cached value, too
+ m_cache.remove(key);
+
+ } // end synchronized block
+
+ m_post.postUpdate(new GlobalBlockUpdateEvent(this,namespace,name));
+ return rc;
+
+ } // end removeObject
+
+ public Collection getNamespaces() throws DatabaseException
+ {
+ // call through to the database to get the list of namespace IDs
+ int[] ids = m_ops.getBlockNamespaceIDs();
+
+ ArrayList rc = new ArrayList(ids.length);
+ for (int i=0; i.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.util.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.util.*;
+
+abstract class GlobalBlocksOps extends OpsBase
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ protected GlobalBlocksOps(DBConnectionPool pool)
+ {
+ super(pool);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class OpsBase
+ *--------------------------------------------------------------------------------
+ */
+
+ public void dispose()
+ {
+ super.dispose();
+
+ } // end dispose
+
+ /*--------------------------------------------------------------------------------
+ * Abstract operations
+ *--------------------------------------------------------------------------------
+ */
+
+ abstract String getBlock(PropertyKey key) throws DatabaseException;
+
+ abstract String putBlock(PropertyKey key, String data) throws DatabaseException;
+
+ abstract String removeBlock(PropertyKey key) throws DatabaseException;
+
+ abstract int[] getBlockNamespaceIDs() throws DatabaseException;
+
+ abstract Collection getAllBlockNames(int nsid) throws DatabaseException;
+
+ /*--------------------------------------------------------------------------------
+ * External static operations
+ *--------------------------------------------------------------------------------
+ */
+
+ static GlobalBlocksOps get(DBConnectionPool pool) throws ConfigException
+ {
+ return (GlobalBlocksOps)get(pool,GlobalBlocksOps.class.getClassLoader(),
+ GlobalBlocksOps.class.getName() + "_","GlobalBlocksOps");
+
+ } // end get
+
+} // end class GlobalBlocksOps
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/GlobalBlocksOps_mysql.java b/src/dynamo-framework/com/silverwrist/dynamo/db/GlobalBlocksOps_mysql.java
new file mode 100644
index 0000000..59b4d69
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/GlobalBlocksOps_mysql.java
@@ -0,0 +1,284 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.sql.*;
+import java.util.*;
+import com.silverwrist.util.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+public class GlobalBlocksOps_mysql extends GlobalBlocksOps
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private DBUtilities m_utils; // reference to utilities object
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public GlobalBlocksOps_mysql(DBConnectionPool pool)
+ {
+ super(pool);
+ m_utils = (DBUtilities)(pool.queryService(DBUtilities.class));
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Abstract implementations from class GlobalBlocksOps
+ *--------------------------------------------------------------------------------
+ */
+
+ String getBlock(PropertyKey key) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // look up the block
+ stmt = conn.prepareStatement("SELECT block FROM globalblock WHERE nsid = ? AND block_name = ?;");
+ stmt.setInt(1,key.getNamespaceID());
+ stmt.setString(2,key.getName());
+ rs = stmt.executeQuery();
+ if (!(rs.next()))
+ return null; // block not found
+ return rs.getString(1);
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end getBlock
+
+ String putBlock(PropertyKey key, String data) throws DatabaseException
+ {
+ String old_value = null;
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ Statement stmt2 = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // lock the table
+ stmt2 = conn.createStatement();
+ stmt2.executeUpdate("LOCK TABLES globalblock WRITE;");
+
+ // look to see if the block value is already there
+ stmt = conn.prepareStatement("SELECT block FROM globalblock WHERE nsid = ? AND block_name = ?;");
+ stmt.setInt(1,key.getNamespaceID());
+ stmt.setString(2,key.getName());
+ rs = stmt.executeQuery();
+ if (rs.next())
+ old_value = rs.getString(1);
+ SQLUtils.shutdown(rs);
+ rs = null;
+ SQLUtils.shutdown(stmt);
+
+ if (old_value!=null)
+ { // prepare the statement to update the existing record
+ stmt = conn.prepareStatement("UPDATE globalblock SET block = ? WHERE nsid = ? AND block_name = ?;");
+ stmt.setString(1,data);
+ stmt.setInt(2,key.getNamespaceID());
+ stmt.setString(3,key.getName());
+
+ } // end if
+ else
+ { // prepare the statement to insert a new record
+ stmt = conn.prepareStatement("INSERT INTO globalblock (nsid, block_name, block) VALUES (?, ?, ?);");
+ stmt.setInt(1,key.getNamespaceID());
+ stmt.setString(2,key.getName());
+ stmt.setString(3,data);
+
+ } // end else
+
+ stmt.executeUpdate(); // execute it!
+
+ return old_value; // return previous value
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ MySQLUtils.unlockTables(conn);
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(stmt2);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end putBlock
+
+ String removeBlock(PropertyKey key) throws DatabaseException
+ {
+ String old_value = null;
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ Statement stmt2 = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // lock the table
+ stmt2 = conn.createStatement();
+ stmt2.executeUpdate("LOCK TABLES globalblock WRITE;");
+
+ // look to see if the property value is already there
+ stmt = conn.prepareStatement("SELECT block FROM globalblock WHERE nsid = ? AND block_name = ?;");
+ stmt.setInt(1,key.getNamespaceID());
+ stmt.setString(2,key.getName());
+ rs = stmt.executeQuery();
+ if (rs.next())
+ old_value = rs.getString(1);
+ else
+ return null; // no need to remove anything
+ SQLUtils.shutdown(rs);
+ rs = null;
+ SQLUtils.shutdown(stmt);
+
+ // delete the database row
+ stmt = conn.prepareStatement("DELETE FROM globalblock WHERE nsid = ? AND block_name = ?;");
+ stmt.setInt(1,key.getNamespaceID());
+ stmt.setString(2,key.getName());
+ stmt.executeUpdate();
+
+ return old_value;
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ MySQLUtils.unlockTables(conn);
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(stmt2);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end removeBlock
+
+ int[] getBlockNamespaceIDs() throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // execute the query!
+ stmt = conn.prepareStatement("SELECT DISTINCT nsid FROM globalblock;");
+ rs = stmt.executeQuery();
+
+ // read out a list of the namespace IDs
+ ArrayList tmp = new ArrayList();
+ while (rs.next())
+ tmp.add(new Integer(rs.getInt(1)));
+
+ // create and return the array
+ int[] rc = new int[tmp.size()];
+ for (int i=0; i.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import org.w3c.dom.*;
+import com.silverwrist.util.xml.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.security.SecurityReferenceMonitor;
+import com.silverwrist.dynamo.util.*;
+
+public class GlobalDataManagerObject
+ implements NamedObject, ComponentInitialize, ComponentShutdown, ServiceProvider
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final int DEFAULT_HARD_LIMIT = 5;
+ private static final int DEFAULT_SOFT_LIMIT = 20;
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private String m_name; // object name
+ private DBConnectionPool m_pool; // database connection pool
+ private NamespaceCache m_ns_cache; // namespace cache object
+ private SecurityReferenceMonitor m_srm; // security reference monitor
+ private PostDynamicUpdate m_post; // dynamic update poster
+ private GlobalPropertiesObject m_properties; // global properties object
+ private GlobalBlocksObject m_blocks; // global blocks object
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public GlobalDataManagerObject()
+ { // do nothing
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface NamedObject
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getName()
+ {
+ return m_name;
+
+ } // end getName
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ComponentInitialize
+ *--------------------------------------------------------------------------------
+ */
+
+ public void initialize(Element config_root, ServiceProvider services) throws ConfigException
+ {
+ String conn_name = null;
+ String nscache_name = null;
+ String srm_name = null;
+ int hard_limit = DEFAULT_HARD_LIMIT;
+ int soft_limit = DEFAULT_SOFT_LIMIT;
+ XMLLoader loader = XMLLoader.get();
+ try
+ { // verify the right node name
+ loader.verifyNodeName(config_root,"object");
+
+ // get the object's name
+ m_name = loader.getAttribute(config_root,"name");
+
+ // get the database configuration connection
+ DOMElementHelper config_root_h = new DOMElementHelper(config_root);
+ Element elt = loader.getSubElement(config_root_h,"database");
+ conn_name = loader.getAttribute(elt,"connection");
+ nscache_name = loader.getAttribute(elt,"namespaces");
+
+ // get the security reference monitor reference
+ elt = loader.getSubElement(config_root_h,"security");
+ srm_name = loader.getAttribute(elt,"object");
+
+ // get the block cache information
+ elt = config_root_h.getSubElement("block-cache");
+ if (elt!=null)
+ { // get the cache limits
+ hard_limit = loader.getAttributeInt(elt,"hardlimit",DEFAULT_HARD_LIMIT);
+ soft_limit = loader.getAttributeInt(elt,"softlimit",DEFAULT_SOFT_LIMIT);
+
+ } // end if
+
+ } // end try
+ catch (XMLLoadException e)
+ { // error loading XML config data
+ throw new ConfigException(e);
+
+ } // end catch
+
+ // Get the database connection pool and the namespace cache.
+ m_pool = GetObjectUtils.getDatabaseConnection(services,conn_name);
+ m_ns_cache =
+ (NamespaceCache)(GetObjectUtils.getDynamoComponent(services,NamespaceCache.class,nscache_name));
+ m_srm =
+ (SecurityReferenceMonitor)(GetObjectUtils.getDynamoComponent(services,SecurityReferenceMonitor.class,
+ srm_name));
+ m_post = (PostDynamicUpdate)(services.queryService(PostDynamicUpdate.class));
+
+ // Create the subobjects.
+ m_properties = new GlobalPropertiesObject(m_pool,m_ns_cache,m_srm,m_post);
+ m_blocks = new GlobalBlocksObject(m_pool,m_ns_cache,m_srm,m_post,hard_limit,soft_limit);
+
+ } // end initialize
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ComponentShutdown
+ *--------------------------------------------------------------------------------
+ */
+
+ public void shutdown()
+ {
+ m_pool = null;
+ m_ns_cache = null;
+ m_srm = null;
+ m_post = null;
+
+ } // end shutdown
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ServiceProvider
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Queries this object for a specified service.
+ *
+ * @param klass The class of the object that should be returned as a service.
+ * @return A service object. The service object is guaranteed to be of the class
+ * specified by klass; that is, if queryService(klass)
+ * yields some object x, then the expression klass.isInstance(x)
+ * is true.
+ * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in
+ * the specified class.
+ */
+ public Object queryService(Class klass)
+ {
+ if ((klass==SecureObjectStore.class) || (klass==ObjectProvider.class))
+ return (SecureObjectStore)m_properties;
+ throw new NoSuchServiceException("GlobalDataManagerObject",klass);
+
+ } // end queryService
+
+ /**
+ * Queries this object for a specified service.
+ *
+ * @param klass The class of the object that should be returned as a service.
+ * @param serviceid ID for the service to be requested, to further discriminate between requests.
+ * @return A service object. The service object is guaranteed to be of the class
+ * specified by klass; that is, if queryService(klass)
+ * yields some object x, then the expression klass.isInstance(x)
+ * is true.
+ * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in
+ * the specified class.
+ */
+ public Object queryService(Class klass, String serviceid)
+ {
+ if ((klass==SecureObjectStore.class) || (klass==ObjectProvider.class))
+ { // return service
+ if ((serviceid==null) || serviceid.equals("properties"))
+ return (SecureObjectStore)m_properties;
+ if (serviceid.equals("blocks"))
+ return (SecureObjectStore)m_blocks;
+ throw new NoSuchServiceException("GlobalDataManagerObject",klass,serviceid);
+
+ } // end if
+
+ try
+ { // look for the class without a service ID
+ return this.queryService(klass);
+
+ } // end try
+ catch (NoSuchServiceException e)
+ { // transform exception for return
+ throw new NoSuchServiceException(e.getContext(),klass,serviceid,e);
+
+ } // end catch
+
+ } // end queryService
+
+} // end class GlobalDataManagerObject
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/GlobalPropertiesObject.java b/src/dynamo-framework/com/silverwrist/dynamo/db/GlobalPropertiesObject.java
new file mode 100644
index 0000000..11c5132
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/GlobalPropertiesObject.java
@@ -0,0 +1,201 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.util.*;
+import org.apache.commons.collections.*;
+import com.silverwrist.dynamo.event.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.security.SecurityReferenceMonitor;
+import com.silverwrist.dynamo.util.*;
+
+class GlobalPropertiesObject implements SecureObjectStore
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private GlobalPropertiesOps m_ops; // operations object
+ private NamespaceCache m_ns_cache; // namespace cache
+ private SecurityReferenceMonitor m_srm; // security reference monitor
+ private PostDynamicUpdate m_post; // where we post dynamic events
+ private ReferenceMap m_properties; // cached property values
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ GlobalPropertiesObject(DBConnectionPool pool, NamespaceCache ns_cache, SecurityReferenceMonitor srm,
+ PostDynamicUpdate post) throws ConfigException
+ {
+ m_ops = GlobalPropertiesOps.get(pool);
+ m_ns_cache = ns_cache;
+ m_srm = srm;
+ m_post = post;
+ m_properties = new ReferenceMap(ReferenceMap.HARD,ReferenceMap.SOFT);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
+
+ private final void testPermission(DynamoUser caller, String perm_namespace, String perm_name,
+ String fail_message) throws DatabaseException, DynamoSecurityException
+ {
+ if (caller.equals(m_srm.getAdminUser()))
+ return; // Administrator can do anything
+ if (m_srm.getGlobalAcl().testPermission(caller,perm_namespace,perm_name))
+ return; // we have the right permission in the ACL
+ throw new DynamoSecurityException(GroupObject.class,"DatabaseMessages",fail_message);
+
+ } // end testPermission
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ObjectProvider
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Retrieves an object from this ObjectProvider.
+ *
+ * @param namespace The namespace to interpret the name relative to.
+ * @param name The name of the object to be retrieved.
+ * @return The object reference specified.
+ */
+ public Object getObject(String namespace, String name)
+ {
+ try
+ { // convert the namespace name to an ID here
+ PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name);
+ Object rc = null;
+ synchronized (this)
+ { // start by looking in the properties map
+ rc = m_properties.get(key);
+ if (rc==null)
+ { // no use - need to try the database
+ rc = m_ops.getProperty(key);
+ if (rc!=null)
+ m_properties.put(key,rc);
+
+ } // end if
+
+ } // end synchronized block
+
+ if (rc==null)
+ throw new NoSuchObjectException(this.toString(),namespace,name);
+ return rc;
+
+ } // end try
+ catch (DatabaseException e)
+ { // translate into our NoSuchObjectException but retain the DatabaseException
+ throw new NoSuchObjectException(this.toString(),namespace,name,e);
+
+ } // end catch
+
+ } // end getObject
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface SecureObjectStore
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object setObject(DynamoUser caller, String namespace, String name, Object value)
+ throws DatabaseException, DynamoSecurityException
+ {
+ testPermission(caller,namespace,"set.property","sec.setGlobalProperty");
+ Object rc = null;
+ // convert the namespace name to an ID here
+ PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name);
+ synchronized (this)
+ { // start by setting the database value
+ rc = m_ops.setProperty(key,value);
+
+ // and cache it, too
+ m_properties.put(key,value);
+
+ } // end synchronized block
+
+ m_post.postUpdate(new GlobalPropertyUpdateEvent(this,namespace,name));
+ return rc;
+
+ } // end setObject
+
+ public Object removeObject(DynamoUser caller, String namespace, String name)
+ throws DatabaseException, DynamoSecurityException
+ {
+ testPermission(caller,namespace,"remove.property","sec.removeGlobalProperty");
+ Object rc = null;
+ // convert the namespace name to an ID here
+ PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name);
+ synchronized (this)
+ { // start by killing the database value
+ rc = m_ops.removeProperty(key);
+
+ // and remove the cached value, too
+ m_properties.remove(key);
+
+ } // end synchronized block
+
+ m_post.postUpdate(new GlobalPropertyUpdateEvent(this,namespace,name));
+ return rc;
+
+ } // end removeObject
+
+ public Collection getNamespaces() throws DatabaseException
+ {
+ // call through to the database to get the list of namespace IDs
+ int[] ids = m_ops.getPropertyNamespaceIDs();
+
+ ArrayList rc = new ArrayList(ids.length);
+ for (int i=0; i.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.util.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.util.*;
+
+abstract class GlobalPropertiesOps extends OpsBase
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ protected GlobalPropertiesOps(DBConnectionPool pool)
+ {
+ super(pool);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class OpsBase
+ *--------------------------------------------------------------------------------
+ */
+
+ public void dispose()
+ {
+ super.dispose();
+
+ } // end dispose
+
+ /*--------------------------------------------------------------------------------
+ * Abstract operations
+ *--------------------------------------------------------------------------------
+ */
+
+ abstract Object getProperty(PropertyKey key) throws DatabaseException;
+
+ abstract Object setProperty(PropertyKey key, Object value) throws DatabaseException;
+
+ abstract Object removeProperty(PropertyKey key) throws DatabaseException;
+
+ abstract int[] getPropertyNamespaceIDs() throws DatabaseException;
+
+ abstract Map getAllProperties(int namespace) throws DatabaseException;
+
+ /*--------------------------------------------------------------------------------
+ * External static operations
+ *--------------------------------------------------------------------------------
+ */
+
+ static GlobalPropertiesOps get(DBConnectionPool pool) throws ConfigException
+ {
+ return (GlobalPropertiesOps)get(pool,GlobalPropertiesOps.class.getClassLoader(),
+ GlobalPropertiesOps.class.getName() + "_","GlobalPropertiesOps");
+
+ } // end get
+
+} // end class GlobalPropertiesOps
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/GlobalPropertiesOps_mysql.java b/src/dynamo-framework/com/silverwrist/dynamo/db/GlobalPropertiesOps_mysql.java
new file mode 100644
index 0000000..c04cbfb
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/GlobalPropertiesOps_mysql.java
@@ -0,0 +1,344 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.sql.*;
+import java.util.*;
+import com.silverwrist.util.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+public class GlobalPropertiesOps_mysql extends GlobalPropertiesOps
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private DBUtilities m_utils; // reference to utilities object
+ private PropertySerializer m_psz; // reference to property serializer
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public GlobalPropertiesOps_mysql(DBConnectionPool pool)
+ {
+ super(pool);
+ m_utils = (DBUtilities)(pool.queryService(DBUtilities.class));
+ m_psz = (PropertySerializer)(pool.queryService(PropertySerializer.class));
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Abstract implementations from class GlobalPropertiesOps
+ *--------------------------------------------------------------------------------
+ */
+
+ Object getProperty(PropertyKey key) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ String rc_str = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // look up the property
+ stmt = conn.prepareStatement("SELECT prop_value FROM globalprop WHERE nsid = ? AND prop_name = ?;");
+ stmt.setInt(1,key.getNamespaceID());
+ stmt.setString(2,key.getName());
+ rs = stmt.executeQuery();
+ if (!(rs.next()))
+ return null; // property not found
+
+ rc_str = rs.getString(1);
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ // Deserialize the property value.
+ Object rc = m_psz.deserializeProperty(rc_str);
+ if (rc!=null)
+ return rc;
+
+ // deserialization exception - throw it
+ DatabaseException de = new DatabaseException(GlobalPropertiesOps_mysql.class,"DatabaseMessages",
+ "property.deserialize");
+ de.setParameter(0,key.getName());
+ throw de;
+
+ } // end getProperty
+
+ Object setProperty(PropertyKey key, Object value) throws DatabaseException
+ {
+ String serialized_value = m_psz.serializeProperty(value);
+ if (serialized_value==null)
+ { // serialization exception - throw it
+ DatabaseException de = new DatabaseException(GlobalPropertiesOps_mysql.class,"DatabaseMessages",
+ "property.serialize");
+ de.setParameter(0,key.getName());
+ throw de;
+
+ } // end if
+
+ String old_value = null;
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ Statement stmt2 = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // lock the table
+ stmt2 = conn.createStatement();
+ stmt2.executeUpdate("LOCK TABLES globalprop WRITE;");
+
+ // look to see if the property value is already there
+ stmt = conn.prepareStatement("SELECT prop_value FROM globalprop WHERE nsid = ? AND prop_name = ?;");
+ stmt.setInt(1,key.getNamespaceID());
+ stmt.setString(2,key.getName());
+ rs = stmt.executeQuery();
+ if (rs.next())
+ old_value = rs.getString(1);
+ SQLUtils.shutdown(rs);
+ rs = null;
+ SQLUtils.shutdown(stmt);
+
+ if (old_value!=null)
+ { // prepare the statement to update the existing record
+ stmt = conn.prepareStatement("UPDATE globalprop SET prop_value = ? WHERE nsid = ? AND prop_name = ?;");
+ stmt.setString(1,serialized_value);
+ stmt.setInt(2,key.getNamespaceID());
+ stmt.setString(3,key.getName());
+
+ } // end if
+ else
+ { // prepare the statement to insert a new record
+ stmt = conn.prepareStatement("INSERT INTO globalprop (nsid, prop_name, prop_value) VALUES (?, ?, ?);");
+ stmt.setInt(1,key.getNamespaceID());
+ stmt.setString(2,key.getName());
+ stmt.setString(3,serialized_value);
+
+ } // end else
+
+ stmt.executeUpdate(); // execute it!
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ MySQLUtils.unlockTables(conn);
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(stmt2);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ if (old_value==null)
+ return null; // no previous value
+
+ // Deserialize the property value.
+ Object rc = m_psz.deserializeProperty(old_value);
+ if (rc!=null)
+ return rc;
+
+ // deserialization exception - throw it
+ DatabaseException de = new DatabaseException(GlobalPropertiesOps_mysql.class,"DatabaseMessages",
+ "property.deserialize");
+ de.setParameter(0,key.getName());
+ throw de;
+
+ } // end setProperty
+
+ Object removeProperty(PropertyKey key) throws DatabaseException
+ {
+ String old_value = null;
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ Statement stmt2 = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // lock the table
+ stmt2 = conn.createStatement();
+ stmt2.executeUpdate("LOCK TABLES globalprop WRITE;");
+
+ // look to see if the property value is already there
+ stmt = conn.prepareStatement("SELECT prop_value FROM globalprop WHERE nsid = ? AND prop_name = ?;");
+ stmt.setInt(1,key.getNamespaceID());
+ stmt.setString(2,key.getName());
+ rs = stmt.executeQuery();
+ if (rs.next())
+ old_value = rs.getString(1);
+ else
+ return null; // no need to remove anything
+ SQLUtils.shutdown(rs);
+ rs = null;
+ SQLUtils.shutdown(stmt);
+
+ // delete the database row
+ stmt = conn.prepareStatement("DELETE FROM globalprop WHERE nsid = ? AND prop_name = ?;");
+ stmt.setInt(1,key.getNamespaceID());
+ stmt.setString(2,key.getName());
+ stmt.executeUpdate();
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ MySQLUtils.unlockTables(conn);
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(stmt2);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ // Deserialize the property value.
+ Object rc = m_psz.deserializeProperty(old_value);
+ if (rc!=null)
+ return rc;
+
+ // deserialization exception - throw it
+ DatabaseException de = new DatabaseException(GlobalPropertiesOps_mysql.class,"DatabaseMessages",
+ "property.deserialize");
+ de.setParameter(0,key.getName());
+ throw de;
+
+ } // end removeProperty
+
+ int[] getPropertyNamespaceIDs() throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // execute the query!
+ stmt = conn.prepareStatement("SELECT DISTINCT nsid FROM globalprop;");
+ rs = stmt.executeQuery();
+
+ // read out a list of the namespace IDs
+ ArrayList tmp = new ArrayList();
+ while (rs.next())
+ tmp.add(new Integer(rs.getInt(1)));
+
+ // create and return the array
+ int[] rc = new int[tmp.size()];
+ for (int i=0; i.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.security.Principal;
+import java.security.acl.AclNotFoundException;
+import java.util.*;
+import org.apache.commons.collections.*;
+import com.silverwrist.dynamo.Namespaces;
+import com.silverwrist.dynamo.UserInfoNamespace;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.security.SecurityReferenceMonitor;
+import com.silverwrist.dynamo.util.*;
+
+class GroupObject implements DynamoGroup
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final String PERM_NAMESPACE = Namespaces.GROUP_PERMISSIONS_NAMESPACE;
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private GroupObjectOps m_ops; // operations object
+ private NamespaceCache m_ns_cache; // namespace cache object
+ private SecurityReferenceMonitor m_srm; // security reference monitor
+ private UserProxyManagement m_upm; // user proxy manager
+ private int m_gid; // group ID
+ private String m_groupname; // group name
+ private int m_gaclid; // group ACL ID
+ private ReferenceMap m_properties; // cached property values
+ private Object m_properties_sync = new Object(); // synchronization for above
+ private HashSet m_known_members = new HashSet(); // known members
+ private HashSet m_known_nonmembers = new HashSet(); // known nonmembers
+ private Object m_members_sync = new Object(); // synchronization for above
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ GroupObject(Map data, GroupObjectOps ops, NamespaceCache ns_cache, SecurityReferenceMonitor srm,
+ UserProxyManagement upm)
+ {
+ m_ops = ops;
+ m_ns_cache = ns_cache;
+ m_srm = srm;
+ m_upm = upm;
+ m_gid = ((Integer)(data.get(UserManagerOps.HMKEY_GID))).intValue();
+ m_groupname = (String)(data.get(UserManagerOps.HMKEY_GROUPNAME));
+ m_gaclid = ((Integer)(data.get(UserManagerOps.HMKEY_GACLID))).intValue();
+ m_properties = new ReferenceMap(ReferenceMap.HARD,ReferenceMap.SOFT);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final int getPrincipalUID(Principal p)
+ {
+ if (p instanceof DynamoUser)
+ return ((DynamoUser)p).getUID();
+ else
+ return -1;
+
+ } // end getPrincipalUID
+
+ private final void testOperationWithoutSecurity()
+ {
+ if (m_gaclid==-1)
+ return;
+ throw new GroupRuntimeException(new DynamoSecurityException(GroupObject.class,"DatabaseMessages",
+ "sec.needSec"));
+
+ } // end testOperationWithoutSecurity
+
+ private final void testPermission(DynamoUser caller, String perm_namespace, String perm_name,
+ String fail_message) throws DatabaseException, DynamoSecurityException
+ {
+ if (m_gaclid==-1)
+ return;
+ if (caller==null)
+ throw new DynamoSecurityException(GroupObject.class,"DatabaseMessages","sec.needSec");
+ if (caller.equals(m_srm.getAdminUser()))
+ return; // Administrator can do anything
+ if (m_srm.testPermission(m_gaclid,caller,perm_namespace,perm_name))
+ return; // we have the right permission in the ACL
+ DynamoSecurityException dse = new DynamoSecurityException(GroupObject.class,"DatabaseMessages",
+ fail_message);
+ dse.setParameter(0,m_groupname);
+ throw dse;
+
+ } // end testPermission
+
+ private final void testPermission(DynamoUser caller, int target_uid, String perm_namespace, String perm_name,
+ String perm2_name, String fail_message)
+ throws DatabaseException, DynamoSecurityException
+ {
+ if (m_gaclid==-1)
+ return;
+ if (caller==null)
+ throw new DynamoSecurityException(GroupObject.class,"DatabaseMessages","sec.needSec");
+ if (caller.equals(m_srm.getAdminUser()))
+ return; // Administrator can do anything
+ if ((caller.getUID()==target_uid) && m_srm.testPermission(m_gaclid,caller,perm_namespace,perm2_name))
+ return; // we can "join group" or "unjoin group" if we have the right permissions
+ if (m_srm.testPermission(m_gaclid,caller,perm_namespace,perm_name))
+ return; // we have the right permission in the ACL
+ DynamoSecurityException dse = new DynamoSecurityException(GroupObject.class,"DatabaseMessages",
+ fail_message);
+ dse.setParameter(0,m_groupname);
+ throw dse;
+
+ } // end testPermission
+
+ private final void testAclOwner(DynamoUser caller) throws DatabaseException, DynamoSecurityException
+ {
+ if (m_gaclid==-1)
+ return;
+ if (caller==null)
+ throw new DynamoSecurityException(GroupObject.class,"DatabaseMessages","sec.needSec");
+ if (caller.equals(m_srm.getAdminUser()))
+ return; // Administrator can do anything
+ if (m_srm.isOwnerOfAcl(m_gaclid,caller))
+ return; // we own this ACL
+ DynamoSecurityException dse = new DynamoSecurityException(GroupObject.class,"DatabaseMessages",
+ "sec.setGroupAcl");
+ dse.setParameter(0,m_groupname);
+ throw dse;
+
+ } // end testAclOwner
+
+ private final boolean addUIDInternal(int uid) throws DatabaseException
+ {
+ Integer key = new Integer(uid);
+ synchronized (m_members_sync)
+ { // look in the cache first
+ if (m_known_members.contains(key))
+ return false; // we're already a known member
+
+ // fiddle the database
+ boolean rc = m_ops.addMember(m_gid,uid);
+ m_known_members.add(key); // update the cache to reflect reality
+ if (m_known_nonmembers!=null)
+ m_known_nonmembers.remove(key);
+ return rc;
+
+ } // end synchronized block
+
+ } // end addUIDInternal
+
+ private final boolean removeUIDInternal(int uid) throws DatabaseException
+ {
+ Integer key = new Integer(uid);
+ synchronized (m_members_sync)
+ { // look in the cache first
+ if (m_known_nonmembers!=null)
+ { // are we a known nonmember?
+ if (m_known_nonmembers.contains(key))
+ return false; // already a nonmember
+
+ } // end if
+ else
+ { // in this circumstance, everyone not in the members set is a nonmember
+ if (!(m_known_members.contains(key)))
+ return false; // already a nonmember
+
+ } // end else
+
+ // fiddle the database
+ boolean rc = m_ops.removeMember(m_gid,uid);
+ m_known_members.remove(key); // update the cache to reflect reality
+ if (m_known_nonmembers!=null)
+ m_known_nonmembers.add(key);
+ return rc;
+
+ } // end synchronized block
+
+ } // end removeUIDInternal
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface Principal
+ *--------------------------------------------------------------------------------
+ */
+
+ public boolean equals(Object another)
+ {
+ if (another==null)
+ return false;
+ if (another instanceof DynamoGroup)
+ return (m_gid==((DynamoGroup)another).getGID());
+ return false;
+
+ } // end equals
+
+ public String toString()
+ {
+ return "group " + m_groupname;
+
+ } // end toString
+
+ public int hashCode()
+ {
+ return m_gid;
+
+ } // end hashCode
+
+ public String getName()
+ {
+ return m_groupname;
+
+ } // end getName
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface Group
+ *--------------------------------------------------------------------------------
+ */
+
+ public boolean addMember(Principal user)
+ {
+ testOperationWithoutSecurity();
+ try
+ { // break down the operations...
+ if (user instanceof DynamoUser)
+ return this.addUIDInternal(((DynamoUser)user).getUID());
+ else if (user instanceof DynamoGroup)
+ { // add all UIDs contained in this group
+ int[] uids = ((DynamoGroup)user).getUIDs();
+ boolean rc = false;
+ for (int i=0; iObjectProvider.
+ *
+ * @param namespace The namespace to interpret the name relative to.
+ * @param name The name of the object to be retrieved.
+ * @return The object reference specified.
+ */
+ public Object getObject(String namespace, String name)
+ {
+ try
+ { // convert the namespace name to an ID here
+ PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name);
+ Object rc = null;
+ synchronized (m_properties_sync)
+ { // start by looking in the properties map
+ rc = m_properties.get(key);
+ if (rc==null)
+ { // no use - need to try the database
+ rc = m_ops.getProperty(m_gid,key);
+ if (rc!=null)
+ m_properties.put(key,rc);
+
+ } // end if
+
+ } // end synchronized block
+
+ if (rc==null)
+ throw new NoSuchObjectException(this.toString(),namespace,name);
+ return rc;
+
+ } // end try
+ catch (DatabaseException e)
+ { // translate into our NoSuchObjectException but retain the DatabaseException
+ throw new NoSuchObjectException(this.toString(),namespace,name,e);
+
+ } // end catch
+
+ } // end getObject
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface SecureObjectStore
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object setObject(DynamoUser caller, String namespace, String name, Object value)
+ throws DatabaseException, DynamoSecurityException
+ {
+ testPermission(caller,namespace,"set.property","sec.setGroupProperty");
+ Object rc = null;
+ // convert the namespace name to an ID here
+ PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name);
+ synchronized (m_properties_sync)
+ { // start by setting the database value
+ rc = m_ops.setProperty(m_gid,key,value);
+
+ // and cache it, too
+ m_properties.put(key,value);
+
+ } // end synchronized block
+
+ return rc;
+
+ } // end setObject
+
+ public Object removeObject(DynamoUser caller, String namespace, String name)
+ throws DatabaseException, DynamoSecurityException
+ {
+ testPermission(caller,namespace,"remove.property","sec.removeGroupProperty");
+ Object rc = null;
+ // convert the namespace name to an ID here
+ PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name);
+ synchronized (m_properties_sync)
+ { // start by killing the database value
+ rc = m_ops.removeProperty(m_gid,key);
+
+ // and remove the cached value, too
+ m_properties.remove(key);
+
+ } // end synchronized block
+
+ return rc;
+
+ } // end removeObject
+
+ public Collection getNamespaces() throws DatabaseException
+ {
+ // call through to the database to get the list of namespace IDs
+ int[] ids = m_ops.getPropertyNamespaceIDs(m_gid);
+
+ ArrayList rc = new ArrayList(ids.length);
+ for (int i=0; i.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.util.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.util.*;
+
+abstract class GroupObjectOps extends OpsBase
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ protected GroupObjectOps(DBConnectionPool pool)
+ {
+ super(pool);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Abstract operations
+ *--------------------------------------------------------------------------------
+ */
+
+ abstract Object getProperty(int gid, PropertyKey key) throws DatabaseException;
+
+ abstract Object setProperty(int gid, PropertyKey key, Object value) throws DatabaseException;
+
+ abstract Object removeProperty(int gid, PropertyKey key) throws DatabaseException;
+
+ abstract int[] getPropertyNamespaceIDs(int gid) throws DatabaseException;
+
+ abstract Map getAllProperties(int gid, int namespace) throws DatabaseException;
+
+ abstract boolean testMember(int gid, int uid) throws DatabaseException;
+
+ abstract boolean addMember(int gid, int uid) throws DatabaseException;
+
+ abstract boolean removeMember(int gid, int uid) throws DatabaseException;
+
+ abstract int[] getMembers(int gid) throws DatabaseException;
+
+ abstract void setAclID(int gid, int aclid) throws DatabaseException;
+
+} // end class GroupObjectOps
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/GroupObjectOps_mysql.java b/src/dynamo-framework/com/silverwrist/dynamo/db/GroupObjectOps_mysql.java
new file mode 100644
index 0000000..d82b59f
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/GroupObjectOps_mysql.java
@@ -0,0 +1,556 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.sql.*;
+import java.util.*;
+import com.silverwrist.util.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+class GroupObjectOps_mysql extends GroupObjectOps
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private DBUtilities m_utils;
+ private PropertySerializer m_psz;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ GroupObjectOps_mysql(DBConnectionPool pool, DBUtilities utils)
+ {
+ super(pool);
+ m_utils = utils;
+ m_psz = (PropertySerializer)(pool.queryService(PropertySerializer.class));
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Abstract implementations from class GroupObjectOps
+ *--------------------------------------------------------------------------------
+ */
+
+ Object getProperty(int gid, PropertyKey key) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ String rc_str = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // look up the property
+ stmt = conn.prepareStatement("SELECT prop_value FROM groupprop WHERE gid = ? AND nsid = ? "
+ + "AND prop_name = ?;");
+ stmt.setInt(1,gid);
+ stmt.setInt(2,key.getNamespaceID());
+ stmt.setString(3,key.getName());
+ rs = stmt.executeQuery();
+ if (!(rs.next()))
+ return null; // property not found
+
+ rc_str = rs.getString(1);
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ // Deserialize the property value.
+ Object rc = m_psz.deserializeProperty(rc_str);
+ if (rc!=null)
+ return rc;
+
+ // deserialization exception - throw it
+ DatabaseException de = new DatabaseException(GroupObjectOps_mysql.class,"DatabaseMessages",
+ "property.deserialize");
+ de.setParameter(0,key.getName());
+ throw de;
+
+ } // end getProperty
+
+ Object setProperty(int gid, PropertyKey key, Object value) throws DatabaseException
+ {
+ String serialized_value = m_psz.serializeProperty(value);
+ if (serialized_value==null)
+ { // serialization exception - throw it
+ DatabaseException de = new DatabaseException(GroupObjectOps_mysql.class,"DatabaseMessages",
+ "property.serialize");
+ de.setParameter(0,key.getName());
+ throw de;
+
+ } // end if
+
+ String old_value = null;
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ Statement stmt2 = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // lock the table
+ stmt2 = conn.createStatement();
+ stmt2.executeUpdate("LOCK TABLES groupprop WRITE;");
+
+ // look to see if the property value is already there
+ stmt = conn.prepareStatement("SELECT prop_value FROM groupprop WHERE gid = ? AND nsid = ? "
+ + "AND prop_name = ?;");
+ stmt.setInt(1,gid);
+ stmt.setInt(2,key.getNamespaceID());
+ stmt.setString(3,key.getName());
+ rs = stmt.executeQuery();
+ if (rs.next())
+ old_value = rs.getString(1);
+ SQLUtils.shutdown(rs);
+ rs = null;
+ SQLUtils.shutdown(stmt);
+
+ if (old_value!=null)
+ { // prepare the statement to update the existing record
+ stmt = conn.prepareStatement("UPDATE groupprop SET prop_value = ? WHERE gid = ? "
+ + "AND nsid = ? AND prop_name = ?;");
+ stmt.setString(1,serialized_value);
+ stmt.setInt(2,gid);
+ stmt.setInt(3,key.getNamespaceID());
+ stmt.setString(4,key.getName());
+
+ } // end if
+ else
+ { // prepare the statement to insert a new record
+ stmt = conn.prepareStatement("INSERT INTO groupprop (gid, nsid, prop_name, prop_value) "
+ + "VALUES (?, ?, ?, ?);");
+ stmt.setInt(1,gid);
+ stmt.setInt(2,key.getNamespaceID());
+ stmt.setString(3,key.getName());
+ stmt.setString(4,serialized_value);
+
+ } // end else
+
+ stmt.executeUpdate(); // execute it!
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ MySQLUtils.unlockTables(conn);
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(stmt2);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ if (old_value==null)
+ return null; // no previous value
+
+ // Deserialize the property value.
+ Object rc = m_psz.deserializeProperty(old_value);
+ if (rc!=null)
+ return rc;
+
+ // deserialization exception - throw it
+ DatabaseException de = new DatabaseException(GroupObjectOps_mysql.class,"DatabaseMessages",
+ "property.deserialize");
+ de.setParameter(0,key.getName());
+ throw de;
+
+ } // end setProperty
+
+ Object removeProperty(int gid, PropertyKey key) throws DatabaseException
+ {
+ String old_value = null;
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ Statement stmt2 = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // lock the table
+ stmt2 = conn.createStatement();
+ stmt2.executeUpdate("LOCK TABLES groupprop WRITE;");
+
+ // look to see if the property value is already there
+ stmt = conn.prepareStatement("SELECT prop_value FROM groupprop WHERE gid = ? AND nsid = ? "
+ + "AND prop_name = ?;");
+ stmt.setInt(1,gid);
+ stmt.setInt(2,key.getNamespaceID());
+ stmt.setString(3,key.getName());
+ rs = stmt.executeQuery();
+ if (rs.next())
+ old_value = rs.getString(1);
+ else
+ return null; // no need to remove anything
+ SQLUtils.shutdown(rs);
+ rs = null;
+ SQLUtils.shutdown(stmt);
+
+ // delete the database row
+ stmt = conn.prepareStatement("DELETE FROM groupprop WHERE gid = ? AND nsid = ? AND prop_name = ?;");
+ stmt.setInt(1,gid);
+ stmt.setInt(2,key.getNamespaceID());
+ stmt.setString(3,key.getName());
+ stmt.executeUpdate();
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ MySQLUtils.unlockTables(conn);
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(stmt2);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ // Deserialize the property value.
+ Object rc = m_psz.deserializeProperty(old_value);
+ if (rc!=null)
+ return rc;
+
+ // deserialization exception - throw it
+ DatabaseException de = new DatabaseException(GroupObjectOps_mysql.class,"DatabaseMessages",
+ "property.deserialize");
+ de.setParameter(0,key.getName());
+ throw de;
+
+ } // end removeProperty
+
+ int[] getPropertyNamespaceIDs(int gid) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // execute the query!
+ stmt = conn.prepareStatement("SELECT DISTINCT nsid FROM groupprop WHERE gid = ?;");
+ stmt.setInt(1,gid);
+ rs = stmt.executeQuery();
+
+ // read out a list of the namespace IDs
+ ArrayList tmp = new ArrayList();
+ while (rs.next())
+ tmp.add(new Integer(rs.getInt(1)));
+
+ // create and return the array
+ int[] rc = new int[tmp.size()];
+ for (int i=0; i0);
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ MySQLUtils.unlockTables(conn);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(stmt2);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end removeMember
+
+ int[] getMembers(int gid) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ ArrayList tmp = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // create a query to get all the UIDs
+ stmt = conn.prepareStatement("SELECT uid FROM groupmembers WHERE gid = ?;");
+ stmt.setInt(1,gid);
+ rs = stmt.executeQuery();
+
+ // fill the intermediate ArrayList
+ tmp = new ArrayList();
+ while (rs.next())
+ tmp.add(new Integer(rs.getInt(1)));
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ // now translate into an integer array
+ int[] rc = new int[tmp.size()];
+ for (int i=0; i.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.security.Principal;
+import java.security.acl.AclNotFoundException;
+import java.util.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+
+abstract class GroupProxy implements DynamoGroup, DynamicWrapper
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ protected int m_gid;
+ protected String m_groupname;
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ protected GroupProxy(int gid)
+ {
+ m_gid = gid;
+ m_groupname = null;
+
+ } // end constructor
+
+ protected GroupProxy(int gid, String groupname)
+ {
+ m_gid = gid;
+ m_groupname = groupname;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Abstract operations
+ *--------------------------------------------------------------------------------
+ */
+
+ protected abstract DynamoGroup getRealGroup();
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface Principal
+ *--------------------------------------------------------------------------------
+ */
+
+ public boolean equals(Object another)
+ {
+ if (another==null)
+ return false;
+ if (another instanceof DynamoGroup)
+ return (m_gid==((DynamoGroup)another).getGID());
+ return false;
+
+ } // end equals
+
+ public String toString()
+ {
+ if (m_groupname!=null)
+ return "group " + m_groupname;
+ return getRealGroup().toString();
+
+ } // end toString
+
+ public int hashCode()
+ {
+ return m_gid;
+
+ } // end hashCode
+
+ public String getName()
+ {
+ if (m_groupname!=null)
+ return m_groupname;
+ return getRealGroup().getName();
+
+ } // end getName
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface Group
+ *--------------------------------------------------------------------------------
+ */
+
+ public boolean addMember(Principal user)
+ {
+ return getRealGroup().addMember(user);
+
+ } // end addMember
+
+ public boolean removeMember(Principal user)
+ {
+ return getRealGroup().removeMember(user);
+
+ } // end removeMember
+
+ public boolean isMember(Principal member)
+ {
+ return getRealGroup().isMember(member);
+
+ } // end isMember
+
+ public Enumeration members()
+ {
+ return getRealGroup().members();
+
+ } // end members
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ObjectProvider
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Retrieves an object from this ObjectProvider.
+ *
+ * @param namespace The namespace to interpret the name relative to.
+ * @param name The name of the object to be retrieved.
+ * @return The object reference specified.
+ */
+ public Object getObject(String namespace, String name)
+ {
+ return getRealGroup().getObject(namespace,name);
+
+ } // end getObject
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface SecureObjectStore
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object setObject(DynamoUser caller, String namespace, String name, Object value)
+ throws DatabaseException, DynamoSecurityException
+ {
+ return getRealGroup().setObject(caller,namespace,name,value);
+
+ } // end setObject
+
+ public Object removeObject(DynamoUser caller, String namespace, String name)
+ throws DatabaseException, DynamoSecurityException
+ {
+ return getRealGroup().removeObject(caller,namespace,name);
+
+ } // end removeObject
+
+ public Collection getNamespaces() throws DatabaseException
+ {
+ return getRealGroup().getNamespaces();
+
+ } // end getNamespaces
+
+ public Collection getNamesForNamespace(String namespace) throws DatabaseException
+ {
+ return getRealGroup().getNamesForNamespace(namespace);
+
+ } // end getNamesForNamespace
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface DynamoGroup
+ *--------------------------------------------------------------------------------
+ */
+
+ public int getGID()
+ {
+ return m_gid;
+
+ } // end getGID
+
+ public boolean addUID(DynamoUser caller, int uid) throws DatabaseException, DynamoSecurityException
+ {
+ return getRealGroup().addUID(caller,uid);
+
+ } // end addUID
+
+ public boolean removeUID(DynamoUser caller, int uid) throws DatabaseException, DynamoSecurityException
+ {
+ return getRealGroup().removeUID(caller,uid);
+
+ } // end removeUID
+
+ public boolean testUID(int uid) throws DatabaseException
+ {
+ return getRealGroup().testUID(uid);
+
+ } // end testUID
+
+ public int[] getUIDs() throws DatabaseException
+ {
+ return getRealGroup().getUIDs();
+
+ } // end getUIDs
+
+ public boolean addMember(DynamoUser caller, Principal member)
+ throws DatabaseException, DynamoSecurityException
+ {
+ return getRealGroup().addMember(caller,member);
+
+ } // end addMember
+
+ public boolean removeMember(DynamoUser caller, Principal member)
+ throws DatabaseException, DynamoSecurityException
+ {
+ return getRealGroup().removeMember(caller,member);
+
+ } // end removeMember
+
+ public DynamoAcl getAcl() throws DatabaseException, AclNotFoundException
+ {
+ return getRealGroup().getAcl();
+
+ } // end getAcl
+
+ public void setAcl(DynamoUser caller, DynamoAcl acl) throws DatabaseException, DynamoSecurityException
+ {
+ getRealGroup().setAcl(caller,acl);
+
+ } // end setAcl
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface DynamicWrapper
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object unwrap()
+ {
+ return getRealGroup();
+
+ } // end unwrap
+
+} // end class GroupProxy
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStore.java b/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStore.java
new file mode 100644
index 0000000..5909667
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStore.java
@@ -0,0 +1,42 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.security.Principal;
+import com.silverwrist.dynamo.except.DatabaseException;
+import com.silverwrist.dynamo.except.DynamoSecurityException;
+import com.silverwrist.dynamo.iface.DataItem;
+import com.silverwrist.dynamo.iface.DynamoUser;
+
+public interface ImageStore
+{
+ public DataItem getImage(int id) throws DatabaseException;
+
+ public int saveNewImage(String type_namespace, String type_name, Principal owner, DataItem image)
+ throws DatabaseException;
+
+ public void replaceImage(DynamoUser caller, int image_id, DataItem image)
+ throws DatabaseException, DynamoSecurityException;
+
+ public int findImageID(String type_namespace, String type_name, Principal owner) throws DatabaseException;
+
+ public void deleteImage(DynamoUser caller, int image_id) throws DatabaseException, DynamoSecurityException;
+
+ public DataItem normalizeImage(DataItem source, int width, int height, String new_type) throws Exception;
+
+} // end interface ImageStore
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreObject.java b/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreObject.java
new file mode 100644
index 0000000..ba7b48b
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreObject.java
@@ -0,0 +1,249 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.security.Principal;
+import java.util.*;
+import org.w3c.dom.*;
+import com.silverwrist.util.image.*;
+import com.silverwrist.util.xml.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+public class ImageStoreObject implements NamedObject, ComponentInitialize, ComponentShutdown, ImageStore
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private String m_name; // object name
+ private NamespaceCache m_ns_cache; // namespace cache object
+ private ImageStoreOps m_ops; // image store operations
+ private Hashtable m_imagetype_tlb = new Hashtable(); // translates imagetypes
+ private Hashtable m_imagetype_rev_tlb = new Hashtable(); // translates imagetypes
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public ImageStoreObject()
+ { // do nothing
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
+
+ private final int imageTypeToIndex(PropertyKey pkey) throws DatabaseException
+ {
+ Integer foo = (Integer)(m_imagetype_tlb.get(pkey));
+ if (foo!=null)
+ return foo.intValue();
+
+ int rc = m_ops.imageTypeToIndex(pkey);
+ foo = new Integer(rc);
+ m_imagetype_tlb.put(pkey,foo);
+ m_imagetype_rev_tlb.put(foo,pkey);
+ return rc;
+
+ } // end imageTypeToIndex
+
+ private final int imageTypeToIndex(int nsid, String name) throws DatabaseException
+ {
+ return imageTypeToIndex(new PropertyKey(nsid,name));
+
+ } // end imageTypeToIndex
+
+ private final int imageTypeToIndex(String namespace, String name) throws DatabaseException
+ {
+ return imageTypeToIndex(new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name));
+
+ } // end imageTypeToIndex
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface NamedObject
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getName()
+ {
+ return m_name;
+
+ } // end getName
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ComponentInitialize
+ *--------------------------------------------------------------------------------
+ */
+
+ public void initialize(Element config_root, ServiceProvider services) throws ConfigException
+ {
+ String conn_name = null;
+ String nscache_name = null;
+ XMLLoader loader = XMLLoader.get();
+ try
+ { // verify the right node name
+ loader.verifyNodeName(config_root,"object");
+
+ // get the object's name
+ m_name = loader.getAttribute(config_root,"name");
+
+ // get the database configuration connection
+ DOMElementHelper config_root_h = new DOMElementHelper(config_root);
+ Element elt = loader.getSubElement(config_root_h,"database");
+ conn_name = loader.getAttribute(elt,"connection");
+ nscache_name = loader.getAttribute(elt,"namespaces");
+
+ } // end try
+ catch (XMLLoadException e)
+ { // error loading XML config data
+ throw new ConfigException(e);
+
+ } // end catch
+
+ // Get the database connection pool and namespace cache.
+ DBConnectionPool pool = GetObjectUtils.getDatabaseConnection(services,conn_name);
+ m_ns_cache =
+ (NamespaceCache)(GetObjectUtils.getDynamoComponent(services,NamespaceCache.class,nscache_name));
+
+ // Get the operations object.
+ m_ops = ImageStoreOps.get(pool);
+
+ } // end initialize
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ComponentShutdown
+ *--------------------------------------------------------------------------------
+ */
+
+ public void shutdown()
+ {
+ m_ops.dispose();
+ m_ops = null;
+ m_ns_cache = null;
+
+ } // end shutdown
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ImageStore
+ *--------------------------------------------------------------------------------
+ */
+
+ public DataItem getImage(int id) throws DatabaseException
+ {
+ return m_ops.getImage(id);
+
+ } // end getImage
+
+ public int saveNewImage(String type_namespace, String type_name, Principal owner, DataItem image)
+ throws DatabaseException
+ {
+ int image_type = imageTypeToIndex(type_namespace,type_name);
+ int owner_id = 0, owner_flag = 0;
+ if (owner instanceof DynamoUser)
+ owner_id = ((DynamoUser)owner).getUID();
+ else if (owner instanceof DynamoGroup)
+ { // get the GID
+ owner_id = ((DynamoGroup)owner).getGID();
+ owner_flag = 1;
+
+ } // end else if
+ else
+ throw new DatabaseException(ImageStoreObject.class,"DatabaseMessages","img.badOwner");
+
+ // call down to the database to save it all off
+ return m_ops.saveNewImage(image_type,owner_id,owner_flag,image);
+
+ } // end saveNewImage
+
+ public void replaceImage(DynamoUser caller, int image_id, DataItem image)
+ throws DatabaseException, DynamoSecurityException
+ {
+ if (m_ops.canReplaceImage(caller.getUID(),image_id))
+ m_ops.replaceImage(image_id,image);
+ else
+ { // throw a security exception here
+ DynamoSecurityException dse = new DynamoSecurityException(ImageStoreObject.class,"DatabaseMessages",
+ "img.notOwner");
+ dse.setParameter(0,String.valueOf(image_id));
+ throw dse;
+
+ } // end else
+
+ } // end replaceImage
+
+ public int findImageID(String type_namespace, String type_name, Principal owner) throws DatabaseException
+ {
+ int image_type = imageTypeToIndex(type_namespace,type_name);
+ int owner_id = 0, owner_flag = 0;
+ if (owner instanceof DynamoUser)
+ owner_id = ((DynamoUser)owner).getUID();
+ else if (owner instanceof DynamoGroup)
+ { // get the GID
+ owner_id = ((DynamoGroup)owner).getGID();
+ owner_flag = 1;
+
+ } // end else if
+ else
+ throw new DatabaseException(ImageStoreObject.class,"DatabaseMessages","img.badOwner");
+
+ // call down to find it
+ return m_ops.findImageID(image_type,owner_id,owner_flag);
+
+ } // end findImageID
+
+ public void deleteImage(DynamoUser caller, int image_id) throws DatabaseException, DynamoSecurityException
+ {
+ if (m_ops.canReplaceImage(caller.getUID(),image_id))
+ m_ops.deleteImage(image_id);
+ else
+ { // throw a security exception here
+ DynamoSecurityException dse = new DynamoSecurityException(ImageStoreObject.class,"DatabaseMessages",
+ "img.notOwner");
+ dse.setParameter(0,String.valueOf(image_id));
+ throw dse;
+
+ } // end else
+
+ } // end deleteImage
+
+ public DataItem normalizeImage(DataItem source, int width, int height, String new_type) throws Exception
+ {
+ try
+ { // normalize the image and encapsulate it in a StaticDataItem
+ byte[] data = ImageNormalizer.normalizeImage(source.getDataStream(),width,height,new_type);
+ return new StaticDataItem(source.getName() + "-converted",new_type,data.length,data);
+
+ } // end try
+ catch (ImageNormalizerException e)
+ { // morph the exception
+ ExternalException ee = new ExternalException(ImageStoreObject.class,"DatabaseMessages",
+ "img.normalize",e);
+ ee.setParameter(0,source.getName());
+ ee.setParameter(1,e.getMessage());
+ throw ee;
+
+ } // end catch
+
+ } // end normalizeImage
+
+} // end class ImageStoreObject
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreOps.java b/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreOps.java
new file mode 100644
index 0000000..de65d33
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreOps.java
@@ -0,0 +1,80 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+abstract class ImageStoreOps extends OpsBase
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ protected ImageStoreOps(DBConnectionPool pool)
+ {
+ super(pool);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class OpsBase
+ *--------------------------------------------------------------------------------
+ */
+
+ public void dispose()
+ {
+ super.dispose();
+
+ } // end dispose
+
+ /*--------------------------------------------------------------------------------
+ * Abstract operations
+ *--------------------------------------------------------------------------------
+ */
+
+ abstract int imageTypeToIndex(PropertyKey pkey) throws DatabaseException;
+
+ abstract DataItem getImage(int id) throws DatabaseException;
+
+ abstract int saveNewImage(int typecode, int owner_id, int owner_flag, DataItem image)
+ throws DatabaseException;
+
+ abstract boolean canReplaceImage(int uid, int image_id) throws DatabaseException;
+
+ abstract void replaceImage(int image_id, DataItem image) throws DatabaseException;
+
+ abstract int findImageID(int typecode, int owner_id, int owner_flag) throws DatabaseException;
+
+ abstract void deleteImage(int image_id) throws DatabaseException;
+
+ /*--------------------------------------------------------------------------------
+ * External static operations
+ *--------------------------------------------------------------------------------
+ */
+
+ static ImageStoreOps get(DBConnectionPool pool) throws ConfigException
+ {
+ return (ImageStoreOps)get(pool,ImageStoreOps.class.getClassLoader(),
+ ImageStoreOps.class.getName() + "_","ImageStoreOps");
+
+ } // end get
+
+} // end class ImageStoreOps
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreOps_mysql.java b/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreOps_mysql.java
new file mode 100644
index 0000000..cfa1619
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/ImageStoreOps_mysql.java
@@ -0,0 +1,363 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.io.*;
+import java.sql.*;
+import java.util.*;
+import com.silverwrist.util.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+public class ImageStoreOps_mysql extends ImageStoreOps
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public ImageStoreOps_mysql(DBConnectionPool pool)
+ {
+ super(pool);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Abstract implementations from class ImageStoreOps
+ *--------------------------------------------------------------------------------
+ */
+
+ int imageTypeToIndex(PropertyKey pkey) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ Statement stmt2 = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // lock the table while we work
+ stmt2 = conn.createStatement();
+ stmt2.executeUpdate("LOCK TABLES imagetype WRITE;");
+
+ // first try to look the index up
+ stmt = conn.prepareStatement("SELECT typecode FROM imagetype WHERE nsid = ? AND name = ?;");
+ stmt.setInt(1,pkey.getNamespaceID());
+ stmt.setString(2,pkey.getName());
+ rs = stmt.executeQuery();
+ if (rs.next())
+ return rs.getInt(1);
+
+ // then add it
+ SQLUtils.shutdown(rs);
+ rs = null;
+ SQLUtils.shutdown(stmt);
+ stmt = conn.prepareStatement("INSERT INTO imagetype (nsid, name) VALUES (?, ?);");
+ stmt.setInt(1,pkey.getNamespaceID());
+ stmt.setString(2,pkey.getName());
+ stmt.executeUpdate();
+ return MySQLUtils.getLastInsertInt(conn);
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ MySQLUtils.unlockTables(conn);
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(stmt2);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end imageTypeToIndex
+
+ DataItem getImage(int id) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // Start by getting the MIME type and image length.
+ stmt = conn.prepareStatement("SELECT mimetype, length FROM imagestore WHERE imageid = ?;");
+ stmt.setInt(1,id);
+ rs = stmt.executeQuery();
+ if (!(rs.next()))
+ return null;
+ String mime_type = rs.getString(1);
+ int length = rs.getInt(2);
+
+ // Now get the actual data blob.
+ SQLUtils.shutdown(rs);
+ rs = null;
+ SQLUtils.shutdown(stmt);
+ stmt = conn.prepareStatement("SELECT data FROM imagestore WHERE imageid = ?;");
+ stmt.setInt(1,id);
+ rs = stmt.executeQuery();
+ if (!(rs.next()))
+ return null;
+
+ // We need to copy the data blob into a local buffer. We also mesh the whole thing into a DataItem.
+ return new StaticDataItem("image" + id,mime_type,length,IOUtils.load(rs.getBinaryStream(1)));
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ catch (IOException e)
+ { // turn IOException into DatabaseException too
+ DatabaseException de = new DatabaseException(ImageStoreOps_mysql.class,"DatabaseMessages",
+ "img.loadFail",e);
+ de.setParameter(0,String.valueOf(id));
+ throw de;
+
+ } // end catch
+ finally
+ { // shut everything down
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end getImage
+
+ int saveNewImage(int typecode, int owner_id, int owner_flag, DataItem image) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ Statement stmt2 = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // lock the table while we work
+ stmt2 = conn.createStatement();
+ stmt2.executeUpdate("LOCK TABLES imagestore WRITE;");
+
+ // insert all the "base" information
+ stmt = conn.prepareStatement("INSERT INTO imagestore (typecode, ownerid, ownerflag, mimetype, length) "
+ + "VALUES (?, ?, ?, ?, ?);");
+ stmt.setInt(1,typecode);
+ stmt.setInt(2,owner_id);
+ stmt.setInt(3,owner_flag);
+ stmt.setString(4,image.getMimeType());
+ stmt.setInt(5,image.getSize());
+ stmt.executeUpdate();
+ int rc = MySQLUtils.getLastInsertInt(conn);
+
+ // insert the file data itself
+ SQLUtils.shutdown(stmt);
+ stmt = conn.prepareStatement("UPDATE imagestore SET data = ? WHERE imageid = ?;");
+ stmt.setBlob(1,image.getBlob());
+ stmt.setInt(2,rc);
+ stmt.executeUpdate();
+
+ return rc; // all done!
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ MySQLUtils.unlockTables(conn);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(stmt2);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end saveNewImage
+
+ boolean canReplaceImage(int uid, int image_id) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // get the owner ID and flag from the image records
+ stmt = conn.prepareStatement("SELECT ownerid, ownerflag FROM imagestore WHERE imageid = ?;");
+ stmt.setInt(1,image_id);
+ rs = stmt.executeQuery();
+ if (!(rs.next()))
+ return false;
+ int owner_id = rs.getInt(1);
+ if (rs.getInt(2)==0) // a user owns it
+ return (uid==owner_id);
+
+ // Test group membership for ownership.
+ SQLUtils.shutdown(rs);
+ rs = null;
+ SQLUtils.shutdown(stmt);
+ stmt = conn.prepareStatement("SELECT uid FROM groupmembers WHERE uid = ? AND gid = ?;");
+ stmt.setInt(1,uid);
+ stmt.setInt(2,owner_id);
+ rs = stmt.executeQuery();
+ return rs.next();
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end canReplaceImage
+
+ void replaceImage(int image_id, DataItem image) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ Statement stmt2 = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // lock the table while we work
+ stmt2 = conn.createStatement();
+ stmt2.executeUpdate("LOCK TABLES imagestore WRITE;");
+
+ // poke in the basic data items first
+ stmt = conn.prepareStatement("UPDATE imagestore SET mimetype = ?, length = ?, data = NULL "
+ + "WHERE imageid = ?;");
+ stmt.setString(1,image.getMimeType());
+ stmt.setInt(2,image.getSize());
+ stmt.setInt(3,image_id);
+ stmt.executeUpdate();
+
+ // insert the new file data itself
+ SQLUtils.shutdown(stmt);
+ stmt = conn.prepareStatement("UPDATE imagestore SET data = ? WHERE imageid = ?;");
+ stmt.setBlob(1,image.getBlob());
+ stmt.setInt(2,image_id);
+ stmt.executeUpdate();
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ MySQLUtils.unlockTables(conn);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(stmt2);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end replaceImage
+
+ int findImageID(int typecode, int owner_id, int owner_flag) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // create statement and run it
+ stmt = conn.prepareStatement("SELECT imageid FROM imagestore WHERE typecode = ? AND ownerid = ? "
+ + "AND ownerflag = ?;");
+ stmt.setInt(1,typecode);
+ stmt.setInt(2,owner_id);
+ stmt.setInt(3,owner_flag);
+ rs = stmt.executeQuery();
+ if (rs.next())
+ return rs.getInt(1);
+ else
+ return -1;
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end findImageID
+
+ void deleteImage(int image_id) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ Statement stmt2 = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // lock the table while we work
+ stmt2 = conn.createStatement();
+ stmt2.executeUpdate("LOCK TABLES imagestore WRITE;");
+
+ // delete it!
+ stmt = conn.prepareStatement("DELETE FROM imagestore WHERE imageid = ?;");
+ stmt.setInt(1,image_id);
+ stmt.executeUpdate();
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ MySQLUtils.unlockTables(conn);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(stmt2);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end deleteImage
+
+} // end class ImageStoreOps_mysql
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCache.java b/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCache.java
new file mode 100644
index 0000000..9b1d375
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCache.java
@@ -0,0 +1,28 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import com.silverwrist.dynamo.except.DatabaseException;
+
+public interface NamespaceCache
+{
+ public int namespaceNameToId(String name) throws DatabaseException;
+
+ public String namespaceIdToName(int id) throws DatabaseException;
+
+} // end interface NamespaceCache
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheObject.java b/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheObject.java
new file mode 100644
index 0000000..d157027
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheObject.java
@@ -0,0 +1,143 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.util.*;
+import org.w3c.dom.*;
+import com.silverwrist.util.xml.*;
+import com.silverwrist.dynamo.Namespaces;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+public class NamespaceCacheObject
+ implements NamedObject, ComponentInitialize, ComponentShutdown, NamespaceCache
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private String m_name; // object name
+ private NamespaceCacheOps m_ops; // low-level database operations
+ private HashMap m_cache = new HashMap(); // namespace cache object
+ private HashMap m_rev_cache = new HashMap(); // namespace reverse cache object
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public NamespaceCacheObject()
+ {
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface NamedObject
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getName()
+ {
+ return m_name;
+
+ } // end getName
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ComponentInitialize
+ *--------------------------------------------------------------------------------
+ */
+
+ public void initialize(Element config_root, ServiceProvider services) throws ConfigException
+ {
+ String conn_name = null;
+ XMLLoader loader = XMLLoader.get();
+ try
+ { // verify the right node name
+ loader.verifyNodeName(config_root,"object");
+
+ // get the object's name
+ m_name = loader.getAttribute(config_root,"name");
+
+ // get the database configuration connection
+ Element elt = loader.getSubElement(config_root,"database");
+ conn_name = loader.getAttribute(elt,"connection");
+
+ } // end try
+ catch (XMLLoadException e)
+ { // error loading XML config data
+ throw new ConfigException(e);
+
+ } // end catch
+
+ // Get the database connection pool.
+ DBConnectionPool pool = GetObjectUtils.getDatabaseConnection(services,conn_name);
+
+ // Get the database operations class.
+ m_ops = NamespaceCacheOps.get(pool);
+
+ } // end initialize
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ComponentShutdown
+ *--------------------------------------------------------------------------------
+ */
+
+ public void shutdown()
+ {
+ m_ops.dispose();
+ m_ops = null;
+
+ } // end shutdown
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface NamespaceCache
+ *--------------------------------------------------------------------------------
+ */
+
+ public synchronized int namespaceNameToId(String name) throws DatabaseException
+ {
+ Integer rc = (Integer)(m_cache.get(name));
+ if (rc!=null)
+ return rc.intValue();
+ int real_id = m_ops.namespaceNameToId(name);
+ rc = new Integer(real_id);
+ name = name.intern();
+ m_cache.put(name,rc);
+ m_rev_cache.put(rc,name);
+ return real_id;
+
+ } // end namespaceNameToId
+
+ public synchronized String namespaceIdToName(int id) throws DatabaseException
+ {
+ Integer key = new Integer(id);
+ String rc = (String)(m_rev_cache.get(key));
+ if (rc!=null)
+ return rc;
+ rc = m_ops.namespaceIdToName(id);
+ if (rc==null)
+ throw new DatabaseException(NamespaceCacheObject.class,"DatabaseMessages","nsCache.notFound");
+ rc = rc.intern();
+ m_cache.put(rc,key);
+ m_rev_cache.put(key,rc);
+ return rc;
+
+ } // end namespaceIdToName
+
+} // end class NamespaceCacheObject
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheOps.java b/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheOps.java
new file mode 100644
index 0000000..ad5d0c8
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheOps.java
@@ -0,0 +1,69 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.lang.reflect.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+
+abstract class NamespaceCacheOps extends OpsBase
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ protected NamespaceCacheOps(DBConnectionPool pool)
+ {
+ super(pool);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class OpsBase
+ *--------------------------------------------------------------------------------
+ */
+
+ public void dispose()
+ {
+ super.dispose();
+
+ } // end dispose
+
+ /*--------------------------------------------------------------------------------
+ * Abstract operations
+ *--------------------------------------------------------------------------------
+ */
+
+ abstract int namespaceNameToId(String name) throws DatabaseException;
+
+ abstract String namespaceIdToName(int id) throws DatabaseException;
+
+ /*--------------------------------------------------------------------------------
+ * External static operations
+ *--------------------------------------------------------------------------------
+ */
+
+ static NamespaceCacheOps get(DBConnectionPool pool) throws ConfigException
+ {
+ return (NamespaceCacheOps)get(pool,NamespaceCacheOps.class.getClassLoader(),
+ NamespaceCacheOps.class.getName() + "_","NamespaceCacheOps");
+
+ } // end get
+
+} // end class NamespaceCacheOps
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheOps_mysql.java b/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheOps_mysql.java
new file mode 100644
index 0000000..7b01d95
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/NamespaceCacheOps_mysql.java
@@ -0,0 +1,132 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.sql.*;
+import java.util.*;
+import com.silverwrist.util.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+
+public class NamespaceCacheOps_mysql extends NamespaceCacheOps
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public NamespaceCacheOps_mysql(DBConnectionPool pool)
+ {
+ super(pool);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Abstract implementations from class NamespaceCacheOps
+ *--------------------------------------------------------------------------------
+ */
+
+ int namespaceNameToId(String name) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ Statement stmt2 = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // lock the table while we do this
+ stmt2 = conn.createStatement();
+ stmt2.executeUpdate("LOCK TABLES namespaces WRITE;");
+
+ // try the initial SELECT to see if it works
+ stmt = conn.prepareStatement("SELECT nsid FROM namespaces WHERE namespace = ?;");
+ stmt.setString(1,name);
+ rs = stmt.executeQuery();
+ if (rs.next())
+ return rs.getInt(1);
+
+ // it wasn't present - try adding it
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ stmt = conn.prepareStatement("INSERT INTO namespaces (namespace) VALUES (?);");
+ stmt.setString(1,name);
+ stmt.executeUpdate();
+ return MySQLUtils.getLastInsertInt(conn);
+
+ } // end try
+ catch (SQLException e)
+ { // translate this to a DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ MySQLUtils.unlockTables(conn);
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(stmt2);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end namespaceNameToId
+
+ String namespaceIdToName(int id) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ Statement stmt2 = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // lock the table while we do this
+ stmt2 = conn.createStatement();
+ stmt2.executeUpdate("LOCK TABLES namespaces READ;");
+
+ // try the SELECT to see if it works
+ stmt = conn.prepareStatement("SELECT namespace FROM namespaces WHERE nsid = ?;");
+ stmt.setInt(1,id);
+ rs = stmt.executeQuery();
+ if (rs.next())
+ return rs.getString(1);
+ else
+ return null;
+
+ } // end try
+ catch (SQLException e)
+ { // translate the exception and rethrow
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ MySQLUtils.unlockTables(conn);
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(stmt2);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end namespaceIdToName
+
+} // end class NamespaceCacheOps_mysql
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/OpsBase.java b/src/dynamo-framework/com/silverwrist/dynamo/db/OpsBase.java
new file mode 100644
index 0000000..bbc7a96
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/OpsBase.java
@@ -0,0 +1,118 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.lang.reflect.*;
+import java.sql.Connection;
+import java.sql.SQLException;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+
+public class OpsBase
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final Class[] ARGS_CLASS = { DBConnectionPool.class };
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private DBConnectionPool m_pool;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ protected OpsBase(DBConnectionPool pool)
+ {
+ m_pool = pool;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
+
+ protected final DBConnectionPool getPool()
+ {
+ return m_pool;
+
+ } // end getPool
+
+ protected final Connection getConnection() throws DatabaseException
+ {
+ return new WrappedConnection(m_pool,m_pool.getConnection());
+
+ } // end getConnection
+
+ protected final DatabaseException generalException(SQLException e)
+ {
+ DatabaseException dbe = new DatabaseException(OpsBase.class,"DatabaseMessages","general",e);
+ dbe.setParameter(0,e.getMessage());
+ return dbe;
+
+ } // end generalException
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ public void dispose()
+ {
+ m_pool = null;
+
+ } // end dispose
+
+ /*--------------------------------------------------------------------------------
+ * External static operations
+ *--------------------------------------------------------------------------------
+ */
+
+ protected static Object get(DBConnectionPool pool, ClassLoader loader, String stem_name, String type)
+ throws ConfigException
+ {
+ try
+ { // load the specified ops class and return a new instance
+ String klassname = stem_name + pool.getDatabaseType().toLowerCase();
+ Constructor c = loader.loadClass(klassname).getConstructor(ARGS_CLASS);
+ Object[] args = new Object[1];
+ args[0] = pool;
+ return c.newInstance(args);
+
+ } // end try
+ catch (Exception e)
+ { // error loading the ops class...
+ ConfigException ce = new ConfigException(OpsBase.class,"DatabaseMessages","load.opsClass",e);
+ ce.setParameter(0,e.getMessage());
+ ce.setParameter(1,pool.getDatabaseType());
+ ce.setParameter(2,type);
+ throw ce;
+
+ } // end catch
+
+ } // end get
+
+} // end class OpsBase
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagement.java b/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagement.java
new file mode 100644
index 0000000..52f420f
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagement.java
@@ -0,0 +1,42 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.util.Collection;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+
+public interface UserManagement
+{
+ public DynamoUser getAnonymousUser() throws DatabaseException;
+
+ public DynamoUser getUser(int id) throws DatabaseException;
+
+ public DynamoUser getUser(String username) throws DatabaseException;
+
+ public DynamoUser createUser(String username, String email) throws DatabaseException;
+
+ public DynamoGroup getGroup(int id) throws DatabaseException;
+
+ public DynamoGroup getGroup(String groupname) throws DatabaseException;
+
+ public DynamoGroup createGroup(String groupname) throws DatabaseException;
+
+ public void loadUserDefaults(DynamoUser user, Collection namespaces) throws DatabaseException;
+
+} // end interface UserManagement
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerObject.java b/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerObject.java
new file mode 100644
index 0000000..6b84b3b
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerObject.java
@@ -0,0 +1,987 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.lang.ref.*;
+import java.util.*;
+import org.w3c.dom.*;
+import com.silverwrist.util.xml.*;
+import com.silverwrist.dynamo.UserInfoNamespace;
+import com.silverwrist.dynamo.event.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.security.SecurityReferenceMonitor;
+import com.silverwrist.dynamo.util.*;
+
+public class UserManagerObject
+ implements NamedObject, ComponentInitialize, ComponentShutdown, UserManagement, UserProxyManagement,
+ AuthenticatorRegistration, UserInfoNamespace, UserPropertyTranslatorInstall
+{
+ /*--------------------------------------------------------------------------------
+ * Internal class implementing user proxies
+ *--------------------------------------------------------------------------------
+ */
+
+ private class MyUserProxy extends UserProxy
+ {
+ /*====================================================================
+ * Attributes
+ *====================================================================
+ */
+
+ private DynamoUser m_real_user = null;
+
+ /*====================================================================
+ * Constructors
+ *====================================================================
+ */
+
+ MyUserProxy(int uid)
+ {
+ super(uid);
+
+ } // end constructor
+
+ MyUserProxy(int uid, String username)
+ {
+ super(uid,username);
+
+ } // end constructor
+
+ /*====================================================================
+ * Abstract implementations from class UserProxy
+ *====================================================================
+ */
+
+ protected synchronized DynamoUser getRealUser()
+ {
+ if (m_real_user==null)
+ { // need to retrieve the real user...
+ try
+ { // get the real user...
+ m_real_user = UserManagerObject.this.getUser(m_uid);
+
+ } // end try
+ catch (DatabaseException e)
+ { // wrap it in a runtime exception type
+ throw new ProxyException(e);
+
+ } // end catch
+
+ } // end if
+
+ return m_real_user;
+
+ } // end getRealUser
+
+ } // end class MyUserProxy
+
+ /*--------------------------------------------------------------------------------
+ * Internal class implementing group proxies
+ *--------------------------------------------------------------------------------
+ */
+
+ private class MyGroupProxy extends GroupProxy
+ {
+ /*====================================================================
+ * Attributes
+ *====================================================================
+ */
+
+ private DynamoGroup m_real_group = null;
+
+ /*====================================================================
+ * Constructors
+ *====================================================================
+ */
+
+ MyGroupProxy(int gid)
+ {
+ super(gid);
+
+ } // end constructor
+
+ MyGroupProxy(int gid, String groupname)
+ {
+ super(gid,groupname);
+
+ } // end constructor
+
+ /*====================================================================
+ * Abstract implementations from class UserProxy
+ *====================================================================
+ */
+
+ protected synchronized DynamoGroup getRealGroup()
+ {
+ if (m_real_group==null)
+ { // need to retrieve the real group...
+ try
+ { // get the real group...
+ m_real_group = UserManagerObject.this.getGroup(m_gid);
+
+ } // end try
+ catch (DatabaseException e)
+ { // wrap it in a runtime exception type
+ throw new ProxyException(e);
+
+ } // end catch
+
+ } // end if
+
+ return m_real_group;
+
+ } // end getRealGroup
+
+ } // end class MyGroupProxy
+
+ /*--------------------------------------------------------------------------------
+ * Internal event listener class
+ *--------------------------------------------------------------------------------
+ */
+
+ private class UpdateListener implements DynamicUpdateListener
+ {
+ /*====================================================================
+ * Constructor
+ *====================================================================
+ */
+
+ UpdateListener()
+ { // do nothing
+ } // end constructor
+
+ /*====================================================================
+ * Implementations from interface DynamicUpdateListener
+ *====================================================================
+ */
+
+ public void updateReceived(DynamicUpdateEvent evt)
+ {
+ if (evt instanceof UserUpdateEvent)
+ { // try to pass the event on to the user
+ int uid = ((UserUpdateEvent)evt).getUID();
+ Integer key = new Integer(uid);
+ synchronized (m_users_sync)
+ { // try looking in the cache for a UserObject
+ IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_user.get(key));
+ if (cobj!=null)
+ { // got a cache object - retrieve the user value
+ UserObject target = (UserObject)(cobj.get());
+ if (target==null)
+ { // the UserObject got kicked out! kick it out of the HashMaps
+ m_id_to_user.remove(key);
+ m_name_to_user.remove(cobj.getNameKey());
+ cobj.clear();
+ cobj = null;
+
+ } // end if
+ else if (target!=evt.getSource())
+ target.updated((UserUpdateEvent)evt);
+
+ } // end if
+
+ } // end synchronized block
+
+ } // end if
+
+ } // end updateReceived
+
+ } // end class UpdateListener
+
+ /*--------------------------------------------------------------------------------
+ * Internal property serializer class
+ *--------------------------------------------------------------------------------
+ */
+
+ private class UserGroupSerializer implements PropertySerializer
+ {
+ /*====================================================================
+ * Constructor
+ *====================================================================
+ */
+
+ UserGroupSerializer()
+ { // do nothing
+ } // end constructor
+
+ /*====================================================================
+ * Implementations from interface PropertySerializer
+ *====================================================================
+ */
+
+ public String serializeProperty(Object value)
+ {
+ if (value instanceof DynamoUser)
+ return "User:" + String.valueOf(((DynamoUser)value).getUID());
+
+ if (value instanceof DynamoGroup)
+ return "Group:" + String.valueOf(((DynamoGroup)value).getGID());
+
+ return null;
+
+ } // end serializeProperty
+
+ public Object deserializeProperty(String value)
+ {
+ try
+ { // look for our known prefixes
+ if (value.startsWith("User:"))
+ return getUserProxy(Integer.parseInt(value.substring(5)));
+
+ if (value.startsWith("Group:"))
+ return getGroupProxy(Integer.parseInt(value.substring(6)));
+
+ return null;
+
+ } // end try
+ catch (NumberFormatException e)
+ { // number parse blew up...
+ return null;
+
+ } // end catch
+
+ } // end deserializeProperty
+
+ } // end UserGroupSerializer
+
+ /*--------------------------------------------------------------------------------
+ * Internal class implementing the adapter for UserPropertyTranslator
+ *--------------------------------------------------------------------------------
+ */
+
+ class UserPropertyAdapter implements UserPropertyTranslator
+ {
+ /*====================================================================
+ * Attributes
+ *====================================================================
+ */
+
+ private UserPropertyTranslator m_upt = null;
+
+ /*====================================================================
+ * Constructor
+ *====================================================================
+ */
+
+ UserPropertyAdapter()
+ { // do nothing
+ } // end constructor
+
+ /*====================================================================
+ * Implementations from interface UserPropertyTranslator
+ *====================================================================
+ */
+
+ public String getUserFullName(DynamoUser user)
+ {
+ if (m_upt!=null)
+ return m_upt.getUserFullName(user);
+ else
+ return user.getName();
+
+ } // end getUserFullName
+
+ /*====================================================================
+ * External operations
+ *====================================================================
+ */
+
+ void setTranslator(UserPropertyTranslator upt)
+ {
+ m_upt = upt;
+
+ } // end setTranslator
+
+ } // end class UserPropertyAdapter
+
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final int MAX_USERNAME = 64;
+ private static final int MAX_GROUPNAME = 64;
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private UserPropertyAdapter m_adapter; // user property adapter
+ private String m_name; // object name
+ private NamespaceCache m_ns_cache; // namespace cache object
+ private SecurityReferenceMonitor m_srm; // security reference monitor
+ private PostDynamicUpdate m_post; // dynamic update poster
+ private UserManagerOps m_ops; // database operations object
+ private UserObject m_anon_user = null; // permanent reference to anonymous user
+ private Object m_anon_user_sync = new Object(); // synchronization on the above field
+ private HashMap m_id_to_user = new HashMap(); // map from IDs (Integer) to objects
+ private HashMap m_name_to_user = new HashMap(); // map from names (DynamoIDKey) to objects
+ private ReferenceQueue m_rq = new ReferenceQueue(); // reference queue for old objects
+ private Object m_users_sync = new Object(); // synchronization for user HashMaps
+ private HashMap m_id_to_group = new HashMap(); // map from IDs (Integer) to groups
+ private HashMap m_name_to_group = new HashMap(); // map from names (DynamoIDKey) to groups
+ private ReferenceQueue m_group_rq = new ReferenceQueue(); // reference queue for group objects
+ private Object m_groups_sync = new Object(); // synchronization for group HashMaps
+ private Hashtable m_authenticators = new Hashtable(); // authenticators list
+ private ComponentShutdown m_hook_init; // hook for init service provider
+ private ComponentShutdown m_pszreg; // property serializer registration
+ private ComponentShutdown m_evt_user; // event registration
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public UserManagerObject()
+ {
+ m_adapter = new UserPropertyAdapter(); // create the adapter
+
+ // Add some default authenticators.
+ m_authenticators.put(new QualifiedNameKey(NAMESPACE,AUTH_DEFAULT),new DefaultHashAuthenticator());
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface NamedObject
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getName()
+ {
+ return m_name;
+
+ } // end getName
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ComponentInitialize
+ *--------------------------------------------------------------------------------
+ */
+
+ public void initialize(Element config_root, ServiceProvider services) throws ConfigException
+ {
+ String conn_name = null;
+ String nscache_name = null;
+ String srm_name = null;
+ String connect_name = null;
+ XMLLoader loader = XMLLoader.get();
+ try
+ { // verify the right node name
+ loader.verifyNodeName(config_root,"object");
+
+ // get the object's name
+ m_name = loader.getAttribute(config_root,"name");
+
+ // get the database configuration connection
+ DOMElementHelper config_root_h = new DOMElementHelper(config_root);
+ Element elt = loader.getSubElement(config_root_h,"database");
+ conn_name = loader.getAttribute(elt,"connection");
+ nscache_name = loader.getAttribute(elt,"namespaces");
+
+ // get the security reference monitor reference
+ elt = loader.getSubElement(config_root_h,"security");
+ srm_name = loader.getAttribute(elt,"object");
+
+ // get the name of the connection point to connect ourselves to
+ elt = config_root_h.getSubElement("connect-proxy-services");
+ if (elt!=null)
+ connect_name = loader.getAttribute(elt,"cpoint");
+
+ } // end try
+ catch (XMLLoadException e)
+ { // error loading XML config data
+ throw new ConfigException(e);
+
+ } // end catch
+
+ // Get the database connection pool, namespace cache, and security reference monitor.
+ DBConnectionPool pool = GetObjectUtils.getDatabaseConnection(services,conn_name);
+ m_ns_cache =
+ (NamespaceCache)(GetObjectUtils.getDynamoComponent(services,NamespaceCache.class,nscache_name));
+ m_srm =
+ (SecurityReferenceMonitor)(GetObjectUtils.getDynamoComponent(services,SecurityReferenceMonitor.class,
+ srm_name));
+ m_post = (PostDynamicUpdate)(services.queryService(PostDynamicUpdate.class));
+
+ // Get the operations object.
+ m_ops = UserManagerOps.get(pool);
+
+ // Connect our proxy services to the connection point.
+ if (connect_name!=null)
+ { // get the ConnectionBackend service and use it to jack in
+ ConnectionBackEnd backend = (ConnectionBackEnd)(services.queryService(ConnectionBackEnd.class));
+ backend.connectObject(connect_name,this);
+
+ } // end if
+
+ // Register event listeners that forward events to the right location.
+ EventListenerRegistration reg =
+ (EventListenerRegistration)(services.queryService(EventListenerRegistration.class));
+ UpdateListener ul = new UpdateListener();
+ m_evt_user = reg.registerDynamicUpdateListener(UserUpdateEvent.class,ul);
+
+ // Register our property serializer to let User and Group objects be serialized.
+ PropertySerializerRegistration psreg =
+ (PropertySerializerRegistration)(services.queryService(PropertySerializerRegistration.class));
+ m_pszreg = psreg.registerPropertySerializer(new UserGroupSerializer());
+
+ // Add us to the initialization services.
+ HookServiceProviders hooker = (HookServiceProviders)(services.queryService(HookServiceProviders.class));
+ SingletonServiceProvider ssp = new SingletonServiceProvider("UserManagerObject",
+ AuthenticatorRegistration.class,
+ (AuthenticatorRegistration)this);
+ m_hook_init = hooker.hookInitServiceProvider(ssp);
+
+ } // end initialize
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ComponentShutdown
+ *--------------------------------------------------------------------------------
+ */
+
+ public void shutdown()
+ {
+ m_evt_user.shutdown();
+ m_evt_user = null;
+ m_pszreg.shutdown();
+ m_pszreg = null;
+ m_hook_init.shutdown();
+ m_hook_init = null;
+ m_authenticators.clear();
+ m_id_to_user.clear();
+ m_name_to_user.clear();
+ m_anon_user = null;
+ m_ops.dispose();
+ m_ops = null;
+ m_post = null;
+ m_srm = null;
+ m_ns_cache = null;
+
+ } // end shutdown
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface UserManagement
+ *--------------------------------------------------------------------------------
+ */
+
+ public DynamoUser getAnonymousUser() throws DatabaseException
+ {
+ synchronized (m_anon_user_sync)
+ { // get the anonymous user, if it doesn't already exist
+ if (m_anon_user==null)
+ { // get the data for the anonymous user
+ Map data = m_ops.getAnonymousUserData();
+ if (data==null)
+ throw new DatabaseException(UserManagerObject.class,"UserMessages","anon.notFound");
+ m_anon_user = new UserObject(data,true,m_ops.getObjectOps(),m_ns_cache,m_srm,this,m_post,m_adapter);
+
+ } // end if
+
+ return m_anon_user;
+
+ } // end synchronized block
+
+ } // end getAnonymousUser
+
+ public DynamoUser getUser(int id) throws DatabaseException
+ {
+ DynamoUser rc = getAnonymousUser();
+ if (rc.getUID()==id)
+ return rc;
+
+ rc = null;
+ Integer key = new Integer(id);
+ synchronized (m_users_sync)
+ { // try to retrieve the user
+ IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_user.get(key));
+ if (cobj!=null)
+ { // got a cache object - retrieve the user value
+ rc = (DynamoUser)(cobj.get());
+ if (rc==null)
+ { // the UserObject got kicked out! kick it out of the HashMaps
+ m_id_to_user.remove(key);
+ m_name_to_user.remove(cobj.getNameKey());
+ cobj.clear();
+ cobj = null;
+
+ } // end if
+
+ } // end if
+
+ if (rc==null)
+ { // OK, we have to go to the database to find the user
+ Map data = m_ops.getUserData(id);
+ if (data!=null)
+ { // create UserObject and add it to our cache maps
+ UserObject uobj = new UserObject(data,false,m_ops.getObjectOps(),m_ns_cache,m_srm,this,m_post,
+ m_adapter);
+ rc = uobj;
+ cobj = new IDNameCacheObject(key,uobj.getName(),uobj,m_rq);
+ m_id_to_user.put(cobj.getIDKey(),cobj);
+ m_name_to_user.put(cobj.getNameKey(),cobj);
+
+ } // end if
+ // else user does not exist - return null
+
+ } // end if
+
+ } // end synchronized block
+
+ return rc;
+
+ } // end getUser
+
+ public DynamoUser getUser(String username) throws DatabaseException
+ {
+ DynamoUser rc = getAnonymousUser();
+ if (rc.getName().equalsIgnoreCase(username))
+ return rc;
+
+ rc = null;
+ DynamoIDKey key = new DynamoIDKey(username);
+ synchronized (m_users_sync)
+ { // try to retrieve the user
+ IDNameCacheObject cobj = (IDNameCacheObject)(m_name_to_user.get(key));
+ if (cobj!=null)
+ { // got a cache object - retrieve the user value
+ rc = (DynamoUser)(cobj.get());
+ if (rc==null)
+ { // the UserObject got kicked out! kick it out of the HashMaps
+ m_id_to_user.remove(cobj.getIDKey());
+ m_name_to_user.remove(key);
+ cobj.clear();
+ cobj = null;
+
+ } // end if
+
+ } // end if
+
+ if (rc==null)
+ { // OK, we have to go to the database to find the user
+ Map data = m_ops.getUserData(username);
+ if (data!=null)
+ { // create user object and add it to our cache maps
+ UserObject uobj = new UserObject(data,false,m_ops.getObjectOps(),m_ns_cache,m_srm,this,m_post,
+ m_adapter);
+ rc = uobj;
+ cobj = new IDNameCacheObject(uobj.getUID(),key,uobj,m_rq);
+ m_id_to_user.put(cobj.getIDKey(),cobj);
+ m_name_to_user.put(cobj.getNameKey(),cobj);
+
+ } // end if
+ // else user does not exist - return null
+
+ } // end if
+
+ } // end synchronized block
+
+ return rc;
+
+ } // end getUser
+
+ public DynamoUser createUser(String username, String email) throws DatabaseException
+ {
+ DynamoUser rc = getAnonymousUser();
+ if (rc.getName().equalsIgnoreCase(username))
+ { // this user already exists
+ DatabaseException de = new DatabaseException(UserManagerObject.class,"UserMessages","user.exists");
+ de.setParameter(0,username);
+ throw de;
+
+ } // end if
+
+ DynamoIDKey key = new DynamoIDKey(username);
+ if (!(key.isValid(MAX_USERNAME)))
+ { // the user ID is invalid...
+ DatabaseException de = new DatabaseException(UserManagerObject.class,"UserMessages","user.badID");
+ de.setParameter(0,username);
+ throw de;
+
+ } // end if
+
+ rc = null;
+ synchronized (m_users_sync)
+ { // see if the user is in our cache already
+ IDNameCacheObject cobj = (IDNameCacheObject)(m_name_to_user.get(key));
+ if (cobj!=null)
+ { // it's in the cache - we're going to fail this operation. But while we're here, if the
+ // actual user object has been kicked out, expunge the reference.
+ if (cobj.get()==null)
+ { // the UserObject got kicked out! kick it out of the HashMaps
+ m_id_to_user.remove(cobj.getIDKey());
+ m_name_to_user.remove(key);
+ cobj.clear();
+ cobj = null;
+
+ } // end if
+
+ // throw the exception saying that we exist
+ DatabaseException de = new DatabaseException(UserManagerObject.class,"UserMessages","user.exists");
+ de.setParameter(0,username);
+ throw de;
+
+ } // end if
+
+ // OK, at this point, we can't be any surer the user doesn't already exist without
+ // hitting the database. So create it. (createNewUser will throw a DatabaseException if the
+ // user already exists.)
+ Map data = m_ops.createNewUser(username,email);
+ UserObject uobj = new UserObject(data,false,m_ops.getObjectOps(),m_ns_cache,m_srm,this,m_post,m_adapter);
+ rc = uobj;
+ cobj = new IDNameCacheObject(uobj.getUID(),key,uobj,m_rq);
+ m_id_to_user.put(cobj.getIDKey(),cobj);
+ m_name_to_user.put(cobj.getNameKey(),cobj);
+
+ } // end synchronized block
+
+ return rc; // new user created!
+
+ } // end createUser
+
+ public DynamoGroup getGroup(int id) throws DatabaseException
+ {
+ DynamoGroup rc = null;
+ Integer key = new Integer(id);
+ synchronized (m_groups_sync)
+ { // try to retrieve the group
+ IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_group.get(key));
+ if (cobj!=null)
+ { // got a cache object - retrieve the group value
+ rc = (DynamoGroup)(cobj.get());
+ if (rc==null)
+ { // the GroupObject got kicked out! kick it out of the HashMaps
+ m_id_to_group.remove(key);
+ m_name_to_group.remove(cobj.getNameKey());
+ cobj.clear();
+ cobj = null;
+
+ } // end if
+
+ } // end if
+
+ if (rc==null)
+ { // OK, we have to go to the database to find the group
+ Map data = m_ops.getGroupData(id);
+ if (data!=null)
+ { // create GroupObject and add it to our cache maps
+ GroupObject gobj = new GroupObject(data,m_ops.getGroupOps(),m_ns_cache,m_srm,this);
+ rc = gobj;
+ cobj = new IDNameCacheObject(key,gobj.getName(),gobj,m_group_rq);
+ m_id_to_group.put(cobj.getIDKey(),cobj);
+ m_name_to_group.put(cobj.getNameKey(),cobj);
+
+ } // end if
+ // else group does not exist - return null
+
+ } // end if
+
+ } // end synchronized block
+
+ return rc;
+
+ } // end getGroup
+
+ public DynamoGroup getGroup(String groupname) throws DatabaseException
+ {
+ DynamoGroup rc = null;
+ DynamoIDKey key = new DynamoIDKey(groupname);
+ synchronized (m_groups_sync)
+ { // try to retrieve the group
+ IDNameCacheObject cobj = (IDNameCacheObject)(m_name_to_group.get(key));
+ if (cobj!=null)
+ { // got a cache object - retrieve the group value
+ rc = (DynamoGroup)(cobj.get());
+ if (rc==null)
+ { // the GroupObject got kicked out! kick it out of the HashMaps
+ m_id_to_group.remove(cobj.getIDKey());
+ m_name_to_group.remove(key);
+ cobj.clear();
+ cobj = null;
+
+ } // end if
+
+ } // end if
+
+ if (rc==null)
+ { // OK, we have to go to the database to find the group
+ Map data = m_ops.getGroupData(groupname);
+ if (data!=null)
+ { // create group object and add it to our cache maps
+ GroupObject gobj = new GroupObject(data,m_ops.getGroupOps(),m_ns_cache,m_srm,this);
+ rc = gobj;
+ cobj = new IDNameCacheObject(gobj.getGID(),key,gobj,m_group_rq);
+ m_id_to_group.put(cobj.getIDKey(),cobj);
+ m_name_to_group.put(cobj.getNameKey(),cobj);
+
+ } // end if
+ // else group does not exist - return null
+
+ } // end if
+
+ } // end synchronized block
+
+ return rc;
+
+ } // end getGroup
+
+ public DynamoGroup createGroup(String groupname) throws DatabaseException
+ {
+ DynamoIDKey key = new DynamoIDKey(groupname);
+ if (!(key.isValid(MAX_GROUPNAME)))
+ { // the group ID is invalid...
+ DatabaseException de = new DatabaseException(UserManagerObject.class,"UserMessages","group.badID");
+ de.setParameter(0,groupname);
+ throw de;
+
+ } // end if
+
+ DynamoGroup rc = null;
+ synchronized (m_groups_sync)
+ { // see if the group is in our cache already
+ IDNameCacheObject cobj = (IDNameCacheObject)(m_name_to_group.get(key));
+ if (cobj!=null)
+ { // it's in the cache - we're going to fail this operation. But while we're here, if the
+ // actual group object has been kicked out, expunge the reference.
+ if (cobj.get()==null)
+ { // the GroupObject got kicked out! kick it out of the HashMaps
+ m_id_to_group.remove(cobj.getIDKey());
+ m_name_to_group.remove(key);
+ cobj.clear();
+ cobj = null;
+
+ } // end if
+
+ // throw the exception saying that we exist
+ DatabaseException de = new DatabaseException(UserManagerObject.class,"UserMessages","group.exists");
+ de.setParameter(0,groupname);
+ throw de;
+
+ } // end if
+
+ // OK, at this point, we can't be any surer the group doesn't already exist without
+ // hitting the database. So create it. (createNewGroup will throw a DatabaseException if the
+ // group already exists.)
+ Map data = m_ops.createNewGroup(groupname);
+ GroupObject gobj = new GroupObject(data,m_ops.getGroupOps(),m_ns_cache,m_srm,this);
+ rc = gobj;
+ cobj = new IDNameCacheObject(gobj.getGID(),key,gobj,m_group_rq);
+ m_id_to_group.put(cobj.getIDKey(),cobj);
+ m_name_to_group.put(cobj.getNameKey(),cobj);
+
+ } // end synchronized block
+
+ return rc; // new group created!
+
+ } // end createNewGroup
+
+ public void loadUserDefaults(DynamoUser user, Collection namespaces) throws DatabaseException
+ {
+ // Start by translating all the namespaces to namespace IDs.
+ int[] nsids = new int[namespaces.size()];
+ int i = 0;
+ Iterator it = namespaces.iterator();
+ while (it.hasNext())
+ nsids[i++] = m_ns_cache.namespaceNameToId(it.next().toString());
+
+ // Now feed it into the database operations.
+ m_ops.loadUserDefaults(user.getUID(),nsids);
+
+ } // end loadUserDefaults
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface UserProxyManagement
+ *--------------------------------------------------------------------------------
+ */
+
+ public DynamoUser getUserProxy(int uid)
+ {
+ synchronized (m_anon_user_sync)
+ { // get the anonymous user, if it's there and matches
+ if ((m_anon_user!=null) && (m_anon_user.getUID()==uid))
+ return m_anon_user;
+
+ } // end synchronized block
+
+ Integer key = new Integer(uid);
+ synchronized (m_users_sync)
+ { // try to retrieve the user
+ IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_user.get(key));
+ if (cobj!=null)
+ { // got a cache object - retrieve the user value
+ DynamoUser rc = (DynamoUser)(cobj.get());
+ if (rc==null)
+ { // the UserObject got kicked out! kick it out of the HashMaps
+ m_id_to_user.remove(key);
+ m_name_to_user.remove(cobj.getNameKey());
+ rc = new MyUserProxy(uid,cobj.getNameKey().toString());
+ cobj.clear();
+ cobj = null;
+
+ } // end if
+
+ return rc;
+
+ } // end if
+
+ return new MyUserProxy(uid); // just return a proxy object
+
+ } // end synchronized block
+
+ } // end getUserProxy
+
+ public DynamoUser getUserProxy(int uid, String username)
+ {
+ synchronized (m_anon_user_sync)
+ { // get the anonymous user, if it's there and matches
+ if ((m_anon_user!=null) && (m_anon_user.getUID()==uid))
+ return m_anon_user;
+
+ } // end synchronized block
+
+ Integer key = new Integer(uid);
+ synchronized (m_users_sync)
+ { // try to retrieve the user
+ IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_user.get(key));
+ if (cobj!=null)
+ { // got a cache object - retrieve the user value
+ DynamoUser rc = (DynamoUser)(cobj.get());
+ if (rc==null)
+ { // the UserObject got kicked out! kick it out of the HashMaps
+ m_id_to_user.remove(key);
+ m_name_to_user.remove(cobj.getNameKey());
+ rc = new MyUserProxy(uid,cobj.getNameKey().toString());
+ cobj.clear();
+ cobj = null;
+
+ } // end if
+
+ return rc;
+
+ } // end if
+
+ return new MyUserProxy(uid,username); // just return a proxy object
+
+ } // end synchronized block
+
+ } // end getUserProxy
+
+ public DynamoGroup getGroupProxy(int gid)
+ {
+ Integer key = new Integer(gid);
+ synchronized (m_groups_sync)
+ { // try to retrieve the group
+ IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_group.get(key));
+ if (cobj!=null)
+ { // got a cache object - retrieve the group value
+ DynamoGroup rc = (DynamoGroup)(cobj.get());
+ if (rc==null)
+ { // the GroupObject got kicked out! kick it out of the HashMaps
+ m_id_to_group.remove(key);
+ m_name_to_group.remove(cobj.getNameKey());
+ rc = new MyGroupProxy(gid,cobj.getNameKey().toString());
+ cobj.clear();
+ cobj = null;
+
+ } // end if
+
+ return rc;
+
+ } // end if
+
+ return new MyGroupProxy(gid); // just return a proxy object
+
+ } // end synchronized block
+
+ } // end getGroupProxy
+
+ public DynamoGroup getGroupProxy(int gid, String groupname)
+ {
+ Integer key = new Integer(gid);
+ synchronized (m_groups_sync)
+ { // try to retrieve the group
+ IDNameCacheObject cobj = (IDNameCacheObject)(m_id_to_group.get(key));
+ if (cobj!=null)
+ { // got a cache object - retrieve the group value
+ DynamoGroup rc = (DynamoGroup)(cobj.get());
+ if (rc==null)
+ { // the GroupObject got kicked out! kick it out of the HashMaps
+ m_id_to_group.remove(key);
+ m_name_to_group.remove(cobj.getNameKey());
+ rc = new MyGroupProxy(gid,cobj.getNameKey().toString());
+ cobj.clear();
+ cobj = null;
+
+ } // end if
+
+ return rc;
+
+ } // end if
+
+ return new MyGroupProxy(gid,groupname); // just return a proxy object
+
+ } // end synchronized block
+
+ } // end getGroupProxy
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface AuthenticatorLookup
+ *--------------------------------------------------------------------------------
+ */
+
+ public Authenticator findAuthenticator(String method_namespace, String method)
+ {
+ return (Authenticator)(m_authenticators.get(new QualifiedNameKey(method_namespace,method)));
+
+ } // end findAuthenticator
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface AuthenticatorRegistration
+ *--------------------------------------------------------------------------------
+ */
+
+ public ComponentShutdown registerAuthenticator(String method_namespace, String method, Authenticator auth)
+ throws ConfigException
+ {
+ QualifiedNameKey key = new QualifiedNameKey(method_namespace,method);
+ if (m_authenticators.containsKey(key))
+ { // dump out here
+ ConfigException ce = new ConfigException(UserManagerObject.class,"DatabaseMessages","auth.register");
+ ce.setParameter(0,method_namespace);
+ ce.setParameter(1,method);
+ throw ce;
+
+ } // end if
+
+ m_authenticators.put(key,auth);
+ return new ShutdownHashtableRemove(m_authenticators,key);
+
+ } // end registerAuthenticator
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface UserPropertyTranslatorInstall
+ *--------------------------------------------------------------------------------
+ */
+
+ public void installUserPropertyTranslator(UserPropertyTranslator upt)
+ {
+ m_adapter.setTranslator(upt);
+
+ } // end installUserPropertyTranslator
+
+} // end class UserManagerObject
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerOps.java b/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerOps.java
new file mode 100644
index 0000000..1abacb4
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerOps.java
@@ -0,0 +1,102 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.util.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+
+abstract class UserManagerOps extends OpsBase
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ static final String HMKEY_UID = "uid";
+ static final String HMKEY_USERNAME = "username";
+ static final String HMKEY_EMAIL = "email";
+ static final String HMKEY_LOCKED = "locked";
+ static final String HMKEY_NOSPAM = "nospam";
+ static final String HMKEY_CREATED = "created";
+ static final String HMKEY_LAST_ACCESS = "last_accessed";
+
+ static final String HMKEY_GID = "gid";
+ static final String HMKEY_GROUPNAME = "groupname";
+ static final String HMKEY_GACLID = "gaclid";
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ protected UserManagerOps(DBConnectionPool pool)
+ {
+ super(pool);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class OpsBase
+ *--------------------------------------------------------------------------------
+ */
+
+ public void dispose()
+ {
+ super.dispose();
+
+ } // end dispose
+
+ /*--------------------------------------------------------------------------------
+ * Abstract operations
+ *--------------------------------------------------------------------------------
+ */
+
+ abstract UserObjectOps getObjectOps();
+
+ abstract GroupObjectOps getGroupOps();
+
+ abstract Map getAnonymousUserData() throws DatabaseException;
+
+ abstract Map getUserData(int id) throws DatabaseException;
+
+ abstract Map getUserData(String username) throws DatabaseException;
+
+ abstract Map createNewUser(String username, String email) throws DatabaseException;
+
+ abstract Map getGroupData(int id) throws DatabaseException;
+
+ abstract Map getGroupData(String groupname) throws DatabaseException;
+
+ abstract Map createNewGroup(String groupname) throws DatabaseException;
+
+ abstract void loadUserDefaults(int uid, int[] nsids) throws DatabaseException;
+
+ /*--------------------------------------------------------------------------------
+ * External static operations
+ *--------------------------------------------------------------------------------
+ */
+
+ static UserManagerOps get(DBConnectionPool pool) throws ConfigException
+ {
+ return (UserManagerOps)get(pool,UserManagerOps.class.getClassLoader(),
+ UserManagerOps.class.getName() + "_","UserManagerOps");
+
+ } // end get
+
+} // end class UserManagerOps
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerOps_mysql.java b/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerOps_mysql.java
new file mode 100644
index 0000000..2dbaed9
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/UserManagerOps_mysql.java
@@ -0,0 +1,463 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.sql.*;
+import java.util.*;
+import com.silverwrist.util.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+
+public class UserManagerOps_mysql extends UserManagerOps
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final Integer GACLID_NONE = new Integer(-1);
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private DBUtilities m_utils; // reference to utilities object
+ private UserObjectOps m_obj_ops = null; // object operations object
+ private GroupObjectOps m_group_ops = null; // group operations object
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public UserManagerOps_mysql(DBConnectionPool pool)
+ {
+ super(pool);
+ m_utils = (DBUtilities)(pool.queryService(DBUtilities.class));
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Abstract implementations from class UserManagerOps
+ *--------------------------------------------------------------------------------
+ */
+
+ synchronized UserObjectOps getObjectOps()
+ {
+ if (m_obj_ops==null)
+ m_obj_ops = new UserObjectOps_mysql(getPool(),m_utils);
+ return m_obj_ops;
+
+ } // end getObjectOps
+
+ synchronized GroupObjectOps getGroupOps()
+ {
+ if (m_group_ops==null)
+ m_group_ops = new GroupObjectOps_mysql(getPool(),m_utils);
+ return m_group_ops;
+
+ } // end getGroupOps
+
+ Map getAnonymousUserData() throws DatabaseException
+ {
+ Connection conn = null;
+ Statement stmt = null;
+ ResultSet rs = null;
+ try
+ { // get a connection and statement
+ conn = getConnection();
+ stmt = conn.createStatement();
+ rs = stmt.executeQuery("SELECT uid, username, email, created, last_accessed FROM users "
+ + "WHERE is_anon = 1;");
+ if (!(rs.next()))
+ return null; // no anonymous user info (will throw exception later)
+
+ // Create and return the Map containing the user data.
+ HashMap rc = new HashMap();
+ rc.put(HMKEY_UID,new Integer(rs.getInt(1)));
+ rc.put(HMKEY_USERNAME,rs.getString(2));
+ rc.put(HMKEY_EMAIL,rs.getString(3));
+ rc.put(HMKEY_LOCKED,Boolean.FALSE);
+ rc.put(HMKEY_NOSPAM,Boolean.TRUE);
+ rc.put(HMKEY_CREATED,m_utils.getDateTime(rs,4));
+ java.util.Date lacc = m_utils.getDateTime(rs,5);
+ if (lacc!=null)
+ rc.put(HMKEY_LAST_ACCESS,lacc);
+ return rc;
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end getAnonymousUserData
+
+ Map getUserData(int id) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // execute the statement to get the user data
+ stmt = conn.prepareStatement("SELECT username, email, locked, nospam, created, last_accessed FROM users "
+ + "WHERE uid = ? AND is_anon = 0;");
+ stmt.setInt(1,id);
+ rs = stmt.executeQuery();
+ if (!(rs.next()))
+ return null; // no user info
+
+ // Create and return the Map containing the user data.
+ HashMap rc = new HashMap();
+ rc.put(HMKEY_UID,new Integer(id));
+ rc.put(HMKEY_USERNAME,rs.getString(1));
+ rc.put(HMKEY_EMAIL,rs.getString(2));
+ rc.put(HMKEY_LOCKED,Boolean.valueOf(rs.getBoolean(3)));
+ rc.put(HMKEY_NOSPAM,Boolean.valueOf(rs.getBoolean(4)));
+ rc.put(HMKEY_CREATED,m_utils.getDateTime(rs,5));
+ java.util.Date lacc = m_utils.getDateTime(rs,6);
+ if (lacc!=null)
+ rc.put(HMKEY_LAST_ACCESS,lacc);
+ return rc;
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end getUserData
+
+ Map getUserData(String username) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // execute the statement to get the user data
+ stmt = conn.prepareStatement("SELECT uid, email, locked, nospam, created, last_accessed FROM users "
+ + "WHERE username = ? AND is_anon = 0;");
+ stmt.setString(1,username);
+ rs = stmt.executeQuery();
+ if (!(rs.next()))
+ return null; // no user info
+
+ // Create and return the Map containing the user data.
+ HashMap rc = new HashMap();
+ rc.put(HMKEY_UID,new Integer(rs.getInt(1)));
+ rc.put(HMKEY_USERNAME,username);
+ rc.put(HMKEY_EMAIL,rs.getString(2));
+ rc.put(HMKEY_LOCKED,Boolean.valueOf(rs.getBoolean(3)));
+ rc.put(HMKEY_NOSPAM,Boolean.valueOf(rs.getBoolean(4)));
+ rc.put(HMKEY_CREATED,m_utils.getDateTime(rs,5));
+ java.util.Date lacc = m_utils.getDateTime(rs,6);
+ if (lacc!=null)
+ rc.put(HMKEY_LAST_ACCESS,lacc);
+ return rc;
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end getUserData
+
+ Map createNewUser(String username, String email) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ Statement stmt2 = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // lock the users table
+ stmt2 = conn.createStatement();
+ stmt2.executeUpdate("LOCK TABLES users WRITE;");
+
+ // see if the user already exists
+ stmt = conn.prepareStatement("SELECT uid FROM users WHERE username = ?;");
+ stmt.setString(1,username);
+ rs = stmt.executeQuery();
+ if (rs.next())
+ { // user exists - our operation is blown
+ DatabaseException de = new DatabaseException(UserManagerOps_mysql.class,"UserMessages","user.exists");
+ de.setParameter(0,username);
+ throw de;
+
+ } // end if
+
+ // close down previous statement in prep for next one
+ SQLUtils.shutdown(rs);
+ rs = null;
+ SQLUtils.shutdown(stmt);
+
+ // insert the new user record!
+ stmt = conn.prepareStatement("INSERT INTO users (username, email, created) VALUES (?, ?, ?);");
+ stmt.setString(1,username);
+ stmt.setString(2,email);
+ java.util.Date created = new java.util.Date();
+ m_utils.setDateTime(stmt,3,created);
+ stmt.executeUpdate();
+
+ // Generate the return Map, suitable for creating a new object.
+ HashMap rc = new HashMap();
+ rc.put(HMKEY_UID,new Integer(MySQLUtils.getLastInsertInt(conn)));
+ rc.put(HMKEY_USERNAME,username);
+ rc.put(HMKEY_EMAIL,email);
+ rc.put(HMKEY_LOCKED,Boolean.FALSE);
+ rc.put(HMKEY_NOSPAM,Boolean.FALSE);
+ rc.put(HMKEY_CREATED,created);
+ return rc;
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ MySQLUtils.unlockTables(conn);
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(stmt2);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end createNewUser
+
+ Map getGroupData(int id) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // execute the statement to get the group data
+ stmt = conn.prepareStatement("SELECT groupname, gaclid FROM groups WHERE gid = ?;");
+ stmt.setInt(1,id);
+ rs = stmt.executeQuery();
+ if (!(rs.next()))
+ return null; // no group info
+
+ // Create and return the Map containing the group data.
+ HashMap rc = new HashMap();
+ rc.put(HMKEY_GID,new Integer(id));
+ rc.put(HMKEY_GROUPNAME,rs.getString(1));
+ rc.put(HMKEY_GACLID,new Integer(rs.getInt(2)));
+ return rc;
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end getGroupData
+
+ Map getGroupData(String groupname) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // execute the statement to get the group data
+ stmt = conn.prepareStatement("SELECT gid, gaclid FROM groups WHERE groupname = ?;");
+ stmt.setString(1,groupname);
+ rs = stmt.executeQuery();
+ if (!(rs.next()))
+ return null; // no group info
+
+ // Create and return the Map containing the group data.
+ HashMap rc = new HashMap();
+ rc.put(HMKEY_GID,new Integer(rs.getInt(1)));
+ rc.put(HMKEY_GROUPNAME,groupname);
+ rc.put(HMKEY_GACLID,new Integer(rs.getInt(2)));
+ return rc;
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end getGroupData
+
+ Map createNewGroup(String groupname) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ Statement stmt2 = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // lock the groups table
+ stmt2 = conn.createStatement();
+ stmt2.executeUpdate("LOCK TABLES groups WRITE;");
+
+ // see if the group already exists
+ stmt = conn.prepareStatement("SELECT gid FROM groups WHERE groupname = ?;");
+ stmt.setString(1,groupname);
+ rs = stmt.executeQuery();
+ if (rs.next())
+ { // group exists - our operation is blown
+ DatabaseException de = new DatabaseException(UserManagerOps_mysql.class,"UserMessages","group.exists");
+ de.setParameter(0,groupname);
+ throw de;
+
+ } // end if
+
+ // close down previous statement in prep for next one
+ SQLUtils.shutdown(rs);
+ rs = null;
+ SQLUtils.shutdown(stmt);
+
+ // insert the new group record!
+ stmt = conn.prepareStatement("INSERT INTO groups (groupname) VALUES (?);");
+ stmt.setString(1,groupname);
+ stmt.executeUpdate();
+
+ // Generate the return Map, suitable for creating a new object.
+ HashMap rc = new HashMap();
+ rc.put(HMKEY_GID,new Integer(MySQLUtils.getLastInsertInt(conn)));
+ rc.put(HMKEY_GROUPNAME,groupname);
+ rc.put(HMKEY_GACLID,GACLID_NONE);
+ return rc;
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ MySQLUtils.unlockTables(conn);
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(stmt2);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ } // end createNewGroup
+
+ void loadUserDefaults(int uid, int[] nsids) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt_insert = null;
+ Statement stmt = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // lock the global and user properties tables
+ stmt = conn.createStatement();
+ stmt.executeUpdate("LOCK TABLES userprop WRITE, globalprop READ;");
+
+ // prepare the fancy insert statement
+ stmt_insert = conn.prepareStatement("INSERT INTO userprop (uid, nsid, prop_name, prop_value) "
+ + "SELECT ?, globalprop.nsid, globalprop.prop_name, "
+ + "globalprop.prop_value FROM globalprop "
+ + "WHERE globalprop.nsid = ?;");
+ for (int i=0; i.
+#
+# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+# WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+# language governing rights and limitations under the License.
+#
+# The Original Code is the Venice Web Communities System.
+#
+# The Initial Developer of the Original Code is Eric J. Bowersox ,
+# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+# Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+#
+# Contributor(s):
+# ---------------------------------------------------------------------------------
+# This file has been localized for the en_US locale
+anon.notFound=Internal Error: Unable to load information for the anonymous user.
+user.exists=User "{0}" already exists in the database.
+user.badID=The user name "{0}" is not valid.
+group.exists=Group "{0}" already exists in the database.
+group.badID=The group name "{0}" is not valid.
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/UserObject.java b/src/dynamo-framework/com/silverwrist/dynamo/db/UserObject.java
new file mode 100644
index 0000000..5e84e17
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/UserObject.java
@@ -0,0 +1,527 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.util.*;
+import org.apache.commons.collections.*;
+import com.silverwrist.dynamo.UserInfoNamespace;
+import com.silverwrist.dynamo.event.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.security.SecurityReferenceMonitor;
+import com.silverwrist.dynamo.util.*;
+
+class UserObject implements DynamoUser, UserInfoNamespace
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private UserObjectOps m_ops; // operations object
+ private NamespaceCache m_ns_cache; // namespace cache object
+ private SecurityReferenceMonitor m_srm; // security reference monitor
+ private AuthenticatorLookup m_auth_lookup; // authenticator lookup
+ private PostDynamicUpdate m_post; // where we post dynamic events
+ private UserPropertyTranslator m_upt;
+ private int m_uid; // user ID
+ private String m_username; // user name
+ private String m_email; // E-mail address
+ private java.util.Date m_created; // created date
+ private java.util.Date m_last_accessed; // last access date
+ private boolean m_anonymous; // is this the anonymous user?
+ private boolean m_locked; // is user locked?
+ private boolean m_nospam; // user "no-spam" flag
+ private ReferenceMap m_properties; // cached property values
+ private Object m_properties_sync = new Object(); // synchronization for above
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ UserObject(Map data, boolean anonymous, UserObjectOps ops, NamespaceCache ns_cache,
+ SecurityReferenceMonitor srm, AuthenticatorLookup auth_lookup, PostDynamicUpdate post,
+ UserPropertyTranslator upt)
+ {
+ m_ops = ops;
+ m_ns_cache = ns_cache;
+ m_srm = srm;
+ m_auth_lookup = auth_lookup;
+ m_post = post;
+ m_upt = upt;
+ m_uid = ((Integer)(data.get(UserManagerOps.HMKEY_UID))).intValue();
+ m_username = (String)(data.get(UserManagerOps.HMKEY_USERNAME));
+ m_email = (String)(data.get(UserManagerOps.HMKEY_EMAIL));
+ m_created = (java.util.Date)(data.get(UserManagerOps.HMKEY_CREATED));
+ m_last_accessed = (java.util.Date)(data.get(UserManagerOps.HMKEY_LAST_ACCESS));
+ m_anonymous = anonymous;
+ m_locked = ((Boolean)(data.get(UserManagerOps.HMKEY_LOCKED))).booleanValue();
+ m_nospam = ((Boolean)(data.get(UserManagerOps.HMKEY_NOSPAM))).booleanValue();
+ m_properties = new ReferenceMap(ReferenceMap.HARD,ReferenceMap.SOFT);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
+
+ private final void testChangeOK(DynamoUser caller) throws DatabaseException, DynamoSecurityException
+ {
+ if (equals(caller))
+ return; // a user can always change their OWN information
+
+ if (caller.equals(m_srm.getAdminUser()))
+ return; // Administrator can do anything
+
+ if (m_srm.getGlobalAcl().testPermission(caller,NAMESPACE,PERM_EDIT_ALL))
+ return; // and so can anyone else with "edit all" permission on the global ACL
+
+ // Presume the change is forbidden - throw the exception
+ DynamoSecurityException dse = new DynamoSecurityException(UserObject.class,"DatabaseMessages",
+ "sec.changeUser");
+ dse.setParameter(0,m_username);
+ throw dse;
+
+ } // end testChangeOK
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface Principal
+ *--------------------------------------------------------------------------------
+ */
+
+ public boolean equals(Object another)
+ {
+ if (another==null)
+ return false;
+ if (another instanceof DynamoUser)
+ return (m_uid==((DynamoUser)another).getUID());
+ return false;
+
+ } // end equals
+
+ public String toString()
+ {
+ return "user " + m_username;
+
+ } // end toString
+
+ public int hashCode()
+ {
+ return m_uid;
+
+ } // end hashCode
+
+ public String getName()
+ {
+ return m_username;
+
+ } // end getName
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ObjectProvider
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Retrieves an object from this ObjectProvider.
+ *
+ * @param namespace The namespace to interpret the name relative to.
+ * @param name The name of the object to be retrieved.
+ * @return The object reference specified.
+ */
+ public Object getObject(String namespace, String name)
+ {
+ if (NAMESPACE.equals(namespace))
+ { // handle user info namespace specially
+ if (ATTR_FULLNAME.equals(name))
+ return m_upt.getUserFullName(this);
+ else if (ATTR_EMAIL_ADDRESS.equals(name))
+ return m_email;
+ else if (ATTR_ID.equals(name))
+ return new Integer(m_uid);
+ else if (ATTR_USERNAME.equals(name))
+ return m_username;
+ else
+ throw new NoSuchObjectException(this.toString(),namespace,name);
+
+ } // end if
+
+ try
+ { // convert the namespace name to an ID here
+ PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name);
+ Object rc = null;
+ synchronized (m_properties_sync)
+ { // start by looking in the properties map
+ rc = m_properties.get(key);
+ if (rc==null)
+ { // no use - need to try the database
+ rc = m_ops.getProperty(m_uid,key);
+ if (rc!=null)
+ m_properties.put(key,rc);
+
+ } // end if
+
+ } // end synchronized block
+
+ if (rc==null)
+ throw new NoSuchObjectException(this.toString(),namespace,name);
+ return rc;
+
+ } // end try
+ catch (DatabaseException e)
+ { // translate into our NoSuchObjectException but retain the DatabaseException
+ throw new NoSuchObjectException(this.toString(),namespace,name,e);
+
+ } // end catch
+
+ } // end getObject
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface SecureObjectStore
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object setObject(DynamoUser caller, String namespace, String name, Object value)
+ throws DatabaseException, DynamoSecurityException
+ {
+ if (NAMESPACE.equals(namespace))
+ { // can't set more data in restricted namespace
+ ObjectStoreException ose = new ObjectStoreException(UserObject.class,"DatabaseMessages",
+ "ose.setProperty");
+ ose.setParameter(0,namespace);
+ ose.setParameter(1,name);
+ throw ose;
+
+ } // end if
+
+ testChangeOK(caller);
+ Object rc = null;
+
+ // convert the namespace name to an ID here
+ PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name);
+ synchronized (m_properties_sync)
+ { // start by setting the database value
+ rc = m_ops.setProperty(m_uid,key,value);
+
+ // and cache it, too
+ m_properties.put(key,value);
+
+ } // end synchronized block
+
+ m_post.postUpdate(new UserPropertyUpdateEvent(this,m_uid,namespace,name));
+ return rc;
+
+ } // end setObject
+
+ public Object removeObject(DynamoUser caller, String namespace, String name)
+ throws DatabaseException, DynamoSecurityException
+ {
+ if (NAMESPACE.equals(namespace))
+ { // can't set more data in restricted namespace
+ ObjectStoreException ose = new ObjectStoreException(UserObject.class,"DatabaseMessages",
+ "ose.removeProperty");
+ ose.setParameter(0,namespace);
+ ose.setParameter(1,name);
+ throw ose;
+
+ } // end if
+
+ testChangeOK(caller);
+ Object rc = null;
+ // convert the namespace name to an ID here
+ PropertyKey key = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name);
+ synchronized (m_properties_sync)
+ { // start by killing the database value
+ rc = m_ops.removeProperty(m_uid,key);
+
+ // and remove the cached value, too
+ m_properties.remove(key);
+
+ } // end synchronized block
+
+ m_post.postUpdate(new UserPropertyUpdateEvent(this,m_uid,namespace,name));
+ return rc;
+
+ } // end removeObject
+
+ public Collection getNamespaces() throws DatabaseException
+ {
+ // call through to the database to get the list of namespace IDs
+ int[] ids = m_ops.getPropertyNamespaceIDs(m_uid);
+
+ ArrayList rc = new ArrayList(ids.length);
+ for (int i=0; i.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.util.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.util.*;
+
+abstract class UserObjectOps extends OpsBase
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ protected UserObjectOps(DBConnectionPool pool)
+ {
+ super(pool);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Abstract operations
+ *--------------------------------------------------------------------------------
+ */
+
+ abstract Object getProperty(int uid, PropertyKey key) throws DatabaseException;
+
+ abstract Object setProperty(int uid, PropertyKey key, Object value) throws DatabaseException;
+
+ abstract Object removeProperty(int uid, PropertyKey key) throws DatabaseException;
+
+ abstract int[] getPropertyNamespaceIDs(int uid) throws DatabaseException;
+
+ abstract Map getAllProperties(int uid, int namespace) throws DatabaseException;
+
+ abstract void setLocked(int uid, boolean locked) throws DatabaseException;
+
+ abstract void setNoSpam(int uid, boolean locked) throws DatabaseException;
+
+ abstract void setEMailAddress(int uid, String addr) throws DatabaseException;
+
+ abstract void setLastAccessed(int uid, java.util.Date date) throws DatabaseException;
+
+ abstract String[] getAuthenticationData(int uid, int nsid, String method, String source_data)
+ throws DatabaseException;
+
+ abstract void putAuthenticationData(int uid, int nsid, String method, String source_data, String auth_data)
+ throws DatabaseException;
+
+ abstract void clearAuthenticationData(int uid, int nsid, String method, String source_data)
+ throws DatabaseException;
+
+} // end class UserObjectOps
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/UserObjectOps_mysql.java b/src/dynamo-framework/com/silverwrist/dynamo/db/UserObjectOps_mysql.java
new file mode 100644
index 0000000..7abf77b
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/UserObjectOps_mysql.java
@@ -0,0 +1,635 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.sql.*;
+import java.util.*;
+import com.silverwrist.util.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+class UserObjectOps_mysql extends UserObjectOps
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final String[] STRING_TEMPLATE = new String[0];
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private DBUtilities m_utils;
+ private PropertySerializer m_psz;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ UserObjectOps_mysql(DBConnectionPool pool, DBUtilities utils)
+ {
+ super(pool);
+ m_utils = utils;
+ m_psz = (PropertySerializer)(pool.queryService(PropertySerializer.class));
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Abstract implementations from class UserObjectOps
+ *--------------------------------------------------------------------------------
+ */
+
+ Object getProperty(int uid, PropertyKey key) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ String rc_str = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // look up the property
+ stmt = conn.prepareStatement("SELECT prop_value FROM userprop WHERE uid = ? AND nsid = ? "
+ + "AND prop_name = ?;");
+ stmt.setInt(1,uid);
+ stmt.setInt(2,key.getNamespaceID());
+ stmt.setString(3,key.getName());
+ rs = stmt.executeQuery();
+ if (!(rs.next()))
+ return null; // property not found
+
+ rc_str = rs.getString(1);
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ // Deserialize the property value.
+ Object rc = m_psz.deserializeProperty(rc_str);
+ if (rc!=null)
+ return rc;
+
+ // deserialization exception - throw it
+ DatabaseException de = new DatabaseException(UserObjectOps_mysql.class,"DatabaseMessages",
+ "property.deserialize");
+ de.setParameter(0,key.getName());
+ throw de;
+
+ } // end getProperty
+
+ Object setProperty(int uid, PropertyKey key, Object value) throws DatabaseException
+ {
+ String serialized_value = m_psz.serializeProperty(value);
+ if (serialized_value==null)
+ { // serialization exception - throw it
+ DatabaseException de = new DatabaseException(UserObjectOps_mysql.class,"DatabaseMessages",
+ "property.serialize");
+ de.setParameter(0,key.getName());
+ throw de;
+
+ } // end if
+
+ String old_value = null;
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ Statement stmt2 = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // lock the table
+ stmt2 = conn.createStatement();
+ stmt2.executeUpdate("LOCK TABLES userprop WRITE;");
+
+ // look to see if the property value is already there
+ stmt = conn.prepareStatement("SELECT prop_value FROM userprop WHERE uid = ? AND nsid = ? "
+ + "AND prop_name = ?;");
+ stmt.setInt(1,uid);
+ stmt.setInt(2,key.getNamespaceID());
+ stmt.setString(3,key.getName());
+ rs = stmt.executeQuery();
+ if (rs.next())
+ old_value = rs.getString(1);
+ SQLUtils.shutdown(rs);
+ rs = null;
+ SQLUtils.shutdown(stmt);
+
+ if (old_value!=null)
+ { // prepare the statement to update the existing record
+ stmt = conn.prepareStatement("UPDATE userprop SET prop_value = ? WHERE uid = ? "
+ + "AND nsid = ? AND prop_name = ?;");
+ stmt.setString(1,serialized_value);
+ stmt.setInt(2,uid);
+ stmt.setInt(3,key.getNamespaceID());
+ stmt.setString(4,key.getName());
+
+ } // end if
+ else
+ { // prepare the statement to insert a new record
+ stmt = conn.prepareStatement("INSERT INTO userprop (uid, nsid, prop_name, prop_value) "
+ + "VALUES (?, ?, ?, ?);");
+ stmt.setInt(1,uid);
+ stmt.setInt(2,key.getNamespaceID());
+ stmt.setString(3,key.getName());
+ stmt.setString(4,serialized_value);
+
+ } // end else
+
+ stmt.executeUpdate(); // execute it!
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ MySQLUtils.unlockTables(conn);
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(stmt2);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ if (old_value==null)
+ return null; // no previous value
+
+ // Deserialize the property value.
+ Object rc = m_psz.deserializeProperty(old_value);
+ if (rc!=null)
+ return rc;
+
+ // deserialization exception - throw it
+ DatabaseException de = new DatabaseException(UserObjectOps_mysql.class,"DatabaseMessages",
+ "property.deserialize");
+ de.setParameter(0,key.getName());
+ throw de;
+
+ } // end setProperty
+
+ Object removeProperty(int uid, PropertyKey key) throws DatabaseException
+ {
+ String old_value = null;
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ Statement stmt2 = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // lock the table
+ stmt2 = conn.createStatement();
+ stmt2.executeUpdate("LOCK TABLES userprop WRITE;");
+
+ // look to see if the property value is already there
+ stmt = conn.prepareStatement("SELECT prop_value FROM userprop WHERE uid = ? AND nsid = ? "
+ + "AND prop_name = ?;");
+ stmt.setInt(1,uid);
+ stmt.setInt(2,key.getNamespaceID());
+ stmt.setString(3,key.getName());
+ rs = stmt.executeQuery();
+ if (rs.next())
+ old_value = rs.getString(1);
+ else
+ return null; // no need to remove anything
+ SQLUtils.shutdown(rs);
+ rs = null;
+ SQLUtils.shutdown(stmt);
+
+ // delete the database row
+ stmt = conn.prepareStatement("DELETE FROM userprop WHERE uid = ? AND nsid = ? AND prop_name = ?;");
+ stmt.setInt(1,uid);
+ stmt.setInt(2,key.getNamespaceID());
+ stmt.setString(3,key.getName());
+ stmt.executeUpdate();
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ MySQLUtils.unlockTables(conn);
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(stmt2);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ // Deserialize the property value.
+ Object rc = m_psz.deserializeProperty(old_value);
+ if (rc!=null)
+ return rc;
+
+ // deserialization exception - throw it
+ DatabaseException de = new DatabaseException(UserObjectOps_mysql.class,"DatabaseMessages",
+ "property.deserialize");
+ de.setParameter(0,key.getName());
+ throw de;
+
+ } // end removeProperty
+
+ int[] getPropertyNamespaceIDs(int uid) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // execute the query!
+ stmt = conn.prepareStatement("SELECT DISTINCT nsid FROM userprop WHERE uid = ?;");
+ stmt.setInt(1,uid);
+ rs = stmt.executeQuery();
+
+ // read out a list of the namespace IDs
+ ArrayList tmp = new ArrayList();
+ while (rs.next())
+ tmp.add(new Integer(rs.getInt(1)));
+
+ // create and return the array
+ int[] rc = new int[tmp.size()];
+ for (int i=0; i.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import com.silverwrist.dynamo.iface.DynamoUser;
+
+public interface UserPropertyTranslator
+{
+ public String getUserFullName(DynamoUser user);
+
+} // end interface UserPropertyTranslator
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/UserPropertyTranslatorInstall.java b/src/dynamo-framework/com/silverwrist/dynamo/db/UserPropertyTranslatorInstall.java
new file mode 100644
index 0000000..d7bdd2d
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/UserPropertyTranslatorInstall.java
@@ -0,0 +1,24 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+public interface UserPropertyTranslatorInstall
+{
+ public void installUserPropertyTranslator(UserPropertyTranslator upt);
+
+} // end interface UserPropertyTranslatorInstall
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/UserProxy.java b/src/dynamo-framework/com/silverwrist/dynamo/db/UserProxy.java
new file mode 100644
index 0000000..63136a9
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/UserProxy.java
@@ -0,0 +1,260 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.util.*;
+import com.silverwrist.dynamo.UserInfoNamespace;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+
+abstract class UserProxy implements DynamoUser, UserInfoNamespace, DynamicWrapper
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ protected int m_uid;
+ protected String m_username;
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ protected UserProxy(int uid)
+ {
+ m_uid = uid;
+ m_username = null;
+
+ } // end constructor
+
+ protected UserProxy(int uid, String username)
+ {
+ m_uid = uid;
+ m_username = username;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Abstract operations
+ *--------------------------------------------------------------------------------
+ */
+
+ protected abstract DynamoUser getRealUser();
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface Principal
+ *--------------------------------------------------------------------------------
+ */
+
+ public boolean equals(Object another)
+ {
+ if (another==null)
+ return false;
+ if (another instanceof DynamoUser)
+ return (m_uid==((DynamoUser)another).getUID());
+ return false;
+
+ } // end equals
+
+ public String toString()
+ {
+ if (m_username!=null)
+ return "user " + m_username;
+ return getRealUser().toString();
+
+ } // end toString
+
+ public int hashCode()
+ {
+ return m_uid;
+
+ } // end hashCode
+
+ public String getName()
+ {
+ if (m_username!=null)
+ return m_username;
+ return getRealUser().getName();
+
+ } // end getName
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ObjectProvider
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Retrieves an object from this ObjectProvider.
+ *
+ * @param namespace The namespace to interpret the name relative to.
+ * @param name The name of the object to be retrieved.
+ * @return The object reference specified.
+ */
+ public Object getObject(String namespace, String name)
+ {
+ return getRealUser().getObject(namespace,name);
+
+ } // end getObject
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface SecureObjectStore
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object setObject(DynamoUser caller, String namespace, String name, Object value)
+ throws DatabaseException, DynamoSecurityException
+ {
+ return getRealUser().setObject(caller,namespace,name,value);
+
+ } // end setObject
+
+ public Object removeObject(DynamoUser caller, String namespace, String name)
+ throws DatabaseException, DynamoSecurityException
+ {
+ return getRealUser().removeObject(caller,namespace,name);
+
+ } // end removeObject
+
+ public Collection getNamespaces() throws DatabaseException
+ {
+ return getRealUser().getNamespaces();
+
+ } // end getNamespaces
+
+ public Collection getNamesForNamespace(String namespace) throws DatabaseException
+ {
+ return getRealUser().getNamesForNamespace(namespace);
+
+ } // end getNamesForNamespace
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface DynamoUser
+ *--------------------------------------------------------------------------------
+ */
+
+ public int getUID()
+ {
+ return m_uid;
+
+ } // end getUID
+
+ public boolean isAnonymous()
+ {
+ return getRealUser().isAnonymous();
+
+ } // end isAnonymous
+
+ public boolean isLocked()
+ {
+ return getRealUser().isLocked();
+
+ } // end isLocked
+
+ public void setLocked(DynamoUser caller, boolean locked) throws DatabaseException, DynamoSecurityException
+ {
+ getRealUser().setLocked(caller,locked);
+
+ } // end setLocked
+
+ public boolean isNoSpam()
+ {
+ return getRealUser().isNoSpam();
+
+ } // end isNoSpam
+
+ public void setNoSpam(DynamoUser caller, boolean nospam) throws DatabaseException, DynamoSecurityException
+ {
+ getRealUser().setNoSpam(caller,nospam);
+
+ } // end setNoSpam
+
+ public String getEMailAddress()
+ {
+ return getRealUser().getEMailAddress();
+
+ } // end getEMailAddress
+
+ public boolean setEMailAddress(DynamoUser caller, String addr)
+ throws DatabaseException, DynamoSecurityException
+ {
+ return getRealUser().setEMailAddress(caller,addr);
+
+ } // end setEMailAddress
+
+ public boolean authenticate(String method_namespace, String method, String source_data, String auth_data)
+ throws DatabaseException, AuthenticationException
+ {
+ return getRealUser().authenticate(method_namespace,method,source_data,auth_data);
+
+ } // end authenticate
+
+ public void setAuthenticationData(DynamoUser caller, String method_namespace, String method,
+ String source_data, String auth_data)
+ throws DatabaseException, AuthenticationException, DynamoSecurityException
+ {
+ getRealUser().setAuthenticationData(caller,method_namespace,method,source_data,auth_data);
+
+ } // end setAuthenticationData
+
+ public void clearAuthenticationData(DynamoUser caller, String method_namespace, String method,
+ String source_data) throws DatabaseException, DynamoSecurityException
+ {
+ getRealUser().clearAuthenticationData(caller,method_namespace,method,source_data);
+
+ } // end clearAuthenticationData
+
+ public void clearAuthenticationData(DynamoUser caller, String method_namespace, String method)
+ throws DatabaseException, DynamoSecurityException
+ {
+ getRealUser().clearAuthenticationData(caller,method_namespace,method);
+
+ } // end clearAuthenticationData
+
+ public java.util.Date getCreationDate()
+ {
+ return getRealUser().getCreationDate();
+
+ } // end getCreationDate
+
+ public java.util.Date getLastAccessDate()
+ {
+ return getRealUser().getLastAccessDate();
+
+ } // end getLastAccessDate
+
+ public synchronized void setLastAccessDate(DynamoUser caller, java.util.Date date)
+ throws DatabaseException, DynamoSecurityException
+ {
+ getRealUser().setLastAccessDate(caller,date);
+
+ } // end setLastAccessDate
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface DynamicWrapper
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object unwrap()
+ {
+ return getRealUser();
+
+ } // end unwrap
+
+} // end class UserProxy
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/UserProxyManagement.java b/src/dynamo-framework/com/silverwrist/dynamo/db/UserProxyManagement.java
new file mode 100644
index 0000000..7d5f97a
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/UserProxyManagement.java
@@ -0,0 +1,32 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import com.silverwrist.dynamo.iface.*;
+
+public interface UserProxyManagement
+{
+ public DynamoUser getUserProxy(int uid);
+
+ public DynamoUser getUserProxy(int uid, String username);
+
+ public DynamoGroup getGroupProxy(int gid);
+
+ public DynamoGroup getGroupProxy(int gid, String groupname);
+
+} // end interface UserProxyManagement
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/db/WrappedConnection.java b/src/dynamo-framework/com/silverwrist/dynamo/db/WrappedConnection.java
new file mode 100644
index 0000000..d00f0ca
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/db/WrappedConnection.java
@@ -0,0 +1,498 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.db;
+
+import java.sql.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+
+class WrappedConnection implements Connection
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private DBConnectionPool m_datapool;
+ private Connection m_conn;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ WrappedConnection(DBConnectionPool datapool, Connection conn)
+ {
+ m_datapool = datapool;
+ m_conn = conn;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class Object
+ *--------------------------------------------------------------------------------
+ */
+
+ protected void finalize() throws Throwable
+ {
+ if (m_conn!=null)
+ this.close();
+ super.finalize();
+
+ } // end finalize
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface Connection
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a Statement object for sending
+ * SQL statements to the database.
+ *
+ * @return a new Statement object
+ * @exception SQLException if a database access error occurs
+ */
+ public Statement createStatement() throws SQLException
+ {
+ return m_conn.createStatement();
+
+ } // end createStatement
+
+ /**
+ * Creates a PreparedStatement object for sending
+ * parameterized SQL statements to the database.
+ *
+ * @param sql a SQL statement that may contain one or more '?' IN parameter placeholders
+ * @return a new PreparedStatement object containing the pre-compiled statement
+ * @exception SQLException if a database access error occurs
+ */
+ public PreparedStatement prepareStatement(String sql) throws SQLException
+ {
+ return m_conn.prepareStatement(sql);
+
+ } // end prepareStatement
+
+ /**
+ * Creates a CallableStatement object for calling
+ * database stored procedures.
+ *
+ * @param sql a SQL statement that may contain one or more '?' parameter placeholders.
+ * Typically this statement is a JDBC function call escape string.
+ * @return a new CallableStatement object containing the pre-compiled SQL statement
+ * @exception SQLException if a database access error occurs
+ */
+ public CallableStatement prepareCall(String sql) throws SQLException
+ {
+ return m_conn.prepareCall(sql);
+
+ } // end prepareCall
+
+ /**
+ * Converts the given SQL statement into the system's native SQL grammar.
+ *
+ * @param sql a SQL statement that may contain one or more '?' parameter placeholders
+ * @return the native form of this statement
+ * @exception SQLException if a database access error occurs
+ */
+ public String nativeSQL(String sql) throws SQLException
+ {
+ return m_conn.nativeSQL(sql);
+
+ } // end nativeSQL
+
+ /**
+ * Sets this connection's auto-commit mode.
+ *
+ * @param autoCommit true enables auto-commit; false disables auto-commit.
+ * @exception SQLException if a database access error occurs
+ */
+ public void setAutoCommit(boolean autoCommit) throws SQLException
+ {
+ m_conn.setAutoCommit(autoCommit);
+
+ } // end setAutoCommit
+
+ /**
+ * Gets the current auto-commit state.
+ *
+ * @return the current state of auto-commit mode
+ * @exception SQLException if a database access error occurs
+ * @see #setAutoCommit
+ */
+ public boolean getAutoCommit() throws SQLException
+ {
+ return m_conn.getAutoCommit();
+
+ } // end getAutoCommit
+
+ /**
+ * Makes all changes made since the previous
+ * commit/rollback permanent and releases any database locks
+ * currently held by the Connection. This method should be
+ * used only when auto-commit mode has been disabled.
+ *
+ * @exception SQLException if a database access error occurs
+ * @see #setAutoCommit
+ */
+ public void commit() throws SQLException
+ {
+ m_conn.commit();
+
+ } // end commit
+
+ /**
+ * Drops all changes made since the previous
+ * commit/rollback and releases any database locks currently held
+ * by this Connection. This method should be used only when auto-
+ * commit has been disabled.
+ *
+ * @exception SQLException if a database access error occurs
+ * @see #setAutoCommit
+ */
+ public void rollback() throws SQLException
+ {
+ m_conn.rollback();
+
+ } // end rollback
+
+ /**
+ * Releases a Connection's database and JDBC resources
+ * immediately instead of waiting for them to be automatically released.
+ *
+ * @exception SQLException if a database access error occurs
+ */
+ public synchronized void close() throws SQLException
+ {
+ try
+ { // blow away the connection
+ if (!(m_conn.getAutoCommit()))
+ m_conn.rollback();
+ m_datapool.releaseConnection(m_conn);
+ m_conn = null;
+
+ } // end try
+ catch (DatabaseException e)
+ { // database exception becomes SQLException
+ SQLException sqle = new SQLException(e.getMessage());
+ sqle.initCause(e);
+ throw sqle;
+
+ } // end catch
+
+ } // end close
+
+ /**
+ * Tests to see if a Connection is closed.
+ *
+ * @return true if the connection is closed; false if it's still open
+ * @exception SQLException if a database access error occurs
+ */
+ public boolean isClosed() throws SQLException
+ {
+ return (m_conn==null) ? true : m_conn.isClosed();
+
+ } // end isClosed
+
+ /**
+ * Gets the metadata regarding this connection's database.
+ *
+ * @return a DatabaseMetaData object for this Connection
+ * @exception SQLException if a database access error occurs
+ */
+ public DatabaseMetaData getMetaData() throws SQLException
+ {
+ return m_conn.getMetaData();
+
+ } // end getMetaData
+
+ /**
+ * Puts this connection in read-only mode as a hint to enable
+ * database optimizations.
+ *
+ * @param readOnly true enables read-only mode; false disables read-only mode.
+ * @exception SQLException if a database access error occurs
+ */
+ public void setReadOnly(boolean readOnly)
+ { // do nothing
+ } // end setReadOnly
+
+ /**
+ * Tests to see if the connection is in read-only mode.
+ *
+ * @return true if connection is read-only and false otherwise
+ * @exception SQLException if a database access error occurs
+ */
+ public boolean isReadOnly()
+ {
+ return false;
+
+ } // end isReadOnly
+
+ /**
+ * Sets a catalog name in order to select
+ * a subspace of this Connection's database in which to work.
+ * If the driver does not support catalogs, it will
+ * silently ignore this request.
+ *
+ * @exception SQLException if a database access error occurs
+ */
+ public void setCatalog(String catalog)
+ { // do nothing
+ } // end setCatalog
+
+ /**
+ * Returns the Connection's current catalog name.
+ *
+ * @return the current catalog name or null
+ * @exception SQLException if a database access error occurs
+ */
+ public String getCatalog() throws SQLException
+ {
+ return m_conn.getCatalog();
+
+ } // end getCatalog
+
+ /**
+ * Attempts to change the transaction
+ * isolation level to the one given.
+ * The constants defined in the interface Connection
+ * are the possible transaction isolation levels.
+ *
+ * @param level one of the TRANSACTION_* isolation values with the exception of TRANSACTION_NONE;
+ * some databases may not support other values
+ * @exception SQLException if a database access error occurs
+ * @see DatabaseMetaData#supportsTransactionIsolationLevel
+ */
+ public void setTransactionIsolation(int level)
+ { // do nothing
+ } // end setTransactionIsolation
+
+ /**
+ * Gets this Connection's current transaction isolation level.
+ *
+ * @return the current TRANSACTION_* mode value
+ * @exception SQLException if a database access error occurs
+ */
+ public int getTransactionIsolation() throws SQLException
+ {
+ return m_conn.getTransactionIsolation();
+
+ } // end getTransactionIsolation
+
+ /**
+ * Returns the first warning reported by calls on this Connection.
+ *
+ * @return the first SQLWarning or null
+ * @exception SQLException if a database access error occurs
+ */
+ public SQLWarning getWarnings() throws SQLException
+ {
+ return m_conn.getWarnings();
+
+ } // end getWarnings
+
+ /**
+ * Clears all warnings reported for this Connection object.
+ * After a call to this method, the method getWarnings
+ * returns null until a new warning is reported for this Connection.
+ *
+ * @exception SQLException if a database access error occurs
+ */
+ public void clearWarnings() throws SQLException
+ {
+ m_conn.clearWarnings();
+
+ } // end clearWarnings
+
+ /**
+ * Creates a Statement object that will generate
+ * ResultSet objects with the given type and concurrency.
+ *
+ * @param resultSetType a result set type; see ResultSet.TYPE_XXX
+ * @param resultSetConcurrency a concurrency type; see ResultSet.CONCUR_XXX
+ * @return a new Statement object
+ * @exception SQLException if a database access error occurs
+ * @since 1.2
+ * @see What Is in the JDBC 2.0 API
+ */
+ public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException
+ {
+ return m_conn.createStatement(resultSetType,resultSetConcurrency);
+
+ } // end createStatement
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
+ throws SQLException
+ {
+ return m_conn.createStatement(resultSetType,resultSetConcurrency,resultSetHoldability);
+
+ } // end createStatement
+
+ /**
+ * Creates a PreparedStatement object that will generate
+ * ResultSet objects with the given type and concurrency.
+ * This method is the same as the prepareStatement method
+ * above, but it allows the default result set
+ * type and result set concurrency type to be overridden.
+ *
+ * @param resultSetType a result set type; see ResultSet.TYPE_XXX
+ * @param resultSetConcurrency a concurrency type; see ResultSet.CONCUR_XXX
+ * @return a new PreparedStatement object containing the pre-compiled SQL statement
+ * @exception SQLException if a database access error occurs
+ * @since 1.2
+ * @see What Is in the JDBC 2.0 API
+ */
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
+ throws SQLException
+ {
+ return m_conn.prepareStatement(sql,resultSetType,resultSetConcurrency);
+
+ } // end prepareStatement
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,
+ int resultSetHoldability) throws SQLException
+ {
+ return m_conn.prepareStatement(sql,resultSetType,resultSetConcurrency,resultSetHoldability);
+
+ } // end prepareStatement
+
+ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException
+ {
+ return m_conn.prepareStatement(sql,autoGeneratedKeys);
+
+ } // end prepareStatement
+
+ public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException
+ {
+ return m_conn.prepareStatement(sql,columnIndexes);
+
+ } // end prepareStatement
+
+ public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException
+ {
+ return m_conn.prepareStatement(sql,columnNames);
+
+ } // end prepareStatement
+
+ /**
+ * Creates a CallableStatement object that will generate
+ * ResultSet objects with the given type and concurrency.
+ * This method is the same as the prepareCall method
+ * above, but it allows the default result set
+ * type and result set concurrency type to be overridden.
+ *
+ * @param resultSetType a result set type; see ResultSet.TYPE_XXX
+ * @param resultSetConcurrency a concurrency type; see ResultSet.CONCUR_XXX
+ * @return a new CallableStatement object containing the pre-compiled SQL statement
+ * @exception SQLException if a database access error occurs
+ * @since 1.2
+ * @see What Is in the JDBC 2.0 API
+ */
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency)
+ throws SQLException
+ {
+ return m_conn.prepareCall(sql,resultSetType,resultSetConcurrency);
+
+ } // end prepareCall
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency,
+ int resultSetHoldability) throws SQLException
+ {
+ return m_conn.prepareCall(sql,resultSetType,resultSetConcurrency,resultSetHoldability);
+
+ } // end prepareCall
+
+ /**
+ * Gets the type map object associated with this connection.
+ * Unless the application has added an entry to the type map,
+ * the map returned will be empty.
+ *
+ * @return the java.util.Map object associated with this Connection object
+ * @since 1.2
+ * @see What Is in the JDBC 2.0 API
+ */
+ public java.util.Map getTypeMap() throws SQLException
+ {
+ return m_conn.getTypeMap();
+
+ } // end getTypeMap
+
+ /**
+ * Installs the given type map as the type map for
+ * this connection. The type map will be used for the
+ * custom mapping of SQL structured types and distinct types.
+ *
+ * @param the java.util.Map object to install
+ * as the replacement for this Connection
+ * object's default type map
+ * @since 1.2
+ * @see What Is in the JDBC 2.0 API
+ */
+ public void setTypeMap(java.util.Map map) throws SQLException
+ {
+ m_conn.setTypeMap(map);
+
+ } // end setTypeMap
+
+ public int getHoldability() throws SQLException
+ {
+ return m_conn.getHoldability();
+
+ } // end getHoldability
+
+ public void setHoldability(int holdability) throws SQLException
+ { // do nothing
+ } // end setHoldability
+
+ public Savepoint setSavepoint() throws SQLException
+ {
+ return m_conn.setSavepoint();
+
+ } // end setSavepont
+
+ public Savepoint setSavepoint(String name) throws SQLException
+ {
+ return m_conn.setSavepoint(name);
+
+ } // end setSavepoint
+
+ public void rollback(Savepoint savepoint) throws SQLException
+ {
+ m_conn.rollback(savepoint);
+
+ } // end rollback
+
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException
+ {
+ m_conn.releaseSavepoint(savepoint);
+
+ } // end releaseSavepoint
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ Connection getRealConnection()
+ {
+ return m_conn;
+
+ } // end getRealConnection
+
+} // end class WrappedConnection
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/BaseDialogField.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/BaseDialogField.java
new file mode 100644
index 0000000..270b0bc
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/BaseDialogField.java
@@ -0,0 +1,229 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.dialog;
+
+import java.io.*;
+import java.util.*;
+import org.w3c.dom.*;
+import com.silverwrist.util.*;
+import com.silverwrist.util.xml.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+
+public abstract class BaseDialogField implements DialogField
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private boolean m_reverse; // if true, field is on left, false = right
+ private String m_name; // field name (parameter name)
+ private String m_caption; // primary caption
+ private String m_caption2; // secondary caption
+ private boolean m_required; // is this field required?
+ private boolean m_default_enabled; // are we enabled by default?
+ private boolean m_enabled; // are we currently enabled?
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ protected BaseDialogField(boolean reverse, Element element) throws DialogException
+ {
+ m_reverse = reverse;
+ XMLLoader loader = XMLLoader.get();
+ try
+ { // get the base class stuff
+ m_name = loader.getAttribute(element,"name");
+ m_caption = loader.getAttribute(element,"caption");
+ m_caption2 = element.getAttribute("caption2");
+ m_required = loader.getAttributeBoolean(element,"required",false);
+ m_default_enabled = loader.getAttributeBoolean(element,"enabled",true);
+
+ } // end try
+ catch (XMLLoadException e)
+ { // translate the exception and return it
+ throw new DialogException(e);
+
+ } // end catch
+
+ m_enabled = m_default_enabled;
+
+ } // end constructor
+
+ protected BaseDialogField(BaseDialogField other)
+ {
+ m_reverse = other.m_reverse;
+ m_name = other.m_name;
+ m_caption = other.m_caption;
+ m_caption2 = other.m_caption2;
+ m_required = other.m_required;
+ m_default_enabled = other.m_default_enabled;
+ m_enabled = m_default_enabled;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
+
+ private final void renderCaption(TextRenderControl control, Map render_params)
+ throws IOException, RenderingException
+ {
+ PrintWriter wr = control.getWriter();
+ if (!m_enabled)
+ wr.write("");
+ wr.write(StringUtils.encodeHTML(StringUtils.replaceAllVariables(m_caption,render_params)));
+ if (StringUtils.isNotEmpty(m_caption2))
+ wr.write(" " + StringUtils.encodeHTML(StringUtils.replaceAllVariables(m_caption2,render_params)));
+ if (!m_reverse)
+ wr.write(":");
+ if (!m_enabled)
+ wr.write("");
+ if (m_required)
+ wr.write("*");
+
+ } // end renderCaption
+
+ protected final String getCaption()
+ {
+ return m_caption;
+
+ } // end getCaption
+
+ protected final void setCaption2(String s)
+ {
+ m_caption2 = s;
+
+ } // end setCaption2
+
+ protected boolean isNull(Object value)
+ {
+ return (value==null);
+
+ } // end isNull
+
+ /*--------------------------------------------------------------------------------
+ * Abstract operations
+ *--------------------------------------------------------------------------------
+ */
+
+ protected abstract void renderField(TextRenderControl control, Map render_params)
+ throws IOException, RenderingException;
+
+ protected abstract void validateContents(Request r, Object data) throws ValidationException;
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface NamedObject
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getName()
+ {
+ return m_name;
+
+ } // end getName
+
+ /*--------------------------------------------------------------------------------
+ * Abstract methods from interface DialogItem
+ *--------------------------------------------------------------------------------
+ */
+
+ public abstract Object clone();
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface DialogItem
+ *--------------------------------------------------------------------------------
+ */
+
+ public void render(TextRenderControl control, Map render_params) throws IOException, RenderingException
+ {
+ PrintWriter wr = control.getWriter();
+ wr.write("
\n");
+
+ } // end render
+
+ public boolean isEnabled()
+ {
+ return m_enabled;
+
+ } // end isEnabled
+
+ public void setEnabled(boolean flag)
+ {
+ m_enabled = flag;
+
+ } // end setEnabled
+
+ /*--------------------------------------------------------------------------------
+ * Abstract methods from interface DialogField
+ *--------------------------------------------------------------------------------
+ */
+
+ public abstract Object getValue();
+
+ public abstract boolean containsValue();
+
+ public abstract void setValue(Object obj);
+
+ public abstract void setValueFrom(Request r);
+
+ public abstract void reset();
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface DialogField
+ *--------------------------------------------------------------------------------
+ */
+
+ public void validate(Request r) throws ValidationException
+ {
+ Object val = getValue();
+ if (m_required && m_enabled && isNull(val))
+ { // null field value - we need to bail out
+ ValidationException ve = new ValidationException(BaseDialogField.class,"DialogMessages",
+ "required.field");
+ ve.setParameter(0,m_caption);
+ throw ve;
+
+ } // end if
+
+ if (m_enabled)
+ validateContents(r,val);
+
+ } // end validate
+
+ public int getFlags()
+ {
+ return (m_required ? FLAG_REQUIRED : 0);
+
+ } // end getFlags
+
+} // end class BaseDialogField
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/ButtonCaptions.properties b/src/dynamo-framework/com/silverwrist/dynamo/dialog/ButtonCaptions.properties
new file mode 100644
index 0000000..bcbb1c0
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/ButtonCaptions.properties
@@ -0,0 +1,21 @@
+# The contents of this file are subject to the Mozilla Public License Version 1.1
+# (the "License"); you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at .
+#
+# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+# WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+# language governing rights and limitations under the License.
+#
+# The Original Code is the Venice Web Communities System.
+#
+# The Initial Developer of the Original Code is Eric J. Bowersox ,
+# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+# Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+#
+# Contributor(s):
+# ---------------------------------------------------------------------------------
+# This file has been localized for the en_US locale
+cancel=Cancel
+login=Log In
+ok=OK
+reminder=Reminder
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/CheckBoxField.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/CheckBoxField.java
new file mode 100644
index 0000000..776871e
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/CheckBoxField.java
@@ -0,0 +1,187 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.dialog;
+
+import java.io.*;
+import java.util.*;
+import org.w3c.dom.*;
+import com.silverwrist.util.*;
+import com.silverwrist.util.xml.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+class CheckBoxField extends BaseDialogField
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final String YES = "Y";
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private String m_value;
+ private boolean m_default_checked;
+ private boolean m_checked;
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ CheckBoxField(Element elt) throws DialogException
+ {
+ super(true,elt);
+ XMLLoader loader = XMLLoader.get();
+ try
+ { // get the checkbox value
+ m_value = loader.getAttribute(elt,"value",YES);
+ m_default_checked = loader.getAttributeBoolean(elt,"checked",false);
+
+ } // end try
+ catch (XMLLoadException e)
+ { // translate into DialogException
+ throw new DialogException(e);
+
+ } // end catch
+
+ m_checked = m_default_checked;
+
+ } // end constructor
+
+ protected CheckBoxField(CheckBoxField other)
+ {
+ super(other);
+ m_value = other.m_value;
+ m_default_checked = other.m_default_checked;
+ m_checked = m_default_checked;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class BaseDialogField
+ *--------------------------------------------------------------------------------
+ */
+
+ protected boolean isNull(Object value)
+ {
+ return false;
+
+ } // end isNull
+
+ public int getFlags()
+ {
+ return 0;
+
+ } // end getFlags
+
+ /*--------------------------------------------------------------------------------
+ * Abstract implementations from class BaseDialogField
+ *--------------------------------------------------------------------------------
+ */
+
+ protected void renderField(TextRenderControl control, Map render_params)
+ throws IOException, RenderingException
+ {
+ PrintWriter wr = control.getWriter();
+ wr.write("");
+
+ } // end renderField
+
+ protected void validateContents(Request r, Object data) throws ValidationException
+ { // do nothing
+ } // end validateContents
+
+ public Object clone()
+ {
+ return new CheckBoxField(this);
+
+ } // end clone
+
+ public Object getValue()
+ {
+ return Boolean.valueOf(m_checked);
+
+ } // end getValue
+
+ public boolean containsValue()
+ {
+ return true;
+
+ } // end containsValue
+
+ public void setValue(Object obj)
+ {
+ if (obj==null)
+ m_checked = m_default_checked;
+ else if (obj instanceof Boolean)
+ m_checked = ((Boolean)obj).booleanValue();
+ else if (obj instanceof Number)
+ m_checked = (((Number)obj).intValue()!=0);
+ else
+ { // look at the string equivalent
+ String s = obj.toString();
+ if (StringUtils.isBooleanTrue(s))
+ m_checked = true;
+ else if (StringUtils.isBooleanFalse(s))
+ m_checked = false;
+
+ } // end else
+
+ } // end setValue
+
+ public void setValueFrom(Request r)
+ {
+ RequestHelper rh = new RequestHelper(r);
+ String[] vals = rh.getStringParameterValues(getName());
+ if (vals!=null)
+ { // if no values are set, we're definitely NOT checked
+ for (int i=0; i.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.dialog;
+
+import java.io.*;
+import java.util.*;
+import org.w3c.dom.*;
+import com.silverwrist.util.*;
+import com.silverwrist.util.xml.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+abstract class CommonTextField extends BaseDialogField
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final int MINSIZE = 2;
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private String m_tagname;
+ private String m_value = null;
+ private int m_size;
+ private int m_maxlength;
+ private int m_real_maxlength;
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ protected CommonTextField(String tagname, Element elt) throws DialogException
+ {
+ super(false,elt);
+ m_tagname = tagname;
+ XMLLoader loader = XMLLoader.get();
+ try
+ { // load the "size" attributes for the text field
+ int my_size = loader.getAttributeInt(elt,"size");
+ DOMElementHelper h = new DOMElementHelper(elt);
+ if (h.hasAttribute("maxlength"))
+ { // get the maxlength and figure it in...
+ m_real_maxlength = loader.getAttributeInt(elt,"maxlength");
+ m_maxlength = Math.max(m_real_maxlength,MINSIZE);
+ m_size = Math.max(my_size,MINSIZE);
+
+ } // end if
+ else
+ { // "size" is all we got - maxlength is equal to it
+ m_real_maxlength = my_size;
+ m_maxlength = m_size = Math.max(my_size,MINSIZE);
+
+ } // end else
+
+ } // end try
+ catch (XMLLoadException e)
+ { // translate exception here
+ throw new DialogException(e);
+
+ } // end catch
+
+ } // end constructor
+
+ protected CommonTextField(String tagname, int width, Element elt) throws DialogException
+ {
+ super(false,elt);
+ m_tagname = tagname;
+ m_real_maxlength = width;
+ m_maxlength = m_size = Math.max(width,MINSIZE);
+
+ } // end constructor
+
+ protected CommonTextField(CommonTextField other)
+ {
+ super(other);
+ m_tagname = other.m_tagname;
+ m_size = other.m_size;
+ m_maxlength = other.m_maxlength;
+ m_real_maxlength = other.m_real_maxlength;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class BaseDialogField
+ *--------------------------------------------------------------------------------
+ */
+
+ protected boolean isNull(Object value)
+ {
+ return StringUtils.isEmpty((String)value);
+
+ } // end isNull
+
+ /*--------------------------------------------------------------------------------
+ * Abstract implementations from class BaseDialogField
+ *--------------------------------------------------------------------------------
+ */
+
+ protected void renderField(TextRenderControl control, Map render_params)
+ throws IOException, RenderingException
+ {
+ PrintWriter wr = control.getWriter();
+ wr.write("");
+
+ } // end renderField
+
+ protected void validateContents(Request r, Object data) throws ValidationException
+ {
+ if ((data!=null) && (data.toString().length()>m_real_maxlength))
+ { // this value is too long
+ ValidationException ve = new ValidationException(CommonTextField.class,"DialogMessages","text.tooLong");
+ ve.setParameter(0,getCaption());
+ ve.setParameter(1,String.valueOf(m_real_maxlength));
+ throw ve;
+
+ } // end if
+
+ } // end validateContents
+
+ public Object getValue()
+ {
+ return m_value;
+
+ } // end getValue
+
+ public boolean containsValue()
+ {
+ return StringUtils.isNotEmpty(m_value);
+
+ } // end containsValue
+
+ public void setValue(Object obj)
+ {
+ if (obj==null)
+ m_value = null;
+ else
+ m_value = obj.toString();
+ if ((m_value!=null) && StringUtils.isEmpty(m_value))
+ m_value = null;
+
+ } // end setValue
+
+ public void setValueFrom(Request r)
+ {
+ RequestHelper rh = new RequestHelper(r);
+ m_value = rh.getParameterString(getName());
+ if ((m_value!=null) && StringUtils.isEmpty(m_value))
+ m_value = null;
+
+ } // end setValueFrom
+
+ public void reset()
+ {
+ m_value = null;
+
+ } // end reset
+
+} // end class CommonTextField
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/CountryListField.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/CountryListField.java
new file mode 100644
index 0000000..a892fd3
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/CountryListField.java
@@ -0,0 +1,123 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.dialog;
+
+import java.util.*;
+import org.w3c.dom.Element;
+import com.silverwrist.util.*;
+import com.silverwrist.dynamo.except.DialogException;
+
+class CountryListField extends PickListField
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static Country UNKNOWN_COUNTRY = International.get().getCountryForCode("XX");
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ CountryListField(Element elt) throws DialogException
+ {
+ super(elt);
+
+ } // end constructor
+
+ protected CountryListField(CountryListField other)
+ {
+ super(other);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Abstract implementations from class BaseDialogField
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object clone()
+ {
+ return new CountryListField(this);
+
+ } // end clone
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class BaseDialogField
+ *--------------------------------------------------------------------------------
+ */
+
+ protected boolean isNull(Object value)
+ {
+ return ((value==null) || UNKNOWN_COUNTRY.equals(value));
+
+ } // end isNull
+
+ /*--------------------------------------------------------------------------------
+ * Abstract implementations from class PickListField
+ *--------------------------------------------------------------------------------
+ */
+
+ protected Iterator getChoices()
+ {
+ return International.get().getCountryList().iterator();
+
+ } // end getChoices
+
+ protected String getChoiceName(Object choice)
+ {
+ return ((Country)choice).getCode();
+
+ } // end getChoiceName
+
+ protected String getChoiceDisplay(Object choice)
+ {
+ return ((Country)choice).getName();
+
+ } // end getChoiceDisplay
+
+ protected Object getChoiceForName(String name)
+ {
+ return International.get().getCountryForCode(name);
+
+ } // end getChoiceForName
+
+ protected boolean isValidChoice(Object choice)
+ {
+ if (!(choice instanceof Country))
+ return false;
+ Country x = International.get().getCountryForCode(((Country)choice).getCode());
+ return x.equals(choice);
+
+ } // end isValidChoice
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class PickListField
+ *--------------------------------------------------------------------------------
+ */
+
+ public boolean containsValue()
+ {
+ Object v = getValue();
+ return ((v!=null) && !UNKNOWN_COUNTRY.equals(v));
+
+ } // end containsValue
+
+} // end class CountryListField
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/DefaultDialogLAF.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/DefaultDialogLAF.java
new file mode 100644
index 0000000..b32947a
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/DefaultDialogLAF.java
@@ -0,0 +1,85 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.dialog;
+
+import java.util.*;
+import com.silverwrist.dynamo.iface.*;
+
+class DefaultDialogLAF implements DialogPLAF
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private ResourceBundle m_captions;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ DefaultDialogLAF()
+ {
+ m_captions = ResourceBundle.getBundle("com.silverwrist.dynamo.dialog.ButtonCaptions",Locale.getDefault());
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface DialogPLAF
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object getButtonRendering(String button_name)
+ {
+ String caption;
+ try
+ { // get the default caption
+ caption = m_captions.getString(button_name);
+
+ } // end try
+ catch (MissingResourceException e)
+ { // default to just using the button name
+ caption = button_name;
+
+ } // end catch
+
+ StringBuffer buf = new StringBuffer("");
+ return buf.toString();
+
+ } // end getButtonRendering
+
+ public boolean isButtonClicked(Request r, String button_name)
+ {
+ return r.getParameters().containsKey(button_name);
+
+ } // end isButtonClicked
+
+ public Object getContentHeader(String title, String subtitle)
+ {
+ StringBuffer buf = new StringBuffer("");
+ buf.append(title).append("\n");
+ if (subtitle!=null)
+ buf.append(" ").append(subtitle).append("\n");
+ buf.append("\n");
+ return buf.toString();
+
+ } // end getContentHeader
+
+} // end class DefaultDialogLAF
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/DialogImpl.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/DialogImpl.java
new file mode 100644
index 0000000..0a70ec2
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/DialogImpl.java
@@ -0,0 +1,643 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.dialog;
+
+import java.io.*;
+import java.util.*;
+import org.w3c.dom.*;
+import com.silverwrist.util.*;
+import com.silverwrist.util.xml.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.except.*;
+
+class DialogImpl implements Dialog
+{
+ /*--------------------------------------------------------------------------------
+ * Internal class to "peel off" certain dialog items that are tags
+ *--------------------------------------------------------------------------------
+ */
+
+ private class InternalFilter implements DialogItemFactory
+ {
+ /*====================================================================
+ * Attributes
+ *====================================================================
+ */
+
+ private DialogItemFactory m_inner;
+ private HashMap m_rp = new HashMap();
+
+ /*====================================================================
+ * Constructor
+ *====================================================================
+ */
+
+ InternalFilter(DialogItemFactory inner)
+ {
+ m_inner = inner;
+
+ } // end constructor
+
+ /*====================================================================
+ * Implementations from interface DialogItemFactory
+ *====================================================================
+ */
+
+ public DialogItem createDialogItem(Element elt, DialogPLAF plaf) throws DialogException
+ {
+ try
+ { // strip out certain items we need from the element stream
+ XMLLoader loader = XMLLoader.get();
+ String tagname = elt.getTagName();
+ if (tagname.equals("title"))
+ { // get title
+ m_default_title = loader.getText(elt);
+ if (m_default_title!=null)
+ m_default_title = m_default_title.trim();
+
+ } // end if
+ else if (tagname.equals("subtitle"))
+ { // get subtitle (not required)
+ DOMElementHelper h = new DOMElementHelper(elt);
+ m_default_subtitle = h.getElementText();
+ if (m_default_subtitle!=null)
+ m_default_subtitle = m_default_subtitle.trim();
+
+ } // end else if
+ else if (tagname.equals("action"))
+ { // get action and action type
+ m_action = loader.getText(elt);
+ if (m_action!=null)
+ m_action = m_action.trim();
+ m_action_type = loader.getAttribute(elt,"type","SERVLET");
+
+ } // end else if
+ else if (tagname.equals("render-param"))
+ { // get a rendering parameter
+ String name = loader.getAttribute(elt,"name");
+ DOMElementHelper h = new DOMElementHelper(elt);
+ String value = h.getElementText();
+ if (value!=null)
+ value = value.trim();
+ else
+ value = "";
+ m_rp.put(name,value);
+
+ } // end else if
+ else if (tagname.equals("instructions"))
+ { // get instructions (not required)
+ DOMElementHelper h = new DOMElementHelper(elt);
+ m_default_instructions = h.getElementText();
+ if (m_default_instructions!=null)
+ m_default_instructions = m_default_instructions.trim();
+
+ } // end else if
+ else // go create a dialog item
+ return m_inner.createDialogItem(elt,plaf);
+
+ } // end try
+ catch (XMLLoadException e)
+ { // translate XML Load exception to dialog exception
+ throw new DialogException(e);
+
+ } // end catch
+
+ return null;
+
+ } // end createDialogItem
+
+ /*====================================================================
+ * External operations
+ *====================================================================
+ */
+
+ Map renderParams()
+ {
+ if (m_rp.isEmpty())
+ return Collections.EMPTY_MAP;
+ else
+ return Collections.unmodifiableMap(m_rp);
+
+ } // end renderParams
+
+ } // end class InternalFilter
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private DialogPLAF m_plaf;
+ private String m_name;
+ private String m_default_button = null;
+ private String m_default_title = null;
+ private String m_default_subtitle = null;
+ private String m_action = null;
+ private String m_action_type = null;
+ private String m_default_instructions = null;
+ private boolean m_any_required;
+ private boolean m_need_multipart;
+ private List m_field_order;
+ private Map m_field_map;
+ private List m_button_order;
+ private Map m_button_map;
+ private List m_hidden_order;
+ private Map m_hidden_map;
+ private String m_title = null;
+ private String m_subtitle = null;
+ private String m_instructions = null;
+ private String m_error_message = null;
+ private Map m_default_render_params;
+ private HashMap m_render_params;
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ DialogImpl(Element dialog_element, DialogItemFactory item_factory, DialogPLAF plaf) throws DialogException
+ {
+ // Copy the look-and-feel object reference.
+ m_plaf = plaf;
+
+ // Get the basic stuff from the root tag itself.
+ XMLLoader loader = XMLLoader.get();
+ try
+ { // get the dialog name
+ m_name = loader.getAttribute(dialog_element,"name");
+ m_default_button = dialog_element.getAttribute("defaultbutton");
+
+ } // end try
+ catch (XMLLoadException e)
+ { // translate to DialogException
+ throw new DialogException(e);
+
+ } // end catch
+
+ // Load the fields.
+ ArrayList field_order = new ArrayList();
+ HashMap field_map = new HashMap();
+ ArrayList button_order = new ArrayList();
+ HashMap button_map = new HashMap();
+ ArrayList hidden_order = new ArrayList();
+ HashMap hidden_map = new HashMap();
+ int global_flags = 0;
+ InternalFilter factory = new InternalFilter(item_factory);
+ NodeList nl = dialog_element.getChildNodes();
+ for (int i=0; i\n"
+ + StringUtils.encodeHTML(m_error_message) + "\n
\n");
+
+ // Write the start of the form.
+ wr.write("\n");
+
+ } // end render
+
+ public void reset()
+ {
+ m_title = m_default_title;
+ m_subtitle = m_default_subtitle;
+ m_instructions = m_default_instructions;
+
+ Iterator it = m_field_order.iterator();
+ while (it.hasNext())
+ { // call reset on each field
+ DialogField fld = (DialogField)(it.next());
+ fld.reset();
+
+ } // end while
+
+ it = m_hidden_order.iterator();
+ while (it.hasNext())
+ { // call reset on each hidden field
+ DialogHiddenItem hfld = (DialogHiddenItem)(it.next());
+ hfld.reset();
+
+ } // end while
+
+ } // end reset
+
+ public void load(Request r)
+ {
+ Iterator it = m_field_order.iterator();
+ while (it.hasNext())
+ { // call setValueFrom on each field
+ DialogField fld = (DialogField)(it.next());
+ fld.setValueFrom(r);
+
+ } // end while
+
+ it = m_hidden_order.iterator();
+ while (it.hasNext())
+ { // call setValueFrom on each hidden field
+ DialogHiddenItem hfld = (DialogHiddenItem)(it.next());
+ hfld.setValueFrom(r);
+
+ } // end while
+
+ } // end load
+
+ public Object getValue(String fieldname)
+ {
+ DialogField fld = getField(fieldname);
+ if (fld==null)
+ { // try looking for a hidden field
+ DialogHiddenItem hfld = getHiddenItem(fieldname);
+ if (hfld==null)
+ return null;
+ else
+ return hfld.getValue();
+
+ } // end if
+ else
+ return fld.getValue();
+
+ } // end getValue
+
+ public boolean containsValue(String fieldname)
+ {
+ DialogField fld = getField(fieldname);
+ if (fld!=null)
+ return fld.containsValue();
+
+ DialogHiddenItem hfld = getHiddenItem(fieldname);
+ if (hfld!=null)
+ return hfld.containsValue();
+
+ return false;
+
+ } // end containsValue
+
+ public void setValue(String fieldname, Object value)
+ {
+ DialogField fld = getField(fieldname);
+ if (fld!=null)
+ fld.setValue(value);
+ else
+ { // try setting a hidden value
+ DialogHiddenItem hfld = getHiddenItem(fieldname);
+ if (hfld!=null)
+ hfld.setValue(value);
+
+ } // end else
+
+ } // end setValue
+
+ public boolean isEnabled(String fieldname)
+ {
+ DialogField fld = getField(fieldname);
+ if (fld==null)
+ return false;
+ else
+ return fld.isEnabled();
+
+ } // end isEnabled
+
+ public void setEnabled(String fieldname, boolean flag)
+ {
+ DialogField fld = getField(fieldname);
+ if (fld!=null)
+ fld.setEnabled(flag);
+
+ } // end setEnabled
+
+ public void validate(Request r) throws ValidationException
+ {
+ // validate all the fields individually
+ Iterator it = m_field_order.iterator();
+ while (it.hasNext())
+ { // call reset on each field
+ DialogField fld = (DialogField)(it.next());
+ fld.validate(r);
+
+ } // end while
+
+ } // end validate
+
+ public String getTitle()
+ {
+ return m_title;
+
+ } // end getTitle
+
+ public void setTitle(String s)
+ {
+ m_title = s;
+
+ } // end setTitle
+
+ public String getSubtitle()
+ {
+ return m_subtitle;
+
+ } // end getSubtitle
+
+ public void setSubtitle(String s)
+ {
+ m_subtitle = s;
+
+ } // end setSubtitle
+
+ public String getInstructions()
+ {
+ return m_instructions;
+
+ } // end getInstructions
+
+ public void setInstructions(String s)
+ {
+ m_instructions = s;
+
+ } // end setInstructions
+
+ public void setErrorMessage(String s)
+ {
+ m_error_message = s;
+
+ } // end setErrorMessage
+
+ public String getClickedButton(Request r)
+ {
+ Iterator it = m_button_order.iterator();
+ while (it.hasNext())
+ { // look for a clicked button
+ DialogButton bn = (DialogButton)(it.next());
+ if (bn.isClicked(r))
+ return bn.getName();
+
+ } // end while
+
+ return m_default_button;
+
+ } // end getClickedButton
+
+ public synchronized void setRenderParam(String name, String value)
+ {
+ if (m_render_params.containsKey(name))
+ m_render_params.put(name,value);
+
+ } // end setRenderParam
+
+} // end class DialogImpl
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/DialogManager.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/DialogManager.java
new file mode 100644
index 0000000..19cf0cf
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/DialogManager.java
@@ -0,0 +1,300 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.dialog;
+
+import java.io.*;
+import java.util.*;
+import org.w3c.dom.*;
+import com.silverwrist.util.*;
+import com.silverwrist.util.xml.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+public class DialogManager
+ implements NamedObject, ComponentInitialize, ComponentShutdown, DialogFactoryConfig, DialogLoader
+{
+ /*--------------------------------------------------------------------------------
+ * Internal class implementing the dialog item factory
+ *--------------------------------------------------------------------------------
+ */
+
+ private class Factory implements DialogItemFactory
+ {
+ /*====================================================================
+ * Constructor
+ *====================================================================
+ */
+
+ Factory()
+ { // do nothing
+ } // end constructor
+
+ /*====================================================================
+ * Implementations from interface DialogItemFactory
+ *====================================================================
+ */
+
+ public DialogItem createDialogItem(Element elt, DialogPLAF plaf) throws DialogException
+ {
+ DialogItemFactory fact = (DialogItemFactory)(m_factory_data.get(elt.getTagName()));
+ if (fact!=null)
+ return fact.createDialogItem(elt,plaf);
+
+ throw new UnknownDialogFieldException(elt.getTagName(),elt);
+
+ } // end createDialogItem
+
+ } // end class Factory
+
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final int DEFAULT_HARD_LIMIT = 5;
+ private static final int DEFAULT_SOFT_LIMIT = 20;
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private String m_name;
+ private String m_resource_prefix;
+ private ResourceProvider m_prov;
+ private DialogPLAF m_plaf;
+ private HardSoftCache m_resource_cache;
+ private Hashtable m_factory_data = new Hashtable();
+ private ComponentShutdown m_shut_init;
+ private ComponentShutdown m_shut_runtime;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public DialogManager()
+ { // do nothing
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface NamedObject
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getName()
+ {
+ return m_name;
+
+ } // end getName
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ComponentInitialize
+ *--------------------------------------------------------------------------------
+ */
+
+ public void initialize(Element config_root, ServiceProvider services) throws ConfigException
+ {
+ XMLLoader loader = XMLLoader.get();
+ int hard_limit = DEFAULT_HARD_LIMIT;
+ int soft_limit = DEFAULT_SOFT_LIMIT;
+ try
+ { // verify the right node name
+ loader.verifyNodeName(config_root,"object");
+
+ // get the object's name
+ m_name = loader.getAttribute(config_root,"name");
+
+ // get the resource prefix
+ DOMElementHelper config_h = new DOMElementHelper(config_root);
+ m_resource_prefix = config_h.getSubElementText("resource-prefix");
+ if (m_resource_prefix==null)
+ { // set up default prefix
+ m_resource_prefix = "/";
+
+ } // end if
+ else
+ { // make sure the prefix is properly set
+ if (!(m_resource_prefix.startsWith("/")))
+ m_resource_prefix = "/" + m_resource_prefix;
+ if (!(m_resource_prefix.endsWith("/")))
+ m_resource_prefix += "/";
+
+ } // end else
+
+ // get the resource dialog cache information
+ Element elt = config_h.getSubElement("resource-dialog-cache");
+ if (elt!=null)
+ { // get the cache limits
+ hard_limit = loader.getAttributeInt(elt,"hardlimit",DEFAULT_HARD_LIMIT);
+ soft_limit = loader.getAttributeInt(elt,"softlimit",DEFAULT_SOFT_LIMIT);
+
+ } // end if
+
+ } // end try
+ catch (XMLLoadException e)
+ { // error loading XML config data
+ throw new ConfigException(e);
+
+ } // end catch
+
+ // Get the standard resource provider.
+ m_prov = (ResourceProvider)(services.queryService(ResourceProvider.class));
+
+ // Set up the default look-and-feel provider.
+ m_plaf = new DefaultDialogLAF();
+
+ // Create the resource cache.
+ m_resource_cache = new HardSoftCache(hard_limit,soft_limit);
+
+ // Set up the standard factory elements.
+ DialogItemFactory fact = new StdItemFactory();
+ m_factory_data.put("button",fact);
+ m_factory_data.put("checkbox",fact);
+ m_factory_data.put("countrylist",fact);
+ m_factory_data.put("dynamo-id",fact);
+ m_factory_data.put("email",fact);
+ m_factory_data.put("header",fact);
+ m_factory_data.put("hidden",fact);
+ m_factory_data.put("int",fact);
+ m_factory_data.put("localelist",fact);
+ m_factory_data.put("password",fact);
+ m_factory_data.put("text",fact);
+ m_factory_data.put("tzlist",fact);
+
+ // Get the service provider hooks interface.
+ HookServiceProviders hooker = (HookServiceProviders)(services.queryService(HookServiceProviders.class));
+
+ // Hook the initialization services with our initialization interface.
+ SingletonServiceProvider ssp = new SingletonServiceProvider("DialogManager",DialogFactoryConfig.class,
+ (DialogFactoryConfig)this);
+ m_shut_init = hooker.hookInitServiceProvider(ssp);
+
+ // Hook the runtime services with the DialogLoader interface.
+ ssp = new SingletonServiceProvider("DialogManager",DialogLoader.class,(DialogLoader)this);
+ m_shut_runtime = hooker.hookRuntimeServiceProvider(ssp);
+
+ } // end initialize
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ComponentShutdown
+ *--------------------------------------------------------------------------------
+ */
+
+ public void shutdown()
+ {
+ m_shut_runtime.shutdown();
+ m_shut_runtime = null;
+ m_shut_init.shutdown();
+ m_shut_init = null;
+ m_resource_cache.clear();
+ m_factory_data.clear();
+ m_plaf = null;
+ m_prov = null;
+
+ } // end shutdown
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface DialogFactoryConfig
+ *--------------------------------------------------------------------------------
+ */
+
+ public synchronized void setDialogPLAF(DialogPLAF plaf)
+ {
+ m_plaf = ((plaf==null) ? new DefaultDialogLAF() : plaf);
+
+ } // end setDialogPLAF
+
+ public ComponentShutdown registerDialogItem(String item_name, DialogItemFactory factory)
+ throws ConfigException
+ {
+ if (m_factory_data.containsKey(item_name))
+ { // already registered - can't register again
+ ConfigException ce = new ConfigException(DialogManager.class,"DialogMessages","control.registered");
+ ce.setParameter(0,item_name);
+ throw ce;
+
+ } // end if
+
+ m_factory_data.put(item_name,factory);
+ return new ShutdownHashtableRemove(m_factory_data,item_name);
+
+ } // end registerDialogItem
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface DialogLoader
+ *--------------------------------------------------------------------------------
+ */
+
+ public Dialog loadDialogResource(String resource_name) throws DialogException
+ {
+ Dialog dlg = (Dialog)(m_resource_cache.get(resource_name));
+ if (dlg==null)
+ { // OK, try loading the resource for the dialog...
+ InputStream stm = null;
+ try
+ { // get the resource as a stream
+ stm = m_prov.getResource(m_resource_prefix + resource_name);
+
+ // parse it into an XML document
+ XMLLoader loader = XMLLoader.get();
+ Document doc = loader.load(stm,false);
+
+ // get the root element, which should be
+ Element elt = loader.getRootElement(doc,"dialog");
+
+ // now create the dialog! (and cache it)
+ dlg = new DialogImpl(elt,new Factory(),m_plaf);
+ m_resource_cache.put(resource_name,dlg);
+
+ } // end try
+ catch (IOException e)
+ { // translate the exception and throw it
+ DialogException de = new DialogException(DialogManager.class,"DialogMessages","dlg.loadErr",e);
+ de.setParameter(0,resource_name);
+ de.setParameter(1,e.getMessage());
+ throw de;
+
+ } // end catch
+ catch (NoSuchResourceException e)
+ { // translate this exception and throw it as well
+ DialogException de = new DialogException(DialogManager.class,"DialogMessages","dlg.notFound",e);
+ de.setParameter(0,resource_name);
+ throw de;
+
+ } // end catch
+ catch (XMLLoadException e)
+ { // this translates straight into a DialogException
+ throw new DialogException(e);
+
+ } // end catch
+ finally
+ { // make sure and close the stream before we go
+ IOUtils.shutdown(stm);
+
+ } // end finally
+
+ } // end if
+
+ // Clone the dialog before we return it, so as not to mess up the one in the cache.
+ return (Dialog)(dlg.clone());
+
+ } // end loadDialogResource
+
+} // end class DialogManager
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/DialogMessages.properties b/src/dynamo-framework/com/silverwrist/dynamo/dialog/DialogMessages.properties
new file mode 100644
index 0000000..bae8827
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/DialogMessages.properties
@@ -0,0 +1,31 @@
+# The contents of this file are subject to the Mozilla Public License Version 1.1
+# (the "License"); you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at .
+#
+# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+# WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+# language governing rights and limitations under the License.
+#
+# The Original Code is the Venice Web Communities System.
+#
+# The Initial Developer of the Original Code is Eric J. Bowersox ,
+# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+# Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+#
+# Contributor(s):
+# ---------------------------------------------------------------------------------
+# This file has been localized for the en_US locale
+required.field=A value must be entered for the "{0}" field.
+text.tooLong=The value of the "{0}" field must be no longer than {1} characters.
+bad.itemType=No implementation exists for dialog item type "{0}".
+bad.dynamoID=There is an invalid character in the "{0}" field. Valid characters are letters, digits, -, _, !, ~, *, ', and $.
+dlg.noTitle=No default title specified for dialog "{0}".
+dlg.noAction=No action URL specified for dialog "{0}".
+required.msg=Required fields are marked with a *.
+control.registered=A control has already been registered with the name "{0}".
+dlg.loadErr=Unable to load the data for dialog resource "{0}": {1}
+dlg.notFound=Unable to locate dialog resource "{0}".
+bad.email=The value in the "{0}" field is not a valid E-mail address.
+text.notInteger=Invalid non-numeric character in the "{0}" field.
+int.tooSmall=The value of the "{0}" field must be greater than or equal to {1}.
+int.tooLarge=The value of the "{0}" field must be less than or equal to {1}.
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/DynamoIDField.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/DynamoIDField.java
new file mode 100644
index 0000000..dd6d3e4
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/DynamoIDField.java
@@ -0,0 +1,73 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.dialog;
+
+import org.w3c.dom.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+class DynamoIDField extends TextField
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ DynamoIDField(Element elt) throws DialogException
+ {
+ super(elt);
+
+ } // end constructor
+
+ protected DynamoIDField(DynamoIDField other)
+ {
+ super(other);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class CommonTextField
+ *--------------------------------------------------------------------------------
+ */
+
+ protected void validateContents(Request r, Object data) throws ValidationException
+ {
+ super.validateContents(r,data);
+ if ((data!=null) && !(IDUtils.isValidDynamoID(data.toString())))
+ { // not a valid Dynamo ID - throw exception
+ ValidationException ve = new ValidationException(DynamoIDField.class,"DialogMessages","bad.dynamoID");
+ ve.setParameter(0,getCaption());
+ throw ve;
+
+ } // end if
+
+ } // end validateContents
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class TextField
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object clone()
+ {
+ return new DynamoIDField(this);
+
+ } // end clone
+
+} // end class DynamoIDField
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/EmailAddressField.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/EmailAddressField.java
new file mode 100644
index 0000000..4a33fe2
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/EmailAddressField.java
@@ -0,0 +1,73 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.dialog;
+
+import org.w3c.dom.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+class EmailAddressField extends TextField
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ EmailAddressField(Element elt) throws DialogException
+ {
+ super(elt);
+
+ } // end constructor
+
+ protected EmailAddressField(EmailAddressField other)
+ {
+ super(other);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class CommonTextField
+ *--------------------------------------------------------------------------------
+ */
+
+ protected void validateContents(Request r, Object data) throws ValidationException
+ {
+ super.validateContents(r,data);
+ if ((data!=null) && !(IDUtils.isValidEmailAddress(data.toString())))
+ { // not a valid E-mail address - throw exception
+ ValidationException ve = new ValidationException(EmailAddressField.class,"DialogMessages","bad.email");
+ ve.setParameter(0,getCaption());
+ throw ve;
+
+ } // end if
+
+ } // end validateContents
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class TextField
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object clone()
+ {
+ return new EmailAddressField(this);
+
+ } // end clone
+
+} // end class EmailAddressField
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/HeaderItem.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/HeaderItem.java
new file mode 100644
index 0000000..a4d0ee4
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/HeaderItem.java
@@ -0,0 +1,177 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.dialog;
+
+import java.io.*;
+import java.util.*;
+import org.w3c.dom.*;
+import com.silverwrist.util.*;
+import com.silverwrist.util.xml.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+
+class HeaderItem implements DialogField
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private String m_name; // name of header
+ private String m_caption; // caption to display
+ private String m_text; // text to display on right
+ private boolean m_default_enabled; // enabled or not?
+ private boolean m_enabled; // enabled or not?
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ HeaderItem(Element elt) throws DialogException
+ {
+ XMLLoader loader = XMLLoader.get();
+ try
+ { // get the elements
+ m_name = loader.getAttribute(elt,"name");
+ m_caption = loader.getAttribute(elt,"caption");
+ DOMElementHelper h = new DOMElementHelper(elt);
+ m_text = h.getElementText();
+ if (m_text!=null)
+ m_text = m_text.trim();
+ m_default_enabled = loader.getAttributeBoolean(elt,"enabled",true);
+
+ } // end try
+ catch (XMLLoadException e)
+ { // translate XML loader exception
+ throw new DialogException(e);
+
+ } // end catch
+
+ m_enabled = m_default_enabled;
+
+ } // end constructor
+
+ protected HeaderItem(HeaderItem other)
+ {
+ m_name = other.m_name;
+ m_caption = other.m_caption;
+ m_text = other.m_text;
+ m_default_enabled = other.m_default_enabled;
+ m_enabled = m_default_enabled;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface NamedObject
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getName()
+ {
+ return m_name;
+
+ } // end getName
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface DialogItem
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object clone()
+ {
+ return new HeaderItem(this);
+
+ } // end clone
+
+ public void render(TextRenderControl control, Map render_params) throws IOException, RenderingException
+ {
+ PrintWriter wr = control.getWriter();
+ wr.write("
");
+ if (m_text==null)
+ wr.write(" ");
+ else
+ { // write out the text on the right hand side
+ if (!m_enabled)
+ wr.write("");
+ wr.write(StringUtils.encodeHTML(StringUtils.replaceAllVariables(m_text,render_params)));
+ if (!m_enabled)
+ wr.write("");
+
+ } // end else
+
+ wr.write("
\n
\n");
+
+ } // end render
+
+ public boolean isEnabled()
+ {
+ return m_enabled;
+
+ } // end isEnabled
+
+ public void setEnabled(boolean flag)
+ {
+ m_enabled = flag;
+
+ } // end setEnabled
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface DialogField
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object getValue()
+ {
+ return null;
+
+ } // end getValue
+
+ public boolean containsValue()
+ {
+ return false;
+
+ } // end containsValue
+
+ public void setValue(Object obj)
+ { // do nothing
+ } // end setValue
+
+ public void setValueFrom(Request r)
+ { // do nothing
+ } // end setValueFrom
+
+ public void validate(Request r)
+ { // do nothing
+ } // end validate
+
+ public void reset()
+ { // do nothing
+ } // end reset
+
+ public int getFlags()
+ {
+ return 0;
+
+ } // end getFlags
+
+} // end class HeaderItem
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/HiddenField.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/HiddenField.java
new file mode 100644
index 0000000..7760373
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/HiddenField.java
@@ -0,0 +1,148 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.dialog;
+
+import java.io.*;
+import java.util.*;
+import org.w3c.dom.*;
+import com.silverwrist.util.*;
+import com.silverwrist.util.xml.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+class HiddenField implements DialogHiddenItem
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private String m_name;
+ private String m_default_value;
+ private String m_value;
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ HiddenField(Element elt) throws DialogException
+ {
+ XMLLoader loader = XMLLoader.get();
+ try
+ { // get field parameters from XML
+ m_name = loader.getAttribute(elt,"name");
+ m_default_value = loader.getAttribute(elt,"value","");
+
+ } // end try
+ catch (XMLLoadException e)
+ { // translate this exception
+ throw new DialogException(e);
+
+ } // end catch
+
+ m_value = m_default_value;
+
+ } // end class HiddenField
+
+ protected HiddenField(HiddenField other)
+ {
+ m_name = other.m_name;
+ m_default_value = other.m_default_value;
+ m_value = m_default_value;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface NamedObject
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getName()
+ {
+ return m_name;
+
+ } // end getName
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface DialogItem
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object clone()
+ {
+ return new HiddenField(this);
+
+ } // end clone
+
+ public void render(TextRenderControl control, Map render_params) throws IOException, RenderingException
+ {
+ PrintWriter wr = control.getWriter();
+ wr.write("\n");
+
+ } // end render
+
+ public boolean isEnabled()
+ {
+ return true;
+
+ } // end isEnabled
+
+ public void setEnabled(boolean flag)
+ { // do nothing
+ } // end setEnabled
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface DialogHiddenItem
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object getValue()
+ {
+ return m_value;
+
+ } // end getValue
+
+ public boolean containsValue()
+ {
+ return StringUtils.isNotEmpty(m_value);
+
+ } // end containsValue
+
+ public void setValue(Object obj)
+ {
+ m_value = ((obj==null) ? m_default_value : obj.toString());
+
+ } // end setValue
+
+ public void setValueFrom(Request r)
+ {
+ RequestHelper rh = new RequestHelper(r);
+ m_value = rh.getParameterString(m_name);
+
+ } // end setValueFrom
+
+ public void reset()
+ {
+ m_value = m_default_value;
+
+ } // end reset
+
+} // end class HiddenField
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/IntegerField.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/IntegerField.java
new file mode 100644
index 0000000..67b8300
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/IntegerField.java
@@ -0,0 +1,271 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.dialog;
+
+import java.io.*;
+import java.util.*;
+import org.w3c.dom.*;
+import com.silverwrist.util.xml.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+class IntegerField extends CommonTextField
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final double LN10 = Math.log(10.0);
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private int m_min_value;
+ private int m_max_value;
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ IntegerField(Element elt) throws DialogException
+ {
+ super("text",numDigits(elt),elt);
+ XMLLoader loader = XMLLoader.get();
+ DOMElementHelper h = new DOMElementHelper(elt);
+ int min = Integer.MIN_VALUE;
+ int max = Integer.MAX_VALUE;
+ try
+ { // get the min and max values from the config item
+ if (h.hasAttribute("min"))
+ min = loader.getAttributeInt(elt,"min");
+ if (h.hasAttribute("max"))
+ max = loader.getAttributeInt(elt,"max");
+
+ } // end try
+ catch (XMLLoadException e)
+ { // translate the exception
+ throw new DialogException(e);
+
+ } // end catch
+
+ if (max0)
+ return 1 + (int)(Math.floor(Math.log((double)v) / LN10));
+ else
+ return 2 + (int)(Math.floor(Math.log((double)(-v)) / LN10));
+
+ } // end numDigits
+
+ private static final int numDigits(int min, int max)
+ {
+ return Math.max(numDigits(min),numDigits(max));
+
+ } // end numDigits
+
+ private static final int numDigits(Element elt) throws DialogException
+ {
+ XMLLoader loader = XMLLoader.get();
+ DOMElementHelper h = new DOMElementHelper(elt);
+ int min = Integer.MIN_VALUE;
+ int max = Integer.MAX_VALUE;
+ try
+ { // get the min and max values from the config item
+ if (h.hasAttribute("min"))
+ min = loader.getAttributeInt(elt,"min");
+ if (h.hasAttribute("max"))
+ max = loader.getAttributeInt(elt,"max");
+
+ } // end try
+ catch (XMLLoadException e)
+ { // translate the exception
+ throw new DialogException(e);
+
+ } // end catch
+
+ return numDigits(min,max);
+
+ } // end numDigits
+
+ /*--------------------------------------------------------------------------------
+ * Abstract implementations from class BaseDialogField
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object clone()
+ {
+ return new IntegerField(this);
+
+ } // end clone
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class CommonDialogField
+ *--------------------------------------------------------------------------------
+ */
+
+ protected void renderField(TextRenderControl control, Map render_params)
+ throws IOException, RenderingException
+ {
+ super.renderField(control,render_params);
+ PrintWriter wr = control.getWriter();
+ wr.write(" (" + m_min_value + " - " + m_max_value + ")");
+
+ } // end renderField
+
+ protected void validateContents(Request r, Object data) throws ValidationException
+ {
+ if (data==null)
+ return;
+ try
+ { // convert to an integer and chack against range
+ int x = Integer.parseInt(data.toString());
+ if ((m_min_value>Integer.MIN_VALUE) && (xm_max_value))
+ { // value is too large
+ ValidationException ve = new ValidationException(IntegerField.class,"DialogMessages","int.tooLarge");
+ ve.setParameter(0,getCaption());
+ ve.setParameter(1,String.valueOf(m_max_value));
+ throw ve;
+
+ } // end if
+
+ } // end try
+ catch (NumberFormatException e)
+ { // integer conversion failed - throw an error
+ ValidationException ve = new ValidationException(IntegerField.class,"DialogMessages","text.notInteger");
+ ve.setParameter(0,getCaption());
+ throw ve;
+
+ } // end catch
+
+ } // end validateContents
+
+ public Object getValue()
+ {
+ String s = (String)(super.getValue());
+ if (s==null)
+ return null;
+
+ try
+ { // map the return value to an Integer
+ return new Integer(s);
+
+ } // end try
+ catch (NumberFormatException e)
+ { // this is not supposed to happen
+ throw new IllegalStateException("IntegerField.getValue(): value is not an integer!");
+
+ } // end catch
+
+ } // end getValue
+
+ public boolean containsValue()
+ {
+ return (super.getValue()!=null);
+
+ } // end containsValue
+
+ public void setValue(Object obj)
+ {
+ if (obj==null)
+ { // deal with null values early
+ super.setValue(null);
+ return;
+
+ } // end if
+
+ int real_val;
+ if (obj instanceof Number)
+ real_val = ((Number)obj).intValue();
+ else
+ { // convert the value to a string, then to integer
+ try
+ { // perform the conversion
+ real_val = Integer.parseInt(obj.toString());
+
+ } // end try
+ catch (NumberFormatException e)
+ { // just use a sensible default
+ real_val = m_min_value;
+
+ } // end catch
+
+ } // end else
+
+ // Constrain the value.
+ if (real_valm_max_value)
+ real_val = m_max_value;
+
+ // Now actually set it.
+ super.setValue(String.valueOf(real_val));
+
+ } // end setValue
+
+ public void setValueFrom(Request r)
+ {
+ RequestHelper rh = new RequestHelper(r);
+ this.setValue(rh.getParameterString(getName()));
+
+ } // end setValueFrom
+
+} // end class IntegerField
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/LocaleListField.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/LocaleListField.java
new file mode 100644
index 0000000..181e5da
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/LocaleListField.java
@@ -0,0 +1,90 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.dialog;
+
+import java.util.*;
+import org.w3c.dom.Element;
+import com.silverwrist.util.*;
+import com.silverwrist.dynamo.except.DialogException;
+
+class LocaleListField extends PickListField
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ LocaleListField(Element elt) throws DialogException
+ {
+ super(elt);
+
+ } // end constructor
+
+ protected LocaleListField(LocaleListField other)
+ {
+ super(other);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Abstract implementations from class BaseDialogField
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object clone()
+ {
+ return new LocaleListField(this);
+
+ } // end clone
+
+ /*--------------------------------------------------------------------------------
+ * Abstract implementations from class PickListField
+ *--------------------------------------------------------------------------------
+ */
+
+ protected Iterator getChoices()
+ {
+ return Arrays.asList(Locale.getAvailableLocales()).iterator();
+
+ } // end getChoices
+
+ protected String getChoiceName(Object choice)
+ {
+ return choice.toString();
+
+ } // end getChoiceName
+
+ protected String getChoiceDisplay(Object choice)
+ {
+ return ((Locale)choice).getDisplayName();
+
+ } // end getChoiceDisplay
+
+ protected Object getChoiceForName(String name)
+ {
+ return International.get().createLocale(name);
+
+ } // end getChoiceForName
+
+ protected boolean isValidChoice(Object choice)
+ {
+ return (choice instanceof Locale);
+
+ } // end isValidChoice
+
+} // end class LocaleListField
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/PasswordField.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/PasswordField.java
new file mode 100644
index 0000000..0baae52
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/PasswordField.java
@@ -0,0 +1,58 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.dialog;
+
+import java.io.*;
+import org.w3c.dom.*;
+import com.silverwrist.util.*;
+import com.silverwrist.util.xml.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+public class PasswordField extends CommonTextField
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ public PasswordField(Element elt) throws DialogException
+ {
+ super("password",elt);
+
+ } // end constructor
+
+ protected PasswordField(PasswordField other)
+ {
+ super(other);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Abstract implementations from class BaseDialogField
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object clone()
+ {
+ return new PasswordField(this);
+
+ } // end clone
+
+} // end class PasswordField
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/PickListField.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/PickListField.java
new file mode 100644
index 0000000..85b00f7
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/PickListField.java
@@ -0,0 +1,137 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.dialog;
+
+import java.io.*;
+import java.util.*;
+import org.w3c.dom.*;
+import com.silverwrist.util.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+public abstract class PickListField extends BaseDialogField
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private Object m_value;
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ protected PickListField(Element elt) throws DialogException
+ {
+ super(false,elt);
+ m_value = null;
+
+ } // end constructor
+
+ protected PickListField(PickListField other)
+ {
+ super(other);
+ m_value = null;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Abstract operations
+ *--------------------------------------------------------------------------------
+ */
+
+ protected abstract Iterator getChoices();
+
+ protected abstract String getChoiceName(Object choice);
+
+ protected abstract String getChoiceDisplay(Object choice);
+
+ protected abstract Object getChoiceForName(String name);
+
+ protected abstract boolean isValidChoice(Object choice);
+
+ /*--------------------------------------------------------------------------------
+ * Abstract implementations from class BaseDialogField
+ *--------------------------------------------------------------------------------
+ */
+
+ protected void renderField(TextRenderControl control, Map render_params)
+ throws IOException, RenderingException
+ {
+ PrintWriter wr = control.getWriter();
+ wr.write("");
+
+ } // end renderField
+
+ protected void validateContents(Request r, Object data) throws ValidationException
+ { // don't need to validate the contents on a pick list
+ } // end validateContents
+
+ public Object getValue()
+ {
+ return m_value;
+
+ } // end getValue
+
+ public boolean containsValue()
+ {
+ return (m_value!=null);
+
+ } // end containsValue
+
+ public void setValue(Object obj)
+ {
+ if ((obj==null) || isValidChoice(obj))
+ m_value = obj;
+
+ } // end setValue
+
+ public void setValueFrom(Request r)
+ {
+ RequestHelper rh = new RequestHelper(r);
+ m_value = getChoiceForName(rh.getParameterString(getName()));
+
+ } // end setValueFrom
+
+ public void reset()
+ {
+ m_value = null;
+
+ } // return reset
+
+} // end class PickListField
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/StdButton.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/StdButton.java
new file mode 100644
index 0000000..0fe4a6d
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/StdButton.java
@@ -0,0 +1,118 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.dialog;
+
+import java.io.*;
+import java.util.*;
+import org.w3c.dom.*;
+import com.silverwrist.util.xml.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+
+class StdButton implements DialogButton
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private DialogPLAF m_plaf;
+ private String m_name;
+ private Object m_rendering;
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ StdButton(Element elt, DialogPLAF plaf) throws DialogException
+ {
+ m_plaf = plaf;
+ XMLLoader loader = XMLLoader.get();
+ try
+ { // get the name
+ m_name = loader.getAttribute(elt,"name");
+ m_rendering = plaf.getButtonRendering(m_name);
+
+ } // end try
+ catch (XMLLoadException e)
+ { // failed to load dialog - throw exception
+ throw new DialogException(e);
+
+ } // end catch
+
+ } // end constructor
+
+ protected StdButton(StdButton other)
+ {
+ m_plaf = other.m_plaf;
+ m_name = other.m_name;
+ m_rendering = other.m_rendering;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface NamedObject
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getName()
+ {
+ return m_name;
+
+ } // end getName
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface DialogItem
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object clone()
+ {
+ return new StdButton(this);
+
+ } // end clone
+
+ public void render(TextRenderControl control, Map render_params) throws IOException, RenderingException
+ {
+ control.renderSubObject(m_rendering);
+
+ } // end render
+
+ public boolean isEnabled()
+ {
+ return true;
+
+ } // end isEnabled
+
+ public void setEnabled(boolean flag)
+ { // do nothing
+ } // end setEnabled
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface DialogButton
+ *--------------------------------------------------------------------------------
+ */
+
+ public boolean isClicked(Request r)
+ {
+ return m_plaf.isButtonClicked(r,m_name);
+
+ } // end isClicked
+
+} // end class StdButton
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/StdItemFactory.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/StdItemFactory.java
new file mode 100644
index 0000000..1c6fffd
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/StdItemFactory.java
@@ -0,0 +1,80 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.dialog;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+
+class StdItemFactory implements DialogItemFactory
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static Logger logger = Logger.getLogger(StdItemFactory.class);
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ StdItemFactory()
+ { // do nothing
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface DialogItemFactory
+ *--------------------------------------------------------------------------------
+ */
+
+ public DialogItem createDialogItem(Element elt, DialogPLAF plaf) throws DialogException
+ {
+ String tagname = elt.getTagName();
+ if (tagname.equals("button"))
+ return new StdButton(elt,plaf);
+ if (tagname.equals("checkbox"))
+ return new CheckBoxField(elt);
+ if (tagname.equals("countrylist"))
+ return new CountryListField(elt);
+ if (tagname.equals("dynamo-id"))
+ return new DynamoIDField(elt);
+ if (tagname.equals("email"))
+ return new EmailAddressField(elt);
+ if (tagname.equals("header"))
+ return new HeaderItem(elt);
+ if (tagname.equals("hidden"))
+ return new HiddenField(elt);
+ if (tagname.equals("int"))
+ return new IntegerField(elt);
+ if (tagname.equals("localelist"))
+ return new LocaleListField(elt);
+ if (tagname.equals("password"))
+ return new PasswordField(elt);
+ if (tagname.equals("text"))
+ return new TextField(elt);
+ if (tagname.equals("tzlist"))
+ return new TimeZoneListField(elt);
+
+ throw new UnknownDialogFieldException(tagname,elt);
+
+ } // end createDialogItem
+
+} // end class StdItemFactory
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/TextField.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/TextField.java
new file mode 100644
index 0000000..cc4d246
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/TextField.java
@@ -0,0 +1,58 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.dialog;
+
+import java.io.*;
+import org.w3c.dom.*;
+import com.silverwrist.util.*;
+import com.silverwrist.util.xml.*;
+import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+public class TextField extends CommonTextField
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ public TextField(Element elt) throws DialogException
+ {
+ super("text",elt);
+
+ } // end constructor
+
+ protected TextField(TextField other)
+ {
+ super(other);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Abstract implementations from class BaseDialogField
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object clone()
+ {
+ return new TextField(this);
+
+ } // end clone
+
+} // end class TextField
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dialog/TimeZoneListField.java b/src/dynamo-framework/com/silverwrist/dynamo/dialog/TimeZoneListField.java
new file mode 100644
index 0000000..db90c63
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/dialog/TimeZoneListField.java
@@ -0,0 +1,116 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.dialog;
+
+import java.util.*;
+import org.w3c.dom.Element;
+import com.silverwrist.util.*;
+import com.silverwrist.dynamo.except.DialogException;
+
+class TimeZoneListField extends PickListField
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final List TZ_LIST;
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ TimeZoneListField(Element elt) throws DialogException
+ {
+ super(elt);
+
+ } // end constructor
+
+ protected TimeZoneListField(TimeZoneListField other)
+ {
+ super(other);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Abstract implementations from class BaseDialogField
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object clone()
+ {
+ return new TimeZoneListField(this);
+
+ } // end clone
+
+ /*--------------------------------------------------------------------------------
+ * Abstract implementations from class PickListField
+ *--------------------------------------------------------------------------------
+ */
+
+ protected Iterator getChoices()
+ {
+ return TZ_LIST.iterator();
+
+ } // end getChoices
+
+ protected String getChoiceName(Object choice)
+ {
+ return ((TimeZone)choice).getID();
+
+ } // end getChoiceName
+
+ protected String getChoiceDisplay(Object choice)
+ {
+ TimeZone tz = (TimeZone)choice;
+ return tz.getID() + " (" + tz.getDisplayName() + ")";
+
+ } // end getChoiceDisplay
+
+ protected Object getChoiceForName(String name)
+ {
+ return TimeZone.getTimeZone(name);
+
+ } // end getChoiceForName
+
+ protected boolean isValidChoice(Object choice)
+ {
+ return (choice instanceof TimeZone);
+
+ } // end isValidChoice
+
+ /*--------------------------------------------------------------------------------
+ * Static initializer
+ *--------------------------------------------------------------------------------
+ */
+
+ static
+ { // get the list of IDs and sort them
+ String ids[] = TimeZone.getAvailableIDs();
+ Arrays.sort(ids);
+
+ // now create the list of TimeZone objects
+ ArrayList tmp = new ArrayList(ids.length);
+ for (int i=0; i.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+public class ApplicationAdapter implements ApplicationListener
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public ApplicationAdapter()
+ { // do nothing
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ApplicationListener
+ *--------------------------------------------------------------------------------
+ */
+
+ public void applicationInitialized(ApplicationEvent event)
+ { // do nothing
+ } // end applicationInitialized
+
+ public void applicationExiting(ApplicationEvent event)
+ { // do nothing
+ } // end applicationExiting
+
+} // end class ApplicationAdapter
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/event/ApplicationEvent.java b/src/dynamo-framework/com/silverwrist/dynamo/event/ApplicationEvent.java
new file mode 100644
index 0000000..5f26622
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/event/ApplicationEvent.java
@@ -0,0 +1,71 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+import com.silverwrist.dynamo.iface.*;
+
+public class ApplicationEvent extends DynamoEventObject
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private transient Application m_app;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public ApplicationEvent(Request request, Application app)
+ {
+ super(request);
+ m_app = app;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class DynamoEventObject
+ *--------------------------------------------------------------------------------
+ */
+
+ public String toString()
+ {
+ return "ApplicationEvent: request = " + source + ", application = " + m_app;
+
+ } // end toString
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ public Request getRequest()
+ {
+ return (Request)getSource();
+
+ } // end getRequest
+
+ public Application getApplication()
+ {
+ return m_app;
+
+ } // end getApplication
+
+} // end class ApplicationEvent
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/event/ApplicationEventRequest.java b/src/dynamo-framework/com/silverwrist/dynamo/event/ApplicationEventRequest.java
new file mode 100644
index 0000000..4740032
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/event/ApplicationEventRequest.java
@@ -0,0 +1,189 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+import java.util.*;
+import com.silverwrist.dynamo.RequestType;
+import com.silverwrist.dynamo.Verb;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+public class ApplicationEventRequest extends BaseDelegatingServiceProvider implements Request
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final String EMPTY_STRING = "";
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private Verb m_verb;
+ private Locale[] m_locales;
+ private MemoryObjectStore m_attrs;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public ApplicationEventRequest(ServiceProvider services, boolean start)
+ {
+ super("ApplicationEventRequest",services);
+ m_verb = (start ? Verb.PUT : Verb.DELETE);
+ m_locales = new Locale[1];
+ m_locales[0] = Locale.getDefault();
+ m_attrs = new MemoryObjectStore(ApplicationEventRequest.class.getName());
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ObjectProvider
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Retrieves an object from this ObjectProvider.
+ *
+ * @param namespace The namespace to interpret the name relative to.
+ * @param name The name of the object to be retrieved.
+ * @return The object reference specified.
+ */
+ public Object getObject(String namespace, String name)
+ {
+ return m_attrs.getObject(namespace,name);
+
+ } // end getObject
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ObjectStore
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object setObject(String namespace, String name, Object value)
+ {
+ return m_attrs.setObject(namespace,name,value);
+
+ } // end setObject
+
+ public Object removeObject(String namespace, String name)
+ {
+ return m_attrs.removeObject(namespace,name);
+
+ } // end removeObject
+
+ public Collection getNamespaces()
+ {
+ return m_attrs.getNamespaces();
+
+ } // end getNamespaces
+
+ public Collection getNamesForNamespace(String namespace)
+ {
+ return m_attrs.getNamesForNamespace(namespace);
+
+ } // end getNamesForNamespace
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface Request
+ *--------------------------------------------------------------------------------
+ */
+
+ public RequestType getType()
+ {
+ return RequestType._APPLICATION;
+
+ } // end getType
+
+ public String getServerName()
+ {
+ return EMPTY_STRING;
+
+ } // end getEmptyString
+
+ public int getServerPort()
+ {
+ return -1;
+
+ } // end getServerPort
+
+ public String getContextPath()
+ {
+ return EMPTY_STRING;
+
+ } // end getContextPath
+
+ public String getRequestPath()
+ {
+ return EMPTY_STRING;
+
+ } // end getRequestPath
+
+ public String getExtraPath()
+ {
+ return EMPTY_STRING;
+
+ } // end getExtraPath
+
+ public String getQueryString()
+ {
+ return EMPTY_STRING;
+
+ } // end getQueryString
+
+ public Verb getVerb()
+ {
+ return m_verb;
+
+ } // end getVerb
+
+ public String getSourceAddress()
+ {
+ return "127.0.0.1";
+
+ } // end getSourceAddress
+
+ public Map getParameters()
+ {
+ return Collections.EMPTY_MAP;
+
+ } // end getParameters
+
+ public Class getParametersEntryClass()
+ {
+ return Object.class;
+
+ } // end getParametersEntryClass
+
+ public Map getDataItems()
+ {
+ return Collections.EMPTY_MAP;
+
+ } // end getDataItems
+
+ public Locale[] getLocales()
+ {
+ return m_locales;
+
+ } // end getLocales
+
+} // end class ApplicationEventRequest
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/event/ApplicationListener.java b/src/dynamo-framework/com/silverwrist/dynamo/event/ApplicationListener.java
new file mode 100644
index 0000000..39139a3
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/event/ApplicationListener.java
@@ -0,0 +1,26 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+public interface ApplicationListener extends DynamoEventListener
+{
+ public void applicationInitialized(ApplicationEvent event);
+
+ public void applicationExiting(ApplicationEvent event);
+
+} // end interface ApplicationListener
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/event/DynamicUpdateEvent.java b/src/dynamo-framework/com/silverwrist/dynamo/event/DynamicUpdateEvent.java
new file mode 100644
index 0000000..4d86e3c
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/event/DynamicUpdateEvent.java
@@ -0,0 +1,44 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+public class DynamicUpdateEvent extends DynamoEventObject
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public DynamicUpdateEvent(Object src)
+ {
+ super(src);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class DynamoEventObject
+ *--------------------------------------------------------------------------------
+ */
+
+ public String toString()
+ {
+ return "DynamicUpdateEvent: source = " + source;
+
+ } // end toString
+
+} // end class DynamicUpdateEvent
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/event/DynamicUpdateListener.java b/src/dynamo-framework/com/silverwrist/dynamo/event/DynamicUpdateListener.java
new file mode 100644
index 0000000..585ac7d
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/event/DynamicUpdateListener.java
@@ -0,0 +1,24 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+public interface DynamicUpdateListener extends DynamoEventListener
+{
+ public void updateReceived(DynamicUpdateEvent evt);
+
+} // end class DynamicUpdateListener
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/event/DynamoEventListener.java b/src/dynamo-framework/com/silverwrist/dynamo/event/DynamoEventListener.java
new file mode 100644
index 0000000..bf1ded5
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/event/DynamoEventListener.java
@@ -0,0 +1,32 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+import java.util.EventListener;
+
+/**
+ * The base interface for all Dynamo framework event listeners.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public interface DynamoEventListener extends EventListener
+{
+ // no methods
+
+} // end interface DynamoEventListener
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/event/DynamoEventObject.java b/src/dynamo-framework/com/silverwrist/dynamo/event/DynamoEventObject.java
new file mode 100644
index 0000000..44d2dfa
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/event/DynamoEventObject.java
@@ -0,0 +1,65 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+import java.util.EventObject;
+
+/**
+ * The root class from which all Dynamo event state objects are derived.
+ *
All events are constructed with a reference to the object, the "source", that is logically deemed
+ * to be the object upon which the event in question initially occurred upon.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public class DynamoEventObject extends EventObject
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a new DynamoEventObject.
+ *
+ * @param src The object on which the event initially occurred.
+ */
+ public DynamoEventObject(Object src)
+ {
+ super(src);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class EventObject
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Returns a string representation of the object. In general, the toString method returns a string
+ * that "textually represents" this object.
+ *
+ * @return A string representation of the object.
+ */
+ public String toString()
+ {
+ return "DynamoEventObject: source = " + source;
+
+ } // end toString
+
+} // end class DynamoEventObject
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/event/GlobalBlockUpdateEvent.java b/src/dynamo-framework/com/silverwrist/dynamo/event/GlobalBlockUpdateEvent.java
new file mode 100644
index 0000000..fae7c11
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/event/GlobalBlockUpdateEvent.java
@@ -0,0 +1,72 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+public class GlobalBlockUpdateEvent extends GlobalUpdateEvent
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private transient String m_namespace;
+ private transient String m_name;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public GlobalBlockUpdateEvent(Object src, String namespace, String name)
+ {
+ super(src);
+ m_namespace = namespace;
+ m_name = name;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class GlobalUpdateEvent
+ *--------------------------------------------------------------------------------
+ */
+
+ public String toString()
+ {
+ return "GlobalBlockUpdateEvent: source = " + source + ", namespace = " + m_namespace
+ + ", name = " + m_name;
+
+ } // end toString
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getBlockNamespace()
+ {
+ return m_namespace;
+
+ } // end getPropertyNamespace
+
+ public String getBlockName()
+ {
+ return m_name;
+
+ } // end getPropertyName
+
+} // end class GlobalBlockUpdateEvent
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/event/GlobalPropertyUpdateEvent.java b/src/dynamo-framework/com/silverwrist/dynamo/event/GlobalPropertyUpdateEvent.java
new file mode 100644
index 0000000..2aaadc0
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/event/GlobalPropertyUpdateEvent.java
@@ -0,0 +1,72 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+public class GlobalPropertyUpdateEvent extends GlobalUpdateEvent
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private transient String m_namespace;
+ private transient String m_name;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public GlobalPropertyUpdateEvent(Object src, String namespace, String name)
+ {
+ super(src);
+ m_namespace = namespace;
+ m_name = name;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class GlobalUpdateEvent
+ *--------------------------------------------------------------------------------
+ */
+
+ public String toString()
+ {
+ return "GlobalPropertyUpdateEvent: source = " + source + ", namespace = " + m_namespace
+ + ", name = " + m_name;
+
+ } // end toString
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getPropertyNamespace()
+ {
+ return m_namespace;
+
+ } // end getPropertyNamespace
+
+ public String getPropertyName()
+ {
+ return m_name;
+
+ } // end getPropertyName
+
+} // end class GlobalPropertyUpdateEvent
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/event/GlobalUpdateEvent.java b/src/dynamo-framework/com/silverwrist/dynamo/event/GlobalUpdateEvent.java
new file mode 100644
index 0000000..1b201c7
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/event/GlobalUpdateEvent.java
@@ -0,0 +1,44 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+public class GlobalUpdateEvent extends DynamicUpdateEvent
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public GlobalUpdateEvent(Object src)
+ {
+ super(src);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class DynamicUpdateEvent
+ *--------------------------------------------------------------------------------
+ */
+
+ public String toString()
+ {
+ return "GlobalUpdateEvent: source = " + source;
+
+ } // end toString
+
+} // end class GlobalUpdateEvent
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/event/ScriptEngineStartEvent.java b/src/dynamo-framework/com/silverwrist/dynamo/event/ScriptEngineStartEvent.java
new file mode 100644
index 0000000..17a4f5f
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/event/ScriptEngineStartEvent.java
@@ -0,0 +1,72 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+import com.silverwrist.dynamo.iface.Request;
+import com.silverwrist.dynamo.iface.ScriptEngineRegisterObject;
+
+public class ScriptEngineStartEvent extends DynamoEventObject
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private transient ScriptEngineRegisterObject m_registrar;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public ScriptEngineStartEvent(Request request, ScriptEngineRegisterObject registrar)
+ {
+ super(request);
+ m_registrar = registrar;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class DynamoEventObject
+ *--------------------------------------------------------------------------------
+ */
+
+ public String toString()
+ {
+ return "ScriptEngineStartEvent: request = " + source + ", registrar = " + m_registrar;
+
+ } // end toString
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ public Request getRequest()
+ {
+ return (Request)getSource();
+
+ } // end getRequest
+
+ public ScriptEngineRegisterObject getRegistrar()
+ {
+ return m_registrar;
+
+ } // end getRegistrar
+
+} // end class ScriptEngineStartEvent
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/event/ScriptEngineStartListener.java b/src/dynamo-framework/com/silverwrist/dynamo/event/ScriptEngineStartListener.java
new file mode 100644
index 0000000..febf1ab
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/event/ScriptEngineStartListener.java
@@ -0,0 +1,24 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+public interface ScriptEngineStartListener extends DynamoEventListener
+{
+ public void scriptEngineStarting(ScriptEngineStartEvent event);
+
+} // end interface ScriptEngineStartListener
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/event/SessionEventRequest.java b/src/dynamo-framework/com/silverwrist/dynamo/event/SessionEventRequest.java
new file mode 100644
index 0000000..0a1b127
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/event/SessionEventRequest.java
@@ -0,0 +1,240 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+import java.util.*;
+import com.silverwrist.dynamo.RequestType;
+import com.silverwrist.dynamo.Verb;
+import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
+
+public class SessionEventRequest extends BaseDelegatingServiceProvider implements Request
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final String EMPTY_STRING = "";
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private DefaultSessionInfoProvider m_session;
+ private Verb m_verb;
+ private Locale[] m_locales;
+ private MemoryObjectStore m_attrs;
+ private Request m_request;
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ public SessionEventRequest(ServiceProvider services, SessionInfo session, boolean start)
+ {
+ super("SessionEventRequest",services);
+ m_session = new DefaultSessionInfoProvider(session);
+ m_verb = (start ? Verb.PUT : Verb.DELETE);
+ m_locales = new Locale[1];
+ m_locales[0] = Locale.getDefault();
+ m_attrs = new MemoryObjectStore(SessionEventRequest.class.getName());
+ m_request = null;
+
+ } // end constructor
+
+ public SessionEventRequest(SessionInfo session, boolean start, Request request)
+ {
+ super("SessionEventRequest",request);
+ m_session = null;
+ m_verb = (start ? Verb.PUT : Verb.DELETE);
+ m_locales = null;
+ m_attrs = new MemoryObjectStore(SessionEventRequest.class.getName());
+ m_request = request;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class BaseDelegatingServiceProvider
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Queries this object for a specified service.
+ *
+ * @param klass The class of the object that should be returned as a service.
+ * @return A service object. The service object is guaranteed to be of the class
+ * specified by klass; that is, if queryService(klass)
+ * yields some object x, then the expression klass.isInstance(x)
+ * is true.
+ * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in
+ * the specified class.
+ */
+ public Object queryService(Class klass)
+ {
+ if ((m_session!=null) && (klass==SessionInfoProvider.class))
+ return m_session;
+ return super.queryService(klass);
+
+ } // end queryService
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ObjectProvider
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Retrieves an object from this ObjectProvider.
+ *
+ * @param namespace The namespace to interpret the name relative to.
+ * @param name The name of the object to be retrieved.
+ * @return The object reference specified.
+ */
+ public Object getObject(String namespace, String name)
+ {
+ return m_attrs.getObject(namespace,name);
+
+ } // end getObject
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ObjectStore
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object setObject(String namespace, String name, Object value)
+ {
+ return m_attrs.setObject(namespace,name,value);
+
+ } // end setObject
+
+ public Object removeObject(String namespace, String name)
+ {
+ return m_attrs.removeObject(namespace,name);
+
+ } // end removeObject
+
+ public Collection getNamespaces()
+ {
+ return m_attrs.getNamespaces();
+
+ } // end getNamespaces
+
+ public Collection getNamesForNamespace(String namespace)
+ {
+ return m_attrs.getNamesForNamespace(namespace);
+
+ } // end getNamesForNamespace
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface Request
+ *--------------------------------------------------------------------------------
+ */
+
+ public RequestType getType()
+ {
+ return RequestType._SESSION;
+
+ } // end getType
+
+ public String getServerName()
+ {
+ if (m_request!=null)
+ return m_request.getServerName();
+ else
+ return EMPTY_STRING;
+
+ } // end getEmptyString
+
+ public int getServerPort()
+ {
+ if (m_request!=null)
+ return m_request.getServerPort();
+ else
+ return -1;
+
+ } // end getServerPort
+
+ public String getContextPath()
+ {
+ return EMPTY_STRING;
+
+ } // end getContextPath
+
+ public String getRequestPath()
+ {
+ return EMPTY_STRING;
+
+ } // end getRequestPath
+
+ public String getExtraPath()
+ {
+ return EMPTY_STRING;
+
+ } // end getExtraPath
+
+ public String getQueryString()
+ {
+ return EMPTY_STRING;
+
+ } // end getQueryString
+
+ public Verb getVerb()
+ {
+ return m_verb;
+
+ } // end getVerb
+
+ public String getSourceAddress()
+ {
+ if (m_request!=null)
+ return m_request.getSourceAddress();
+ else
+ return "127.0.0.1";
+
+ } // end getSourceAddress
+
+ public Map getParameters()
+ {
+ return Collections.EMPTY_MAP;
+
+ } // end getParameters
+
+ public Class getParametersEntryClass()
+ {
+ return Object.class;
+
+ } // end getParametersEntryClass
+
+ public Map getDataItems()
+ {
+ return Collections.EMPTY_MAP;
+
+ } // end getDataItems
+
+ public Locale[] getLocales()
+ {
+ if (m_request!=null)
+ return m_request.getLocales();
+ else
+ return m_locales;
+
+ } // end getLocales
+
+} // end class SessionEventRequest
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/event/SessionInfoAdapter.java b/src/dynamo-framework/com/silverwrist/dynamo/event/SessionInfoAdapter.java
new file mode 100644
index 0000000..36b579d
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/event/SessionInfoAdapter.java
@@ -0,0 +1,44 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+public class SessionInfoAdapter implements SessionInfoListener
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public SessionInfoAdapter()
+ { // do nothing
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface SessionInfoListener
+ *--------------------------------------------------------------------------------
+ */
+
+ public void sessionInitialized(SessionInfoEvent event)
+ { // do nothing
+ } // end sessionInitialized
+
+ public void sessionExiting(SessionInfoEvent event)
+ { // do nothing
+ } // end sessionExiting
+
+} // end class SessionInfoAdapter
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/event/SessionInfoEvent.java b/src/dynamo-framework/com/silverwrist/dynamo/event/SessionInfoEvent.java
new file mode 100644
index 0000000..2826228
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/event/SessionInfoEvent.java
@@ -0,0 +1,71 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+import com.silverwrist.dynamo.iface.*;
+
+public class SessionInfoEvent extends DynamoEventObject
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private transient SessionInfo m_session;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public SessionInfoEvent(Request request, SessionInfo session)
+ {
+ super(request);
+ m_session = session;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class DynamoEventObject
+ *--------------------------------------------------------------------------------
+ */
+
+ public String toString()
+ {
+ return "SessionInfoEvent: request = " + source + ", session = " + m_session;
+
+ } // end toString
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ public Request getRequest()
+ {
+ return (Request)getSource();
+
+ } // end getRequest
+
+ public SessionInfo getSession()
+ {
+ return m_session;
+
+ } // end getSession
+
+} // end class SessionInfoEvent
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/event/SessionInfoListener.java b/src/dynamo-framework/com/silverwrist/dynamo/event/SessionInfoListener.java
new file mode 100644
index 0000000..0ea9926
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/event/SessionInfoListener.java
@@ -0,0 +1,26 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+public interface SessionInfoListener extends DynamoEventListener
+{
+ public void sessionInitialized(SessionInfoEvent event);
+
+ public void sessionExiting(SessionInfoEvent event);
+
+} // end interface SessionInfoListener
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/event/SessionValueBindEvent.java b/src/dynamo-framework/com/silverwrist/dynamo/event/SessionValueBindEvent.java
new file mode 100644
index 0000000..a97f934
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/event/SessionValueBindEvent.java
@@ -0,0 +1,152 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+import com.silverwrist.dynamo.iface.*;
+
+/**
+ * Events of this type are sent to an object that implements
+ * {@link com.silverwrist.dynamo.event.SessionValueBindListener SessionValueBindListener} when it is bound
+ * or unbound from a {@link com.silverwrist.dynamo.iface.SessionInfo SessionInfo} object.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public class SessionValueBindEvent extends DynamoEventObject
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private transient String m_namespace; // namespace for this value
+ private transient String m_name; // name for this value
+ private transient Object m_value; // value for event
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a new instance of SessionValueBindEvent.
+ *
+ * @param session The {@link com.silverwrist.dynamo.iface.SessionInfo SessionInfo} associated with the event.
+ * @param namespace The namespace URI associated with the object.
+ * @param name The name associated with the object.
+ */
+ public SessionValueBindEvent(SessionInfo session, String namespace, String name)
+ {
+ super(session);
+ m_namespace = namespace;
+ m_name = name;
+ m_value = null;
+
+ } // end consructor
+
+ /**
+ * Constructs a new instance of SessionValueBindEvent.
+ *
+ * @param session The {@link com.silverwrist.dynamo.iface.SessionInfo SessionInfo} associated with the event.
+ * @param namespace The namespace URI associated with the object.
+ * @param name The name associated with the object.
+ * @param value The object value associated with the event.
+ */
+ public SessionValueBindEvent(SessionInfo session, String namespace, String name, Object value)
+ {
+ super(session);
+ m_namespace = namespace;
+ m_name = name;
+ m_value = value;
+
+ } // end consructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class DynamoEventObject
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Returns a string representation of the object. In general, the toString method returns a string
+ * that "textually represents" this object.
+ *
+ * @return A string representation of the object.
+ */
+ public String toString()
+ {
+ return "SessionValueBindEvent: session = " + source + ", namespace = " + m_namespace + ", name = "
+ + m_name + ", value = " + m_value;
+
+ } // end toString
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Returns the {@link com.silverwrist.dynamo.iface.SessionInfo SessionInfo} associated with this event.
+ *
+ * @return The SessionInfo associated with this event.
+ */
+ public SessionInfo getSession()
+ {
+ return (SessionInfo)getSource();
+
+ } // end getSession
+
+ /**
+ * Returns the namespace URI that the value is/was stored under.
+ *
+ * @return The namespace URI that the value is/was stored under.
+ */
+ public String getNamespace()
+ {
+ return m_namespace;
+
+ } // end getNamespace
+
+ /**
+ * Returns the name that the value is/was stored under.
+ *
+ * @return The name that the value is/was stored under.
+ */
+ public String getName()
+ {
+ return m_name;
+
+ } // end getName
+
+ /**
+ * Returns the value associated with the event. For
+ * {@link com.silverwrist.dynamo.event.SessionValueBindListener#valueAdded(com.silverwrist.dynamo.event.SessionValueBindEvent) valueAdded()}
+ * events, this value is the target value itself. For
+ * {@link com.silverwrist.dynamo.event.SessionValueBindListener#valueReplaced(com.silverwrist.dynamo.event.SessionValueBindEvent) valueReplaced()}
+ * events, this value is the value that the target value was replaced with in the session. For
+ * {@link com.silverwrist.dynamo.event.SessionValueBindListener#valueRemoved(com.silverwrist.dynamo.event.SessionValueBindEvent) valueRemoved()}
+ * events, this value is null.
+ *
+ * @return The value associated with the event.
+ */
+ public Object getValue()
+ {
+ return m_value;
+
+ } // end getValue
+
+} // end class SessionValueBindEvent
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/event/SessionValueBindListener.java b/src/dynamo-framework/com/silverwrist/dynamo/event/SessionValueBindListener.java
new file mode 100644
index 0000000..6db62cb
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/event/SessionValueBindListener.java
@@ -0,0 +1,59 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+/**
+ * An interface for signalling when a value is bound to or unbound from a
+ * {@link com.silverwrist.dynamo.iface.SessionInfo SessionInfo} object. If an object implementing this interface
+ * is added to or removed from a SessionInfo, the methods on this interface are called to
+ * reflect the lifecycle of the object.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public interface SessionValueBindListener extends DynamoEventListener
+{
+ /**
+ * Called when this value is added to a {@link com.silverwrist.dynamo.iface.SessionInfo SessionInfo} object.
+ *
+ * @param event The event object for this event. The
+ * {@link com.silverwrist.dynamo.event.SessionValueBindEvent#getValue() getValue()} method of
+ * this event returns this value.
+ */
+ public void valueAdded(SessionValueBindEvent event);
+
+ /**
+ * Called when this value is removed from a {@link com.silverwrist.dynamo.iface.SessionInfo SessionInfo} object.
+ *
+ * @param event The event object for this event. The
+ * {@link com.silverwrist.dynamo.event.SessionValueBindEvent#getValue() getValue()} method of
+ * this event returns null.
+ */
+ public void valueRemoved(SessionValueBindEvent event);
+
+ /**
+ * Called when a new value is added to a {@link com.silverwrist.dynamo.iface.SessionInfo SessionInfo} object,
+ * replacing this value.
+ *
+ * @param event The event object for this event. The
+ * {@link com.silverwrist.dynamo.event.SessionValueBindEvent#getValue() getValue()} method of
+ * this event returns the value of the object that replaced this one.
+ */
+ public void valueReplaced(SessionValueBindEvent event);
+
+} // end interface SessionValueBindListener
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/event/UserPropertyUpdateEvent.java b/src/dynamo-framework/com/silverwrist/dynamo/event/UserPropertyUpdateEvent.java
new file mode 100644
index 0000000..4d28fba
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/event/UserPropertyUpdateEvent.java
@@ -0,0 +1,72 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+public class UserPropertyUpdateEvent extends UserUpdateEvent
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private transient String m_namespace;
+ private transient String m_name;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public UserPropertyUpdateEvent(Object src, int uid, String namespace, String name)
+ {
+ super(src,uid);
+ m_namespace = namespace;
+ m_name = name;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class UserUpdateEvent
+ *--------------------------------------------------------------------------------
+ */
+
+ public String toString()
+ {
+ return "UserPropertyUpdateEvent: source = " + source + ", uid = " + m_uid + ", namespace = " + m_namespace
+ + ", name = " + m_name;
+
+ } // end toString
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getPropertyNamespace()
+ {
+ return m_namespace;
+
+ } // end getPropertyNamespace
+
+ public String getPropertyName()
+ {
+ return m_name;
+
+ } // end getPropertyName
+
+} // end class UserPropertyUpdateEvent
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/event/UserUpdateEvent.java b/src/dynamo-framework/com/silverwrist/dynamo/event/UserUpdateEvent.java
new file mode 100644
index 0000000..7c4ff6a
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/event/UserUpdateEvent.java
@@ -0,0 +1,63 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.event;
+
+public class UserUpdateEvent extends DynamicUpdateEvent
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ protected transient int m_uid;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public UserUpdateEvent(Object src, int uid)
+ {
+ super(src);
+ m_uid = uid;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class DynamicUpdateEvent
+ *--------------------------------------------------------------------------------
+ */
+
+ public String toString()
+ {
+ return "UserUpdateEvent: source = " + source + ", uid = " + m_uid;
+
+ } // end toString
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ public int getUID()
+ {
+ return m_uid;
+
+ } // end getUID
+
+} // end class UserUpdateEvent
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/AuthenticationException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/AuthenticationException.java
new file mode 100644
index 0000000..8054595
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/AuthenticationException.java
@@ -0,0 +1,39 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+public class AuthenticationException extends ExternalException
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ public AuthenticationException(Class caller, String bundle, String message_id)
+ {
+ super(caller,bundle,message_id);
+
+ } // end constructor
+
+ public AuthenticationException(Class caller, String bundle, String message_id, Throwable inner)
+ {
+ super(caller,bundle,message_id,inner);
+
+ } // end constructor
+
+} // end class AuthenticationException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/CallFailureException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/CallFailureException.java
new file mode 100644
index 0000000..270b3ca
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/CallFailureException.java
@@ -0,0 +1,104 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import com.silverwrist.dynamo.iface.DynamicClass;
+
+public class CallFailureException extends DynamicObjectException
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final String BUNDLE = "com.silverwrist.dynamo.except.DynamoExceptionMessages";
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private Object[] m_args;
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ public CallFailureException(DynamicClass klass, Throwable cause)
+ {
+ super("call to dynamic class " + klass.getName() + " failed with " + cause.getClass().getName(),cause);
+ m_args = new Object[2];
+ m_args[0] = klass.getName();
+ m_args[1] = cause.getClass().getName();
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class Throwable
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getMessage().
+ *
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage()
+ {
+ return this.getLocalizedMessage(Locale.getDefault());
+
+ } // end getLocalizedMessage
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class DynamoRuntimeException
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getLocalizedMessage().
+ *
+ * @param locale The locale to render the message in.
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage(Locale locale)
+ {
+ ResourceBundle b = ResourceBundle.getBundle(BUNDLE,locale,getClass().getClassLoader());
+ return MessageFormat.format(b.getString("callFailure"),m_args);
+
+ } // end getLocalizedMessage
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ public Throwable getTargetException()
+ {
+ return getCause();
+
+ } // end getTargetException
+
+} // end class CallFailureException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/CodeNotFoundException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/CodeNotFoundException.java
new file mode 100644
index 0000000..edf0fde
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/CodeNotFoundException.java
@@ -0,0 +1,122 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import com.silverwrist.dynamo.iface.DynamicClass;
+
+public class CodeNotFoundException extends DynamicObjectException
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final String BUNDLE = "com.silverwrist.dynamo.except.DynamoExceptionMessages";
+
+ public static final int CALL = 0;
+ public static final int GET = 1;
+ public static final int SET = 2;
+ public static final int PROPERTY = 3;
+
+ private static final String[] s_messages =
+ { "codeNotFound.call", "codeNotFound.get", "codeNotFound.set", "codeNotFound.prop" };
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private String m_message_id;
+ private Object[] m_args;
+ private String m_message = null;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public CodeNotFoundException(DynamicClass klass, int selector, String name)
+ {
+ super("");
+ m_message_id = s_messages[selector];
+ m_args = new Object[2];
+ m_args[0] = klass.getName();
+ m_args[1] = name;
+
+ } // end constructor
+
+ public CodeNotFoundException(DynamicClass klass, int selector, String name, Throwable inner)
+ {
+ super("",inner);
+ m_message_id = s_messages[selector];
+ m_args = new Object[2];
+ m_args[0] = klass.getName();
+ m_args[1] = name;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class Throwable
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getMessage()
+ {
+ if (m_message==null)
+ m_message = getLocalizedMessage(Locale.US);
+ return m_message;
+
+ } // end getMessage
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getMessage().
+ *
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage()
+ {
+ return this.getLocalizedMessage(Locale.getDefault());
+
+ } // end getLocalizedMessage
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class DynamoRuntimeException
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getLocalizedMessage().
+ *
+ * @param locale The locale to render the message in.
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage(Locale locale)
+ {
+ ResourceBundle b = ResourceBundle.getBundle(BUNDLE,locale,getClass().getClassLoader());
+ return MessageFormat.format(b.getString(m_message_id),m_args);
+
+ } // end getLocalizedMessage
+
+} // end class CodeNotFoundException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/ConfigException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/ConfigException.java
new file mode 100644
index 0000000..7c4a450
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/ConfigException.java
@@ -0,0 +1,91 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+import java.text.MessageFormat;
+import java.util.*;
+import org.w3c.dom.*;
+import com.silverwrist.util.xml.XMLLoadException;
+
+public class ConfigException extends ExternalException
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private Node m_locus = null; // locus in configuration of exception
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ public ConfigException(XMLLoadException xle)
+ {
+ super(ConfigException.class,"DynamoExceptionMessages","configException.xmlLoadException",xle);
+ setParameter(0,xle.getMessage());
+ m_locus = xle.getLocus();
+
+ } // end constructor
+
+ public ConfigException(ModuleException me)
+ {
+ super(ConfigException.class,"DynamoExceptionMessages","configException.moduleException",me);
+ setParameter(0,me.getMessage());
+
+ } // end constructor
+
+ public ConfigException(Class caller, String bundle, String message_id)
+ {
+ super(caller,bundle,message_id);
+
+ } // end constructor
+
+ public ConfigException(Class caller, String bundle, String message_id, Throwable inner)
+ {
+ super(caller,bundle,message_id,inner);
+
+ } // end constructor
+
+ public ConfigException(Class caller, String bundle, String message_id, Node locus)
+ {
+ super(caller,bundle,message_id);
+ m_locus = locus;
+
+ } // end constructor
+
+ public ConfigException(Class caller, String bundle, String message_id, Throwable inner, Node locus)
+ {
+ super(caller,bundle,message_id,inner);
+ m_locus = locus;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ public Node getLocus()
+ {
+ return m_locus;
+
+ } // end getLocus
+
+} // end class ConfigException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/DatabaseException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/DatabaseException.java
new file mode 100644
index 0000000..89b4629
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/DatabaseException.java
@@ -0,0 +1,65 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+/**
+ * An exception thrown indicating a problem with the database. This commonly wraps a
+ * java.sql.SQLException, but may also indicate a problem with a connection pool or such.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public class DatabaseException extends ExternalException
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a new DatabaseException instance.
+ *
+ * @param caller The classname of the class that's creating the exception. Its class loader
+ * and package name will be used, together with bundle, to find the
+ * resource bundle.
+ * @param bundle The name of the resource bundle to be loaded.
+ * @param message_id The identifier of the message to be loaded from the bundle.
+ */
+ public DatabaseException(Class caller, String bundle, String message_id)
+ {
+ super(caller,bundle,message_id);
+
+ } // end constructor
+
+ /**
+ * Constructs a new DatabaseException instance.
+ *
+ * @param caller The classname of the class that's creating the exception. Its class loader
+ * and package name will be used, together with bundle, to find the
+ * resource bundle.
+ * @param bundle The name of the resource bundle to be loaded.
+ * @param message_id The identifier of the message to be loaded from the bundle.
+ * @param inner The exception to be nested inside this one.
+ */
+ public DatabaseException(Class caller, String bundle, String message_id, Throwable inner)
+ {
+ super(caller,bundle,message_id,inner);
+
+ } // end constructor
+
+} // end class DatabaseException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/DialogException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/DialogException.java
new file mode 100644
index 0000000..b10f27f
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/DialogException.java
@@ -0,0 +1,84 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+import java.text.MessageFormat;
+import java.util.*;
+import org.w3c.dom.*;
+import com.silverwrist.util.xml.XMLLoadException;
+
+public class DialogException extends ExternalException
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private Node m_locus = null; // locus in configuration of exception
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ public DialogException(XMLLoadException xle)
+ {
+ super(DialogException.class,"DynamoExceptionMessages","dialogException.xmlLoadException",xle);
+ setParameter(0,xle.getMessage());
+ m_locus = xle.getLocus();
+
+ } // end constructor
+
+ public DialogException(Class caller, String bundle, String message_id)
+ {
+ super(caller,bundle,message_id);
+
+ } // end constructor
+
+ public DialogException(Class caller, String bundle, String message_id, Throwable inner)
+ {
+ super(caller,bundle,message_id,inner);
+
+ } // end constructor
+
+ public DialogException(Class caller, String bundle, String message_id, Node locus)
+ {
+ super(caller,bundle,message_id);
+ m_locus = locus;
+
+ } // end constructor
+
+ public DialogException(Class caller, String bundle, String message_id, Throwable inner, Node locus)
+ {
+ super(caller,bundle,message_id,inner);
+ m_locus = locus;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ public Node getLocus()
+ {
+ return m_locus;
+
+ } // end getLocus
+
+} // end class DialogException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/DynamicObjectException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/DynamicObjectException.java
new file mode 100644
index 0000000..3b7d8e1
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/DynamicObjectException.java
@@ -0,0 +1,70 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+public class DynamicObjectException extends DynamoException
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a new DynamicObjectException.
+ */
+ public DynamicObjectException()
+ {
+ super();
+
+ } // end constructor
+
+ /**
+ * Constructs a new DynamicObjectException with a text message.
+ *
+ * @param msg The message to set in this exception.
+ */
+ public DynamicObjectException(String msg)
+ {
+ super(msg);
+
+ } // end constructor
+
+ /**
+ * Constructs a new DynamicObjectException wrapping another exception.
+ *
+ * @param inner The exception wrapped by this one.
+ */
+ public DynamicObjectException(Throwable inner)
+ {
+ super(inner);
+
+ } // end constructor
+
+ /**
+ * Constructs a new DynamicObjectException wrapping another exception.
+ *
+ * @param msg The message to set in this exception.
+ * @param inner The exception wrapped by this one.
+ */
+ public DynamicObjectException(String msg, Throwable inner)
+ {
+ super(msg,inner);
+
+ } // end constructor
+
+} // end class DynamicObjectException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/DynamicObjectRuntimeException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/DynamicObjectRuntimeException.java
new file mode 100644
index 0000000..f794f49
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/DynamicObjectRuntimeException.java
@@ -0,0 +1,70 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+public class DynamicObjectRuntimeException extends DynamoRuntimeException
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a new DynamicObjectRuntimeException.
+ */
+ public DynamicObjectRuntimeException()
+ {
+ super();
+
+ } // end constructor
+
+ /**
+ * Constructs a new DynamicObjectRuntimeException with a text message.
+ *
+ * @param msg The message to set in this exception.
+ */
+ public DynamicObjectRuntimeException(String msg)
+ {
+ super(msg);
+
+ } // end constructor
+
+ /**
+ * Constructs a new DynamicObjectRuntimeException wrapping another exception.
+ *
+ * @param inner The exception wrapped by this one.
+ */
+ public DynamicObjectRuntimeException(Throwable inner)
+ {
+ super(inner);
+
+ } // end constructor
+
+ /**
+ * Constructs a new DynamicObjectRuntimeException wrapping another exception.
+ *
+ * @param msg The message to set in this exception.
+ * @param inner The exception wrapped by this one.
+ */
+ public DynamicObjectRuntimeException(String msg, Throwable inner)
+ {
+ super(msg,inner);
+
+ } // end constructor
+
+} // end class DynamicObjectRuntimeException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/DynamoException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/DynamoException.java
new file mode 100644
index 0000000..6b8597f
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/DynamoException.java
@@ -0,0 +1,98 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+import java.util.Locale;
+
+/**
+ * The root exception of all checked exceptions thrown by the Dynamo core code. It is capable of
+ * "wrapping" another exception within it.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public class DynamoException extends Exception
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a new DynamoException.
+ */
+ public DynamoException()
+ {
+ super();
+
+ } // end constructor
+
+ /**
+ * Constructs a new DynamoException with a text message.
+ *
+ * @param msg The message to set in this exception.
+ */
+ public DynamoException(String msg)
+ {
+ super(msg);
+
+ } // end constructor
+
+ /**
+ * Constructs a new DynamoException wrapping another exception.
+ *
+ * @param inner The exception wrapped by this one.
+ */
+ public DynamoException(Throwable inner)
+ {
+ super(inner);
+
+ } // end constructor
+
+ /**
+ * Constructs a new DynamoException wrapping another exception.
+ *
+ * @param msg The message to set in this exception.
+ * @param inner The exception wrapped by this one.
+ */
+ public DynamoException(String msg, Throwable inner)
+ {
+ super(msg,inner);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getLocalizedMessage().
+ *
+ * @param locale The locale to render the message in.
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage(Locale locale)
+ {
+ return getMessage();
+
+ } // end getLocalizedMessage
+
+} // end class DynamoException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/DynamoExceptionMessages.properties b/src/dynamo-framework/com/silverwrist/dynamo/except/DynamoExceptionMessages.properties
new file mode 100644
index 0000000..dca6589
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/DynamoExceptionMessages.properties
@@ -0,0 +1,33 @@
+# The contents of this file are subject to the Mozilla Public License Version 1.1
+# (the "License"); you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at .
+#
+# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+# WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+# language governing rights and limitations under the License.
+#
+# The Original Code is the Venice Web Communities System.
+#
+# The Initial Developer of the Original Code is Eric J. Bowersox ,
+# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+# Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+#
+# Contributor(s):
+# ---------------------------------------------------------------------------------
+# This file has been localized for the en_US locale
+noSuchServiceException.1={0}: no service with class {1}
+noSuchServiceException.2={0}: no service with class {1} and ID {2}
+noSuchObjectException={0}: no such object {2} in namespace {1}
+noSuchResourceException=Resource not found: {0}
+configException.xmlLoadException=Error in XML configuration: {0}
+configException.moduleException=Error loading module at startup: {0}
+requestParseException.msg=Error parsing request: {0}
+codeNotFound.call=Method {0} not found in dynamic class {1}
+codeNotFound.get=Getter for property {0} not found in dynamic class {1}
+codeNotFound.set=Setter for property {0} not found in dynamic class {1}
+codeNotFound.prop=Property {0} not found in dynamic class {1}
+callFailure=Call to dynamic class {0} failed with {1}
+scriptingException=Error executing {0}[{1}]: {2}
+renderClass.creation=Unable to create object of class {0} at rendering time.
+dialogException.xmlLoadException=Error in XML dialog definition: {0}
+udfe.bad.itemType=No implementation exists for dialog item type "{0}".
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/DynamoRuntimeException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/DynamoRuntimeException.java
new file mode 100644
index 0000000..e7eb1a1
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/DynamoRuntimeException.java
@@ -0,0 +1,98 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+import java.util.Locale;
+
+/**
+ * The root exception of all unchecked exceptions thrown by the Dynamo core code. It is capable of
+ * "wrapping" another exception within it.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public class DynamoRuntimeException extends RuntimeException
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a new DynamoRuntimeException.
+ */
+ public DynamoRuntimeException()
+ {
+ super();
+
+ } // end constructor
+
+ /**
+ * Constructs a new DynamoRuntimeException with a text message.
+ *
+ * @param msg The message to set in this exception.
+ */
+ public DynamoRuntimeException(String msg)
+ {
+ super(msg);
+
+ } // end constructor
+
+ /**
+ * Constructs a new DynamoRuntimeException wrapping another exception.
+ *
+ * @param inner The exception wrapped by this one.
+ */
+ public DynamoRuntimeException(Throwable inner)
+ {
+ super(inner);
+
+ } // end constructor
+
+ /**
+ * Constructs a new DynamoRuntimeException wrapping another exception.
+ *
+ * @param msg The message to set in this exception.
+ * @param inner The exception wrapped by this one.
+ */
+ public DynamoRuntimeException(String msg, Throwable inner)
+ {
+ super(msg,inner);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getLocalizedMessage().
+ *
+ * @param locale The locale to render the message in.
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage(Locale locale)
+ {
+ return getMessage();
+
+ } // end getLocalizedMessage
+
+} // end class DynamoRuntimeException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/DynamoSecurityException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/DynamoSecurityException.java
new file mode 100644
index 0000000..a2fa7b5
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/DynamoSecurityException.java
@@ -0,0 +1,39 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+public class DynamoSecurityException extends ExternalException
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ public DynamoSecurityException(Class caller, String bundle, String message_id)
+ {
+ super(caller,bundle,message_id);
+
+ } // end constructor
+
+ public DynamoSecurityException(Class caller, String bundle, String message_id, Throwable inner)
+ {
+ super(caller,bundle,message_id,inner);
+
+ } // end constructor
+
+} // end class DynamoSecurityException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/ExternalException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/ExternalException.java
new file mode 100644
index 0000000..b58109e
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/ExternalException.java
@@ -0,0 +1,206 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+import java.text.MessageFormat;
+import java.util.*;
+import com.silverwrist.util.StringUtils;
+
+/**
+ * An exception type which is externally reflected and contains a localizable message. The message is loaded
+ * from a ResourceBundle as needed.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public class ExternalException extends DynamoException
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private ClassLoader m_classloader; // classloader to load resource bundle from
+ private String m_bundle_name; // resource bundle name
+ private String m_message_id; // message ID to load message from
+ private String m_message = null; // non-localized message (cached)
+ private ArrayList m_args = null; // argument list
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a new ExternalException instance.
+ *
+ * @param caller The classname of the class that's creating the exception. Its class loader
+ * and package name will be used, together with bundle, to find the
+ * resource bundle.
+ * @param bundle The name of the resource bundle to be loaded.
+ * @param message_id The identifier of the message to be loaded from the bundle.
+ */
+ public ExternalException(Class caller, String bundle, String message_id)
+ {
+ super("");
+ setup(caller,bundle,message_id);
+
+ } // end constructor
+
+ /**
+ * Constructs a new ExternalException instance.
+ *
+ * @param caller The classname of the class that's creating the exception. Its class loader
+ * and package name will be used, together with bundle, to find the
+ * resource bundle.
+ * @param bundle The name of the resource bundle to be loaded.
+ * @param message_id The identifier of the message to be loaded from the bundle.
+ * @param inner The exception to be nested inside this one.
+ */
+ public ExternalException(Class caller, String bundle, String message_id, Throwable inner)
+ {
+ super("",inner);
+ setup(caller,bundle,message_id);
+
+ } // end constructor
+
+ /**
+ * Constructs a copy of an ExternalException.
+ *
+ * @param other The ExternalException to be cloned.
+ */
+ protected ExternalException(ExternalException other)
+ {
+ super("",other);
+ m_classloader = other.m_classloader;
+ m_bundle_name = other.m_bundle_name;
+ m_message_id = other.m_message_id;
+ m_message = other.m_message;
+ if (other.m_args!=null)
+ m_args = (ArrayList)(other.m_args.clone());
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Sets up the instance variables of this ExternalException instance.
+ *
+ * @param caller The classname of the class that's creating the exception. Its class loader
+ * and package name will be used, together with bundle, to find the
+ * resource bundle.
+ * @param bundle The name of the resource bundle to be loaded.
+ * @param message_id The identifier of the message to be loaded from the bundle.
+ */
+ private final void setup(Class caller, String bundle, String message_id)
+ {
+ m_classloader = caller.getClassLoader();
+ String name = caller.getName();
+ int p = name.lastIndexOf('.');
+ m_bundle_name = name.substring(0,p+1) + bundle;
+ m_message_id = message_id;
+
+ } // end setup
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class Throwable
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Returns the detail message string of this exception.
+ *
+ * @return The detail message string of this Throwable instance (which may be null).
+ */
+ public String getMessage()
+ {
+ if (m_message==null)
+ m_message = this.getLocalizedMessage(Locale.US);
+ return m_message;
+
+ } // end getMessage
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getMessage().
+ *
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage()
+ {
+ return getLocalizedMessage(Locale.getDefault());
+
+ } // end getLocalizedMessage
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class DynamoException
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getLocalizedMessage().
+ *
+ * @param locale The locale to render the message in.
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage(Locale locale)
+ {
+ ResourceBundle b = ResourceBundle.getBundle(m_bundle_name,locale,m_classloader);
+ if (m_args==null)
+ return b.getString(m_message_id);
+ else
+ return MessageFormat.format(b.getString(m_message_id),m_args.toArray());
+
+ } // end getLocalizedMessage
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Sets a replacement parameter for the message.
+ *
+ * @param index The index of the parameter to set.
+ * @param param The parameter to be set for the message.
+ */
+ public void setParameter(int index, String param)
+ {
+ if (m_args==null)
+ m_args = new ArrayList();
+ if (m_args.size()>index)
+ { // setting an index that already exists
+ m_args.set(index,param);
+ return;
+
+ } // end if
+
+ // this needs to be tacked onto the end somewhere
+ while (m_args.size().
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+import java.text.MessageFormat;
+import java.util.*;
+import com.silverwrist.util.StringUtils;
+
+/**
+ * An exception type which is externally reflected and contains a localizable message. The message is loaded
+ * from a ResourceBundle as needed.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public class ExternalRuntimeException extends DynamoRuntimeException
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private ClassLoader m_classloader; // classloader to load resource bundle from
+ private String m_bundle_name; // resource bundle name
+ private String m_message_id; // message ID to load message from
+ private String m_message = null; // non-localized message (cached)
+ private ArrayList m_args = null; // argument list
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a new ExternalRuntimeException instance.
+ *
+ * @param caller The classname of the class that's creating the exception. Its class loader
+ * and package name will be used, together with bundle, to find the
+ * resource bundle.
+ * @param bundle The name of the resource bundle to be loaded.
+ * @param message_id The identifier of the message to be loaded from the bundle.
+ */
+ public ExternalRuntimeException(Class caller, String bundle, String message_id)
+ {
+ super("");
+ setup(caller,bundle,message_id);
+
+ } // end constructor
+
+ /**
+ * Constructs a new ExternalRuntimeException instance.
+ *
+ * @param caller The classname of the class that's creating the exception. Its class loader
+ * and package name will be used, together with bundle, to find the
+ * resource bundle.
+ * @param bundle The name of the resource bundle to be loaded.
+ * @param message_id The identifier of the message to be loaded from the bundle.
+ * @param inner The exception to be nested inside this one.
+ */
+ public ExternalRuntimeException(Class caller, String bundle, String message_id, Throwable inner)
+ {
+ super("",inner);
+ setup(caller,bundle,message_id);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Sets up the instance variables of this ExternalRuntimeException instance.
+ *
+ * @param caller The classname of the class that's creating the exception. Its class loader
+ * and package name will be used, together with bundle, to find the
+ * resource bundle.
+ * @param bundle The name of the resource bundle to be loaded.
+ * @param message_id The identifier of the message to be loaded from the bundle.
+ */
+ private final void setup(Class caller, String bundle, String message_id)
+ {
+ m_classloader = caller.getClassLoader();
+ String name = caller.getName();
+ int p = name.lastIndexOf('.');
+ m_bundle_name = name.substring(0,p+1) + bundle;
+ m_message_id = message_id;
+
+ } // end setup
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class Throwable
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Returns the detail message string of this exception.
+ *
+ * @return The detail message string of this Throwable instance (which may be null).
+ */
+ public String getMessage()
+ {
+ if (m_message==null)
+ m_message = getLocalizedMessage(Locale.US);
+ return m_message;
+
+ } // end getMessage
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getMessage().
+ *
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage()
+ {
+ return getLocalizedMessage(Locale.getDefault());
+
+ } // end getLocalizedMessage
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class DynamoRuntimeException
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getLocalizedMessage().
+ *
+ * @param locale The locale to render the message in.
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage(Locale locale)
+ {
+ ResourceBundle b = ResourceBundle.getBundle(m_bundle_name,locale,m_classloader);
+ if (m_args==null)
+ return b.getString(m_message_id);
+ else
+ return MessageFormat.format(b.getString(m_message_id),m_args.toArray());
+
+ } // end getLocalizedMessage
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Sets a replacement parameter for the message.
+ *
+ * @param index The index of the parameter to set.
+ * @param param The parameter to be set for the message.
+ */
+ public void setParameter(int index, String param)
+ {
+ if (m_args==null)
+ m_args = new ArrayList();
+ if (m_args.size()>index)
+ { // setting an index that already exist
+ m_args.set(index,param);
+ return;
+
+ } // end if
+
+ // this needs to be tacked onto the end somewhere
+ while (m_args.size().
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+import java.util.Locale;
+
+public class GroupRuntimeException extends DynamoRuntimeException
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public GroupRuntimeException(DynamoException inner)
+ {
+ super(inner);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class Throwable
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getMessage()
+ {
+ return getCause().getMessage();
+
+ } // end getMessage
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getMessage().
+ *
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage()
+ {
+ return getCause().getLocalizedMessage();
+
+ } // end getLocalizedMessage
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class DynamoRuntimeException
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getLocalizedMessage().
+ *
+ * @param locale The locale to render the message in.
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage(Locale locale)
+ {
+ return ((DynamoException)getCause()).getLocalizedMessage(locale);
+
+ } // end getLocalizedMessage
+
+} // end class GroupRuntimeException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/MailException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/MailException.java
new file mode 100644
index 0000000..4a70694
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/MailException.java
@@ -0,0 +1,39 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+public class MailException extends ExternalException
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ public MailException(Class caller, String bundle, String message_id)
+ {
+ super(caller,bundle,message_id);
+
+ } // end constructor
+
+ public MailException(Class caller, String bundle, String message_id, Throwable inner)
+ {
+ super(caller,bundle,message_id,inner);
+
+ } // end constructor
+
+} // end class MailException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/ModuleException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/ModuleException.java
new file mode 100644
index 0000000..73a28cb
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/ModuleException.java
@@ -0,0 +1,58 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+public class ModuleException extends ExternalException
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a new ModuleException instance.
+ *
+ * @param caller The classname of the class that's creating the exception. Its class loader
+ * and package name will be used, together with bundle, to find the
+ * resource bundle.
+ * @param bundle The name of the resource bundle to be loaded.
+ * @param message_id The identifier of the message to be loaded from the bundle.
+ */
+ public ModuleException(Class caller, String bundle, String message_id)
+ {
+ super(caller,bundle,message_id);
+
+ } // end constructor
+
+ /**
+ * Constructs a new ModuleException instance.
+ *
+ * @param caller The classname of the class that's creating the exception. Its class loader
+ * and package name will be used, together with bundle, to find the
+ * resource bundle.
+ * @param bundle The name of the resource bundle to be loaded.
+ * @param message_id The identifier of the message to be loaded from the bundle.
+ * @param inner The exception to be nested inside this one.
+ */
+ public ModuleException(Class caller, String bundle, String message_id, Throwable inner)
+ {
+ super(caller,bundle,message_id,inner);
+
+ } // end constructor
+
+} // end class ModuleException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/NoSuchObjectException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/NoSuchObjectException.java
new file mode 100644
index 0000000..a3778db
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/NoSuchObjectException.java
@@ -0,0 +1,142 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+/**
+ * An exception thrown by objects that implement ObjectProvider when they
+ * don't contain a specified object.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ * @see com.silverwrist.dynamo.iface.ObjectProvider
+ */
+public class NoSuchObjectException extends DynamoRuntimeException
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final String BUNDLE = "com.silverwrist.dynamo.except.DynamoExceptionMessages";
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private String m_context; // context of request
+ private Object[] m_args; // arguments list to generate
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a new NoSuchObjectException.
+ *
+ * @param context Context for the generated exception.
+ * @param namespace Namespace of the object that was requested.
+ * @param name Name of the object that was requested.
+ */
+ public NoSuchObjectException(String context, String namespace, String name)
+ {
+ super(context + ": no such object " + name + " in namespace " + namespace);
+ m_context = context;
+ m_args = new Object[3];
+ m_args[0] = context;
+ m_args[1] = namespace;
+ m_args[2] = name;
+
+ } // end constructor
+
+ public NoSuchObjectException(String context, String namespace, String name, Throwable inner)
+ {
+ super(context + ": no such object " + name + " in namespace " + namespace,inner);
+ m_context = context;
+ m_args = new Object[3];
+ m_args[0] = context;
+ m_args[1] = namespace;
+ m_args[2] = name;
+
+ } // end constructor
+
+ public NoSuchObjectException(String context, NoSuchObjectException other)
+ {
+ super(morphMessage(other,context),other);
+ m_context = context;
+ m_args = new Object[other.m_args.length];
+ System.arraycopy(other.m_args,0,m_args,0,other.m_args.length);
+ m_args[0] = context;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final String morphMessage(NoSuchObjectException other, String new_context)
+ {
+ return new_context + other.getMessage().substring(other.m_context.length());
+
+ } // end morphMessage
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class Throwable
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getMessage().
+ *
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage()
+ {
+ return this.getLocalizedMessage(Locale.getDefault());
+
+ } // end getLocalizedMessage
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class DynamoRuntimeException
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getLocalizedMessage().
+ *
+ * @param locale The locale to render the message in.
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage(Locale locale)
+ {
+ ResourceBundle b = ResourceBundle.getBundle(BUNDLE,locale,getClass().getClassLoader());
+ return MessageFormat.format(b.getString("noSuchObjectException"),m_args);
+
+ } // end getLocalizedMessage
+
+} // end class NoSuchObjectException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/NoSuchResourceException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/NoSuchResourceException.java
new file mode 100644
index 0000000..d4ef78f
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/NoSuchResourceException.java
@@ -0,0 +1,99 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+public class NoSuchResourceException extends DynamoRuntimeException
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final String BUNDLE = "com.silverwrist.dynamo.except.DynamoExceptionMessages";
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private Object[] m_args; // arguments list to generate
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public NoSuchResourceException(String resource_path)
+ {
+ super("resource not found: " + resource_path);
+ m_args = new Object[1];
+ m_args[0] = resource_path;
+
+ } // end constructor
+
+ public NoSuchResourceException(String resource_path, Throwable inner)
+ {
+ super("resource not found: " + resource_path,inner);
+ m_args = new Object[1];
+ m_args[0] = resource_path;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class Throwable
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getMessage().
+ *
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage()
+ {
+ return this.getLocalizedMessage(Locale.getDefault());
+
+ } // end getLocalizedMessage
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class DynamoRuntimeException
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getLocalizedMessage().
+ *
+ * @param locale The locale to render the message in.
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage(Locale locale)
+ {
+ ResourceBundle b = ResourceBundle.getBundle(BUNDLE,locale,getClass().getClassLoader());
+ return MessageFormat.format(b.getString("noSuchResourceException"),m_args);
+
+ } // end getLocalizedMessage
+
+} // end class NoSuchResourceException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/NoSuchServiceException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/NoSuchServiceException.java
new file mode 100644
index 0000000..31e99e3
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/NoSuchServiceException.java
@@ -0,0 +1,224 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+/**
+ * An exception thrown by objects that implement ServiceProvider when they
+ * don't implement a service of a specified class and ID.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ * @see com.silverwrist.dynamo.iface.ServiceProvider
+ */
+public class NoSuchServiceException extends DynamoRuntimeException
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final String BUNDLE = "com.silverwrist.dynamo.except.DynamoExceptionMessages";
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private String m_context; // context string
+ private String m_message_id; // ID of the message to generate
+ private Class m_klass; // class of the service we were asking for
+ private String m_serviceid; // service ID of the service we were asking for
+ private Object[] m_args; // arguments list to generate
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a new NoSuchServiceException.
+ *
+ * @param context Context for the generated exception.
+ * @param klass Class of the service that was requested.
+ */
+ public NoSuchServiceException(String context, Class klass)
+ {
+ super(context + ": no service with class " + klass.getName());
+ m_context = context;
+ m_klass = klass;
+ m_serviceid = null;
+ m_message_id = "noSuchServiceException.1";
+ m_args = new Object[2];
+ m_args[0] = context;
+ m_args[1] = klass.getName();
+
+ } // end constructor
+
+ /**
+ * Constructs a new NoSuchServiceException.
+ *
+ * @param context Context for the generated exception.
+ * @param klass Class of the service that was requested.
+ * @param inner Inner exception which caused this one.
+ */
+ public NoSuchServiceException(String context, Class klass, Throwable inner)
+ {
+ super(context + ": no service with class " + klass.getName(),inner);
+ m_context = context;
+ m_klass = klass;
+ m_serviceid = null;
+ m_message_id = "noSuchServiceException.1";
+ m_args = new Object[2];
+ m_args[0] = context;
+ m_args[1] = klass.getName();
+
+ } // end constructor
+
+ /**
+ * Constructs a new NoSuchServiceException.
+ *
+ * @param context Context for the generated exception.
+ * @param klass Class of the service that was requested.
+ * @param serviceid ID of the service that was requested.
+ */
+ public NoSuchServiceException(String context, Class klass, String serviceid)
+ {
+ super(context + ": no service with class " + klass.getName() + " and ID " + serviceid);
+ m_context = context;
+ m_klass = klass;
+ m_serviceid = serviceid;
+ m_message_id = "noSuchServiceException.2";
+ m_args = new Object[3];
+ m_args[0] = context;
+ m_args[1] = klass.getName();
+ m_args[2] = serviceid;
+
+ } // end constructor
+
+ /**
+ * Constructs a new NoSuchServiceException.
+ *
+ * @param context Context for the generated exception.
+ * @param klass Class of the service that was requested.
+ * @param serviceid ID of the service that was requested.
+ * @param inner Inner exception which caused this one.
+ */
+ public NoSuchServiceException(String context, Class klass, String serviceid, Throwable inner)
+ {
+ super(context + ": no service with class " + klass.getName() + " and ID " + serviceid,inner);
+ m_context = context;
+ m_klass = klass;
+ m_serviceid = serviceid;
+ m_message_id = "noSuchServiceException.2";
+ m_args = new Object[3];
+ m_args[0] = context;
+ m_args[1] = klass.getName();
+ m_args[2] = serviceid;
+
+ } // end constructor
+
+ public NoSuchServiceException(String context, NoSuchServiceException other)
+ {
+ super(morphMessage(other,context),other);
+ m_context = context;
+ m_klass = other.m_klass;
+ m_serviceid = other.m_serviceid;
+ m_message_id = other.m_message_id;
+ m_args = new Object[other.m_args.length];
+ System.arraycopy(other.m_args,0,m_args,0,other.m_args.length);
+ m_args[0] = context;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final String morphMessage(NoSuchServiceException other, String new_context)
+ {
+ return new_context + other.getMessage().substring(other.m_context.length());
+
+ } // end morphMessage
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class Throwable
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getMessage().
+ *
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage()
+ {
+ return this.getLocalizedMessage(Locale.getDefault());
+
+ } // end getLocalizedMessage
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class DynamoRuntimeException
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getLocalizedMessage().
+ *
+ * @param locale The locale to render the message in.
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage(Locale locale)
+ {
+ ResourceBundle b = ResourceBundle.getBundle(BUNDLE,locale,getClass().getClassLoader());
+ return MessageFormat.format(b.getString(m_message_id),m_args);
+
+ } // end getLocalizedMessage
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getContext()
+ {
+ return m_context;
+
+ } // end getContext
+
+ public Class getServiceClass()
+ {
+ return m_klass;
+
+ } // end getServiceClass
+
+ public String getServiceID()
+ {
+ return m_serviceid;
+
+ } // end getServiceID
+
+} // end class NoSuchServiceException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/ObjectStoreException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/ObjectStoreException.java
new file mode 100644
index 0000000..9450797
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/ObjectStoreException.java
@@ -0,0 +1,39 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+public class ObjectStoreException extends ExternalRuntimeException
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ public ObjectStoreException(Class caller, String bundle, String message_id)
+ {
+ super(caller,bundle,message_id);
+
+ } // end constructor
+
+ public ObjectStoreException(Class caller, String bundle, String message_id, Throwable inner)
+ {
+ super(caller,bundle,message_id,inner);
+
+ } // end constructor
+
+} // end class ObjectStoreException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/ProxyException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/ProxyException.java
new file mode 100644
index 0000000..65fe29a
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/ProxyException.java
@@ -0,0 +1,84 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+import java.util.Locale;
+
+public class ProxyException extends DynamoRuntimeException
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public ProxyException(Throwable inner)
+ {
+ super(inner);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class Throwable
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getMessage()
+ {
+ return getCause().getMessage();
+
+ } // end getMessage
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getMessage().
+ *
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage()
+ {
+ return getCause().getLocalizedMessage();
+
+ } // end getLocalizedMessage
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class DynamoRuntimeException
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getLocalizedMessage().
+ *
+ * @param locale The locale to render the message in.
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage(Locale locale)
+ {
+ Throwable t = getCause();
+ if (t instanceof DynamoException)
+ return ((DynamoException)t).getLocalizedMessage(locale);
+ else if (t instanceof DynamoRuntimeException)
+ return ((DynamoRuntimeException)t).getLocalizedMessage(locale);
+ else
+ return t.getLocalizedMessage();
+
+ } // end getLocalizedMessage
+
+} // end class ProxyException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/RenderClassCreationException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/RenderClassCreationException.java
new file mode 100644
index 0000000..ab6badd
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/RenderClassCreationException.java
@@ -0,0 +1,55 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+import java.lang.reflect.Constructor;
+
+public class RenderClassCreationException extends RenderingException
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ public RenderClassCreationException(Class klass)
+ {
+ super(RenderClassCreationException.class,"DynamoExceptionMessages","renderClass.creation");
+ setParameter(0,klass.getName());
+
+ } // end constructor
+
+ public RenderClassCreationException(Class klass, Throwable inner)
+ {
+ super(RenderClassCreationException.class,"DynamoExceptionMessages","renderClass.creation",inner);
+ setParameter(0,klass.getName());
+
+ } // end constructor
+
+ public RenderClassCreationException(Constructor ctor)
+ {
+ this(ctor.getDeclaringClass());
+
+ } // end constructor
+
+ public RenderClassCreationException(Constructor ctor, Throwable inner)
+ {
+ this(ctor.getDeclaringClass(),inner);
+
+ } // end constructor
+
+} // end class RenderClassCreationException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/RenderingException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/RenderingException.java
new file mode 100644
index 0000000..632acac
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/RenderingException.java
@@ -0,0 +1,77 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+/**
+ * An exception thrown to indicate a problem with rendering an object. This exception is commonly thrown
+ * only at output time.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public class RenderingException extends ExternalException
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Constructs a new RenderingException instance.
+ *
+ * @param caller The classname of the class that's creating the exception. Its class loader
+ * and package name will be used, together with bundle, to find the
+ * resource bundle.
+ * @param bundle The name of the resource bundle to be loaded.
+ * @param message_id The identifier of the message to be loaded from the bundle.
+ */
+ public RenderingException(Class caller, String bundle, String message_id)
+ {
+ super(caller,bundle,message_id);
+
+ } // end constructor
+
+ /**
+ * Constructs a new RenderingException instance.
+ *
+ * @param caller The classname of the class that's creating the exception. Its class loader
+ * and package name will be used, together with bundle, to find the
+ * resource bundle.
+ * @param bundle The name of the resource bundle to be loaded.
+ * @param message_id The identifier of the message to be loaded from the bundle.
+ * @param inner The exception to be nested inside this one.
+ */
+ public RenderingException(Class caller, String bundle, String message_id, Throwable inner)
+ {
+ super(caller,bundle,message_id,inner);
+
+ } // end constructor
+
+ /**
+ * Constructs a new RenderingException instance, copying the data from a
+ * {@link com.silverwrist.dynamo.except.DatabaseException DatabaseException} instance.
+ *
+ * @param other The DatabaseException to copy data from.
+ */
+ public RenderingException(DatabaseException other)
+ {
+ super(other);
+
+ } // end constructor
+
+} // end class RenderingException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/RequestParseException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/RequestParseException.java
new file mode 100644
index 0000000..556c91d
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/RequestParseException.java
@@ -0,0 +1,108 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+public class RequestParseException extends DynamoException
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final String BUNDLE = "com.silverwrist.dynamo.except.DynamoExceptionMessages";
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private Object[] m_args;
+ private String m_message = null;
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ public RequestParseException(String message)
+ {
+ super("");
+ m_args = new Object[1];
+ m_args[0] = message;
+
+ } // end constructor
+
+ public RequestParseException(String message, Throwable inner)
+ {
+ super("",inner);
+ m_args = new Object[1];
+ m_args[0] = message;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class Throwable
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getMessage()
+ {
+ if (m_message==null)
+ m_message = this.getLocalizedMessage(Locale.US);
+ return m_message;
+
+ } // end getMessage
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getMessage().
+ *
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage()
+ {
+ return this.getLocalizedMessage(Locale.getDefault());
+
+ } // end getLocalizedMessage
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class DynamoRuntimeException
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getLocalizedMessage().
+ *
+ * @param locale The locale to render the message in.
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage(Locale locale)
+ {
+ ResourceBundle b = ResourceBundle.getBundle(BUNDLE,locale,getClass().getClassLoader());
+ return MessageFormat.format(b.getString("requestParseException.msg"),m_args);
+
+ } // end getLocalizedMessage
+
+} // end class RequestParseException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/ScriptingException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/ScriptingException.java
new file mode 100644
index 0000000..4fe184e
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/ScriptingException.java
@@ -0,0 +1,118 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+import java.text.MessageFormat;
+import java.util.*;
+import com.silverwrist.util.StringUtils;
+
+public class ScriptingException extends ExternalException
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final String BUNDLE = "com.silverwrist.dynamo.except.DynamoExceptionMessages";
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private String m_source = null;
+ private String m_language = null;
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ public ScriptingException(Class caller, String bundle, String message_id)
+ {
+ super(caller,bundle,message_id);
+
+ } // end constructor
+
+ public ScriptingException(Class caller, String bundle, String message_id, Throwable inner)
+ {
+ super(caller,bundle,message_id,inner);
+
+ } // end constructor
+
+ public ScriptingException(String source, String language, Class caller, String bundle, String message_id)
+ {
+ super(caller,bundle,message_id);
+ m_source = source;
+ m_language = language;
+
+ } // end constructor
+
+ public ScriptingException(String source, String language, Class caller, String bundle, String message_id,
+ Throwable inner)
+ {
+ super(caller,bundle,message_id,inner);
+ m_source = source;
+ m_language = language;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class DynamoRuntimeException
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getLocalizedMessage().
+ *
+ * @param locale The locale to render the message in.
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage(Locale locale)
+ {
+ if ((m_source==null) || (m_language==null))
+ return super.getLocalizedMessage(locale);
+ ResourceBundle b = ResourceBundle.getBundle(BUNDLE,locale,getClass().getClassLoader());
+ Object[] args = new Object[3];
+ args[0] = m_source;
+ args[1] = m_language;
+ args[2] = super.getLocalizedMessage(locale);
+ return MessageFormat.format(b.getString("scriptingException"),args);
+
+ } // end getLocalizedMessage
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ public final String getSource()
+ {
+ return m_source;
+
+ } // end getSource
+
+ public final String getLanguage()
+ {
+ return m_language;
+
+ } // end getLanguage
+
+} // end class ScriptingException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/SecurityRuntimeException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/SecurityRuntimeException.java
new file mode 100644
index 0000000..8721d85
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/SecurityRuntimeException.java
@@ -0,0 +1,78 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+import java.util.Locale;
+
+public class SecurityRuntimeException extends DynamoRuntimeException
+{
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public SecurityRuntimeException(DynamoException inner)
+ {
+ super(inner);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class Throwable
+ *--------------------------------------------------------------------------------
+ */
+
+ public String getMessage()
+ {
+ return getCause().getMessage();
+
+ } // end getMessage
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getMessage().
+ *
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage()
+ {
+ return getCause().getLocalizedMessage();
+
+ } // end getLocalizedMessage
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class DynamoRuntimeException
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Creates a localized description of this exception. Subclasses may override this method in
+ * order to produce a locale-specific message. For subclasses that do not override this method,
+ * the default implementation returns the same result as getLocalizedMessage().
+ *
+ * @param locale The locale to render the message in.
+ * @return The localized description of this exception.
+ */
+ public String getLocalizedMessage(Locale locale)
+ {
+ return ((DynamoException)getCause()).getLocalizedMessage(locale);
+
+ } // end getLocalizedMessage
+
+} // end class SecurityRuntimeException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/UnknownDialogFieldException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/UnknownDialogFieldException.java
new file mode 100644
index 0000000..e5a6bf6
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/UnknownDialogFieldException.java
@@ -0,0 +1,57 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+import org.w3c.dom.Node;
+
+public class UnknownDialogFieldException extends DialogException
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ public UnknownDialogFieldException(String fieldname)
+ {
+ super(UnknownDialogFieldException.class,"DynamoExceptionMessages","udfe.bad.itemType");
+ setParameter(0,fieldname);
+
+ } // end constructor
+
+ public UnknownDialogFieldException(String fieldname, Node locus)
+ {
+ super(UnknownDialogFieldException.class,"DynamoExceptionMessages","udfe.bad.itemType",locus);
+ setParameter(0,fieldname);
+
+ } // end constructor
+
+ public UnknownDialogFieldException(String fieldname, Throwable inner)
+ {
+ super(UnknownDialogFieldException.class,"DynamoExceptionMessages","udfe.bad.itemType",inner);
+ setParameter(0,fieldname);
+
+ } // end constructor
+
+ public UnknownDialogFieldException(String fieldname, Throwable inner, Node locus)
+ {
+ super(UnknownDialogFieldException.class,"DynamoExceptionMessages","udfe.bad.itemType",inner,locus);
+ setParameter(0,fieldname);
+
+ } // end constructor
+
+} // end class UnknownDialogFieldException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/except/ValidationException.java b/src/dynamo-framework/com/silverwrist/dynamo/except/ValidationException.java
new file mode 100644
index 0000000..fbb203d
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/except/ValidationException.java
@@ -0,0 +1,39 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.except;
+
+public class ValidationException extends ExternalException
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ public ValidationException(Class caller, String bundle, String message_id)
+ {
+ super(caller,bundle,message_id);
+
+ } // end constructor
+
+ public ValidationException(Class caller, String bundle, String message_id, Throwable inner)
+ {
+ super(caller,bundle,message_id,inner);
+
+ } // end constructor
+
+} // end class ValidationException
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/iface/Application.java b/src/dynamo-framework/com/silverwrist/dynamo/iface/Application.java
new file mode 100644
index 0000000..dfeb6dd
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/iface/Application.java
@@ -0,0 +1,50 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.iface;
+
+/**
+ * The interface implemented by an application object. This is the object referenced by the
+ * classname= attribute to the <application/> tag in the
+ * Dynamo configuration file. The application container uses this to communicate with the
+ * application object.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public interface Application extends NamedObject, ServiceProvider
+{
+ /**
+ * Gets the identity of this application. This identity is used along with the Dynamo version number in
+ * such contexts as the Server: header of the HTTP response and the X-Mailer:
+ * header of composed mail messages.
+ *
+ * @return The identity of the application, in the form "name/version".
+ */
+ public String getIdentity();
+
+ /**
+ * Gets an object to be rendered in place of the content returned by the control operation when that
+ * content is a null reference.
+ *
+ * @param r The Request that is currently being processed.
+ * @return A renderable object to be output.
+ */
+ public Object getNullContentError(Request r);
+
+} // end interface Application
+
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/iface/ApplicationSubstrate.java b/src/dynamo-framework/com/silverwrist/dynamo/iface/ApplicationSubstrate.java
new file mode 100644
index 0000000..7d362cd
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/iface/ApplicationSubstrate.java
@@ -0,0 +1,113 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.iface;
+
+import com.silverwrist.dynamo.Namespaces;
+import com.silverwrist.dynamo.except.ConfigException;
+
+/**
+ * An object which is used to provide certain data and operations related to the underlying environment
+ * of the application container.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public interface ApplicationSubstrate extends ObjectProvider
+{
+ /**
+ * The namespace used for all substrate data objects.
+ */
+ public static final String NAMESPACE = Namespaces.SUBSTRATE_NAMESPACE;
+
+ /**
+ * The name of the data item containing the base path of the application. In a Web application, this
+ * is the web application's root path.
+ */
+ public static final String OBJ_BASE_PATH = "base.path";
+
+ /**
+ * The name of the data item containing the code path of the application. In a Web application, this
+ * is the web application's WEB-INF directory.
+ */
+ public static final String OBJ_CODE_PATH = "code.path";
+
+ /**
+ * The name of the data item containing the classes path of the application. In a Web application, this
+ * is the web application's WEB-INF/classes directory.
+ */
+ public static final String OBJ_CLASSES_PATH = "classes.path";
+
+ /**
+ * The name of the data item containing the libraries path of the application. In a Web application, this
+ * is the web application's WEB-INF/libs directory.
+ */
+ public static final String OBJ_LIBS_PATH = "libs.path";
+
+ /**
+ * The name of the data item containing the path to use for temporary files.
+ */
+ public static final String OBJ_TEMP_PATH = "temp.path";
+
+ /**
+ * The name of the data item containing the substrate type, for example, "Servlet" for Web applications.
+ */
+ public static final String OBJ_SUBSTRATE_TYPE = "substrate.type";
+
+ /**
+ * The name of the data item containing the substrate specification version. In Web applications,
+ * this is the servlet API version.
+ */
+ public static final String OBJ_SUBSTRATE_SPECVER = "substrate.spec.version";
+
+ /**
+ * The name of the data item containing the application's name. For Web applications, this will be
+ * the application name configured in web.xml.
+ */
+ public static final String OBJ_APP_NAME = "application.name";
+
+ /**
+ * The name of the data item containing the version of Java we're running.
+ */
+ public static final String OBJ_JAVA_VERSION = "java.version";
+
+ /**
+ * The name of the data item containing the name of the underlying operating system.
+ */
+ public static final String OBJ_OS_NAME = "os.name";
+
+ /**
+ * The name of the data item containing the version of the underlying operating system.
+ */
+ public static final String OBJ_OS_VERSION = "os.version";
+
+ /**
+ * Initializes this substrate object. Called as the first operation in the initialization of the
+ * application container.
+ *
+ * @exception com.silverwrist.dynamo.except.ConfigException If there is a problem with the substrate
+ * initialization.
+ */
+ public void initialize() throws ConfigException;
+
+ /**
+ * Terminates this substrate object. Called as the final operation in the shutdown of the
+ * application container.
+ */
+ public void terminate();
+
+} // end interface ApplicationSubstrate
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/iface/AuditRecord.java b/src/dynamo-framework/com/silverwrist/dynamo/iface/AuditRecord.java
new file mode 100644
index 0000000..454e3ca
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/iface/AuditRecord.java
@@ -0,0 +1,87 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.iface;
+
+/**
+ * An interface to read audit records as stored in the database.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
+public interface AuditRecord
+{
+ /**
+ * Get the record number associated with this audit record.
+ *
+ * @return The record number of the audit record.
+ */
+ public long getRecordNum();
+
+ /**
+ * Get the date and time stamp at which this audit record was generated.
+ *
+ * @return The date and time stamp of the audit record.
+ */
+ public java.util.Date getTimestamp();
+
+ /**
+ * Get the namespace associated with this event. A Dynamo namespace is generally a URI.
+ *
+ * @return The namespace associated with this audit record.
+ */
+ public String getEventNamespace();
+
+ /**
+ * Get the name associated with this event, relative to the event's namespace.
+ *
+ * @return The event name associated with this audit record.
+ */
+ public String getEventName();
+
+ /**
+ * Get the user object associated with this audit record. This is usually the user who performed the operation.
+ *
+ * @return The user associated with the audit record.
+ */
+ public DynamoUser getUser();
+
+ /**
+ * Get the subcontext identifier associated with this audit record.
+ *
+ * @return The subcontext associated with the audit record.
+ */
+ public int getSubID();
+
+ /**
+ * Get the IP address associated with this audit record. This is usually the address of the person that
+ * performed the operation.
+ *
+ * @return The IP address associated with the audit record.
+ */
+ public String getIPAddress();
+
+ /**
+ * Get a property associated with the audit record. A property is like an "argument" to the audit record,
+ * and may be of any type that can be serialized by the Dynamo PropertySerializer.
+ *
+ * @param index The index of the property to retrieve (0-based).
+ * @return The associated property value.
+ */
+ public Object getProperty(int index);
+
+} // end interface AuditRecord
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/iface/AuditRecordCompose.java b/src/dynamo-framework/com/silverwrist/dynamo/iface/AuditRecordCompose.java
new file mode 100644
index 0000000..b9a5d88
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/iface/AuditRecordCompose.java
@@ -0,0 +1,26 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.iface;
+
+public interface AuditRecordCompose extends AuditRecord
+{
+ public void setProperty(int index, Object value);
+
+ public void write();
+
+} // end interface AuditRecordCompose
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/iface/AuditRecordFactory.java b/src/dynamo-framework/com/silverwrist/dynamo/iface/AuditRecordFactory.java
new file mode 100644
index 0000000..5c41a14
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/iface/AuditRecordFactory.java
@@ -0,0 +1,29 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.iface;
+
+public interface AuditRecordFactory
+{
+ public AuditRecordCompose createAuditRecord(Request r, DynamoUser user, String namespace, String name);
+
+ public AuditRecordCompose createAuditRecord(Request r, DynamoUser user, int subid, String namespace,
+ String name);
+
+ public AuditRecordCompose createSystemAuditRecord(String namespace, String name);
+
+} // end interface AuditRecordFactory
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/iface/AuditRecordRetrieval.java b/src/dynamo-framework/com/silverwrist/dynamo/iface/AuditRecordRetrieval.java
new file mode 100644
index 0000000..f94de31
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/iface/AuditRecordRetrieval.java
@@ -0,0 +1,31 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.iface;
+
+import java.util.Date;
+import com.silverwrist.dynamo.except.DatabaseException;
+
+public interface AuditRecordRetrieval
+{
+ public AuditRecordSet getAuditRecords(java.util.Date start_date, java.util.Date end_date)
+ throws DatabaseException;
+
+ public AuditRecordSet getAuditRecords(java.util.Date start_date, java.util.Date end_date, int subid)
+ throws DatabaseException;
+
+} // end interface AuditRecordRetrieval
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/iface/AuditRecordSet.java b/src/dynamo-framework/com/silverwrist/dynamo/iface/AuditRecordSet.java
new file mode 100644
index 0000000..38317cc
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/iface/AuditRecordSet.java
@@ -0,0 +1,28 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.dynamo.iface;
+
+import com.silverwrist.dynamo.except.DatabaseException;
+
+public interface AuditRecordSet
+{
+ public int getRecordCount();
+
+ public AuditRecord getRecord(int index) throws DatabaseException;
+
+} // end interface AuditRecordSet
diff --git a/src/dynamo-framework/com/silverwrist/dynamo/iface/Authenticator.java b/src/dynamo-framework/com/silverwrist/dynamo/iface/Authenticator.java
new file mode 100644
index 0000000..9e3b231
--- /dev/null
+++ b/src/dynamo-framework/com/silverwrist/dynamo/iface/Authenticator.java
@@ -0,0 +1,28 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at