From 66663c8b2051d197852c11765d6b934aff3ecb5c Mon Sep 17 00:00:00 2001 From: hns Date: Wed, 16 Apr 2003 16:28:04 +0000 Subject: [PATCH] Merge from helma_1_2_4 --- .../data/030SYS_INFO_sUSRPKeyInfo.koi | Bin 8064 -> 0 bytes .../data/037SYS_INFO_sUSRSchemaInfo.koi | Bin 5664 -> 0 bytes build/antclick/data/042SYS_INFO_sUSRGrant.koi | Bin 27488 -> 0 bytes build/antclick/data/051APP_AV_IMAGE.koi | Bin 14736 -> 0 bytes build/antclick/data/053APP_AV_POLL.koi | Bin 7000 -> 0 bytes build/antclick/data/056APP_AV_TEXT.koi | Bin 10440 -> 0 bytes .../data/062SYS_INFO_sUSRSequenceInfo.koi | Bin 0 -> 12600 bytes .../data/063SYS_INFO_sUSRSequence.koi | Bin 0 -> 3952 bytes .../data/064SYS_INFO_sUSRPKeyInfo.koi | Bin 0 -> 8064 bytes ...yInfo.koi => 065SYS_INFO_sUSRFKeyInfo.koi} | Bin 7848 -> 7848 bytes ...nfo.koi => 066SYS_INFO_sUSRUniqueInfo.koi} | Bin 6936 -> 6936 bytes ...Info.koi => 067SYS_INFO_sUSRCheckInfo.koi} | Bin 4856 -> 4856 bytes ...koi => 068SYS_INFO_sUSRPrimaryColumns.koi} | Bin 5584 -> 5576 bytes ....koi => 069SYS_INFO_sUSRUniqueColumns.koi} | Bin 4560 -> 4560 bytes ...koi => 070SYS_INFO_sUSRForeignColumns.koi} | Bin 5552 -> 4616 bytes .../data/071SYS_INFO_sUSRSchemaInfo.koi | Bin 0 -> 4536 bytes ...s.koi => 072SYS_INFO_sUSRDatabaseVars.koi} | Bin 4576 -> 4576 bytes ...sword.koi => 073SYS_INFO_sUSRPassword.koi} | Bin 4528 -> 4528 bytes ...rPriv.koi => 074SYS_INFO_sUSRUserPriv.koi} | Bin 4584 -> 4584 bytes ...oi => 075SYS_INFO_sUSRUserConnectPriv.koi} | Bin 4560 -> 4672 bytes build/antclick/data/076SYS_INFO_sUSRGrant.koi | Bin 0 -> 18248 bytes ...ervice.koi => 077SYS_INFO_sUSRService.koi} | Bin 3472 -> 3472 bytes ...oi => 078SYS_INFO_sUSRFunctionFactory.koi} | Bin 3504 -> 3504 bytes .../data/079SYS_INFO_sUSRFunction.koi | Bin 0 -> 6248 bytes ..._sUSRView.koi => 080SYS_INFO_sUSRView.koi} | Bin 77800 -> 77168 bytes ...USRLabel.koi => 081SYS_INFO_sUSRLabel.koi} | Bin 3456 -> 3504 bytes .../data/082SYS_INFO_sUSRDataTrigger.koi | Bin 0 -> 3808 bytes ..._ACCESSLOG.koi => 083APP_AV_ACCESSLOG.koi} | Bin 5568 -> 5696 bytes ...APP_AV_CHOICE.koi => 084APP_AV_CHOICE.koi} | Bin 4784 -> 4784 bytes ...{050APP_AV_FILE.koi => 085APP_AV_FILE.koi} | Bin 8192 -> 7568 bytes build/antclick/data/086APP_AV_IMAGE.koi | Bin 0 -> 20360 bytes ...EMBERSHIP.koi => 087APP_AV_MEMBERSHIP.koi} | Bin 5680 -> 5888 bytes build/antclick/data/088APP_AV_POLL.koi | Bin 0 -> 7224 bytes ...{054APP_AV_SKIN.koi => 089APP_AV_SKIN.koi} | Bin 5896 -> 5896 bytes ...APP_AV_SYSLOG.koi => 090APP_AV_SYSLOG.koi} | Bin 4904 -> 5016 bytes ...{058APP_AV_VOTE.koi => 092APP_AV_VOTE.koi} | Bin 4984 -> 5128 bytes ...{059APP_AV_SITE.koi => 093APP_AV_SITE.koi} | Bin 16704 -> 15424 bytes ...{060APP_AV_USER.koi => 094APP_AV_USER.koi} | Bin 6984 -> 7208 bytes ...AV_SHORTCUT.koi => 095APP_AV_SHORTCUT.koi} | Bin 4520 -> 5672 bytes build/antclick/data/096APP_AV_TEXT.koi | Bin 0 -> 12728 bytes ...YS_INFO_sUSRFunction.koi => BlobStore.koi} | Bin 3472 -> 2880 bytes build/antclick/data/DefaultDatabase.sf | Bin 4608 -> 0 bytes build/antclick/data/DefaultDatabase_sf.koi | Bin 0 -> 6984 bytes build/antclick/lib/ext/mckoidb.jar | Bin 991141 -> 1125395 bytes build/build.xml | 6 +- lib/ext/mysql.jar | Bin 125901 -> 0 bytes src/helma/doc/DocApplication.java | 245 +- src/helma/doc/DocComparator.java | 108 +- src/helma/doc/DocDirElement.java | 67 +- src/helma/doc/DocElement.java | 603 +-- src/helma/doc/DocException.java | 41 +- src/helma/doc/DocFileElement.java | 160 +- src/helma/doc/DocFunction.java | 287 +- src/helma/doc/DocProperties.java | 129 +- src/helma/doc/DocPrototype.java | 220 +- src/helma/doc/DocSkin.java | 175 +- src/helma/doc/DocTag.java | 244 +- src/helma/doc/Util.java | 76 +- .../extensions/ConfigurationException.java | 30 +- src/helma/extensions/HelmaExtension.java | 96 +- src/helma/extensions/demo/DemoExtension.java | 152 +- .../ApplicationStoppedException.java | 30 +- src/helma/framework/CookieTrans.java | 128 +- src/helma/framework/FrameworkException.java | 32 +- src/helma/framework/IPathElement.java | 35 +- src/helma/framework/IRemoteApp.java | 40 +- src/helma/framework/RedirectException.java | 54 +- src/helma/framework/RequestBean.java | 174 +- src/helma/framework/RequestTrans.java | 297 +- src/helma/framework/ResponseBean.java | 417 +- src/helma/framework/ResponseTrans.java | 877 ++-- src/helma/framework/TimeoutException.java | 33 +- src/helma/framework/core/AppClassLoader.java | 44 +- src/helma/framework/core/Application.java | 2170 +++++----- src/helma/framework/core/ApplicationBean.java | 540 ++- src/helma/framework/core/Prototype.java | 687 ++-- .../framework/core/RemoteApplication.java | 59 +- .../framework/core/RequestEvaluator.java | 1324 +++--- src/helma/framework/core/Session.java | 203 +- src/helma/framework/core/SessionBean.java | 148 +- src/helma/framework/core/Skin.java | 1168 +++--- src/helma/framework/core/SkinFile.java | 187 +- src/helma/framework/core/SkinManager.java | 195 +- src/helma/framework/core/TypeManager.java | 549 +-- src/helma/framework/core/ZippedAppFile.java | 294 +- src/helma/image/ImageGenerator.java | 405 +- src/helma/image/ImageWrapper.java | 527 ++- src/helma/image/SunImageWrapper.java | 162 +- src/helma/main/ApplicationManager.java | 588 +-- src/helma/main/HelmaSecurityManager.java | 357 +- src/helma/main/HelmaShutdownHook.java | 57 +- src/helma/main/HelmaSocketFactory.java | 71 +- src/helma/main/Server.java | 1070 ++--- .../main/launcher/FilteredClassLoader.java | 45 +- src/helma/main/launcher/Main.java | 221 +- .../objectmodel/ConcurrencyException.java | 68 +- src/helma/objectmodel/DatabaseException.java | 63 +- src/helma/objectmodel/IDatabase.java | 113 +- src/helma/objectmodel/INode.java | 423 +- src/helma/objectmodel/INodeState.java | 28 +- src/helma/objectmodel/IProperty.java | 98 +- src/helma/objectmodel/ITransaction.java | 35 +- src/helma/objectmodel/NodeEvent.java | 103 +- .../objectmodel/ObjectNotFoundException.java | 62 +- src/helma/objectmodel/Property.java | 419 +- src/helma/objectmodel/TransientNode.java | 1239 ++++-- src/helma/objectmodel/db/DbColumn.java | 46 +- src/helma/objectmodel/db/DbKey.java | 120 +- src/helma/objectmodel/db/DbMapping.java | 1333 +++--- src/helma/objectmodel/db/DbSource.java | 183 +- .../objectmodel/db/ExternalizableVector.java | 71 +- src/helma/objectmodel/db/IDGenerator.java | 85 +- .../objectmodel/db/IReplicationListener.java | 23 +- src/helma/objectmodel/db/Key.java | 97 +- src/helma/objectmodel/db/Node.java | 3579 ++++++++++------- src/helma/objectmodel/db/NodeHandle.java | 143 +- src/helma/objectmodel/db/NodeManager.java | 2669 ++++++------ src/helma/objectmodel/db/ParentInfo.java | 67 +- src/helma/objectmodel/db/Property.java | 732 ++-- src/helma/objectmodel/db/Relation.java | 1056 +++-- src/helma/objectmodel/db/Replicator.java | 162 +- src/helma/objectmodel/db/Server.java | 31 +- src/helma/objectmodel/db/SyntheticKey.java | 111 +- src/helma/objectmodel/db/Transactor.java | 480 ++- .../objectmodel/db/WrappedNodeManager.java | 361 +- src/helma/objectmodel/db/XmlDatabase.java | 295 +- src/helma/objectmodel/dom/IDGenParser.java | 99 +- src/helma/objectmodel/dom/XmlConstants.java | 27 +- src/helma/objectmodel/dom/XmlConverter.java | 731 ++-- .../objectmodel/dom/XmlDatabaseReader.java | 370 +- src/helma/objectmodel/dom/XmlReader.java | 415 +- src/helma/objectmodel/dom/XmlUtil.java | 234 +- src/helma/objectmodel/dom/XmlWriter.java | 832 ++-- src/helma/scripting/ActionFile.java | 232 +- src/helma/scripting/FunctionFile.java | 136 +- src/helma/scripting/ScriptingEngine.java | 53 +- src/helma/scripting/ScriptingException.java | 110 +- src/helma/scripting/Template.java | 324 +- src/helma/scripting/fesi/ESBeanWrapper.java | 125 +- src/helma/scripting/fesi/ESGenericObject.java | 299 +- src/helma/scripting/fesi/ESMapWrapper.java | 288 +- src/helma/scripting/fesi/ESNode.java | 996 +++-- .../scripting/fesi/FesiActionAdapter.java | 291 +- src/helma/scripting/fesi/FesiEngine.java | 1357 ++++--- src/helma/scripting/fesi/HopExtension.java | 1335 +++--- src/helma/scripting/fesi/NodeConstructor.java | 214 +- src/helma/scripting/fesi/PhantomEngine.java | 29 +- .../fesi/extensions/DomExtension.java | 401 +- .../scripting/fesi/extensions/ESMail.java | 460 ++- .../fesi/extensions/FtpExtension.java | 548 ++- .../fesi/extensions/ImageExtension.java | 124 +- .../fesi/extensions/MailExtension.java | 382 +- .../fesi/extensions/XmlRpcExtension.java | 196 +- src/helma/servlet/AbstractServletClient.java | 885 ++-- src/helma/servlet/EmbeddedServletClient.java | 73 +- src/helma/servlet/MultiServletClient.java | 141 +- src/helma/servlet/ServletClient.java | 98 +- .../servlet/StandaloneServletClient.java | 127 +- src/helma/util/CronJob.java | 80 +- src/helma/util/CryptFile.java | 160 +- src/helma/util/EmptyEnumeration.java | 39 +- src/helma/util/FileUpload.java | 194 +- src/helma/util/HtmlEncoder.java | 1153 +++--- src/helma/util/HtmlParser.java | 439 +- src/helma/util/InetAddressFilter.java | 155 +- src/helma/util/Logger.java | 625 +-- src/helma/util/Logo.java | 234 +- src/helma/util/MD5Encoder.java | 81 +- src/helma/util/MimePart.java | 176 +- src/helma/util/MimePartDataSource.java | 72 +- src/helma/util/ParanoidServerSocket.java | 106 +- src/helma/util/SystemProperties.java | 339 +- src/helma/util/Timer.java | 118 +- src/helma/util/Updatable.java | 72 +- src/helma/util/UrlEncoded.java | 58 +- src/helma/util/WebBroadcaster.java | 685 ++-- src/helma/util/XmlUtils.java | 171 +- 177 files changed, 28899 insertions(+), 18112 deletions(-) delete mode 100644 build/antclick/data/030SYS_INFO_sUSRPKeyInfo.koi delete mode 100644 build/antclick/data/037SYS_INFO_sUSRSchemaInfo.koi delete mode 100644 build/antclick/data/042SYS_INFO_sUSRGrant.koi delete mode 100644 build/antclick/data/051APP_AV_IMAGE.koi delete mode 100644 build/antclick/data/053APP_AV_POLL.koi delete mode 100644 build/antclick/data/056APP_AV_TEXT.koi create mode 100644 build/antclick/data/062SYS_INFO_sUSRSequenceInfo.koi create mode 100644 build/antclick/data/063SYS_INFO_sUSRSequence.koi create mode 100644 build/antclick/data/064SYS_INFO_sUSRPKeyInfo.koi rename build/antclick/data/{031SYS_INFO_sUSRFKeyInfo.koi => 065SYS_INFO_sUSRFKeyInfo.koi} (99%) rename build/antclick/data/{032SYS_INFO_sUSRUniqueInfo.koi => 066SYS_INFO_sUSRUniqueInfo.koi} (98%) rename build/antclick/data/{033SYS_INFO_sUSRCheckInfo.koi => 067SYS_INFO_sUSRCheckInfo.koi} (97%) rename build/antclick/data/{034SYS_INFO_sUSRPrimaryColumns.koi => 068SYS_INFO_sUSRPrimaryColumns.koi} (72%) rename build/antclick/data/{035SYS_INFO_sUSRUniqueColumns.koi => 069SYS_INFO_sUSRUniqueColumns.koi} (98%) rename build/antclick/data/{036SYS_INFO_sUSRForeignColumns.koi => 070SYS_INFO_sUSRForeignColumns.koi} (59%) create mode 100644 build/antclick/data/071SYS_INFO_sUSRSchemaInfo.koi rename build/antclick/data/{038SYS_INFO_sUSRDatabaseVars.koi => 072SYS_INFO_sUSRDatabaseVars.koi} (89%) rename build/antclick/data/{039SYS_INFO_sUSRPassword.koi => 073SYS_INFO_sUSRPassword.koi} (98%) rename build/antclick/data/{040SYS_INFO_sUSRUserPriv.koi => 074SYS_INFO_sUSRUserPriv.koi} (98%) rename build/antclick/data/{041SYS_INFO_sUSRUserConnectPriv.koi => 075SYS_INFO_sUSRUserConnectPriv.koi} (91%) create mode 100644 build/antclick/data/076SYS_INFO_sUSRGrant.koi rename build/antclick/data/{043SYS_INFO_sUSRService.koi => 077SYS_INFO_sUSRService.koi} (91%) rename build/antclick/data/{044SYS_INFO_sUSRFunctionFactory.koi => 078SYS_INFO_sUSRFunctionFactory.koi} (91%) create mode 100644 build/antclick/data/079SYS_INFO_sUSRFunction.koi rename build/antclick/data/{046SYS_INFO_sUSRView.koi => 080SYS_INFO_sUSRView.koi} (95%) rename build/antclick/data/{047SYS_INFO_sUSRLabel.koi => 081SYS_INFO_sUSRLabel.koi} (84%) create mode 100644 build/antclick/data/082SYS_INFO_sUSRDataTrigger.koi rename build/antclick/data/{048APP_AV_ACCESSLOG.koi => 083APP_AV_ACCESSLOG.koi} (61%) rename build/antclick/data/{049APP_AV_CHOICE.koi => 084APP_AV_CHOICE.koi} (66%) rename build/antclick/data/{050APP_AV_FILE.koi => 085APP_AV_FILE.koi} (50%) create mode 100644 build/antclick/data/086APP_AV_IMAGE.koi rename build/antclick/data/{052APP_AV_MEMBERSHIP.koi => 087APP_AV_MEMBERSHIP.koi} (57%) create mode 100644 build/antclick/data/088APP_AV_POLL.koi rename build/antclick/data/{054APP_AV_SKIN.koi => 089APP_AV_SKIN.koi} (54%) rename build/antclick/data/{055APP_AV_SYSLOG.koi => 090APP_AV_SYSLOG.koi} (63%) rename build/antclick/data/{058APP_AV_VOTE.koi => 092APP_AV_VOTE.koi} (56%) rename build/antclick/data/{059APP_AV_SITE.koi => 093APP_AV_SITE.koi} (54%) rename build/antclick/data/{060APP_AV_USER.koi => 094APP_AV_USER.koi} (51%) rename build/antclick/data/{061APP_AV_SHORTCUT.koi => 095APP_AV_SHORTCUT.koi} (61%) create mode 100644 build/antclick/data/096APP_AV_TEXT.koi rename build/antclick/data/{045SYS_INFO_sUSRFunction.koi => BlobStore.koi} (53%) delete mode 100644 build/antclick/data/DefaultDatabase.sf create mode 100644 build/antclick/data/DefaultDatabase_sf.koi delete mode 100644 lib/ext/mysql.jar diff --git a/build/antclick/data/030SYS_INFO_sUSRPKeyInfo.koi b/build/antclick/data/030SYS_INFO_sUSRPKeyInfo.koi deleted file mode 100644 index 61ea401d39de8538e46634a6b6b1c29f3988b8f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8064 zcmeHMJxp9j5T18%aKQ0%V8ik2Q>s&>NQdpj#8Q;QCostToH;-yiUh^DEVZvlGw@^>Qg z{*?y)BeZztBP?ny*_qZtT5w#;iTuXI#ie?DY_EF%$g$ghDPKn5G6Mg<2fZEwo0%$HWt<*H4pE)(onwBmK87zVZ_TJ?rf4T9Jjt$9;v+5wAO$`};?L1UT3lgU51 zgL~2XHA&_*y?lSz2zW;y)_$|rV;Nsh&6pG0v6K-xm;589?vGlYc;)CBkv9&SmscdL zH?BLq&xmfb0-hP6TYM?&=ZZ|zCQZ{4E#ujsMbI@Wp|7BNO0-HV7@x=JDtaeriYK+8 zt4Kv=yTGnvq(pO=u>!3EEUdEqHauv?-;*eReWgZ1I`^~~yv_Wr8uRmd#?WanQ!{3M zMvLY?YP5p59ZQeduXg-C!5GW8gew0$_CE>FH}I??wu^{Ek?!d?4<=-AQw4CAmi3H7 z72_49Tc&3iJfK~AY{d+7N$_~Tf$!rE1p5VE!gv22@;w|g>F;G~_*Ws{_aNj`V2w`d zB;@<2EdFiC5BMQ}C1dfgL;mVk$Pa=w_6JWwekdRE$TNRabsMnwD;9s%;s-5$$l}u$ zKWyw*jrq!YQ+Z&tl9%9IuURLtYIQQ(K%KB|%{n2j4Q|!y_fzTr zTBzFpEsU$rsoyp1^m)3E3Z1D@$30}~cn$UYh@Q~TKv}((u~2~Tgax!}IJ46KmC$d~ zU|JbxuY!p{QE{kxne zIq$)#X7HVeTrJ-&&TrUGd*e87IXF86C+A=pu>{sL2o0{|2Jo%3l|#~iF(z(?)*Zi|X7Jr~@R|Jbz3)NAeV3#eT!z+- zueTX|pGV;1+dTHj1?5-mkG^K`xnB|!zjf>n#PA~VrJBL#enAYr5_ZS=`0~iN$t~Cl zo@I5}#=$oSB}Qgi-q&2#+%pp$on6W99(92?N}yTceez;0t?{<@Ku;{oxZL^E8LWem zt_1qQw#sl9+p*<2N8WSfBbn&?n&EM@Vg8+h8*EiHS${a8*AK?>!e!6k4^$K*_Q{82 z+qQXD6t73p7(hJJZ?yi!`DyaOi=mnITeOHvoNB}GF<@sPFXP!3k6L3Umz*yd5EA;? zP(EEhRUQB#@OuvSZJF1xL{N%qGa1+BLZ=?LQOHt)k&ol4P&oG8O26Gk7 zsoPq9jvQ+nf!{U!q~QNZvZ`6%_$j}Ij=nzM&px#`RcekJt>*uK05BzrWN$(=^$ym5aoX1{7`B`IsW_@Lbd}kfLa>1m*HOg9++-N>sKgUcR zz0=E6<^D>Y*3jrwJdaz}uJ6>@01BUs!dS6wC%;3d=(F-WoU4>aIZxL3_%DupS}9M=LFVTBijaFQ K>E6cQ#s2`PGW7KT diff --git a/build/antclick/data/037SYS_INFO_sUSRSchemaInfo.koi b/build/antclick/data/037SYS_INFO_sUSRSchemaInfo.koi deleted file mode 100644 index f947a15b9c8d9ac2825cfe387897405901ee7cde..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5664 zcmeHK-A)rh6h6Ccp)GW~t$&Drn;5T*Nzps63Mfepw8TOJS1eHsUI10OF(Gjup}v8) zdO`XKTyoh*;1T);dd|$5dUn!vLoXmP9n(4A`I$L?Gs6m}r{4j<`OO3IHH=(v4Nis2 zLNA`b7Z~2AdXe89E%yet{Hk~zSM}QbUsawHKa&bvWd-<=2$4GYd%}EH(_EzKR8P}F zU(@NXrm1tNEu0!s+TR85%Vzs+``!ND!EWR5!x7}$+wGl3bETy$$*&9U$M;BmC5cb2 z(#K^mb#hX}e@c}-+&$PsG-~lI%AIdmUAaEC`1osQ?8UjGaeT5Ys9(8@MjP$E+-H`(yHHsr!&k_}%d z!(kD!!V)!RTxj41`A-YK5L1pcGMdbEG@Z=4%2>dW_xMqj5 z$uCOLhbj7ciar>vS9PFZLXODfPc(-=qVr6j&Jn2Ml!rEK<8KEV(1aCek#LHI8}J&| z%swG1a5z*yUqP55%D6-##$JRky%|}7a{^BZJS}iu;DW$KfoBAs6}Tj@CvaI{U*L+s zRe^5^d{f|C0^b(+j=*yQ-xYXX;Clk!7x;m|4+VZiINo>F2deQF7uxhm_M7@a{A233 zORdeoBCNwY!D)Df{ar!9Cal7SS#S0`M-wAMIK)QA9j;uUfZupBOB`E~R&_MNGopvt zk6GiV&_f0K82i4Svjh9SCHV6~?azb(bw+{tALdY_LC8GkW8zkHZ zyl)uF@O>H>Kam1XEq)GSe%X{rxt5fV!zW1?6AYQBd}NIzCKKjOf4o4;OuQb&i#CQY z_ATDZ2a@_@`Sod2K6AJu{O!-^e1_j!Y5DM;l@RyGbDWk>`3!x_{Oo-C3H_m%X>eYC zKPjJt^Jf0ObgcdPteJY3*R>DBUp61VtD*$xGY!CTl}qLg2^iFoa!yJjF$qk4&rl)X ziMp}|NZUVf;Gh1}^yEjzBr%1+@m0ey+?^NeEO9odm)dtAG%qNft7O#ECE6>2j*l zm5!anAzkU0u5_i7&PP7_W4D$>fRJN%{QSLrwrd#UlhQGAttR!`oj_r28Kqx7?I z?4`y#C|{Ls(E~CB#{=4r7+h&e3Q-)T6* zdq;ZD!jm$+yb{7gPlL+&`}xbu2QXp%{kHd4%KN*AhDQg7&e=XhlNhnPUnWiF7oboK zPx3IC#d1&x%(akM5N~a3U0v7K+}YB)HKO9Pj0}m=-OWwO4!GcsyiNw0Oe@MBb-j!_ zlR?GVV?Hcnvdk#S9(RL`>sEYe_8T_xhoh3qSX}U;lX?SLR1#7cTnTb&NWtN}rZA%!FsMX~LX0Owe}?ODSqMshI$QcvGMbpkaXppedQXn)G4+~zbU9Q$I1|4b z6;d%ib47yCa7qPSc0FI!m8#BERihB9!VsWL6@DO8jR;km-y(FX^% z;s-&Fi1SvgOQsZWU**i&4)z1fOM$doI;?s6DQ9u5&xDpojb3l}&})M%QTYcxb;nwcKxbFY(~*=)+mmVemFlHjQU+et25iK|%z# zgYt`trmy>vqs7}jLS zJZMc8z6S3`=cl~wf_RvQRxOVhzPEYs?SzswC?3brMS-*|#Jq9ffNl=;%y|dZa|Pxx zx(Rt!dPGPzfs*V3=N!<#UCSn;=fxg+J_uUw7f)KX4;9zpUFg#C?9HzU;vl~+E&C0> zyFK{1+q0x>-9~}+c|h1Zv#)>WQ+?*g9xU7A4k&MZ&{h<}iYrlf==|`t?C%)9L9JJa z1z|7r#2O7g#kRM=NFvWAH9?et0d1c*r%P9n&J zoalmqV?E5%Bq2|mM8YaRtEx0FKYClPdHcxE1Xx+KXtv^njH>dn|2%jlp)Us`DQjMf zW5^DiAARLfF4c^ueT}g=AN$WkUpS%KB|5D2wS?^7kG}HYg)@|3`_{Z}qWZtUybglh zgU;-EO-SqVXJ2{fD+yK~gxAuj<`n}O(ijC{90Q^|qr}Q6T)^=lxmZe}2+dcA=T*$F zT(EFa)#4>LEnRl=E!DT)cKaQ7-gUQ%wv@{Mn0^4g2W2T7C@ZvFrsYa4*Hy!sKnhMG zju}y`>U66-sibrh5430E0&oVeK@T{c{=pX^5{@s(#WaYBP*HJ7X<4~<`UTDJ>-W}1 z?Uq#LPr`eFN{N2`{Hreif1LixYL`E%Z>01m)~XeoHD~0SO=RQV=BAd$)~#(1N8_=b zb?din+TW1acVNq|J@uP6?AX40-QgpT^mIRVwCmAB?H$R^gAx6_gqAUone<8Vv|d+r zX?;>$yboO>vM%Gg(%S6nP>v-hOh3AO`CQM=C;OW-Gj;H(Qgn!qTpXb^<0ZmW-n4!m zy2|(rU?x5-a}tf-%zM!NZ#;4Yu{+N#Mv-}r{ zl)7PNKajqk(vNem=(HW2h`|M@Z-b`)K9_#n^&h={Cfyj|u8(K+W1aT6$koTj{%afb zV>@6}(rMGz01lLYg-(Ah>H{35yO^){-Obk5Y8YP5@I4H#V0b0Ns~EnQ;rke_W%z!E zA7J=Fh93gbx-OAv(0B#fyT%(|GRIa{uq@U52(-qvIA_8Nw- z8oXo7;GHps8Mj?mOn9uz;CPtfDT8-kG`OyYVHRgk%7oWP7`|?B1AA}dunFHAW%xyd znD+lO|4U4Z}=VZQ~|9(Pi)f7XQFC6W;!e!N~~2EKUcD)4A8g zIS7#K~Lv6We0sH?yAa9i!82Tu!q7N>f8v_vIjJS)D>{^J`;6=G4lR3~`ZR0eT%Tr@R_{209yrd$55Qq> z38mw}0i7S-I6lSnv}@Vz?qPw)Lf8d&QlV3@QUrq^K^2ZKt1 zKi15!r-ovv4vE|i3lY!}ACd*(rS(Z~4Z>MywZ<6e8cobA}G-i~V*l`rO!?#w<3(z_Rb8c($Abh!FEW<23- zCk0_oeA6l!bEWtE_Snsl-UF0RKF(kxID2~`y_58^m$h-zR%BpMvv3=)Cmp-oJmq$=`PGt1qs^&yQWuc&S0Br_;&PjF)EX zIoE#;d~roR63;YxzKP$+di`I(e$ZV;z!bpXMpn740g~5BfK-V8YO;{+77&U#P2 zapIYey?4QVm@c``W;qt#5K{0Ow`Z~trfu6wdlOk5!crp^FSs)EXT$6+>vh@PvEE=d-13Cw;keRJUI_! z_*=EVw(N;7$vNVkwZ6O&ylI}((cdxpHuIcjog?RWGi>JUxqYP31I|m|G@g4z$CLXf z3~w{e&(7O(f1*tq(nuOyTAsc6Q$ME*;$k|p*85)kGyccX)@lrIKlLU3zs=F#H2N>V z{uP@XP>Lu1Y322_Bbs-1%omw-n0e>y`H*p(VxJ2pA1?dg@7~8E$JvIz&wVU*x+Z=k zy~?Y5--VplGCY0nW3gdM{HR~%#gpbO_JHm&Ua}fahNqdgF!qpTABzoBmEpvbczf}+ z(Ce&O09#unerZM9vz)~t4yGe#zl7`6*M1gzJrnPOw(o|&sTXKukzqHE4SV8CcH(6p zG#+xSV;Xxl^R$MyVoU$|ckOGj;Y&P;w-;ZU=X9(W8@^^e-tf(_uf>M3GHBvUvcSA^ z>~Fa-ylMR}q06V7S2X%I>+?q6KK8lTao2h-s{$@~fa|J(lg5u-H@JJu;GPJ>QwH~* zG`J6+p`X)-^_IrRVhmq1`1nPG``Nwym)U;!a|{nLJk0Rp4398;p5al3pJ4a`!%s4N zk>N`Wzk=acGW-<7uVVPs3_s0qis9EV{91-z$MEYJegngAWcW=CKf~~w8GZ}HZ)Nyx z48NV>cQE`;hWU5lo@L?hV))$*zlY)XGWUuXCm3{NurO@_b4@V6QM4#VGN_{40ik&G2s+{w>4P4F8Vd-!uFNhX2U$pBVl#!+&A;D#L$e_-_pVo#B5l z{7;7e#qhroJO2kK+X1MCeeLI`e(=oqqN?FWv+h4v-_$^QGyEo`&wJc|Kg7X)L{!Uq zC(lBETSGFMkY}@B)2kn|O7q&FW!%ZHpx@XS*SsdQ^x}1&=Ceu5Iw!9}e`7;3nviFc zzh3-k+!%v_az+Z*F4X=cS&sJ(T3 zJv;k9FZrJ=BkQomRW6Z|ve^AyYD({V9S`eBa3`kWg5x_LDqJM8zdGYr4mcn6nQ!$V z&8KLZ(x;zKe26*D`GOnh$;L;2m%{S16zb`4CO)w&d?GsL86^ksJ0BVK6YRSbZa$%z z{MT1VKQ2BeQ`!0CnPXa^>eKAA_|#<459OEE&tO$HKEeJs?B*lf-$^Kk81QQPE`a>L zI`h{?o!3u{IsF4QF8>v$|76VNp9Vj;VvL6_fgiKaQ{%jhsHf!qE(y-Pq0@Rlh53)` zvgBeKBr=xD>;yTNHLL*snn1&MSDR^2kghnE&M$(m$vc!H4U5e^EZTt(U*?-yrY?f#Zh&Z4zbB z7JS|(A8n9$jVspmt&Z zb&FW}@nU|)5F-WU2wcsCP=>}+94}1fCrlWHhDrNj3Ll%m35`MteN-HsMJDYxTQO5Y zH05K3;{7qxK;)DggHSs8@!8o!q+<(E?oJo-vxV8B5#66du2IYf1#B)VjXefFm?=!p z@px0y&}u(`jBA2MH8C|>y!XjrMs=Fze2$Nb$14^NI4qGf-#@^NcET6Z))KpiznO@g z!D8wBz5Kr+o zfvCA7Zn73LEclqY-w^MoE$+Cv{V;F8cOfUtUB1V=>{+xO<{r1zLCFQ$X>LEl+v|(5 z%iQ6PIwXJLB?CP&>a-7td2hDLy7%cN2;j}9wxm+~^b|~Jwtmw4^b#~ME|!ea6(Hck z`43ja>HK`)Utq|yj~4t%TpzEa{O5H{>gaQdI5iQ}5ogBBmz`b7?o=9YOEJPI8j`KGN@!?k6qwd&Y?c%?HzSNY(~Abk z3D8ltz^d%=9`iAjK7xkUSJ-+O>r-r=Jz<;dS5UPKe-+lxR@pjxjIp2|h4QiLVB5Te zoyht2sjq$e^pClpU_^*#U2KD`0D+J=NTVuS zK~5QpqfGLTEnt*BY}*T5t3a44TLO(tbbx=4;5(F;GJlKs&=wAt;Mo>@J|K<1QPKYq z=_%5GBK>F5e%pgiQBo!PM*{3k{RknfI87mYlKEp^C4v7VXU=jxl1EOF)D5%4D zah=*p9?1RWA(j7>be*(3|NlY$m-x^a;gMGG*nlZr2Si{$0%SHZ&yZ>zo8CiWBk_>< zw1vwh%I{D-i8tYiK;_9^o&+isERJN&KsFvvo;4`4wiW)LqxLsQi=V&# z{_sO8cS+|-<7+mIe;4!Wpu7^m^a^l(3C>}D3hyaUa*JZmAxuV&SB`%dDo|uO>acZu zn%Z9`eT(!UY4MAju~G8nz9-lHeH=|E@D4iqT)=Dd6Zt(44UK9Zm9 zSzY#4z8Wq$ZRkrb>|S}A$SeEto|qqLLPC2Ajb&i#zq;oD`5{|nM{h_>_ZHh1H1%$GVm;Bqx$CbJ za`pc98g}yE=h$`4-`4zH&2I$#9$WKsnqSiVHO;SU{BH=Nl|Sqqcw32=hJ5F@(U;fQ|7~Yp!ocKtLkg{+FHKHhTj_A z*K?RW2;>qF+ApqQMPR?6R^fOzf4?msqU}dvcynI726(@-MF1G^zP@%~yn}P7$EP`b z7w5ADe(QL1oix^LYgP*74>%Qt`)qQ}s)lzoz+h&EMAiUCnO< zebagQ9=1b)u>^$peRBsYn)5rzU)i}V47i^J>(v<8?{7{7JAInUtH za{uT54_5s;j8XNsHGfz08$sX1@9$zi6o}15!@GYADpYQ|)Xs@_!@t%u(R9R$B@@l? zKGyu!@#ef!@vTFis=uxIh?`p92>K?x2V7`}0)4q8NYi@H*-+6G?*#k+O?d|>=b`Zq{{Pa$o8XrF>p;zfx3)jaeq~`C_x(GJ-#Xr$mn!~k^4r>N z4e!Cmf${d&3{C-r3CJrxFAt0Npw9P($WfjLd-s#p@E$6+hqs0Ej*qtSi<{z0wXuZo zzEp<_XnWN6@38yHQR6-2Ku(Z~32$qyHN1y+AxP8x+pwQFHFz-Mt;NR}%6Q(V`Hl(u%i8o@?5w^Cd(9JtSBn_Ores>gORCKgFsk6$*%=l8d)et~l^7>ElW854bJ zYxk9r9aDU9U-4d;%L|Kx!9ZO2$e8G>Hu{AB9mf=3TTgP$IoKJb1Rph~YGXaM&$?QC ItW%}*Uwc*73jhEB diff --git a/build/antclick/data/053APP_AV_POLL.koi b/build/antclick/data/053APP_AV_POLL.koi deleted file mode 100644 index 309a06978664089a5ed4e3bfc57c393eda514c9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7000 zcmeHLy;D;`5WkmzAdmzJXu#(E0m=kFqm>9@=FNm8lEB2m2>~e>Wf(t-jN^ey5bOej0)26OexU z1QumWCTbr4D6J=5$Y?#5iLyWLaUECU!*Q>Bw%%C={>2QKOJWtY1)rM+<1V3DQ1RJvSzTG*-kRQ8f3m$f{kZY6vDSF8F}>1w zzS&rNx>4DDwJ{H!RRjy0Pd8xxu=art>driXQ4=XV?n)m##o#l98|L+%d;K~Ke>5~q z^B3wBr<#Y3QO}0yNFPJwqv})(VJ=3%9Y#mT#&gZXNRW#M%lS&xDHXw@ClEuxdP6>f z$!IT5rBp09#lTo#@(=KiDWUgZP%JtnbA?hRPiggRJk5OcVK81l=aVEpFJ$E>MEpq_mr*{A@LU6hCS5vru2I-8iV`XYB*$Fx|QcNQKVC8lv6 z6S;HphYSi+7hi=2Bvyk4&zhynYPZOA#aJpaTPzi?&Xo$wi^aQHG8~{#sE91pf4|^V zs?ZM}e6};xB?=}MZhwvJ{lyUvH@~h|q)=EP^o7s3!Dg^S-yc2$?=(w^1AZ>t{ubHy z9_E4YDYt1#z`-31pMzJZr9uwr`S5vn*jl~=Ipmv@<3h4YQfx-JB=X_TaOb zPuQc&b+2Ht?@a#J48-h~rfzF>S$-cd{VF^1F-E_?wA~cmQ$dn#QE$8)aL(Xf!}}Q} z`4$?EKM4F);BS7M8WdO;;jaG_#>f1pngZ_#+!nYaa2GI&ORZ8iXz<@7CZDk&{%Gut zX9M!X$4B=cx4wsr%Ye*&SYJZyO+427i1Aj$_-e%Xy@+u;V%+c=%Lsxdes5pA-@9bR z_CHaB9)^>r{P1)nJX z$y0LQ07We}s9j+CP}$}gb>MhQ8@O7H*R-Y0Pf3jH^6{p? zI|8=_?g-okjN($O^8o&PMAXkjjajgG=w4y?sQkxsunzNg((fxTPZvY@)4jst{oVX0 zWImcAKRW`q1?~vk1&rcSd*J=QR5SLd7+!n{l)Qem-G*sV*2kY5p0Rk3;isY09p6 pf13Y!dG|ln#b3;SQs(2R`!D!sYLKQ=#D5C&f#SAEsnGA&zW^yz8e0GW diff --git a/build/antclick/data/056APP_AV_TEXT.koi b/build/antclick/data/056APP_AV_TEXT.koi deleted file mode 100644 index f469ec8a48f4dd7876ac0f5b74b21ab3f90ed26f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10440 zcmeHL%}*Og6ki)09KIcl5<*K>k(Kz+BGXUWo54n232e(=5;#;qQY51$3jH{sDpGy) zk>2trxIIK1^C$SoF~=T#(@4gXyDt%V_tFABNP8?tLIBxcTy)z*C*x3Xg zfooo3d>uFhGwKXvpKSQ~HQ(vWmdnm(&tJWqefj*S zS39#mZvD3PZ0pzU*(Y1S>})-Iv0dHyeLDw>K7ys47u#T;6h6?whL-~{E_Vu#9qNat zC|rYBTD5xX_3I4$kZ6ePmo}=NpNEBUrK54Hk2v|rW!FO-48uC^Ep!uuQK-j(&HE<7v)OHFZt``uu#-al40pc$aD~^`lU)(OxC2_(LI&3m3+~MO@B~+WqLe+ zIWR66OXLqqPH>rT({At%&jyRe*J2rM;3W%V;byD4O=Ij_37TCIAeVijK2RqNCE5_?*# z_f`U91K&Tu)rT2JqQKy$$0qi)w6R*vS2oC9sRAlpdxAA1};xPpehVC3Kv4I_RLiN8OeSJ9hg)4ta z%H|;M4_E(+)VqgnEZpR4G6@{8x5BNyA*q*T zC%v1^9Ewf|m_>;mZxekGHhAvzuoNv}PML`w`l2biM@mw&fxZ#*0eIAn|2+3Mu81Li zGRAT3hOTP{qHbM;?h1DQz2Kd@Tz4|Ve?{s4IYRPit)pQ+Wa@-t^?*Ku?-YLhktS+z z(=q;CqvIySEr#1BPR1EdGhAS}#&Cn-Cc`a;+a{ijGn{6)z;KP>2E$E;TMV}WrB?S?E({J8dJJQX+b{dWu>n|ONO#K|$jtBl7$_z&t6^@=f1m4WG9j*Y$j;zIR+mGUSt!szaDueJ@E4#&k|}C$0p@ z1N?LQnLVkm7}_DZa0S|<5XglqP+kWCh~)1DE}jELps#-anqlYjy#2(__w*XPRD0hi z>^#oAG37JwP5j`ViIZ3Md_x=<3f6GhAS} zVd6=Sn@rwfxD6PWWS*_{*bn%7McY4}OATMQdQ8?ZnJ4q%W7R{=Fzcd%?fL*R7vY4Kp99rimZToA`0t z#FL0|$$GvuJ-wc+9_ctbyQzoj$FtTWomP3SiwBqWzgTq~S3V%u>mirVFRu$vLH|!y J@A#O!{y(L$gP{Nb diff --git a/build/antclick/data/062SYS_INFO_sUSRSequenceInfo.koi b/build/antclick/data/062SYS_INFO_sUSRSequenceInfo.koi new file mode 100644 index 0000000000000000000000000000000000000000..9a1b1043305865ebe810be1ed01b8cfbc304d86c GIT binary patch literal 12600 zcmeHNOHdp~60IKozhU?f!>@rE7=B`qtTndR_8=@IR(xhPz#@Cs8d=6hVGALUZ7ISL z+eaVSn~xl|dvN%u;~aI=QAZtpsZ%cB^}4K#K70hDtGAufDG`vofo?k@)48 ze+VJ0f9nMJcStq%??B2Z8-6AEDOZgNhsyq3wP)u2^>C)Re8fRmDe4qyzH}}dRQ6AasG&i9d72Y=XdUZx3hP9XL;|d zd!jynBY$&wZE0Qht(LtacfN!?CTqNph-~-PiP|53%)md{RC{=PcjxXcz(K>Cq2BsC z*n!W$hga|2y1R4c!4DqohYc>XaJe3-Cqyschx)RZc3#z-5U4Fnv@EQxugxs3uWYWa zy{}ZQ6ljT>ODoIy4d~_XHYclGWktffo|j!oF;(FmFQ|@M3DvA4G|2QqWf8mn{@lL+ zqf#(+tE|aU`M_h9zkU91Yrr}=-TEW8qXyU%DQmnF*t(c${%1tq>r{F6skfUcp))|T z9IL9PuA#B1CE6NmYwzgn>WTLz`uYb3hwR~z(PU~&^&5EzPB$d#MPA&1-%YVB*2I!n zZ-?e)aVR#S^18^0TYwM658|FU5MRcTK#dpsI=5M!u96waXYO6R5iqqENdA!aY?*eW zKks-e=BNt2&Q7f#xqehN%8}6dyHYR|y{ta2i5>9>l(i?m68D%sEC)tIvW|?W3o#BA zFpPyf zc=~4-cVe8i}+nBj&|5bVlrA zEddVRZx!)*_IGs!@|EIqU_p=`s;o29-Ps zCcbQfAKel6#djd(t3D-X(tN}#^@j~XcKiU9RvRkk>3AJvG4l2mWJ&QNM1D+BmGu>% z!VZ?V#mKuTc0tnH;+rsO4PQm_zK8PGhst{zCnJH ze-!zreDah3=0Nflu_EQ;`@5v{r;~pHCvOgwzs<=1hWS16&xXjq1@do*%ToR&d2iSO z8+;8mFR1~tJLP5V9}Sh?wf|}OHSt4GEu?6Hg|yVzh&|Y!h|7=%jWW)(hVr{{CJ(-j z9*-XIrs7-d4e>fCrinMLIaM@%pVDO=&!Z*cTg>dYPe9HG@cROOhamSB&U92;U#|@ zR`tEdu#k}ZhRe4pz3>38n0O9;kJ}p8kBQ`>oa!+Tl&`x2`6}RZkQ`DFUrg7haG?`E z|Et&jw=7lxUC}2DMwtV7vh2YLgLkV3LDIVZ=fKpMg81ovArG&3sJtB}-jTd`vX$d^ zBrWN^rwGSMtg|lJR@E{z&^u~%G_>|L)%0`?t8P6-SYXKgxxw&X0oiW>^8;>K4-fH` zly?q?Cqm_|jL-4#PR^^MQnv6b6@oD+Y_ly$v16T{ipPnL6v$FgS!O97omX%v`xP$R)%OkJ6*bkE< zpB3!i!BBbK{ksIW@jdA?cjOLUg56Yxzm&eozO%UWNuPaNwEwPxeOJXLcwUDS^eWto za#B+8ATBZSP!2kh33J*{_^?vG#c{7r_+bt=Axnzt0+hq&BS zC||45BfZaU$ou2h@D>lZEw8MaFH#Rv5+^Q!Fy)O{Da5%aP+?1`9$Agk=Do=ODN%Ju zJ2JP9z5B=T)aiMKRX%D1Plv9(j-c*mxl24mZo>jszkh`?_pIv`4}2(m?{^dcj~YGXdL5uFW9-L#+$g1 zQ6KpNv@bi39qIlVM}Ze1d@#LC{VE&B^#PwrS&cFQOlk?LLz?CZ-HoyP9w!D8U;iK(|cw>q0AY)H~WT`mT(7DYVS@pWa_6dz5o`ocefslQxKnyd-8AYSg&I%+0XB<{&+t5 z9L6wv$m

PhG`HU$uAdv8A!1Ad)x3fKM%ERzG%T)mh-T7zkdttkBR2T zT+1lmWw9*J={a9Kp>rDlM+$s1KtH270E&WxPhk}U;&I^o7eeOe_kaM~NfvmJy~@S^ zm>MvH@gMfDNm-4;`xGlz8V{@@%!8?vKJb4U==TSaQQc)62R@Ssr*utH<+B+7ZPUwr4>0jS zP9ARXa(u+A*EfstKaekgg5p7te5ik#8<+3XfBK1PCwuzi!MWeO?f&>byN#1V+IM7T O37`MS+W-HDCH?~o+=)5> literal 0 HcmV?d00001 diff --git a/build/antclick/data/063SYS_INFO_sUSRSequence.koi b/build/antclick/data/063SYS_INFO_sUSRSequence.koi new file mode 100644 index 0000000000000000000000000000000000000000..ea3478722f072547406dcce3561ff13835c55490 GIT binary patch literal 3952 zcmeHJO=`kG6rQ9;V^#17xj-TIpKeN9C6^W^JM1zeVL#4J`%}z{7eWDez<_W29cCCZ0gxE({}H_YRxvy zjaI!+ynbAPxB|;pfWIW_pamGG+^05(G(<&G?@VV#Os6YM|2fwgLOcdd*Az+Csp{9d z)#+QdX%Sh!)oVrVvWz$x5lP4D)EakS=P~M^M8x=GBsmzU@Wa%0({OsV2cy}yz>l;< zx?!7Lt7X}}s4K{=hP~7gklj@Y;f2CWp=Mu2{9n%e%mqWlRt_Sj>N{S$J`t$lCijdwitV($V?4-E3Y-+S|B<~Q%Xo!w2~)vI3t z!1|jT;t$ZGxeu_YwqznJm29gs4%v4~?_SyHQ{Yt-zz*PkP{}JFrVi%=_ zzXJZKjY$!;rHs9kGO-}#z|};m*hdP_!*bFRoSAJ}p+t_0_ezbHXGO zU_ta=xm4Rglj$}uOe)wRZ^xU$(G6_a+x3=kZ3i*p?Ri^x>H&*t&e+NOM;Xe+pU(eI z2C`xsl_FJ;^6GlI5wKd9JAcsGLpfUx&8ZXGm?_8lT-iwD{)b12OIn?-^G^qDc)om3Rov>7UASur&fR7QAeuw2omH^$+DX76V{x)C< zR$&LK@IYRvGtQkmP=YmBhKd|<40Y^S7rqU6j-5wv0FP@!SK;nyzCY`IvJ0{e_Ou6=Yt!*5+YX1n-WPQ!0pe0|r&;|LXpamU3I1r7g& zPh{1`G<;3N*EKw@;Ry|AH9V=|DGg6+ct*ps8vaPbHwbsuo5%z4<-D|Oy=R?-y4A_D zk2)dWo^=9L8`Qeh?@r)49VS{H8R*+$_XB5+ImPKeHzlZR>2S*22q2@b|(Qa|9 zAva>U3X6Tmv4-r3<00&MaMbyo#d852DZWLPBHuCMIe}~zF~=4BZ6mviIE!}BlPq+O ztz$nOR~zX0ISmP;p$b)kDTJG1h9ZtwLjM|+apZlwMD!J{qy?5 z;1y?HB~iEc4Q7&%;&oR2-9=Z*_Y%u};+LSsvcBqX9_9>&X=b=8?yY-xUB?<+!8lfF z4Xp+hKL^d!y49b_Q^YYDgy+1$Q)Re{^;d?n!HxJhbiw9`s}FvuApCB6@T=hoig)`3 z@e}8DItag820wKN%eSj;XN-!Ql6~iQClUVrj6c2Fi%D=_f6&&SM?*y*>E^{m>`E?&tpA zF39?>T}M+4s1#pHZs%_*APp*$^a`lr36Y&>~>Ns zYi%Eoa%%WW&z+<6C&#?hNp-ef9hiw|tN%nQ0v-5wGpH>7*B{Gr@9=`^y2k^RuF>v%u z21jXV29^DXf*t(ovZ!6#sqZp};5|Jy8qpJP(y$aC)6dA^Rt^E#H1CT934+W1D9;SSN0EsTYaU&1%sT*27~ delta 14 Vcmcbhd_j4GJ}aa0W&_p*JOC${1cLwo diff --git a/build/antclick/data/036SYS_INFO_sUSRForeignColumns.koi b/build/antclick/data/070SYS_INFO_sUSRForeignColumns.koi similarity index 59% rename from build/antclick/data/036SYS_INFO_sUSRForeignColumns.koi rename to build/antclick/data/070SYS_INFO_sUSRForeignColumns.koi index 012a4fb47cafe13d814cde8fcab199a399096f05..a920b5ee1828211f6cf7eef8007bbb8e97e6c314 100644 GIT binary patch delta 329 zcmdm>-J!BUfN`<|Bb$`q4hAsbyYU|iAbj2vlMNV8Y!+Y=V4j@7C^1=qm7mdVvjOXQ z7DkVWg5s0Kxe6yc@Uycj0F^UN6cnC(o{wYmdaeUZj0uwqc>O2JaR3Nh~Ocvnl zXWTJ)0iQi%#pDNk>OeAp%L1rbpRr?d0e`w+1;_{n1{R3L4E!FG6Sy=c3kc{lMoe}P z2sgZeD$j?Z9#vjIVsZhO#N-D+{XkO$!vj~K$`jU)s$Sp)kPiX{4Pc5PVDbbm@reos Gi~#^bm^_sL delta 322 zcmeBB*`U2afN^pHBgbR`Mm8b73;&^j0StH#Og3OV0hD5A+^{*2QGt1~0xLhG%4P%B z^DK-G69vU5i*prnG(Z$Dn7n~Ye)D>+15A^}c{L}`;8kagn0$iQpYg(E3BG>D4U<>! z*)tYQe!-^>Bn9}>85<^7@TUtF0Ch7mFt9)jVc>U|{DD85F<`QXK)B%rR5?BjwW#s} z0+TNYxHBqDmJkdNT!1P^STCx2fd@c72oyAcDHevw2L#!U@vB3VE_QP CI6kZZ diff --git a/build/antclick/data/071SYS_INFO_sUSRSchemaInfo.koi b/build/antclick/data/071SYS_INFO_sUSRSchemaInfo.koi new file mode 100644 index 0000000000000000000000000000000000000000..712b8277c2248b961db15d30fe9304b2dd419b6d GIT binary patch literal 4536 zcmeHJ%}!HM5T1McLn*Yq;2+`-H*sl9if)Lj0*cl^ODrU?qC{(O0aRt735oX+aOWea z3(}>Jz>=j)9)UN|nKNhV+!L;qZb(Q^bI*M9b7s!WoO^EJ@bC)&c)#sHd;ud9UO-S2 zQu1~w@27Yqa^?#^g%`^5JP1Fag9;2PaCs`g?>97&diXrEe41${Vw&wR9X@6{bilOd z+++){jFkNQQ2emkc-eTh)!N>y?!4KBTw}elQLQc1jU~nP!GHT2X<#Jr$v67A46^(C zW&9acdS`RHh3KrsqbT=2WAF6(*y6oU?YNZ*Tj4tj-&J^uaJ=uP4^-ndTWIN%?l<*=_p9E1*wjqF`3x?7Qdmwe)C8S6*B{bN%vmF1~#8y z%i1USmwFV*4sH6r$11$uM*Ewa#I^a9KBC~vd_4H)Jx=+EFAAbD@lJo;d`dICrkmff z!=I899JX$z&N_x*p*CLd90ljfCo*B6?VMM8r^^1!IYif8-sz8iW}GM}Jb67QCkIG?fr0zRVDd3Ofz8kOelY<6@@5mT delta 78 zcmaE${6KkwJ}aZzW&_q}7Cs{e28MtJAOQpk|0i$c5u3c8lamp`I?tKIXt>#iD~1^; baFIuL^EO@q#>vyg_+`J}aZ=W&_p+9snf#1W5n@ delta 14 Vcmdm>yg_+`J}aa8W&_p+9sndT1SbFh diff --git a/build/antclick/data/040SYS_INFO_sUSRUserPriv.koi b/build/antclick/data/074SYS_INFO_sUSRUserPriv.koi similarity index 98% rename from build/antclick/data/040SYS_INFO_sUSRUserPriv.koi rename to build/antclick/data/074SYS_INFO_sUSRUserPriv.koi index c707064766ab8c85c5ce342f75e6bd60635af64d..e2eb5d27d10b8e9b90b28d8f1f1d36f79f4267bc 100644 GIT binary patch delta 14 VcmaE%{6cwyJ}aZwW&_q8JOC>q1o8j? delta 14 VcmaE%{6cwyJ}aZfW&_q8JOCjBK0b7zJ4vy*C@MW^iyYfPrAc<^{aZnK=*qhl0r$+1E23 F007^|6-fX9 delta 55 zcmX@0azS~60OMo_Mm8qFhRqU;;w+4sn+;eqI5_@8!R7_L&zU&`VBCp<_KX1lWEvVg diff --git a/build/antclick/data/076SYS_INFO_sUSRGrant.koi b/build/antclick/data/076SYS_INFO_sUSRGrant.koi new file mode 100644 index 0000000000000000000000000000000000000000..64d56c2b64038d2f1854dcd74edc3fce33e031ae GIT binary patch literal 18248 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 HUs(AccDnXm literal 0 HcmV?d00001 diff --git a/build/antclick/data/043SYS_INFO_sUSRService.koi b/build/antclick/data/077SYS_INFO_sUSRService.koi similarity index 91% rename from build/antclick/data/043SYS_INFO_sUSRService.koi rename to build/antclick/data/077SYS_INFO_sUSRService.koi index c0b2d938f0c01e802349d1eef980452947b01363..402acdcdd0155d6cb71db00ad6a478ded628c58d 100644 GIT binary patch delta 53 xcmbOrJwbYdJ}aZ|W&_p(ERzGc)fo>=HeeT@%+JNaxB$*-fU;yZcXP2a0|1Af4Nw38 delta 60 zcmbOrJwbYdJ}aa4W&_p(EF29CVDMnF0lWC*d@h;E+*~}24qzTX7sq6GP6@__$sf4X KH&5sK$piqtvJZ^_ diff --git a/build/antclick/data/044SYS_INFO_sUSRFunctionFactory.koi b/build/antclick/data/078SYS_INFO_sUSRFunctionFactory.koi similarity index 91% rename from build/antclick/data/044SYS_INFO_sUSRFunctionFactory.koi rename to build/antclick/data/078SYS_INFO_sUSRFunctionFactory.koi index 217a1457f279e0f899e8e8a018c21b703c51a655..74ef42433b71fc4947cfda02ab7979f322493412 100644 GIT binary patch delta 53 xcmdlWy+L||J}aZ&W&_p-ERzek)fo>=c3>Butk1>4xB$*-fU;yZujXQ91^}uH4uJpw delta 62 zcmdlWy+L||J}aZnW&_p-EF29CVDMnF1H1U-elD5G+FU%04q%=>7YCyPh{f12S%6!8 J^LDPEOaSrp55@oh diff --git a/build/antclick/data/079SYS_INFO_sUSRFunction.koi b/build/antclick/data/079SYS_INFO_sUSRFunction.koi new file mode 100644 index 0000000000000000000000000000000000000000..b5843af63e3eecc97bdabb161677a5a4f587c3e1 GIT binary patch literal 6248 zcmeHLzjG5u6n=MD@)4aZS+N!8C)dT90mdef@ubKIJaOU#%M7w-Ol5?u!AxS==m#Ta zn2E}iN#{~!l7d<#C4YiSN>{1rlJD*Ao!>2J9Loq&=t;Zpd+&X_`}XbnPC!qe{!T>B zKSqGxfh2-=u&7uveHiY4kk;hfoYvX@$j=`Qns4kMS72O$|9=I{L*g#9gSKvL#*jou zDVl6+otoF$JJR~Z{;p;?FQIu(m;AGn#iR%t%iuaQ@}Q`%lFuIP0q6(iZG>{j>6 zz*#g~d^nt6P*@pAK6$c$4_q!y)XIBRpy38LA0G@o*!y|EQdZjbzMWaHrbwNyl#h5udt4>FdSy;-%&Fo11IJuNRc-_#!xz zxN&o}v;ntGT~w~{(A~krE1GC(du}lCOGT82IWd@gRgtZOOAO{;Q~cN=B?q&=(y538 znG|FMji@>UyMgy`@hB>Q=YZ;n zRe*P>12gPu?rE)hoW+DOQyze@ z{W;5Cvg|F(Zd>-DW%n$*4;$hZI;;paQZlurb<_t2b)k`8BoaqXqLhaKzG-{?C6M3` z_v`aI(r#O}J-%nf`>byqSwa9`JAYLd_(z_9xUVp$ zz<{pSnU}_9CGt`CO4^6U9IN!I%`#me(hs_ezKm3KQ-BBMH)P=@+kw_dl ziKg2K;CoX2?ff&G55`63bK3l0oHBpTS*({?irZ(+KYQBzg8})!;6x!^>wRNAZ`8dK z`+3v(Pj4XyF~8qeSsmY>X9MyNI-1zE;#U6IUVQ#h=O6z63_a87Iln^tY*#o zFme?PdQ*}q!$ W5o{LoK6E1`QDH4`8NF(_xflXW+cS z$iToqIflz;G6%Q9V$pu^%5R^y)@fldDXR?zP@$8L&5>msFXe>?> z$yArf0wJn@OfO{4HtAB#_KwQTrGxB&9(4Pq4UE`H2)A-DFiH(1X~EH?iSZ|yudk-D=$U=)3^Dx2CGw4*10ZVw-q_60FiVPF6N diff --git a/build/antclick/data/047SYS_INFO_sUSRLabel.koi b/build/antclick/data/081SYS_INFO_sUSRLabel.koi similarity index 84% rename from build/antclick/data/047SYS_INFO_sUSRLabel.koi rename to build/antclick/data/081SYS_INFO_sUSRLabel.koi index 6eaa3a7b29cbe17de0441d868ee1e58bfe054f14..05a0bf1a3a2f9efea83e3361961239fbf24882fb 100644 GIT binary patch delta 98 zcmZpW-XOiffpM|{BgbS1Mm8qS4VwcQ&ofV!XBA)!+-$(w!NS1+20R6m4{!!dF5p&Y nJTN(cU3{`W7YE}4II985lG(hP>kQ-M?VKW;bJ&#`nHU`a+m9I` delta 102 zcmdlW-5|ZefpM||D;pP20RtFtZrB{ic%FH(JgWes{$>N#4wlIkJi?PtbGmXgKvX=K x9KbFT^Y9N zSallXN+{oVZ6|&iVKpj#t%O4WwEqIv?jJV+c7T-4BfY3^9~TRiGyNcguE~WENFrCr z8)b0AY5{5%U4HY$XyT4XWQ|^nChj6J&{Qd!y@%{c0~68IeWdb5PH|)idV+NWQ`F?U z>?`#_8&SOY(vPF1-{G&`ps4k|{c92TLSx6vC@&)Z5B6}HzE#u2_YWXQ-&bE`FaS#o zr^g}u5yXlb!gO73zH%PIoe+Ks;Wxlk1~?L;f#&ze+~}va2G5_2_u*jhJy0Y1jnUQc IUn(G~-{g3|ssI20 literal 0 HcmV?d00001 diff --git a/build/antclick/data/048APP_AV_ACCESSLOG.koi b/build/antclick/data/083APP_AV_ACCESSLOG.koi similarity index 61% rename from build/antclick/data/048APP_AV_ACCESSLOG.koi rename to build/antclick/data/083APP_AV_ACCESSLOG.koi index 4cd25df2ef2a44592e5b1170bb7cc93a73ef7c3e..ef2833f958b61bb49498aeea649672ab8c41873f 100644 GIT binary patch delta 473 zcmZvWF;2rk6h!@PoW#V=?%IW^u+t<36rrKT+`tHl+BBww3LzTO(HiCeY)1!)d;xb* z<_NBUBT%w73UXGAw5xfe(f_~NtM(<~fMUedGlf)k2L<(MfhAqFVUUzd$}Ge-qtkL` z7d_N$iq9c4dGa7anmzIf4&7U%-VrXn0j;ob!qzR;&MAymYD4CQYVx{~DmTTGH^AF4 zG>JE}KD-;exDNU}QeNPB#Bk=GZ*a~ya`!~bVqCk&xc8$wKT-S0Ft&d88h)nnTw|$m zrE$HFwIV_MFEhx1T8*T9kh>c_EBc#*H32tHORo2WfV|`YZ z@&pb~VXG%UB4figx8LpU?sw+U9B46AW%3P#NT5Wy8s^Rn(%?d5=n0qQ*8+2;p~kOb zu!T(QK$RlV9d}Db8M?NM4?m%LKI9lrHMdIrr4cG9kaL?vfsq&EJ#b0ftZ08lyGx3f z;CQH{O{#e2cc+4r%6tfOOltQ;eH+|a+(kXx6yq_B@EJ*z!%N(9Yaz0+ViRp{357~H zz?-iS2Ptue4yQ`lT;Vv|^LQtkuFn#2J;fEDdgjl!nq)hzyQS7&|8r|}!V_DW2=mZ5 x!!s)(vCnFwT4IfBKEl*@aV}Gm&c++>v0mS-p4s^aI-eb+$0IK!OuRcH{SDgcbTt3~ diff --git a/build/antclick/data/049APP_AV_CHOICE.koi b/build/antclick/data/084APP_AV_CHOICE.koi similarity index 66% rename from build/antclick/data/049APP_AV_CHOICE.koi rename to build/antclick/data/084APP_AV_CHOICE.koi index b9951a30e6c31bd838727d97037ea50223ff8a94..f0c2021fa4a7f94994a0cff774cda2afeedaaccd 100644 GIT binary patch delta 306 zcmdm>xP+=VDmvn2jV?M9L_H=*_=my@-rTR$!gq=K)wP{CkMZr72gJ+GZ+~dSRl?} z;Jbjv|A5Np7l0~kn7n~cZL%BCz-K&yliPXah4>UumGU`EzQL4mB*Pmr}8%8(YIf$9_U4U_$&s^9cPmA`S*zwwTZiHgHPkXuhHPxp|}M9&$Q$XHAnP z3yR=Q4)G)m*YhedNmeosYQJ~Dhq%Q`_F(jolSLUCETSF}7U7X&A$2<~#8q_Rt224S zsYR?$1lz_jRXEk)MaB438kh3i=lxzE)~;rNcV)TCaV@8K5SEr$i_{0MRoYj%UyHGQ zH#}5_vuIo$$Ij-O@aW$be_3ZL#l1{?EXK+b`^VVV*|vg}<%V$o!>?wpUy1YX2je$c Ak^lez diff --git a/build/antclick/data/050APP_AV_FILE.koi b/build/antclick/data/085APP_AV_FILE.koi similarity index 50% rename from build/antclick/data/050APP_AV_FILE.koi rename to build/antclick/data/085APP_AV_FILE.koi index 05a0ae9344a1673f15265cff138d8cf018af2a01..9e02d65c6ecb0d0da65ee3d4f15f2b73a7f122d1 100644 GIT binary patch literal 7568 zcmeHKOH&g;5Z(Bn~WbZ-`CclVRyIPNz|aDN6g5<*Mf0m1QueMEgLO$yYp7Bh2{r!Fg`W5(dDGxxy(uRKsT`57uIM z6vI+bU95!VT39OfDv2zE`vGr&K!->@nG89q1W#6iYHhJt1BDZvj_|Ws339cd1_d_w zc@FynBAVXuOj11g`bssZ)X80`V(?`xl8C8LS_<<|PZQIW8WXt-gA)b?sSwe8!d>bk zEZDQI7|+9D6_e*W>0Gf?yt!CfUMUnGWl3?E!l7YwouS9eVHHmeJZQS}w8aK5W!Aq% z`udO!nALBKCsHWNKn9+HirvBxyK^Xh5Oi{tLm#pA~qiE}r#?1W+oVTt}j?vK2l|B5?&IB~B}|7!(O zzRVnXk6(VLE6+}RNzwm(LVr3I{D&2L8YzK``vZ*cbfk<2i;Bf89LdW}-eS1T@E*e* zh7%oo9>ZCN%M7;|ZUaV2B4TcAm@8k(>6-<0Nd0K(${QB@1&iFb$erWm&Vfa~Z;{6q zd1R3{Eb;}5-0v-SV_E71_%Z#M?g;r|e`XmjGu&dh&F~(>9flJf|GItzzev)*0CH94 zjpuvb2OUN3vG^w=U7l$(%=9xICQo$yx8*w->+xsKI$vMJ1FKHHgjwLc-*ruaP!CC- zj{tI2`r)+w!s~Y-hG!`L|Mh<1`Ce?Z{AK;S@1MVYK5Y3;cJ%!Jw|uAe_53gG>3BNQ zvDad_4HzjA?5yXP_cK3VTfSZy@=)Ff)_i@TFS9>lxQ~Q&QQv=QfxGi{En+xkc%R_| z9nSz%nMgnj?8e1G@*`?TlJ`~3>`x6%)nW0CG* rzxzTicaIqEBl&Qt=Z||xKCOK@*5S9*C!zwoE!K~;+h2Zl1>Dwmn!GJu literal 8192 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 delta 749 zcmbtREmOll5X~O6p_zQ#B^^>lQ`12(Oaz|bz|huEN&f-G;W!17mS<2*9g>^r41)xR zj6~L9`w!sKv>h4*!?0%G-oE#C?@sQjoe>SAGPBztijYv*@)Bbfe1Z3&{fvDus-Z(BrCYQM+%9BXZvzshPhayDFH!UVV=K*DpFcA^@j#*JTy(-aj zLK+~kLYz4p)L)|Z62(izXXr-rrVCU_b0@vBbi#$Nmq5DrjLF+-(=z76IM;_Ex}JwC z!SUpt!>raTi*|rVJ7i*j3sG-OwJRCMdTws;m(^M*yt}PTZW-yf3vM#~09qgasxSEA z!%fh&Yn1AZapKmn6&&Hgt~0&0Haz&NVS(>+Jc~mN91~q%n@%#*PJ#6EmW3?~e4nrO q{R!U0KCXG4`EfSjvLN{XfYpJ4(sdR}&JwA`U(8Bld~DqjBlQIXSc&TZ diff --git a/build/antclick/data/088APP_AV_POLL.koi b/build/antclick/data/088APP_AV_POLL.koi new file mode 100644 index 0000000000000000000000000000000000000000..1beee8146d218a4cdd3fb772eb335e77b1164914 GIT binary patch literal 7224 zcmeHLOH&g;5Z=uLA|Vd}A>Q@}C>4C7CnF?PTNSdAEEFEBBw!9Hq40H}EUL_rBi?fK zs2(`y=+U2$;~xD9DKFYRk1*-%xRaBplU7yNQ+3}u}=|r3c;Ab^yTW<{(ctzm?+Nd3)PBg z=V2i&brkOFV}kjxO}psjViMe8bnFnMYc-4nbMa&?U$ITA1R6tuhy?Wa%!hk2+>2SU zN=38e8VeZz0Pk25_BrSl3opr1(W>NGS*4ETijN2eBiGe@k}MzQ!!}o3LjkjAFv92p z$<0lQyIIZW?EGo`Ofx@)>RKhgT3teS)++2bRAgB5J#8M-inVMOo}MPA88s&6&dmQ| zP*}Qf4JM!v-dpT7onNc|CF3_n*AlssRl2!k71vfu53@{hoQ1+Jk*-A_7tM+d>)>HP zcY!UD3ls9zzs2+iFGtv0{Wjl`g`!-9h_}TZ#X@QNsJF#kC53*2k9q6gWBS9*Jnn6B zpP9HcZp_;TU!l6@(WFRLu8KJB(zY+X> z5T{}U^Gn$GpAzp;xnF9J=(h>(5ZooW2N=m|F{U4S+#^HCU;4<)KJu)OJnbQ8(J51w z$HUG8mS-_fl|;PSR}X(u{?SL?@{!kk&@sbxBm)N650N2OkOy*6425A`kPH~E Y^=W|s{(s={{fG&JDX73Dtw7lL1y5NAo&W#< literal 0 HcmV?d00001 diff --git a/build/antclick/data/054APP_AV_SKIN.koi b/build/antclick/data/089APP_AV_SKIN.koi similarity index 54% rename from build/antclick/data/054APP_AV_SKIN.koi rename to build/antclick/data/089APP_AV_SKIN.koi index 6625eb8cd80ebf07797f055c036c9f02353b96d6..5cf0a812df0e3f2bb0bc288bc370db3dbd617a5a 100644 GIT binary patch delta 535 zcmbVHt5U;26y04YY&%J_c`c}J1`(<_XdK*`J#)_8`#Ncm204Z!JcbzW5SvQsHB`TEsY{Dje6s}=z5uUh;Hx6+ zo$SJt9YUrV#ENF-9u6U8KD=vBG(jrx1ae)-v_b|CLxEQfRto#iO%bx`%oP1FS*xTe zh!w&c--laG5IIK;{un+IwEU)wXbV_r8DvbzpGM{^I511K7@_U;IAqqF+M;l-pZ%jN zwnlKRpTeAb?W-N1*d@fSfKS)BbjF*zoT#Ix9i4Xc9434;aB7)Wv4ql9w*O*Io@uep aUXwz?qxS0G4t}^#2!e_q7k7gfEcq9?eQe_Z delta 828 zcmbVJF;Buk6z)4kiz(b)ODit)WI$X9Iv7VrHk^!;b2s@1maP+kyxlM|nI6D!7qi;MtYlHkKyVVvUW zL@V*kj6O*eS_+29+_Q2f3_Zn6+xlSOQsPI7<)!9H|L@gjLe{vcwQM8HI&FPx7#PzA zJ~4)Gbc8D|a9}fBSro@i5EdY#k1~DI4iy1r`4~B0?qC@E*->_zu!hZ2>xDG$qo5C| zPCe9>OT86*OdRE-`I{?C3tB8fQMn~BO9yJ^1Jz6|sIX8i|4bUX{9kmtiDP1q4hn+LXKV?O{B8<>zQREgZ|gm4Cg&P$tVz44i$imXuxgP!;LikXXYo&Ednxb6N;shxf*nsJ_ z90!{KArFu!mRu~&1&uM}KAzM=nC&0f;wFk|?RDif^E&sM)(TcV+WN&^bT37IxN50p z$kiPZjNZO0rX7tr9GB{H))c7ZT!hZ%OD)i@%#}dM&+v2VWZi delta 565 zcmb7Cu};G<5Va3d8H}9^0}V@Kbx6Yk5ep-XY#=5!)_y`Jlx~cTZs|rx#zJ5w(iu(obqC3N2Ssr+;jY0H3O;ALR}Q_URXmWl0M(p1^M{VE{aL32jRFvWxGlcv3rE zow>Y;#tE~jLsUWS!6N{pB1(sAG;BBhjB&w*!nx%l2MoRipO#3I_ved zJ&{qZPeBVpbz}SDJ%2rx6Uu&N&<-Nxh#q7D_T8+>@VCjfX(%XHXDd_6Fa487fg=8AOS!E8#ULh^+6Q;8zq| ziHr+Ln(2g_vNN~0&+YBLyIF7APYGvaV5rUX2#OB&`HfSVzgi?T+d)c~FfB>9i$N=D zBU2}sxss`Qq5~SBt9w|w&&c@0p&qSEH{QhSFn;qw8kcTZI6S%mBd02zcu&kp>rmlb zXyigN8A0(YggV5;+dMq2tOgT$y>yOH)~RLGIz?A8N_cNl(QciHxBD30(Uj`8W6 zm(|}Ue#hdz#pTisQUBiJsl{`PzX~objjIbwZJJB}Gp;W!9o4~)Iz_I`)^o=VzIhj~ IdpRTX3u8Q6!~g&Q delta 627 zcmbtQuTR5380{TwS=!$9T9UCM+6$sV7Da=hLE*?;9RoE5$SJ6tB3quBBK;2_nW+Ng z9Ci|k0^}U@*On9nAw2W)efNHRx#7;jOUPI@RjscS*a#pF0~Rpy@R3Frq*O^Zkm3%r{QM>%(M|+O<5U8oEaRNnYPVsKqNOi6nlhw1&9b5@Pd5VOcEEQWKS}HOo zin3mfS=FU*ES}ca#sK&1xN;lzs=cn_^W41s(_EK{08i{73zK-%Tw>rtxVyibzJ=hK x`Ncs;rbk7THy{2vWKj<_Q@k*@xa>|yQvAi)|3m8~)*zd6BymAXh!1OzgkN0&Wz7Hp diff --git a/build/antclick/data/059APP_AV_SITE.koi b/build/antclick/data/093APP_AV_SITE.koi similarity index 54% rename from build/antclick/data/059APP_AV_SITE.koi rename to build/antclick/data/093APP_AV_SITE.koi index c7dcc6b1c5589739489b9b7659ff02419650b382..dd5059ee228e392744a1d50bfb478d7c13074732 100644 GIT binary patch delta 1372 zcmbu;KabNe6aaAB(EEdgE)=Pyq$EC3CGCk;0n#?Q$rF^R8E*lFi5qXMU}(hD+X`=C z!x96Gm9j8~1+mfl2KfZ&z5%?n_s6yn5)jGm`#mSmPidULrujrt_(DGcryI;G;64?r zFiJ2StwJZwPS}{ik{$!E?9iuKP>E|03m-n(JFFYOxlxDj_AX`;9Nsl%5ke>q@*!=q zt+b3tg~L&!p1pUr>DDSiB9SfJ&lEkJ}MqZJs7=UC;DQYA~9oW1SFz+3+I z;^)}~a=*4`r&tTOy1Fh&yx8#3xxor+%sz!%p-Tg3hfcM5v9^BLlMvw|hXb4wIK)}P zBy`xl0%mxBm!H>K-+woU$ag7$k?*jUfOkEo8k9>)KM$60&~vE;hd9SD!Fdj|p2Hq4 z;T!&R=Fsjrw>wMyvCipw3%2;pONGF%!{gBU=T5W9oi;ryT>fJ|yx1RC_bk1KK)|f; zOoP-&OT)SD5UIX_kQ)|;6T_+IDG8;PAYpE}(A`I>4fMHTVK_0Is-6ghjNmyhwd1haeWJKLB7YuM(}S;WBbzsVP@GOEyHflDzO%{@ delta 2216 zcmd^AJ#5oJ6!x8HlXSpNKuN%r>nM)Tu3}*|C~ks~JTjUkt;7|l^Lc=RAJH=L&6rn}^{ z6IT!p+VD=iiO1eay#=4e4!GTFHC^5|!B>Y{T(-L}C$M6!83RX=aj=l82xfO$!N;BV zD6>@TVAg5lc1Gi-{rX!mAyn1c`dkG*s8-IRJCwzOXPw)@6Xgejxk@m$V}pE)x{Mvk z?M-UGUlY>PjR@r3793~-%r(BDn{*m++>MM|p9OD~FQ^ct?lD2`MKOIXHlxjSv(xzC zrSctNoOqr)(w{Q6{RImXH}lQikcvGmFdHoM&`+3!wYvX^0}gemp}N$`LU?;VoNGJq zl}2CD1t2;Pr<%|paV&*x_m;4)OTnafx2S|^GwzSv#GgzF%e*{)0=4((4=o1*!#;3W z$ZDl75-mfyQuA`XOwxo2sl%M`a7OBggL6W)AXE#D2bF3v(dg=hRq_97!l@w~8KrU? zO0(f{OK4oPtQ2H0GN}(7wKC#uwY`y$Ob~o=z15{(FKLY7Mdlnc(7!# zU0S!D(t2FDv|-;(`)GZyV+h~W2BvkY5$T#|;>DF`qMIgwW&$En!Z?cG4tUdT!%you L<~;hZKSthf8ck|k diff --git a/build/antclick/data/060APP_AV_USER.koi b/build/antclick/data/094APP_AV_USER.koi similarity index 51% rename from build/antclick/data/060APP_AV_USER.koi rename to build/antclick/data/094APP_AV_USER.koi index 7341ba53971fdc34b2ada40d1f431db8809f2b69..7be3f430b0debab4f4fcdce29d45b2d5ad3091bd 100644 GIT binary patch delta 718 zcmX?Mw!&fo<77uhgUJSrY)oP+fJ_ZAldl5Ei~utwIW|9Jv}c|iz$iIcft8;zZnFWa z1jl3!VfD%Ry!=d}CngGt0}bF1P@BAu_W%>)gvkwj+dyVn@b3UJ#U`@}JYZsY090Vc z#5-fMf{>h&&jWK1x7|)qknzOi4MO(hYF!{KKl!|%!eoCbc_;A>)F2T@ z3o>!EAQOLqsva0aA0*_WBs|cBGtl@QX#5pu{1a&W7eGD;JeceuNmk&3!f1h*yZ{H# q5Tqy0X?5JFPg9<@8YD6Yz`#G z(UFzKRYoRfH|;NohiQz_8~UZ~_dZX)+&5}ZcJ9g0El|}5Ap#yLl#HShA6CSa45Cj| zy%|r5pM#s%$nMz7+eN*fG`UGx7dTd%wB`>DZg|PRT=0<|jMNuOyXco6spF%qJ*A2; z_O89rT!6XV+*D=>tl}p%eiB7lOJCU>9bTIa@W33qpY|+FX{Q3$+`t|;$Q*%w z7q)Ur6in=c#zIoflAy)i*l}wb=;__avz2%jSu-PREVCzknH6%@%E(sy<#1ux5aA?W zMmGflcDaJ$8K|m+YJ5Yx5J2cr`T~T6(l;@ydiZ*ZX&yY_CQ9=*;?YQCxZVaa}Hb E0wlSHvH$=8 diff --git a/build/antclick/data/061APP_AV_SHORTCUT.koi b/build/antclick/data/095APP_AV_SHORTCUT.koi similarity index 61% rename from build/antclick/data/061APP_AV_SHORTCUT.koi rename to build/antclick/data/095APP_AV_SHORTCUT.koi index 45f2cf57608fefd39aa31843a62e0d2ba900b18a..adf0b128b36f5e0755368c7e9a9c98d697f44968 100644 GIT binary patch literal 5672 zcmeHJy>HV{5Px=>CXkOh%>bjv3=pMI5Mm4YP%R~KlsHuxP@0xVjc8TACRB-x8DZ<_ zu`pDO{Sz`Wc4TB^>=y35=jYg0I~FNb5cNfV=X>|=clYk@J%^m0ekO!S6N}(|0Tfji z;FP%(`}X5JuFPn*K6&h?zpi;6S2lND_#tkXfiMG;iFGe+1DD|GS~7hHiVhhgu^*f# z#+=_8aUM8s^A$4X6jLUN;%2wKp|^}u#~_hnvq|pl9vUvqLKA#^8Jh8q4E}hVUJ*=f% zO~yM$BB^3SZ`?2GwNAb9w7?c8?2WM|l1TJfO>5IU0h(+58k_QH7}?+E0kfIW91(xp zhs^eJBP{uwtTPj@qDTFW9xWWq8aRv+N98h^9)mCoQ6 zp>rYK)C|a~wR6fnZgL{@h2$5R{h#OSl^o}nMtZy{nebpdkm-$1DR~ToQ$9oTIg&5j za_TOUpCEY)$>O_d4nYB~6`ymUay|JKp#L7A{}!PC#KIsM5f>K;5&mBX*f)Lj0!Q$| zkiV(k>m~8oHDTF|dL^uT-mc#nUvJCjNWO5(^VbV-D4Fp5L3|11KlzWxm%{l)@h>`m zIKK1-uZO7rUym>D#$U}L8Tnt`L;4YtPmnxD@=v#%je|_dWaE|lFDQR$+#A60`JgIspP1r4 OFS80AvYV8F2>A`{8*Tmo delta 107 zcmZ3XvqE_R<3t5EChirJ4>Eq3tiZ^|#JghiK}H4U$qKCejJBH%SS#2#8W_MpVe$eV ziODCp#hAE%OcWHK{GD53vb_NRWI3Ly$r?h(84V_H;1-{#AOK`!2&yr%Y}Ob4&a`*~ JCnFOJ0{~wn9T)%r diff --git a/build/antclick/data/096APP_AV_TEXT.koi b/build/antclick/data/096APP_AV_TEXT.koi new file mode 100644 index 0000000000000000000000000000000000000000..53a6ba673bcbfef23778befc5fa6e667d3602186 GIT binary patch literal 12728 zcmeHL&2JM|5P$195FmU7J2Hw;A1#V#Lm;7FZcmulQCAAKWiQkmswB`zjS52jI9OGr z?w`=!eB5h$;OrxR0!JVDGpt_Pc{6XF_r|;X0;J+29_pR_y_q*VUvG9B@$~7RLJ03) zO>qAPXj;C3hZ>KZE5-32Hm8SN93Ipz>EGxaRR3Mmqxj~2c-Q=%_^~Vo?e6oA} z`|V%1A8h}!bN$}-&%4_X9__Suf7_|TVxYkK?xP*pUnCpKz@}dXa87#)w&;C6DQF?&}jN=4ing! zpo3(_aRyB^TaBO*+;66Z5_?ieOUHSg4rJ}1(MpTSnUp!xQnS*k)dO()mGZ08;|Cjw zap_pR-!VDKWj=x4s7sO)2eB}V7Sx0-LpVnHn zN>B^@JBhJ@?eE|>r82Gv1A~hh8~L=pdAD6_ZKAnG3slB@f;DF=lTUXVRe$~d>-bc_ zJZYcMoL_ror|3{Xo~nttK1f_NGyG_Iu2C?)3-PLwmRlu!O~sD zB{uMLB31t;>YKxTDqZAq_yFUS>;tKbHemIm9dHHJvJ(5GqzC46XxRSj7?Pf zlp%N~V7GQ%B) zyA1aj?lU}KcxdDK62oPNI}CRj?g369?+?8wfvfKdPP+binNTmK8_Uz?hL%sg$lgEo z%ps2)^3WmQa>#Ev=NtPAY=42v`%Hhp@X*HZ%e=?DLuf)$eCpPs`20k) zx}fq9laXJ1?;H4K>$AY~-Ghf1_6mK5x&F|WAC>xe5yY)X!VmH_M!J3|2jS%s(~ue~ zp0PiE&IcW>AG5eW9P<_X2JGkczSr%KlJdi_cVzn`(g~H64~_PjS_g8?S2<8h|6hGB z^=$helx-}BHa;rncl3P{LHt0MJH+v7)C140fe-uqylj0gv-%Y|R&f~q7P}1h816GX zV0dWb!}|Xn*ZVJ?dqUFl;cAnfe<%mZV%HYO>#qIrbFQd7n56ByzF)C#ytn84^8UD_ z;xhazb{JN9Gvz&o`ThZu4{dyC{Skp(MG}7C-xx_+an0AoGUyrcy=~{0*XKi)&nrFK z|HY1ti+zR%3=eI5X!Qxft|AG)#QKCF08xZYEGj=^GU|cn*1+#ueHMEVv=LwNEvZjj z7a_^NxHKcK=O4;paY@BtlGH$Ph;NMI`5BSqT8U}Ia>w^8_KlIh_q{(pQh74sEe>sb zXy-T5^^jy=qkX2&olkBzu&mNkAwufK+gIM zl+wO`lls{C;PqKz^-Hf$2!?lVBf(A#O{O*x*e)Z|2W7 z?a%r$1u_Nxz5@DBLZTOVRW+s+3$ty*RE1`EYQ=Q9+b!Z-g)D3G@RVr zkD%1M>|Hh6jgIQesgC?;aCePSMdenPGD7i;vfAn5bQ<9gQyvtCw}bH*!>#VlPoCl} zNArP*C)qn*#8+4hSD6D4TLA~h?M}OT+G+LA+DDN}836&plSb{L+xd^pFQTf$V-&u?U^B$PGZi6UM zk*IT`+-1*6fV_r2-H-2&!TS{lM-Ddo$OH>$pK0e!R2d|@AZEW@4PWPb=|??Hk3@G$ z^z{DQX7TasSg`P>{ETi8^8L83TBxB!|J(c-*O&T!I5=`}7crSsE2Pg)xIsGl(;%B~ r>|kepK=bVWjpy@tbxxbVJAdKqzh-_wbuyVKC(@n|Rn3+(1w{QD4(g)* diff --git a/build/antclick/data/DefaultDatabase.sf b/build/antclick/data/DefaultDatabase.sf deleted file mode 100644 index 4ad38cdc0d27003057f21c21b4d1e7dbde95cf49..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4608 zcmeHKSx?(Q5FY6D(3iGqOF0^#_g&|3IC@B_>wrZdR-8oTDKe>BqJphD35d7+A^t-D zT066|CSH>OPert`v^ae8?KR)*%=-G_uS0+_02s$6p6JJA{BIn7pZv%^SMYra+gQYw z_^GdmKYE{!2YRT`HEa|CDbc2uGg?-2Hl2pGQ7kvwHK$^)c?XvNEkOG$2zy$w7yI@( zn4$g|#a{DUKf9hBVIHQ5kyRMRw%7b22@hb72swpdhpk;VJTQWt?yld)g*=2=V(AKt zC+d?P@lbh%R189|_1*8Y9`l+P6qeK6_I6#lq$iM~$rcsHXSd^SxoxlRhP0rk?3pEn zW4rD4eh_{|`!iwBsh+L1y%4vyhxX?%k8|Wy&yw8;eBWz!B<%%E5KVRPO6d9>9OETS zl2P@oJhbQl}xyaEIln*)_P&Zgu4V~B(!d>f5H)0Et@-MC2p5XB}Q@*an`I2F{!Rc$fj5b ztxwNOtZII#a=!(M(26-?6B^Gfr!{S;zA3Vvpsk4bA-a-nn5JjYbEuXl=qQGbYv@#p zUBB6B1%AgB45 z>0+e+QHY2$nLEme@$>%??oc#GzAG4pdGXHwas3&I(wAdZO{!_J{QiHPf6B=T{f{RQ zfY+xakvEAz5*LMf%iG69@|J6qns7_*mbZgOZCI26qz6_SfDB8hR2zWopo#;K8(MV$ zbRI~lJOFt{mFfeqFt7pvEHYcELIBH*MrVie4(|0Gqw&~7^u0ipI*aIs!P&PFE1Lil z*fp(X5*xV3Xkr7CxB=uQN+`e-vv~tJG0;Vy^8YNh6yIXhTgvGE_s`z{di2>*Z-~1T zz%++O{62*-F~evgw(m2Vi0x7Q$Zw`teE~Sj_X9fm9G)J|d3BWku_o$?^!c~*|2c?{ GQ~m+nA-ALe diff --git a/build/antclick/data/DefaultDatabase_sf.koi b/build/antclick/data/DefaultDatabase_sf.koi new file mode 100644 index 0000000000000000000000000000000000000000..c02904d4edff7bc5c563dceb78fc7097e12bbaf8 GIT binary patch literal 6984 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%0AAua#66h= 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%0D>~ga*(2 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%0D+?Sg; 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

A-wrqMU5(KoCS1V*kayz_OJI(_G5P~|Pd{GMP% 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 ZXk$rYJv4z*jDC!M=6x*a+ghSO{|~mIS!VzM delta 581524 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%0DoMUI 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%0DN9^Eb=fXg+E6^H~-_pOV@JnDo?)aHHX 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%0A5__IG%Q7dmsM>ql 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 U>Wk@eL2-M7gClb;I5o%r0OJB~6#xJL diff --git a/build/build.xml b/build/build.xml index cd0dd648..ee9717ba 100644 --- a/build/build.xml +++ b/build/build.xml @@ -8,7 +8,7 @@ <target name="init"> <property name="Name" value="helma"/> <property name="year" value="1998-${year}"/> - <property name="version" value="1.2.3"/> + <property name="version" value="1.3cvs"/> <property name="project" value="helma"/> <property name="build.compiler" value="classic"/> @@ -28,8 +28,8 @@ <property name="jar.name" value="${project}"/> <property name="package.name" value="${project}-${version}"/> - <property name="antclick.name" value="antclick-1.0pre5"/> - <property name="antville.name" value="antville-1.0pre1"/> + <property name="antclick.name" value="antclick-1.0cvs"/> + <property name="antville.name" value="antville-1.0cvs"/> <property name="debug" value="on"/> <property name="optimize" value="on"/> diff --git a/lib/ext/mysql.jar b/lib/ext/mysql.jar deleted file mode 100644 index 32f0410490683d4d054396baf7a77ef978f12c62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 125901 zcmb4p1CVAxmTuX$ZQI6Qwr$(C-DTTGmu=g&UDaiDzn-0a@pdQXZN%n{yeIL+O`OcU zU!F`w8Bj17pnte(r$)N}2>j;@`mdA|R~4q0k_Rv<{)M3dLH&LH6^8a-VRFLqQUGxk zRR%f0FS+R{Ss8kU1$Y^Hn%U{OpUO<jtotX<4AOFRQgRD!Rn5wdbds{Ol4_3Aw7`>@ zJf&%5IFHT`&cHy5GLTT$O7lj%e?QIh*Z-sNf7UVkU+M_<H`l@0;y<eQ?-5Y{iLkJC z{U1=U{{>}d_g{b||570Ge+Sxmxj5PWm(HpB7dZaEgNwMCo0~Z^nAjS*xU^_oxuCA0 z|EX19tTO{{5(cI*p$$bM-N+cN743(J4I-k!MS+8!H)MR&hI)!_hUk(5DRDpIu)<k< zN_;{lYPMIg3=EWnJ(_(o`IF#(l|K8VW8pa0;p0JX8`iqC%Ifp7`|B-tjQ_0e>kKj= zBP`l|8=(L-jE66dBv~UPB_kzM6PUyVIA=ghKaMri@DZM3&oouT>lr6`Ei-4yQ6LaP zcm5$9@nsJWws&M(N?-2ba!Ypi$>C2|ZIO}okOzn*KzPjK{Tm~>&CNGq?+&a1Vh?d& zPj~r2AAjT*DE=Mfz37+ZSc29OC6B=VcLb0BWp;7^j(^#~8BDh*<tPB%GyX;uY2R&e zy1X_SCIt*OCafv=qp&HH&<Sh`;suf11Cfuj-GeIgTmg<ob5UbFou1SIpQFj7Z1Ns1 zjdc`1`y)tnqNJJR+z;k!C)0Oyv#fv3+x9Gc=(xI`$@q~Y5ot^PVR5Rg#buC%8m7k- zhqPP0pw+&>k=>l^F>PI?`MFyG<I!qhDK{4>d8}ZlArpA_l)QDFYk*-Q+rpq?lhNcL zFE%rG%~9lnJ~b8^!5wsskxZ$I4CJjqZL(nsy%smAJeCz8u{vJPYkR961u&1#%5!%q zvxYhzi)3d?n?cAb)unLIJdIR^GMkhtw!LAYI|@wXvD+Nsl1{6vu}T?^pVahdO=*<v z^4wKda?ooKs|+^2P_LWaX?he;ufwFH?0396WYerJl(s48f1vTK3b(hr>c4$R(Q0N{ zmcj8CuIyk=$8RV#@8wfx`HU?}oYd5POKj9lbiR-`6XykQ1RV=GA7mA_HGiZ_CZI4F z(9qf}KPV<*IB-VtNrW;cOs*%!786XiTPGM+!h<{X+U*S`MH?S<#6F7#0ZSaUL?UDr z!{`cbk2YwUsYk2HZId$nX}&rBlD25V&FavhwOGjjw#&`IW4%~-(>TYHMJ@3YKy8;+ zv?@hPSQ>=G(zG$C<ziZ4X%m|U(_y(mmrI<hN-UTqm5>StNWcIT3s3K_$@+`_!r&iB zg*!yWJAIR2|Kf<WX_r50r;gk^P|+4+--bG*I2XAGTqM{zESxkXs^=eYxuG(n*U+Ub z;$Nt!OE9b@W>fVg-8h2O)2#ePEuThnTjCj*MB_nN*g%g7Lt($W^{rwOc~@U4>KsQk zo0?W4#NiXI6iGzjQQrY@Jgthsr?s=Obt+${3er-p=JQykc+-FCUlcE{SsUfC^(oOU znw1ySrj3%M<#NG0g*x_WR_TCSc;Zy?kUC^qG3fNDt=q)UC1}7?fhfV6qzG|cpgjRS z&?jX9;!CD%8ZL0C9^;3ue8fDn<|j{)OC1!;-%hFcm<~Thhs0D5yih(ZMtsm)=XD0u zwSDI0nkDYt2#CEUE;fSn7uTh#<w}kUUpv?JsF<G-_+(Wnb~DZpd>h~J-%K8~lD1Rw z0a<ERJ-N1O-X8viZpXc|FO6IGtYWezPN-6+1MX4{CtxFmmW`2T3~V~Yp*!|93jLI5 z>MVGLK1Vc1EDyd2JIw1LXC(tTECpLY@HH5`&bXIKcTC{(UUF57;-qSvLyQeun(Wy1 z>h}HHS20+`eqY@oO>^QG=~O*`fG3U3EeW!21)+13<{5vt&BtU`kIpIRr6YXmMf_a0 zxxQDoi%^N-CiXiNfw!-q@KBSpZ>DH#q3}?VyFHD9m1h9G?JzYx>+WtqUN7T)guZ%> z(gNvzVslZ5sVlgsG;^U>7sgKpO8&U88Frnu?b8_?TD<9%X#Zy6|5I=l<T`cKk%!xO z%k!CGjDytt+k2S54D=5r;Q$TcT$g};l0Z_z{X$3on6|g}#fB%W3_<DyEEiP|+k7@+ zzXXnqgXBX2t$lIwK^KMep&73>)XO*Gfr@?e@`8@a-4&-X{Sta8-jt{+&K8T*!LQ2O zg8LQw77GZsWCAl~C9Yh_GsudBdvs^7+xpjeN3mncXgQAsE}|s6M+BGF8-&LghDQb* zX~3>7Ek(f5BkoEd{Sw2WY7DbpoMfLlnQ^S~30?NZ;k5_d)-u$N!ywCGVl%h9#Lnf@ z6rRr?vv|4JXJE*7Jv-+>ObRbJ0}s*1NEa(}puI8I@5fTw*<N5o2H{_`{nb1>e^}yW zx&T&ZnCZPPyog4cli6k(><s5s;|0Yw?R()Crdo$JTYKuYGfujAzLDsQ20iD&IgY|8 zC?#imkX{+6Rl#ybVuJ`16kOvCpf_q5^t26!+fO3{5uU`~E#fuv#;Y{u+_SQ=3?C4q zw4S!YC#q{iH#oM5agB*j8ZX0HG@7OM*}_X8OK({)>IQf@s;TU9>1V%L5?qqDxhebq z;Eo;Hq5E1D__a>q!umkh>bZ4NU%O>d(=ploh;3Iv&mn1Fx^3&$%Nsd*(BiFVhh^PM z8dCF1c1w8B%Um#(od)$dQIoyDnn91u@h^{X`6U)!Peg{n;gO-RbM_8}t99KK{ruW+ zI?m5V*b$R9Y6+ge+7;Xqr!e0c?B?-sOqi>sbVFvr-Sl#~$13m2U4E6ir((;~Q(wJv z&0k{S)4m%J?dr9{um=aGzrOX(z3T8#|FTr*$!OGqI;L`*or%|v@rS-yI%uEWz5yJ4 zn4)L0L;?C!<m03xyJS_e99O05i&b(RlrUO<grbAb16*NNbYuFJ#<F@aTbRGNnYFn{ z_9L|+zmRsg#<2K0`o=n)lO;doE+8eukI@h3#raK!I~F00hxuzpigB@Y;%P8z{Lack z4!SOYOZZTLL{tvirgd%0J@|$Ba=a^j&6(Nk$;1_$!!MltaqUtN_#ecHA-A1e{x9nZ zM)@ak`X_7qR~{qw?}&-0t(BR*tEiE!t&y><nTo5CtC`*31hRjotGGHio0%#)JD8Z6 zx;dNulfT3%4oD9PA^B|$j}BL`Z(c5lA~q_ob}h=tiwG0Xf41r^!e_(Vw~7c(g+LK} z0SQXyRGdqlGw`x@Z+LZk-4WJ1+%t`8fe}U!uk-*(1qy^P+Ac7WEh+QC^twy`%G7P& z)Mxda3HfbjWdxJQTP-VGTc=ZL?m5Dgwc5Hbe&MP1U@eNuw<L{|4qZE<JGBi>Neg00 zGtD_#TcQGM+^z)ZfF9!7$vZR#ME~@rHW|hmhC&ACGRv@?V)`0&(N<)*v+MaW)shPL z9dQ4)ie<%0p9M&g>k*{AJtcn^qbRMdaMc0kqI~rWBxwj?*hDo<H(sm*4ew!$U5IH^ zcn_=s=5Y<Od;;O<^aY$<oUKX4D8D#{n(U+gLlr3qsOi|iKtR`j{r@A-|Edb%|BWjC zMG3;r7XPUS)jbtd4Yc13WE*n2Y!Jb5&Fz4cnP3Q;QhLn*HgGv{VUx-V#_Z!JI(z%W z+qkgbls7Vjez&oq^0|!(xffjlfqx>GTsV<!pjk~RUUPo!FrNJ-jmP;O0llL{vqw@e z`9(j5v25X0c*;~@)W^Wx&{k$*<723O<7Iey6(5^;%vIh{3@Wec*{3fu6o}(!Cw~L* zHQaQUob<-v#eb_yNR4^mV6dlP8xLAJhEFe+{o1Dfh<A)Z$Mzh|E$8jnDeBTZ|CS9# z=GA%y(NES_VIn&Y$CRIDT9=vWr|-;eTDL^Q-8x|H(|qJ-Fr9etE5G~|?Mmi=BqWfW zYDdi3{$zc85KYPFm3oln=85@<N?)TKUuvF<%N214pECd^%23o&diH9Gn5EEBAOcb~ ztUA2~k>)touSbXb26q&ygQE_&J><6tD_x1@8A!-hgY$;`3ZKC>^W)DC;f>dht2a)N zw%R0}^{NN;SGP&@4LHvoTksj2`ZiE|9{!|C{S{RQYmUuAwrbO6&l#Q9Nc|H*soAj1 zw#PEkOY`0z8XW>`jxa|Mk2Evwl-hO^On#0~E6e<Mb+0)p0E?G}Vle?@Y|SB3YuTUl z#Yi!b5$oBZ{D|AdqY$U2DZ3>bWGz<~%0njM??bJgMYygfezM+rIP?AmN*KYA<a^Mf z1S}<jY~~%EQX9;0+SWXDHh-3{B?zc5=fhEV3ndrYLlZ&0f0XR&umocPYDD_Xr2Y_^ z%=0Oo=}cY0Z3sZ4S>^*i_s!fA;kH&9&dir-(m%ube&-9LC3RW1KBu9E=1hYID@R%V zuDN+L+CW#en1Fr<R;}9Nv7NJI9X;QJja*7kgT8dBqO`Ih$xOJ8)mCK6iDTMi%es@| zp>Nt<ymL!(xYlFxv4#Y#XKLrjje@@=@qhJ&j52T>rl`CTy33-S%!)ZN&NPLr-0<WO zxW{Ek_9DZ*>(7ugMFq>59%*{8Eea{*o|&}@*gr>z@9Dp%Em>n3^GJN3njLXx+J5$G z#xy<#PjaV_iT+0U*u#oGFGl_*58nf&^zN6W*czbhBf-4rki27&ry0HL33gb>B;gJR z-v;{){*S2&_Juae2l{s=Li|rtmEnIeRsZk$C}RyGjO2$dcw-SuI1UWLp!!2VNDS)d zq_nW(9?uAqr~=|ka}XYFwGalk5CXdLLd|fP+VY)J{r<}9+!>~IhRJ#&3iT7(E&503 z0!2z*atq^Y4j#YYX9`je*O)+SSyj6-77~GRb|Wn2ROl&*i<Tyeb@D};V!~7?Y4ZZH ztaSb*8)7Gw>w`Lejlf=HT#LDd7pm;O2+$xAXFWjYNV#Y8q#N`6LjC0}EAV9Iy1Mf| zlJ|WnKe2s0aXZz@Gb?EH8uaOR-+T%miilnjaZl1Fi2r~5X`Ea6;nx55i0gk_-u`t9 zO#E;A%)#E?%*55o!Tz7!l*$9`t84ba>cH8xXRjY`pUiRbt}T*npG5&q?FzfdCO0J# z-zud|b@-UnO|fO~zO>V37Xnp56-@%=SwaIs1AJ^*xS?K0VmVbvL{knq?pLuN77g_$ z^R8#7TduV~|F?UuP4D|@_EommLE-CdJEX2+J>E@3SK|PrhY@K=DO|jfBV9-WGgtfo z3&a>JSI~en1Th3HR?hf783dt)V-qY=pbsrJ8?)v}LFRz<oOHwQBPG}ncDPj*t}x+@ zfl4@elljR4Im0eY-tP8UL<y6S{^xCbr1c5A^nQE6<$VBPhwR=}FfS+@JdgSw)jx7y z3q+8bX>jK!_$7!B*bB@xs^yyzT$^X3!G2(WMSm?w8+0r*9vT*=C)%A96dp=@ZkH5e z8CaG-59Q4metR;dhm*s4%-LHZD6Z!{HGpd^CLhBykC5lVmr;K|BJK@)^o{OSU~FGR zze{od%<BUdj^XhT6Wl+l&0u<e3Z!pPLYL&edRu>TnGyAk-JbFF5FMl*?ad8ikQ2;5 zdF7p6Fn-@YXb<BJKWGo#GqwK?x?6jnUG_mcXb<xZG)NH56Cc)2wciJ%9`jycsXNHY z9_@`Zh?99mDToucTYSG3<P~b0_MRiC4R-r%jCq>r(H{cyaTgRM;97at>k5Qmdtk}q z<AI^OYkaZoN{wLWXe0#W4*d-^=#_c)8_s`H$A5JH2PPt{uh4#oe@%Y`m;l}VS@%6G zL;{m%$^av{0L8rqU5dfy1LqspYu^5D^0trk{*o>HoaaMZ&Cy<?YXIXtB45FaR?wW+ zLxR39!2o&`1(JC)MbbC?x6VxXz(DxG!SaiyDDIHs7z~&JS(bG?xiWwd#2%1=5p_ZB z;<qV@P#-l~TnSuUPs?LDe^?16o){!HDF)SSzv6KY&&<EOH*ZBz{O}vSn=3_fktDn$ zUmjbkOrWG(nHP0J;P&;RY`3^PQqxIHAv@}Hc;9gOIJKnk)os{h2<o?_K@l&(jocG< zx8ZQ5#1k@K;=sWzd@U3SOU2#hkM&Fuswwwu$Vl|RD?3*=5BAPLgoZ+ITZ`Cqnna}F zrTucUQV*p$Qls>hvK1?i4VSnAd<LIFh05EHGEKV1rE{I~S9@03T>{Q&wF`QkSkr3c zJ5ER>)!s*(q#d4#+mvyk=70jL2!gl^{sqnDlCD%~_qbg#KKrMvqyUsg>=hHbL$R!| zHk?ATCWh@^j>YYT)z#(Mqf;?Hvr8wJVgec58WPsZF%|E6?9#B=C#0!dMgw{0Smb(y z1$mRYPLpP%mPQj5l8##HOvy254{K8)g)o(<j9FFfID9}XR#oKFrKplhg7_S>dcC#I z4m%&2_|W*(5;PC_w#D$wd0IuH>_b?jw+bJ6stq6VOmQSrOda3y$o1*0^%`WH$#u1- zyeY764qc1;0sze8r>ajSJ+TPF*gM9;<^%+$dxec23$rQNOhuwLGj?PDbmDce*L~ad zC3|>@rIa-Ii12h$xoQdBM0qFPCQ+0{`4Fm@Qm!5q(Rh>oBhb=08#LS^Ut*=6Df8_0 z$?1l3MAGPwJl8`G45S2;R~{SD{AB4yxl*l!5rGsS(neM;=(j`HHhjRD_v1LY#BLrT ziL`R~MYFuejX8#wRKV}%^0nJYQxc3T;{4*s#VO(Fve6+mW;+{JSwHqL^w16YpxRba zIrmHlSqld&MAn5A6Cs(IP;{9eN9q`za9iSipp`|f``=}##1ZVrbb$^y<|Ip>386w9 z=&g0lQVOF{cv>S*e7Kr>*7XfUJ|^LLcw?rggMQ2=awODJN;McdMNU@j`o2N4gh@&h zHrFiPrL$=m&XwZH{3aoZ(qq%|A#VQG!kjtHBhfLm0->6XW{)?cvyPA=LlUMIUk8u# zsV6@BC-J^^la*^$VQ!B!)T@)*s@c8lN{#|J9@82pr@Tx2?=q#RdpLsNeXZ9j!y(&U zBi6PPJ-Wd+Y<4(Z6q|AqbL!E~uIZJr%omB!^R}PE7G;yzPQOAVk#T`1oYik2VeGB% z0vEbwI*+-MU5;&ux0;92xf(esLRw(z2W@D!K_S)JG5w1M{T%yX1jF(x9ib4a?}1(k zOz)9GBCt=+;QR;nk@I~1E)Cf4%z2;ie077Ue7;EoDtxbOAr_u*I&Zl!bC37j5CNw5 zd?A=v-Q)Y@5R5}cFfxr|^#nhgQl!i8j*EE0R-@9)r80^fvkA76BoT1@aJ14|6-O{1 z$id7GP|ytkgi`G;RwgE-&_D)C2O9S_kF>Kc-EURV^#i<QB@eEUs=oMpM7(j7-Y9-( zW|I_rvoyb>tU9|mT-$y~xQL`o!9VH~_`AI=kfB#weNqdGLyRPK`-+SR9vL8=#v9c0 z^RJtbQB%QPmWcwX3^isf)Q_=w14q_bk+p=ebtx84*`O+?6aji!`>s)0Qej~I4x2gC zb5diMiW{RH4s}v6o)P9Vd&-ucbiEboqXS0zh?gaIi=)DCJ!!JnOp)<1=kcbr<BQVd zFtl7&xQ1c^G#&^`Xuc@ZD&9DL$1rFSjj25By%D1SM)*^p>y>oGwY#x6tHQ%!g`3S0 znyuc_>RR=N@YleTrkkPip!by@eRuF#1#({|t^R=X&K^Zpq|+<^&dl3YMbukJ6Ma}j z#j(IAWu0ON@GeOO7_%T%Xe!7@#$@INP-U*8l%9F{$f|8GmQ9;(DyEY7%Bb<(Gi;DI zqGOk=m(b|%vbcT0MQEOJUOjjYF5BMNn2XrpQtU0%=xWIfvrj6D9%Doco$D8csbp~* zlEKT(NywHReK9>iXj7t|<42ChL8xbN<Vf12cv_k}XDFS=J{-xfTC0tezx7BrR#o_- z>JC$QidY;ehk9-Bi51(fo2HhqnR8me$dp8I{Om|`Yjw4{R#vBRLQx`tS+6)`%ZYbP z8mYtIQqh*ENm%EgZn7C;;67a^mq}RqK#@Pp%1l2-mWhiSOX|_CtGS@q82>SWndT*( z&yhEXq5&(}04r5D+-J^Qa)ZZoC=XFOO4Z;A?Guvw?8~I3Ms0*zVd~e}#j7L9+2VUO zn>IV^DABdrQdrsZv$7-R^I$f9m14ujZex8>x?+r1q$h1^vjq#%r?#iKhuol9d#<6> z_%RrsUap$GPJU2Nk6txDWh&~{eN1&DJk5<>PVbrmr(XH^(w4Z*3f|$AJ5*dAkwY*L z9Y$8NkAbqQqg?9eC5Dy4`}Ja0=^?%rIweKL+q#)dw{&Gyijj~w*_rC3R#MT=(w5Q= z8J#K`6-S<InN$tvib>T{5jC1rt0(37PkAnRBg#yILn`)Lz|88_<$P*u*knH&^G3S7 zbTMJyG|J50ur^0T<drGMeNr$;mJ~C4i<l1X&VbLNsElowPSv3jo~-q}ge=XHTB&qp zSzu0FE<L^t-Zq_O>Dc@PtXIxW83*T9$9kI;VLc7&`du*ngeeIjshHB*I=h%^<kB`U zv2lwoDL}=$ukcw#N=SufmSWctA!4Tkj*U*((vE;r-)gochOLU0oqzP?Ps6Io51EF9 zACxu+ZwTIBl8LJ8TAlIEOi^Vezi?%^AZH=`t4^qcXI0I;Qa7qtBr>aMvRD#!HOvG$ zQk>CBK@g%OoGHo%Y45qj*L=fXaHZ5LiR&hCV@jzxYwPB;IdR)u13v~=^&PZ6r==VQ z-*$eHbf<!xf*;ofnHp0@a8Ket6%vP3KaUVr4mP1Wuo$x@`te|3tZTLRS5m1e=ycTZ zQ;<GjZ7uNxP><6lUyG$x9~!eR$jMS>pLh^VMkG;_PA6Clbka<Zq*tmabyH7n*a?@+ zsKfMFYx)~!s6(AhtEFHQQlFLHW2NRJ^D*;Am1#5Wjuq-y9Msjq2c$TFNif(rJLg+V zWOEELsi^XcK`w>3+S+m9o$6HR`Y91N>^iq^BGz^0jwB^aq39H+s!C(f2<VCC1mr3T zF@m$HRlqnU`(*28kRO&2#FfjlMoMW2rjx+JSalJ>ABNZI+Gk3&=fhA9v4GcoubrTv z^H5lon68K}l15OwRyz5dZt?;u*`v7XgOid&6*-J1t6;dTDAHQXwccl&t+~XJ(~}om zS){DMDC_MOH0dVY@J?!a06)JQgPsg&tNG@Hsr8+Jn%cIGz7A)zPVR~-GmPLKC<9eC zW@ZH*+iDP7`yQYkjY{3D(r#83N@5vyS|r#uL7qP)1jiZs`p4(z4D6@~I5St<;!nGO ztmecmm%Lb3rJ@+{3bfl~-xLf`$xW09Oee?8+P1D%P*?H)%sinedVy4Y<!gt%g$VR| zDyB&(7!0eht;9&BPc3dLjaF?%Tt9*|yE<J|jVEk<{ob|@FltL!ze?D=VYK5(*tk;t znn;t@*bp$P7qn_q*zi=?x?z3cL;txv8@Pw67b-a3F?I1;6Ze{9yQ6zD`S8pAGkB-h zvW;=$W-6&JpOD2m9Yv027P?oySV!o04@@2WEhO9_7M1WTR(o(Sv*WJ@DlTz9KRCYa zR~95V-`Hcs&e4L5ph*{UIO&i{tds{`Zp3mh&>-dvoSY_<(SqP|T5MTZ?@>eV29T;z zLkNXwQ>K^!TL>4dX|n?63`{zlkawSxd?lpaK*5FFNRL+ms$djrg?e6DI<R;Wdx@w% zo>Om(2i+S1IN00JEY{o5;<<H1SP)oNMIAjcqJ~Hzh~S{k?}j(ShRqp`DhA`<)ln@U zhJJ=p5IAp>&q06<)B(SJeld??iUu~&vDo>v{>IoQ#9<=>I`W#2{xPU;q@ATpv;Fpd zmcg>C70CEGdi?x0wpsy45&MhK?$VCupp%Z$6EB&c7yDMEj#_?1WX$T?xu6ZknVgyz z<j@I&hd<V+1C!4;F)&~cj#`oA&54&G)un0V)FUc%o45ZGSr*oKA@fqXGV1(k8mUvX zYSPTgr(1{wV^%eHFzaet>zVgubs1|=^@v-7M|Gd~-}Iy<$jaH;gqoyE+QI4xaLf%H zWK~)Q<k(zhOH^Q@gI>FpuE8x__K=Uwh7I=W5b`F3>y!b?E!dW&qv=7d$W0c1ce2Fh z1%9Zw<+PrZu1Gs>CaYEDzFEAWS9UKnwUv{PR?fFT;oVp$18}zOm^>$Xoh<WyjJ9x5 zN{^9#Or_fMFLEov)2=EI^5yyvv+Li#Y1f99mAEL5t6%Wp-s>rkUI^jPHDW{+2eGmx z3aLueeZ0<R`ZJw9MVV3Id`Unp;(pATLFRX3l9XV+$mDTvb@;ZLbOeh8%l8pnAuLTz z9pgv8>$7ewlpJl^upimDT(@vP2k9$A?L8t*o3?&{03cdpf21!kbejL6Vv325=^UUV zM^rK%vv7wXb7<M<o!MkjqV7J^Gt1?e6R;z=n-g+HlRrX5JiYSGE_J#1WUf{?gM&E4 zLzeW9f`fb5bl)OKvPJY6P$+drpAAKAgeP4Wy-D?Cy$wQ5Wie|l64u-(?yl%YU|;U7 z?3NmM;ZL7B3Bu8cqTR15d2g{_(KByDZ%8Fs&o{dUR21$R?91^YC={k0G2yOlXJ0G6 zst=rGZk+UC=;kHs{ni;UlVj*g6f|2fjmOP;r|iDTDctMZ-&3y%qsdaKP}8akQtdYd zo(Rc#`xE40`=yM-+^gJXfwCHKpoe=!m*t|=l~>OW5~t->Dh1Dm5rl6#9+aD=ycrxL zHPFQYZn3z<3gcpNOHsW8`O{rA)6|;FG5*O|f0y@S{!b!Xiqzu$9vk!nzc()ZaEmj7 zAvkd-;95n%EMLS&VqE<Ao!t3k`}_VPWK}#mB<L4eee%1fpoD;JvfzZ&Z(qvy?yKBv zokoQAf_vbv_jv(B>XsT%f2tJG#T~0T3&6k*&+o;%QagR+wUnsQi9KFh5t|A#_Qr%x zcb&RbZ4bhc@VV6;h2LxH9)Au)iuY|=oFPRzquf&lT|Xej{4l0x%5MRx^QjKD=d+pO z{pQ<4opgD=BSpb~MTyK)!5W~Z7?x?GW1uF^FTSQ~wux@4hRWeyPC%xhzF(_XN<Ge> zt`+&Nt=3!6=Lkx7j1q!j8!_J@+l%z>67)(?xX+}-6Ij0aY;D8trA_PdH>|C83@9dY z*Ha!lBZBY3CA|UOThfY+CSLpcCH_sUkAb<wq0lQjZ-Z1HJj1MB78qZ^a%+Q3&B_Fe zVq-}l+^IsE2Xz|vS3WX&4qfGAPFUKwka*vOh5SGuevh?f{2$6J8lI(_E@w`(cY6UK z13m8avC%3oPMrsY^3!pS&4@M4aKW(MEg27$-mIW0K&{3HQd|kAFa4cq4N*9)iz|*T zB7d|atpriO&ZLY|?{_f^x++LIWZigwD(csd*xWwiEmIm>pMqsqjGONdu_z|{)UX(b zB{iAKp0ucl?Umcl8dcpgZ-vIOxIq(Qj6bm_1Zyk@+NZc-GS^-A)pv+Z=@?pw+kYt2 z-{)yN)0N_tF&_y79c-%}b+v)_VhI8hX%tc|wwx3AK12xBKP;!7Y<3B&(7Fm&t)ll@ z^L8$5<MtYBAG&NEex_7YFB%9NS*<n|eGDl^5F=Jz(#SWk-t*%ip}M7tukiV}jr;JI zRPVfM_`Kfx`k5im=%YUBA|mHKUqhoynf&(Ohm_?zu6)5e4(<0oqGm4HMHCgFv{>7a z60$Q)@e#1FL!vp=t$s6<gio4Dq_9^MCHGaF5WW{CS5<M`f_c7Y=F)H7D+<st;@pO5 zL-xf_KXPtYZ?%zH+HPI^xbj5S7yEcUu;0#gfVb!Tqcw?)vyo=5jFk12lCB*N##O!F z#M#Bi+oo&82s>q1H)lLe49OVjG$h9{x=m`doiQ>WANoKFD>~%WQI!nJXX5!bK(%L6 zKgXESkh1j-7cj@rP-C8M0|Qe?<}*_46m%2M-m2lkr-ZQ8cvrT4RVC{_7uHeDEu}EC z+ugeFEbi{5B;0$ZHDyoJc?CnarAzg-#+!Zj>jup>`vgyCof|=PSbE!`waJ8G=weYd zz)95WnI3X~6`5<Z%HySZwPW<`)qP0^i#ufci$ja8Wi>8cRv?o&#nE{lo~K9bfG?5i zD_uOh_UQW9F!A`vJtkqbQ<Uk5V_kzX!o)5HQE5`7UY<f@JOLH8oy-D@-|+h`3HQN$ zeJo6^V;%9cQlS|H@;0=Qb^G&ROc(QE7@tq+IODJ7uRA^}#w*xr9Q(@jP4FMa>qtoF zOCEF}AmG3ExBma<OqBo55G!WnYGiEWVkT$iYV?orKh3c>e$bveBM)!Aeo4F9X?9xi zqA8ACc*Kon&Of+@bDHQWNs>+^or9qVs9KXE$CDC|e>|1Y_uO?!-HF&x@dpM6DNE~Y z&M$rzz4|SEp33^O`tb4Nhf6pPz5eO_1L@zz`yY;#_valn0oUV%0&1@7RoAxm-?LT- zyO0-F-!DAEK1Z9rW&e}#&HBt2T+vVZ)_{nFJ<@wbSsy6e0MpI<j2DZV-(gk(W}AB% zFCJyzAy$7(H~TVP9Ll~Utp1p74$1m}H4==BnZVzBZrAb`;x9}r6eC_S@_9e?!O!!- z^rY;IvQn9;dL*+}geXxKGXUTL*v0S=Ze3DsFDm;X94wbc%~1>H03EDnmd(kEgar-& zCe!9Eg;eK!0cHC{$EE_d9vJ!akqL9LjAIrmHh<JYGB$r{qWgSl+>@#|4gyc^0xOo@ z=y@iTw!NirXdTeRynIHEJ26+kr3Wd0Ox^G(O-LOee%0{E*0)A{*e&*D|1rMv!rL36 z7#Hit>`50eXY%9=U^ILZ0Wcb~txJAd3KoNotBuP+UI2V^M$akehGO+&Pc~xh0rDho zktDZBtH$;`vTaN_7Hk8SD8i%=JCo-eoEr*^17j80`qFJCH!J`TqS2GscxG?#VrqZ~ z3(xF1Sg{qrgSj(%fj`z9t0!rpC)ON0*OYC{GH-zzP;cDaZ<)A&QoIy<Yw~0bcxCkt zTsUL;&;{g|qpqv38+`cYJcGyfDpDdE{ALBz8$F40y~besK^L#Fd?*79M$f0P{lJ3_ zCeEv|{91$!hR$uAdVv2nccVLgVU6_z0<brJo{i<ldP`E!7q-yG^1%Vvn?2`6^5QOr zOk5`3j`d*qU;ymRoclC9>jU=2&Ofogfr{5Upo`O)y!nd>#hwrkeoq_TKmZ&}pN3+0 zhtDOjzNv}{O`eWocc;(kV|ORdDY1Iu7Phc+&7KedccxDa0Kq69C(h!0<0k@u;LLeX ztUpBQw-!Kf?A$NbKW~AN$vb1=Z!sjr2F6dofWGN-4XkgPVgr+>t62Y#1qYT7dO+XI zxd+xaLop)D2S1>1?i>;8o48oe_-QQmcc{|5Invo2_BVKOpXrlE?C-3FJ*E#GK)~4f z9rib9F(UJa1mMr`c|P_xY;l0ulSAz9+=T$94+X%Vk@G(6Z^Yt1W=}={LZc@oz~5## z0rCx>po%3j<umG-b6NB(Izukx%epe`nR1zXf-daKI9YZ;mDjQ}cBh{(%6#B^R_6V1 zoZ{ooT)5+M&?Ye5>$m;PtWJ)PCnrEhs+(v(3rYF)Cy!mutV@h+Nz|loWYL#!9>nWp zZ)9qx%bdG3D5S$=?Kvgdt$7Tj6+$W57Fp8ZUc^OA28K2FELl?Kp>}r5k=ML3b<13X z0IPHXiyPJx_3Ks05&`}o6b31i<`J;(4^P9c#CmWTi{C(!H`5~Ny}l!*I8G5S3FYNK z6qQI}3t6LjA~Pi|j39!pHgg%`hDmX>8hpijPS}hCnDwxv<v?0_RbtCkP#bk$fanA{ zb7!2r-$Cd+Rm@)r;+oY#NZ+g37xkfG(@;uP3riAPtv#tAMRcH85hSsPKq$+`WQ?5y z?8a7I3!z|_B~f3{Sw7K<^?%wGHD?!CUQYUABP_ybJefPE?Ves3cVbN>lsAQ7{~#bz z2MS*bD?vJr8o8*X)|6n*+Q`p4ha?z6z0jrpNef!S*3_;!IV2D#D_08Z;uhR+dRwFL zvYe&WCVBId$W3*IpEG)5V4F&TV}S(87`q=ilq3kRkhYP$iQ8}g($@&YaSMovjX#sY zbQH4O<w#k<FLE?O6%-Lo=0XbA5f~^rbAruMY!hVEPqsuQ?14X6wt_1!OB%Ko=7ten zxq|T9M>%ZSGwPRbbdn*HPEvLUy~-wPPR9A1MLDHQ`+X-CXxLYZh*pIn7*WPdNwn{V z?sLS?rIA8kd#I`d5`h8M6v$(tvwp0csUah_tz=ci{0cz>s*<17x_B%IUkobWpqYAI zi{MBvc#&ly;V%jUy@foOLmiq%BzotdS9&F#<fdd}W95`|({^;n<>fR#$cKZwORB0F z{fP3jkr+l<n36WKF?<&C<>ZQAb#1F|U0YK!C(Dj5NS0A9l2W}^GU-a3M^ZM;Tx!s& ze*i@j@O+zPkDF1HQwra3U??XiSBi`Pg0>o6=@?|HQ)cB#C~I<0aY96+?!(y&bt@f- zl6KQ)L6XeI#2mOFwOKOr#shsl1ANT>5ZzB5l+$v>uj`GcAcQ*mD0e(Ok=b4vTJt4? zBU$!!C@l%S9r}iUx`2yWuOb9!?I&Ze6WI{*Obox}J(<!#<H1l`5fFofnr|WsaAfb% zJF$pwFm&Cp$dmAcr-Atklgg|N8$)QKeOy}7q-SPfcw05HqmJbeDAXJC)97|VE_U6I zqh%Y!poYV583efiax+;z`;G4EO3Xg~-Ztp8^;jlR`=u8lPk-e0!<ySb-J!|5CcBJ1 zhtXNn+Zd>(E~RdZodw(p)-~4<CS2#-u(!Z_S{VB27wXCSV5h?pZ+#X-dM-rW$FJmu z_e|qbVQprSPgZfZQ`Aeha2FTkU6x!F%JI+@WGYC=G^@j4>FV1=ygeERao)(f)f`fe z)Y)eR%;<NKzvOHjGw7IXJyN{Tn(6S}*4@I|x8Cdy2@<YwxVAZZ{z4&KwJa=1maV0a zF<B;v5SW&}q$$zW-UIru994`kPf?8@)(p|Z<^1T%J@8AmzNerngjR>X*Nd!K!;Okk zUrqwRR|``EvTB^kfmxI)6*a9@VXT``fvyEJt}1MkkMg4d!A2qZJnF1o-ZU=+a$1aF z5FHh1Htz2LUi91enl0*3cS%M=c0liroz$?)bqE62r=>?{qrFaM?w7rj9`G{fo*EqK zeq@224(U6r(9wppjX#V)Dgm4FI&YYTgBRj5GeDk}Q~hk7q)yWrn+c;Z{>@53Bl&uy zWPc*7HE5OUd9cI%M14>dm0bgg)J!^Mqk_bXl-XhUVG4nK79CP`U7_ab_|7bE?6V0G zE8C%LX?l%Cxn=Le(dJcA{7#<_THWYtF4N(HkPKP&L#D)NvV6ui<19XQ;2nt;Nv(%b zk1i-Ib;v&s4*#fVD1CN-p9e8BG1Hdg*UXHNuRBl@3{bP-BQy7i$^;8oumLO>^s|da z&S~Q>uJ$O*xoiPG(A<IVff=YX_Y?NRfzpC<v>B7svr?A{6~?-as7d7r{_cFsUGCfo z`3%r`)7CY8RXFp-4QTEwSL$TF4)kq<UdP*HeXHpKBwhzT+B-2K{JqPCkLG;O=3gza ze4Al!TpGM{^ILo$Aa?V`H_HsGP{4h*Nx_br-PiY)MmNR@y9kK%Rq!Il==?z61b)N_ zIw*4JFYaP0rHgq_D<iDDo(2(;U+jn4E~`~P)$5<nDffkLVBUDqfAg?4@p2`_#)U<E z92HtxQemINB7z?k2lYzUFe2gLL_rLSh8##zAw_{hf-KAnd6MBkG_O0d;Nijy1CqKq z32@@UK1GAXsIVo&8KfWpM5OCnXgE;1IMHK3;7!4tV4o;Kh5>K{QTK{O8F0~KI2o+m ztAx0~P2Yu%WPHucftufqriMh#%mgsxAcZpFpdpExbO^q-!+k5&APf8C!29G#aqwW_ zLqP}Y9AB^_pbz^(SS%=15fC6w1-wZ8(5O0x{dlrju?cX`kjcbxU$pCl2#_C~;74D~ z7|`%`vi671h5;<95W|i_L}*eF5JQFIKztDpLY5}&yZ4GDXlLRq2ntxO>{!rZA0f~` zv@Myie~6JV=b*tHGbhDH6!!}>5Xgjv(HV`FWFdp$1Y@V_9u?LWa?Qs?aN2`V5$0f> zqKrL<F+h_6J`DX+a<xDq8Y4&(9Nhuo5u#2^UBEwl2qA&4f`%<gu%qLnyr~j_%*9N& zG9+zdMj(ZdKaPrr8j=i2xG7e7A!<k!0&A>fAcKn=2kZ*xPk{sq(D#2>+Cr@kRu>Z^ zHEj^U07Q#MY;*v@PCsx7@%A&ajY*xhcM{2H(8meE(4!+vKurdKfASy^;K2pHfDDKk zG7-c?<J2&)abU$r2nS9$F4w#!3^&3~aaDX|SQEuVAIA~TlmCzg=Wr)W8aQV<cYi~X zNmhtu5<ttq2Tk+LRX~6b3~JPa*e&oKsmeWBz_ilg?<6FQc_t6{FOm?H65J@xFY@qw zDm_QK6|vFN+!G!!;>1gMj(`9h7BbJ%Inwj2yUJi^obRDU2QSfzDz5K`5|bgXwK2(( zLTLIk^>Ql(W#ZvO$U3wjK3NJb`-24qnt7T8(6ON4CpD|d#5xFxtGLmTsSi2wEfb!0 zit36S4djx4gdm^07Jci34E`OWVvYm}{(mo6j2CW}zseo)BP*Ww(*tGZ7Bc=iw<zLV zp1nVxdPZ+pJ<R)B!T*wOhuWPzA2)v~<DCVIWrgoqD)zVl7QK5px459?|Dds>tr4n` zgPEh(4z}Cq5A%Fl`M^o=Z|z+z)++($|KRBvE3O~=wwAYzw!2cKNMm|(;roE-!AzV} zBWbA_EcVm?1WDqZE6zuZ2=Nc{H`0oax-TUb?So1ytq;P#!^Os9+d+|K2QrR@AT@-> z9g^A>zF#+?+GeH}Yb#+z0-4R)m&E#M8>P`Is;e~MAcQyYU9f@<jMEOpg-&8JsRrzG zFr2YTAR2M<dhzX97&1tJ86-PaC*qI7VI~9_E1b})G{%2g1zR-l4>Z6(3f_P^#qX^d zk!<%9Ap$$cmcUQ4Ykl5?z)v%x$F;;|DcQ66D5$pf{#*y?lCiq%hY3p`XKsis6q*QZ z0rN1wH^>DU|3@SOM{69RUp3zcc?B_mI+^#!1o6a5fz8N-DhF*Ae?h+I6g&UK7Ei$9 zN}!qPy+BO$_UyDhu)$9Rb?_B-o1i5To>Xz&b(*s}TLEyWQ88~kV{RZ^ZYOHEV#>!Q zzJ(GSpe5#B$oj)rKhL%pcE1@OqD!Q7OxI_cigXsw*ZN%08lx6XX*qeLJ%|I9#iIO! zEO!wcDAI=e^Wt+|h85x39b>7YbhBT7uOnXS|Mb53XgSN-`Dx!Hu@|3oqAGpyO`emE zIh*HpHLGv2_`~n8SA!6qTyb-M=Ufra@m-G%Y|D(FlN3v{L>7(z17RE9gfwSiLQ{7| zWRNqoO+>a4nIF9Z`%Z{|X&e)^P_jaBgV}#I&$kgR(An6cpxAZQe!Qojn;58xL*F@u za7s8Un!Ye;Wri9mJ~Yj_jb=a`m=IC2;vOGF^RnF=QEV+KDE^m`y}r~51s5wGNSI~1 z*S@0+D*i&NT%l*=n&a{Nev+<*yU;L5LE2>Fe2b>5T20CIWIw-dywbtzLe-$Mq^=kd zVGLPHPWunAZf%Iwl|gfNs9A0L>qssBP0&rhZHuw_WHxw85mL}b<^wyTfJ1CG2?m2p zD)}Jb{oFOJ$X@Rint3h!Bn;0%d7mfdZ<vHUlo!NRLtBKn!JrOs>!Iw@J-Y*cGe$C= zV6}NAqW%qG1uYC{OIZ@X6-^4rKaaSDqX#o-#Z^)*B`&WOtr-xVv~x`Z(E}lBA&|6? zi0beJ*r!gCzF_QaPCy(Zw%8%oW^()Kq7R-8h=aSw6%u=u#XgGFPpOFY2u$ybYy?Ji zvJC0@KvV4Z(j+r_s~wg>sGfRFMJD7~6zSru^Kc^z4r8Jro>&=yV0ffZmcbQ-nRwxz zoY7;DfGDDG;-_Ca55qD-Ob`+voPzl<mt(<FP&A(arqCA<;=p@W34;BZRBG^R!tmZi zW*MM)utGg97>iWAMX-VHmReEiz}s@BT!2Q_r1ALidCUk=0#njK;R4g*%4~SI#pmOB zG(P?ox`Uz`^%w$@Iw4+c<R)GeyxsLWPHfB<1e>MX+{g3PS`DC$Vi8By3n)Ia=<)|r zj)E#K9hhrIx&l!a0Xr~30fpRj7@3@sn<Ug?3KDaFU@~servKCB)j*)3))puzuexfT zgrLs~_qq5;BVtGwIM7mj9M<NQZwtJ65rhbcH68Fe@<J$h7lbjXv4l}tzt9SvykxWD z!Sn6UAhwYR4Y>1$P&<Tqylps_5rk<BBeW7RrYgvUA>ceyZl+Ek0@Z?`!UC8)BaYqx ztQf=PVO9*}*&w(GCS+_F2W(-&{;p9XmB>(HNKs_iNJXlMNK2fMsNap6c!RlOf}P<7 zk-Gh@hGhr)fG=fWHjdy9d<t}y9H+?`gI7fXPLA9uUH06Ub1ObL-2Sc#pXt%xszxNq zGEr?B@?KQ*wa{}b)nAsKDTChP^O##+<bASwk7Vi4Y3X`yyW+TyL*P!O*^-zwdmwZm zdj!+ytZt(%+3TtK(3<<`giz-unS42XEo}r!zTqZF(+pYFh_iqEg5}wAIrcPyPw5e3 z(gzrrJfX~m35U`={8!fcXl-{8fyJR5buX&RRNh9bc6cNsKXnDntgUI{_Kd(T^$=GA z#oU85xJtXd*Y;QtkO_J}(ml@AUXv*B0Pog?`(%rsOGitkPiYsfz^az-+p(&9q<_;7 z?Q3gHDc5>P)V_s=Qd2o!;7{A2sA?T|=1j1514XbjkIP~7^Ey;eQ44EyrSyo8IQh5< z@EG#4k)1kd5N?8GooKRoh<2^_^#U>i82Za~%x%&GRn9y)62?GfELLLR`%u8=5JmXz z<tOfPw5P}hX>uIuW8gqWS2AqszJ5qD;9MhfruMz+>qVITu#ZdB<aB@7?s-E&B3E;V z#aH;Pg>D}>K$^c^S4FQ30tU>9R_=jua?3dEz<LSYV#mjxN*z?~Bkx_n$U{`Wge&9q zODEgA#^ovkiLkzcn=G>r%QA+qo;jN)ddlGVR#vAhj@G(gZhr$G@5n6H5=KocU-l+F zKcjy!>!l=m!IyZZ5xnm-LQv%9;pX^>0WTfc8UE-?jd6dDm?5KAd=V~l6WmA&!Z))k z(f}UqAtsX>5VB+>)SH1&{K55bi_3QuHFZ@Xwo$(70^?@i-!XO6c0oR-Y!|XB1LcGS zsZV7BU!URSMa+nKL=K)(Pm#4+{ygLYq@4{F#vEF6(;Z@&yLl6OD0+9@najlkx_;dq z$7LS%i^$1i7G(|2=>twEBM9mj2FPuG4VeuTC`=Z{A_Vk_YIdPSNYW)C@p?<53q%o6 zja+NP;N}R5P0+A$aAJ72jU(q=*j3#~+<F$jHLT6}@S{u(1(MPcu`!nrpBu!mZ6bba zSj&j6Ys~PXU*6{P=vk7S3cY<1!o;a|vnhUanszg?UG*}v3$}bOT%djR&63(4d25=W zHSCqLj^>t~k)AoMjRbvKF~*g%PV=a(k)9DOtr@IMc}EK^*{W38ds|f2E0WW@w!_Q2 z{Y%S={f8(1j;3M^hZ1CM4+gy+q@5A{W*v_u<#N$YT}W#MhMfXFTL8Uw8A6s)jC(1) z-?|MftqrWrB8K{Gn!s^$cmJXScqGEfAUP*-+Ac)GOR+?P00?QT=sQ&kZ-K9DT7u{w z$^u`JGzn8LG#L`vZ+qWyju9tG%`^lp9<z(2QeqhjnFPE(d`TjObm0z6>GR@O;7q$f zkGZHEi$~!%8`SQkE3o=*U)?l?@yAHI#I-B3gf(aauga-KVwrL}y(Tu(3Db+j6L&3r ziYfdeF@g!V_=NNOxhO&a-vntqZtju8XY!Ml)AC+Ln7>FJ_Ju>`hm58)Z-5S7Gz~E+ zM(2trY1-nf!C`>3#<?iktK{M?-D|+l?LRZle>kVU_vp^{=uSGcZja1~HOMrKxK&zf z?rC&1!F4pnbujdr#BDY)YW-R*_3U76`f9Ne*NdL<bTsE$!k+p5inft&Slb2fLVE4B z^+E4M`Wnow!z=Q?Xq%W-nH&5(#-9-{k35z!HVgVjF)bRa#H}T1>(#bWM=Pxj`X;bf zEq{dt?A0@cI%1A>B>7S|s@@$Xe$|Hn`mfw$y*K|uF@>{=v#VW0n_14yLGNVx8qTdj z?-=@;w!g9Lzv6E!f?k}@GG>)nNAs>Z?3v-O;Aq5f!7?mP+Xl#Uxca5#DDxijEBFli z*f~84{LO9)dj{6gToc~azQN<MUZ`t}cp1=UyAyA*B&-TKtrgF1jBpR(Z^o5ls~2-= zwl2ZA8*;n1#P80Q?WRn=lem^TE_S0JUt2!(n_ev;YzuR9!C$?+zMyw&^|zwmtZmip zr<64oxG2+WOHzr8(w^S3tvzt}Im~V8c=cFUDdm-G9zm(q!lNz6CzH460X<<*;ZaLh zFJC+KM_H5%@?jQY67T9S>9vQZK%$L;I$*}XN(-Q+Fa5a6BTe~}LciviKwqP<HQ2d^ zv1-vgCtZ^unoU`#?~ce_ymsJm{@1b(@C$dy6zvPi$-L*qLut?j&OvDq0oFyCuLJ_H z2daT~Tg#?HD}{i>it>CjIlZ3aAJa8b)7p?$&RM-inOVvd#CiG0v|*<oJn^ous7rmw zORRL}%vQN^>#1Ei)5NRO25OJufHS2#ai}1%Th>Mu18P~(N`ytcWg~S&R<m7k$dB<* z4-<dDQ<PLHN9OvUsYG4>+Qcjw*GI6ElxaEph}E}PGioZEvY1ZV6(w`$<i@njIpYmT z!v)LviRqeJ{quNG{|rt`2@)1YJ8a!g(CM842jvTFB}3r+h4<j#Dnf!&9b!1LOENM^ zKYh;)6MI>*exN1kJ+mWMUt#Tgc-|rsn9uIm+0fdC(~Dn(MfS#S{mP150$kQ^Wkeql z6{$r{&p8K8-yvl6DvucRQ!l=2+}yAnxjpi!^V=T()P7!YWcYd^bnhk*15G}l*fJy? zKX`C|AEM7EZP<~12#4GCX;ohE7w35Gh20b9s{NeNjX!Ir`Bz%S5->`nYvr?pvnF?( zyE`~pPvNb$wE<hDo*d2_{*rzNaxcB^d?EwGDb+0VvR$GRkUBy6Fb&!moYtWbcY%|e za6m8$lg{?2X1eYHBX8GtJh$7O3<WQ7M>~9yCm41l#8Vai;6)%kniVFMR1NDqJLLmp z3Zo(XyuM`QgM+GVA87N4hf@7fK-qz`07K6hklh}f&S95iUj&)Oge0ToB#Yp$usaeR z;RKv7h5%4&Fg}h}+%;6r`e!VE3h+0g)mAIha9c2*ow=0Q-66vrg60&0f`xrn5}?N} z^9k}Eczwc64C|H)nyoOScKp;$h>zOqi3NM8$f>8eT?AleSq-X6rX^JG9uVWsDWxHg zi(J#LCd0N1c1G52duZh$j}+la2Yr1A>amVOIP03HXdtCLm+4TdIWKW9&7WYUlLZ*i zn_4q<8t$>_PCDe4g9lAna!0YO7Y^+)CG3ybN!QN>AhaW!VfOPX2e97=F|1%}TRU6F z4k*%nV|#2eEIl*vd1=^Vf=;g_J^Fnbn0e#0e2HsOV2wAAobPox<UXj1<`xsC4z%kb zb9<LlGf8}Yj8?C0mrd+4W!`@KOJB7;0?cb_kiwO|KTCi}yTkW9D5)QxNsYqs6|MMd z5`cnGl6(lQ!Y`W(avs~H2Nkcg$u&s7Te~KHD+OfV_2VCN_rN~oy<j&L^z8H*rtx78 zU*@zY^VLWEAI{z?IIeBk6160YnVHFAX34gg87(eJC1z%3W@ct)W@cuzm|3!@wa>oY z_w<f)Bi`$X`dI5@Mn%=k%$aj!<`^7VUPniQo>fZ=o0gMDz)0B|`HeQ}l;oT!kQp$& zT<HU$NE)(u*?}HNH0P|Z3_nZX*@aO)C(%37+!?x&C1@#?XO;Zc43DC_91`27o#301 zq9ZSbp-$1OF(sEJks77CD;s*<K_3*L-LSjsNkJcMY0ij2+yeYNPymQ9%Vp)&Q_#z0 z<Y#P9FUj5=i!eN7x>a?(+7!A~O}#Ln4-n99q`mZ*)f~ST%d}{9trDx7h{{E~H>m+u zg3BeK5021okiDtkXW9Pvpja+S-J2!>Zz|oJz!X1s$?nYwfJNuyy7;CWr3>LVD925D z?kxtMA96F#2s1ADmztw(jW3m1<b>{+*TEQ`N!EP1GBERqzbFaNtFfWmKmf!bZ8aC} zW5Pxw5(Ylr(ss!{)e_3IW*o&?4H3qRfgoI(E7UmY?Pd<P^F1$V?t~&dR<}*~6n?s< z9M{h>U{XzayfCjyw)0MN_`gXtKSprQmgwF(qe2n9-Vln}dX)(MO1^5NHkFH9c&55@ z_>F;d`}XBSXA^vYb{qGnTFY)yoVun~L||y1<CMFsX;fOw%#SnTAo5syHsQIJBadm! z<amN2w2E3C-L<_%Q0Lz~@o}I|ESu&>@I|jEK|txKfPi)=eTBLMjk#4KgWU|Ht_zSx z5Ct|OvCGp^ZVM+o_gWxW)iVQ{H~f=Dx68T4d0#K&M2A}PI(aUMoB()dFJ$T9Yuji# zp+!&pwOBu$NQW;^Py#L$YuiQRH)@|v<Zn=cX^UpXs3Da7SYW}o16Q~=?kU7kPw>U- zu*iWs{j=vBnriHS;K3x3t^mu@oB(!$T|fe)%e`Cl5`|YEU={-B3j4bi>L8gMj<!q= zHg&pCSl2$IOI{cFR3e5aMSU<!504;B^PDxFdt=kWn4o3WR#6|q7XSC8s~0>R-t>%( z-2Ia~j$8FT!0!D^xQrJmyAc$gEQDUIj8XzDcq8Vt1`yrt85^VTc)QspV(aGy_er}C z>r`}{+nObjZu+Ay25#}dv<uBs@a6+9=1<>!BSR>O5wBx`&{TVf^ZX4qoJaHo;M|gc z8&f=0m3#s)4d<|UkyA8cFvX>@M8`1K;v^}>B<)05rlI1*fzT4$*t5cw%OmR$_Ym!5 zKmKI@&V&E+zv3dAA1#;<HA9AA7O42?kf3gIN*veQ5i~qUH9xkGa<b3t@7l7gScX}q z#6U5xQKEVaxPkX#F;!++DmBberepbyp~POPtX<KB-fP;m<}^dgwZ6s;#-v<EY|EQ9 z&1s#PZ3C~VyehZ1nl1s-lH1Ti8@hNP@U<`3*dp6OTmDwB$VcY;fmMRdvqp2E!yWxk zcnxbShJM{3aahOO<gJyqt3k)#81c-Z7_MVEq>qvXydXj8)>fA!U9btW<O#E0d$}@V zy>N<D_^V+hVFHz+YsVpXXmX>3bMW?H^&B(b@GIqKt4wv`B>r$2zhtMQTOzZ|Q60ZA z=Q?qf`gtbJ!Tmw+SC0Hc-p}agiA~$4=1_mhoM11Coj>RyFNL^McFkJH*=LCnl!EI_ z%6{?^d+Eb7oOD@%FeiUHgPQ!A14imbxtKBL0g1$4U^086mGKuF_5bKxc{n7xpJ%g^ z-NDv+ZkS}6BXnajaicPE2a@qgyUNyWk%FE+#x@g<3kb~-u;5kPrMt?~h|E>YdW;&k zDz`QTt!i+I>y#|92tG*a{d7SoWsbdIqx30W$|E`E8Ch~mb)EuQsH<9^3!jk~sP<Us z6SBRAXFL<3{PBUS#mr~Ix|+6{R>er(L!E~7&XI&0h~3G$%_j+GK`6CXk&z5F<wAPp za2tEe?lR&cI6+=CYc3jL$TONcLETZ6GMT#RH1D4rY9TNhss*7;)fkaBX;s`{yzL}L z8h?4$Y8r{+u&`e|xkYCb5~3K_oi_Gds9vK!(L^@-@u$#Q2KKeF_Gi%m=on?V%U7<e zL{h|>DW~aV97Ymx03Jz1G?~1ytWDe!9m9?Hs8fqcYfn#`J0hs?#qtIm_fobQW|AAP zy|YIFYUO69RccJPSN3_p4Y7^9#Y*Spg5}m@S<@wC!`fqC>iLU2wz$Q1lv(A5mx2iM z!gUb^)$PT8+Bg;Q$;rMEh0sR(>$-n&SdvcioQo8^0+Pe^jig@`3du{tm>X#4Bwz6c zrNfzhfxZz9{!@bzeTlMUxpj$*Y>8-B%I&5LeMIVvjQ_+GwSzBNBZy+lmY!*W$@D$X z{>8|T7Fov^PejQ#FmBhYPUi^FeLJ_5O|Z$wu-qB{G{P7kiMUJR@7V)e=1Md`7C)@q zl~WY%l{0YZezm|;04(LH)goQBVYpgqhDz|*>Q${{lx@MpCPbd5lg3Gey8@yYyUPRu zSYO$413^U9+4KwncFt?9z@r6comI->m4AI;*N2x`u^Bw#xC#8>6afB^FpQ12<h`nL z`eUyAPuFzm2acQR+egU!2h4yK#^RR{K*W1f_Is1_4CaUYCdW_I^6V8Q6970}EBIn> z#ZP-i#tcLPvPx`DD0QWq<=t96jfmU<Jv2IuJmVdancj%pg4u8C)Zuz1tf5ukwep@C zAMl?$?qH0Y_+4TdVTPy7B6^G2Ve%Hgh2!Kgn*RL~DUa140+`1Nkk>~OiIB%)``630 zlE^h7Bg}yl9>v%zf(eFM#mN){uiW#>x?@k~EPe6-J&sbm$!dU`NZb4tk-p=wdIQv8 z!zewyKfNWU^m}37s%go2FMX=~ZL^j&yv4kmx*=<lu`^ep>Z)*AHEh<F(N&Wg)}Ni# zT<4Y@C+c9uuY>D9r%&WS0tUCj9|>*-@)0Wvm5<$NvQl*_lNqx}iNtU~Y&saMap)kF zY+e)ypdjXR&w7lQh_VK}-Piy1Q32bn!q!`AG}fdKisTJPfPg#tBNJXd3Sq#T0OFzA zp{03)bM0s|!uATU`n*vxD%KW%Jv`khxiZO};^s(&`V{Bab$+67@?o^1()xiZJj0p_ zADeH&<b|F@uT|Lb8X@k@oYX}F2c-Lu`vRo>Q2GL-`CvX&ZoIK#t8xvyCj^(fte#J+ zq`%!)9`!GFQa$NN#YmVX*sV&*1?iZ3)LB3C?t2MdZ}G01dn7@ybNB<N&7>4i61r5N z(Ddb7_9XzsfF5;u`q)kA%Z6daOu5T^{br%e7OYUkN_j&vTh%YK^ScgsvyJTj8s^)m z?>yr_xEaQOP^5Ux_rC7gv3v;e9T1ibz4kdIdo3Hh*SG-QgALx9U~hxoAIAw(Fb|?6 z4hR`owhEC4-n@4`bvy45j@+%c3QeXEUQBn5#(z}o=yV1~y;ouWJTwAvJ%@O*<V3hx zIt=m<#edkc#anh7M|_bPc}Hzrwwlwt9q6+2eBvPc5RK&c7<|2&`ucH~;+)l5`9Za8 zbld0ISJ&^^_gZ~fY51Y$epqvLnMwGLYu5i!uXR{sy~X)s-OaSct2Oght@&{r@lo2> zZHUE&cc|BM?zMW0cG*dtu1WY>2i308WYehsqYwC=hW=rpUZ(E-%Y&QdDg?bb@&(3y zAHAM051kf?hLM)~u8|9qQ3ueK`haaF_fpsA@$zcjRUP=ke(t~5{oeZw@QTsR`nB>% z2>F0Hf%p;z{-V7$*k;ff?sV;reHmg4{cz_+plYq>0#2ErYJF2<1^VLUgev2*m}ouf zPM5RyOG9ADoeof<={uwcGenM|&i!NaXrB9(FpBff{4?OAUj1RMel7~^qi6#0!$|DC zNu&S6_w$>vZ~NYvN8W)$DR02f$CTJN{Le?0!=Sf)*|0ZuivjoRu2<}<t(677L!MU1 zhRYF#AI!Tf?5%x9cdeNR96<WEt@svND~GjunS11vu^ZE-*Za1nl0QX-2QOACZ+!S= zZ<#W0?e)^9C|0NASxJp1AkX3)`Y^K<n|Ul%To>icQXRZ_Njkesx92-2%nE)u%?dH9 zR!D30%D{RNaE*%2a^MM{URtBbZbBD;yeVvHQuf_U70b2piE}dGzM*cl)vupaW*a*f zP3jF{apD!iGqx$|<EtDM$@>Z7HlhUQ?l9s-JG@xEDEs=d8Ut>G!ts@;N9r@I#`T+L z^X_9qwYMpF{?i9%^vC_M%5$98>p0&iGCsoV*4%d0TLYolj~HXvXR9M<n<kUPFT0e( z({%09?}&djL^|*)Dz$(6^2N#L-y0(TIhl_49~&ZpdJg}aQ$uCrFHVgQt=PBWTBxsi z5f7xMbRe;X=%=CrCdlR%xN<Q9GZ?M@<j|ImfI9x_3fb@XHC9*C*gE5qI{qo!@z~r6 zkVb!;?g~DH&Rg0-#A3P6CeK<P*X=wHou))7yxv}3=-q?&e0(kQ$>4^c)c9c`z=C&C z-=CERqkU1ENdRj6U#KeacGy*)A6VX>KQUaJU<NezkSel#U^q3DUN}wF?E*YD2QYlB znH(T6xWr7+;wmx70aIwh<IVGwXg2(ZXWV)tJp32-*4Q-JxcD&Ra9v-Z3hjw-pq#6` z#taHMr4?DF$v}GE1h#7^e>y%L*B@%ZX%<FSmbB*YO~pod+{%WRCNdNpW!Mm4ZPEu| zE-aUD%ul&|ad7VdGi@UzJdLqvIAI--mi=WHmb6_%34SNr#n)=sxNvq6Q~S0#<Ng?R ziw&xkgM7pIZ=3sq{A{8(=%K#?F9eCL-CT(Do1Ii+x*_3q-rQYPP#3i}#<!L%MwMc5 zC(4clr3xHfvU=eQ=BVvy8SU9h{6h)uN{2~`NTR^e!<x%_fAR-FOZLWw0)JygF4(mx zsH<%g1A%((#!sfqy`+z2)m#e52r)TFbTd%sW3<<=PV<7%BPPrt!p(vq#Uid~&@|K+ z0Oj7)(3dCv-Y9BMfggfy%*+>y-n^vO{JlUJ7fMpd=nf?mov}%Z+Ax`1IWe@w&@mA` zp)8sO%FY_ODl+Z)B*|3y^3zIn@)An0!p@WC6(dfZa}%MQGXvVWnH!3nr$mYV)7jHg zZ9yw`R12;OPScfE+?pd9(3t4D);$E=g~u<Ds^XUC4%84KnuGPA_cdo~4GO`lv$2+w zEd8ky3Vx$BUZs=m&~My!RZ;7%%g^W=1PfAhV=rRl3MMp?2dyf)oZ4-Yn-c3pUx#?a z@XhlYa`WP9rglr<-=YLnQQ61=A(wEdMMqAxxY=2%0aKtAXy3nA=0lTE`CiZDT?W;k zl8uPLbgb#hc4vK=%;|D9??d$YJ&vGW=;qgH@ido)B%(j%u7Tv{rvQG#jrPN0RP2n1 zu>&3mTLDZzEBlGRCS=y`+X!FmE<8r6m~XY^eC=dj1xJ1ybsq5M#hYWCk(|F2=0!m0 za=n5b$`E5-l&ybll!nAHEiBi8Zm%>gK7IOR1le<}yTl$z@do&j;ZM!Uj{X1{<yKqO z>ftB31)dY0RugS~!4(<JJe~kdKTQ2$qlaIS&wK1*t%Y8(Vsj-;PY6Rx*6;Xs8>Rh< zvG#_Jsqa1)yl+b5Y*za0a%DlEwVQExv@S$;R<*4JUNp8Im?&#QaX}#!ei<Ol@mXL> zR+3%@*DS|4V^Y>8dmb}GF~nmAT()xjh%RDp9qD{q>9fHIuG_X5oVs&OXV|e#xCPrC zPcxr6EiX(L)wU%FTf!RhyKKpwT05&dCSt$F!6v`3DY4>2w!6C#6}j2xO)vOBdxgGy zyg_I+8E7QB%6v5Z`tdIojdK+x2fa@o%l=Q!rvGl<{%5TEk3^C}wkD4Mn@BQ44cZx3 z75RNBv0nC6I^A-YHEp_<%3@b7Hi2E&H=SKN{pb82F}fjsy6MXOgocv()3eIme9isu zuxO((U+CgV@j&p1Y>Q14D=|hrwjPx)Uf#d!Zkm!yMrta2_wXEAXR$Ke)cA3A*>=It zgYuN*Z?jGYV8|T3Vuh9+ViDqv+c69@y56W0<_*%%8VfqS-g!pJb@mCy40VnP#*|d^ zNyF0aJxr2l24~QB=GvNmg@Mj!R_>?4)+PtgSjJ`VE`EcrGIWN|(iywr4$Q-I3E#Pg zv(j}Y?K_8aVr&oDnSgU*ZWr#?z}_6h-kh{f-@%8wG;qf3Yr~ddY!BM$fV)Ix8UxQT zaPIQw{N5dec(W594AYnHPh(9(D8u3&yhGoao^%CRpRh*UO5f>!WOnzTA_P8R^$lTv z@3GGEf4LS%&e{dZHs<q|4SRy?Ga@&*;zG{Cyaoput0Y{tSr|Tgx|or2HBj@8rdam2 zXvws6*>kNiuLm=}g`Vqk5J2$vzRG8k&m^fdGdbsSokT)fF;p*f3h;ioklq6o0DB<g zFW3mO8>}~qH2~3@Y@{VUgkIj{bN=}wpE9hKEn(a_(nR`Rl^8fhOYzA4P`~3`xbt9D z>bv1L@cU;%n!$aXF5eJ%+lvS!xP1dsQ;7L#I&=Ha#hChpCh#*Zr-3Cp<IVl#Ah;rV z1ux~NXwPoPLHHr^Jol+Nko9_;?J)!?ncom+v-UIjM}O=M@X{9Xm#)scZgv9onUZ(4 zs<luy=H8;+BVdA!Rvm*ywL*i^0dcKGvPYFY=kTwX)#p2_YvoB6W9V-NF**7IgRBTJ z&EBXF3iWPIC)$<OR;jGG_h-o0!q_^!N#Nz0NNPhcYF0do9g2|cn+hdO_WqJPOkL$p z#72p^E%iPkgQ{1`Ag95M;{GEFRL7_kxZ-%t%)IeHyxp>@ol~~FR4OXE)9G<GKls5) zZM?XQefLf4Vp<6Mv0A<g<I_0xN_z1zbcdw{itu!8NBD_JGoab5b*N~tGK;CL;;IPt zRyT*RyX0WgH9m+1u3O1>4y%p!X9a@e%UC1CnAvzlHxXui=FXtYu_us9%xXhK@`QpU z_Y6VNVOTnS&VI_hpeJOeGkk3PJd?4+36J#4p?m<te!O9VBx+z?a#(7AWkw%QprfMr z8O)8u-mdspE|DjP7vmdr*T%x64qt$aVI&IwoK}~frqiG!1-NEChnlSbL45l;E3?vR z<d=tH`AhDdcJ1FO?Rqw^;$4UF@Yp|kWWn!%Fpe!^v9N*c$3fz^>7<%5`ebk?(Wt_6 zbjGOCM!zj7J;>jzweVMH%yVW5W)ag0Y)gpAWHS06XK%x2>x)ucDn>LX$XKz-b-Ak0 z6&WH^$ouHy2z!A_zQ@#Zx219wYy0VO7ZmjNA{>09m{x;~v~*Qz!g(VqrddkkE}%vT z7~tVi*BF)fw73Wh<%JrZmxY2Yz~7_kq$wQ56dqcYBG4(=YYlGpN~Z@96mP|rvlJ2S z+Vm<JFrXc!%Cg%fPb{{2ZQ)sa{McPT<p&wAX-tJ+e=pc!*IBXB-cn>@_d;NI9f;Fu z(tlz01k>oZ0=^=26$#0bx6J<-ej=rWzHUvtrhH8qR<ytHM4scOB2urnbB*DUMD~ig zR^|P+{aSa@p^i`TPO*3S6y)6ii_N0m=!}IkmQw1NCpyFpY$d?AVKZ8^3wvLQHz!4f zeC0jUR0?1VmSycW%eat`I0AIB(wjK6z|-qxSFQrESxi1a50|b>FGNyH4N25HqrrK7 zz9!S<7im1+6u5e#8idF_+;Z>>Wo5F{mTo?MSeMk$Ja9C;*7)jA$${Lw4A+@0teu&^ zWv(>;W?RTlrad)w{sy&dEpu=kHqL~QC_O}!#7zOuahS|6@vWk`DKm|$LTx~^husch ze_-@feJ82CcZ6dme{A>aa}?4DMe8Oe7a;8dPL0sSy92?bwUHsyR8MY-9mLngT(XC5 z?=<WP=XJU$GuosVb%D`-BHkc-Te<MtGdkKxP~FhtkxTeO{ez6pZ90=F9pqyICFeFr zrGEH6mD<%mqv?yZMkdohSj`_s$=jsW6X68ze2rGwx^|WG1{m#yj;EF*$S&aUP)+9M z!QNf;W)#xmcF6GTANBX`L5F%Tg}(QZJK}3J&8_;b9Fwl_#k=rahe)EsnMfS6UOqb{ znVUmyiem<$ZW#qLB0{80f3Y9i7=UI<jH+xp9`_%;z2<H@VkSQ#rr+gsjyTn*rM?iO zU%=o8<O?b6>>;5up{w)>DT1_N&L{~*+>ud7KTXGM=i!}}=%(PbV2&9n60_M;pl6C2 zITFy++HuOtQ>&E((x?g7%?b;GmnGaDRv*B598swS!6H-GS!L@K{lKlaax{Pm=tfR( zUNzQUL`5Bjx6OSMI_f8xDw)~&nZSRAl#|W>P3eswH7HeiaWJ6)y*#atG!QjMv6(1G z(-|h}PF`JeCjK5>Q%LMWiYI3w`lcA?eYe@xCLtkcU??y_(sUW#1}NxVz-cpMDzu{3 z=Qxyb@r9-|HwryLn$28R^H^Tb$FPuDhaGk+!nsjP+@O}2JdrCvJArBhXY8Q4_E!t5 zZb+$o7I~?rN}p8-jYhmEq_cQ}dwV`_Vc=yLjfX=5zG+a@r5u6e6Z%YBNN&cdvS14B zbLvQ}WD4!C%#m1^l(W!aoC0|za-5Xa81a!(Ubn?x>%k-uuUCnX$Ez5XnaSR>E6oo$ zlfE5a5nf4iT{|tPBrrk_HeJjo1`n^AcapPKn8=m+y>yCc<{cp|BOL++IHL2`sGE7w zBO9FL*>%2iM$y#TyRIEt1F3EC^4`BI^dJB!Awx#LWcaD|(3e7dzZ7Ev6;9(vbBuN4 zQ7IYE+V>yjG=B7?H(jdvNZ;1eAKeqQa|WHl&ib`?i;zk7$iL(77H<!(iZ7^?yx--0 z<_l3PBT-PMF<p<u_T&}1N-!Orr1vGZlqjZ7t2p$LpL~-z%ZVI#DF;jC#BSVLQCU(n zSwtS+ur3oSmjL+HZJkc2*=-$<Rk|DoYA!I7+MM5tqjMqO4<@9Vv9n7psF#>H`qN<q zUOGLa;4TN#Ktpv}FP8~e!7MevgiA)|0Rcf~28zOk!5TJ)RZ?)C)0&+i)K}7<yv1y) zXK2kyBnLI|F@h2@bmAOHI=@-=^cCQ;S$4ZDS#g&-hs77UuR28<r#yI2eK{^pNGI=i z`n&z(U$k;r=NOo=pG4|>sQ;ea{gXnS;y+zPh3)hK*1&(!ZQ9vc{TE$$g3^{9sxsQU zWv%!Hg@!R$Nx9w%$!sEfK9P!6@#{C`JPQ!TVqv93gSo=|HsUs)M7e>jrvsYy;ip+u zcX6X~u&BwWBR>}IJwoq2o$X6Ir@7f#G)cpY4kN3{=gG$mx69|9tWW$sn5;8+R~RpH zTMP{Z?|>6$fC<hT5A#&_Yn4#Xb!oCTDvt?M2SE=mo*;>yniQ!#D|D7VXO9iDuOgn6 z$R~XZlM5gZuZU~XIvjc_eA$)8*Cw(K&&n<x75CD*ee9ZG$OXY~4^%Xfl#)m)l6UCq z5Sgfte&`;FXpDYp-)=QHmo1gBHI*;3;FDYrbu$CYSDv;>MlmqQNrPx<O0)R!@e<;| zjSNA>K_ICzYk7#$ART6Th@X~O6IQMt%dfiM80KU0S19&@i$NWc$~P`?wY8>SfB()E zct~fYXEAnkAz@?MFDxuloU5BG&@-LZXZoy6SM(~^(aKeQOYSN6Ei0yO4x|?Bl_XgY zxnKqlED|+WWvL$%sfnI*=S$VsE=^WhoM!{KbJppB1U=<8#3oVR3gW;2LSvbuX4E0& zO`Pojg+WOD1VzYlHa@Oi$&{C}U#qov!%85L?-2bHCkO1s&CLzn-B(up$nPtuV_|Ft z9&PGe;eI6%Vfn#8dK2sDuL-IrsrXWT>DE0_QApf<xKHA$bhMw9ebaRm)~tNI$=H0{ z?zQsu`RCHJ*Ze()&HS7~zQ?}7Yr%frrsF<(0t@Azgw+wH1dD&zwk)Tb9aqLp3TiXh z>=J5^jWIG36sZ!<YRwMpM=?jwaF5Q>U(cyVJuTl(Z4|OOBc+SxUbj0lni+wH8_F8* zfLU?O@^mgc5?R%vnFX1-4vXq63@=u=Y$H;QgYZ)=)WC|22%Vrk9N-c*O>^Aob~<po zFrlo?KSCj-^XQEI?)`HR)}`5u0Xm}PA=+br77+_U>ogLAGh)F%tdNbEQ%;s>rdF|K zd!AT>XYM%gMo+lUW==A|B9%2Az^z|J771yOfuo)MK;;R7Gf&iQ9bJy0eq2jjZv=9N zJC%bUG%ag+*K~(VW@;9F0r9djOai(G3w5IK_y|?Qvtd&bD5vuc8D?FCj4?{hi8mc; z0qGc)vbP@dq_Ym{`)0?NUs2<d&}<5VN{7^#J~e4QUBfU-+3UTL!mJTXJ9}xS%jLGI zrpDSo$M^t4dm2Je2N*RD>Afhh#tT5@%AF7<D+2MwYPwf8$0{L(r08AQKi1bp7}amu z3Mi8bl_C}rCs~NvbNlc@&#aEltgXSmBD;NuF9tQTx*qb%3N8XNLePo3g9m<XuhEVS zzeQn)+oOL6K-n4Tuo6Rdf(FRds33b8^1(Q`^BpV@V{DP1WEaCI|FpVEl76psftDmH zmIgij1+Y+WWUuO8N(=F*6Xjv7pfPLiU!)qc%!v>t5Y-qGX>h2ln$SsoD;Ut(y{7jF zV|-i}n%`Q@mG~g-(ohp{Y8O?b8&h!)*<Svfz-}eNkD?a4xkhxm6oHL(P4Bz-rLuM# z+&6f?usSbla!PK|G=1iEcI)3*1-IF?yEB;OhUC<3XMuj%CyS%OEG+8$zL@o>EIz%v zX0=;C>fk~ks>DT=Dyfv<cTZBR1b^J_e74r#q%d_-caB<;(8{}lh_L?t$fJz$c7Whe zgZl*Dl^fwPa#6Q6gYgaG9qKiraa;4MXnV>yuk(=^J|q=@dPVpb(x)vXmIV*~<%`3o z`on+Up8tOYSS2enprwiH|Gq{yD6Gk#%A;u&;qzEzocshqhX5BcDbl^JT#v_KC1cYD z^NF6Xfh$;cl;FWixB~G6?NswHk#e8@Dv=v<`A5FL!$=)k&%I81u`}J_VbkdRx#jVm zryZ+zgJ=~Ao(L|3c#v_JvESN<c#?74I%Y=!Dal57aDfO-=&gD1ft%8*+9?hoG*}$Y z<nxo;O6lx(s5}OexKA`{k>?@kvF7zoD=-b6TgQ4&Xl2+MPpaxVL=vuOLSVAdZs5$G zTt9w1zrg@z_&Bsddop?{Rh>;6>$+Wje2{PrxElc@b{snpVANbQCY3T!-a)dBJBDue z;Q!O@_tnG^?S=!7ze@NhUzz#$n#?re()|b_m+{=^Sw{s>i<qMw7??kdmD%|CFfxqk z{Z!x?a9Vh#XAXPyzAQ)b(_sYIs4$j0jX#I77En&d#wcK$b97Ol!NsL&I4ZUgNI>~i zxNxT`SFZ(#wVjoJjSXo<q=VR1J(srX+`iW-v*`0Mr0`j9vy+<Kz()l0k3NShjL_0U z!@WzF2vRwzp=>4P3`i@GQZb_zEI0|re(1hfj7>yi0RE8qd?8zm;te6Ur!6^Jo(w!U z{oNoU70R6`<X~Q<-+@#gS?B+T#^)XM-W}fwo8#uR4Y*<!gA>JahpVM`+%{t9Mw-{h z8$9701u5$C_Uhmax{Wy5P|}FDm}xp*WcMW`l4KLxl!ZU}LPD?Hp3~EAz|qB@vL*aY z*xp4Ft7cK(0WZsrqBuk}{@$*Jd)`JGznDZYMpVl^2*fs@&VS^oo*HEm)f8)n+%r_9 zsu&QA&~c)N{suX64sUCmg*SI%oKm(ERQRAAW95kLnBMuZXvwe0Q97|J!NOB8HJ4UU zRL-XrBYwX)mD(zvpapZgm76B%^3Z}%!N1+&QUi%S(b2y3aul7>u#NebH&~iD3AKWL z`GWN65&!KC|HP91BknC?0yH=Hd-^{je#&l532CTnDv|bA3@T+mm7_6LJYi$(pj`HJ ze*8gFn8uKa8D-A?Hg$<!d`!W7Y|2Q$&gFLZ-JlP_D4Yyd^3JeN7c|y`cx~VC4P54R zrQ_r6L&w|6ir4$?>802%b*B<zSei+@uWU=pz=YBI`hj6W8k^-Jy1A~RfN&4Kd*x65 zgtRv13mcui@kD{b$%#h)7Zd_UF}ktpwM|vH@=>Bj^A3H+@%hNRs{7i4wR79P(^N;d z0DcpfKb^pN4*|=Tsq%x7nx5N?H~>)-0$!Qkv4!cfuAECV052JT!xnqCqAwE&j&G<@ z#xrrQ($M*CZD&@uX|8Nq=7hz38hP&8dVYSQG9?BI&6sbQ+IYO7r}ix})0|bYg1xjr z3j(m=BEggJen`?OWQnUC7bOl!o49Kb9SlX0oLw|(P2f<?3^j+gC}0vdfD%$BS9qO` zanyfYVYlL3_AzYG>M&HMXy$dU-z)v-nN+$F=QaqvQ`n}THsu;f2$XUvGjchoLGP!U z)2d7NSdG!ITxpCb^1NC;;zo~iN`PjvFdbq9wwCctm8?Q)<>@aIpz~2Cs|=v?D#>@J zhq_qaI4ci;TiWuv!(%FI_NMy>hEh0U9pw5}+#?`HRQhY7yETvEdgkmR8<REW>wycS zSKWGYSW5>4k~CPip4+|*(>QShKlBo43IQ`;R&F=fUPK3d4#Na5%Nc8XRUP{{$>@rF z$Bx$v27DF;YDRTL*<F=TEUz@Sq1a@OhlT>BH5dlhvuDPT$6I|ljv(1#iKKOAp<e}a zpT86S5lGHL<P$%Bk@QU8&V8B(hGIMXZsB;VRK3CgZWb1?K)n<EFg4Ou&yD)ZA#Ra_ z$ggoGI8Xl&Gi$3y7@H`0Pi)5J1ID$3nGgK|KT3LT1XYxblsWAuhA2CkO)u#}HEi^7 zGdpgu4MtQ~v|peobsqy9i**b=K4n%$S?S6oO^fU5^Y@A+wC<UDf5VI8O<Sy`F7Ubu zGGOiJ*+Cj(O&0SsIYW9Kr}{1-AbBG`JnZ-VG8gNCD%$8b<#W%+mmhIgu^n(N3bd3E z>CTfTf|lIBg+OclZUoGKVZ~z}f4J7CyCNqh>5YZ(x8P~WKmfNpmTP&xbw!y0xGq0{ zpxD%sy&PMDXxe0uY3@i-A;@Qa&QhVegzz;2!8X4N%JFt8qjqYMFZP($_n{s~ur3_^ z+n9bI2wH~P%{{S$(no=y27A*macrZp^uTv_{pI$4PBpL<pXAkzkbk@V-%3bD|Ii}B z{7<(GQv*GHrhgMK`sbqmNE-6@BEf%fIA<uIejc4j?+6{V9U#8h=yFJ;9bZR<!Krd> z=Tbp&;Gjc7RvL$DrQ0+<Yn-ZA@UQzcVtN83A&A?8*oSA9YXuv=OwvY1Q|?<Fb_bdd zk6Bq=+dXjFV$QSxVFC5tQh!R6MKa!mE2-XFqV{GCfBzn$S1cG3?^FJ}&z5>0WaJLy zL9KO^gGNRt{}d!c=5Vh5zT_d!K4;oYx{)E<(ubP#)p&R=%B3d+4uhQ{Y?1V94?%Y4 zfHDYh-kK+nKF#saL|}s$KubQ%1ahZgvaEIzRz`0$AU4E^ts|K_F<hx2w$vSC9Us8r z)-Sh?wJ5hCCxlTk>L9q&U{5&>%qLwati-e9qob%lN-guN$tj_p!VN7<Ee}{OKuRJ& zHdzT!qW*nztE#B;M!29g-c?#0S~Ix4F%6TR(^bGk0|keSQ-WP<iZ{H^P3)^d>7tG9 zjRQ7@L|#_x-lRQZ^Hz~ggKALCf@wkVD2!@M$B=|*poMI%k$c%o1Ppc5;tDMBGKNC$ ztXjC|-BR)Q-1g|%yo{&W@&^`U!{xM3noM2X$foe6X5BBY53-(u3R;B`QrqU)m=?!~ zsz)$t3%_ME!8LHtoN4Ia?TP@fEHfH7enGn4#hwo^y6mrG7q;oHPVqLhz$&nkERrwU zOk-2D{=`SJQl2|zl51Fw3=X<N<A_94caqg&&`0^+I*;Z0rS&Sgxnnphw+XcsoZR(+ zJXW7Y-fAB6J`1oNFXD<sip$D%iPZBw_IF49^l~q)uB&8lT<+B(lSS@Jb@*4U-d;B` z`Kn`!xI>l>NPE5)n=E(vxS;p2;MIHD6#bvS@qGG(b|L>vAw6%>4p~7+8d3pZjgxlc z*Sd@8nq;UZVkc+ZlEu_rJ<eTqq&kq>o)+iXCrY>y2zLyPa^6L9b{u!Ak}ysNKnKlR z;LxeLF}Q>5lkp_ei9Z9*1X^0P?gX{q1US?R?6eq>=N&RB4NCsFQ@7}B&m8+Px@g9C zjnwb#6epWHe>tHFqCnZp=h>_HUrzY9?#4g;iSB=P!v9RgQ=zD3hRTn|H)meQw#J}Q zrc@!V-jh#Af6uln*+3*hhy#trpS%HQ(`(SUk#RoMHCyBh?&bYMqMfBg@_csJk9NGn z?l9eM%KdCgXUi+w*Mj%H<|OYTZ%4l(5c-MDIXQKZ^<tS=*LmiQ?3f4-PMQ-ZAg}IB zETAo9k%XOj=6o`m@K(--52}qK!FAg59_u^DkAz=t3dQf_#2g9%e6wP+4;6nZm^M`& zg%fG!&<iK7E<V_Z+7^-&ByU4|)};URf>&T0elrL(o7<x<x|uh#bna)7NP5q|4A^1! zvTS3X-%KCeorW<YJB5>HUW!q79~O-f`*9<N?Dff9A$(oxpdqDK>B^gs=pvr=Rwjn8 zV!1&oSl0giO!QjD*@Mvk{vi%Ew%j3(H)0^O9zMy6*OD1^U*SG%jo8`-xU_(cL!QEX zu=2wdSiI%kt~bb{V-N_z_Xy4SXPczM3dhL!AyI`I?JZ)W!cNN5&fAT3bqhqOTn`=b zTUiu9ZAh>iSf}Rb`~9Fs$QV&Jm@V;KFZST4HOQr|o!JZCLREnM!c3}+qdpvs0T`{` zKn0|;|I4J%wz_ihpJkKvH~7CyL!^7%wfmDKzvnYX|94vUPtzd$pG`wt_V3KBLUGM< z?k5u88n;cgn~w?|yhYAVs-%V=5{kk%2A|M+pWytj#F^>+`M6x0+vP2<=)B6HpYb&h zsV;38M(r3@?PmNsCBx2eX*H{>^R1ir!Fs75AJqjF990;V9F|J6y4ZlqfMFX2LrG0x zheVLt%U;Qt2~Vyvr26pg&nz}vde7mE+g3?1(G_=WShl8^3hw5&8{k|VF!1GBed}$T zyA$^=y%5f2nnraBlWfW9xoLzgX#KWrzeba+<+8q5(0|_x`|{}nduI7qlz01v$xj|x zOSXteS1q44){;o0k`UQ~?`{4%u+&V5Z#BaES}L3jtc*E%;ZLV+Q59+6J`Q3#=FDfq zAf@FRrBA}|l)>M3-JxjsOI9t!su^()1wX`UH@`a>!KID3cCB5k+m$+$;=o_W2$dHG z_eMGmCkQ(p)G(JfkzP3MbzP;7&D997|8izKYgLG7F69^k|20@NR9*OseAE3`+Aasm z!IX0O;)ub43YMec{BDeKogi{4nJkwyP}H?EG#HeGWv}W4^|$Wyf<jcNeHmjAx&UQA zZamAt?BXW&c$NQQwfIaf9It-}WV1vur?w~uN09?_b2uGigkw#Ps!??)zO5Q*Iz`}& z*)~QZG*uJDhIxUWm*|PKNfI23j$U6q22V0`ojwchX>-Xbd!@cc+6pQQSW^urlX0|! zI(!ve<^E*!yG9ptfz`ktj0YRxB|1+312%;}RC-p%5ocC^nO+iwL>T>NRBHRIF#pe{ z_aAjF{wp=G1zH0>b$|Yk8qnXCn4uso+xw~e1DgPvyA4@f40-SSjXjgC|LeUjP9D`x zXS_6>Nz*jFh*u&dD&qSWuXr1E_z)_Je)CqAmxGD4rZi9Y&JNNr3`Ym^ljT|Yr5Y`= zZ>j<y+<m}4IDsMSz|kv@KCj5Z%o*r>v_@Mn7ej<+QVw2v{62*onhfk=K-6csdE9!s zN%n&@k;kc^Y!%Kmh~@$u!EX^7f&^NDnN~g+Eva;<1G;CRj8Y?f7aLh{#lE09<H-Zr z(Pb;|#?(~`4ubvBmDgT>7SZk*Q%n!iPBSd$8S|7Ljg%nNr=S_7Gdgs*0nHg@El)$O zhpc{}0heb)T|X)(6D#UoK^ktsWTus)h@rbWi<u>_g{ey4)&724WZ6%o3qCKvfPp9q z4&!*fAXJ2Di<jH7LvJVG25z(-lL{1bdS(y?IAKNLSdBpT3)(D1j{vur?2Okz*?5+D zA7_F2ZUJTB<X_jhw>WfWz-Qc;{M^9*dGr1wdi?k1DFE#p%<UC{_J40$f})lc%I8@k z=#vvayQ<z`3R^)4uC7*QrRSc*PL&%XAQp}|0ZK#v%h4vKft{%n=OcoGf-Ln3>{Wh{ zr!Gynt!L2u!E>VJaD64^?fG;KaXcs74X+K)4G$Oz6O>qJN)hoD0~nuRXp%Wz%ZmAF z>&hnd5_J?41#mFSBiX@teTF&9SVvY47O#V|nYj8>DAIzwO#YtPupOh(-{wyT*aZu= z_jm#7>T5?ZLlvFooR&JLi2m$&rhSUyHpVzARVN(dnvu*SfkPj2NWzPFYlUocHRu{Q zJ|=0q#DeVycX0dWX@Hn@wWCJk(?rqzyF4c?eX_Q}`MmjWx(<N_fhM@J9e^Qg4c8%( zGYNaRU-qr73yWHczMuvVRV2ukuXfsj=SP3CmyR!FKl$}n7)yrvjh_nlTD112<5Ncx zITX}SS$>d${qRILXR<ltru>chXKt@>L+BE;PhHLYyP5x1*p8{tK~&+Z3$EU`bjXxR zbj&Jgu5yl(<KAMfOzAhOA3WUM7`yf>$Ln80u_V;^;Z(o1RoUu3^Pn(D=+ykQas_=) zF=aB3l`g$UxG`Y)j^SkO_uAl1C&KW?Za}UdW@>X&GJB!z;`_`%teDDc4HJnvpmJja zk``X6FG`hfjms4v1HfN1b^OBv7C<_BIBchoOyr=l4HogL4gK3g?OV4X2mzGX>OwR- ze^ma2g>*Ep<V%S0kIC$fA(5YMNhDn7bPFE09DfCmWs1!-+E3d{{C^D||HuCRZ+gK9 zd1+ZtCbV?WS_lwy^no~60XdwhV$AsduYBGsVMVp9YO@<BmP=7t`y>5+Ke`El?rpYA zWg#o}JQ<T|91|~3?rx$4LB^cR)^bkOzXT9qft=r%?Nj|yoRN4NCG1pP7yUQVe4vZm zx$D*+TR!kM%r;dOWLsb81+Ue>M>CnxTn$OEsrgWaRK6~va~IkjzmCK?sUS=4)<<^V z`~<(Dei&kI$M{6v)f=q@aAb{D{i%^B5*7%_QW|QX4dZH@`h%E58}P;5s46&7Ric4> zf{w9+@m|IRBjv2jHb*0!66$R4?%aKjsT=_2NI18YS{<Q@kHJFg2NmJvf}Z{EBf(Z< zy?O?e*6cL*-uhL@s&DN`<2h0v294d&&~3#itIvs_!@NI3O^e4T600*;s|ps%{*`2g z^)k7ze?|oA|JR7{k1!sgs3kl96OFG=fTqEl<P>s8A3Okj9wIATlF<MRdL-~`=*#w+ zxsyVhNzt?n{3|8lT}VHq*Owoo&P8oX{wVCy7wavL>2{YHlbY|(_qgco1F0dZ6xwNO zOf{zR#+ta2X+f*Y?1k6EgOXA!YQ6apKq*G0(+Yx*!Hj6hEgNMNv96lNDLIC)N5Ny0 zBfJn+*aRA-J%kVjxXaTD&TIUxqV#XJxpos~g9<RR;5Fv)(W`KT5@H>eLu>6>rsm+x za%*tqBf9J@yMQy6aQ3}Q-DD!q(q<(K0>k<y$0=T$+<k?>5*4BWehdd8+i@P^f+DM> z>7M01KpLeF1blSd2e`PoOE5H6;)Os<C=D`nNz|h49_@9%b~dc?`dsuV`m<B3V5(9& zG=t*TYRF9hMXX(_bM>41>^`>^-Fv3nGIe25$@@T6KDMEigA?7awkij1hkG`$<JySX z1$``#;XDOrsYZ!5k5E-(wk3{DP2Drf7E))K#nB!f#w+N$-wS^j=a~?HZ=#OJ1V0#F z`A$pe7^yd$iK?@0sckiTKj+D@*$(noKGjEkLxZP{Md+*JkNcC?BwzTn{Q@uiy`H3_ zjahiFP>;EOS75UI?O#>LTikWW*-tA0{V%`$8xJV?|B44N{~I1q{EtP%|5K96%phQH zrT6zaW1(PSH7ke3hY3@lWn&l4WWaggZW3148l@*C^!DYKAsqBbtt_}@wSOa&s=k-^ z$a{DQ1@&ag^TwyATL!@@y4va3X4y^NrXM~mU0xcA>0!EY*EU!7bSH*}$~diYTk0A? zt6D44H`#}7sMt_~DF#7E22|vh?$Y~hUV}Q}@!188MRS(2<P*C1P!h1@kLR^67|LY^ z@=aE+ALbJHY3Pk>W##CqzkoefoI2;sL5W!PyJU-$PHj0ni#Y=r0mEW?WSsbOhIN1e z@j%|AFjYA5Ia3q^G#OrKqv4dp)VL+VqVI4#4TWFxOE9>xnnSg~#?%1IuW9P0Kd_@V zj4L6aHI;3qy!~DvLYob<z2U*g<FRirvDFzK86?QVAajbH-;IYo2%t9Os1dOwcA78m zAbYPphN8$Urcdo3cW<y%^lEZ&?=mnmKrUed&&VNbMjps@X;PtN@aHvuIdR|#!##{Y zr7Kj_Y?l%@+}!Hco`JumE)25s*<*xnri0W<*B6>7upCi{7NMZ9elwKqF@FGuZj%_J z9F79OyTC|pL%fM9^m7W|OuvWsqm2$>HOMIDB#Xqka`#;l34?u$_c9=$j;$`Z-OG)o z^%5*?_Li_>&O0zpDp4BYcKg`*VGNzdVjOVxt-fkSxx&?#weK2Q2|S@{n07b8sNKPq z)a4IV{ik$iXhGIT_BG^Rr%5nV{T9k!aqIuO1^v^&{?hyYOVRr;z3xvX?!N`L|H@{V z8U7n^B2zZEw*?3R9aXJt&G>Dt94!9}y8aZTaK}@|{*aBdj7*}KSg045lpr;qTO``W z7D|)O)0ktOU`NA|r)(3f1vnX{q*&nc{^aNCkVg{|z7_#5SS(QYFa5>=-hTPgc?tI1 znX)or`OrZz_x@*#W9y~s(sk?Q&t`}0x((XGa;b&+&#zm>Lr9$?R}~`exLYRuPS<>a zmn^T|z#qS7qOd&2vwrN%$YOgAX8kyvVQ{{aBzU9t*IC-(fHxkndVX<&>oR%*>m$T| z@4qq%>|%UP*s+51GJ1mS`|)e13+sL2iZJkl`88?>I`9M4Sa%w$6sr{56w6dRtkIXa zUv8+@H4q|DBoR80;$3rOdVIRKIy5ICCn6^!$1f)iz$S><mm0l@Kf4%IAICaR9v;t> z#}gQsIm6}A^<7sd83(H=yxbByBw3Kfgme$iRBdOR;=FT?)f|tlBE=_#%ZMn0Kx~S| zi=GMphX;|KA+yN3cq(@8($E3RWcd!+Uj5y;0mX580pMGEcmt)a{@e<VDT$%)dc_=S z2=PY9lxZ<ST|3~Vr#S|Q-WV8JT|`k}WC)=bnJ_-y9H!cTFSRa)%#+D%Kc+f;<{5sP zn8}XUmwPW=X;5VeG$!|08dNNlRuLTJC(YcmkD2lKoYBSnKE)x2y2*;J6@4*@z1SW& zc~uyoO9{u5WUB{p$W1#(UBv!OO<4!M;Y3qv9roLSC9rOy)}DD2BQmkrKA=1jN^m3v zK$<Ca8ehmJtfKB@2#HY`+{TWlEE}jMKbpQct!@|$WZmeVD-;)>w06u*XK@<gh3xSq zp3=aueivtE`)xyl(ts>W*VZK`fuoXS*j)bo*GzR<jjb?k-mzk@ylkRfY`uakc8b3x zyb8+cuc(wXnP*ExGd1B{WWNUwP7`!IWbj|KE-^d8?6J%aLmI3C0phX7gCCKu?-8jf z*s|4rrtx2S?)^x`NfWN(S)F5{Z@-Wi$NYd3rEIc?KP^a5PNr;9W!|WVvzmO^U1sAG zeYd?wW8PhiqAV2l0E(}a7(o`WKFn8K@r~324)7S7q4(S+q<>Y4vmO-`9+6o5I;OPv z#cT9SghB>=O@X`4==<p*6T6wZ=cb-Eo_3FF|4tSdL(|#XZimrI?ZYM|j84?~(J?LN znjY}tD>4Uzq`uFD+aCU5aLQinc88X+Fpv#@jqhY?y4P_mS$uWA+i^c#kHv0EX8zpc z?i68ornsGNab@6rTKmc+hmTR8oaM}!S-cF6@7xh2Dv1>`H^qGNngT*gQrgjlhbk76 z1CD~D?RU841g3q^nE<K@&HdmxvE^8kWGhraOH{xGNmE3$K`~OomgqM~#me#ogP30u z3hA~=)l2dyWBxgmaAUB3$|BTn!Dz4BjHFy+>=jHIW1mU}c2s+9bbil8Dq;ou{Nt`} zIURDGeY9qzD~>#sMiDk+;kb<%cdP!mZ`5tI&sQ_qRDh&MqPAr}vD;t`;>In1&M#Fj z)ANzN2ehU?9K~OD!1Y^{MsJ&^#kl)sMj>`ob@%;G4U+6B)U5&XIyG;dv+AjGmNWqt zk7;1S$TazN)A*wqG+bZt!j=d|9jEy2(Ay3rl-nrJY9VGCoO7IZQ(A<-7bvU?gi^AM zaBldA8tr>q-XcJqbtiYjUX%EoV?mpAfbuY5%(7oyHg{WQX6gnrodJ>!IC0&uCy_ZZ zU%nPzp#<K3)ecQ!YEMTHGuflsY&!Z9o+49~F=j}$CgQ6_B=}47o3-~6fkAWf4oaZp z%Je>OYp8|hM4lN|rM@%eCixXXyXv+_v-tMglXv$7?;oP?WLE%pq3yh<<nAGxux`pL zaUa<o6(89>7Pux@yj~-4ggrY@mvv%m|DD?>-){MJB5TUdZ`PP&7lxdJwffES+mcVr zeX3X&$jyk4u)N-o-~_#Wa8XcrLwRsf(7cgp0;?l9lWI5L*EmvaX+4&gyO!$dmks4b zW#u|X{YfOu%Ecs_EG(7j!lFPLrUDl8iWImV0(KXg?Q3^8r64fbE%}=P;)gSm4CPR) zaCtD>t|aFByClERUX4QE&%48p-Qq<$`pXKp9^U(=|8NirD0ewRExc(!S=v40sFKzs zZ;0#Qys_VHMV|1QvO1@0-Bkq|s%t$oPiaecoe7iHaU9BPkmp>gQ0WjWe$UYhGB`^P z)uPnDl&?7jo{6Kk@edZ}Q5$iXHVgND7mX2+C(oHXPNK1zwKfA!TlG)xP?-EKyCY$j z@TsyZTG=j)LD}#v;6}NY(?JR|LAC8Jkkpv3so|V)^|D-dC<dyZU1E7bvU+Mr>dQu* z7=-TBj_;Q<v{{g4>|~JTyAL0C79N8Hy&i<@HD6SsEv_@f>=*A+C?24&v)q6-o&MBb z?w8DV&?>lYPjqd3Z;zVMOZt?pq~c{WgR`aW2J%c}NoU)V(w2&Z<4(9LSfqWRvxhf# zizYg-X*`a`8u&%FQsI7rV8x_aeSd^Ig>tEQ`SVwDY)62+dZKRPdB0(_vmw1$fH)qi zxAS>lm|aJHX{}NOUXlHRI3A@odK`VYaa~91jyt`+KyjRiJ;Md7K2AKZYjc<V`m)hM z9tFP;YX+$`?D38hTk}8>)kPl_XGR8lbW_P(EpNDefQoe#hn>ygGuo|a0CDt8wEy_q zCNx}@0UrHB2|J5`oZ73G`Fn>>Jcv~+xRe!sf{$m4&sylx;XWRUt58Y3Ria7JW8(T- zg^PJii>y^$E{K(n5mEY(3U*eeO)ZU<6M<~P#`|$kQ8wc6k!bwgoPoWokVM^F($Jj2 z3YR+X5&D2#Yq+eeqKU2Rt#d0amlM^-55a@?4T(Q226y_VmswP|?`k#o@k;`T3%zv) z7ju3Z%H~sv*x5}jH|4ydmfHkg{2Zpo4AW-}N5vz1Ee)~cI&=rdTtoY2%^W`|yAU7C zP`JN^J%aESk4~j9zY9964R~dye+1uLWs;8_+VGY#U%99F>^V!BY=bj{MP+5bS;f&k zxsE8?jD!_5Mjo2*=2tAZdQ<*uYJ?Q__GbTcVnl)9-=U#@CR6`o_3q!3slRjf0%bQl z9A&hRjcS89U>d|KMUD&9YBG3!TA{pI@j{}~276WF_kPv&Zu~$f*bDj@ceF0yjN|U` z@uLq<45L?w$V1Q^nzsB%=DNdfuC802D89#=7oD!xP^8*#G-^GGNG&EPO+fczU2G>b zu_v*?A;o5%05=$e-#~NNVGnR*cal9taF!>jz#Lr+M1SXR{gF^x=z6k)oxWUnP}g$7 znU^u)LogUM<atDUA>l=EHAQSo>`l)jw}EdPT5U76qj05wU+a@gQbRikeZS93l^re_ z{p;shAgH#!*#)L3_{otstyaU?vM4oV=->9wn-wb0z*cHCP;=#3nYJwaFV5aE$kHb5 z8tpE#%eHOXwr$%+m+dawcI~olSC?(u>aU)8C%*U0b7CguoQQk>*gtl}&d58jT-RE; zR;K&vv!$=QR;-V{_<v6h(V3+huGXzNdr&%hOYgE#lWWOBVj+L}Nqtj1BJ&`U&T5y= zI-Svo+3(4ZQPw392NCC?ya&4E?2)Bq8v{YPzHw09YSTvAUw`NiJs*E^&D6}FVl7+e z^$u>7BLH{Gc|hl@CT_$>7C6?uT!OyXQ=5wsLRQt>#$gj><T}$FddM<~cMm+Kn;e}B z7WD@Unb|aW=zSkB>NZI#bYEGqX&Wc;4I2)>IQm&>TDc><S-Eo824(t&qrcd0V)&q7 zE+iYT`jF+1Z^d$tjDU)9%dKT?tZN9@U>tV^-;O+RzAu>p%X-kfB`a3b`1le=Uoh6o zgNwjDX#Z-er0A2_V9K-PfcGRk9+J^HbPpR$ID_AgJm{tTU^D(E5rK1M<RdEvfT6Cd znSx!ClDQCFbr|G=MY~|L^5Hs@Hf-POXsY(O-@P+M*Ct|mRf}?ZJeA9ugZnt!konmw z{ZC~y>Mt(4v_Y48)Y_@<;Nfxep$ENKMX(P-o@9HOL&LS3FddxJdk6~6pFU>=kY*=^ zJcqIshp4Y&G1V@U@Yx<Uq3)72Ylo^Qi95YNrO=eWCEU9KfI`^5l@^|8|LPF!&M(9` zv2O!@WEuz!M~V&4exv-r8!I%MODnS0jtJfRg(H3MV0AAZlzfusf-7u{P;AG~_<@+0 z1Aie%Sv;S{+J__Ebu36bRBSkpL*D%&J~sj*zRQDUpBD)s(jBzg8;nNu9dR?y`oqs- z43iM&#IQJ3Bj1$v6UjFVm$M4^nR10Vz9e#m>GN3EwJuuSwJcg{WmcQ;d5B)ER85;0 z2lfL2_G4wpgfH{5<GZ)NwIRMGr&CBbV$c@$_WXim>b)eI)1Y&)-uinoa!P4^a0_5v zl$-VigSmrCKP(<~Lnfk5?}2Em{|$KGWG+9cj21N#hx%n}l*W6zS2i<JX3i}bAiS3R z?Gx;;#_K*uZffbP>GJwIi2T1a^51L4zf~p~>Hdu}nYbl4FONLj?RG{Ug$D)m{W~bi z$+H2<gT;_=T0*cyeh(t?tn<Yr`N`_aX4#va``sY8jI=nhLe7U4^C$SweAU7r>Ku5A za|zFpQ`gabw%6Oo(-EDx5vW_kalZ=&v_@g>{j8AgP<~VqwP!80k;o7%2Bpw6&phj( zPl!s<c?(OUEB=C~PE~V<T5{XrGV4<C$#U?m|D&c7&17|%Rv*iSCV`$o+#+@$leGJ! zXum^n^VA?`b87{pt@U;CaGdJxG{%supV_*VreS2{g=!!oNzs02L+s{h$IjA?@w#zp z%=SX~rn8Ri8BIu(qGicJCflQIf3D#saEhArbfsp;9<5{KaEnyautd`u&t;g;r6&WY z0I?`#*g$DCvrrbH$qC@cKC@srZ3%|yAD2T}-S<4w`;S~Qu-2hLS%-{E)}&+n1oubD zmza4xtCn)mkX}tMhd_q;3JM+lrFV>wa+!I?KJ5^+F<s|zZq`;45Lo75i!u~M`}MxG z463H)@ApQ22D}OG`pOR~F7pUQp8dNnw)1l@*HzyucUk+*rT@S*lpF_v`h;`AK$qBy z$e624?#Z>xynBVTLSUGX_Uq=?)zLRS0I;+D9^>;0l03?ko?w{Fs<Hcr{$vP(Ivp3u zf#QgN>o>Lly5|#@E4bH?_?3i~k{sK^+xKU-xTp0SI^p<8ap9A|Ik!aNYMn$qMSY-B z{|R1bT#;Mc9FBDmZTPlAn<F|jqUq@CZ^y*zJ9we_{u8~DBOM6n7n$c^MTP};LQ6sf zmb9?8)Ub3(VHvV~Q$&T7ug3yVwmj>q)BrH!RF1I@vA$wZY!?&%8C|Pp&tl9K(HWV8 z?;~{B&sP~_l?unY$X+IC{1!Xg&<^Nu1ZfT2`-c@gNhWC}|BH3F{FjT}|Nip-TkVyR z?*D4932U-nidV>=V8OcW_<~U3R^WK%+3|8VVI+8?pfCpA?^P{@0Eo!Y<~b@v8Sig+ zW9(Wm>CB!6=cZ&CX?CWcS(j^XcT@r7hAKknk(9~IAn+-qd4y$zgYcUNKhWM_xLPfn zJ=PX3isxs~412O-6sp?-V>VBqI+y0X;QFz&=vrfp8bRG~h_>|QC95qM%)y^*D(E_e zP%Ka|LX@orY#K~q#hOaBb~7W-(!JP>TgG%=$8jCUS);=P;<uYNb4f3Io^|~AI4{iT zsozjCA0~@y#Rqh&6<@qA(3OSJS-r)VtQ(uV`A2D_8U!tU{l>{)F!avVH8CQ*h<0cl z<}sLvd1^q;N`BjY7W~Pe`B;aCrP$&}CGh0Eg`O+Un14&lQv!mb!LQd)r;6##<`yl$ zAtj7J7cpZ1Kb*BFCp<ZZ20{y_k%Zv&goHY*yM`<xS819f24v$1rO`isl_qeAqAGma zzZ9?Wf8n?PK3i1(o+FaAbC$5Nw>Ggcv2`~2Cn?1BV7J5zW(uYQMoWu7I5pMNJJmBf z(qsB7Ek(m{c%-K?4`XPgXE!q^VXVKWuV-u|H(f8WIwxBtKPRIiM@vIHwIC-cA<??< z>MIQ)O)KtKdPcfhLVDi_etMF6aw%K_+>d*QDsfpF^3jQDBY9(eAWaaUD1HcL1o8Us z9s&Biz`zxYu3$sa`k*lX7$ry6$nWT{F=Tyx{wm1-!_WSGl=%OCly>&c7IwA<*8hR1 zW%@6EEp2CJVPs$}ZeVL{ZSqfDH`z*QO%yp~s}U582+AK`u!W77g*AqPrieuCRNLMX zT%6qE*riTIOgI@^YG&r`Lay*9zTO;0D#hr`6!XVA-tQBR`ftFG!ZAF)YMNO-Q!7rc zYM)Qte1AmY9o{jAAb4$uEWG<}Es%Kk9-Wfu1mg^XY7qrlqfGZT?ZGtB^$4fco-~}3 zRg%G}!KC~LjqB7SsNpmusaYfY>xb&6Zc)aGl3|l;G`b94k`LP9yWn<0;eC<KCoq$% z4nPL#`D^7Tprnhc6nW$ITo8i=^J@+Gm=P;llg@?vC^_3qB#Gj8raZ<O0orqnGBo2K zN1#BUn43wuNoS0`{Xe*^mnK~-j$1V>4q+~0ln{@}Gce~S$V!FS?u?h*1=w7U5_+`v zQGm-ZdyW(Q5&(|r{LiZem4}4ZZKGDQ5kPIW3jDnz$1?tlm3gCcIvR`=gliW?y|A{$ z>_)12xm-XtD+#1H>5vivOl3#H#?D($x_px-#>7eGH>FAM)0G^ma|H<v2ad`TC*u8M z(AZmpxYEkdE5^)Xx+GlwpORbajf6HfPYfDvza9)F(wm&`;_GRIZiCMlR32Me6c!lk z$?dJtnhuW>O*HP;FOCY|dX&-THj(PB<}M1Gi~HJqw0^a6%rC>6vyN`Hi8cY55s8s0 z`@{?;s3wxoP{0c5cRbQJuNo7p!BjDJBB_L6mx?qBTx2gr%ykVsczf_y(=Po6V@aa! zSC3x-2QZ!oQVE4q-*LjMp-2@}XsR182#UUyT{T(#)(tOoP4gPO3d1h{I8KOgN>xVa zEsY>I1Om38sxd2KaNgRO6e?yhRyWn9f^GHE9z@@zoZ5x;-z3U#|EX4<+M~rBIhF)y z=2$rirQ94chTtoE#^^3h-KF0g^!lRuruG6NB3lY~8LLZEd*3J%TFQ4Zt1DW1<;*k` zTgrBU3pE%iZ4F{fbO(X%Z1-X!L>?Ol)ZA|3BfN5T(0{JH?3v_w7tXe=)C{hVQOYRf zHjHTy)4xc9XZT4@MFDKN(#vKYeq%`#RTRfah8TG6Me)yg)Zq6NeJd?OY@<<`wJDQb z$R=!e5})~C--uSiDs&}&#U`X|LePg4<w~?+7B=$c8+z)sVYc<>vzwD65M}x(%`cod zA&tpxB6$T5_=A5BBh%e}7!Y~N(JojGv=9@ouxAAL2tM?3Ub)8JLF2XsrvZ|iNiNRd z7dppSSdOG2bk2th+^?N`q2FBD%O<7ex}tSTqQR|!z{FE2AL3CF6R+wLLhR7wxfF@z z(){(7-eXGgJNR+_iQIWLP?xk+(54a$&};{8BVfJhSm)3;G``$RSvTi<i(}Q^qoh|i z_jwP?bIA4`u;nAf^)7hwehqtZ&*j4z>n#-f7M(c7wlzcBJ%i=-n@`BC!^0E(6>D`Y z7YQg9K{1;jl9#96$Mj5{bHmq3?5GL6Q&^t&S3XN_9Zn{UKGUA!a2Tg*@sF7&`XpVD z&oZ9RGK|>t!Y(jNq{dR84=(m1eJ4$aULL4;uS7=Au&&VA`>tC&`<gAk6Hs-z9v>Hw z4*6k?RlQ*iNju9}u00Y$-LvJjUVgvcq_X8()YVzPlZz`PX$;&-;0|TE0U;N^6TOI^ z*Y-I2uSa`)C^c_jdq4l$UAC@8(^kGTF(SDC1cZhDi^?hE;pAZbzj}ncot^bxAX&-I z#nI@Wl{6_qN2*UAefZC?jGB~`lF~SFd%7JqMBC^o;hAg!d;o1q3`3gM3DldaOM(0h z__2`4G)6+bZf);W|K06dEYF|2&zoB?NET#ea`7-D9RbB6O-W)4P%J1$sCt-qq4By7 zBQOan9flFuW-EGPnf`WrowZ|D?O_Ja>;q01(5i*=6S&tfxGQVi^CgUh28H1klu>zs zm>uD}qt+@eQadl;afY)ks-F>}bucUuGS&>|?ZCe>cw(R4I{uIkd2M7&;ktduowC}6 z8_Elk?+5p>_Rk7JF{zqoon~*kUV-DRLhFU)khz-ud2F{{-3m{&&|~d(9r-%bc?dfq z4GS?cd)TlV3u|EUfkz7BfsBv`-Cqkbb79a2!>L9tC2x$}e*n46G@vAm%n<bMnmt4k zadV5FcSu!uHU{EY@wzWpJx7Jqb;xu>(I6z8YFMsa7K6ZxrW{=g%s~du;SKcHgo^Mh z+UtM8g@b>A3x5|nS^nDz{reO~tA=|aslflS`DNOCk}OyYBvRzAFh`V)PZOb8EvX5O zQm5;XVLiTR%x26c|D_rAX?4hP%L`bPFTQns#J*>)_+*eyKK}C6GuzBaW4mG-&X~OV z<9ov*c-+UQpdI!Bs~($?x<0XwO4`iW8a;X;eW~wA_NyIveeyk<Jl@M>9c>WkT+O~a z06gCv9*)9Yy_cxcCvnt>5m)V67+K2RZ}b;bw&5orz$}$-d@4KAkS5#g4h<PQ@rJP9 zlOiJJMiRMXM+Kv%?)HIPbq6-NqimZdxua?u=TY$6kDE^&(klj!oKbM79}OvRY2L(p zMi^qo*ecf&$Y=KaLnVwcqp1lB2@Es>GO*{(PsVJhQJtOwef5PZ=yFkV?BUw9@kTOz zN)M9e3uJd1L^kYP&>E0)zYzsRbO#fVR&{COe^1;D)GE<WI566Z+ca96$&a5Po+^1% zY|q5|Ldujyrx!$9HeH@zDrQUolJbPCo99j8Vao_6o1Qd+qk_ySEuya|(SJ~Bc4WX% zF$gcQXQ##&-GW+8jGXp+LC6_*8emR|fYkUrBq8?ssD{v5VlHLzjx#?1jMR&RNG>XP z?6CJL13E<5WQrfS?W{3!B#v!rU~5$wbDC)#+K$mR0&ET*0*sCyJ02&48aPGBp2aJe zDiaJuY{zaEj7wISm?x;BGHp?C*cd)^MMFyI0|(d1z2XLS%_$jIjn%HSfEfGAOvSnG z89H+_EPysC@nuM*X~bB=>#Nm<jy75PJ^kCpp_v7jS~^iMp3taQ;*k+`>BVcL(l1)W z6)(!8sBPe+A%Ja~j*5xbH>V>+V*u;k^*U2wI$2bkYJz4`aLM(&SuSsKgRbZDv!T(H ztOgAcG}2A^dV?k%t3$-2#(tytv?XZt#U?g7gYZ(-Ju1rYxrg!J1hos_jJ@*=!Sv=j zUsl+d-Y}J;b}?O92zLfrS=s^YtcPGs@fb2sEj68F@%rl+D0(|qo^?DO&mpM9pUFHr z0a7a7p;s#A;u7jYd-)kdB5t%x7o5kYdPmM$mv6K68=KB~jIdgRf|^^EMK~3;dVXa# zFerT6Vi;e$bei2-j9zJUxirtQ^LB!CaW3Ie+DG{=+q-Pu+ChHla<mn>%;vcQ6G~P7 zt|hOjeI`<eV-H;^DXQIl*)#CZ@@MFuUaSIp3VpjP=gCK*J(m)0$TFdARe~O_Ii^i% z$@9sL0O^dQQktwH&ZbFV5y5;gzl`gkoa=$iASrcr=$+eH$aJRsGSZC|C5shIZ6q7! zinnNSyYSV`nff7_?3N<#!H{M$DnqWav8CK`%7sX?HO~suD_3r_JZ`>0Xv&gE@YZJ4 z`ZiTzBf;?_mtWcZW-~$M2p({LQ#2(@eBG)J)N+DX+!vFUkXVNwl-O5=YR{1azl)uf zqutd;0=;5JGJH3CG~BfDinbX#PoH_sjWOmJ6DLeASd239a;ykqH4H(rZ}=#l3M`o) zd_IaV%rDvUU-w9%!jtZ$4h3IZT@hHf4VnA0xW4sq%j(D?{XWnFDQP{u9Ut(`*p}!8 z2Pt7VyCrbz&O9WSvB>WStVMBZe&@Nd5Wks0KHZ%|7L@M05qYRmDm`)u3ZD=*nCl_N zjAfA(;DP%5Wxjbytat8&A=1m6v3p}={1XP2gc-+Svf9~SeE9&kMH2hC0N7yH%B)u3 z7;`cZryCzpEA`xYg<s8DK@74^N2hKu3zv^TR}h+RPlqIveaR)&tlK^drP?kI3_^TE zfY_|on7GLqa~w<p{u9Fz?G90M^vW@1wyP`Xm-$b|D+??HQv@}=J__K_^&Uas9DNZo zf2#`E*rBSC8^YbpSkFg$;leXbZM58&*VD6jL<DO1)3%wNbS_)`idI=kbq{s+S)c{v zj2c{6;nG+5xe*ALsN4mF*a0p|sA?l=e(o@cA`EwGSIVL%079R=C#0FP_&mE)t`k^= zs9~h|B5(9>k^!Dx!^=oX0dNgxRj9TW#rfkHn!-vab!8+;pCXBX0W%e-^&$9x(}bw` zKbJjz{k}b-9NQ#>+oC_%k>TbWt_!ls-<C<ESly!=Nt>7{;N9H)$~3e#k`cEzTnz^X z$m5KM5o`(mJYogT>GZ994z7H=Cdu5xn+6>!ezs(4Nk!Od5AGm0P2%+g6dyh2;!|g| zP`x-;#p8JE1pdVNcrKl#E790HixhZ8oO*ch3j7H5`RLN`+&w{&P6pq8F;uTg<Q<Gy z_Q=_JM_lxdYy@xxfv%a>+7d4^MQ_^0++N8!E(Jg@5B~%7SjVhe^nQ^aI{y*$aQ}bb zBSj62ob4Pv{&}=iWy5hz82OXcfmlR!byWt47SO^Uc2S6m458l~%xY1V$46iRMA2Q} z>1u5}8oy8KgY5p@w8fI{)cII?6a{Vl8omR(pTp5|+!nouX?5c+Ym4XY;`OQ9*CWCq zQz+Nyhn)pGU-;5ZQ;3_pui9Y3574U<@f{x=yxblkg+Wl1FQ=R0O<s)A`4hr)3XAq^ zT@(tcd1{{u>=Jw5FlTi^;Vu$R&TdEyyRBu*;GGR@1^3TlgXkj{SU2}g`MR=QClo!1 z%t}rF#!J_Z2<;}Ct!|UXLjGIP`8Kn(rh|pahaM~Thy0#}`m<;M1CWg54TFNFvsEge zr|c5PydCBMDWJWy^J0GMl`6#a((!HARthQs3K#`~%JgvJ6N*TJdNWSdNX2w)2atS3 zpjJ0?bJu_n8{Ovjiyq3g`cxm@Tt8oz8p1V!Kufk-KaubA52r7lOe4*jFN;1uho{&o z4#r+OurxJXKS=`vqcKv&M7MW;Iu-!oNJ@{K%DchrvyYt5*e)8&c+MGIpk87=BkGks zulBG#FZQ_AdN!sfE?75C(3fG5vgDAkh*=f^<J{+VJNYXCJ6G+2L?=g)n~A}_NtTEP zLw3~d*c;9JXH>h-K^c3-QCuv}p_od0Zt`QG_&>iJrdN6|Q532u!-{Xt16c|OHl2Zj zoi3}+($DNyWuZ@&?|K2VYJy?6?9bm6ndMG?YGxo_wBdqo7-*3F<~d;yfN_sPpV+HE z7{@(iYP#pkaGNX#sdoEW3c!s8nS#N|+_J^CeB}jG;C2iwW?Ct@j3ad8Oum4g!0!D# z*YV#2W{x7wUDU2YbE3WT9x+dz@lP1QY2|7$>rcAB3N~z9n=6B&{*+oECy5YxZ)^C9 zU6h9B%<Z{Yi9SEq;P!+XDiZ)|{W*c!iIP&GGR5M9EL$>Nbr{-{=NB%}f+*l}NHaTl zXA=HfOjRkr`jt_gL=kbCk%TtZA2z3Ruaa{gtJ9OX>S;w3T=-Tp$ckO6<^}t>ULR)u zU3rERI&Q#`mT>qO=^bp=Jtl5G4~E$B4Zd}MnJDTgp-wE-9pV#m-yi`p<5Obl7xSMw z`)@_`@#)8cG~^TqY}_&wqjj_ZJO+^p^eW$;>HOT{#NpI)K|cPD+|M9y0k43vDl+z_ z#@M}4BpqT!DA-Zr8UU^A-1^`>uc@z$bf)H<BGTvzt?u#eAaEgWAc9NCxvpecp=WE& z>8^8FW;lLLkT_>RCTzSK(TEkrgTFicqiOi(GtBCG#{D2f-ow^kfI8!dTC)F3D&YAS z6Vu<BDX#yvSp3x&nHc|XpY%_TNySD9O9k22cC(2%#f?ygf_Zi|M8=_URTFX%ElLm; z7NxP+(naDjXxkLc4GruwBIh-_<|3*GpDAV!oNF&uae5_)I9T3vBGk)q+Gols$Lo^A z?a${?^A^GojBnT;;^wgs6d0VHr8`v&gzfFV&F9k(xMt?{E<d-u<Nhr6s*aQ%>RZgi zUG$!}sFsSIK=zOu10cK|BiOt1cVd4AWcTO9jT{U0ncC8w>>j^W#U{N<ude!}Gf3jd zv%_Qy>sOa?b^1=0E$v2S-P|ol%ZCUHnpD@{iZ+=~4JH#@O;wb>8+DLmY>TekVD)PF ztZL0?pE~}LE7{-Y^`M0hvnUyK87qEIN#<##^fa12KZZY}$$wudtiYT~=KNLKUHo+s zYLC0?Yt*j+=rxqaUL;8=fFTENIE<MGlEhI1XC~6h;E&<4KtrxLWC`QAU#Wd4;mp+# zQI8{ZfxIa#Q4-;V$;6ih!W5UI6mc51MeG~18P%L)4K;5TjWYGAb{e~2rp(-NGx12N z4(sU(T2IlU{pRQNXPz#Nj`Q|Fs`HEy8)y?Sdg7JaQvM5RX=V#*n8$H&H?WXgPZ7jp z<PzL{&4^n!*F3n;>zs0{h+HW+!-~Hz+p(Y!jniBw$*Zb=r9_kx?J)Bu=<KgS+gT&t z%2wdF_uZB7%$MjWFHB-usU5r^jM{ETTrFN`%2yTeNXq3V(tOrL?N8g*<t+SAaX4*R z4!osW&VW5guX60(*f5|o;8oZfHt|eQz&EI{>DDg;+vx65Z!$CNTZnOvPkNNSTQ^hj zFH2$euDx(4E8cF4(JEJF)kzToUy`;Pbx^UgqdQ&|Q!c0QG%C|N>4kNu`F_u;XavTJ zvy5J4c1;;wGfOS?3BNM_`aOvD5q{3e3*t;HEHQK!JnWL-5$1h-n^M<KL<aP|C+w5T z@Mm6*3~e*q#SX)xCKi{3_|OlwI>w&MJwYtbEa4!aV<TbUW1haC93qdPu3Lz3apVW` zVDXzoR6&`T8G=_(@gsf>v*+(%67RJ8(90#n0bK;C1=Eo9IE4Z;e_;5~t8|#0(FIsX znPpUaDZ-%gEh5fAbPv$J>_d^>m@9ZM;?oEoL#}v2PqFmci+0%h#;o;`?-K-~pr1X< z)`{QCj(HQfBV~lM_32ThM1I^zLbRi2hw=Jba}EjRwnPGTzrUF&0e=Gjwc>Xn8~=oV zt$2z5xZ>IV+ZC^F@c(Y2A=SQ8bU#BtOd$fr;gM@;G^^l~7pf?i+qQvN@B^@1!-W|2 z%^8uH0`sdj&P|_u>fS8T*4hv%0hVh{t4^;4o}O0|(8R=<V~|f>Zq05fZdVyUKRaD< zZ~?n=c#FN%gFNDl>|^+YJ%;*B=tlNYy$)b|yg+2enfC(0W!nm%u`l*eu~hB>8ggUq zlD+f1$~(+~X2{&*&m5rBOuqinnKuR`y2{rHQ7Jy|pf#`8n7U6pt{nt>GOTyWa8fs{ zN}CGTv`U*w*SuKt9(Vo$4N-i?*YN?dD?MZ|yh%4{QPU>gdD~KWs(XN_8e?yoJuHkP zV{fWGE{rWH`F<X<%7Po4vSkJyk~~)9V$lGi0$2L@ub==VXAK<0vHKfiZq)FVH$?}? zIReOR2Hh8-f>j0@^rfiyZNIDt3?gD}%u7a^b~UME#E5<gCX-*1%|W-<tdol&%u;S1 zMLQRw15pWx;};Ff;dAymrW(VO%E|$B*o<O73JqDAzQP3zO>1Lg>U0=!RO=Z`2hQI{ z@`j2(5IeF=6QxsPk6lYF&^-rY(n5lQqh+dj#aR0BeYPHN!m{_HN%p`YaiU)c4wMe- z7byY5=jxf*EWbR*Vonw_Z&CKmY!y+BxhE&fBm*>7Qe(*I@KCDtCzi3Kjt^5Wh(i+S zkUFO+Kr>F4LLU-sg^znU4J^6M%^^9d*(cB995!VR{Ic`CwmH=ePcCUnY2zqp{fTDq z@(07zuUBk6s47=(%2j3cBQc?e23^0t#d~12rzwa=rD+jqrSXqfX-}u^wdGky4P;pr z5C-9*WYlU5qFSrWj_PAIRV?>bWWltdJ2SQ5wJV<weM>5nPb2Zm#4I2(elOi6dzTg? z2{x;2Q4^dz&$Pk8!Zpnq6DtskcP+VE4HR&dR&w}`R_3<q;Si20+!ggfc?s&_3ySoG z>&(`^9>j1~vF6E>lR!)}j~;9(k$W7?0ahilf!P<6<akwv@Crs>1&8R#P<oLkLb26{ zB<CjK0tyrbwR1I;?j25+c$O?v6a#xa$F&OgZ_Jbn=Bk4#=SCa-Gsmb$99KWEQP}L2 z2Cts`lPH)IiIpdf9os^K*JvAmPSl>18#Ac6T8ai5tin1dMY6VpU=li%%lBhf$H`^` zYnQ4B%-59-26{lI)KbftX+z_#GZM{Zi4P5uV7e6xHo5BTa9RjC@HpL+@*JBE1KiIG zrF1!sEKPgv(@eS7>?fn-o0t~H=I1T+<;bb@BAvKTT;x&PEsG)Bn9ss4+IA%z?W(7< zf3$~+juymtODge(ABH4LpMo_yO65WR5_7}~yFazSo|sgzo-dlg4{M=FsI{1~_*sGE z{dxZFnAq3*Sy3UxvA9)eAA=`yUsl{r+@_`IspNWJ$HB@DO~MmEe$d>+V0Y`}#f5lV zOEGkK`=?Bhw470hZ_`G->5!YM^(wWLCV6Ifj1$?2hxIFsW*Oo$EZ+gFXWVGHmpL3~ zoq~SS2>c5EEepsEa{bF^Y1YTW9Ar_BbY8S!iaZOYj+7dNd@Y?zjxW>G--A_3U7f+t zP$Pvt0)q@z1mlg?`x6oNlDEEZ(eflCzA6bENKO0}N^+jOeLL*JK|5~diW~+a_@Qu{ zWStSz#UAmXbMj}w03Y4LZf>^fPZ1}~J2=2Al@>a<=KS?^)6qeS&~hZSS7;F~XXi1s zpi(L3Jzc7>3mrnoPXQZ~Oi@@2on!n}w3528$HtBln{aq4hi8k0hfJsZn|p0RA7~E% zJ0B_L8evgV5C`O-^-jRZ?00PHo=21AKz3rnRI+7}>^l#$87GAv@f#0=eF1Lbs7wJ! z5+L@2?r22&H+}qQt~qn_WYW6AP{&T^89f027g-&3^Z{*N!g!KQOC+(XF%l+6$}jWV z>4FaUU%rv#94myA!d3`D>)1Tfe|7>mZcP*TW3%<?3fUtdQb5yR7(GukO=;I=0C9Q{ zNg$<!RT#d;uTe4q-K*XB#N2kSIC=sj6kQN~6x?32VL(tUX50~|&g!GJ4}x9t4aVLW zLt*6NKlGSoT}@)~Nr}f>A1kxym^GhU<|Z6s<KkD|JuSCk_;l5`GIq$I?od){dQ!77 ztweI@;%N&uw_H(rnJ>G-lK@<y9__`oo-^I1h*oym`*ggFYSAjzdwhTGW)((O(H39L zuG)|P#PIX}|Jlv{wcSnJP@I>CAN~WrN*aU@0PuhG*x5v~21JM>3<4=0NTFjqTmpC& zUFQJA6n#j~-*jJ4-3=U^hjv!QZV0fS3e_b~qA!TKj+)#5oS)m?o=rdH91q!8o1^!# zpe%XOM`1zPT3!<r3y5h82nG^n86j@Yk#m>z%-DnP%`xTeRs)`t*Hc^-2Z1e0l(`dK zH3cMlqXNWW0`JxjGLq7>kSu<2O;OT8hs-#JU)lHXtM)ECU*xNZGu#(ZCGR<oZ|s^z z2LLgNR2)w+IuGw^!E`y3$T6$KUurfHJK7FKP9cmBYu;l{C5pMiMy5z?#KqbO-7~A5 z<AP$cG@D~et$SSER#GV5%m=`%_SwoRZxAMx>8lQdMlnXIoeS2>JN`OwtnWCo&KOnX z&Bzc}?cld1RU`JEjD5@9qn=`b$tpD!>Og9$Eqr3gK2GhQ4`~uu6>YV4Ukxd-d7o#M zwNT0^M_KzFKhzNbiWBKRL_f1>11iPI=w7`CnoLo02%$9$rHZjYDRUw;ICZA}%Pd-( zt1lULp^i2@yJXm;l?d~^$XMx*&I#dkD~i{ZutT&gQ&hHjv=R-jM><E~Fvnz?ya51{ zMhZ1%kgH0A-+HO#gkG4_TIQXm3Tu>}*s$c+-uMMm#`uxV9E{uU0+&XdHq*EbT}i8Q zuTgT|NI-2T#&XQaNTqlQBO^=%(Yi}IGb~+ld`&1w4R+cFLolJI$=Iy@iA}-0sS^O^ z!#UdygPL|e)BprVp{>u+WHcLm=HMf3-M3ATnDIQze{<lwI^n_t%7z~PPnZ<(;&JF# z;T)W#^Wi$7=i(2ApE#fLYB>JWr5}E`hu=<}@k{??E9Za8%i(C^bcW7!=f#TS=Px*r zV&bd)oL3q46APdr-jDA^MSK)542BT_ezV@9x`xu>rM#oO{)e%c7i+Ad{Yx{!{Fj`l zzqfh+!HOgQcUL&Epn<cIxx9g+fsNDuba~N=<6l_?$UI71u6vl~N)SP6(1qJ=by4u` zgs9Fa6akX)>ckagOp@3uvX*jGCgXSn3jXl>z|Z6Zow8`mV}!|v>rXdXMt@%3oPGd* z2LjhJSKiqs_)2FThLJ<hUR`deyV}OcUNc{HC#mI0YL!k>^-w!<V5J6eeaourNHid9 zFlZUUrDLH?Q#AT$W5^D=u=dPD13le{iVUW!oxOroceuGBlo**UXff|Xz2^Gmjs9bp zQ+l303*|_H9XC_Nu5Vs@HgX}iqDZxDjCoe2y+JxQF^0&{9nGxHmu}{6u|(Y=?{~$M z*T?3L+4nnRMtR!PYwh#hYG|}(?e!rXw6$dih5jED_0p1aRrrk#$9==`(aAk)E^fBI zah#Z0^@oM`i_s%CW@%$`h#JV{Ep@{s4RsL!znvSJPd$58csdD+JMF3bQD@Puo-=AW z+-9}H)ro_ucJ{|!J_7kXp?ZHj#cBYtu7y=mRb3N&i`pSb7U$(JAO20W^yU%W*DZqg z0xIk0T_~`?QF(*f_r-TM>nZSkYsV^ssh?@ucFK~&mKdLG=%QAiz`y-`<{_5tQn8g` zFt<zl;!S3dMf7UeJSC3fT&{t@d;U>fA25fXroZGi^RIs4-ybCWw_yTbzQVu1Hvc39 z)F8F7)iD0>J*IB#e5U|GTqZ7NVX5U$DQ=9G!h{Vv6~(vkD>P8Sb|o`*SlO7GC?>$H zVBLJu*i+dP0jPvaBsUGrdBRscX<S)$PJ1pkL~pS*NU@$L=pp;wO?F&;bl>@0`PkvP zzh`^x2)36h)WL$MO20b5Ppe%6q1a+8UJLRu*csdslG2&pBBJQ7kNNdW>yGW4K<QQ| z98<kBKS`3-7~Wcv)))-ds9bY`)~MZpbts4cZw~BFQmSs#P(P`n*!9~$ZC>^xpj`EE zrFBRRVs>PVdZ`ayKy8lSiut(XNp*i^g(?HK<w<zM;96}tydJ6hi&L?UZVgEB3>?8j zT}mQica5ZZtMkF;p<<|>gCeXPMnaL^c~AN&eDO>kIKU?9TO&s|q%RE^$H!!uUJ3)e zRPMLq@DL^#TIG5_pm>Y6=Yf)R(oxo$g_r=4O8laV6dT8~mc?cB@^wERO=v#+_-(FQ zn)IMa8W+^f-;P^w8#pBvC8dwS=P7*nn?VL@`LpseRtiP-swJehibxtNiwRdrwl@;R zNh&9S*3!M^ht$oj*P&#jgGfmyGZOM{p3SX=O1WefjZ_J<PN^B$^fAI0)G=hoX}`O< zaaKc@@_-w9hLEgSDK)<~j28Ap9EulqWXeSjUyOiiPfo<We&-RbJ50MgOg0bdBURaW zBj;d{ViVV1A_Y0kxRXRWnUU3rJQFnwQgMguP}-7G1pO8&ioHhY^*c#ARxu%>B(0Ht zONVnyC-rIe9kqXk6f_wP*g8A96nnmkcVn)}GMTitxV30G{JkFekP9d9USdT{uQFES z#n`M0gd>;aL0Ov#H50o~M31<?lElPVcL)FokK$i56v*f<1lUcKk!Y&PITZ#|Sp;Vt zdGjkX)m0iCmn{?5q<6xPM|=<bh2glAL7$bN4}nr{r$lYBR4{<gOXNVrTcNMJ3&SgR zd*r<$@{r1kj*Qac8Q!*GaEviIvj>cNU@Iu6aTdXvG;nm|H-L665>B@>j;LqA7*-?c z4Xc;(4Aw<)L*w19-&Cqdf;-?w+%<l?W%P2@V4gf0`1~DZR}dH6_E=~6J5a^63fdb( zV)!pT=sPH1@*5&<;u|AUK7+SFclF(pFv{n&f$1A)f0baUqy04&R0)%MRRcKp5U?7% zt<voj#O}Tt65qhB`s6K%_w0v{@3HbYXv)G(bm%G1M7V@E{#0C?oa(!BKq++bi=P0L zv=QQqs8a{fpUKbApOiOj+=L7<Vk8OA?ZQxh;-1MqNp9@k#d?hpWA`eNx3?JuAu6e! z84?*A(xg}MZFtJmIb|tm$29wQ@7+wEE`P)NH;On~83oVlS7oc!xppF>^of9PdqRn~ z6kS8qAVVSHkqA8pk7X-M5{M)r|IR<{XmpKH3iq{6S@y>QNvCU?0->eyPyWtAvmlf< zT4fTm_h%2kc+%pkvl!7tq-lSI9IX&{%P=YpTBgXnV7AVAG_2Fk`KX8F0i-fA8B-@} z;R0+CUWYwB@-(UEGd@g%d^3VP>l+k9CXs>rXozw`^%P@FVlz5U%nv7CWlLtBQSbMM z$s(JDOGDG$Tw6E7Qx4w^f4e$RLYf0kJC!ai4lS?v-M;d;YLm1C?d)O4ghMIn!s3FL zpON&6%ZIGK_Brug8dx%pVoe$G7M4bwY?aB5&?B&svb0?7%Gk`O3{ij`z`cH2oFqql zsg8>!b(xiDmz!G7RwhN~zFnpi^XlXewzL&wIVU4L>AM%vhc3O63mbM_WLT~-k|s9` z(5&-FrsclI1Cxw(z=%7V*D0Azc;T-COWPAu>UeVF?y_T3g-lB>(VQe#?CnFZy0!Y# zj>r&x*yed*NhVTgRyE|sV&n0J)W|v)5;V{z1vN(${mZdipH0^>zyn7a6UTWyE(}*V zR-U(`Qu{Uo34BWrGmYfpLa1VRs*WaLIwb3q3h<qieT)X+WA~d8qb=rout=LC(GD|9 z%36X}Wh~GjtsQBxi-g~shal1;EQMCc=zWK+p}@538|E{Brn%^OQ&M&*7TttSJYcN* zbsc*v+MeQra2d?sY_6s<X+8Mca|^<3`<D}r|4K6*ZvZ~pZPuLQBiWIOa(Q);7uW&& zy*UGyZ3pwX6~XIvnR9MTodjK-B``wqm_Fa**pyMq1`8{IY=<-ObenqJ%XFIq6wS$W zX9KAaE*KY&$JcWKL-`P2s*x9ZddkWN9g6aVht5-DoZI$D?T5-z6=&6B8>?Jiy~{)W za1)+u`0t9CY#-&IjcO}yC3HjePO{L`+U8j=KFgTg>c&kZ>-){nbnIlC9Ko>ePJ=;H zDl!MiUz(&Y(#c2ia^ydkmyV&^;k<-9Lt)lukF&+}QK=r8+nm%#3*#k}&R~F?s_x`9 zOSWCIRNrFq%56B$`M~T7e$rNgIjM{Ap;D0>y)j5A0CBwPVZS)hC&X$KWv6WV*qGr5 z`bS_>7TXV=&S%%QN7Gbq@<g(DS?1WIE#6+wVQ8a1f&fQni$=VLb5v&Z-PU@c!Zwx2 zmFw^Y9=7g1BH9R((drpLw;I>V<DmdfmGK(P^FU#ylGr&S)N$8@xrbE2fo<Fhl4wC~ zH~=ZM=Gd<yR$GyEkwce4`4CjJVK~Egk`?Leo%stJ#H3?_LPaykb0&E>k$L=JYzKMG z2hH169SA^bI0CSCuzLEyDvwF?`LSSFj`+SscP=h^YuthzUO-slPrpjuJao()XhhoT z9w|72!m+9^h!gsYF|^r^^xxLfnqMGPSMlUXgf1>0v9k|jj%tf?y4s3ITV2b;qFYSk z+rgw?S50#8Q10Q}1O1hbU4eirZ|}6A?=&c#<ENvTroHrFwOvYhF8U{(UD^HocwiSM z@<RpNK0&fCIsMJp(?MRt%I_cNG?t*>{{fjP;r3W_zYJH(i2qOQ^Y^1h|2B(<k?#Ly zq5Kc#Y1D-DR{s5)?`i6h(Ibc$9$y*=PFRAJp!b^sLGH>7KZKMzlzBh>T>^}(Y2O4$ z*oJkatKEfeEiGWx+)4|OkT^%!gu1%AD$;&c)mZ(T*0sj_sKaY(Txv5T?tV#bLTCCT z$7`D7>$0({47-lo;Q4KT5^wsR$HU%!YDo!dh^UkAi#Q;7XOM<ccJQ|PH{aIKg1B9I zNW#CJLDw4l6$Qxmcp@*#z4!(fQB0FlOTGB@{gC&SHwX=&kA_8DhK2Hy!Ob+NDcW~g zxP8T6pWNiHv@6_?R`yZy>(np^4HS1mB4JayMU~u?99=VCUqgBP0pwBAw<+?{ZgKBb z>I^;Gks^5oUH{YoCw~&C{0dKkSG-S@h@H1jPSUJ+s~~Axu<t5)nY%A58KZE^AjvB` zsv|H`-(GePnLZ5f&>ouLMe#yRl9RvBE6FP}YDWG-O)^Z;nv(!d{(?;cr|1}vU?3?< z{=!W{hVlrCs2$**m9OH>Fw!+33%)GG9L$u+jcu%Fsz(6JBRHxi;b~@Z%@OP)W1v^E z%ZB_|+Ses9Xh(6*FxFjFdj-GkM)88%$Su3;ML5zm?F+BZM;ybKKNd^zBH{PJ3=z6K z4Rn4qaDbNho}m6g+2dPPyG4H94CSS0(5<wr1og(_|MeG{g6^z&z0-J7rnAlH<WC+F zxur+(kRJ&T=s=h8!e8Z>gZaRhzeE>0s`DDCw~W3|*{VMfwLig@y94ZlQgaOckS6?@ z$yF=$#I3+4H-I`~H@WOJy%gE8*YkU`C^sJub?4uKVmYMXF1_{+u7JuZz6J`GQ*+Pj zi$vC~yvBgaDZ54to>qLe4xSd^?MReAI=q9Y>;HY{Xvj*}a|FJ_d<k9+`W*00ZzR`! ztvGq8sw!IMqDlu#lZy+h#&&S%(I*}_epQ%wMQJTfX80FR1-i7AED6(!IAc3c0{RRF zNPE-6Frh}LlM|PU=6#T@%4z}zPZkU1i;mX)B_R7GNvFQJ1S4oo=_GqK+h=99t82BZ zcj8m{qHB56T<4+~u!$#eRyRex`*bo&U9U#Wg`GlnQ&uTHq@Fq3NP%+|SqQ##7HBi7 z&W*Xmw5SPIe<OV1%9Acrq&CY820>lV<_~Sqj*jd+sMsPsE8P#(rZ`&N(pyZG#W|8& zTcI^A>eX&|!<;{$B!RswI*v4%_6!SAbcrW!@}RC&*~%8cG<G%HfOT(O2&%!5s-{43 zC<wigZw7|AGBxX)nbgdILe$%Y8*%zE5KtTo4}u!Li>ZL-SqP`5IZK+iOCcOF;H<fj z4^^_NJyJ|ysMJv+5}RL(2qQ^T+a=!A><WOk=x-&+8rUrKB_HomQV0jiLY-zl*(d{a zv1U){TlsR&FGow6$I8>dPmj3%<R(hLeOetwFy^A<WaJ!JqVep2EI1uju_oxmCn*;Q zKc6f_1lB;#L0bw$lArS=Oo+zoK`r8|!V4<_lg|{v;Au}rUSup6#q^tq@XXXHm)N9O zSYs;2>^WWR^`%CMOI92`=I5*;D+nwV0$>=_Flb|{77h*xr_^ecLj<0oi|3LShf69^ zCe09yY^cpPMVgX^r-NB|EH4X3zvS07uq91lR%L|@2wQ0>0vcCBnoAORME5w?t{cOZ zh2yG=R8;^?g<w%x{*yEd+T>*V4e6~YHkYpYfe2vz`pFVpLs6n+0?<Mm&s3|fY%8Qu z?SgF9KF&+>^ORVli|$+Qh?b1v#jy#wYo}*s^k&>yv$pVPkh??D%(!fBX^q0`JT{}B z{*}k-CJ>Fw$P$P+F&z2A%$$!_;jj{y{j3?8td|?1V8i;4=p5my0_@{ep`4QItfdS+ zD_vA-VoKF9Q`$H-t(=Por|KCM{q(hzDKYDZjqGF(?hF&IdC07XhtxXf)`pDZi<ETY ztd^FoOQ)u0Dbm6=%|#L6!G_Jn&?D2Px*oeA%-B`VH2K&}*r^IXiU-4Om7xmajg{rB z89MQ7&rW>GfL|At*T@y~%q>_uip&Y8Ewdht$(su1a6$J8vRZXe(=z(l*Vu$#CksZq zpga_hH(G|P0%fs#HY$Rk?Ia5ycSCUJrEKckSBly-oT-*KQf0-!F2oogu%g9l2}=se zvhVuVk1mhb>C#ihX?K8>9Z8S|emp+JaR+I28An}b5JB=_L>68cMez)5*N2PH_lobi zvtYjmr(tm2bQ_Y2l_#WeQ<jqsDp*^B!T!O~a%$-&$c{2wqF2|eTf;!Ci9QQY#gP@Q zla-9(Pat$;V6~f6o-y~UG0fWOW;m2Swb=WX!WG-Z0A+rcdhBW{QslI9496HaTDtr} zzUVHBEK;gtelCLX5-}qovXy66wd|X&fD?UXW@b$^6r?UG#7uCY8o!6T15vNyi{LGG z5cxbvxi&^;VDAtUk5gu?rT4Q>y#rUs&|UQ)(j$0`YDYx7ZEZz3&Omw@2<%P_be>_R zSxv4+rYL?r;{0YG_rWe>&E}$EC=y_i+nzy;U>Pw0umuibv`MUMQa@1Xz%*%9kNmRX zgZ24HM6V`qlN1F&vB0>SM2}gW)bE{jIG@Z>nHL*qE+`V0E9^i%XG6s*-D<fj9;Ea| zQq~0Gm3m`%HH@X)p`cq`ZEg(c3pf#{Nt>`R?JvG6rLoKCju$h-*fthXa>v471CdPU z?Qdg9>IU$Yci?6V2Q>)`UiF6K<yI8dVeX+8X{1o0biwiQ4`RB>RN3MG`u%wN{PQul znyj%%lNe+E*b#*zXjrT`UojYOPMNMBq$|=&zdd}9ZD;mdxAuV=eK*urfS5`bV(@?( zL-j4#p~{Qp`L<PR{w<Y;{DB&S%0YA`|A9=U{J~_U`T>n~@tD>MbyAIqld>;MM#Zfa zxrNaIrQWdo)R{*+R87w~Wu}<>(3iUwKKlhe8x%hKfPi~k%$*f>XT>?lOax-u6rY<) zz?~IqM}vZ}0iMJJV)~E)cAAD+6t;+J$}pjJj4ju7d+j>w+m-x_Xcy$~_I8Pb42c0P zcQZdbl^0gUJ=d;4P2Hl~Ebo-Dwrvft*hrteouL`=c;Lk!RkKZxr>mded3Z`qyk=*l z<>31*xeJO0`PY95l3~CA=QFns;FGqQu9sH8UM#;6g$FItT^_DJyy}ad$(Fo=1Xk*= zmF?*pcUBjbX;f6SDqF2D6uUeY__z%hAk>Fhf-p%7X(=e#rAp)JqBWvlp1Tt&5mkAX zjh$MAtC$xIt>zD`MW|9zHU@T@^BWb0>wYUkGaHU02;N-E!2!@{1aHOPRKq`M!gjL7 z$hoYMTLQGL9e(nN1fE4n)rJiBB8&2dBtsu<BP4Z3tk2l`+W6^}+^XGGuUAjs1m)lI zFtZDa)}?gt&z2VSp5<>Al&Ij69I3Kz0>>K>;f=T?x%H2u)1-bsZZbB_?dB6fTU#_{ zMiDa1pqjVd&|K(1-q{5$YC^|>`&5b5cr|BE6Vgb5Fp17{nnewKm7p4n2~GxBJ4#|Q zNe0`+C3nSW?(%e~1>^P00dZH~`s|C<kZsi9F_{GL*KJRXnqYe6u_Xwgg;JrO4o@*R z4W4U-4y2y<B88KUOqfNLk0rE2=@m%aJ1p?mF@>pmM2IG{L@MReV9di=lzk__?^~pt zIdTWEq^~QwP+o;zF{GOD%^`-%l(B2dtQKF&|4=IAS2j_r6XkShDzi_fe$fO7Roa#q zgX7*UD)5}fk1&;b^C4Usw<~9pR?uMMwa%<Wk)F(Ba%s+>nT3VbbS3yVH@Hw$`|q@l z)Iy=lM>NY?4s`o9?WHf$C@ZaTa%weO|6b*6vK^pYqNI-~TWDfyva`A<gsKp}omzZc zG!?wJvTC+o=ik$;g}jL>hvMsV>5cVZ?EzQz^)vO3!&6+rP2Yrhv*;#Dki~=}S`FSs z1#`k7ZkkefSjF_Y*A4%!m0OWv$U~iU7zIor?mQI0F&a&k=b(fH$3?POWM&O<JnY^~ zwk9QKHT1BFcXBnn5v0ZQ#L|y&gD*P*yLE~KY^tm2^owdGk;AT8s_{&)V^@Q%o654i zf>OsBHNvZwR&ZdbQV4xfXG*Fj_C7Zg7wehU8DeFpK_UFubzn~)UTSe1pC$5$A5`iV zcE%25$}!IUqCod$ASG1fPRCBu^c;!)A+274*jaQtYz;SQKt*~os+9~y-({j;#Tj_@ zlUy~^!K0Tn=8%VX8Aom?h->U7_jicWBHW1r4C`cMu#?_$p{N^*CkyIQSQF}Al6%(8 zGIfvynp>+lUU_u>s>UU&owk8!H&rfqRH};+n~Y0V`>Zm$U#~dzVtO1Cr9;E-ix3ly z6jrbUq|K9cZtDgcXM^rqybSzgS??;hw<$)R2-4)upx4uaX-W)FtI6ZFgqzYEhX7uS zR56}023wyWw<=+wjVr0`d_yvFXZP3hU*<gJvV}=x`xvi>I&RD<3){<S(!(__4LK*v z9{N9l2xX>v%<*G0jSW;Taop81j3%-QYejK*7rzUZ_Hefn1tCjy5FKp@11e~f6l8`v z;P%j?lwb`ot{|KpU4&ov$$%6nYtY~N5LU28kDFroia5A1CIk`{Xu;H++Fu_&fa8Tp zLxV2@K<&YBhZ?TN<sqDQsIDQByP>{exAjViF(h{)Yh%7F8GpK@8A%)MZzaAo8-J!w z+<+PGyB{##4x4-iP23=w?ej6;;^V}pp0R_&#M=Mh8`Q*j+`EAZF7dm7;e){b!%ei! z^W%PNI_jq7&&}1*H8h7Q=^?h$0rInJjNcyuv{gOX^hdR8D+w>)=iX2cH+E(if7st< zJ8h>1@-c$F6eDXI^gz8aB*SIuJU}n%+9y1q^RC$eKp@$=+UzhQ;=0P(QIJ3r<k{h% znzAEU6<8q&yBg|vAuEGUqPh13uGk(ay@u~4oTm3!90fkhqD-r})tDiz%muK2E~3gy z;nVkFe4*vWFq92tUnz!z6LG$ioO66PQKwBgxV?s$XrCrn*wXkWRS1OYjw#;RPydIU zJUfIyh#9jR322kx+7nYyHm-y^&IHl;#yxHYgfJsU=G%i8bUCIKNKtesC2?s1l0LVM zLFKnte+3TQf(2F_JL~*L9^h%o+9bt377h~Y`s+=+Lo)cBEI-gEF8G`V_?pD9aauoj z5Yr$N2DbCN#qu@#-yrRt*p;c7(@tCHsJH=%SejTN!Dicp15cbJHvxnC4aPH^KNfso zlT*pYkKwNKjRBJBN>zD$7pf2|_m2#ztg2-Kr}vi*^Se^lVvrs{YaOXuR#@$x5Vo*5 z!6yK+NVIU76e|vbtE@OY+>l5IdAG30F%tC^jD#>Z{|K2#$VQfXg%)+z&`0;DN{a5u z<I3Er2>Ta$WkZ8c16N*b$CRm4#v{W|W10}wPBmN4c0y*uCQj{;XREQSZ$GmGme50L zk+$is>;DgB?;NB_^nQ7E*|u%lwr$%syKLLGjV>Eqw(Bidbyb(~mbd2{v%53DnV8tk zh#PV9pNz<i%$u3dbI#|q%k`ONM#S(d?Sr&3`<)`vOwrQF=<BvG8-Cl`bVJ**!w|7H zc(T6dj@cKRbHa_$YSZIbs2rK!d1+yCC}Ms)Q`C8&el3&IXNDaUWD*AVlFrMC0hsQ4 z&+#9b<aXG~yWEIezY9SB{;UvwkD(Z)D^t=Jr4@pGklB`6r0o;k&NS^~JjRKz5ZeF} z({oKLZWdS>gFWg)BP+Os!$?~|5%*0fqBQM6YTtlAGT)$sFtvgho`OHJeE*wvf*4+d z!!wV8q8r+X3cJH;Wd*5wf}S=5)GfQLu{Cr4v&ZH^%T|XSp+QNUo*%TVJ)~|KrJ@r0 z@6c2LcTH}I!Bx(|RmDM4O@4_%4$eUi#X%hVQ*@BVHW0%LaC(#03TW?igj-rFfIX*G zOi(=Mpd^(sO|D%&VA$RkqUaPc3d&?T$t8~o3xmqs`cKlV=cFZ-ISySRt$8d#%NPt# z;%ukPeaJgR`MPbYc`aTMr^Ko}Jal6d1gdieKXi!6ueLgZh}zxW4^bHby_R{bmGgxL zmxlwa6LKfFhlN<zlt#CQ0jx7}qnlF$rsm0TUkaYLIZv+r?hOJ0fg?z+dF_LQguup; z*&B^trKK61zkJ%A74H=s1#4-kUM;y2)$>#RV{->|Qc`=DXLDDM$@l-9(%DkH;?qcL zq#R*xpPoWf7VTem{LVbB*gxnvVr*B~=d*lkbR}#2-K~ptZ?SfA6KD@-9N4)rzZ~a{ z8QN*!{-iAk-{XaySztF$N^FU}%N3PyiOcem*YJ|zJpkTlc=53E9%&5rln#t6zJ#tS z??)B79L?p!m`M=GclXedHk14C7(wO%rO@4ja*VtXFApGmMigs%Xevwx%Jojn2?=Y( zsO~e54wDt}VYTe&N{9O6=*lKH`NaNVyiV?<?v<S(-xsG76<W13q+|3jZD3~E)N7he z^cg2WYorx5bfIB#c|~z}kLxh$+9Q{pj1X)kp^++|!)fUM#s_cm6EYZBQYVU-!I>-w zLSKX*`C(UCV8ZP@x&V=Z*ddo+$0%0JsWxV&zlDe}0?4UxV?ILP5uP`Po4%9;a8$)C z`mRFvdX{Gv^_3fv;cp%eAs^y`(sT;{>5F1r#@9H+U>@s$1dF_;sdl{~Tw3`vLa1rz zdG#T~;(*@ik?+5Y9LBX#n72n<&}&WexaVH#?L^wWlQ_*i++cEf@N~4I=2R0o4?zU3 zBJi^>$an9&q<|}4Yd&|P_N)otBUO2R_GrbewYnfT>hxPlfa^1H#ckR9sR@zguG5{K z2gb?58Fg>GXfHOsv-G@pSM3HbB!YrM@TMU377>x|v;3>I$n=}9dSK8PP>LX^hAt(; zhxD!;o%npC6;Y<UN3r6HgbqK{n;z^pXoTx+UEXp`k4}8pg99JzWU<#btxi8W!e}<J z>CzUoe1+nPxEG4~K<zhU!jh?@D4NQ(l08f&&sEsDzyQxpFm$rk#jw;}=h4}AVou7r z-8I%0e{$R&vEa;Hid;Qoe17a6K6YU`RlO3ACJ@UF)o5N@2iN6|pzM6>H$V7}-*{LT zT;E}^c9A#fqhn>ak)9fWQHk`N@+{Cr1M|W`o%9mfJ0XmK12tx#Y_)y~HKTQdG_7^B ztj<!{D?|>_6SOxxe-J3T8Q?9=4{1`+Ib<yyf<y#D#1{ygaK&CN1)vsC=NeY*!W3k6 z%u%TGS(39gsZXtNFt)2CUaS2#>|DdAI(gH#N4F}PetD!;7|d@`_5FIXA1Slp+Zd-= zaLi%<YuRA|+m@eNu{+&i5^ddM4!@4mP-DmnN>n~^yG?yjd5kIRSW%Xca*|d?-JNme zRs94oz+}AV4*;#H)<+xvbme=F`Ba$ckh9#j5bs3HjvplW1~V+>_tfV1AI~iHICzDV z1k8QoATfQyDiE$8i)+l3qhVBDvG`1vgnny-{hCTtgTA;c66>!e^M}2bRPYDIk?9m6 zsuLfw!u+r#0n}^tKKT^90g(BvMl(fFj2z3^9?<c(bWrhwN#H5u?h`~ssvCiXkDPoF zgE!Ula0J1|)rtLqf2p5zLT}37vKkJRR1Hh;gGrV8RR1u1r42%x+zEz`GCc&P|J)M2 zgF_#H16#B}?+cl}6t(b-w!ueiNhvzuOU!2){u1UOEEy}*$tL3LyRu5IV<$?buq+00 zr!$viDWtzwAEIH%%Uql;K;?-ENl^^ozY%MIwzv-C|BU4b+)(5{1b1ud-^6`;l~I04 z6oSH9y6HdGG=x7aH8=<1_L<|pTI}s#F!VrGWC7ymjh^1^p`A+&x&noq>5Mm!n3T<l zO9r;bC4P2hQ~BqUd_&@hEkI%T;^-)AdSP0sm}Pq<R^cJJL$pK_wj#M{V)A-^!QhZJ z&`e;vY;IsT@7eKJLPs?lfI5X%?(u=gTY5!%wf!t_T=Bw`g%3i#Aw>D8N7+}gh-HCe zqPxo=;`?6k_5uC;qv#unS8g|h8{4;QO#N)#gQcaf>49mfj8=co$Y0QJ?GI7{A$$43 zp$c9br?dz%9{_9&Cg<4356xA-<20_a#=BRa{E<v_8e{;)G`)#FNge4YPGr^Cq28%Z zm>Me|&Yne=@p~+{$NcsKh~f4&)CxD}iZ^#J1Mt4k@^@`8x#&3y7bCkZS57`F=UXIP zT*mvlVUO@6yG`<6SJ4K4WxE7J{ya0YZYaU~`VXSU=2><c3j4>872*F=YvKPOtN4Ff z3;#1_-9t@B>0g%N7i0LdZluExE_8^_jPlYhz0ojI7@0-uWT?eR8$ULAHaJhm_)nTQ z>%&y0Qlu<k(areizfA~`=v-RB=MV&GeLw5<{Lf?2S;!^iFAlHPl|PCsxpHQXTFE@k zQUPS2!1)*Mdd5BHR>r-Ae>BZD#4^QFJ_;W><Pv;j3c3uVFAHE5^B;e<=lPu^b3%8@ zwp=B%&7vtT^R{|ryVs~2p^+SMiR&of{RbPa!+Co15mwA<jtLHO7nSvlk7NBek0tUB zhXE^MIp*@LYr=(&q==@&{4^{14L?(~ht0cT(jW#xq>K27hQ1u&R|H<y)IwtmD=i({ z*?R)B0D{g;8xN)c4ZVuR`6h~frn}=!M{(1smW7`5-V1%i&?F$om4VGl@1exJr(!vy z8vvxVcy`b`{nTAV!F8;b^xU|?pkuG%RC}nwwbZcoGOuj5I8|8P>*%+yWw~(hC06jt zCuz4kO?Pc(ci=}BnN5Zu$qZw!E|_BOpmR?wGFv2kc0qLDfqQw-`)vYfTeV(=AF<7R z?*)qx^YgP_RS&jhTwlK^X;$}5miN3}fV2ONb~5=GHP;-<v&~lP;TuiP8;DYhU3R9B z4&sh{9-riyRtEA0HyVX@gqC_Uv?uy`9)evV3~Nj_iaz*wcYxqdui!}hEE(=zeJoje z7YoF=b2?lf{TVfY{7vyC^U*k#%ixIo9W`g&VtYnMvUaFAOche|oq$Z`uZGZ(h1QSO zrujuHlK+%dWGhs>MBr;B9q-vEte+U^Yg#$nnFdz8bdd}H6k6OsBh~5p80Ook`evAd zDzmE~<MSqFfb;}HA=S!D_%!1T3jELQjZF6AGxVR>O!a?C5%~YnIs327dUZXmfA*m- z#BB3n<~DYl7#d~0*c`lyk`9hG>P&PnFz8}yTn@z)GiXXQUN)QP`48~#Af=Ud|G{?l zt}@+1?^_`tm;XbHk~A7|aZcT)Res+<-+U+2*~iz*{J?N9i#?q;#0|8IT9lsX&Naoq zx(^EpB|7|J0<xEd{J&UWJ=VR{yZ#Uwc{*hlveCMbz|rt;0US3+e}JTDFxCSrW>_nw znTmEMI{lFt1gvJ5uZE;*UP}c4_WHMW=3R1JB96XSjO1d0c^AO~ttE->MqBBLYny&6 zVMa;rtGy#XuNn({L2E3AndtTk(ZynlBYKI<Ha%{5G=MjhU2Vz@GTrGxfAy43!*LB8 zG??+6EIq1ky54q5(bX?RB--f=n87_{dhQg_J&?Zc0DF0fNi{^w<zhul$PBN&<4Dk| zxlLMyE)6{%I>C@;)L@&lGr77YBY)}XC<X|%;kEl`mg8}BPQ^aK@{YGQgmqVt9HUmH zHIx#TfHuKEiL3SwYKu_{1ELpJPXgR9cw5kc>@L$47#!Ut?XV-vOG{i`1nHF)naOI& zP+E84$Pg~W)ST+*%`)bEx_*t5az2pCeP@SqcdOOyKzmD)0#rjI!848a*z$AUr+!md z0f;{`O10F*^drhDLm4rV#JLc;2Y+xLmT41WXbGc*6XzkR9Hwh#5MsQ#!CYs~ZM3TE z@o!j1zIpo2SWl;LOjewY^n6_TS#?zW3kq4`*ue?^y60QxP}Bl3!d<{e)1L2DLwC{` zPT5iT$4z*8WEhVD4wq}3Gt*`QdZa(YEgh5fG7O7m$Ap_w1;mI<tYvX2h+W%ab1ldC ze<c<(u9v8#N^?1erO>(T+A9jEP-)zLzjE!&FE8deZo-TlR^(?njAm6HcHHSo$aiix zv_T3m?{m;_jpa0K?(qH!TozZHKRYV7OjX)>wnTt{u%eWzukgDc#xd50F5^RqzhqwA zoW&Z4ZCIuYh&R-TxcsrxmT;(%(zrM$hcpnX$%CG76&iqaXLe{JtON!qZjaQ|qV7#B z=!+1LE)=K!XDJr=MMALeL3|N?5s{`y7R-h0uw+LT85s5uMc`c8v-_0ynTzdI&<2I& zYx9|7Q%pomR6?J@yW<sENSkBkiWP8>96XTWg>P>T{O7VUXPI(Y?vA}QDP$ur60{=d z8xW~3b@IXLW69jdNcGH{IU@%W1zsSFL7gkTmh;ZRxEMx($X*V&-jW>OGU_K(P9LH@ zN<Ew2qji1Uw`TFFN1o|%x%39>%y78w6@OpE^o4ik`p~Owlj~ZQ839&@6TrOH3StQh z`JGLOGE<<i<^LX)OSHUYj^m?$-78_&m~rFa)S4at&{92sE`PWeY$$Lf`T9@j0l{T5 z3EICU=KFs#GX2*iVB#PD8@&8~XfEOwmj7M3YN7EDIiP{wpI%^?f~Y=B9R<c+R=NPq z%?$l`n}S~5AX`&|h8yAlrXW8f{!2s|1^vuN`xQ=qavY)HXgD4(5su4IzuWalmWz-B ze&R+G<6>PRU+pDuzy5u%_NDKA@BQN0YhNv{V;Rff@yD#!A}9ka@9#hvWie&71s;(z zh(7Z3kfPWSL(IpRA}t65)W@8n-ysdq(=fgU3wR+7u)b;wdLet5j|oLy5PekV0U|_Y z=OgF=Wh%oQ<@l@8Z0vt%=x4Zc+Fwt-9iH_CB)!>V64Mb9n=4eNo8TLDXW0G<Z#TEN z)5@FTdLZB~(Q7J<JhdL-dSK#bKbU6~3O|&XB}TAUt1Kl~<kPXr*^uuXv}m<a(Vv2T zb{o!#SxF9^NLNZ;s7x?Quh-+Q70os?y6ZIk6H|YX^rWYujIi@$j2mHE^z)CFLABy= z&=WO+KF6h)_v)5vNZ6dxwnX(CTmW}3a6Pah+}4unGEk0`8zlpV*!!lbDJkJ3X{>D9 zbYXlWG!~_`NU#67`TojOI3ToBA&A0~Kh^ARpY+mf<LO$U9o0MFHIkEPz}R(BvJUT- zVrO*PDfuNz(5tvZQf%(woPn!wG?Kb0_7G>}b@lMsq|4Fo2`TGnNW9U0<K@R|RG%tr zHzt3x>o)q+O_iuH*83YcI!&b-yn2>?VqJ$h*|sUdB%bBfT=JMm?AU4zJRNYxw5IXt zdR)P9tu=qFW29XNU%XzNio~0KX1l1XnjE+jh|L+;=jA_PCalb@_r}IXjlRdjbFTdg zbc1ZZvUdoiz2wZSIIDcNiev8+UZ#2DRw!Jkq_!yF!=zRyTs-R~Qr4y9=2T^NBbxA! zjX$3vfq6~!F`Go97;cX@TP_wyH4!P-jA0M=NJ>x<&gDzTkP0YGL=S^j=GX35EUyx` zyMy>9v5OuZ^nmz@i995SEIRjitdi)JeKS16JkAl^T?EO#)z-wGo}Xi5d3M^;AGC?O zZTcw>HnzPqE6AfJv}z9rp=w&li8UP?`&2Gk53;!aY;~Q1*V<4hpq1+&u1R+8@$(e> zZ`r%cDJsH(q;FEk;raIX1ik?HSJN;N$WQfyPXJE1+xrCi7dOx|{N~3ztv?kI4R#-* zU+=(guuvVS22i5=z`5;%-G}NoI)EB1)BuXyiopuO7pQp?_7>fecBuo2fy&~A2T_8O z;)P@=0g|L|SttRrC;@d*f}Y}qi&27RC;@p<f{x-uOeIP@CG%awRD+4My`X{e2NOe7 z7=fT4JmFeHg<9SSA7#Tz!G)UM1Rrt3l~G6(_ykcix8>lCcMyEH3^x0><q9E&Wt)Ij zPLO>Np_U7~Z_!L<JZkU2TPN=lqR)irz|&g%8z%qYqtEo7v3ES94ey_4wYWD#U)bV5 z@5ka^ociNlrBC&^&r_CecPgL+XR#RliHyK*@m>Lu`@@m^A8SSRYx7cEABcjr2QRnH z@B@iTCcu#?Fr!6{0G#KPpzfrQf4MjL%RI~&p*+=vLHR3Ag9&cqS%LWf&NM9jYeFp0 zywS;P!o;&_>b%pq^McEy6X+T0<oCpG&s9kd!eyj~;=_o(8RDPSo<Y>5NI(V_(0qyh zjXL#v9r6uTP!W329IgU13lyDU1E-@0WTzZ(jqIk#J1PSxD54qB0FnREfXL>JF91CO z;y2=q+r>0G5xgGejq2?XrSzjw?e-0MA94@*P;U?q!(S=N3Dik-d<*|W6bjJC&{h6q z_Oct?cNZ<J_eS*J>^F&|^7@?rJOwat|Kp#`f6br%hphfzBR>AK2LIoz&2k<XZ@kq- zw%T-0ih2T>=(I_x66diD2iK(OB76W{v>MTnr?aT6!<gZ=tohWU2<nz9tWB{O&7-s~ zu}$$ch=V99PkrzsJVT$7HH||tmefsd24}ucPl|;e;_LTtW_G~MY%bSJE|t)8;XFSm zW>snkB6ox!AO2W4JSNL68?~A8Tv3P!Md%oO1~W9X_A~$#@?V@;)X*3_qe)Yo2u7$a zqzHr^zILn!JflYtQYKy3Fo;E0$`CCClbSQf&;DVMSe7zl0VGDRLDk-25%}R=D}?!a z4d?urOO4(okl(ko1y0J%iy(eY(ITy2dd{ICcs~E8|Jr>WXx<c|oP-^%>ICq-IQ9qK zwK(o9=avgcgZ17Bp@td8xiQ-~Mwf#GKw6AOv$aOerg;#&g-TPQqo^1@9Hc7lNo^~f zNbiZJ7&2N(jh(SxFSe*^?iy45p|BXUt7rj4dD9pR`3K*Kp(prf+OBz!fYIo|z=Cd( zv32g-b|5c=llt8g?OquGPrY{&giO92-pQl}Y_0Y5C!#-De>Bg24Zwl^HCMwwHpa;! zes3J`m;Rbh-Jc3+&w}cHn*iw88ye}w>YW&KV^MH(H1v*xZ|*ETgmn7|g|l-Kq<8BG zapN*re|~f_^5GFSAUFyb`6rMMd$|LUA>vOY)&N<c9$OZq?v5~pe|)`xtL@H%3JtQ{ z%0L#HzLnAvntc+QcM^C3VECs}tZ?j2ALMVJ)!+qZ0c@~}ya2(J2u`8n9|QrIL9JFk z?<4SpCeArSRyh6%LuVKtAt6TM&QI~zN`Ip{C=Oi$hzS%%QFa`9NY|w@CY~PeuSW+R z1^OU|Y?9i?Cs=L38%0nQ=&{gtFUkmUC}?Mk{>+p?Y##FKm|0p&EBy%_mo3=a<*Jx~ zD!n^k6iAOQ@A24DU(Aq3WFq><lN99rrQf7iU{ub~@f_h0ug67fOeZ>3kr8p4(a_(K zkq|GCYb|eEwv_DsmLpAHnu;MTdCTt6;dGHJIYoyV<`ZCsveu}#pSpMi#>?Vh9ver2 zb}=eU>KR`k4-=dAT>g0c<jX2_z``CYaX9i@25%`yJl9FJUCNW9Li(X~(R-+FKJV|` zRbIdGUpzVT<v1x+n&IbukpOB;nM;{4iSg=eclM5ti1UqmOE(LIREZ<E<o59g^M|(- zUrLNkoaIjFS(J~~SqE-8ZUKqwDV2=JzwzWpWwy)G<hb)tAUEgzzv|buOAX+1wsiG) zec!ft`8b~)Y|gK*|6bWr8s#qI@pgK$zj$~&d!|;y$#AuC*prWBsVU?W5HKhR1oYJl z<i6$LRa*1$zW>VQY;WUA;`G^iW-wsb9bK@QbLZsZY(8_l%EjG!<813_N1pO`Yw<9X zveJ?>ddY~Wz~q#tEa#$-oJjGVb_O^64T()X89TjMkt2&|!uT&v*;@W)53N+#054u@ z`4WY(Hiv+|{>)q>03l>24ZAGJz3mEbVZxhJ!fgh{L<c3J)ha7GwQX_vZ*st~D!3fR ze0Ky7pi<%?q~?$5-Ie)Gs)8ihok&=`M!iHrKAm^XJc?#H`!C*7suwP))H0UgwHlsk zqjBZ41`OM4;;^q0MQ)^kx$m}$2fjm#t~&bh6N_i-<E0Q-+^Ve)SH85aex}{@4LK9t zRoy-_sFTcIs*#}+Y*})s#|mvyiN&+oiRs52$>bGY2M=8sy|ltYja__o-~&W??;m}Y z!vooJu2HBS*p9jaKGnG~xl`$i+7tX98n(9JEJ7L23ozeDU)8_@Y|c^BSDgJhd3MgM zPBSNV0a4DfQT&=MmfVMkDndMcHRagGVs2UT?@H{4`3&RB4Pp#0R8xc1)7fu0r}ta+ z>LgaaDO-*Bt5a2$LPG3CC<KQ-3DGuRHjTAQ1g_3YUtWp8!~{!8iJ<llO*NMG)*CK! z)8@}%v@zZ&f_QP+0_x(L_VS{PX^r*!wqKsalrc4s^Mh`<{Lm8|+#pmOlfz+<m4Ibj ze?-B?AuMcvl>V|IoU9dq3Z#+cEe2%b-LTey9j-q?fAJ94fgY}Z?vNLt2bUj0Xc1ro zDHL8vLZ3%wivE!jVFfV46_ou^FvO%bI&+@u{YHl?7y&oQtw#Af(_J<=8$mUggZ+ax zFkZ($|H`95Qg*}%z?Ge(4n)dZz1;>9APm6GC)dI@o`<+;;lAP&T{=+n=E+EU^D<XW zl={*l<6sxbF()a4Q@4-?tCOZ4?@j(XyvLx^yyw|pzJ0$1HAv311%mnOk5Ju4!hT7Q zP~EwNQK;p3noD~9nL>y@wkFRPG8iFh-7FX`v<9kuWJf5as@>v13R$UrB?UYNK<=B} z!hea57_kB|LXD1EVFfGyTbfG5fC({4yK7M~{5%a%58-Fz0F_CPR)co4=!g)2h{nk( zqSizr46}ci_3k{V_*<DA_c!^|pm9VrD4F|Bxg=@NlN?yRc>+p{U(k$+He+_Q+W=aT z1MU~hxBMFP!-UcKku1VDEK}3@ye*LHgYQI*TUce+7+W(ddpg-;^+a_1XA_E{IBW-n z-cip{bl;t@7jMd3*`z?IuQ7EtHir^NzH%WPm15x>Xy=kGS2y%`^tb9Q1;V$2D&Xfv zixrI#d6IG}xqpVM?=-1HG_Z+MM;cNlqb{w{z?U8cN1Z&Ek|srVSLC`XV-5krD*e>F zT#|=vI?}6AyV+JlvF*Zv<fLI!x^9`g=Xim<vW!MGnlk-<=;7ATR^HM#8lJlQya83K z>l5@BDr3{-`(tpNvnDTZP2^u(-EPzm$jQ5(DLdx=IXRJx3ir|v7&gI_KASMK3L{2< z#<Y1EmHWw}i@_vC4TcHn6u>&}2V!935D_2|H^Z1lLh-JqK}N8pu1(pzzm1y8Pb7UE z;B@Pya4%<pyQRD+&0NO3u~;Q@q8bj#q}n8#p3{c?C2><$?@o}oC>X#jjHN-$f*$2c z09`io;aO5qj3?l~g{lCXBvoFHO5+34^CWtz!Xl7Xt#~~*=Egnvl#=!iFHgH9k>lR% z4x?w6O{rm04f$=(VQ6~mbn1SPMx=Wb`X)%rkuMe>4NozmjwlyfZi^5&2=m4rN`?Iq zHIxb;2%owFHN$Gy<1OZ?_~3CiXHWt|FEp_#(NHN@C8mTIy<IU8xlD#`GafIY<!;(o zaD!5(F-~zvw<VL^DK|f;EmfkEDDjMkr7yBujy?4>(n{F%b@-BD%$K-<o?*c%3{r^0 zv=1t|tU1atfn{;@)y9a+U^`m}CdsGiVHiJvEXl4r4sM~W4s@|jsLj3h_M>fOvrv8C z2pro3yB;2tz8uj{TxphOEniN8m6~ynbubQlt6(?Uu3uHC5Y)E}6I`L5d>k(q9A4~X zV@rD|9~KWmx-q4@QjlDRv{LYAg<^4!F;VO;p<N8Tsq@~Fy^!%gdfTfw{$eq8e|;4w zi`f)a7==_|{L+ECGsu;voaE2RI+wA(#9w}$(%0B&;S5lsM9tmQ#mR1t@T1Z*x0i2g zY9DLM=SX+*{~b$^Wu&njorl3NlE<5whvl`UBPw~^&wnO>;@BN5+nZyWjDErPbL+RN ze8bd}jGEeUfa1+0wUGC_B-y)bUR?=9<t;iPmug6ls%v8pF*GkK!HOoTPMoOt$7AZY zsd&DAyAFDoPJ->4m!<aW;>vBDRlCjmVeyHq3(Hm}V;92jnu<@{6eE`N(&`Rr+Fkiw z^#*AbQhmP9>Fq+<OLev#uxxYH#7e(&P20qAQ<cCMx00mf8rM%39vb#eJqBM^9U$H= zrfz->|3j=i+6@cgm~<-Ya(ee9azlLUUzwDghg#wKT}hM}c*Ks;N0t264r}XHmzf7( zScG{BT#LTOEYs4fge(ICtAN%k0V!hKe$_n)S+Alub%xC1h9Z6m%U7SBF4Uel1T8CZ zAiY{i_362@`bs|KvkXshw}Tzl(;PJ2GEx1#DmU!J58@xF12X4whgQ*pkE|$Jgj8V~ z{h=^SA(7Bz{Pb&t#djAWcUBifeP*LCSn~3XIKlH#pQr;i;9o7#1Ez-)^1QzL(DF+7 z!58Udx1A7>ftNqNkv|2R=Z6qF2ZfmLjwl0%M}^q$66HV2qJP>K$jws*Uo4W}E}Qmd zx%)x}Djpdvobxm-egD`;Qv3mVM=lLd4{r{+R&+wXflbY?{`&hL0Dch1-EO`RJU&wv zJB>AKVsLD5c5o!^0f!!XEg#&;8P$I~lxi?HJRDM&9VBp1WvI?JYn42WMF!?`nX)Kv zj29#&FFeMjDZ)b6Xy#HCGo!1K)C*GkR7TrY(U2JgD+P2ydUfPh1qiO55;IWtlT)<^ zD`RoJ5wIQsL;q?11L;7Qbx2}#TWLan=B?m|1TQ=W<Zn5k@g+I^_I35Wx*jF5x32P9 zlZs-{pXymrgULVbvM+;FKEsFYmIq5}P5kC?z7FObmc~aIjT+ZhdEx2eC>^g3;khqB z2Q|I)A}tcV2hB03qxe8Q$6SiCxDnMHjh3eA_Csj;sQ@Dvrj79-4`Go;((}Z;fRt`p zN-d6ajVYfQ4GRLs+D;e^UV0MT!k|@n!#k3!`PSm3UAv#if1LQCF&p2A^#j$SFf{d_ z{fg758j7M_s8I@+X1OBNGwIAb!|*w*1`Wj`Bk>I**Y|E(p6EVFsQC6T^MahUAM6ZU zhHypa=<A;B#CsVhHc!@VFBOM;b4dUFL&zGwsPXGl@M|10kw}Hh_LU!(5BTB^KkQ6* ziZ<X!uHU&*ADgP96-epf_BE(2pnJaW7M#+z;fHBl&B<&u1%Pt;a#|FpizOskwcgcR z9HbX;zRiiggS+Q362J5)iBP3Fk^l;=7J$2kSWuEf$zMJNwNstP>p8<CzhbVQ-En&0 zE^1;IHSpZ`mc)=LY5sPQIg^+~{`LZ&J|C$j1W7CmyV<iGbb-E=n&$*d2-O?C)12qn zQ$1xztQ~eeXx@fREXUp`2)COZ>5N_wlH_SklAThWuA5ze;xmERfsF((4l6C1{hbdJ z@m2ASZke6r&vs3IxYnWNp_WzRI3Yr9AWt^1B;khPJO3@f!3#P5bAANwl#|P3&+-JF zmlo6DV}rd#$2W$&6-_Y0r2AS0*d|vm0ERf-n0`d8_g4Q&GAHs<s_rLFy#*_m#7FJY zUiw7e8?*2cD$4reISr%tEu%dfdcWQ3Y|#Bgm}S(k2UdQ<xGhkWv5ly9SE|8#v3jIz zbiGvNE-$+OyajVUFIrY`8NDq<)8&SbnckB&qK-YQ+zurGR%y&UiH^RDej9=BVcJA% zpS#S}LE6tUomFK@LKi&@aq6y}of@ec2BlFll62y)>MF{KHztgd9s-MVmOA`ehFKBL zE5@6QS)+ww!_uBAyO)%VIV9R05qtFvFUQte(v7XtY7QL;&Dm^pb(}eJyCs7?<rIr* z!BhE|p)Y%b3bE-1$vyy_9KJ3pv~9P_6DPMZgChC(J_ckaei402(wG(#9<s<*V=YE_ zE<iAb%j#3@((m#!q|?%z|AZRg3L$*IFwIr!asY{2`wef8t@-!K6V+x&#G2UxI@JsH z={X0D8M8vP*Q#f~ddaw*mm5T;W}=2l0`=)lqX8{Wz-IioNq!+hy`T|^4<X@Xbn>6> z!6q@$`i1qcVDrROHz|^81F*X0WyMZ#Ht>wZTVdh!UZs8iCo<-(s8^po@vo{K$Z~sP zJSqQ+ylcjMOP-O72>EiPVT3^55&^l&SM$PpMz}@++eRjijPUDnkwVSn@bz#52;a0n zPmU?yl44ecdgn*HvYLY80(+&erzBP{{}QriuW4k*#wCHg=}f$r(3x1ZDu&Z>_on%p zhU3)^(^yzs5JMgwR#gTiH@K+JPe%aseRWZBhAIGd?^Kn`G6XP{CMXj;31&N#1H&UL zoC}@o%S|M$i(9s7#E=OOvTKsv6-rO4feo~%L2^*^W}Vn?-_riRb=ADju=>ciBa<3o zf4jop$xMq@Fg!qL4#dU^kQWo;OL@`Ii8nb_HQu$PwTGbbm7?bC7Es-o=DF*`MSq{Z zw#}mquGbTshfhu61}Qt07py88teP2%)-xY1nYRIVI7;|PL#mhuf$P@0j$@)~CE1r+ zdJM^C2ltopK`FN)wV<M)H_Y#fqEi6AGps%Xc?@`6%^E;lhb_%+<^;cqaEwgRt0l~p z*LRnY#P&_FG?@a&Fr3l>hWl1;NXyx2|3as3|98cSr*DO-ulhX*p|69BvHJnc>V|nP zH%xCzy)!%=kg`n)m^E1yov5}l#<`gp);mVt?56LWq@y^U2I0F;${Cs_vnoV<s}Br^ ze_6{0IXf`YQ5gFvw^-c-!ktrX<)g>9n}D@E+Y;-9$>Y_^zIs1Ky6y_~C;e5n`JO<< zyIy;$6=JTQjR~_>%d#^jznj4$B)mHbY4Sc2pWp;(WP8M4{tDS$7w8DTvgA9dc}DTz zv9=^T@4!F8^$9}fTYn-o_a*ObXX22*?nwjHan+8p%Lo5^>CH|3+{JV4Gjt1o1X`r# z59&Zq7h#wE%4<jTc3*_Qk3myJ&nA8E!v;HIUsKS}1Wq1$W<J7I|LB=AkGuIXiC<*z zpO#*as*4s<j<5R?nfc=_k>7z9u=kkDg<MOlV|zW0M!E0WneW<0iq{N{#DH3IfaNY_ zu~*O8GmQ6(4Q;1a7YZ$O{G;D>9lADn$c8)<vCj2R>2lr?wGVR=uKvgZj+XMs*)yt# zzL#_OCxH*Kewu@TiZCcExC|k2%L`iVU*U#69dQ^Dap@It_zLu890U8BVoIB<@Ou+n z7i5N)k;P>Z`<6(HwYG8nio<kapuO@=JgUJ1y_#}Lv-SrRZCS%kWju_hc0ff#tg?;v zsn1TgswgnJG!b9QRb;b%Zs@5Hq4esP2Vyv=^d~m4k&&MvY@6>O62uwUIrzGIfn3^_ zPEDs=S6BovL558x5Shu(x`IH~76Tls-R29oG{zmL3B-bc0<8%X9X*reuOBClvyabK zpn~3SS<t;6&a01Dq4W>?w${WCL~-0O3&}`YnHyrUNW%t_Z5em_7Bj1?4*@E=&mzt# zQor9WAe1vo>59jvi}1*K`$s#K@$2;MVm2LhoM5Jo9-Hn{EVS;nKhSp+=7Xoj0O{-N z_i&#Ddtj`-7PO#B$^DTx5vZbnD*=;WCUm=cNXXxkz61`ZoyZ0~4+|Cr-Wd6l35E(( zfmI*SD=_|9h`)y;=@NpB03$0n<_CMzWX9<?ojZl^R^}An7gO%bbhB9lOLVCvsm?@G z-^t4*{S39$^^dymeJ$&<&1{4%J`N$`R4IuCr#0*IIX)-<9)T<zn5YMrU>atkv0^j0 zjKVMo$nu!I4>iZWiztnPM1shk<0I$rCvN?JFZ9Hom7`mj%uDW_8(92E-*t_N0}!qq zcYHw^LLS6I)_t$<|FraIquJKMFn|0Yp#LAs$z}f~lAPs#S5E$4NF(GDj^@fvHjeK9 zolc|tTXsYlSzwubc0}E--YJ|^r;P^nB_{Wflvta(YruigM$}a;HFja%6$KnCFo=j^ z4}HjjAj>VnWG>I7zh6kO_yG3|aqE1GxoKaxF&GRjl2Q?RJZ~bJSXp|ZD+=17Tb}kN z0w92Cfj?Ref6qU;zAA?)FV}BMk!YDBQ{YD81oLdqaGdhnytvIPTKZVPg#9Ct8(wN2 zJU~@^M*^yn5&x=-*`&M4B%7NouJh)OP@J6sl>}zZ=psV&)-|QM<`APew?zxnTz+(D zng0ZiqZk42z4k98c2#CO$de-bdNGXONZ+YBb*Dn2x@S|Zw~_`}TM^y$`wj6={n8Vo zm4%PrxNqAxAI+jt&B1~RLI0`X|4^vyL;r_(Y5zC=U&PCQz2wyYpDy`-H#+<N$LI{? z@yd9)zfX~mfM+I8W`QP8jSd@YRs;_tw`PZt2E{f-5M$M0&xT<`1Ibj?{Z-=dw*)~0 zBr~CX<#0GG29#04&cW_Q*N&^!pzX6i&}g7M_jRuOrf-ToTY7u{d!E_rzgeCC<9D7H zNX6O<{2<>blI$%n2J^dLNI+rq?LI#$DU1bSY&bdOWrXa;J|xYNS~kT+JVHb`%33G_ zO~vhvCgb-N@baqZioM*`-zfsb<IardqW9{Ab^{5ouMQ6TVCO7&{kpx0#P$lMpx?WI zK_NuPn?#3)Bd~$uLy5MxwAbs#D0?M<dR&HQ76_p^H=&_12VC_ds%{`UR-xuC8!r9W zwnlI0<-9A)^jIJU5_9@I%T~Vp8KdLw?3f4!Qnh!MM6c9{-<@EEzYtcTm3B<GPf(8$ z;7}wYAX!gJ{R4F!sTyce;FTstczTF(EjV32(d7}RXX6;};-Wv)$PAU}b`}<+R0SmG zQexerfm#?4I66AwWK`#$tx~E6w#Cd>0qbInECT18@9?qaAAsv!PoSOs4MTw$&k`5| zLxWB&k6bR7dON-{Lr!+c6F1D)UKk$*G5hPr;7*ITP(U#R!qLy(QX$nl3yhz2hjg@G z;zL>-8=*oPw^q1U7N&l;XS81-e4SN5xdx+UfX_!dBop8gw>Qd(8fa%3#`%{EcPD1x z<RoySo~!!_vomnMUdZ`!zw7Bn|3hWy8{qRjHCD(DB={>3{2lxH?d15G81h{^v^xs! z@iim=Eip7e3*@@~HVE~*bwIctbCLKV0&bghm_RIVVs<x<W3Lq^78-f$DZ$ObO^eQ` z&Ujx%42F!`Nmzo(PkxV4Tw4;<g%X}ajmoHjUOQYLqq9P05Q|!Ip)zWZP%yqvYnlK# zAJYy0*y0Gynz;H<K`N^wHlQVrLl-@UdE!reLzW-w_D|e;j4p`z%vZy$g@Iv?VhVzF zW@B2cEzU=cSzDrtp@FLoGeBCSfnrQ(m$mk)Pk-RZ(3ydXxK|lv5u@D@gMr&CvMmpl zP}VPuBEs8$C@Rq#dl`!@G+NKwfhviHbrzd$iqWa*c8Tg(PeN+S;HERb3n^&{hZbL> zT^S|E0p!~&pkhQ*$m!D8A2Q`|s|}CUl&I4hg#>SB*=i->L{=a@S6H+rHx$BFBqxOd zm(udn8{rLWIkg*EkIW<|>q(K@f{ciOB11SZH#eXcL|0rR+34BwgeUDns2g%_bCS_x z6-549%A%#^7e<Nv3xu?$V{Wb;ddvWC`0iGj94FdJ($eFUlm&+km5_91lk!y9UPjH` zo7@H-+0{@>ZTOrxYOWp{7DQJH5-MBqC-));H#2+E)gMCmL~>GSY3z=MzhH6l@+V&H z64E#a*O#Pa2u^PFd!1!BTgNHI#S~&aXnc^Fbp#iG<40}sOBi$Z35lZX;>RG#4yZ*% zmeAV-cXpM^1Rx{Hrh<nkGQ-h6r*5Bzpl4Tp`9d8=n+N>lR=iwqjlne~W4Am{Efdem zEx%n$F8-VBEx9=t3snL(r2&nQzPwqRxcKEk1!cPU>mnx)v3g5BSBvP9#Ib$cU^m&M zKxS)|tcP@$Y-%!{EE(vi>S>YAl9{=IEfWV%xlKAF7aZMb(-nD4si3LJL9(KGx-q`< zzS`aHMyI5Lnq1Z_lQ3ODX(>l0E!hsfGc7Es*ORM7I;k5`1#WYhIF^dKGEPhtoU@UI z)5C-LH&rZCZ{rfu%mmDjAoL#Eyvk@87h7}iH~b@q_%Eo4;nC&ZY06N)t>7;TG&0qn z*L%SRmIE&9&h)qk<yac0%ASndrzi1<wcRu?nAH^<ZESPX6?5$ww76wURyxbxUfAkZ z@tsKU3ItY3`0KNG;;j7a@{n8@GQ$*>Bqj|q?nv<36SSoXG`Tb{vl1J*C1AVe>X?Da z>Q?Od`}x7{%l+eQmAoVj6FYHF+l>@(bBEHlBSC989V}F5$cZy^9Hgrzx;6UIbG@a0 z%;RT93gh%ond+xIBzhqRB7`h^tpUty0R+Dbw=>pTD9)r%cMlGtqJK5DxH&*(cRDNZ z6Yli|lJiK|LBMR<BxY}4&Gw07yjS65?9)O$3AR)wUtdd;qQtgJtaE83$GW`WtPS(^ zh`eF*YQ(x>|6|eeDl=UZrWs02z`B$t;GSMqnFS|=YnPS6#d^3O(G$pZ-2&_h&H(xZ zecVbDs()hQOB7K4{@Nhtq%)0WY(ORWwL#14;nMEinQ#X1w<WO|Uffw(5|3JsVl=Qv zGij-U;rf-`!G>u?*+HhR^bm-5n0(;OzqFh|t`d1pTwt|p&tI;GB|usdYgo4=LDX?k zLd11xDy&}{dpTOf7%^JZuA2em=ctLzDpGSTC<iJmj!xb(cjrqhnWfq1-?DzC^8Y*~ zZ#US?3%=}%UL&*RJC{G*5FyBI4v+JT;FH2~vE&zl&@>jtlCfVLi|Q(<3#6Stg&!sh zIqMkrUyp>6BJCe#ey!dMmQHNs!hAu{o0zYR%{RruI=&=m$68xswBU4F7>hroBxoG> zx;(VJ-kYg=Z!v%ISf;?dw!}qIL+BrKuVz>q^BX0U=+&C=JaujKE@a%B-`bPPAQL1O ztcpd7Cin$pb{dh=ekH<qN5O34=y+dqvUbwl|3kLw(ayoiwbtn+ld8SB(B(K=aq21A z7cQFOCAvCRe`xj#*aZw@bVT!WzmvJ6G4Rh>e~sH{h~4h?fa(;ale}=3AJ}oP6CYqi zG{&P@2%_}AlXfL1<XG*r5gW;QmfU|^J56}dagf`#&AdEx>%GoDM00PHybxS=foq^7 zYVp1>Wwf)%PP1U5xnOkR!h-7NE;}0QO3{n-s2l%L-JINS-t=<YzfX64MDVMSyzo?s z5=RB%W)nlY!Fq2-1kdMbEY@pzASWXur=Vag7URyxpllS3w<asnS#g}}9kN6q*`R+z zdI{_DX>4kov|sjczjIn@M<e;zLC(&OspQ;t7<$%E56j5-$pT@a9sj~iEl}A%*^;T; zi9yakESAaT4jIdc(kkz=Ki{1<zDXKO>Q$Kj4D62if=~+p@ylDBzs3xiX=TjpFe~9^ zIMyBBWLLcfldr6m9m|ZjVR+SlE%DMDrlEL*yI6EdnzV%^1Dkoy6?@9JpOlbFK@muG zB+8iOj(6FGdFkO2l3k0eWUi-oTCnOuV3;G2ES2?<%FEe=lQwWfVCujTkEdn$Ox)<J zidDJsls}Fs!CxL*Ip*>kO2)wQwV_)<#T64wpx?RIDJ-DsfKT+8yZ~jM_OSLB_eh}c zTE)4?;>KK6W5A0uxe0OhxUw9Ue*iabJVn56^Z8S<cZ$442NTXw=pQ*$!Td4;GIHNC zsR>Per;7z<LY#dJi*9zr8~3|BZ$qkB9Zr}{=$n?L*>lF<ig5tN30!`o30C?_>B2CQ za{u_S+xLL_%k2OMJlxCNH4Y9=;71^<c1TCNlfC}(VJTUEgz+!$V5a8ASS*Y?1Oxxn z`3uE6hA@j9$w|F6dwU1lzBFWxzeLW7C4c-4ddd3*Y~Z%ukDBvMa3bcM;wGksoJWV) ze2<z*jMh*p^MMIK#`hCD_g+}Ot{#KRNO`O0z7|0{B{}*k7e0IP;g3n-eR2t%U@c6w zC(Q4<#v28n!tBL##(t*2A~P(<<uRnOMEAQEU^A)V;+WFL#lUpKSLM~o&vC3FxvS|0 z6ruGoChx~g|HS#6Te1G%jBp4D;ixdNu~Ugu61^3%M$zjScM*(%41uMo;AejhI}g2n zd8f)~<Oz@$wX!16*g0<sy;mKc&n`-MD*7`1oalxwzhRbFr<SxUX;qeVIcFcmWXxSd zOYUZiPo6ukqlnU!BTtcUQy%1GXC*I$N9R<Vxiojv7Zcs0vrx_|jB~&xtT+qIA~W%` z5CFrtxLJQuMNhp%SSGJ*Hjri-U9RE1L`W%%uEGD4+W}#T-WcxZiwmXDr=&|y=h#UF z=?GY-5$KrJf?yGjX(?fhnIVIW=SY!NTXpAk*IO(txXRD+vQK<ONNP!+p7RYwXlHup z%E^~AO{j6JF>OWB>|AokapaIH3787pf&lFZ^Qy<ekNX>E?h1qWdQ9T!H4c@6GBUME zccM0jQ(<5X3HH5E%aR&GolpNaZBc(Qz>!8DCj+&f<r2fOmo@ezDcCN)+Q5a3@UVBG zZFf!)NnXe%TSe@K;gNKk<LM-QlOvw_&&brRab2R;-;Nx`U;M+N(KvCIwaI*w^5)CM ze>bqVvyExRG}Zc{FGNMV_#-QFEag9sx$`zznPw%f=-oDo;?ZT*Lj8*j6`O_Ejk%NU zV<^wx>`jj-vi2~_rOivr0~FQF`H=Vd-WgvrxLy+0PW-mL8=Ugs@8tmtSJ%njd5lcF z7j7*oRPpDm(aCqk4{o<CE<lU>;Opk0p<PIhLt3(*0ruh*Bt4QXJuz{N@P%n3$CucF zukg1XY=d~N!}+17By)0c_Db@{7OsuDvW#x0VA`xGe3npqbB3)hh8CJ33zOT&y5jqe z;>)@5(6LAoluQ}ROb)XF&#lq9!A`s2Xly2~K^hZ2abA+CCR)3j4~CM=<2e5ci@B&L z2urvb?tSwAGGs)wr6NnE=CXr0<jaIB!0#m)#|$@()t5Z@B6u97w0TPT@(6eJ=#{SE zH;oI^m0Go?^$+>18T|}3DXmnuB4v){ZfwU46846Y#eZtHaq^5-+Hs+M;O(hZT<{EJ z)|<f8<)WkIdee*8Wl=1k;;SlIx5ca3YL?jk`K!ERVcy0$YL=&wLM6&!;$EmBFLW8d z31sPD-QRQu;$|XWB!P8*yv;z(&Ly|_SlwYTwbM2N+Z8G#R(@ZRP6(l?s;#K9Cs`*r zbJ_>=niM$^+Y~K<sLmFNRvfl?wX?`3mUwT#pY!uTSvPJdS()aBc$-su29Pf^{XwGA zHFbd#wnN9mMrV~D<Srq#aep-vv1GK8t`{bwV_Cz$M0{8lvA6yGftbpnY;_V<@mVBn z*Qz58ZNNF@+{VY+46;dHWBDZ$g4UZkZbmlJMwg44OlWC%dU-}^PCe>!&KoG5<XTpM z=FGU2{8N_!Jlmxx15j5|=RsezHP<bn)6=BA=9ouuiK+uP$2RSYIG5gzbvE@&eV8Ng zYU+!J+vxeCS@=m*xNZ;vTqqGz2u$%-xo_RbfDQ6|!i>19$;ISscqlv-Zp?`fvSwfd zLaAzkI8g*Q^#1c}LRd*Gc=^O-Rz{2@6tsgKod9Z`#a9t>3E(*|D;CWS9U}nYSs^B@ zG<n@#2+wOTQpr$NW}LBpt)khbNd$T(NOi5YQ0k2zIkC?R(#prL_};;ig{JB-#IL9P z0F|})$E;{O<Z)mSb4F?CiCyTYMAL%WxvoF7KjE&&(?3r*Y?rIwJz`cY)Pt(BBVfid zFH|{AK$>iH$RBd{p@z!XF>=4u=YC=^H^QgD|GlH=bTJg7V7RECiAdme=1__fnE<k6 zzqX?IQHGk#z_e;%LHU*XT=Ftcx!C+Qs`Hk|`lY7egMCH_!A(qJuVi8n%iYDpv1#Mz z9{mM;m+%G6);fbhJ0%45hF%E<M)!(lv*WPiIe_Av=B^7VaX==_p}_y9t^>U-KOF#5 zb)F=?W7b5>{yXQAL4L$Xe2{>a7bKRqSHeb{A2PkNtSHX?{uT&1V87v45C+?kEZ-Ot zKXxTxVpTfzhx&^h=rB}*-o%(!K&toNPx^?iGNCB`eaoDE!WGUKGbs#$)lv+$TM2Fu z7OP<900|W!ys||8mnZ8+2xOHYLJ&++g4176$07zkRe7l?jLr(zwwb3D?DZ6peOt2v z@Yx%<*>YBtgNx{>-UOgBwwb`DcVki-iD7;3VAoHID0&}e@m{B?m~>5NkQ<Spm)*Qq z$s#L;jAjqBCWnBlofnRdR*+M#EM|mgfDy)J+@ormQ6EIWG}ttvq{&-Pnf)z$7#>yU z+*lH_aS%XqylQpayK2)lifpeS2e7f{*s`mxQ4$*g$#MWa4gzst7rvA<3Df;Ujl&?8 z6eEZ5WZ(&}Sy@yF;<d<AA>x%PJ#wO_syrkR+fElnCdv9p&H}G$8lpIhv&9^;x-e`$ z);<1Ee>ce17E0m=z-jzU+edDA#crECWidw4#OrP3%Eeo9F5leAis0Oo7vo#6G+9<b zZbCGS+#eL>$1<8&e|6HO+|;Jf#NmWIO9>}gB{ZCw<D2%AH=;nuO_a~JKBMnuK{2X` z#$8qVf*Z$im489H!ccQIYoCyjyg-_?9a7&mZ_N754U<b>HGV|C{U~iL90LDaAK;M( zBKUx-_QG3cfvFqNAxGt#w`!jLP9L&bA;SpEQ@KSxUud3&?V6K;t=c=ijICOUdxVc> z94FsCK1?r`YfeE@sU=`$9o1)7szt&#g><6wcb4yjLc<XU;-YIutDCP(5WDLM+kGpf zSKSIm|MQ|p#LWmzJ>KE`gBgJtbvsi^Ks3V@rx#R+LeAxY8BwV<%@#f@Llu$p?MHsB zs@FQUy%`=&`^&~QQ2}Q)<UALZfwiKkSE`U~WlNhqy1ExP1mcS)sc2>q%pXf-q~MBF zy^waw?oCRbcuImuX~nDZuB*a9!-C`+q9MazEc2$nkI5VTM+>=Vd{J0A8-}T#!2^%I zM+;u~Z*Gd-ScYlY#z~bh=@TZ#6)+@qY*h5DT3J}$3G@|dp1>`1^jA5Wt1iZuE7q^i zXzSZ66yBNMouGXIX_wz)<%h^Jr-ZCqP$pzPnby?-+X2qm18IrIi_@%Hvm(%ULjV>; zP1Aagz+8NSijn5>afv;@i45F=L2Aq_#aWE6QsVA|eIt1gM@q;%^&4UkSa~!#kuWS` zoRWmV?jSps<u(W!PaWLbjp*c}kt0A>MOMuiR4^#&zt0n+qhGoW*DlWO^9h7}sXY8& zB{CyMx@7ZCi1mgccJdXVr<_3e3VkQJ_KdtBZz*GV)OvApXI6x%3-&eBJ{hxU8M9!S zQnjTlH&995o%O^aMHzC09@mzopm@q`-jF*;CYC9EhAH~nOx^xy0o27!fhoQd;%-DH z4jD(Xkh*)z)Z-qCDY>R6l&)a0)yh^Gw7Bk>lD$9eazBrYwl2B<FUGzBMwDRNc4p4l zwr!hde8#rU*tTukwr$(CZQC<{?t3>c_uYSg@+;|1RVCeB-AV84U3;&!g!M)qPcQ(e zPMKUc?Qa<^7?&&QSs2$fRg%x=#2^!n7Y+}<?<S}inUIbqy2Q9v)y(*y-AW_Yulx;H ztG+}K>k_UopQVNjt+_@s(_v;euNkcIz+8I(w!5WIA*HfS#&?m@YX=QTgv`(sv#r}# zLZ~hZS4d5B`A3arazhYm7b23iQ>ANBma&j8HB7KhX$-50b|F6t2cKxDGe1A>=*IMo z+#|!{Zf|e-6g&gYx>Fu?Cf}@)4YWlcw<q5$>v4<Q!joCdkJ9vk($&@{*L0Vp>y;<e zS<E*xw#6PR6?LSDljJ_F@?}2!X>eU2pCbDDdQ4a1gP!LaU4WjPR)%*x4fHn}<d_cr z^wtNcGC=Ad!in!*u^jF-E{#WmuJqs3dmtS>!@gY|r=eD{!(Jz|oo&HBcQL&D4in@x z^Nv~TaESN4C$Oq!Uc)<jlF$D{u%i3v9yUD#UtI5ep>Onka+_^q+Wnb&HoD!^^J-@N zpw@w68y%Wx>`owxi!R*Vr|=ayMlx-o3G`;<%$DpgmVYtNzdvR6APwYu;>_~<%ty{d zx?#SM>A$4-p!{`>4no(S@QK516CC{Tt;Ug7mm{PPEkbgkaOcJm6Et0TBREvm0wHu) zv^&MTk=Tb*r$M@o@JoLbq9y(L?(ZL6v=d{8Gh9L$boow7=T2mITv!em&rKvdai%M_ z%W8$Ks5z&<mCLWl8|EXs+%V5YyS!`YM-N-Duy$8?{?ihwC`3h!A*IaRJq#QKMbray ze^yNWN7tauo#I&nWAQF-D1%&d66~W2b|olUgdtyZEV`e8xrMIw$Ei2u`f&Y&3l&XW z0t8z`TU{a!xrT((!fR!5x5>7++hhd}#yT*C{YH^BdzeW-W>wf9h#!XMZ3x#PMsKbm zp5r&9`EgwJ*M@}iV}`L>P83-~<A-4Qk)>;~_$=dM74SfH-Lo%2*4cL0kynQ<{mx3S zjQme~xQ!ZOhP{@Pf{N{4i>M}@`vifBynVn(Ur9R>kv|&@>12v`F`9HXOiQ{)>IfMt zvV548ei^8qB?7xGrM+8VcBKU|QB)9}XhXHJ!Ay&VK|#EAfOzu4=){ZWhvd+y&Y;cR zIPwzR82fdZ@astSv%S>xm;=+)qsJ6M(}5JMV&M0mWf9N#qmI-Bg8iC1f{xL(b4Hh* zQuW=`#OzA->jbWh8xotL)PD|^6f`sBD$`}kgHlV2&72Gg8z%SS5ZQKsS&tE1i}AM{ z85OaTRomcP3@|IwnCWL6h}s`%pxF+wG@{gFvE*=duHE_8qSUKS3@fRVN9e*(KsZ|e z{uU+NEApm5@TED5uWk&&^?1U-^LWyP<DK$EZeN4#B_)DmFgC-?BO$3RCLu7JjtlrR z`H@5%Hy977-Tv4_tZ!BkO93t#8F2tK^iFRBswmA}#oFxR*(1pVJkcTO6Av4pgdQU! zN0jd(WQ3>f&vqik0i`pjQp^$jBuU;7XT$Mcv%m+s%_+f%T8T}~3rQ#S%${yjf18r4 zUNm`POH6YeF##^g@LM6222lM4fKLMG%G%ygBhgQE#H#~v3cXG(fvz0a|N2H1l3Q(t z;f40ss@d466UX)ewT>46B+%70#)>DXNdo^i+i&cZ&%ek9vMSPpaFM5`FLGEs-hxi* ztrO~keb*VP9#;o|_Me`t)NC}bkZD?3yEF91p{G~Bn_{~sfHi(y;YqBP!@yL;p<p19 z#lZF??~t21aU|tO$0zI@@mVpm(VBIMG=0|tK2RwDnG{1OGuhT-$dCVCq18Vx<+?oT z_GN5UH3WV9GTVD26D8$n&z81#y32|`Ix3hhS17R>l)h*1AnIkO3|Go_c;L$ox@gLY z&1kDz+t<WZ<c2gJyTl#l1#7FaYF2N&qyTq8-lr);x0Vas&I6gZ;Sq0_<VeKB{kH2d zZ@wjZG?teo-|g;Z8B90iMMm~!!I{m*%gloi=^PU3%>4UNJ_fVYxO*G{6^PsozIJ-2 zPJq|hEy>T~7`Cc&v}j}TjOiMIdA0gN^I2aZhWoCy&xe1&tzTq2%ncBzJv<w84`}0- zSu6m#I$6D9rDXBtN2qpL1lI$9k@NEKNP&6PXIT_94Nt2vy<b?hS&+>*OdzYJQn(Yc zs&bY4b%ne^@m?05v20mbl>}`Dwux)B?HbL{CHSPIA_M6rp~Zvvh@0Q7_A~T`tRi=O zG!81!A$u<~5AiTBH792h^31*{uL8z-mscVD83db$PejB?>TXzF_*fFHE>M>(XZo;F z6D2ecRaa{4vtgf1lD=3ArY(**^Fnk(ooa770c~B_T;lpSuXVI-X2?hdKR%e=n`zr= z-H(af9*)MpP4iL&KD%FJLzijaeH4D2#}fr=X-8gKeVM*^mh@=ss2T}Lm49pjVKr_` z_T!BW?`)53E$-i3gXIk7OGaS(Au?Vy`5SD!ZUMFWUD4FcpU6j#ouXiNj<Eyc1n)!( zWvR)h6#f*4gTeJ4R&DYRA`07C%g3y}<(CJZG^hzQp$l+Ui0X<kny@UjEG*tdEx6T{ zK2H3eMC4}>N+GVM5acLsQw?LpG}OZtMx;u?A0pe>wZ-*%k7473`9`3W?8Ua;RoUS~ zfHpL*sN=KLUGXNsM)%IV{aQ~?4*EU?UmMJAX1f&`4SkkLOW7qWF}O|<-OaosUz(2W zC7cu6!*?mc<OB~?j7@DnVL#6zJkNq{Yq>09;KX?~OvM8ZCwn-`Q~mU2;?o1&#9aoI z<r&OZY!T&WYUU*xLKWN~3~Tx`Ksef*P(LE%G9D9e@Lo?5tx0ikH%A8JT{}<unW)h_ z+I7WVvLeO*D=n2io!e8w0P@oMfzv(Vb8CC_WxHr*2LYWg>V|xeD5QxQvP{zr(=y0g z_~0O5NR6_AD6ruh?7!qdqs{|bZ~y=@c>XmT{O@=!{Qr~<{vS??|IPvrszYdM{?J_; zqi*TD#GoY+2jn0{2El{VR}h3FA|{~!fhM2`O_KcUBNl{_fl;@zw8mQ7WQHb{T)--^ zIJZ<FZ;7ACx<+GaX|B?)q0xS=+}?J`b=<*b4QeDZTCJn;cgpj5%YK^Yc;lPrd4rAn z>8{_n2llYZmDUBF3b{hDR$Mq5%0e|$Op1lJVvy6T%s2|PidJdoeq(MV(eR@oV-(Uz zbyP;B#HBDy3bM+MpO>|~C2gEVQeCk_e6akrR;jmf!ZQ+TSr;qb31qpwClV_~vwTMc zg-daxK#weZYobykr6WizIZUH<<H+y*mJ_A=c+5Q2p?ybWqbf&b5Qp-qWM#bHQ}Rvm zLdEvCFrRr%e7X|@1UdVOUn05zq8?+x9t>oVQbY;5lFbST4ST_k7437&j@ibz%)4TT zT<>z}iyO*z&Ysl9lL(5n@{JT_*D44O`v7TIVD?kF%kM!A)&6EmmvX44+6V}bbg1p9 zW(t>fsJ2^Jl<nL-F12E32G?dk=eC|<T37UIJ-e7u_mqz0(f5>&>`?;J;8YKvA8ird zk%N#hQ6=u8JzJ;6VC0Tr5ceDHs*U2E;8hJGNUs5q>fvb07Y4MAfM+U~J`lEjF%Z5h zKel?Et6{K|2+9`-v<*KvM%R#0GPQ0QN*D1#2DB*s@~~nIzJp4c+XuLMFjCDMgb!vu z&mbI|AmPoS0|XR2rQ3Q+uP9f(=>w>XM5Cim!uWd0DURuMKFxQ;cseH62r!Sp?5?t% zWtTW3(rBs|N0jc|JvOBeRID3Il<xfwjEL-&Uu`!KA5~D?LzJG;qtB@yzkBg0Ux<K> zo!J}6{9@Xzik+LA_1Mqg6fK?}g#>pE!Nr}kx6w`te=O;_!0uPrSLSS3Z*N$yXDk*F z3eAS7rrIV?|85N(`X>6CzfUE&nX^L=UTm4?dXrKgA|$9-1s}2yxpdN^g=2ir#1+q$ z%?#c}aVQjYXG-z@nxjU9)81?d*&Hu6cmr_9C-b>-z{OR~G#2>9`bju6Se^l*6ec<@ zbdx)nXSzUTulBaKMAnLHBO4?9;}!VJpRI~3Uc{vgZv5bax(-;KpZpsEo>&N5%u>)P z&pZ6X)eNq3713Gb8|Www_<bBqquXF7kFV^&@;E9S+@rkcxf!D&jfU|;x?n%`@M>qN zz9ZBRr$~NR=WH14_l|5&b6SeJz%D=C`1r}=^LzdQ^Lmq!Jom-r<MrkN)SQlkk9xg6 zOeX)X9k3W|rR*r7T~<EFg2Yhk(#7R1%q=H<zwAnLx)B;ppe+-H<y&UL)w3{Ho-Si* zhWuRHh%D_6%##ZGWI<fGi*ld<V0QA-Cch+eVxQ%E9&f(yOm1C{uPnP+gF_6-!W<^^ zdF4=yBSBUO))J<mIuJqi=$xKOJtwndxhZojS-mTv_qUl&wD*hz<TQ<Gq^TGzR!PV+ z4HI#lvO#lv5R;j!vJ*Z3C}Z?;%z6^WX8MP}*yhF%I7>T`-1QE8-vu%5DgF?)o<-Qh z%jW@0wllnL)ZiJMQUhpkP`(J<?b(3D__AO)%6=AsGHB<nXKm8BL|iiA;Tdv)-bPxH zr&8Ke6!T@J>DqFUskPX=G*m0Qu=`tLMxr=m^>N|pXIxE1b)R9C)o8i>;F7bP+fu>f zWZvM09!U2pN%&kq_XX~n{4P70V5ciPHbfwY3&BBhfu;@W_EEUos3KjTaOfV}ke_;m zcWQ0%()Eg%FNbL`*5tT0js<Fd`83`I3lO#C&7l{h02M+Ng_wICarU2T7b_bZbvuGN z7a!DJbR&?9a0zV+y?dWjuAom}Z4Rup4naZ0j|>v?Wjh@wp(x<<4Ey33R$*PsyV$|p z943Z4g$XTlYK>yY-v*D+FK$k=r)>npy=Lo_TSW4R)zab?86JAJ>;<hxWKWWuZ3~Ay zfNF3sXg%=_OQAXSKgBw)OE%4Xdsk4wpqrUk%50YE^#hx@c33%fPKrv(%4Vtod`mm? zHy9w<3pZph382w^#w-(o#Vj8bQ?onvH?A<=B1$i)9%}w{2)&3^S-zt1sM=f?P}la) z?|xnMtDEPrK^r2BKlcyZOd>oAz+HP%&}}hmsh&n7mD(}o<b*kBH9XwN-7Vo-IEF>4 zpVr!2x-tFWh}Vf3-lW=e@S|1F+ofa3W);(<#&gFK`1-qm)|8Rgi?$OE`6b@3^9$n* z3pY<@F`)BSgS1;v6@L9Cvv=fX20qiRYm0>+@?;=+$IMxvx!t%2>*;Bx!76+7RQnGn zt){?|O5H2w2as3k?)B*83)sZ+P4o+y9(ncL&Gbt|kauq}c`bf?)*v)Yc7OK|p2`7! z3n>z7V;2gmRmcx_%*guh%JBT8#z;8tsQvm_IrpRCL+h4iP$A|A#Fr$n1cY^YM`wpB zvFs8xIa3XJq!7rah?B_F5aQG4Hj4{t7Li{#xmRJ><wdWz$&1Vf8Xr%zEVE${JJqy2 zHd__NMKmn*Ti#a|@Vt*6B7b9@=9h{2@GHgh&EtDtLm^ovEM`{^E^QxLYQn5YY90X7 z?SiYV90byo*%PRLE;$D7#wC>KX1jjXq?(BZ={S+vmGBk$CHa;*W>)|P_~TNn01tt4 zKm;_sj3hb_WAKk!cc&{w6np>+R^LGxIK@%X!<2kjZDVPprPOdyQ4>tk49@{?bLw;g zwOugvDP~5XJ!V(LF@kb&@<>q4f(ly7g~G1RpOQcw(kd`EbJn&%3f6R^`unbNDPAwr zOpAc~Rtf{mF5>I+pn96}(S7japNf|ce_6cssthdF!2T^y2(YFgdsDvNA2<c(2dGzh z@Ab|z<_F+cNiWk48q61@_xw)w4INBYFdDN9g7(~wA)?d@k#{SF*E<GALx1GSm63z$ zx>u-0nNg5YEJo)CMP9Oz{oR%H@9I>W`b&&7sojvQ_?h--UrhrA3P(wB#SCwI`y*l_ z>9*EImQXcDYpba=<co+0je1jL2+P$UGSdln5mfq7N8u*yN!I=%^BX4EnX8tJBOf+I zQ#fIb6X*-66+Wgy!Hk7rtw^gu)_9S&XXuw-ylkO~Gw8R0pIbiPB6j8@lG=9_7UrJZ zcKa5*L0v#Pix#a-+%R23GOx%ymLL(Niw~^`)fHlfN+&(HHsIt-H;5gI{=+Z8?io{T zFP!n#{m#rUv>r14WG4`t9%Y`tx-jPT?+z8}C+jAQc49cK`N=i-21N0#sg(ViJWb$I zk1qG`@xAbetK#fcUcq;H*?PGwdW2L*s1AZxr96iy=D1o#>nHiuT{KHpAX(NmHDW=x zgYism1WEb)@M2bo9}%PedYZL~9y^CM&<p3aaImryFysf22$YkJ!f6pQdIE}dr~Nsb zsIjJRSYJj4uVBEW036F<j({c<l{#P3Hvmb9MlEcsQ|~lmMs8n6?G!*16&<k|Fy0!8 z5TbEPNvFUd(^f2M;vw3BdJ+XQ`ODl8mBg}fahUD|iuWRQw3$?OhtY)<)ag5t02P<2 zb{`mdon~2)7JEa1NVfDGdr#QUMOcJWzqh<S+Uz$$V9mbARCQojYV_xtRCLs=N$`-l zZFt=Ix-ag5tv=zI3s;&W@c_esl7eEjj8c45!UsEU>uMdVajJ@ggrZuQF@jD2o7ALU zs_mE9ew~=^#KFFMhpoBY?LlP`(8rlyz_9#D<=j!UtoG40+?}+2!pIq?IA?@jrCb9# zs&E7shni5d?@Uz7k^-$KVY0r8#kpixyV`ScK!)D@Z}x^^s%p-Q&kjI3??k2g0Qf0R z)Akg0{gx(Kd2>~3vP^hP`H-|K8@0L>i4<VZbp2PVO9)rdLHGPtN4au+UT$b4fEYN~ zF6x<h|9fwW(=L1xE#!g%Ar0{{_JRT||AgpN5@9=vZlk2=^!;wDBxK*hkEBr<IrTBJ zf(F~3B0E}9UJ7rMB)+)1*ttQx{`i4sq_RNMjL5OBIfkBodVL@Zt=1>aVRm*riceyL z2wyvN#rHb|RY9f2+Mfa#Sl7a%eTw{V#<&<YGkUrB2Rln>&1iuoiW%(jaOsipjpCn` zoS)t+NW`nxDB%2!4LSJ)n4r6iD_-c6UWpH!eKm))m&i==2g?FU&NXu?-A6v~AT-^W zrXewsj~wPO?TI*mII+{C-?OlZ>jI#QS>$Ax<~Dw#Wn+u>R5@UWRY!2nXhq}RU;=#A z+Lw*tGKV%oi|ozV5O9MBt(qttLr2E&FIA$ldvKfLM>Xfx58(cr%vdjlsoE~MGa%<i z&I{#5JG7H0IAh7JwV~_;dq>){iGsuedoPM~PP)ym$+(tOvI!(eag|@ZF)rCiYus2g zMx<il2N3WVw<EsilcU8UterfY`EyOY(0>f2(BQ4FsjgmDffbZQG$$iW_=$mBORYjQ zx-Ub|b6akNW~n^NPdTaG1$qqDcMlyfm}k*Xp~|dkc(4JN8F0;&=Zk8pIeX`JVpW7S z!F%E*kML<wnA8(<&clk8PaZ9}A^DgV!yj^8E=A6YEo(TZuJeOgG1Ek5p*wBy2%&?W zrD&}&)NH+6CPpGH2dXOH5u;G{R_aF57R&JYsO>;ubX~_V*Rgpk@j|Z+IHkk&N8a#; zw0<sf)!-AVq>d}=MdvDNBEFDeiJ^p#1L6pV*ak9VHD5x%o-M5&%RgBSGNc^I#v5rv zq+8)r!nsJ1SL3THn(XyL&1K5KbLe5!`74=s+!cSw6;qk}2G4GF{nWW^{3OWqZP#`r zN5=<jGSe27S6w=HkN!ZWXRIp2wk2;??j(f`R3*wz@RgmJMc${SZZ@^#k}|E+<LxaK z=$i&(1n?G-+#j-z769SRGE0wSb3ls9x{y`-^2D1)dsLSoBfmh5`nTj#bk$3cSJSZx z3^HYQAFIW%i0IXsNHO)F{Q4Q!s6rG@`{h3_PNUR>TMm+~RoMOUfzs-%kl`oE6~Oqx zS>_XO*OPa!^%iOJ&1+;ih2=A*D&)9P{YsW1O0!H6ZtZf*Ob&}CCJvH4i(1Gr8pf2q z+UlLkqSm?oVYaGVW@C0~btw`$_HYMw?TT*A(fuq(*wTh`$V&;g81fP-w2E$d^ur*f zrV$P4{(B{AqA!21WzbqfsggaRQHfu<ujKR@)zmj130n5HQ&|t^%H9mR&&#gThUQp} zh|T7#OzU{%kn&CY3wnfByDSG-fh-l8`tEQ1T2Y+llymksnpV5|y5_WxQ;t|oCden~ zoBgCdl!}qbGe|CSqsLcZYX&Q(qZ0$CfCSX7ee)jT7K?Y+P&V>p{pT%IM`5JR=*t|D z-#IIB{zB7x4ox^+RZBfg4w+U-1+(bQmq(xnPl+V1v1R|NY>?#vNf(vfcOximFbt@g z+XKHuzaZJHd$?%H<7l%|E1X`q*JCA-{!TNMtX7?;;^x^P_{X_JtfLw?Q2AHW12aUE z78<yQy*VbTK}pgV_b7wx1yRi8IRmJMltPo^Bo%Frr+ubt7ybF8{*5}6Z<uAGr4k~L zPCzm=@Y?pDpV)5AId!!jp!x!(kIr&0oHVDse8MVkV5QCJ4I}t6-%#XlQ)HSiM|9YF zWSeEV8Y%|K*95gS!?>RPMzLg90GxyReI+&1Q>{x5b<{AYu^KjjBZi?ZzygIK1c0pC zyWUb;&+ZA04XOb$IY?QqhX*VXX}Y~Cmd|mB%pdy}2O8esqGL&8So^?JWr0`~nxdHY zx(SSCa^89-+oOnq)Wm_*$k8uBB&k@-?5gY{_8z}s5b{L&M~7eyLF{UFft9@!sf}9g zwJ5{+?V3x4=%BiScz$&!Ne*<z3&*Fn0?Sv%3^w}~H6y$0xQI-H#|Y`k>sP2as2!2; zcg8VT4nFD#+vmGNwR8X-l~wkKNWHngFCc3br58tvg%18##VN59pHvOS`?!B>XGKIg zt-KkZuV+%D+>OJqNR0~iw-Wc_Ld7|++Tz7FrgPGwxMKDggHlghlKEl=K2;o2H|i$` z#~52qDH&2OZo2iAId?lpH@<~vaGdE=-(4r9hjGM@yb$c?Y~e`kyCaz9Y`0^8u1{P0 zDQ>c|xCXCgY>mQ}9n#}5>?@yrT94d&BIFA?@J}c4j&!?5IYifdn$b5~iCX0#fZ|_p zLO|HVvk*xphB%C}Uf`HyKAxz4Kn}%@g-qJigV#<=6w@kPVan~-#)}reek2~U`M&8W zuXFEQDMd>?e5K8-ykp0LOFc%Zby&ym6{7&YkA39g&S#|xH>qE>HtR3`zTJ!)wZ#x= zjlPJJ7eanCrF0lZZ4bRNBreN|;k9Iq;ULu%hYK$EuwNWz=x-CuaFiZ5X*u}krg-Hm ze(c}0F+*1;k4@RS2xjb(nwDb)vqeeoN}tqj;XYtm!#xZ%gMC+9!;+)Q^h`3^|Ha-C zN@SBTd}Z$lOx*GYXC(2%;<TOj?H7qxe9}PK-Af1A#K|xw&^+PZ=Z0-3->q1Z!S=@q zlooCL8rGi~9R8gfKjkaJ`EGqmsW`M-8A(~Z-aIEuxi!>!y)K&Lhq2eRIaNygxY7I6 zNtDFfeUE@SZf_I<%AZS+D_Au3ci8=g7>5&g9d>=4T&+WD3~X0Rfpx)xTCzERJF`RX zSUvZfypdt$ics`N^3$0Ik|yKiZav&z`IEZk<?DFG%P(zfo;EohR67j_ta8G=v{KVf zFL5sXlB^=?S?YA<x(6uOqI3VaJLV+&IbH&_-WoPl!h@XyGG<MfJvu9*L^ruJFOjxL z|MgcP^Z2Gnf^L;w{5k)<;dHRX@UDL$>z9Ckf9!=Jsc4HES-ig{&)5Nae8!vyyBFlu zZk2naZ@5hF#9W;M^6W&l4s3?sJ3Biz!@1}P(T7QM7gg?>XO(~OE+Z`2@eZM2%xh$b zq|J6nZk$N&d4JHC58Ccv(O0X{SzK>@H2NoO7?Mo-C)p^cm!Y$!M_Y#j5U;@12l=`I z4{k#>x-Z*}SEi_YV<yM(Z5j)wUi3B50oN1|mA7%OKlf`b%}{==+wB@*=`F18mVe-s z>NS6tTBou6<j$sbzpL=@^mR1dq=$kdUFlTI`Nwn8k)C$It7am@({#^ggLLgFZLfra zYaRR1DacL1YPL%a4u`IjPEfMOCTsb7SG>`4U&7{d26J-h04H=cW4Eq`$R<ZHzJ_!g zQpfjed1L!zP<$;YlFabLQ?&j20upol_xL1oH!kBqlVPDT?0vd{s~R`#y-fcvxC)6^ z(p8T@ZcI2K4~(L76YaV8T|V8?S1B1@sd%Zvv{j+^ZS7-Ck0M$@=S5Qx4AGqnJ@>~< zw^xRg(-QlGezLQ~PifAa1rL`J?bJeK6EM(orq`qg0+;7KATmegZMB@tAO%M?5H;s} z6{9R#WlM%qR#^RLWCLM1=13oF&W<a!R4@gW`GPM}HmNMfp7b<=bD!$aL{6`-n?H~^ z*ugm^J*O>b8CUUQ{=sBqow(|^gQ`iu&4hhc7W+xXSA0ef<t@ZbwVBt+JD^kRk09Aj zPOFb&Q?$X_i>rqVJegV;ZjQ#udCLw?rEZqSXj;_gA(U=Ba!S_tX{B@|XLFrG^$$2g zES<q7O<NMoqR$AKxz7lTk6w99kAQitZP_MSUGXMeUEwCaxcHnBc*L9<aEO`t!6B$; zf<nh<Z16O5{X)m52zi5U2`9pD^t0iQn?jp!xOw-FokDc8&j_80-L>}w=*#Z=K}vPH zi599PSjwY8N@2Q*da8x!$`t?TD(R^vqAQaGDTV%D-6Mp4ZoL#y==%^|T!smvAlCu< zX!QS@RBc38rU_CC*Im^6=?*#g&Ws0W(>mnNAZpWj#?Hv+h6g4=(4e&mnFP*==PC*C z)J-f3m<KFDRwAj>HSnLv=SB)7Luk?Ns1i67&QJwtQ#6R3Q07hws6c5EH3;K7CeD-x zHbH7pJz(aZ2Q)!gqP1zCfCBC{3a~+5!ncW;6wgcwG=qCa&d}y+fOM?~Xp=p-<yNDt z(KxirR?pxFxQFlp7bE#P?s63|0;=KyDmMa@i})x}^^_s~U4*K^1Xh&*QB4G@C<Feh z1XW`Otl9`v!3n6`2~f`O)2Qg9MA1`*_}3NDM~SGX4CU`4M9mq9DhyCXAy9=lpmHL> z_|LR7fN~{3xwMZGU5^?3UmBFZN{}^W!2f&}DWIw&P=y<yvOj=%DL}crj}l4G9e7O{ zh$;(E#TxMcS_36ulBkaoO-~uZ-$lrpGen<7{2q16o-*XWN)R>NKow?y%8>x&%05bD zJ!LWgOY(rqg#hK^K8FbZzVu$8rQ(T#-R~dp8yI*G7w}>24>319_rIn;{=dL*|C9ds z-;~^u%IDTU)S}-~&h75)(8xncqG%01f7-cGZvy>Jn%aB%cukx&w#FQsSEN%jY1-?5 z-+um9^zaOXBmHS>aQU&K#JwpgDKS6CKiUgjO36!37MFeM+7)Z=XzOuSYq$Lr&+*sQ z=2pk&A<Rn+;B_#(a1{(z>~X(rNYF0)(>?$m?A<Or9_)P}k%v>luBjDwf26*L>??hr z>|b(56X;<Kap-(#&VKZMh@b7DiNB1B=tCINjEb!ak-d5)Oc{FYlQu!Re!JAsU(|S6 zP<yUHXz1F|1b)eWE*v2$#4lh}#pZ|!3n^~mkxMk2A+Y8k<?@@P1T_lF5rmbrTp4AG z60>tDC^X6WhoNg?L}wMYGftZel{kp3Ps~Fp^VQBN^3N(^X#pT4lV{cFk9Dg$rRhn) zIx^Ps0_3(uIguJ}g9R`R=Z&hHWyF&LN>t|92iIaxxOS*-i)l&o6KPhb#pD?k%XVq% zG!bP)ps55v3*}0a)ROEXMONrnkkP+g(RUx?N>NB0T)0Bd8*K$MM^1m_=;#ZhOo9TW z?;Olo6zh>E)s!}=<*5GQxTr5_a;cy%j+L2@8(f#0fpm%}$r%}|v0N3%(kzxF6y>^h zO`ra;I`|l1Ukx`}p$!VdT3FCqV%`vcR&gA!Y!Iv-Y~24yVb<4sW17Cs2nwLDHkl&I zn*M}xQ)6*q#emyY!bq=C8$#tK*T)0(bCDY2ut>b+oEmrWhqJb0@@<J|w&4ddfYwWo zXnsBBX~Eyeu}FlEAbX2HRSlaW%AUYZm`PjD#F>as9W!$JsR2)njKv5s4t|q|c+0{N zM`)wTmL#)#RdvHd>C2_vNS?6ScA?I;AuJMOunMJ^o=qNmk_(;-b+IGA#FPf+O}wR@ zvY#FR#2waxfgJ{YcOC}iFw{yMfi9#_qvg-pku|a=ZRaB*nmix(;aobc@qeagi@6J- z&K>7zu-c?HGj5}DEN{2#Xcs4*W4#+=vtDZmY<}i}D94o6mn~m}p(<80os{1fLWO`T z7E8gw$fr8i#BEa#PtPV%n&e=Mu~S<RS<cnF#oB$ru`^*3VjJy*wG5ClH5$b%Bs9I6 ztH>{=cs@q>9aC^L$2NK27J3r(cv_@RqE~fk`e5}j#}$$IU?dFK5Cgy5^BrQvOzSJe z<CZccIs%E*C)&nihazvVY1kmNq!V<_G|b<ZzakC*t2jc4NeKT6)P)s4^`=kk^@d5{ zioFhO2dKtv8D5RhxG9Jty!R{i2IZwX=P~p!+s+{@fCCpl>sO@!SO6^KWB@Pq143@J z-DUa%+mTnEZLpLq*Hu{**=@q_ThJzU7>9FkO@VUnx=@J;D32&+I_o}LvFhSI=L(xJ zFzJ|pf!5nN4}teUD-=$A2U!zRX6s<uqc)RZX$-$)_y=$3ZtJ;a3wuv(p3J-~RyjCx z;Af(%*gg<2_LfPj-=y3J7d5#eH_~t$w4B!pM=X6#t{R)v<PAn`(aZQc1A1wb-v9*i z6FM0OWonb{oxjV4b4coe7;sBc&Fw_Ac&n=%>S3-^>mi^pd)<$@Lzadt3$BEclG@f| z3;?arnoY+b4!%5L+1Xy|a+X>6tIz$k*?>E{P#@kzX3jPEtJ6K0h_@laykr=o55R78 z$aX~I`2JYMeu&*gr+f?Dp^Z)xd&hqeE_so>CLgfHtrK@sL0KBcR+2Z_MOQkkh!<B< zHzkrZ)h#F|t%@gC23Q)lR#wy`x?3LdYAmdIA^;i|R#wy{E;iY9S60*}f>{_^>f6sd zJ2o@nnw7Ex6_@j%&8|IYjk>*HEay72&P{utfiQ}ridMnC^95i#Z7oF4c;UqQk8v7) zDp|aQc|*O2YZxWZ4t^uRS3fh{k{`G8+RFY?P*7+dur>T9`(^*fiS|~T{^P&$-y*O! ze&s)WrrH0C&-C9prSbk#{#!v#QrOPU+U}olb0uSYWKnp}Z~ztoU>NWSi~cwg-<J7U z;68LB-57*XAYk<1#m$q3nr3$kcH#{CDTL#UUptf~j7qfLPdc}7H*Cr7PR{Uphm_v3 zm-FY#^E{h8p59;g>(?cMV6?0|_|j87fE(*Rpc^XD@8`F_e--u0AH)!b2gvgj_>n>M z2h{ly0jJx9*`)2jQvxUNAe03#0cXR*3kV36AWR{OK<Ee92Y^AqA>fj73%DfQpzqrD zAq9{@$RK2qatpd7-C*y!_CW=pLC_&+lXeKWB;H`|I`&}&ut8WOY>{>dx+LG=?sD&X z_JIY!LEs_ql6nZdB-~)^+V`Oa&_U=Rbdh=pzBJ)(FYdela(wrz^F8`fP@WtU&b>T% zQtka?0>e?Kp;lSud%AA14BLF)U1=!_BYAl%9`{W#KGRdSG_Y8^VP}Q^VA;H}nN$eP ztUTn$G^KmJ;#=mxp=Z8bz__ODuxAp<9zhhz9?*`(5P}Ci(J5z{W14YhFQ}H(b@x__ z@N4Xx?8D;k+HYgtY&Lr9AL1*P=_R1-O>;2eX-7i_=E7@tk14vAm^C)^luh%%B#gIM zjRpZVahUWMOfb)OBQESUht8P?!%42pH891MLr<$oyNkHgEGzdajDgj3<&o`N@`Td1 zc=HB{K~~G<ht7J6&aL0$UNQ*27)lb99iwS+4hAkXh{Y{>*~b!0*tMGT_Jwob!5;S7 zfo2#FJkouUl!9|?ox1gAugZZeUO7TqwIkenWt^$G#rG;T1!f2?u{sH*2~;Z!OkVs` ze2@*1_u0;wQc9!YWcW>Xd#_u!_boofsv{iZzZ*wjMJVTBl)UyqB(>PER9!cF`;#t( zG=1ffRoEVA*lLCzZ9O&II>brrEUohFcKNv~KUEd~q}4P{!xZ49Z8ZO>BL$y~BlBm! z4?{r}Wk(?^YpE4$MY$7;&kK9F)H^#Cwq42)Rx8SjJZ&ED5$LLiz6@gywmh{7Hk-q9 z+RLiXV@e%K!zrN-9-6S9drl~&;?pgvAjiJ-c-OQ`&!G%|vT<Wmwk97iv;R8*Q#or; zu}H2um<J71Z{!}8bXQWAPPb_avT@OJNL{gdS7FN0)gZ24gnhUUTAFm9?wzTuWV8~# zA+L9Jkbm^tO2WZe+Wb>$G~nT{?~9Y}9=9ibq$cYqcFERe2bT7lns88q!ZCJGY{^J( z-t16l%^?Ocm)Mj01H46<#@m;TN|qjYp@$|8&vpIyB-P!2j$3O+SGB1`^Wq2-WwG+6 zK9M^_>+HaP2`u#pS7y=T`jr`+Xgj5g3&=uY*I@R3=1P0_VOQlrIiW<^>Y{rD3j261 ze%ECMh>I>ieGqh+9)r|mEq*(7<TzgLPTHL}Q@8oI8e4(O1@RiGW3?P1dy^&f(OcMm zv^x_FP!h28b24N><mg)QYrhfpmna6y?eflb!xI%fEl{lu{ILAJ0PpWqW9`0#r}2{a zUkY>udHd|KVVp0)9+2M2+Jg=IG%EC+--u_+nxL7(7r=vFdO=Q|qQTYgT+(2U-de)_ zw^S*wR7Ez#v*bovLl^uY$04nltPr`o+zdMXMzz2D1NTT_&_YpRtWldyT*_4|b`f>W zS`?}0ZCX`xcg1VP`xo<+`dMeIb}?&}`=e}Iqz{-U!lhxL^g4sE21H=kLMJhuLTNCq zP&P5GkbY3oS{qfnu(rWLT*A>oOhVN`?E{&ZSE%mH7f8;gEh-P@EixA>H|n3~t@>rr zQVJl>@)gn!6fATSG!ya~b&B<QkVqwJVQVbDX_<xUD2=*6i%Eq^<Ym@ChDN1@YG$rU z>am5&Mx{z>W{yc_)AHtZ3v1Miv4u;9rJ6}&#-&r#N+a^;^$SbXi<yN@hNXsKX6e6a zlow!yNhCnOf&Ss>6PrApr2p7?K<IyU^#9$?|HnF~e-kGuRDp0&R6+ULrcNEbL5$Ni z|KsCpmMTd~49I6jkTXiZG9v~=>?_cCs(*(lK*qE?nT}`!h>W75c?Ps5EIbT?Oo?GO z>zBiS-bIJvd|u^PuKu}TzvX$)n93&h${SC2yy1S;YTRz@>UzN!%?(M0d25YlHCSuc z0bs3nV+3lgd!r2c%;<vU-^}C!=I@-e&n|s)rUkuq`BnYe-~NuiF}(u_hx?!l8})jF z+mWnteZNb*HN6f;Kk|0N?-8PcXLN(Gm36nrydTYYsIQ%IyHf!-ZZi=cjP9M$%K^Gi zO+CEB?H`Qc;nz!qtNHgs43773Fkf5qAr~S!<-wHg<QPBo%wVV2kgm$*7NdColnl=G zR*jCdqh+j&Z&<`*D|q+@<moUR*JCu;>8TLsA7rm^U1z<^+%Ijw&feUKlH#h!5~hMu zg6<DRv9U$5pQoLnMc_Ckww~;XnpC-UItuft0bBWJo$sPb5c0tRuJJ;8QO3+tQbW%Y zG4IY4ZXV5?Get0kBrp2z3GN9+5xf~DYa)mWm=F(X&ZiwyRqp26SL#Vgio*|;u2*+o zo?%JY(sc)}0*u=yKV<l{CqXuzE<!(18^q$L8D~{QS$d<Qrd081hQ;<MwO^H(s?jnY zO^5!9#w=f6geA5z(l4HVFvTvJ_sUXFQ&xH=&YTl7;zY4H5mO|4vV?}MSjqCVEry;A zTVWN%QUWSW2ojEkg?#hAow}vngPJbwzOkJMINffIZYe*iI86L_14qe7V+ThGk;M}f zzh1<Rct9%XS~^Zt6;ZWctqQtfr%V}n_{njC)z?vE@}`{5psPWvf@NDABmzQYRja3Z zZB#40XdZih;JI{KHK~H>C6}|By_v2&LH?buXhtv!6o$4W7%E7JMhN##R2rzj=f$JR zVJ-qn4PsM}h!~?L4|iH)BMt=k`rJk(MY}o7@uNUgbBIS^#jd{Md*@UWgnS5kr3W*} zgn<t6;QSVhovb12nG{luVFBo3t}Ly!a)sg>^cA7NgljRGq{puVzeWWWnxG)HQsj@7 z0?G1dToQeKooKz>6o^WWiu6WW(kIF@?odG>Xa#$5F>qFh_gM!F92i$3Xc(IqPxz}N zc#ACioiLj9gTc0AZl#JY3~a#s(e{KHuMB3Q+lhg*O1pSok|L~$2==*Ns=&76877oH z@S?|G0IOVY1Tpyfq76TQ!3;i-MGZcnmrH>4a58ZWW~OU3hUjhr0<hfkI(@GuJ8?F( z0L5#+vP`HkPcPYCmMlZ8EY8Cp<uQ?u#odi;Vl?D7C6^695WDqm%rUxqSunZ>buqg8 zuMIx{#W1`LZiv5xM)ju|FuaEl#^(EgYRa_x<e40S(#nh*3OM1>B~5+1Cb8Ds@_nzW zR-#Z2EbS#^?kT-;yGPhV`V~v#y^u%DLdi#eGZuo8R{|}N{PNfQ@MShs_}j@Zix|4V zJI7EqaIO5v0vNYBKeyo#9<Vkl0$%|q%K|3v4;YDDLKQMD_FURq6?3cNmEFBd0rxd! zeG7-7by5^ToyE-f6<Tcg0X5pusDLEhC!k^XaH42SM2V)kSm3|e{xpLE!M5_kh2a$Q zR5#VMzW&Y{hsN|^Qzz)q#flIxDFSU$73wN9O}JZhs`0$gs>{}uv+AM-=UB`DVekJ# zO-E%e3>S3(Hm`^)A*{p@`Jwo1lpxera-J&RdTYbgeDKC-x_EY3|Dd={F0~obm*3Bn zfh{}S1~w^e_Od14_Z;<>%7-w99G6<afz?&j6Ka<4-pCwQ#P@hs+A&;T@icL{gboJ+ zhneDPa$is)zOH`g_u$}}_-@OONJ~Mm#mQPQo+eJxsPiYjrb7r>9Ii(Eo`|$AUBbdg z^w>(+e10$?O0v{uZ#JQ2%5n@P;wCpb&68PIU5ydVMWl{N@l916FTZ(??ZTp^rF(vC zkY=kVleCENXj;?i1$4_y&+Hxais_|ia=T~Y8>VBvU|UxY69BYpet;PioHj^k(j2Xq z{W5Ci8(z9kKleUHV2&M|;FvuFTC>CPM@C>rH;wH8Q<THnGdGyt9NTV$Au4P}Q!y%E zJjaapDHv0A31ni`7S}$NXJWwKMly$SfIZmN;j=<FH2|>0rbbvkf$(?st2`7#A|4sY z@s9b3u2%%=6$GLXc`%5;08HlYxO}qeGW^|f%?<ETI`IB)S#yxmEA}~Ji&$@4SP5)6 zc(QpcaK!_7eCPU>aJJ`IG>07>ac7|QdexzJC{>ZEjT3KW*lAQYt1;cyUV;JkfQTW8 z+^X0GBMM4k<N7<}T`IMgrItPwGfgzXzDoSy=wxgMfxa_0`_l;m16nN(X7q9Fz6iS9 zAAw_r5VDhGZ_r4^xD!4y2*DK^zwqHuWsw&%Tbn{@rW~!v<U*FJy^yrsDg?4Yf=cR; z#6t_?73QuX7F}|?g_zmK$e{VFAu5)u@Lg<W?BNS2leJyzr{;{|v2cRC$~;B8DkCW+ z``Zln>)`2bw?-;+ZqG$IPVn&GllGZ}$7eT;Z!}J+yjqgU%ZN_!+O&7Ya}(LrnhaFE zIE1|%mD6*EaFlY9>ES|KkpUESX-<f`Uf{0@QqSOVr21g9Ep1Do1J(5Ryy1+LS&og4 zWC(wc??WFo#Va^tmA*70OcvBh<V)}k)#_#%3gn3^*ImQVoZ>}j;+x<j`w=Q1t2si8 z1Rl-BJZVawo9FtvgH+B<4Am6efviNS)(tr8wyf5)O^OJ+F`gN_WUY=Rlc9^3t=g?t zd4&s>X&Lo-+yZA6Po}3F;GPm^&N=k;vFi(JwMS>hP4&=P@xUM-IK|IB8MO7BTGq+Q zxC5-STKhkBNL)*N(+2NxhwfF{k6X*#a0j0Hn%IhK&K->qXcq6&vU86Oi%Z`t{=n5z zD18_zei)+ND`98llnV6sW?rM|*3Sn{vWh|{<|(+8K(u6NJ`ivVcMlSHQLq5r!ag3& z(;^aR;R}cpQcf6&`4PXz<2BgTZBoZCPIxEYeI=0iElnxcYLL7sw0b+5FWJPKifWi& zig|zsPljSK#+%m0T;!&@uEk|;D`m1C?~PZwFCOtsEuDSbQknQb`7fsrQ-u!^?=qT4 zV2LiquT8k1V!ex(?-`98tEknMG5cSV6PztB6P=wnhPp|O2JO}{b^V}WAVRC_&zgM2 z<03T#A}m!XYUy$^?|2!bnm`$9*Gs%uSERf<7m3d%z)JLt?qLgU7rc&PT=HFwt4y<# z6}}N!QH_be{wuVHoNGHRga80ILityh@89=!vHw$OuV`&<X!YN5y<rrO^bd_(KzAe( z7X+x^D+N3Vig?5f7eGi5Dur-NxI+-P8ta!_AC!EQux|`GJ3z2Ng{gea+>}`(Q~mwt z{cGSb%CMlv6X?UrHIvyf|8Ha)@|SVP{R@GZ))|R8JIlb6u0J{o3Pp}aMplW-tBs7- zcbv}6eWNemuDoIaS6cNo1YFpGzz-k-pwLRQ6^!vHQ;LbDtaRgZ+|1KWs3IEqr~10t z89R|=5XYFaV4Q1bLK<fUCH#;4B`xLafsEXl#kXLH?$-``e`>LGnrw>R*Rzv!{^1i( z+ZJOi|GYlb|6+pscb^#RKYbu22UClG?t3UqD_|L-d-1Zir&}Zi1Z-OW8O*H>6C*Eb zWL_6o2Np2zm9GJZRiHCh6{P3GUoF!#5Ltr)!*RF!fyHKwiWPVMHaCyP{ovwuyP>1+ zdM8Rig}s{ax{mhTI(FZBUca99_I8H_%vV*uVYP$Iqeq6`_XBsk%ak5=JV9uamZv=6 zk)fn^iSi3aPiELn(6O_Ppv1`<-z>vjR%5@PeYFyC%6wV5D^hSOOrL6>VqF{`36|?A z@FOnDC_JH_XRI1)8N$~pTcCPE0VPP(HUdY+Dn}KpvGSC&u(Di%Mw4e-nw*}rSgc5{ z4|l4Ur<1{+EQl@&DU{QCR5Kv#uxeUDe_`-AU9SfwXaJjy_J<cRRX;lWAUjtMMW5#_ zX;hoss#A9^d&)DEnZQQf;};9DdmN8z)K$TJOp16`EQnFI#bKh{;#VH32z$2m&%IvM z!a2wYV`4AgBR#@Eq|KYVDK$RBa<=eOH<B9i3xl&6r%+S8rR7zu4Pa)OH%Y2LbmY<~ zH#FCXS|e$f_cX1ylK7;P2lG1(C{ymVsBR@=?uT~;Ok>Jycrk69HJO_&ESjH3F0w+) zj870ZH?p5|x??&e6#O`8K+iKA&njD(JW5&y>Hl5EC2)2p>y0#3tk1`uZd$5;Oq)~| znIzo3POk;^tOI5rBx4?whpr}~JaOUAV+Y6|vD5JViU&L+`cyrEC(G!5^6DD{CyFbG zj>a@aX$p>RCxBcBAvSVl<2nycG5{b9NCz1$yU1kQp)w-8Mt&0mTH4oN6n;Q(#|*ql zJ|Wnyxn(&~#6q5JDk~9<@Osof9;(g5=;D296>y3Wd{I1g{hdCj4{tZisyBf2>0)v7 zwLE}g=(e!`_D+#U6}sj5!1K_K$8+*!eAbnH@r<b#baw{+MrI21DY8QhcY!X4dpK64 z4;?DXV!}dn;*5)AcgtGTdSFJH7!cnglvSSk<Agi4)~&acz?RTGW`z^$xoJkn?6J@9 zXYG+y?X3_DI{14GZVQN{TttCt&(PBs?gkJ*w#s7NWAHQt_jbj@(Vw>G;t@33(gsB( zzno<ez`>Zhcyfu=S3p04G*4s#p|$?mnu#(E5u;64a2Aw=Gt{K%4x8@V7Z*S%F*9)| z$OUdWao4hSu=lh@4TXx+It@dzv%`9gpnY$fdaEivPe9vb8u%rpr=k!SULa`Hc5&)* zb@d(IZWv<q#qrRh0Xq)?I+EoQb|8M#Nam6c_Rh}Y>;`AORd84-Cv$|}2^i;!``-ed zKw^y*y}tke#6bVsR6_pz^8f(<ZYq)glO=G`rTc%gNK*bkt`M{^HMDXNw6?M`)ORqo z{->!;RMxPcSBC#W=BnK%|1E$YK>Sx7C@TJM4h;>&jJ$oR1{gTRvi8mjYLp)}hT3mQ z)6-9{YXxsWI_`i}#Gy+`S99aHe9q0p0}X1FWz5T1<@d{G<LNA(ulMZjuipR)FC2dC zjGO49Ny4-O0;j#eRe>?b$--W8YSgtYQv&*Oe{<{URgu*;{_56|*Vd?RMC_ni1=nKp zqm5Ox_U~yqd9g)2zZ`m^KC624?9qn9sd)_SM6W&|!9L8>^Xg9?>w5I=Clh#}^eq#3 z5D_>Ssu9CzCD%|{ro0Myjfx{fh6=Pg2ue_g4-DpiD2=L@<rYH<TZ#xgCsq_uwk3{< z#mFPJ!Irj};l#p6Hy#tRcxemJn;sxToYxl-QX6g&%HbCyvJMZ;OY9~6q3<Xn+Zwq& ztdKXLBZ1J+D@};r49Y7-4qQF4x1L~F49FtWP*}WYf;nM=#a})#>;@|cor7A~mnRD> z;z>-56cSPRLMulr(LhUblSs{$n5TTRXDuUN=+K*_OkyXcCeUqQIIS29iIe}FXr-f2 zj>BakqSK8>1EVn|-u}xBe_z;%FPXVzf&!Ml<VJhxMbN%gQ3PIZg%P5JfjTB^sEkbV zpw!Doqa+bC7FlmJgQszysr3*yIGdgn%M1yUC{BdlZc%<eX|~rcS(xdl(_fTpiV@o> z&4dqTj1tRLX>LfUDDjxgZ^Ra;jVN843@vr@tA0h8FXfpDpLb0>Q*DxbwhFwwkeF{4 z7D`9KF}Kt?0luq{ZQMp)%=RRxP@4*mO{zbkhGi*XWKB8sM~WjOOF^>ILNI+!dpm=P z@oA3*BR(ar77PMIg}{J2_}Fxkr*qr|Ol4)yCj#vjG2EZAh@pQkCZeC6aNn?laGzW| zF?N6fW7t+;NbE>#*Ac@SAE(cmv1=Fuf-Fv;*i<;Pfvij{8gfoCKLRy?_D-BOjY70i zn8a-H{?v=n6<3HYT!B$~KOzFescU$dqcLYAfnQ?fL~;ll%r$9{+nqD`o{@GZF9Pr7 z6w%uSYna%=`od;@_RW4ldkWk5RFqLeRZ$`mNe#KsL`3e)NaZ#@AXA%%+0=QX&G^jj zang~qUPv7Ri)X2!tPutcRcfEr84fS0F;l&dQ;DvW<FLTUAfTy6v%IZ9p}4<x!8-xx z(d3#l{}7|tUMw%a%%8T5%}0ci15@;LE8O$Jk&g!^p7;0u+l&66+fdPykZ5j!9fB7! zTgx~=tgAXLz|UJHV5*aZnz$&L3PR@FfD0e+7h(|Y9IiiUv{;@!!owlNfA#_LgGDL9 z!D{R%d4*pn!06^1QDsQ3_ng~xtqeYXAP_jJsgW{>9&^6WGmDUXCw*jM%VPVeSiFqt z{KO%Nr++=j|Ih~cMMZ13ExqM*9w7<Ha1qSVKEm)@F#)d~@De;UAptdlU6W`oPa(?d z*v{G}d(=yGb^UstRVeg6aWjF*PK#sv4sv=aO?S<IU*lK6a+uwxb&L1EN@jnd+=A#@ z&j%_Ebep%f2+ne=mbn96lf-RQUG7Kds}FYhP;scxo2NVZ#L-HAW8)jzL2_47swo^i z2WZk24Ocl^-KxioyV)tNPb(*RL>3-6G0jeCQby@t#HT_x9sNLODe|PDHa4dY)=IMN zPF0~_+jH=F(`*<#^`Oa=f)XfQUpn%mekrta=PJ!7nhNGyBjwAC-umFmn(FqSRz%|w zA<}@cmH!sFA&7PWQ@)kd%+v4T0L1J~Ha(llWf02Wti-k<cfsrJ`Go~Pkj@gtyIc`Z z=+X3l_<HBy*t>39c*nMF+s=+{d&joDlkC{GZFX$iwr%Y=xp~ex-*@hLZ@s6hx~i+I z|5?Aadd@ZG9CM7-ZEffI)vMQtxe?_!59*4Q*7z#|?YcaJwl-_h52SKUo=3)>i{Epj zhhlP0+lRG&UmC4~xXx9>nHpJht2QZeHbYEnW4vZOPChDJ1y;-<zk&X_E9Pk$)uw*e zPt)Q5x6Aamiu3>L`}dt8RNU+o%nh7O{x#y;L^Ij;2_TAo>GvbY|A2#o5GW4)`-2Jz zPbnaP@&w$<#Co-TsyeA>k&;sY9?j$;fO<ai;o)fd>!ouGaTm-eNIZz5Z$g7V`N*h! z)uYLOp4^QcaqpmZ14ZRhc5(|b-`ImNa_M+sA*<j<CiTGJ@Sa@0Rmba^*C5*(`qL1P zUz)DW?W>XR7iZ3CrMa`}>De5$*;2dRlkc9s+LYG(2Zc;~WV}uBc65+}#jD+gpTJ38 z7G-jBDA1}8Y#>cu-9=t3M5NZ~f4E?uA?}%tem?-<|8brE*Ca~*?;er+zdjt3I9YjM zCdA<FyGFkX;sAo3Wmy5)PNNR{IZQ6|&|9@t(}uuH!{(E_23|xIgwG$p6CIl3?Q<pH zoQtnzc;<7qYwV1_{n?rCRv3sv#M)T#a5*`RN67t$XIgN=IO6OJg2D%9K;!npcI5q+ zO-A5IiZIXA`uCTauH%HY(C~Q3Ax&7>U@wv@S0HUj4<`@`%A`6uU<Xz9AFEE%Cc=_Y z@|0B-rFS0}-Nn`|XdgQv$%G%js_PW^e=~9`_;N%cJG|ptgj4H)Q8O;XmQ<-8mY4A5 zQhUZx=w9rM46<9&pOrFYimV-fershO?9x_6jrqzXgE6ZlpT07X+$qg#T>{aUMS1)% zNeAPU5Jw^#XI`S+1Y52%XblTLTnbnOI~7cJk+wwcbV^y`t4|-9K~S<jMyYgS7cX|= z7ysK2zVjd3f>i}z7yjOo-T!r4{@qPQL-4=1MbgIpzd%oxCX74kBHHJ5m+7huAp!^} zFfC!NwQJadn*fd2w=%3isL%{_!lq<>OIlPr3gnWOm6cWFlBEsZEVYk$ZBY^+HWVNx zB5WmX(`ffrTV-?kW^%s%H<O2Db<>zbf7R}I>p!%vU#5Rw^WkKB-|vd=h^eT6*Wx$J z39|4H#jHO&@ciVTis3=^?u(HJ&)u0q_J(eMo}DIflkH{RxcvJAa^}1QZKHqB3+>|X zJ`0e_jvQFd<GvG+%C6i`{+gYxALS0ep}=d!dqIE}c3@~<h^7BhKPy26JTqtb%-{hg z|I(~r^bl{H4HGv1+8tJZsoRbL0ZKHW^fTZs+|l<V=bvB*Ss7Rce&)vC-GUs)Kio37 z;v0$~@#V$uLBTw<kFGz!*?1%Ox+%=Sw|}!i=sI*A-SYI#P>rt3yS~|{Qv0NT>KX=- zf4handF>+jx#RIu<%Z;^@5QkE`!f{+Z^e!ov~Tqe1~8enXH-kJ+?5Pw7O<-9I^a@E z_o&=hS9px^AvH|`iv~22&XfQK6rHtbF3TlreWLB^s_iPPa<yc!@$X@o{A#?6vCQVo zJTOerXqN-Ky4^Bd!>F28uWjL@OoOR;7O$B@uPA#}n*d8AT-o=$fZfHF<XDj5D5$1o zBuuE7@Ac%#DSDMQMro~~q@|eICOC`i?I;wV7I_0nQZZCl5)_F+Hq8t^cikg&0E<IX zSbR|mv^%zv!`&E;bTRWnn=mbG<yFKfpEU)E!dh8IhFaA!i=(IzJz!yIO2$e|Ea6-; znoA0GmX;2mA%F%5iyP=+HIB=olc!Oa!7|im93Fb2)+a+E37N!%oZFRM!@yH0%6bdE zTCPOd*xI#}iN~XVP}Yc0Lj4^NN?4k_dI{}4erqBTEWbx`D*c7((Nu=c26_SxO^^oZ z7g3h|Ik;KpAIGYM&rHb&P2E$;b3QGtpV8!Xa+2pvzzmc8tn{6gEzDK;(k^Zk(fgOC zP{Q0vGEG)>G-Vkh)`U_ucIcd~D*#%uWZPn&%-PAM%5Q;6ZTZJ^HE#Eoh8xDX_`bAs zM&_`VF7h<X<@hQerH<A79x^VoL795hK#)TVzA`H;z7!@FVX&kWz4ClKJnF3=8WkO2 z&raBsij{yWYF2A9GZ-aNeLX96VwA|JG-y|gH2wB!9KqJXJ?kefux=#>y!GXmI;0Gh zckFJ(IuulmTF7Lhic)isAbt+%_T(*NM_p=zR8Q{Vl%fnZ6Qgp3YALtBuJfNz^bS+K zWP*2#xvd9oOBzPZWp0+EaK)x)TuW19%}q-ZSFpvfd?%PNrk-A&N*2m75MC#A$$uP$ zKUK^?AmFl|v1HD(XeH(c@SqxK%$WoD%2eV(Th+=V@Udaf?xB4v_S~NNX6t5JR|#Vd zE=02Lfq#DH?#1w0IrP#Pi(Bfd<D03xL;Y5}#h9^8<@eps*<PRR<*~K&?V<h*@4nr? zruMAMf{%K?)hk#o7K;h^UHVM%Day*Zl{ECqQ2xyES+GZ@lec4nR<omuR<rAZM)1uh z*xK33c&?Gch(ioLVpz{3!!%+M1-+EP6r@Y-Z+*=r)+x8&=TdbKR7c}yrbK-x?US!* z0V7ZyL`70?;B(MOgj7W<dgx(mkwjB|aly7l)=;ySJ)gkpE~Oq5Y3-pJH03&;4)kcj zzNU|V)zS7gfnFHXEq{C<MPZV)o!{e8+v!-M=W}B#Gnl(YMVJFZTZnXbg?}p<rbCdt zO4U#v3Ct82xGt^;YKD_%jB)ecAf^T#s~^x_?}}2fq1S3B;n4FklXql=Q8BG*bS+Zm z0sJMEtPl#44ju!BAkP}|fr55gGH#y0YF+;1ZtbQ}p#{6%dKs=lKRKH=B)`6ItkbaL zo}8J^DqM>_>K}xz@?O$de(aF^qaRgYNdf2jw}gxt?le$RM|y2=s8XTM{Z#*Hz*zB| z#CL3uP>B)+MPzBU!7#H;G-h-m!aD7pI>B&fy_JFE@K{dGFH=IWt585Eh)dn_gvT*O z&%ux-0u^{mqkNh1-gP!OOQg`Y9EsElHX$PBNF@G>UDI4g<S>!;gfk;xTc(6NEg36j zd`Z%ti=UPvFjH#OT*}3kR7vuVhs~T=wK-adqskv`%5)NAoH%|f{=kaLqq}@rhHV8b zmx6S>qby8@nhIfvye*&Vjpa_dS<Eao8ftUrK0qRqMXvPap~AD#*mQ$yZ^nUTdB!`S z+5{G?do9Q&GeSl;!pTSQrzmpTqY*=S;f`lXWfn?$N4c(MOA`;%lmXX=m@Wbadv22N z#-9iQ&$bqg1iB>s`l2?4CKal&WGRtV%la(AZPx)p#1cKa(awb_7zE)!K8PJ?arhp* zYQ7)xoSr|n?Af4v{_Om|{}y6~;=Ltr>HRIq*!Q-}6+S1dutxpfpURBvT9@=;A7e<) z0fCf@BI_yz3eK4EdPXS+?bJ?Cgr*$AX!9exm`?!$(RvHS&bW|_b_JxjYex7``~~Dn zQ0v25C-i%?fO}~+<jZAlSr~}w;Zmp%-iEp{00iN>p>sQ!=CbbafbT0#U$M%$^SgQA zh)EF@D}Go&TWVR6${&eE5-Hq@;_Ybty88FQJnxijV`0lIBaLb@6qjX_(HgdWheTN5 zTm+WPyV2+dPG2v<#Ak@;+YZPogsCD8EbdS0WgpQ3AgJHwZTHT4Q|1K0Xo}y_g}lnO zzEBE1k5K8PuK$D>>$o;ad9Mv4ThMA#Vydk-dBdgP<s4qiX#Q}8@rYaa-aK@PQkc#1 z;8jp32+(=P0w7nmb>AqD+Q1dF$DnR~q6{#$=z{r323Iucr9@xjE92Po9aV4C$K2O< zfq(3HL@xqo+$P?wWJ0D-Bn6-?Y^0K)eis@o2W3XjNg-KKS0L<hu5uZ%HYQe<D4WBM z;ShEYdU=D>ABr5;#fYU)G#t7PPb-Br7T6;P(WHYB4QCOP;fXqG@|TEi;2$)tT7*FJ z5D;s$VQH;sylgPzkZ7o-Z{q2003rkxrx-Y`+B|`!ET8qbKLbr{Soex*>@Z!_E)F6G zlG`C_dxk34&^>TJh%);MNQ-Qg#^|!p##?<L?Rfl@ZG8Gt+Ovr=)vkQ=&cQE#$fZo( ztRPOUaQd;F^Cb_Z6(GZ1ahYd|nyYxx(gxc%J$%4XXpHfbHE)4g&4traS@#N7I<KZp z8_1a?bFqHlF0I^uwJ0b%Ty>@@Dc}CxY$3k*VQo-)L>7$dW)$3bcIWGLph^Lqf8khs z;Ry4_Wj)3hd2hYrbRiN0OQ>)ig<tkJ8Wy=|D|*-g75d|c7OBv{$npTT15#teV8q@a z?^zPkZ&&Vjr1O&<gU?L%xS!&Rn#y&S&2+weDWYh~CIA?>{nR3?Ow5O|4vUUvu_}@r z&q8<KFV23o8wY4T>?_RmvlI-;RB`eN-=Cr2Z8{eiLKCBatV^Zd_r0##G$|XZ!8)9h zktlw@SXfunY>K}MiW|BuF!H+=eO$yREI?+jyJk6H>yT#r7xY<vEFjdqMi?(UDkM++ z4C>L5`Q*e*lrZ9z-^>2_Q;JTW_aMwH5Mh-XFk{vMvAo0QTKrO-Poj~C{^U2ejLVgt zfuZH{!q-Ym)(h5d-OH|B+mnWz0=)KCK_b^B7o{=E9SQ^Hnm6DB?xAzII<95qZH5@D zy4CrZoq5WfcCCNNtUa2(J5l+hLH$?oDryDmn+<^jbD_~H*BKLgABCs@Zd(!~bT|v? zgNi$pz$s>vbOW``DF9YI=yjP$U%(-EN~>4Tb(h+BCrTGbGV60ddMvsHNP57^Nj|^f z=b`hJg82#=yhoW=x-R=0Nmfjjo|1avz9Ly`ijinJ9oL)g3wq-6NMBeGslOm8rpfAd zEJ7A}=hz*InFUkM;OVW<`I7r;O`&#-XL&I7L+Wg`$}-6Otl03;GQUuWaw{~WEX&{Q zlm$QMe3*TThSdzZad?Z^W*HF@or7xj50V=_)i`l0r%2|$5dysd<rZ@HmS*NJuN{(r zMH&Og+EbvxwHjZ;tY6tH#|n>|qCcz)!VP#Dk9P!L{r=vfJYXS=yp;{vn;*xs9S5u_ zf?6UJv=Zn&=|K$?m?v*#b;IbbF?vyGv;q+Ts&ph4OlTe(uBU=rT)SztU&8fHRm4`u zz5cE=>h`qlbf2$+$)+0X%uF>_1CRf#w{NqN=#HZ$ql4)QITa6Nt68f~m8xn)L-@e8 z=dtA2CuzE0j`wiow^5H)>)kNKm|(qCvBEnq%+G6_ifyoxXrdQyin-Q2Mjx-R+~D1F zpoV$sa_DB!c^?*Af8lCUKa`U-(r#U${<!)152g=@K&R{b=0p9X|Mc%`xc?5*YY2)M zI2$P2xi}h`{DX{0nf|jO#Pevk%nxn~t_v>b3Xbjy?&=B-F9zQDp6~qeP>KApq4TjZ zw%3RI5iarpDV{PAKd|#Ymw%u#y%B(mCM*UHE(VT2-O;f?e4IJ3x3^#@2JT-uP%rY4 zInd$k^Ho^6aDXfZj%Fxhr0^qsaNq|}B&@YSJd6Yj@FqCue~fgb5}L4je}nAe@Ato7 z75Be^;s4L7{u};@+B!RW{O1~r;<x3n1yP5(8{RcF)bmg+E2`F#v2~bWirv^{VgCk* z&5I!K<E`3qI73Y|wHqmKg_A2GGkE_X7<+(?RSJSJJl@O9V(I>v@}_Wd@^Xp7{9BtP zhI~%V%fZ>fm}?{)B#X!3(m`C99(@juA%yHWY;zo9<c2$2kHh>RdhS=d;0!{<tN!Xw zh&m+k&}p>%nVcrobsxmAjZ!(MW2okF9En&1_KUYG0Cq@Js0+Xnapo@jqqnj_Pve|Z z@jx_iUQ`<o!eHFCv1s#hZ8N*?H}~I{-8hmgF?*yoz0S8P<;v*lMB9hJ_cO_DGE819 zhVbx3si4@jre{Lq6%ub+I&$yp;XhpPC7pj&YZAVcyEqV0z>{SPW7!Q1HG}fQVC%WJ z5V!aXQHXdRZ%&;uVj$NeqS6p)$|Nx`dg}&j)F5(+N^oz~<yLnycd*xY-Rk<<UA6`} z%_@oZmacvnCqc~k3eqXrQs`&1bdwiWO3&DlzG5;Y$ODjWQ-k(0U96gUMXYHRF$Ynz zcTPdQSdpY^W0$(WiCSy8p`Ssa>y!-GB-#a1@%Pk`|8dlRoR&gWeHQ@QzndKY{!sk; zBEbJV>i=~J)S<j_P0+r6uNskOSR`1dH)Q~7gOuhr18s6~Z8@#y^_Az*=KvNFTIB8X z&f}(LX=ygfsEVM9B8m})Tq0bN5a#8^^GZc%g{mUAYN!mnKkUF5RL;Cu5;iAIwdV*{ ze|7EqTzfrvZD$Ps@;xzdpCO-u*<rp&wwL~)x}qC3`5YUF0I}o5-h6k11m$JCfiA#i zd;Edd(UuSrb7!yar%#Y@<B)v~pNs!=bEe1N9y97I)CW18bFiz7%s)At1C<N)#8LoZ ztV6%s0F)WI$?GjQL^<vCa&r&l4TP|y5Boivjo-t6aeOJ<!Pis4z}(6p>CWlLUaS!G zhmA9kLEQ)*e|J|AzpJkV;ilK9gPV3266RSI>X#9J3`<<ixO>25o%#@mMu6RzJF}nN z?mF8ud>75G7jhRt55l*`$TJC+Jkwl^$34oBd%F71!(B6(%VTC=qWu)+?6_N+q4&nf z?VD3O6JDBqE<JvReK%%bhFt{YPs&|+<WJgN2INobA3#Ms3A2$?0L%1rDuwm3d47YU z2O0GtW>=_*4MR8#|G>GG2HnlPAxAZ8Jngddby^p~Di_G-CSw;qz8CK_gVJ_SrDD-z zHf`{Q0kl8C+2f>O0q|;CldwatO<3vaq=`Rn&!pijJg1NmHv=2<&-YBuy<VFhY&PbW zJKL--U-|v9NTV&vu&n;1Pg&sq00R1YDU%s%Q|OtmcmLzptSoO?IF)N^qoaoUE4R#~ zZqkF(R4*+$DVyo5dN(lH<*}o-NMyhzIc^NrRVD~GL<@weJ5VN{Od5>SBL2tWv9rw! z)P0peVVwIDmgSI&jYMy$F&=Y;Pzm3wes^3wtFV4FjS_9qFg?*(vQv-o#F%jh-KO=o z8_c$SnQQfIu#wuWnzcrhjSQKj@g`;@oNcqAuy9?TE-hD9;ub}8qbb+uc#QB}5|vzp zMQ2_S+v0-MYW8)Tzg;4s{5Xek`j0eIO=7`bxg+jtP#tb4k>2cC*W~a;2jappV>jGw zj*SYk2fT~t7rF=ro+byXC*|U7HLRtA%NfdMKCx)y8?r|KjohA%<ZuHc@n8#ajdD!p za4xDNONenKQ^Z1*c_Ec#i#$S*tojNeG^JPp$2rBkA5=57s)Eq#U}s~}F#`8PCNwJ2 zx+TYvf#|L#&@~E;M11|QU&Z=}>!=-m6=)ry-89b-&S2^RpuaSz`lPG`pA^`ucCuRh zsXmki;d#*BBd))27@z`wQ3;{FLoiT1Gkj9i0+<`}Zzik_G||-U@v6;^7-%@9lF%B) zNlZO#&($Us0ufc6@zn#x-O+YYd?h8qV?`TDfx}CY!ih~o)8b22Metq{LFdsF83Mx1 z5q-f3df-rw8YjE`182f6XlE(IR>M>KL65>?iPJ?Ih>yZv!a2j}!xKbPGwn0=RR(|^ zpjD^ycQ&!0Nl8)~0mgaOG<zzsP3pUo4_k?xDm#(xE$Y%o$c0v%gB&cD+?kZAR1<dU zD>Ax8LCx5&3aNB;v1d9fbN%t0vPcmFr}5^B1BTI^Lqa;$?SPUVZ{i#4Q)mTA5mY3! zs&I1@Gf0vB-S`0PCd#>ZgJ?Fk1Xu)f+HCGzoI;fibmHPrGV5|z_J_1RT2a~}pyfS0 zV7goT6oZpsr$065qe-cZa%a=py;Rcac8mSmr(zZZ15^d=!S(2Te_5pZr;dI%`QbK= zV~#t)m&m(tTA6Du&QRI`!;iBYmW4WrvIuh)tUbu2pRjStE2n0APfA=9BWb1@kxm?7 zW+xU~K{O@E05^ok=pn6xIbms)U{SGUwS`9jxgdxFcect50nw+c0XM?X(pLdco?;X) ztx8)Ip%%(o;+7TxPEruvi5XbE;&2gy(69g%@0hU{w~q4W5^lCQY?ZpQ^7y%;HqN2U zhm96O%K}(rFNn0!gvq3zI`ng_RF86RADP+0)|0%J@d4F!@$4Cr?ra&0Ev?p7HxhC_ zx>@Ps`D4jf0+jJu)Lnf_W6msr*rk&wkMkY|;4)*4frBxyaeK?()7RphD23JlTZ}Cx zq~wHLR0=Gc73$+(jHUvzq^$EgD_zE6J>{o^3NIuIt=*+GA#qrZG)|Ulw2piUt<}CR zIwb(&Irc>zqjOs2d$vLo+C9v4<A!P(+tADXCIA`&<<p9zE<98{$?`*=_y}sXW1Tb9 zU4a>=Xhre<qd+6+vE}AW8?=yAvTZXOZm8{-$`O4|+7f`4;*0vtC~zCibF0*X-xZNv z#k?p~J=yJ4Msp^G)JqslR5CzBi=%P$YSTn(4Uw%qEYl#CeB+=}u4tZWKKe|xQe$`B zN>vkCb>x9casZ)MtBVfDlY5fD3owzEUMGe(NB;X3txtYxF63Bla|gY$=$`Yy$Ciff z{=7aJALAPM^|KQezXQl_AmilzRm=AC<Xhn5>fs`dn?1dv<+Ok+kj5NcV!f8=o8RFQ z&uR)aCyjdY2NOelh=>?Mq0s_2o5|hcw4mrWtWqI8BY4`6#SG%!9!|@lToL@hy-A~B zp6LUwn6=KGpMoEGf*q;8Ad+JbMWKiu3sGy3<R4y88x{px^k?4By}ueCAr!i)ki(je zkRqF+3k=SRa9vdje^wx$O`(+hjMT06IU}-u<)2gN%DL?bc%#*xY~HcNutB;l&2KGx zkz<awsYR;SWWkwYmn|^D-l=LC>SS5&>>qj%yHE9jbQ068Y~H=3UownOE6U#X1Z|{0 z(is9Q7YdgiU^j|iH73PM=<1h+ZiTq^CGBm+J|XGh3d|Rq7dG19P8#Cg-=%I7-0^b< zq_@Nz#a{2|<ujouzV=3AS?24OUjmE_<Rb9>f4a|6jvhor<M)iBQX3#!3*Mk&OO%3n zWO5Us`uu3YcjwTBpUKQ1mB)v%>raPl&*!>wA}kp!LZXF|e5;e#K}_HKjQvd@hwyS| zzWRsDyEb)<yqDM^tteR>3mvWH@&u)teG#^X-<+q-MRuL?R6#Z^p7x&oh8}rh_F4&f zLE32<2oNV__D~ylA6kXq+qd+g(N{mAIscdNdtBMSnB_?zY|dK^U-}Jd*ZSxS6>Be3 znA2@RHW&w{mvtVln0or-YSoJzS+PSR(#jkk&p*VdYU_TZ>HKN81L=9scbM|l={@S9 z0;Vuw>j3QDR=jEU=e3@7%)zV!rrGU58?ifotKVOYT50;iyxE*#(ca~`@OK|1E{Yfv zFlmfQnWK%EL*NM&*C_9-FUq>s<CFO&(zlt$4K}H1NWE}5%pk*IaZ|1UQ~pD?Rb$)V zNRN`ix*a>oJU1F6!@L9z3@Ra{j?1M5BI|XD?s#zYi%HSXe_g_1axjIxMvn1>-A1|z zRC-B>eiC$Lhh+1Pcwh{gg!mq4JS;Q%v`TFJs{KRqOO{u_iPC<iNoc{P(d^(5F3}u+ zfjD$oVYWTmuoI=B7Q#(G=mfFTkdJ%tagW@Ar8ftoIb3`6dOEayU{k|Dyhql(1_zG; z5l?Q_tf03s+UsJ*sUNz%pjR4_HvmWXWq-?1BDkYhTJn!?^k9D~(jB*8YyEcEqW*|B z##BLy8!Xv_OQ763KXiyMMZ6Vc+ZNf}r8P&(y02M#T=Q(~a^0**M+S=j0Zwn(EY!Yj zJ)S8<ve6z?O{?bXf?jiK*ED^8kT>bbWRs*6(RH(ODXP$~4P`<C+Mt<ksdGY;2Xs%S zmzuC6AkfeM=%{HY%s@YWQ-ty`{_`^Z{qg%%_AjQr|9tCg;^ge)V&QD^e{qEV^>_cU zivIg|Le_SM|3xfRJ9R_(9;ELyO|#%ufTUB%4FM8NXae|!YoOb#DUe8Nrwh=9GRo?$ zCmJK0k_)KnAn7RDgJ7U4!h}<56Yc@=zx4j@`RZZF-sk!R+4D)Dx6owe^WnIrzut7a zzTV2%{(O1i#?=TG;u@<}6j~8x-Rrd!0WA@x%`!ZVuN(biD>8_Dug}t?k_#c9RDhvv zVtxN@kb*HZJ+eY%RI*}){7Q`|o)4@;%O^2%f{_7)^#^_flvl!V#K(!^A|_H-h(^_) z)w#|%&{3_=79p9CxF2x=HG+(U;sighNxhFB0h^JQeR|AYZs;EWVi<;5?_r0mgO<H! z#9eg=2&+btb7aSQ@`PL1#a&{(fGw?ESvH_|UyZq-#(?rXnps5_vb{A;T2s+BZUU=u zZi&=lVU9NYs4cc_4LBnT^-nXUoW<*p(WpXxLYaB3c-ySYb=UTV?!mv*y;!`xJ`UMv z)v3tvOfAdgkA;ody}Kw{^ZVc>FyCGcYpl`@tJ+uxjkk$aB|A*Ka+c^+sjY>B8Ng*S zIRS9y>Nk|>XqCNMVCMo9Q=^z5Q6R!<M%<gJ_{GDlO<1FR8?iTS0US5Q0nInx&R^dp zqITphWqVL@vW}V^5O0YZ>qcG0K~>9uObazK@4_7;T;&^3p#v{97TN4vh7T>~K@{ld zeM~T4V)u-`{pqBeumJg4`dyY_O`FXuUCT-`MEG)ldox1x$RSkkXcXAEr7L}DT29f@ z*Lo~v*|X%eMZ9o;^HVv_pU(2+24<dk?m-#jQo+jt4M_P#do%HN#z*OAq23hE(H#UA zkw2SEYzs)|xIdRTOn23r0f8J41?AUF-2pZBQhm$NUA@iFVu(ui*k+W?$|yJ^k55j2 z<{G%9Lv8}gcX+%Rk{e*1R7o0^&0ZHfC9M=Lahjf+E?sfa-u;}u9fNuLf!{`qi>U<e z(EDeCg+1BLW^Z+*BLJU;JG}Iaw3*&oO3RT3i-5%oVXPylnb>caEEWK3b4%V3gon4f zkx@Zl1T_6FZvS3%WShA3VT+}y2k&YQX~`RlSlA>qR0`UGgJ`enZeF_;?I_L#DGFmS zvd^t4j^d=OtSm4AEDO2e{3?gYpqON~epG>9o@2mzdVT>GsblURTQiNbcHzsw5=@0E z)e~<!2@X2hm;}|N8kG|FxAZz|C`@z%f>~!90b{GRAI;?4z(o63&09;nrknn<cGPN@ z?lp)uJ-?6fm5@tLY9+0yZ)K*i?bJbo=<oDVf%ZA%OqFTI!tpdWN8Qdy;_2j1iM5;A zxS3;0n8_K?lArmbuJ>;<2P1O3#_?1>=P6o{Cb3BaG1Ie03NMQn#pEZkGwoHelMkQZ zUDRg@6|rkQ+)|Ww(>9Qkgee{0gw}!o&WmqSKv2yNiUUj?g|gm}ZKTIdTjd07pAlM; z(78OAw=vp6RGOGYr&I)@<wM8Z!>z=YHHzY<>3_{0O5MV?7Y^U?Ok-dV3rmV?pdg=- z1)<>-HswAR4H)Mwi?vuFk5KemFVJvoXU!`eC3;6EM_@81trGVEo~u*y2D#8@XMV}{ zuS<ThYF`M-?GF~S8eG)L?T;)`io*aGZcFhbnPbhCx1Ccc=pAc#AYEXOdDiqG@!M%P zud>4mzLw0gSw8V7V$3SLsP9x7rR*X{Xw$~4cZJ{a^76T0^i<~yL7vn1s`~W_+`*(C zWo3(#rA=u_XS@s(d6`A`96lZ~owHJl&mdKIBXPm0_ea6kJAZ|z1)wTSmJYY4X8{tz zWy<_kQDoHPB-JOeOtKv^Da6eTP(BLFh})7r{RA(9Mc+O+CH5Pk#Vt0n2(?}}n3=dD zrcIDqsI2vU9SYoRf!It=u>4u9uaD85wqCkNcGFrKr|Nt`7atqd>-2l`bX7~E2>6kC zcJvz`m*ux!m0ON=HT<-KP0ga_HGlOGLs({l(VCthJ@5ys(ua?;(dO~eK5pd<gDh6_ zdh7l4883*=Cw(}>s?N)6{)A3uYd<Z-ZZ7Z>JO1LWusG8srW?07*C30^VhmU_Z55j` z3UV{SN5B_vbxL9d&Ui#TRhK4qL5NtWA|6L_?|US5$aKjrA^`XWNI{<wJj48s*s0el zmV<Ug%e#~8Lv3I>B%|iHy(S6lBYwU4PDK!q<y=ZFn%`tsy#F!w|F5a(TNvj5N=@H2 zAQP4Eg!Z55DM-!A3q=&wm!fdfrVSEQi}JBP)Lh5{B$SX2OgaKvW}Ga@QE`twtyr7A z-N0>*oqFrq?Kb*}Cg)a|@Q(NM$5*)T9Ym=ay9IqvvUlp}MCN_A+mzQ7>F>|CHv$cR zJsl_m3VgLXjzC}75rdrY-fvwO0UrF`*ziA>m_woA!j2#2Fn--%t)56W?yxa5p&_+W zuLQ~WD2@^%2CRWhxQh0yfpWN3!w#f}jP!MKrJPj9VXm2d7F?N%4r-o!WqVW>u5$2H zX!7I2!h?n3&X8F4Xv);})Wxc)ch+LTTs1w=L=f8k1%%TxZPNhRx*P*hQqOoI&I@Bs zS+0Hn7B`6*3d>L>QUfdxjx_W#paEny0ULjSKKL;@<8pi|v`eR&LH&VV!-u4rYg`u$ zgSF*`6%rM*&5SwW)OS1gCwfCBz(AHKI~3{)3akP9h_NQObQg<v+@9*vQP^G=GXZ^h zl4{d6aOzlA-ksaSk;kZoihtZDPdt5@ilra}K!<k`U~(!Z$VoL%-jm5X-EKN%AMxs; zw^8iXXD>=kLNY3t%BANNd6u7g{F=+J6-f~y27$_3vP+z8wqmh{?-m5RzcEk@kF{t9 zSJA`A=SWz-3)WG(Lk7pNk2ZF)=ZsG)BkPcoXJkG{1({`E!Q^d=tv6`p=&sw3<F4GR zjlDI*18YDKqJ)h@afZsBl2YDLvBL*<y$>S!ZJ|!^!tJrKXOTw{9KT=otZ_HvkS<0n za*52Zb`usXf14IOeGAq<)<TeF=DeJC-~W4*Q3cFgVlDCf0NqUAHoaY^TQgDc!!LOJ zS!(Dlok%5Q_6DwtEI^VVCt#`0#64J`yLyKQZhIdhxYtBVn7i0m^fWHN0;6@8UM<c* zxxmvU1gz@sML4sy-j?aG-nJ!Cfi{hfl`FRIfV@&(4%X6A5<hFsk%s~If^)a|v#KR> z@{wLIDlfax);_>cL)VRqnM)W5Q*E(1n6CdGGm&Z-kHvAJP@A~fd}@FgqRp*+@>oL6 zV8!B23&R3XHh`r;DWj>7M2^p9O+o|XWRe_VFx)g6Y1@OS%U%9ZodHjKkn53gr83Jz zWgeSFwVehYxb`Vvl*XY^b8yeAi})_0N1m;9tQNVKIMp$JAH0rf{&sf|qlU{Ig^DdA ziO#oHToTWn)Tj0?6S7gN0~v+G<!H`!=W+HU*rs{5<Q9mq`)Xv@L{4>A#TA`K158iC zl?9JFr9(&aFS13vJpW*k#r~Y8{tPd@B?4T3umrEeJ;*`9>@;Li7nuzgzGQ)F5x3fo zZ5&a(_iKz(jeZ!Zomy9uw2BQs!#k!K<+MtwgCsp>*m&wDD_vH%T8-r<a@a80Y;n3( zWTi>Ql_$>B<2uX6?lpR##fz-$XpPWIB7*u-Qi6R{<+dY$qgEo%(oCuxPJZ;6l`rz{ zqkw%(-I;yvcvzQYvJQ&p<SXnQwC6ycH40(Y5^gf`D7k96r}`D#W+jR*$>=B_jVOIO z2xPe~KX6B+<&awoh0laiM1`(^&M(Z~9AKu6bqN$%^{0vA8Rx3SU$vyhz{On_YIjN> z%1T;8T}a&S2Ao^o4ZOy{2Mg!qw=$M4EDEa)Y0K3twC!&zb(-BxEP?L1qC^LbG-s+_ z<|}yp<~2WGggm!WvJ<q2n_}#kEq#c%_T`w`G`8KqYZ@aM!DhA}o83Q9ef_#z8j}#q zoc@lg+Tm7hw6v|Q0nRM6=yZ0VmlOzdeC>XGlfct-KCf$N6j1octh=en^eI-T1`2<C zf&3GNw`EAU1ine7D&JV)zpL{98in!yM--Nl6OsJyYW#me1y${Tpu%TxVU`7Rk%?!W zR?rWr^}<PsPCrn^Q&DJ(G5`R0OD;aad2Te**>nyjz+Lnms_S_tV)~JY&6O^B`jax{ zjnpDNke<xS<eKa4!tPgB!}P@V*ZT`9kjzdAqKwXrJyW2YJyjqlvTjSH8=DT)E?-B@ z-XFwjL#cj1cp75goQGO}h=ERjX7IVvwnE$jV~qh3EC`1xZ7?Gx-p}~gWK?M-+7JgE z8f-OHZ`?jfo!Gr-SWoqSKD3-bd$m6P#hWzmcb$F=B^D|rr9zXoNK_i?mhj4esqti^ z7j;xnv0*h-&=Qg01Zu`{MMh3fhBUK`2|!u`ON#fhqa)O*X$!BJ2ftfM+H|tWs4NO4 zYeUwN=r(e6$-YabdahRVG0VDI+<YCl^sqK(4RMVTUQ+-IGTv?Z&4>hlf>Z|o(|eo* z-Vloe8W<jYU_e*D5VnU3s*ClA44)I51nD?!m@*^nN3(1QTB*5HbUGlFj|?}*?(K2Y z-G(LG#Nt;Ak3+>#Az?atP>Z_bo(F}|V1r&8c*OSJ>S~c^<SMpAP(?pT5U=fPQ2y$P zkT_HZ^sAMLJ5JN;gz5}h03-GEA#cL=a$S(kUVGL>MUi!K`vN|hi@Vle+`0~FBs`uL zhQSnW{GGh;8fV^kUS}DYkYR)s>X&32J)^DkX(jgMTehw^iu)?y&Mi^4bYSHcE|!$1 zNugfaixEQ;f`sDIxe040J?spe6E2+vBj;7($qP0j?Jv1(jasq(Cq!=F*u6T`pL<~e zM6HKOv^g2e7{$lwAW!&?_AE&y+1fH}TISX-VqvS<0sgbbJcLZH&1en630k>O7-Z1w z3ir){trB_O&?A~e4m}zbY4D|#>P_>>rKi-alZSWdG)<)QBJy?UK}E|cy5w(Xc4@;y zgn#R0Of@GsGm>dCf!#)&Z$o9oSzju{%<F<Q7|_r%dCJ!c5I4E52;fr!27Xi6!I426 zBGTSB7{>8nf$e`KbbEB5*j$OTt{hdr?CB%Eisw99Wtv*~IP=Uk-JH+@4=V9YKNe1p z-Yej(dG?my&s;kE4r|ZY(A5Xyf&wJpXBpzxXsXn2{5@!dpPwhb@1Wa7HtS6!E5q^V z+W*yS@w$;3`~4?>=_BKktUxJ5o5P#sqik0Vq3`hLIA8CM_o6r*o-OGn#D<f>9v*{y zk5v9m_{_r{ImNuNJ(CfcG)uNjq;-8o;%$cD$!zM3GfZ;=rO#&ipk}{^`5D0U)Aj-D z0}U3mRv^{~HvS%FNCAsMF7Z|gs~^=UKOhBdB(z3_#e5OAoikVuc0NU>pA&zMMyg^- zngDt&?vX#w6Qq#fVxKgKPjs|2n3=euzVwzaQ;z+RSD4EvD)Ws~dP&`mm8(Mxel}Qm zfm3}*VgZxRh}QBUDGagTn@PZiQKir8rvZinZAsfD`$bqMf%XaWPfXfykin4v{bq4P z{%<kqf8GrLQ2;dlZifG7G^$cvSHn@o{A4FhBf_GD4GM4MZfqhaL*%u}HHR0DB28cg zqN)lPu9t*JkW81MJPEqqg;8M8Ue1rwt=RI|y_56?t||YL8z~DiVUSt6Sbck&4*8fS znD+GvH<;LkV4ye96B~&D>mW&X6Tczfy5IBh-sul{mKYl5_YSCy6oryzt{&Au50p3Y zJ`x6<MH)a%$@R*EmZjm>89v^NjlB(uRIQWsj0+&5w5T&S-axF^%;O>fAjK!tk{e|8 z;>A=iOTk(?E^n|1lg-lyJIYPgM?}D8lZ`iJngkpC-jN1ZuT<K3pw391WW4PD$dA;& zKYR1gbEyp1O%X8jp!#Kbs%Q^p$C6pG5Pm<XYu2Tc%|NhloqV*<W)-tcYE9V^CJWYV zuidNNLc2=?_G=#pN*lT>Xp|9Yx|n56i!^<qv0QV%iNru#5Fae~mS5{LT9w$m{E#pW z^3ayF-IhtjNRzL=7=iLm8;s7N(n2gf`_Y)W)TBO4g|xk_>MR3W5d_G_hNa+_G^Q9g zzR9zLfaLgIUGz@fSk)Ah!N6k%@J9Vbz|pl5h@cHw)*{MsR8t(j;P@Ghry7T$XZ7)R zE(A2EYiR)8IC41jRZo0v#SV{xXh{x(9H6eD-wL)MZBc`}HJiC9QbH<4K~29PKR3Kx zMaRZglO#LI7axpGfesH0?t-c%#0Lx_KQX(>3c4#qln<c2G8Ljt1{Wek6tav5JXo<+ zi;FMiFie{YpXAVStnKNQavWw?5Ale0CW8=_G~t;gxK_3R+aTlPzWQ6}i!28vm;UeS zyIx;4PjMDSS;MDqcGKgaT$4x%AcM(d&9pA5irCE%ZJoR+S=@iV3i=fP+>oMJFx7Bu zx#jdGQ&>8!o}yYQCz!sAlKB-_3jfw8+m6$_Q);v@v{>$rQqUpcnE3EkZH(bz9dV{f z^B9jgEuAY#0zaWxq*beotD|-dp%i))#kvc2?pQc^8HbEwSTxh;BbKLBIhWOu8ZO+W ze9}%;2rJ%A0)}H8B<!@@0F#Jg-4(O?UEJxxG*h$6F~d~!rigScCG^0!WUh{FMM-xu zfucq3LmRCm-bZS4Ahq$OYd*cTdEk;>^{hh|*r!_^Sf`L-nC!<v7-kXxr<e~;L+isi zJ(r`P`R$CP76P#w3Dh1<IADU<K8|n&Rk}Wr`vJ3G+}?&a@QsOgbd{VmSVbWz0~4!H zOyRMKBg7s{Q1vvo;1aGbh6&Rtvdk<U(~anYd!SEPhS$IC1u}t!{?QsmS(vjA;2Dh$ ztatiDJe8}jf~A^#isk)bI>+z{`;UTaUfA*%hRG9?YiMij8$U10)plR@&NU_s`z?4s z(T0IVay056SMT@Ld%t+6Z2lFPo7pRdSCHTPSOq+Tr0iouP!Oi44vNu#5=UBXw-(iw zfMPsvF<REchP(fXK&@`s%)H+b2;_f_K-mA|R`maC6gmBW#nW{s6jjWxtfMB`CIDO^ zrhu-1wbVQ~HL9$(C4*wXX%Kml&|;fx(`m9XiYrHuXTNmk_H}sZoyvoxelcREKNbP* zFoc=+t>72b7w|2QWJY0;3QvO5lpA07byG?Ar_%>Gt$8mP#ot_Eff5v5&XE*b3Vbnn zHsBMNe1wlhk>E^s(3m!RNCTh{U3XX{2yjqXXiQ|r2{3Wc$QDFVnI6jRm^%}ho_+71 zM|}>FPVEjr@|-t?DC^JPE@D0b4D$D)M{Nl@bo7M1*D9bg4%}4w>2C_HYp_4F5M%eA z;`;$0=^$9(+P|+$vkmRVO%F7=V&fZ)2`$gclP~mZ-OAG~@r`Sr)1#R+-k70+ngErS zuy9?s>ozUvEY953#<FY$Sn$SJfm80~JK_T%E5o&11r*u|ET&f6o9Wpsa>ZJ2E-q@b zc$`#1Aw+#5Q~sJrCH7hadH^m)iajh|nmsPw>mC^5sU1-WJ>*+vJ%gLSF|csbb=g}I z63jBIDs$nca;f14+>8u+svSc+R02igz_TQA$O6GEJ|ubB8s@TAqb1~|sw`x5!reO5 zWF{_bbmvZUP$qKmPNt?pi+i5EJ@QSSLhOf~bCs3DB_^B8O}~FDj{->Tw2ABtIZ^Q= zgT)M$+!@)Oar{h5K26TandJ{rh40wL5^e*TldK=4qgEr=B&xZ^Lf$+WD>_7k>yX>3 zubAVjZBG{f`84tACuiul+*`R)6={_qcH!<YcFL#4iw6^7Dq1MF@LPvv-Z2K+tf)|r zgN2)OiP@4hZ88II&prMKqTT~mn=jn~31hQ(mtm2?`SCUD+p<7xmA1888w-i~%4Tw7 zrrw@H1H;dO3_0P?usIRWz;7bnVGSzZPIE+u^#>Ypduf@b*n(khQ|hp)@dN(ZMy1M8 z*;LB2B=rWb>4o%rzoYIq4mpUs20i*}m4s)JgGn=xqb6hwnel0z?HLgvZ&ESYZzo5} ziiJW``q)m=9SMaKSfnypIg&NeJ~XtC{uUYkk-<~O@==hR-?_Z2VzQ4@1!rxdm*qlR zqFmR?tYm+ob_s8Gs}w-ZVu7R-_Teo#59BB=P6A>}Qi|$3AkeD@$;sX;g&#@JJa8$M zq&EE}Ha}tp<U5~5<al0BO;l^_m<TSfSZ)g3UuY8_MO?y@Jl_y6J38V>Ey|(k6Y?@_ zx{uvO6~UU6_^t%@yj%_}7Pj46;f|BirzA&nn^_i#-WDQIji#0wpSqY-S*flEF#CXo z#ehRjLTuX598<8NG@XS*Any1}u`DNLP;GM`)SoG6LgK!sgemSA&fiQ8K@uJ(ou+7F z0xzZGh$e3W8@@?z*0AsZ`}t+wJqATqqV2QmQW%h?8Et9uCmEkWP>vLuMJL)Q4Dgyh z)bB<KJ$R+v4V>iPPHoyA3)shfx^=PFW;+CgT|O*a0|`*Ryopf2ls}(~Wqyb(&QF;) zUv@#eLcP~uUvdgakybnQfpchn^%7hA!L?OX_trz6uduDaYcTZt!bL;=TxSqAujSB4 z5>??i-ZjR&Y1j1#RmIfyqoaJ@#0gI<($x^C+Sb)3Jq9~MI?Kec{n)&y9xv#E{zIqM z%o7v!fDk#^S>|4=eSb5PEe_JJ(ctAI$f9vsHMLJ4%-iwMH0J>$+~8%Ucme>lqa)sN zSN$|xud8TT_n9WXdTc=_qBHdBty#9v7Ed0A5B9*gZ{h4Z&#X%zqEsrqdPA=ppVMpb z%Mzh`Ysv9;7nPT_nuRNySZ0)uQtxosUHat<-xg<YqtO!$O+vttzcGVTAG#^ZBFDj! z+4*P|l>ZxUFoMu7t9LD;*2~Hc{9Ma-C^%UN+kNi*L*#Ybm?cgnGnwqJy-iwWlihiT z&{E&*c!jI{;pqax6^xB`+O|H&{43~V$d`iahVY|uffhlL222|6fF6LL@7Ap6-?<|A zjPXw*fG=aH?EQwv0skvJ{zsqVzx!t@js~_)2LJa^y~?&S&Nnu;m8gHI3u3o1rwOlU zOc#*w3t0M56)O@I{6q4G^kSPe{b`>m$ELN`UCGH$0UztEJQ1_C+d+t5-i|{QIhnVE z-MzOPq~Mf0kqu5yTlbqzT~1eA$6GmHpPyW>jNm+e9E@kev;smp@5sKeM!bGdGT;s% z%6lA_{q2GsAsNV9PeiBvkpgBusVFB^gtq%2Kac8mgsJ^lnfbj>`o)D#jR@)uzfk;t zQxj3pq7P2x2YUN?$32ljjl*U?^p)E%20E^v39}iLnvy9xTW?lQFuI$$D7)D*J&5L8 z!Cob*9>MxgR1aB2+orknm6zKx!-`#HlOnQrX-=9ajJU%rW6^87lIg9w?k!q&tX2MG z+_TXBJz@hz!wgM1Mroirl+i+NAUnj(pI|RO1b#L4jQfi*a6YKWq=>aUcAPT0D*e$5 zzJ>?6E71Yr*Q_rOEU_G_x?`sV)?Jy9X;&hbL7B)yeSSu?p%yE4aNdG-XZf0}NeG9L zRGO8^qGD40;tH#~ibFaZe{-y!e(Km!M4FJ~=#jKE!|mfl{@9wgEt|3mF$$9jF+YA% zUO24|m8oNziX@g|lXZpXfYuN>E0hTqt~N3?^OdlfJ>8|mN^%_t^`by8bEK^5x?+>c z=8j45!56d%bFs`;sQhMTc4}&|UpaBEl^IweZ`-s@^~qtYBo;X>l5o`So<W@#SMsfZ zLQs%qXC4o)A~I|F5|w~?dq)}BI-5K>GF0B6{b#J1g;RzVC>*X3m2j1EjHGsQmU_j4 z=Q2r&v*r~Uh~-A^D1pgjTR}RurfxXy;^{L{QLkQ!vzEOg+ah!`)|6^XLcL6a8%a#| zrK$!&`P6$x>OLdWQY*{0ePyC*)tR%Ho3XG?G|=Qxd4B}_NBM^H03Wx|M!%WJU%6b7 zakthb`)A82Y8eQ)9CY(!`n=6cOz>8#`nes~1fsibahe;?e*5rucTm1Wc*8s0k`I1s zTpH6l%@RV3e#;rxmi|)hFq6BTSb}ObuTgGz<yI>p<_VT5VUK&uP2SfsrPIHYs9cj` z^M+C|XfdW5E^^lwjBtLAgj=XukF)7|#4R`Mz0jk`dB3B0L5#SXFdgx7?Fg<OOKxy` zGH_g)30oQ00%8o9(C?ZN?G1bouDoeU-2!L3n&fDmt7)2NrX_IAcROHS>d@&Kz5jfc zKnBrY?a$!{7-AKh(6X*Hw9;Bv<2Jrv3m0-8S?rd>ytyBu1`M~<hTOidL=?U;b*OJL z#AmO_pTsoYQ1|2WN?ucj4SZ^;zc1Z`;&XceCqOEx!QbEtvwles+`#w_+68_^|Gc4? z?BQYENNgZ_MiK-ha0FVIvcCQ9xydqf_xXUbmst%#l47=^30W)m<0$lokQYb!PZj)# z?H&!n?;9sP#Q%nQvHmsCxSBXR8T{8oY>=9!Gs-g7=aqSTGQ<TW4;32`2$Y~JZba;o zO%PF%&1?(gxCF4_348L8m>514i&4*JeIos7S94*ZY+D+@*&oqg7-g-v$fB(o;gZYe zl*{MRYWh_9^lN%#4pZjL$@}_!{NwtmM!n|qDJTW8r}J4F6=BaF2fv5M-GhSRI^Nw4 z_1b@G9MvgYF;O32gw0~Z8Bjl9jVi7f7H=)rmsrZIo8Yd|XBh$~ZrFu4Y_GEyH~{>+ zOMTA=`8ws<ZvcV}Kh9lck13g#{x%O%PRxM<UfMhLDdy%*F)Zfx6O_hBXAcEAC-E6o zIVXCD1vw{b&&geA?;iP={uPGDOZ-3zSyx}qFO%;Esz>~2&8=hlZkFjUIq@4*F9A2- zthDV|cdb3FZ+y3EC+W=-a19A6US3Q!la;m@a|-pgD;0nxHcO>Gi3co2&oHxyd<5&& zwRZp)V%*!oa$FgEgty6b1e;KlH@o|xCQ5h|M$^V6>{wwv70bx0!ahDl?=R5t<Oh>) z3@I{C5iS;G*F^G6Uw8b#Y|zf;`z(gzZEZ8le9{+Sz*Epx(7pr@HIipI$W~)W;7C1m z<BH}Lt5}Dz58SL;mFAzO`Q3rA)wlK6M~KuqGzv!R%@1dBR~vk~@j=s+5wTYrM7ZgP z^ex;Q=EUgrK%3qL=3?91s^oHRRLgHq&;p&VDBaHw4`GzVUvge&mwI5TN}&;x93;~r z9q}mW>t!<o=sdR2*{kzsNyeZ8_-)+i+tq0flpy9>y{QXKoC;1e*?G$r%Tc4q&=_{= zdp1#2+b56=VU&lQ7nxbtXX(T%<gAi2zHJyYA${}rL=Px=z@#aTt(Pb+_uEvZEK$qC ztn~(^TZD3)fmk}&&V7#4avs&z7l|Ho>W!pa5sD68y<w;2<#Eu#+}tc_6Yw_+O(w?z zj@;dF$YcknZ=Ce>(9NYcnr$*n<KC!!{eP9WjJa~e;4+1aZ}!kGuL!Kl$?^mz&Dv0G zjn|UE-2-dC`_E`fvrNp5QIejn{c=ET(?)A!n5ShHs*hyH@1+6GPf@uSt<WlK*<Fkf z=h9<ee_<n6?HCi_sD^fSTh#(zO-iq?Nb;bL(Sj)m-`;7~0qx#De4_sB0sk5~S#m&I zy*C+_V2v+Q-gb^Usz=cxV#}0lE*Bci;WR0W)8ST?_{Ffe=bWd;j%P#6(ZrFIvGBK$ z;;oFIQ&^`+>o(MO@OpboI@%T&XS&1*%*MJS_A!k!cI-m_xUoe*yt`>pnx12MNe}I} zDWGn3PKD`|U5+_Ug3;A~N{!FB#I&quv;ut`<2D-ItxyP0h^nX@clo&Vqj^Bx;(o#f z!rUE@F?7q6P`*VwS61EfYq;HK*fGd)tn+HCBI6ZS{UjZ$-y(|B|C?^(+0Uxe44vV9 zH>BY7d^>Qa>qGgvm-wqTOtwlj%PsxBSw~g|5jeyi^Ht}5D9Jj#immu$!E(idQB22U z@W6WWhp+&f9Hwabw9kETBO&7NOUP$&-wQGN!~P6mTZoyCg6HT>)D28omwC=!PtPhb zJerxW-*Z<4jG%cG{C}~PPF47(9)o7RJ=c7MgUJ21UjM3E??OgV_>>Dhl367?RO)0M zE7<_Jm>$I<5_kfSW1DZK(SHtTw^)0z3lB;yl2@@s#a`Da5+H9X-rq@*1bcRw>!a{3 zA^=0q{p8cw`RUoPk(EuSMfOv&I(Wwo4*E_&KhyW56fpcsFZ2+0oOgq~Lxu^XE7TG_ z(%bca_<F}+(Sc{(dwDP0wr$(CZQC~XvTfV8ZQHiJ*4_VePrdil`S4DvlBra>CaF|v zIz8RL=P@pIZe*YbN<IZ11^?ZnX>^HmWp2J%Ncbr$Fv^9R5c#s|5H)4Q{FJDFt%Jmw z!kHX?Z9LExRhwTQq7{<<khKA6t2rF>WJI?$_!$x`i1yx-Z~l;s^(|uadq|YeAuM+e zQ`pUZa1k77t*<8W?_J$o=iO2Bs4ZVeGqeShf%XvTM^_XV8Qnq6S_<dQj{N9~dKT}+ znGNSW*;s+xJ#K>A9}etH4(x9kmliL&uqhtaz4sfPCKikbjWtoRm9UGp*q5~zl+)YN z$L!(k{{A__n>#V`Eu0r`$Uk60WXV=LBzF3xKRY;@`zl<1FKqX{@poZ9t#FJ#cQSXq z<qlO&pNKnEdwF<*!N?s%E?pt%t$QeHM)HhmEAd6$81#fXR3x*KLQC|*s2LqxnjLc6 z!mrSuO>|DP$;O))!K<x0|7yebFB<%WfR4lx<Un~$?IF0dq=$_ZO>QmebE9*F)YA?S z?%5I5OS{Utu5Q#MP$u+}{m6fX1>aL2?2h@wL4@%!)rB1M=FaNA%?AOopE{too2Z&v zbw+@Z_gYP7+N0MMRo~R~gx2#@jE}>%MkHtq(zJDj=?@o(aB<Kzg|jdwDX@yMpY3f* zx{W<7$wJP~sd=2P?IOcX%P8Ic%z({ytf)A*`7<%2e)S<Slf%xt!_%gqUw@&+bYF9b z!?FBdP+|En^Dz6rsTUvS|8M&J52*0}`S~jL{|Pu7T3A~+|94GN$UiPMvKr3sG;aF1 zDSHEPQ$V1SW(JHkBCH5jOoow!nq%J$7`XE0_{|k#9a>`}e^>L;XPH|+Qf=|yKY0N* z&F)Rg3RPy+V%?Q0l?OW4uMxk$Q@Ro<th=cmx8Jv)-Q9P+UN=EV+3piT@XQbnaENPz zc-;t_b*n)>;t#aT!OV<Z|I)tspdmQmq>p$&IPmxLf`z<ulI{#4=qv`L?iopa+k@4Z z_mkaKkaVLrNw85J!v5IIp}%47bgK?ry8G}n_6GFZCEbyRcBRAF?aykFY*Fmnboq1! zyWM@r{&YzVbb9!}`P~>6yGgJg^ec3!4SW)J=?(l@yMdE@gExwmc&iJJ6@MdV@|GSL z^`N;sZ42%s@fI8)dv^}x%T2hmfXFpa;-%Uz3Rj|zWX?*t<ABIbr6<{s3U0(jc8Cr3 z67d!oLIZ94U^;K|U&-&j0Bq)J<y)Typs~D2fAR#3kyq!JLcv&Yd@sUSksfFtFrCN> zg~_ZaFK%Ks+6MM95>@nH6(w7C4!jG^k%ezC2+CQRmI2D@iMdWeV2Dmhsz{`P^64~t zq)#WaC$BJBZ^#P&1euD)#H5Ha=Wya@QIXo91zZR<UqGZYVzWiCR~Zp^CV9!wDOXmr zOt`wjq<;d=AUMd1qT8Qj><O%$Kp&+=c%5_yI5i1IK)BC~s@=b2bk#2nhhppruuI_k zPEi~tu9l2idLbvIop?jVO<)Kh=SWp?;-C@DY^xw^PK&ZTB>1bOF6F4b2r*n&P<F%& zx%*(RPd<mIph})8R5&=Xwi2)-ZnrDXj{yS%A}G1rmN0#!8u=Czb$j5&IKm&V&X^T( zem{QRfXuU<E>oc(GxTcm1ppWMmLDZ{M<i*Ni#m&*kzmNmQ{f2hg$(&T#r}GH=rA33 zZ}cTRB6nW~&`)=0_Qt{G5E-Snmx{cHaGf`RV3wda{>I`<bjSefB4xL=6s2Ja5*xMa zXr2*to@J`eAf5<K<Rm|GtA2C%)(y~3-Rg8*p~Cpn7tYtPX7cUTbjEu^NSEZDGEj3o zrbG3EWGQ=y%}sD9_tpq759^0^&8l@@x($N@c<#+uE_)`iou$lppK*5F(b2)a>xVGM z3Xi#6v8DlTs|v&wv@gCU*%l@BR_U+vozHJaEKgWZ*<U(Zc9Xm(PE0Ruv55%@`x-iu zOcUVHo1m(cfd~;3B?iPr<SW9Jv>YuF@_-!<5(X?O9a(7&lDR^V$Ha~Z8%#)Txs-wf zD~v4lHL~1N7k!N(BzI=PvQE4Ap$Mpf%-T~hNJ+7I*Q-%%F=+CI^BZ?B2UZQeR`h2% z3vn79EZN*q5yB3u;Yxw@YM|aomS*CBqQPi|W2F5TP3p51z)z1if9OejWej`HP||EY z^e_2xMRY@vi8OCw3e1?9M4h2&k}GX3S-I!f_{v4pI;%1Uu(CZ%c|}u<|5Ou*ir2(w zw{VD1|I8ZTtCLrCI^f?Mg=nqAj+7{hO)sHuw%1T^t5xSWt47PnhITG;D=Di+Rh71G zH*;!uRc~gA?<Met-t8MEFI|oeF5xe+5x;7}U98OT7j@u@($3DzMpvX^GFcMro!l*R zOpm`Cf?%f)9px@s6y(Vb{_o4OxY=t`63BIVkQEVYU6f6H64`>|MbNS87CJYTOzvT( z^mA{v1t-O_tjo?xZJOTA%q=g^$Lj+Wjic9f8LCJb1p2aqOqHoo{xMWm*)DiAWx%Al zSCM&+-*-3*3cs2a5lZfiV)`8{j2?}Sz!&K^)y4r5uI82%1rD5Pwyo5;;gvbpn;zf{ zyb>)QW|;ymc{mFN9!i@jtI(1;x93FiUgw@>LKJw&^9Iw(*A<!<m7`iCiBTeIBMZfr zCS>Vy#h*+bEy=XYdH$k6n<@2+{V^S_9U0S>79DS2v+`oiZZP)}rX|##o-`^Xi7)tA zhlI<<(+8fY%17fbQ52KfXHYA0iiI+06WB-nB{+odkBZE3gczS04e%s{Qk|P<(3(-6 zD7P`BOdK|z2Fb{5=AVz2jBJIHk}v~w$(0(q-<;V>6>;?oZB<(4$PjMYY>vhm;s}^^ z<h5QOhK7U*bPHX0`37Wp-LO92?jAn<>w#a--kpxNmZ6HqaNEBZ!U@(nsm+;E(KnIk zPl5f-Pq=V^_5ug3=-0%)@9I=MqgBbc)~F$Uv)ms&akA4*kWC$GSpoKlU#sD0`>O2d z*Vw^WGEKC1oHGL)psO)T_PHX17U8A%s00w~(IZNC?wKX{xx-m7O?uuS3ICD}ZEw3M zrp$~Rn^`@(MX2rJ#h`$-X!NBJpg=v1^horL0L{=HSRx#4Df5D0Ukhx$pivRF5m#+Q zs9p6TSKU+R%pj#AZt9fO9jEIjW8u${b3}}52$BD+w3~0r8@}jD9X%RV*Q_C@AZQ`1 zau`_j=mJn_&p@uWL#Z>!7*%%mNVd*hkY>X%UBZ}<oz3ugdiV?UFqQ=sx3*=3a7C&c zSU9g<VRcbehQ5J%T^}{qhtuj>9cUqOu9B)Q$b=%-*@h0LG^^ctLRQ8MTyH5izXUW) zkciQzhSZQwLYW_2V{#d#kO)!?ThXMgU3nL*dz6Qpam^oEI(g(O4RQW)ox5pI-hQO) z#G>i++OoMJ^aKHF@4k#&<Ie*Fvq82WT4{?YLVEbeJBd7V35-w5VP)f37F#k5*<ftm zWpvSC(c1xZY?a9p?CWgLs(7Cg`e|;b=8Gw8_ooq}ntc`@ou4Dkz9eYXoJnmEaaL~N z!F~AfUVcRsZ{kmi%aqFN#FA6A>T~El1Ol_@K5G--6~l?;z#YvyOgNMnRYG^>%$AvH zj~cZpo>AK0$K!GJ+IRi%nb}U=gZ^`!hO)OYFp9P&cKQKiTjaDpO>?wGI8o+S)`dZ9 zCu-em(=!N<IvtDC`K1q-Lqk<Uf5E-aDPSq^ZJpVa`O&q~B!G!fKcTN~i2>$L@k#jI zYLDXHniIO2gZTDeg}V=0TVM<S7Q*!4|EF)1^}lKj{y9$oLUQsN60%~++FDMS5)Hn% z2X}asPmGGfT1+ojGdUQ11Q4576M3M<wTD9<=4U{j+s;fr2q#}3iF&50E-d&SD-3AB z+bS9w9`6r|&x3FyU3h#MpYzks^xuX%aHE6gdpq3RJ6o}~=a-xN?yOg@zImr_vt(MT z7V(*E@$X)VT8|&CySlGl-#P6xu3?NicK=?l*RWouTXD0gYSo30w&r7v`2%sy`SDoP z!!b*@ke~5h?~mz;Yv*K@$Jjw}^i-9Em6h-N@#)wWvP!fYFKpEN`}E~%tzP%f@o6u{ zBRkd{{2-YYE+ipw_0&wtW>bxg;l%)T1TNBPgv3Gx?V^a#;d~=hfqo>OlGgm?@Wc|9 zCyP`nYi*UpUz5gW4;&27erh&{9@)oc39G1FwC0G$s<q7{Osk(<4&7qEi)fb0f2(9l z8&e}F3U@``2N2ZJz2t`v`a67EdRR;Y_RL;8)@Ut7rMqb%IwLR${7ltQTIoKTc3=2* zTl6C7MeSIpegcDV1ASo&Bby?o9#m6VW=AM0rYcFMQryhRn-E`_Ym_>t0~MS<l6p6X zK^(|3>$lbBy9tJoxfL+I{MN?0{=5ahC;Zq`my9*x3VBe3Pdg_qQB03>)aEz7w>t>_ z2n$^;9)ye4nQc+$jmPIxP>m22Id^KcXX!NI)tH{JNS`e8w0Di_G}j388W;y=8aiAl zO`X)tyPY)Wb2c~IO!u~_@p1Gz!zt$FuCD0|Yky31p(VUzM|eySYQw-H9))_<=BA1z zfx&j|AUB@c%GpFT=G!Kj>)q9b1Ju8Z&8HY=o}s8~ca2)!8O&Kk@+-f(>f6_mv|L$# zAoI`f=mzBQ8=I)KQsAvKB;WA_x<0#gBrZ!m$e4#cW|YYukZdKijnqE7Wxj~Hkge_V zA`1M;kTayVzZ`8$s;jb_V&$0ICDhQfoC`O!MSK}GXBJB2(2FTj(YXRj=r>nVl%rFQ zcZk~yXZt(d#YH-a<eqrdWtC||WN}H@+P9&`I~&wf?^`^nJ}>`ejiPz+*(>VLK?)%? zc9WyJx3^4cBKudH4reBA`WF_1cBaIYNRr~mP%jki5-9|Z154S=XjVRs$>ZY!sre-5 zLR!m0d{cSEKOieGrKWN|##yRjM6hnkYppQQWaO;P$DR{TFL0`42IeoKNFBas!(8ct zBsjyhh$Pg&#@QN-a(#^ZMjCt*y-vN3ZrV{-B3=u?Xh{auU1TN~8@T6$TJLbGFc4!% zSmb530YA<)2(U|a=_L+5SSnw>eG|=>tio2=#iMob&k6hE2YurP!>8!3Bo@D`708%~ zMtPZW<mh`IMOXuX0f>bI4j=5oC#z&cFmP(hs5BKZkQ@clWBKg7c$G2@S7xk<UIu<d z9(@{Qrv?fyA`1iBxc89uhf!e8wdTxN3OUAbWCbVQsu+gDt^j>#X|@c6c8990FN~l- zuqrnL1cUt5XJtTWBFnG7uKC#3?&&c!o9P|E4~`^ApxxD;*EgP1h6A$e*)5ucndB$g z)L(TFWrbzWH=M2DCx9f00sD^dA)U0K&!shtQ)&8*W5rs$`<X8Is(-KoG9<`13_3*C zT!yg9gK30qXO^F;D6ydGO+J`^2m~YFr-tLkqk~;3-E|_a4-fGYlcPVT&`1~#&_N@u z*C5GpK~w7^6U2iES0AE8rYKNjgU{FxiInLWzy~Cv2q2<Yc91*@iHAmJ7w``b4)pfZ zAf8qPH-rQC7SarlA44;VyCqERb}8g6eIw$jx3YAtfG_+t%nTr7MD-UM#fHKpq8GLg zIw48|8d*7NOh+@^k^s8nk|6Prp1cXZK30k+?P>tgRG3iA19gB!I%2~FqUzk+2BjmL zPE1N_HHea@UUQz1#*OZOWY&+UCvK1$V}ho&xk=f+CsmiwZ7jr(wYIvd%DmFl0f&GO zjx;7L@M&t`+hjM$t0TtN1j{5auDhV+W|tQJs{-#=g>2V<KmWRh^Q%8Kr^d2Jv`0*@ z7fHR~oz4QW0uTW;4{<%#;BJ`K$?hy~-Rt%jOY4hdqBFJ<)yiMfkdGrj=(Tq>@H!6x zu<bDIWEPmaHXX3xQL62xK#ckf4pvTla_q{#wz6RjmnIth1GNhER3Q#|6k-&iU4un~ zw1tY|0WYFnMMNNMml_Ppoi>?1U|UieZit#ao1NdH!`6XsS_uUjNCVdpNRDe@Q}{-9 z<u(P-)b&*|i42uU3Nw)<5DovWsTbPn6&^0$zQqDc>y{=!wmt<PTbEq|S$l*(iEvik zE;&JoYYrSy8Nuv!Ty1|a-YE)LPA)exH2h&+eH6543Rzct`0`@P;ee)ZE-gx|o)&ZG zqhZ{MU{Ackod7<*7{K#8!~BOI0Uv@nI0uYq^|jhozs}tKg<ep+DDhNJBJGN;lbA>p z3;|@cjxrLNu$yk87GX`87vHBK9e_d==W|1cpADLuYJ;BA7?27aeq4H)nvD{l4b!Bf z4owSs7}}K`lHHA4u6H#%+@$PZ;_4JxRA?Hjro_n9R)QF`HC-Tg2L1y9-Jenj2WBc) zdl=ial7{}D2tr>|<Dr%j(tqo!*eUeS5|rq!lNR87jZ=RlNa6~j?zGm9V1F7WBIyym z9ti!G``??CWJI$XjAKESUc9jNA(;?H-o?(b{HH)2Y?8rN1PpN=Orn9CX5t%h2$@yZ zugaU*>9pt(eDKt$YR>B(t^}F8j_827WL{9;fgh-_Z8_vm{&}y4k)THM;mT%x_`#6( z5!6to(M|x91zRX2T51f&b0w3rmKAlUDAxZtiVZlEGL`}38p=leNiN!m;*Mp>BWrOg zBnjx)QZpl1ydGQ%By(=df7R_I4oNO=D#lp=6pxiw^z<TBw&D4*J&czDn@VVA^p_EY zM^W^f8*nj*@itoyHZjj}=2FC_u^(Fwpo)RWO-L*R{-oo3*6kuWmx@}b;NyvCdxt}O zn`KFt?O&j5{e4GeYqqXtS<i%0$88J;g$@mU2!!|>&D~FBOBpZs3ob?ezyzW#{JzIW z716z()UU(U4p+dsLH-VDoIrhy@h&M1!k{T7?S|b%emF8`N-DPC&>2Y2O<e)v3k$GV zf%XDA=AfG@PRR!J?&$Hy;*Z1|e7vgvDV!gpmSs5C;Q44eM%3-pwXru_Ml9)Jx(8eO z!e|&>;r-{>R<!Bk`Pm5q-+d4snOmV-;U-{D9Llfv^_4$7hk7D^y*=m}=-ter{3r;R zoHeD1o}oFKB01NQ8jqH@wg^y;Kzw*&LIL7a_D`;ie~Of2q>A^P@>z<pjX_WxMLc?F z7;?NT>_3GpjTXHTWNC%93=`%t5gh85gTKbs;Q&&Aktn;_#Kw8(@v8qQ%1a@U6H_6n zyVcQ7_YE4P{peUUqeZIgEK5=c83B-Sh|$^vZU@KYWNFcD<Xr4#wBX0cnD8E{ftm(- z7zysXbLoj>U51?kA4vW|bE4Yhx3qf{65~V?o6TOZSl$iyO_=6L=g3Hb>Yjkne4QFI zKsrpHvd}<|Z8$L-%E?93IfBm*K@f9LaDz(xKUv-;_djkbx)S9heM}E^lI21;`*TfH zBIm5|5nLqwW)Dy-X!$BnpBIT5#6wMA=t=OS5e5*~q<_>MYA7@wAZ5Bl?OomjsQ+j{ z5la&CftmXQl)!qE(~`_2E-vpn)dHOm7M&e@NV2{duAGq5E!i``1@|NVI=HG1WLH0m zeZiXvv$!nk&{qfVKXuL_i;j@R4=j<(iDVR6)ZLM#@|5;t6=lMUS3pFJIWwc!u?|y# zVu+ej0f@H~W(pG474RU}65pih?NOwdbR-6Mt(e9kjzt-#xkK<D^MeM*Fdn=9qa!Y1 z_bDdCiCER=x}@T;GC=NAyNz-+v7S~FbF%+#E~!l9Grt33?))7E*2N$A=w`LH-xq|+ zyxmleGG@o_Lk5u(y2TU-Ax@b)V3*co-`K;9hXV!GM=v#H&yQcpDq*Z1Al$l=_DN3w zx&eRzjo4#@`vQiHAQLw;CDi<6tR5a2eDhsFu3X({=%+PWf<zrK3H>scFrZo&`%TnR zLlX(6v&Vt|?deHrqVk`5wQ>`q61X|2svA`)6$U^G6iGz3vq@mx95c~Ig7M*SlhfWQ zo(vTnk_IQRnoUPX^aNqCH(Umj-b2n?kg~GFgYvHI(AAk^j9jelGf&;}vg*<73=;So zkLZ{|aZ7P#T!|k?%MYTdWk}pvhJHx!#$R5J^A(<0KeyRojzdXheu?w)(4zM|V;8+- z%064eA+d2holl4}smwKG+JTrTjTWJg?VP4=g*Pm#f)n}JKEoO@k=|g3sZ%vXG&e;H z_g0dOA+!2W*3k3NRmPrL9225!R!ou~TK}pV&KolNYJh$toCNfm(pWX6Gg$TWhRvUG zj;M!Zg<A9^Rxs9O=-$+v(rDKaHvu+3aNEE$0-xjW^U$t$PdWA)4_LnrsZYw=54C#p zJglPi6j!JHcjFGoS31phgDB!+5xYgiL>WxLoJw>~W!3#KL7zHxKs=9-u;L?$%)}!l ziHAUW^F9=4ZUEXu_Y9n{$o{rU(jubEZCv-zqX^S<AxfeqPJ@giHZ=iN@$@Ere~5zL z1oxQ2wVyrVDPP0?J?W&v;BDq7tZNm6d>vC72NYUavS99!fI7@b%V{%k^5$0I5A1Hd z0=vPTvUdns#r;^m(&^vn4svkUp*lcUk&eD*D8oo9e-X|YXj+J~LeRbvDe_nmN@<uk zM0=8pIPry`aLj+=8PSqUQM~*lR4?RXYj?a2e@q3(NNzG5)$B2xCi7wUU?BD@#=mrR zT`i;fS?hnHfW+G1Rgd^EYZB2ymI{@JzqDsa2<K?`5nfm)bs2yTwnpl2mtVD5Au{mi zDI{-P2{vhvy9JJ~V?#w<(i6YzA6}^F`1AWBiWo*5+eUt)WK>03Eu9aq-1?wgap<n} zDrj&A5HWzg&ts}H-D3QJe00jwQ(KZbsbgz*Dy>@C*M~4?L1_ci^+|d9q?C2bZwNuh zZo%8Qrg_;rX>h?w7DA*F7wxwufXdWxudz=nb#Am7krg|gG&q;@=RD10Fj$z;Q^9cn zwpf;EoB4fLYV~iM=<f)%RYZ1Lm^e0U<8~I%IDJRez`xp_Iw=1d6|E?-e|~Y>M|ltI z7MhzmdcdpkQ$EB%EMx1)ckX+a)iz2hPO|ihv&(Hf!i-BL`}@izNsv0W+m6pOjSZk_ zS0p4$2*zqdMgn#lzwpCoSE2@3$$M7}{v|Q{_XRy<&j{QDP6WO{fNiN%ceB<g<-yMY zk}mRBztEw(buAMsBF_xZ(^g++(vTdUV!{oupJC4qdIE?oBuuzFHn_uP+zp6vtm+Y` z_KJ{j=+^erur)w=c+luix91100OBdNsegjnJBQ5Hdr&rnHsY1VD!V8s8pE`>qEY~K zv9L!jtm0^XFvsI75GT}~em~REz!P7N%&05ZT%Halj6Bj<VTTgddqKyqj}~U*!{Iwm z`qWI4hL8)*Eh3nSyZm@4$8vVCLfCU-az7maZM^y%>IZ{&>qxud9&w@{9=XzSpqxhl z)Uey~2!~C(k)1drG3*dVqw+(qY0H+>z;@8GbrI2?T?tNn%TAT#C1_`Yc|#Sb?@u%? zhyWu6^L6pR8W%s`bv4?}P#2L{o)yaxQrSF+KbNj=ON^Le7<xLM`Z3G<Mf0-*U6za` zF+VGE+N@QT<tt2BAPF*6*V@BCQ3uUTNpZ5(TSgC}=MJ|3Q|mBYDxlw`rV8B|8Np-a zW>LjLrTN1EHS453o<M%)ZA;gP(UnC4oj!Zbj!GnZOoMbYVAEtnrKBuWIrt-)SAz4> z)lo~H8y{Xgp`sLQ^#~g1>WgHuhHC?Dzjxjqb>tG%?@2~(w3EQ7SRXPTA2hi#HGNl( z6}kWsEKC{Y!ZXf}vuawx^EfSaXb<33nCE2zhjiBIxR6~hSEc{3_&1cY8_g|Z2q5<+ z;ydU4-3N;m^{ZaAEJm4vKd3+D3Z)=OMBoQNWVxJHNJ2HfXyKY%4)7;slVmeNXb|&w zTeV_3lkBMtKMFaQw2ni%W1TG|R7PE_SbV0G-&>QQmB-v);heD<5J)KtZ3zLE6;P=; zap;*kdAKpoH_O6L!o)bOS*RFmir%TbclhYOOe2&~UZUO0i=&#P%su$Zv3qWQn0mGB z5`Kh`Ge>GCh$LF(-_IubJ8f|r#KvT!=Pf_IV8c0cr7e=pxTC@7bDEVxAIr(4iOZ8n zNSebQ^g?yYRb}X-dTJDMy!YDFHE6T3yHDuXSbQ&)gs+kq<k-qt*>vIV4;uwH9U`?X zp(zgOzFm{Z6zEixw>?z>j#vGUHgstLeiVU#-3s$Khbj9P5aAC6HpB?$M?iw48OZ|2 zm0mw~!klGyDr({Un_7O{I;)gq&#(fB$@~JB+r3nqELYa>=gNhoBrhD6oe3K|Q7%#) z4aa)KnYEN}v2fNXitxslsRq%%-^o8^sYfyEC8)(E%oQ|h>IWto%Kc~-veNt_+h~w< z2u6ESG2-kC1kYql-8IGEI!@dIx_aUz0*VNyb)6)f5b4I7AW#m6hzZ*PjDP0=C9zuw zx2jhFOF<MzP;!Z`pH!7Ih)EOxpqzu@d|g-?AjSxzh_3hcM|$-s2vaqA@7ZT9`=Kb- z^&~LCj^M7GE?*@69GT71fYGE+=-U)O6_cR61a}=FsvINX5k6eYU)LTDE;-X)(^_BM zl?g45^0v>gxZLyYe1DayZi>HBe7I(RLTKDYLBz;16gEr<agADyFWLQd_DFcQeHGTs zh{@26kt_guK-bY|(ns^+pe53|0(i^PR!<~_*fEf@L7UF#gpf;oF&H1jBV?ELfEwI* zkRxNNjx-nHTRtdtcKJXeBIwmQ375EK&$D$U;m*n9=y*iQZei1Y%ViFHQ7_?GPE`%w zgI$&=r-asR-l3V~D7WBv`4q8+ir8;OaFiF1lw^!GQeP^~%Pn^Ou6%x|zh<h83-yvy zP|PC=yJU5-?;x!ThSnyYyBT*I0Q7h+PTMoCwwY{{lKs2@c1ydC_j2gGIiG`#Hv@*k zIP~Us7;f%TYFrCYG1N6qGb)amsoOW6u1=2=khKQ2voTj~-Yy8b4sxRKMdzSI!ma{0 z$^A~}>Ox$@&BaVH2u#L(j>c9qW$#vq#5zJk6^U=N{Ck1B7`&Cw2i{n3Q=i>vUsImH z0Hm7HDs{omy7q=$I!qaH4^W4Gg8D-p&0d7RS#yNkv$|YMkhb<NLc732wq8Fg>8Or| z0ePkfC}@l4z=$#_s&vplLXwMZEhp|EOtt|oi0siZfoo=`7=N6neQ$-$aZ5B!t?5~K zW~tTY2w3Q_Z#^uoQpt%c7+l9e4V(iJAk_YA`xR-B6CF@|@@05MCB=2(Z#La-&R&J* zTQI6VCuDJmtN~`i)m9T+WYlM4lFi`wh-{L16nCPEljlgrZ+yirP3S-+Z;nww&wJ~N zmJO4%aZ)=6XWxn@nLf9EIEe1;uP}1+DoMq8^~5yw?C-EucN8S`f>?97Ae1ex)Ej^S zOGBEQ8hik{G=3k!I;{ev>!xoI_=3JFQSvXwhMI5&tXHGS)gJvz^ZrWX0m%xLS}`U3 zq^5PEI_s!xFQtYX;e?TRKb&82oifW7an5%jvYyvoF^-Y?NhHRd8ta_$gPd?z=(8O{ zvyj{_@WA4Rn5vp>9fiFvOO9^e-Q}s7=LCRkL24@P{&ZHBsa2^-V|N&%!l~OiYY0Lt z4hX<wmw|s`4L7w{06$~rQ_CMI-Yk&D<u0oTA*R9*mixOx%0i-de9^7xe)Ck8OJUQ5 z54)bA7CA^|0WAa)n^HRkhH_LF#KC<TZLH0OllCg@yAQ&z7USfoKXghrV_>Ss;Jsqm z5#pjWw3S@qh=qvLK)xKx1!8(r7GP(=H9g!Smis#F2AIJIbGVs0TpZGuAyWmQ;TrN! zONQL_<&Tv+xE|NtW*=`q-Q+(px<n7%+xO0VwKb8)pLhNJD@7L%s++Hey`f|0g^xBv zuNJIvU!r+a;-a=#xwwK}b`_ilOvq;FHDph~Swo#!zt#*Q#K?~DJhlNhZD53Wlc`V= z(QLxpYsqwU7j#cTG?^_&ZgG%NhEAxj_=!=00GjU8;#!`jPaRF!1V91q(8Zhqo=`i7 zpeyg_DcFn9IJ-X3ZbTufKC|*C+9{G+K=O4NuU}e|yztoa&cmN8;C#x`pcelHox-?} z4i0XAqL^&h)4u1lR5F1KgDnFgz)y=TFYkv;>*~w&yFCBc?K@T+6k?^N749E>qw4az z8Z0rJ^g`(@Hr>K(Ico3Mspe1sI&1g_Ul$ie=0s(^VV|}FKkuwoYSweYY9GegU81~e zv{I=H);;`@n=JjStmkXuqGqo<4>kvqd`ehgx@-Un(E1lMT(o2)ZH593PdAToKSyS9 z^B1VIifmVWFdX2Yi;z`5y-9>f&TY->M4$4V*KQZ6o+YOvG0cCwcZUsCIXFu1P|df( zm^X==T6W$vyffF%tvK<TE=OfeuUn_k$kh^~l?9qs=X;5VlHhm_QDF}^gXP$fR;RLK z<;T7U*{t<DKp;a$wb3U;7@m4#r;po(<iEmPC@>%)bsg*zKjal2-yazRL?P2>`UioH zEx!wBO^A=Tq#Bb7%s0H?n*2xX?4H1?;8|5(mc^aayh^c%dJ_V7HWh4C=NgU+CnKtA z2&*Pp{*Dxh7!wbG@g2?{bHf7XloP=Sy?oOkTzk`>$@d|g0e@-9-JGx~<cZT&6kMD) zr~?QY8sTPh{Mx$<1_kEeJ=>l5756~^wpcMN>XS$8&-F=H8&^zsR}xygiM0Xms7aXA zq3FSP7PWuIRT=YK3_qfDFWSErt&|OW$A4I%dHW_<;5o=OQN!3P;T*Y{=e_`#TTEnD zQ*`gTF+*<4R$>3-PKWN#e3yDEIo^k-5LPZp;mS+QLzUtq3#T434Ep5~!T1pJg<8r2 zg6bsO+xLJ*zJ7$Dh+8eCQ`*h_5%t?%gQkF$$k}TN&|X@Sv?IBtV?(d=rOl)!4a!QH zG}WqiLBnbbZ(Ld0wEw!prM{70s2RGeZ+XAJ!rBt)A3&C+mbg?X-JW)-%sF=}q_JGe ze<Wi7wzbIkp$rnAI{?os@@-d}(P1o#c1*Apr0m1t(`P4)?YWkneeJZD&vh|}t_d<I z^-r#q!bxOsJgq33F|~@j_QXCnAqR?z)DJA|gmWdi8%((W6+?y4+I!*f3lZ&Y6|IH4 z0oNBQdVI@td;tfPvSoynLj~IhP9<u#mz1mkDM>g$J|8Q7ZmRf>n5pXvXv*$-Rvq*= zJ)QNuJD<u;AWYSniyRccZZ{cM#!A8I6YmGko^0iAj~Q6urAT)KSi|dbZc)%FUNfuN zGOsjIix7-IMx}+1jF_{Yd`-Aw;cCR!y(6$Wdm6~;V07qG@iA;g>Fa8DWr;aV)Z;sc z(H$krso3L2ZB1yGsu_beD6Hl?X|rD~sjH%cwMh@&U2?KB>;?vRax6hzNnnE89+WfF z=R><i?AePH>Tr&@1fX%W>V#R%;;Mv}#Z6dU)C^WP?@a^$=E`V>*uB<HB^R4MS^`3| z*VGNCv7mIV^1ef$WlA+S!ifBYNrA_HaMK`_Bfg>27^h$&u4txgAWv8<h_$_?Tiq(W zzasI<TACkJFZPjq#}2>pv3>n9EJ!5cpJjf4&<8*b&6)q5zYYjFSYhKs{bL5zV@@3M zJ^D=4nS^@Wlvpc2=95Td1Go{!Ux__DiWNbUKe<*m8DW|;xSLK)Ge(@D8Eu?&lSxWt zV;c2*5aS{Q-FMPSc4Ro-0<Z>TJZ(5Q?2N}7AvKf&)*XG2^w|xS29;IuOjC%afQ2au zG?&iMp4$hifE(>bUs#c8b@Iw)mQq7i$&|Wjr-$LA%PqTthiw~YtE}9TEqB&XSY48s z?{pvFB@A2e<-v(<`a9VylvxwPB###QMV2tJooSePY#9B*i>Ue(qlgE5pXJ2M5{69+ zEP_czY2G<Aw2dAPp9iyoqTceV?ePZ-Q>a^J@BLGk>#_SEyTIdyMo&k>nnt-6adn>x zFxl=Rev@LpQ<wlf<r+C*3E!ez;J`u0{@vIlP)kOWxF4<F9tUHtMTSKjQTvt`qDE$V zyV_-Q;1u-96+^(GSS9vwS0gfi9K`R!r1~)8ojXnT&*3{-vy)#pE8E~^|Dm<{30~-r zZ^Zo6Hid)Pj!c*klZTltA9TrW7(z}a?ER4Y!fpHhTWEwnh^O^HZrE=I+^EwdeU>lw z^eOY!G#Zn;d*1vXw%4b(JthS9uhr{216y7{^q6UoLqA*ufyQ?Lx~P$pM`vcd=-o&E zwh=>4&)<JnNZ;IsD)n3*l#Vy;9<ogj>T}}3n4K7KzB6}R(q0<U6AjQ!oz8y^9y#2k z2OPtU3?=$Sjkv{Q#JCsj_u`feVyN?5VfheeggqUadwc!5kD^&@&A}gzXN8tF&l^2L zIEBsCabJ!6;b0yd-A{67&w;ZQeI?33R<rBEnjU5T(`bj^w9C5#XU+l_yBIcZ9qx>< zCSC}?T3Wcy2TdcG{y94ufEU3o9psH2W#`eF7NgHqZ~SQT5S{>D{ryujh)!>1eiM2d z+WI(8wqfj<aFWjBTci+t*~sB^{<9Mm)+)@Xn+a2zE8030d46X=pMlw9X3RNEpIGly z(yMEPB=HuSiw_lh=tb?p`E^QEeI6yOpVaS#$W@o5OTwT8_{LrEZc!>*gn!_67N!c` z6UQwxHQJBXz8mcNk2^;C!j|Ve9E83(alU5?B)YX{Mj9nfQ1j%qR?*o%+W)yv9S4@9 zU276Cb!FhrHK2FqhA6o4=mm_>ogF9n{fN*hv3o{t%D?%S06(F@1q>3R9E-~!e_cgl z)27?nj1NV`i7&l=Z5!qUc#wJV*DmzQxt9$mCc>ghJ7{xrl!5~DU!u40>{Yz79dk-` z0CAmdY>At0d!O~ekiPRTyUW4Jy10{Ecr1Eiam{wh`q6flv!OdmJ$c$Z7vpGbE8f3= zfpwc7p1F{1=+oBT&0_eoJSky!T67ZK6N>2BYf`%9&D(^%CULLhiD;JZ?eBj{@+Fky zNS)vV00e0N&(w&_|CJi?4{`;dC?X&%Bhsv8<Fq*z|6{Fs&nI19Lr6i8k9L}%b9>E^ zB)s_~Ss<u**`{4nNkC6*0E~_a9BxR-_mgvz4#+Rr#O9`}Vks0Dlyj4FQ>s_u<AbAZ zN9x!6j~5|f|8eSisd<t++)VwqSQG31<>5<E`{cfRVp#h$aJ5AX&9iy@aJT_JY(Jj; z`+gM9(~OMF%<%Hq6$(m>ZLxpaSuppPyyigOM09?1d<2;i#pt;>$|<>`ivGzx4W&J1 zqAuJ;boVw&o1CB#yf;mdG~%gO+DT^y(IiC^&7mbvtk>8xJL1u?zlikMviLF3wFgrd z+LjdfgI#Atl=z-H^<8xDkXua>ori9PQH?JmnpT9IDZY}NRRni-LNKBYA2!Bi$F`XB z?<tn2qA7wikbp@3!xA{pDP67I4Sos9ucirQYD61op#wN;)tew@eSw&1IU&R5omXvm zY{a2Z*8=`*!4I)=)NVaXOy6Dr`=b_zqfUSmM-u3L4petRYfRsrD8GjOd^Z|5i4To2 z@j+BM?K31HjR2fr%^@)Y6NzNuiOGUZYn^fzmh5iSO-X^@qi)w_?C5vq`Dbojle*<s z#Z58^a%m+om=1W-WYwC#jryv-_dOWh(`=a9;JKIK_p-ewQ=0Tp<-GdSu#F!#j_#Ju z^XS2gtv6Q&G!Ox)q{ndrYVJbKDwvi<MgE{T3ZpFa5$g4dR~D6Yu{2?Q(ktXC7A3k1 zaS^z|<nPKk38z+Fn|rb9sT^TWq%@jN{frU1On!u6XY;LoXWbe7+27wU1!)xJ;vpMC zAren|ZO`BLN2Ie)?aaUx-PaIy4lW*^>ug@WcPq6mnGf$gT_&``&DX)qRYTk$`2wMJ z_IbftPly<ja}oRIy18~9s1KQweMHZ?2R7@VCUi@~NMQvy&}#82u&a?<vc>*pbhsa1 zHf*?>>R70UPG0KU>aNrS-kC^5NNJLnu|1O&g8eFJs_w<TsF_?oV4tD=%}KqxyChs% zKw3(^hbL-bjASHOmNWO<xA+|np8HYr)LKWKGkLP1n|4T&sI_k(0S84O(rjz}k;MGI z#hq9))g$zk4U$W@N!5)sba^4M4cn0RKt}_%7n_qFPZ?n@d5A-w!c}?Son}Z^s0|v& zE-#aCat}x$d;%fOP${}Ug?7KL;<FHyNyegY0HJJ)_h%0`hMd^jbFWr#N9y1Jjm(XK zHrEI|2eqooHPls-WsoBjW{4RL6R<;d@Gz=E+56i~hDmu<`M3oTAJ?cknaPlc9@Ydg z(1BV0=K+JW(97;d)d&o0>575WXXLS-RO!HU8`a6tpkSr(Arct#@wu1W`R;cwT~UeQ zPn_JnsJ$bh($&3n0Q{RS=kl?;uGRT^{fLUff4#6|NU^Nd%I13A2~Jh3?W<OS*M^GG zcce?cD=UALAZ-swg_8;2h#x1?^N9K7M7I`Jz}m0{edZutVUaALKg;vgRw2PBiQmF- zx$0*0HL^9b`cb$xn>MSZOV*kbZKqO;Mio9i;G`^6!bI?^jP_=bQ3Xeh--g7)QsSb8 zUdmGA<WfYkhK5Igczpqty#Fn)?!~Uff*bSn^39hQy&9M#0k)AlGq$W$7K%-_2KUdu zxnpgf*{*7#0eYTK5iVl760)6uUbF1kn=53hUU~xxr!CKkN|GwNGtk09=Z4DA;X_zk zN3YVfN_=6=C$7}Ow^3K-Oem7Y^Yv}hY|z||U>-1OjT=e`u!E~(wB|i8?T3@;Hq>Wh z3yUthhGV#?`O`@th$6x7_kNuWtN1atU(4-+CvT5(&Z0BlnBYpW<C6i!1;;bcrcM63 zZ~iv_^4W>51|7<^bAol@0Z-BRPia6PCrb*|iobZ^^On(#vGdE;09faPB1D4g_(onw z%4Rl0ibqk0f&awM<UfmtkvN#?RR=mw-R<*J1f{IP!{$M%N1&P1v;g#V{DqOI2ZDsZ zz{lt9N0DXIHRg1ix0jM@-&sMTFGJ-i=qppp65za#o_rbF9Ivi_>2KiKNzU85Ue}+q z8iKJ}q+Kn$`YVHJX&|JJ=hpwez1PLo<sm}WXk_GR+p1HE;cB|i5jZqbAPG2PjJs}r zn>=-agv;lKEbfKaDcnF24Kd_(8pg<gq6_da7Db1EKniUjE_Bu(GQ&8G@lm}JoeTPh zhx$#d_kPa7z|Cz3nVJ_xAOq}*w7=9GH3yW{0Tj8`_zgqCFZF=}N@$3&@3H<vhg3ht zNlUcObb<fsPN&-GhGkWvVAc3R9(fK~qX8jo7!hUIP=l()NO@i$EePgv3!CACJIFRJ zl21#3IJgEJkA{vdFNluUyQ8)Tzyf_surc@FL+;IxBvoiQ>P$js+|iDrswloMc@znC z_83JAbIjIjbji_1y#<${FI86R$2*dkz2|5B=~^_9a1byCT0@C&atDDT2w$P+z+iE2 z%~;p%N*yl5SF)l#foFz|^*v|^MuK9b%oTR$(VWi=kk$lE_E4;>;+5yr9zb(=+yB>y zwy-d;uL>GyJ!892@<A!<!ze-0_n=H4hwtyhNa#b8?(PSnIQwEp@e0zve-dC$o=&~e zlP;bP!}#uAnLfX-jNseQ?b&(|TVXZ{R|PRdRE?Oxj9IBduva=nI-6Z~`UO#%69sN* z<?6P6zI1*!XgF!>A7AN^cVcmG-ak{@l$|t4L*9P6;#+xk>^hGAGP^-gY{Do%5!+!L z!(Xf3M)dOWJloIizGxbk%>3dpseT_^p`44Jv=c*pXJaIq<d05R4cnazC;;0UE96}m z`)$szVKeZ@D{&XkXg_mbudN^(n3Rp>Bzb65Z;Kt&jY+vobz)yPQuMy8H{RCfEAuKt zGA_%;nQFNJ2qr6Zz`JnB>^}_E`1Hs%5te{>#x}G%cdK!=o9!Jd_1gXOA1ef=6^9tp z1)(jEzfhOsl3-qDU&fEc8~?W5B#v2`Rj5<7jn-&?Dl4t$H0t7464VenHAx+KRfblH z)=tAp9o@Z=$WAI7n{W<l5ZO#x5R?v!q?`F(kL!l9Ba|nk-(OOU{Ui46+;feAhIdRJ z$ct%>zO4mAOneR4N6ew3LQlie4e{<PhpPE|jR5T<wyP)(?!9dIFqe6Qgrp|5DhZVo z;ZOAcLV)tf6c~E!y`9^h>dL>jiZjDA71ZS@Mht<gmjgo_s!8B4CE_;A1pDv|gIYb6 zGm98q>(UOu_k#ivXWHRY%sqN#PBIM~id7)P5@VJKvp~9E9?X^3&efseee{^nc}d4b zpJ7q{O)^F@f-1K@J#U`P`Nky(#k7R`PUwiWz(ku3Rzr|D^hyDM+?2BnSHFK=#@7a= zV-%^jPF+}L=dyYgt-$st;;>eVkUD2Fd#xE4({}3>AQW5R5vm?}ftn=qpnIE6)k=B4 zdgZSM0n)DcWLw*{cpZ2#v2zN^(iTBdwyC+w?{Lq2uC;VCq0r{X3KP>ABH!fbankxh zy&m{7YyYWgNZp-q?di0wikwi<?t}O#FUdq%EeK^+=0O3)b;=$+9z{a*RuM|AVeeE8 zDVmLID59mrkKjt}6%cw6q^SR~-justvS$7icI_@M+wJ$1_f~*1eIT)DaMmcHx-VAV zq9Djrg`+$wIlk9M*<Ubm+f{|*HfQX{jv572QGidRiKCoj{vngNV0-`Tg=nqV>W^5v z6KGeUU5jz*;^0FCW;csNXK1(e#m0DDn*8PWYt_02|2bg)o3BAq_Gdg6v6>I-rvHcU z^UvC;#_~qlrRmP%w=~}H?17aEtHaj%1+cskO}=iQL%#HV0_9AuS%mgaf2#Xe^`W{w z4X&-q)MVCY$5uJHeK1FHPxOwN8b9z$3aDul^<R`1t=iRq<iaT+{k!_!A9m7~nCovF z6v~R673l<rluB{M!XWAD03YMgSONy~)|u9whu5w(2IZ|n|8xVBs3hmXZ1xJ@Et&*B zid2SYqYWC6`hKA@RaHif*L3$pE?r%kvX=tiP0aP1EJWZ54;-DdAX@}eWpw2)XB*~L zDf<SJSEoe9`{7T4+jl@IS?vr>Psc)6E17R!$oL;Yrh<k5XS?eoy8iN8nU2mer5@r! zs4B75aj~u4ca@WR+Gz79^h(}LoAQAvBPHi*{pB+L&S$L7T)<>htWf_MS+>SSn^sOe zn<3Y?wd)MOv5`mqsO7B}nYP9cW2I+@)1UE@?pr;~RU2hvmG6!2=dJw@)y9tex<Ro( z9Eer2%tacGUA?<zl=j?wse4%;0i#ijk;2Z$%KoEib7q{KE>~Q^y7WhwYE2^KOvQFp za#$XcnR?*j^g4p7=spWTrA(W)(xI25+7F<8QPQq*c}t6m9wTVFtvuqn@=nsaSw|CR z#g37VAW$!r1BZUbWs=aU;Ka_&&3X5Ya@GtAW8(lDSy+o_D1%<-9fcum!hlWYO+79f zrO5)c!pLU;uFXZXXxs7!+4GG&88Kf1(iPmV?I>r=F?Qb2qtq;aLn*i6b8-5aE_gD& ztgNhsLcMoc^SDz^KLHhb9<Q)RcKRBOns_pp_p5Gp6|+^-F$2Uw{Gb>gH|_IPs^X3e zneuSL!7SY^TsXUawKokEQ!yo3iUs?lBaIL-3uemnKMv(e5JXw(lvj!Efpqo;K}L6< zi0P(^H>`Ccy6Pv+gBcrTLgI}q(|z{p+il?Yrp)QG!UWsVo;sF>Vyw9A#0(vaUQWjg z((A^$A~Wu7y>goI3dE?);e*&4QMsGnZ!I9uWl_gg>R~v<_CL~1dl)mXL^iuTMIQLG zFnZJVT^D25Ka{KG-_hDWpBL-6maCkDvRJz`&ZNH?qEW)X7m`~sVZE@mV6}gc7&;Jo zXz;$`-8tX*e?IT`?Ebg_|MCwZgfQ@h@*lzSzP)|l_h}#l850U^tR+^_#Mudb>1g}V z7_e2Q&Z}u|ka)5HKLdFh8<aJu;z3|-?{grV))$>5kgFP3yfErP%#THc9Pnoyo_UOf zvtd-8!Ti8w(BfTq2A``(P;{uY?Z2aNt1E4j1hSk*+WPr54^me)O(b237(RBCDE*G) z61tYlHVX);V9%!G0`sMnY<H8KZy1_kv0~zBbJo_}klJCkC`_}v1B9s2p@I`qgXpO? zQjXU{FCUz=IV!>R{S38wCx-{n!bI7(7?|l}o(B|E0JbEl7_mvsGQ)J-(PJvrb37P1 z_wHEhFge8t4-&{2qyAyb2pd8tvX=FlgLnxzEW<4TAX<tjG-{%atqrh8LYbb2iVSfO zy}gyj#a0!#JXc8P3>{DJQ4`}%=4TE^-HvRB;_Mg~g<nCQ9nLR-Ky1fvBKi0<_tIW3 z?b#QQjIVbX)Ren64mK^)R#^*B#6z;$BEWQ!M*gX589WG?vSw_@k?V@K4>bOZHk+IK z1-hSmYvg3L;^<|fYnl$@he~*zw#5*JcWcv3|LjYbzLr1Tki8A&13NYb9;r=+(khnY zhn9GLdlWW4Uha;ZHY`C>3pI18Z5Ejt8&spWVy1%$yQTeF`oMIjh{C<7GD=FRFffa2 z`NfQ1m=x(@#p1;2;GubA78ZEYmNW|O6^>k^FWll{%jC0v0R4x%to5P^vFSY;u9{~< zMB5TQd%@2U*Re_MB{<GjJ7M|Elqw2O!zuHzO?X;>2U7@@(P-Tpzm#~z!Is*w!H9ue z^WB}WL+g<g3DXm(p$f5^K#_T?ufJ1ut@W!PQeEZ++b#%--Bf+xC*3g)bzCNSY5)VO zyTJmH#@K4O1_K8AN(?)<$s*&!d?TRx+1EcPiFH1P=|W&95zy)Au5rfjbfP!@tV;eu zedV1t;ARuDec6CMnBBJ{aJkOKXSuwTmpbkG57zwX`vy||JBmV~zl;kFMPUSV3Fe(8 zWjb^Fa$JefRe|eEpdfOMlNx{TKuDAFn+Cf&z{Dt_EUuDhfJ9=vFKPG<T=<UQWf`XV z>!FPDEGSn*n8VrWd_QGSDS`L*4sz@UiSPNo0tpr5@#OsQQTR;7;M_v}yP!6Gb;TSb zF2)xLE?#HtYysoz{?_uBwUtvAkIN)$fc^MY3+!7%eh<Z1Mk;gk<p5+MhNGd?9Mux; zFz)X<mTZNA$&GNG9Z_<@{-3f%l>pW{`->}Qv7snq&hwJ{K)5E9dVKeSv3j@`vb0Li zVcABa@iN41Y-?pQ9fQW}thS}u$II_<Gu40qXsI5q^E`F~(1-RRis(>3)l4Cw-#-8D zfQZcGrojwVqA&-4Z|21VBxUOuY}Et54r=n}*o<pbJ~C^$q}jslk7LuP8_}%Y?i}mY zr>G_7ZPN^*X>a_k>hh10te&?RXclkQ3U)|gBh*MPe*966c&uc`&Rdm5KUgs)#YSsc zT2bb_^^jGF_M)ML6{S!>UW*Y7j6Q*j_$<zxEVf1ePDxeY8GG2OLilxC0+Wpl^rpg> z7LLB(EHIDi384$p55ea+h2tHTBKMix<VJE56)%uNkROM#n6`pWv5bk*CEI(4LHzSv zyfYXb5k)|E;2SbMNes}y1qc9UYc%#xHb;7Nm|qa5axJ5!atr5h#}%8x^7hAr`oqx| zmTc_)25}^=9+hS}EamGo1|A)y#rTI$MquBkGR#Oy6KjaGN6MUG5@{hwcqVwVdIIN) z)CSUUmCZz`a`3}&J24=Y*d1c%zWN_DNvNMcvPJN(^B|mhU#-n_f{2^U5BO2Dh2!$t zbA4!P1w=(V1I_(kd@upQn~{dNkga++Tg6Yam0A027SJATfuWlM$A146E7X$zfPF&( z09au8Ppl9S2pQl%@+<%VmH#VR2=QNM|FeS!_!jujQAR{rfJQ=A^dC0=KW4}P;QzM& zm|ZE%8F2l(;6F;5|Iu*ye~s*4_y04K5s;M-6;V>Al@a})1OM+Z<v;q&f4Bb(T=cJR z=V<odWB%V;{ofY<io*U+XXgSNMG?mFy$T^%gz{(&CB`Cc0~JaNSQRLt^dYT0j$U~s zV%**>?Un0o*}H3@ny4TN4bleXB^9egps_Ro1B6gi9*P195CnMy<)Ns&)QBPp68wL6 z*V~!h*}IFAT-cV(@B8MPZ@&3v)0>a!aX8$gvf3ZD7w-FKdfj4r)zokuKQ>sVZ&$yd zWs*@#k`yFy=vcGZx6s2`=o56$-nb`Y8q{3U4}}II-RYrF)O}K5{(MCX-QUO>n>1P7 zyZ^d@=yVI8LJsvkrp%;Cfyb?Q{ROheBUgBo$mNjfq2D|Fs;0Q?n(9<s0ZkE0?Dp?~ z!{bpc6JM~A@;QlBuwmR14YKmJO0hU?cV4e^5aY)HvpI47`@}EK%%*u*-b1@FHd&Hv zC}lgCW50lJ6`F^ldc6vBgPL(J0^=R!`-VzV{hN|RuCBL}83J4(-P0iZ6uKmsp2a%e zo>d;Gz#{k({z5lB=<Uih5mc!N2rNmXZM~iH_&aclJS=zK>sC5MB+ZR`oXkqm5`VdH za_eKbfG&U)n5k=or|NkERFTgq*D683^7&K?rq^9xxHkdu1zetatiqC6t}al#?go*b zG~}iAI}$tKtGn?%P~Ldw6#=u@t$1AQh(iHpD@g1hQQa!sC?uV93rN+j3TF<t?g=uh z&!qPI7@`B}@D9?w+7hDI8D=#Lg<FCa@4wivAB*Dv#yO%(vEaWmYb>F$eUH%VGD}xv zL*GvL-;*4=R<%TzOc(3<;N9d=GW0wSAit1rF0_Q%HKkTYOo~J*G5cKR4=uyNT?<8d z-)Zw%vda`-z~gr);kqsCYNo-jIGD3I7y4$I^c`9kn`ynMiG63##kx~qCz$lzTW`r0 z+92ei#>xo1hhAQ6!5qbTXd4t;p0o2(KMdFoXBy1Scyfa!L@&+8+K_NV67T$Z4S}l+ zr5Y$5&|BSWmN?zv(`S18np~*V%~rJq`I;K=a;r1621w3dt<#U6h03oYyzvX`(6Tt> zn4OBCYo@L_zX`VZ4I3T5uzqi}gvMT2gx=hdmQ8En81VeUy7jgtTC}hT_WZ_g&a8xG zH{$cOZecuaXtIP&Q~gw%U8zAjpm0_Vc@%+JR$Al-ig|A|TY}YEzgzXne9}X-OMeu< zcOL#e1l#uL2#p>-kApTvt#mtO&t%!_@(2<W5>Pa;to9Wc^%{&?zzMjwI<~q~DO1y3 z&#tN-n#)ibd$WVkit{vGbRU3o%)^L~J~Qpe+BgM96G3BY`DJ+NAvks(c8u|i07<%y z={993wC#)<8JU9Mm~;`vxc*h`s#I@Ws#kmNde{g_C6GkfyWUba#VLtwrnqz)nyp4d zYIiPJ>4w#2_m-q*bt!o2wIxnLbAtJj)zpxX34@Ndcft=+kxWeBgk0G6KZHcJ+~28R z|8oL<R|V_wLC&__QkH3BOP?hBomF;OlWW3PwHs$BtIv<QA0n8R<J7=!pwE38zZ~<V zkSn|ImLBba+7+iK8aL1}otEq<8z?c8hDZ;VVh+l%=y`pczm3hb-av`{#LZQM`-A%s z-kQnHulGAkwr~U0&#lc*O?fF7{?Zf2m^6-g=7NA3T3pI}!E90LnbkP@>?0}2v=K(B zP?6r|Ubdo%B7E?;Iko+>0r0S0_~hsyJhj~wu*|+y<aOCqw^xwq5Wc19=39GkB6vSf zl5l)s+Ms*!;LR>Y2G~EY+qE5VsU*a$G=?cj!%}SK&=tj*NXO#dwM*JDIjxu+UdN#$ zqtUG0h|V$TRd;`F0oB&axDO9|MnHAUm{O!^RtK0zPwl<F841YGI8pKg?mJEd^P_Aa zZNFyo(ST1Z+&b_q%$A5b=Z`MkiUhRaLC8#^K_-;!+D3<i5(Hhk6I^c@#RAeyzdL+& zZzuqT@`0cm>OGkkJCqNMEERwj$y|C#gpcMrx37o2Hz4+BF*He%EePQk7BNoVH<GSa z9sw@_#^TZzX@*^_S$Vx`ufpLw+HOS}5A4{PTL9`6eE2})pJ72>6pOiJMaqbS@Hkp? zycH51V&<HDok?k%d7??z^=Zl&q}39(QG*pSkQbSf1<cQ!d_6lLZhDTGEM0Hw*#Qf5 znzp$6@sjlc6nXukB!ou57LevGljMwV1g!oc&!z2xb+yoM={MxL^Sn0Z@=SKirG9KR zQ2tfsGOnNa1VjY3k{yB})6xR0WXuCoL)54TTYHM%Otv(z6j2R4Ba5vf!)rA5b(Teu z(<OW@MdM;i5Tr7rlB9i0SxRKj6>O8lVQ(1cgVR@yEXP#7z&I@Su2i~^TyNP;1`vBa zxe>!&E5?W2jx{XCe9bCLqHD<5zrsb9!n7kF*t#wyV>{7%Z1#0L!Zp)=`ob3eb6xw3 U-Gl#CDwRrGanesZjg=|=2jd3V-2eap diff --git a/src/helma/doc/DocApplication.java b/src/helma/doc/DocApplication.java index be1bbb38..c8e8c4de 100644 --- a/src/helma/doc/DocApplication.java +++ b/src/helma/doc/DocApplication.java @@ -1,98 +1,197 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.doc; import helma.framework.IPathElement; import helma.main.Server; +import helma.util.SystemProperties; import java.io.*; import java.util.*; -public class DocApplication extends DocDirElement { +/** + * + */ +public class DocApplication extends DocDirElement { + HashSet excluded; - public static void main (String args[]) { -// DocApplication app; -// app = new DocApplication (args[0], args[1]); -// app.readApplication (); + /** + * Creates a new DocApplication object. + * + * @param name ... + * @param location ... + * + * @throws DocException ... + */ + public DocApplication(String name, File location) throws DocException { + super(name, location, APPLICATION); + readProps(); + } -// DocPrototype el = DocPrototype.newInstance (new File(args[0])); -// el.readFiles (); + /** + * Creates a new DocApplication object. + * + * @param name ... + * @param appDir ... + * + * @throws DocException ... + */ + public DocApplication(String name, String appDir) throws DocException { + super(name, new File(appDir), APPLICATION); + readProps(); + } -// DocFunction func = DocFunction.newTemplate (new File(args[0])); -// DocFunction func = DocFunction.newAction (new File(args[0])); + /** + * + * + * @param args ... + */ + public static void main(String[] args) { + // DocApplication app; + // app = new DocApplication (args[0], args[1]); + // app.readApplication (); + // DocPrototype el = DocPrototype.newInstance (new File(args[0])); + // el.readFiles (); + // DocFunction func = DocFunction.newTemplate (new File(args[0])); + // DocFunction func = DocFunction.newAction (new File(args[0])); + DocFunction[] func = DocFunction.newFunctions(new File(args[0])); - DocFunction[] func = DocFunction.newFunctions (new File (args[0])); + // DocSkin skin = DocSkin.newInstance (new File (args[0])); + // System.out.println (func.getContent ()); + // System.out.println ("\n\n\ncomment = " + func.getComment ()); + } -// DocSkin skin = DocSkin.newInstance (new File (args[0])); -// System.out.println (func.getContent ()); -// System.out.println ("\n\n\ncomment = " + func.getComment ()); - } + /** + * reads the app.properties file and parses for helma.excludeDocs + */ + private void readProps() { + File propsFile = new File(location, "app.properties"); + SystemProperties serverProps = Server.getServer().getProperties(); + SystemProperties appProps = new SystemProperties(propsFile.getAbsolutePath(), + serverProps); + excluded = new HashSet(); + addExclude("cvs"); + addExclude(".docs"); - public DocApplication (String name, File location) throws DocException { - super (name, location, APPLICATION); - } + String excludeProps = appProps.getProperty("helma.excludeDocs"); - public DocApplication (String name, String appDir) throws DocException { - super (name, new File (appDir), APPLICATION); - } + if (excludeProps != null) { + StringTokenizer tok = new StringTokenizer(excludeProps, ","); + while (tok.hasMoreTokens()) { + String str = tok.nextToken().trim(); - /** - * reads all prototypes and files of the application - */ - public void readApplication () { - String arr[] = location.list (); - children.clear (); - for (int i=0; i<arr.length; i++) { - if (Util.isExcluded (arr[i])) - continue; - File f = new File (location.getAbsolutePath (), arr[i]); - if (!f.isDirectory ()) - continue; - try { - DocPrototype pt = DocPrototype.newInstance (f, this); - addChild (pt); - pt.readFiles (); - } catch (DocException e) { - debug ("Couldn't read prototype " + arr[i] + ": " + e.getMessage ()); - } - System.out.println (f); - } - for (Iterator i=children.values ().iterator (); i.hasNext ();) { - ((DocPrototype) i.next ()).checkInheritance (); - } - } + addExclude(str); + } + } + } - public DocElement[] listFunctions () { - Vector allFunctions = new Vector (); - for (Iterator i = children.values ().iterator (); i.hasNext ();) { - DocElement proto = (DocElement) i.next (); - allFunctions.addAll (proto.children.values ()); - } - Collections.sort (allFunctions, new DocComparator (DocComparator.BY_NAME, this)); - return (DocElement[]) allFunctions.toArray (new DocElement[allFunctions.size ()]); - } + /** + * + * + * @param str ... + */ + public void addExclude(String str) { + excluded.add(str.toLowerCase()); + } + /** + * + * + * @param str ... + * + * @return ... + */ + public boolean isExcluded(String str) { + return (excluded.contains(str.toLowerCase())); + } - /** - * from helma.framework.IPathElement, overridden with "api" - * to work in manage-application - */ - public String getElementName() { - return "api"; - } + /** + * reads all prototypes and files of the application + */ + public void readApplication() { + readProps(); + String[] arr = location.list(); - /** - * from helma.framework.IPathElement, overridden with - * Server.getServer() to work in manage-application - */ - public IPathElement getParentElement() { - Server s = helma.main.Server.getServer(); - return s.getChildElement(this.name); - } + children.clear(); + for (int i = 0; i < arr.length; i++) { + if (isExcluded(arr[i])) { + continue; + } + File f = new File(location.getAbsolutePath(), arr[i]); + + if (!f.isDirectory()) { + continue; + } + + try { + DocPrototype pt = DocPrototype.newInstance(f, this); + + addChild(pt); + pt.readFiles(); + } catch (DocException e) { + debug("Couldn't read prototype " + arr[i] + ": " + e.getMessage()); + } + + System.out.println(f); + } + + for (Iterator i = children.values().iterator(); i.hasNext();) { + ((DocPrototype) i.next()).checkInheritance(); + } + } + + /** + * + * + * @return ... + */ + public DocElement[] listFunctions() { + Vector allFunctions = new Vector(); + + for (Iterator i = children.values().iterator(); i.hasNext();) { + DocElement proto = (DocElement) i.next(); + + allFunctions.addAll(proto.children.values()); + } + + Collections.sort(allFunctions, new DocComparator(DocComparator.BY_NAME, this)); + + return (DocElement[]) allFunctions.toArray(new DocElement[allFunctions.size()]); + } + + /** + * from helma.framework.IPathElement, overridden with "api" + * to work in manage-application + */ + public String getElementName() { + return "api"; + } + + /** + * from helma.framework.IPathElement, overridden with + * Server.getServer() to work in manage-application + */ + public IPathElement getParentElement() { + Server s = helma.main.Server.getServer(); + + return s.getChildElement(this.name); + } } - - - - diff --git a/src/helma/doc/DocComparator.java b/src/helma/doc/DocComparator.java index bf94f0a7..ed0748fe 100644 --- a/src/helma/doc/DocComparator.java +++ b/src/helma/doc/DocComparator.java @@ -1,44 +1,88 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.doc; import java.util.Comparator; +/** + * + */ public class DocComparator implements Comparator { + public static final int BY_TYPE = 0; + public static final int BY_NAME = 1; + int mode; + DocElement docEl; - public static final int BY_TYPE = 0; - public static final int BY_NAME = 1; + /** + * Creates a new DocComparator object. + * + * @param mode ... + * @param docEl ... + */ + public DocComparator(int mode, DocElement docEl) { + this.mode = mode; + this.docEl = docEl; + } - int mode; - DocElement docEl; + /** + * Creates a new DocComparator object. + * + * @param docEl ... + */ + public DocComparator(DocElement docEl) { + this.mode = 0; + this.docEl = docEl; + } - public DocComparator(int mode, DocElement docEl) { - this.mode = mode; - this.docEl = docEl; - } + /** + * + * + * @param obj1 ... + * @param obj2 ... + * + * @return ... + */ + public int compare(Object obj1, Object obj2) { + DocElement e1 = (DocElement) obj1; + DocElement e2 = (DocElement) obj2; - public DocComparator(DocElement docEl) { - this.mode = 0; - this.docEl = docEl; - } + if ((mode == BY_TYPE) && (e1.getType() > e2.getType())) { + return 1; + } else if ((mode == BY_TYPE) && (e1.getType() < e2.getType())) { + return -1; + } else { + return e1.name.compareTo(e2.name); + } + } - public int compare(Object obj1, Object obj2) { - DocElement e1 = (DocElement)obj1; - DocElement e2 = (DocElement)obj2; - if (mode==BY_TYPE && e1.getType()>e2.getType()) - return 1; - else if (mode==BY_TYPE && e1.getType()<e2.getType()) - return -1; - else { - return e1.name.compareTo(e2.name); - } - } - - public boolean equals(Object obj) { - DocElement el = (DocElement) obj; - if (el.name.equals(docEl.name) && el.getType()==docEl.getType()) { - return true; - } else { - return false; - } - } + /** + * + * + * @param obj ... + * + * @return ... + */ + public boolean equals(Object obj) { + DocElement el = (DocElement) obj; + if (el.name.equals(docEl.name) && (el.getType() == docEl.getType())) { + return true; + } else { + return false; + } + } } diff --git a/src/helma/doc/DocDirElement.java b/src/helma/doc/DocDirElement.java index 90182182..71d26fe0 100644 --- a/src/helma/doc/DocDirElement.java +++ b/src/helma/doc/DocDirElement.java @@ -1,36 +1,53 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.doc; +import FESI.Parser.*; import java.io.*; import java.util.*; -import FESI.Parser.*; - +/** + * + */ public abstract class DocDirElement extends DocElement { + // a default file that is read as comment for applications + // and prototypes if found in their directories + public static final String[] DOCFILES = { + "doc.html", "doc.htm", "app.html", + "app.htm", "prototype.html", + "prototype.htm", "index.html", "index.htm" + }; - // a default file that is read as comment for applications - // and prototypes if found in their directories - public static final String[] DOCFILES = { - "doc.html", "doc.htm", - "app.html", "app.htm", - "prototype.html", "prototype.htm", - "index.html", "index.htm" - }; + protected DocDirElement(String name, File location, int type) { + super(name, location, type); + checkCommentFiles(); + } - protected DocDirElement (String name, File location, int type) { - super (name, location, type); - checkCommentFiles (); - } + private void checkCommentFiles() throws DocException { + for (int i = 0; i < DOCFILES.length; i++) { + File f = new File(location, DOCFILES[i]); - private void checkCommentFiles () throws DocException { - for (int i=0; i<DOCFILES.length; i++) { - File f = new File (location, DOCFILES[i]); - if (f.exists ()) { - String rawComment = readFile (f); - parseComment (rawComment); - return; - } - } - } + if (f.exists()) { + String rawComment = readFile(f); + parseComment(rawComment); + + return; + } + } + } } - diff --git a/src/helma/doc/DocElement.java b/src/helma/doc/DocElement.java index 151a77c7..1406a797 100644 --- a/src/helma/doc/DocElement.java +++ b/src/helma/doc/DocElement.java @@ -1,304 +1,403 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.doc; +import helma.framework.IPathElement; import java.io.*; import java.util.*; -import helma.framework.IPathElement; +/** + * + */ +public abstract class DocElement implements IPathElement { + public static final int APPLICATION = 0; + public static final int PROTOTYPE = 1; + public static final int ACTION = 2; + public static final int TEMPLATE = 3; + public static final int FUNCTION = 4; + public static final int MACRO = 5; + public static final int SKIN = 6; + public static final int PROPERTIES = 7; -public abstract class DocElement implements IPathElement { + // above constants are used as array indices + public static final String[] typeNames = { + "Application", "Prototype", "Action", + "Template", "Function", "Macro", "Skin", + "Properties" + }; - // identifiers of this element - String name; - int type; - File location; - DocElement parent = null; - Map children = new HashMap (); + // identifiers of this element + String name; + int type; + File location; + DocElement parent = null; + Map children = new HashMap(); - // content - String content = ""; - String comment = ""; - List tags = new Vector (); - List parameters = new Vector (); + // content + String content = ""; + String comment = ""; + List tags = new Vector(); + List parameters = new Vector(); - public static final int APPLICATION = 0; - public static final int PROTOTYPE = 1; - public static final int ACTION = 2; - public static final int TEMPLATE = 3; - public static final int FUNCTION = 4; - public static final int MACRO = 5; - public static final int SKIN = 6; - public static final int PROPERTIES = 7; + protected DocElement(String name, String location, int type) + throws DocException { + this(name, new File(location), type); + } - // above constants are used as array indices - public static final String[] typeNames = { - "Application", - "Prototype", - "Action", - "Template", - "Function", - "Macro", - "Skin", - "Properties" - }; + protected DocElement(String name, File location, int type) + throws DocException { + if (location.exists() == false) { + throw new DocException(name + " not found in " + location.toString()); + } - protected DocElement (String name, String location, int type) throws DocException { - this (name, new File (location), type); - } + this.name = name; + this.location = location; + this.type = type; + } - protected DocElement (String name, File location, int type) throws DocException { - if (location.exists()==false) - throw new DocException( name + " not found in " + location.toString ()); - this.name = name; - this.location = location; - this.type = type; - } + /** + * the simple name of the element + */ + public String getName() { + return name; + } - /** - * the simple name of the element - */ - public String getName() { - return name; - } + /** + * @return absolute path to location of element + * (directory for apps and prototypes, file for + * methods and properties files) + */ + public File getLocation() { + return location; + } - /** - * @return absolute path to location of element - * (directory for apps and prototypes, file for - * methods and properties files) - */ - public File getLocation() { - return location; - } + /** + * + * + * @return ... + */ + public int getType() { + return type; + } - public int getType() { - return type; - } + /** + * + * + * @return ... + */ + public String getTypeName() { + return typeNames[type]; + } - public String getTypeName () { - return typeNames [type]; - } + /** + * returns the comment string, empty string if no comment is set. + */ + public String getComment() { + return comment; + } + /** + * the actual content of the doc element (the function body, the properties + * list, the file list etc. + */ + public String getContent() { + return content; + } - /** - * returns the comment string, empty string if no comment is set. - */ - public String getComment () { - return comment; - } + /** + * + * + * @param rawContent ... + */ + public void addTag(String rawContent) { + if (tags == null) { + tags = new Vector(); + } + try { + DocTag tag = DocTag.parse(rawContent); - /** - * the actual content of the doc element (the function body, the properties - * list, the file list etc. - */ - public String getContent () { - return content; - } + tags.add(tag); + } catch (DocException doc) { + debug(doc.toString()); + } + } + /** + * list all tags + */ + public DocTag[] listTags() { + return (DocTag[]) tags.toArray(new DocTag[0]); + } - public void addTag (String rawContent) { - if (tags==null) { - tags = new Vector (); - } - try { - DocTag tag = DocTag.parse (rawContent); - tags.add (tag); - } catch (DocException doc) { - debug (doc.toString ()); - } - } + /** + * filter the tags according to DocTag.TYPE + */ + public DocTag[] listTags(int type) { + Vector retval = new Vector(); + for (int i = 0; i < tags.size(); i++) { + if (((DocTag) tags.get(i)).getType() == type) { + retval.add(tags.get(i)); + } + } - /** - * list all tags - */ - public DocTag[] listTags () { - return (DocTag[]) tags.toArray (new DocTag[0]); - } + return (DocTag[]) retval.toArray(); + } + /** + * + * + * @param param ... + * + * @return ... + */ + public boolean hasParameter(String param) { + return parameters.contains(param); + } - /** - * filter the tags according to DocTag.TYPE - */ - public DocTag[] listTags (int type) { - Vector retval = new Vector (); - for (int i=0; i<tags.size (); i++) { - if ( ((DocTag) tags.get (i)).getType() == type) - retval.add (tags.get (i)); - } - return (DocTag[]) retval.toArray (); - } + /** + * the list of parameters + */ + public String[] listParameters() { + return (String[]) parameters.toArray(new String[0]); + } + /** + * add a string to the parameters-list + */ + protected void addParameter(String param) { + parameters.add(param); + } - public boolean hasParameter (String param) { - return parameters.contains (param); - } + /** + * parse rawComment, render DocTags + */ + void parseComment(String rawComment) { + try { + StringTokenizer tok = new StringTokenizer(rawComment, "\n", true); + int BLANK = 0; + int TEXT = 1; + int TAGS = 2; + boolean lastEmpty = false; + int mode = BLANK; + StringBuffer buf = new StringBuffer(); - /** - * the list of parameters - */ - public String[] listParameters () { - return (String[]) parameters.toArray (new String[0]); - } + while (tok.hasMoreTokens()) { + String line = Util.chopDelimiters(tok.nextToken().trim()); + if ("".equals(line)) { + // if we've already had text, store that this line was empty + lastEmpty = (mode != BLANK) ? true : false; - /** - * add a string to the parameters-list - */ - protected void addParameter (String param) { - parameters.add (param); - } + continue; + } + // if we come here the first time, start with TEXT mode + mode = (mode == BLANK) ? TEXT : mode; - /** - * parse rawComment, render DocTags - */ - void parseComment (String rawComment) { - try { - StringTokenizer tok = new StringTokenizer (rawComment, "\n", true); - int BLANK = 0; - int TEXT = 1; - int TAGS = 2; - boolean lastEmpty = false; - int mode = BLANK; - StringBuffer buf = new StringBuffer (); - while (tok.hasMoreTokens ()) { - String line = Util.chopDelimiters (tok.nextToken ().trim ()); - if ("".equals(line)) { - // if we've already had text, store that this line was empty - lastEmpty = (mode!=BLANK) ? true : false; - continue; - } - // if we come here the first time, start with TEXT mode - mode = (mode==BLANK) ? TEXT : mode; - // check if we have a new tag - if (DocTag.isTagStart (line)) { - // if we appended to comment text until now, store that ... - if (mode==TEXT) - comment = buf.toString (); - // if we appended to a tag, store that ... - if (mode==TAGS) - addTag (buf.toString ()); - // reset buffer - buf = new StringBuffer (); - mode = TAGS; - } - // append to current buffer - if (lastEmpty==true) - buf.append ("\n"); - buf.append (line); - buf.append (" "); - lastEmpty = false; - } - // store the last element, if there was at least one element ... - if (mode==TEXT) - comment = buf.toString (); - else if (mode==TAGS) - addTag (buf.toString ()); - } catch (RuntimeException rt) { - debug ("parse error in " + location + ": " + rt.getMessage()); - } - } + // check if we have a new tag + if (DocTag.isTagStart(line)) { + // if we appended to comment text until now, store that ... + if (mode == TEXT) { + comment = buf.toString(); + } - /** - * utility: read a complete file into a string - */ - protected static String readFile (File file) { - try { - StringBuffer buf = new StringBuffer (); - BufferedReader in = new BufferedReader (new FileReader (file)); - String line = in.readLine (); - while(line!=null) { - buf.append (line+"\n"); - line = in.readLine (); - } - in.close (); - return buf.toString(); - } catch (IOException e) { - return (""); - } - } + // if we appended to a tag, store that ... + if (mode == TAGS) { + addTag(buf.toString()); + } + // reset buffer + buf = new StringBuffer(); + mode = TAGS; + } - public void setParent (DocElement parent) { - this.parent = parent; - } + // append to current buffer + if (lastEmpty == true) { + buf.append("\n"); + } - public void addChild (DocElement child) { - if (child==null) - return; - children.put (child.getElementName (), child); - } + buf.append(line); + buf.append(" "); + lastEmpty = false; + } - public int countChildren () { - return children.size (); - } + // store the last element, if there was at least one element ... + if (mode == TEXT) { + comment = buf.toString(); + } else if (mode == TAGS) { + addTag(buf.toString()); + } + } catch (RuntimeException rt) { + debug("parse error in " + location + ": " + rt.getMessage()); + } + } - public Map getChildren () { - return children; - } + /** + * utility: read a complete file into a string + */ + protected static String readFile(File file) { + try { + StringBuffer buf = new StringBuffer(); + BufferedReader in = new BufferedReader(new FileReader(file)); + String line = in.readLine(); - /** - * returns an array of doc elements, sorted by their name - */ - public DocElement[] listChildren () { - String[] keys = (String[]) children.keySet ().toArray (new String[0]); - Arrays.sort (keys); - DocElement[] arr = new DocElement [keys.length]; - for (int i=0; i<keys.length; i++) { - arr [i] = (DocElement) children.get (keys[i]); - } - return arr; - } + while (line != null) { + buf.append(line + "\n"); + line = in.readLine(); + } - /** - * from helma.framework.IPathElement. Elements are named - * like this: typename_name - */ - public String getElementName() { - return typeNames[type].toLowerCase() + "_" + name; - } + in.close(); + return buf.toString(); + } catch (IOException e) { + return (""); + } + } - /** - * from helma.framework.IPathElement. Retrieves a child from the - * children map. - */ - public IPathElement getChildElement (String name) { - try { - return (IPathElement) children.get (name); - } catch (ClassCastException cce) { - debug (cce.toString ()); - cce.printStackTrace (); - return null; - } - } + /** + * + * + * @param parent ... + */ + public void setParent(DocElement parent) { + this.parent = parent; + } + /** + * + * + * @param child ... + */ + public void addChild(DocElement child) { + if (child == null) { + return; + } - /** - * from helma.framework.IPathElement. Returns the parent object - * of this instance if assigned. - */ - public IPathElement getParentElement () { - return parent; - } + children.put(child.getElementName(), child); + } + /** + * + * + * @return ... + */ + public int countChildren() { + return children.size(); + } - /** - * from helma.framework.IPathElement. Prototypes are assigned like - * this: "doc" + typename (e.g. docapplication, docprototype etc) - */ - public java.lang.String getPrototype () { - return "doc" + typeNames[type].toLowerCase (); - } + /** + * + * + * @return ... + */ + public Map getChildren() { + return children; + } + /** + * returns an array of doc elements, sorted by their name + */ + public DocElement[] listChildren() { + String[] keys = (String[]) children.keySet().toArray(new String[0]); - public String toString () { - return "[" + typeNames [type] + " " + name + "]"; - } + Arrays.sort(keys); - public static void debug (String msg) { - System.out.println(msg); - } + DocElement[] arr = new DocElement[keys.length]; + for (int i = 0; i < keys.length; i++) { + arr[i] = (DocElement) children.get(keys[i]); + } + + return arr; + } + + /** + * walks up the tree and tries to find a DocApplication object + */ + public DocApplication getDocApplication() { + DocElement el = this; + + while (el != null) { + if (el instanceof DocApplication) { + return (DocApplication) el; + } + + el = (DocElement) el.getParentElement(); + } + + return null; + } + + /** + * from helma.framework.IPathElement. Elements are named + * like this: typename_name + */ + public String getElementName() { + return typeNames[type].toLowerCase() + "_" + name; + } + + /** + * from helma.framework.IPathElement. Retrieves a child from the + * children map. + */ + public IPathElement getChildElement(String name) { + try { + return (IPathElement) children.get(name); + } catch (ClassCastException cce) { + debug(cce.toString()); + cce.printStackTrace(); + + return null; + } + } + + /** + * from helma.framework.IPathElement. Returns the parent object + * of this instance if assigned. + */ + public IPathElement getParentElement() { + return parent; + } + + /** + * from helma.framework.IPathElement. Prototypes are assigned like + * this: "doc" + typename (e.g. docapplication, docprototype etc) + */ + public java.lang.String getPrototype() { + return "doc" + typeNames[type].toLowerCase(); + } + + /** + * + * + * @return ... + */ + public String toString() { + return "[" + typeNames[type] + " " + name + "]"; + } + + /** + * + * + * @param msg ... + */ + public static void debug(String msg) { + System.out.println(msg); + } } - diff --git a/src/helma/doc/DocException.java b/src/helma/doc/DocException.java index e61d16db..3fa9abef 100644 --- a/src/helma/doc/DocException.java +++ b/src/helma/doc/DocException.java @@ -1,16 +1,43 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.doc; +/** + * + */ public class DocException extends RuntimeException { - String str; - public DocException (String str) { - super (str); - this.str = str; + /** + * Creates a new DocException object. + * + * @param str ... + */ + public DocException(String str) { + super(str); + this.str = str; } - + + /** + * + * + * @return ... + */ public String getMessage() { - return str; + return str; } - } diff --git a/src/helma/doc/DocFileElement.java b/src/helma/doc/DocFileElement.java index a932d3e6..3811d2ed 100644 --- a/src/helma/doc/DocFileElement.java +++ b/src/helma/doc/DocFileElement.java @@ -1,84 +1,112 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.doc; +import FESI.Parser.*; import java.io.*; import java.util.*; -import FESI.Parser.*; - +/** + * + */ public abstract class DocFileElement extends DocElement { + protected DocFileElement(String name, File location, int type) { + super(name, location, type); + } - /** - * extracts the function name from a file. basically chops the given suffix - * and throws an error if the file name doesn't fit. - */ - static protected String nameFromFile (File f, String suffix) throws DocException { - String filename = f.getName (); - if (!filename.endsWith (suffix)) - throw new DocException ("file doesn't have suffix " + suffix + ": " + f.toString()); - return filename.substring (0, filename.lastIndexOf(suffix)); - } + /** + * extracts the function name from a file. basically chops the given suffix + * and throws an error if the file name doesn't fit. + */ + static protected String nameFromFile(File f, String suffix) + throws DocException { + String filename = f.getName(); + if (!filename.endsWith(suffix)) { + throw new DocException("file doesn't have suffix " + suffix + ": " + + f.toString()); + } - /** - * creates fesi token manager for a given file. - */ - static protected EcmaScriptTokenManager createTokenManager (File f) { - try { - ASCII_CharStream is = new ASCII_CharStream(new FileReader(f), 1, 1); - EcmaScriptTokenManager mgr = new EcmaScriptTokenManager(is,0); - return mgr; - } catch (FileNotFoundException fnfe) { - fnfe.printStackTrace (); - throw new DocException (fnfe.toString ()); - } - } + return filename.substring(0, filename.lastIndexOf(suffix)); + } + /** + * creates fesi token manager for a given file. + */ + static protected EcmaScriptTokenManager createTokenManager(File f) { + try { + ASCII_CharStream is = new ASCII_CharStream(new FileReader(f), 1, 1); + EcmaScriptTokenManager mgr = new EcmaScriptTokenManager(is, 0); - protected DocFileElement (String name, File location, int type) { - super (name, location, type); - } + return mgr; + } catch (FileNotFoundException fnfe) { + fnfe.printStackTrace(); + throw new DocException(fnfe.toString()); + } + } + /** + * extracts a part of the source code, used to get the code for a + * single function from a function file. sets the field "content". + */ + protected void parseSource(File sourceFile, int beginLine, int beginColumn, + int endLine, int endColumn) { + StringBuffer buf = new StringBuffer(); + int ct = 0; - /** - * extracts a part of the source code, used to get the code for a - * single function from a function file. sets the field "content". - */ - protected void parseSource (File sourceFile, int beginLine, int beginColumn, int endLine, int endColumn) { - StringBuffer buf = new StringBuffer (); - int ct=0; - try { - BufferedReader in = new BufferedReader (new FileReader (sourceFile)); - String line=""; - while (line!=null) { - line = in.readLine(); - if (line==null) break; - ct++; - if (ct==beginLine) - buf.append (line.substring(beginColumn-1, line.length())+"\n"); - else if ( ct>beginLine && ct<endLine ) - buf.append (line+"\n"); - else if (ct==endLine) - buf.append (line.substring(0,endColumn)); - } - } catch (Exception e) { - debug (e.getMessage ()); - } - content = buf.toString (); - } + try { + BufferedReader in = new BufferedReader(new FileReader(sourceFile)); + String line = ""; + while (line != null) { + line = in.readLine(); - /** - * connects all available specialTokens starting at the given token. - */ - protected void parseCommentFromToken (Token tok) { - StringBuffer buf = new StringBuffer(); - while (tok.specialToken!=null) { - buf.append (tok.specialToken.toString() ); - tok = tok.specialToken; - } - parseComment (buf.toString().trim()); - } + if (line == null) { + break; + } + ct++; + if (ct == beginLine) { + buf.append(line.substring(beginColumn - 1, line.length()) + "\n"); + } else if ((ct > beginLine) && (ct < endLine)) { + buf.append(line + "\n"); + } else if (ct == endLine) { + buf.append(line.substring(0, endColumn)); + } + } + } catch (Exception e) { + debug(e.getMessage()); + } + + content = buf.toString(); + } + + /** + * connects all available specialTokens starting at the given token. + */ + protected void parseCommentFromToken(Token tok) { + StringBuffer buf = new StringBuffer(); + + while (tok.specialToken != null) { + buf.append(tok.specialToken.toString()); + tok = tok.specialToken; + } + + parseComment(buf.toString().trim()); + } } - diff --git a/src/helma/doc/DocFunction.java b/src/helma/doc/DocFunction.java index fb18c3e5..577d5c2c 100644 --- a/src/helma/doc/DocFunction.java +++ b/src/helma/doc/DocFunction.java @@ -1,154 +1,185 @@ -package helma.doc; +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ -import java.io.*; -import java.util.*; +package helma.doc; import FESI.Parser.*; import helma.framework.IPathElement; +import java.io.*; +import java.util.*; +/** + * + */ public class DocFunction extends DocFileElement { + protected DocFunction(String name, File location, DocElement parent, int type) { + super(name, location, type); + this.parent = parent; + } - /** - * creates a new independent DocFunction object of type ACTION - */ - public static DocFunction newAction (File location) { - return newAction (location, null); - } + /** + * creates a new independent DocFunction object of type ACTION + */ + public static DocFunction newAction(File location) { + return newAction(location, null); + } + /** + * creates a new DocFunction object of type ACTION connected to another DocElement + */ + public static DocFunction newAction(File location, DocElement parent) { + String name = nameFromFile(location, ".hac"); + DocFunction func = new DocFunction(name, location, parent, ACTION); - /** - * creates a new DocFunction object of type ACTION connected to another DocElement - */ - public static DocFunction newAction (File location, DocElement parent) { - String name = nameFromFile (location, ".hac"); - DocFunction func = new DocFunction (name, location, parent, ACTION); - func.parseActionFile (); - return func; - } + func.parseActionFile(); - /** - * creates a new independent DocFunction object of type TEMPLATE - */ - public static DocFunction newTemplate (File location) { - return newTemplate (location, null); - } + return func; + } + /** + * creates a new independent DocFunction object of type TEMPLATE + */ + public static DocFunction newTemplate(File location) { + return newTemplate(location, null); + } - /** - * creates a new DocFunction object of type TEMPLATE connected to another DocElement - */ - public static DocFunction newTemplate (File location, DocElement parent) { - String name = nameFromFile (location, ".hsp"); - DocFunction func = new DocFunction (name, location, parent, TEMPLATE); - func.parseTemplateFile (); - return func; - } + /** + * creates a new DocFunction object of type TEMPLATE connected to another DocElement + */ + public static DocFunction newTemplate(File location, DocElement parent) { + String name = nameFromFile(location, ".hsp"); + DocFunction func = new DocFunction(name, location, parent, TEMPLATE); + func.parseTemplateFile(); - /** - * reads a function file and creates independent DocFunction objects of type FUNCTION - */ - public static DocFunction[] newFunctions (File location) { - return newFunctions (location, null); - } + return func; + } + /** + * reads a function file and creates independent DocFunction objects of type FUNCTION + */ + public static DocFunction[] newFunctions(File location) { + return newFunctions(location, null); + } - /** - * reads a function file and creates DocFunction objects of type FUNCTION - * connected to another DocElement. - */ - public static DocFunction[] newFunctions (File location, DocElement parent) { - Vector vec = new Vector (); - EcmaScriptTokenManager mgr = createTokenManager(location); - Token tok = mgr.getNextToken(); - while (tok.kind!=0) { - if (tok.kind == EcmaScriptConstants.FUNCTION) { - // store the start position of the function: - int beginLine = tok.beginLine; - int beginColumn = tok.beginColumn; - // the name is stored in the next token: - String funcName = mgr.getNextToken().toString(); - // create the function object - DocFunction func; - if (funcName.endsWith("_action")) - func = new DocFunction (funcName, location, parent, ACTION); - else if (funcName.endsWith("_macro")) - func = new DocFunction (funcName, location, parent, MACRO); - else - func = new DocFunction (funcName, location, parent, FUNCTION); - // parse the comment from the special token(s) before this token: - func.parseCommentFromToken (tok); - // find the parameters of this function, but only if it's - // neither macro nor action: - if (func.type==FUNCTION) { - while (tok.kind!=0 && tok.kind!=EcmaScriptConstants.RPAREN) { - if (tok.kind==EcmaScriptConstants.IDENTIFIER) { - func.addParameter (tok.image); - } - tok = mgr.getNextToken (); - } - } else { - tok = mgr.getNextToken (); - } - // now find the end of the function: - int endLine=0, endColumn=0; - while (tok.kind!=0 && tok.kind!=EcmaScriptConstants.FUNCTION) { - endLine = tok.endLine; - endColumn = tok.endColumn; - tok = mgr.getNextToken (); - } - // now we know the exact position of the function in the file, - // re-read it and extract the source code: - func.parseSource (location, beginLine, beginColumn, endLine, endColumn); - vec.add (func); - } - if (tok.kind != EcmaScriptConstants.FUNCTION) { - tok = mgr.getNextToken(); - } - } - return (DocFunction[]) vec.toArray (new DocFunction[0]); - } + /** + * reads a function file and creates DocFunction objects of type FUNCTION + * connected to another DocElement. + */ + public static DocFunction[] newFunctions(File location, DocElement parent) { + Vector vec = new Vector(); + EcmaScriptTokenManager mgr = createTokenManager(location); + Token tok = mgr.getNextToken(); - protected DocFunction (String name, File location, DocElement parent, int type) { - super (name, location, type); - this.parent = parent; - } + while (tok.kind != 0) { + if (tok.kind == EcmaScriptConstants.FUNCTION) { + // store the start position of the function: + int beginLine = tok.beginLine; + int beginColumn = tok.beginColumn; + // the name is stored in the next token: + String funcName = mgr.getNextToken().toString(); - /** - * reads the content of a .hac file and parses the comment before the first - * javascript element - */ - private void parseActionFile () { - EcmaScriptTokenManager mgr = createTokenManager(location); - Token tok = mgr.getNextToken(); - parseCommentFromToken (tok); - content = readFile (location); - } + // create the function object + DocFunction func; + if (funcName.endsWith("_action")) { + func = new DocFunction(funcName, location, parent, ACTION); + } else if (funcName.endsWith("_macro")) { + func = new DocFunction(funcName, location, parent, MACRO); + } else { + func = new DocFunction(funcName, location, parent, FUNCTION); + } - /** - * reads the content of a .hsp file and parses the comment before the first - * javascript element (only if file starts with &gt;%-tag!). - */ - private void parseTemplateFile () { - content = readFile (location); - StringReader str = new StringReader (content.substring (content.indexOf("<%") + 2, content.indexOf ("%>"))); - ASCII_CharStream ascii = new ASCII_CharStream (str,1,1); - EcmaScriptTokenManager mgr = new EcmaScriptTokenManager (ascii); - Token tok = mgr.getNextToken(); - parseCommentFromToken (tok); - } + // parse the comment from the special token(s) before this token: + func.parseCommentFromToken(tok); + // find the parameters of this function, but only if it's + // neither macro nor action: + if (func.type == FUNCTION) { + while ((tok.kind != 0) && (tok.kind != EcmaScriptConstants.RPAREN)) { + if (tok.kind == EcmaScriptConstants.IDENTIFIER) { + func.addParameter(tok.image); + } - /** - * from helma.framework.IPathElement. All macros, templates, actions etc - * have the same prototype. - */ - public java.lang.String getPrototype () { - return "docfunction"; - } + tok = mgr.getNextToken(); + } + } else { + tok = mgr.getNextToken(); + } + // now find the end of the function: + int endLine = 0; + // now find the end of the function: + int endColumn = 0; + + while ((tok.kind != 0) && (tok.kind != EcmaScriptConstants.FUNCTION)) { + endLine = tok.endLine; + endColumn = tok.endColumn; + tok = mgr.getNextToken(); + } + + // now we know the exact position of the function in the file, + // re-read it and extract the source code: + func.parseSource(location, beginLine, beginColumn, endLine, endColumn); + vec.add(func); + } + + if (tok.kind != EcmaScriptConstants.FUNCTION) { + tok = mgr.getNextToken(); + } + } + + return (DocFunction[]) vec.toArray(new DocFunction[0]); + } + + /** + * reads the content of a .hac file and parses the comment before the first + * javascript element + */ + private void parseActionFile() { + EcmaScriptTokenManager mgr = createTokenManager(location); + Token tok = mgr.getNextToken(); + + parseCommentFromToken(tok); + content = readFile(location); + } + + /** + * reads the content of a .hsp file and parses the comment before the first + * javascript element (only if file starts with &gt;%-tag!). + */ + private void parseTemplateFile() { + content = readFile(location); + + StringReader str = new StringReader(content.substring(content.indexOf("<%") + 2, + content.indexOf("%>"))); + ASCII_CharStream ascii = new ASCII_CharStream(str, 1, 1); + EcmaScriptTokenManager mgr = new EcmaScriptTokenManager(ascii); + Token tok = mgr.getNextToken(); + + parseCommentFromToken(tok); + } + + /** + * from helma.framework.IPathElement. All macros, templates, actions etc + * have the same prototype. + */ + public java.lang.String getPrototype() { + return "docfunction"; + } } - diff --git a/src/helma/doc/DocProperties.java b/src/helma/doc/DocProperties.java index 5eb640ab..6a050859 100644 --- a/src/helma/doc/DocProperties.java +++ b/src/helma/doc/DocProperties.java @@ -1,3 +1,19 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.doc; import helma.framework.IPathElement; @@ -5,59 +21,76 @@ import helma.util.SystemProperties; import java.io.*; import java.util.*; -public class DocProperties extends DocFileElement { +/** + * + */ +public class DocProperties extends DocFileElement { + Properties props = null; - Properties props = null; + protected DocProperties(File location, DocElement parent) + throws DocException { + super(location.getName(), location, PROPERTIES); + this.parent = parent; + content = readFile(location); + props = new SystemProperties(); - /** - * creates a new independent DocProperties object - */ - public static DocProperties newInstance (File location) { - return newInstance (location, null); - } + try { + props.load(new FileInputStream(location)); + } catch (IOException e) { + debug("couldn't read file: " + e.toString()); + } catch (Exception e) { + throw new DocException(e.toString()); + } + } - /** - * creates a new DocProperties object connected to another DocElement - */ - public static DocProperties newInstance (File location, DocElement parent) { - try { - return new DocProperties (location, parent); - } catch (DocException doc) { - return null; - } - } + /** + * creates a new independent DocProperties object + */ + public static DocProperties newInstance(File location) { + return newInstance(location, null); + } - protected DocProperties (File location, DocElement parent) throws DocException { - super (location.getName (), location, PROPERTIES); - this.parent = parent; - content = readFile (location); - props = new SystemProperties (); - try { - props.load (new FileInputStream (location)); - } catch (IOException e) { - debug ("couldn't read file: " + e.toString ()); - } catch (Exception e) { - throw new DocException (e.toString ()); - } - } + /** + * creates a new DocProperties object connected to another DocElement + */ + public static DocProperties newInstance(File location, DocElement parent) { + try { + return new DocProperties(location, parent); + } catch (DocException doc) { + return null; + } + } - public Properties getProperties () { - return props; - } + /** + * + * + * @return ... + */ + public Properties getProperties() { + return props; + } - public Properties getMappings () { - Properties childProps = new Properties (); - for (Enumeration e = props.keys (); e.hasMoreElements (); ) { - String key = (String) e.nextElement (); - String value = props.getProperty (key); - if (value.startsWith ("collection") || value.startsWith ("object") || value.startsWith ("mountpoint")) { - String prototype = value.substring (value.indexOf("(")+1, value.indexOf(")")).trim (); - childProps.setProperty (key, prototype); - } - - } - return childProps; - } + /** + * + * + * @return ... + */ + public Properties getMappings() { + Properties childProps = new Properties(); + for (Enumeration e = props.keys(); e.hasMoreElements();) { + String key = (String) e.nextElement(); + String value = props.getProperty(key); + + if (value.startsWith("collection") || value.startsWith("object") || + value.startsWith("mountpoint")) { + String prototype = value.substring(value.indexOf("(") + 1, + value.indexOf(")")).trim(); + + childProps.setProperty(key, prototype); + } + } + + return childProps; + } } - diff --git a/src/helma/doc/DocPrototype.java b/src/helma/doc/DocPrototype.java index 45dc9e86..28f390be 100644 --- a/src/helma/doc/DocPrototype.java +++ b/src/helma/doc/DocPrototype.java @@ -1,110 +1,150 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.doc; +import FESI.Parser.*; import helma.framework.IPathElement; import java.io.*; import java.util.*; -import FESI.Parser.*; +/** + * + */ +public class DocPrototype extends DocDirElement { + private DocProperties typeProperties = null; + private DocPrototype parentPrototype = null; -public class DocPrototype extends DocDirElement { + private DocPrototype(String name, File location, DocElement parent) { + super(name, location, PROTOTYPE); + this.parent = parent; + typeProperties = DocProperties.newInstance(new File(location, "type.properties")); + } - private DocProperties typeProperties = null; - private DocPrototype parentPrototype = null; + /** + * creates a prototype that is independent of an + * application object + * @param homedirectory + */ + public static DocPrototype newInstance(File location) { + return newInstance(location, null); + } - /** - * creates a prototype that is independent of an - * application object - * @param homedirectory - */ - public static DocPrototype newInstance (File location) { - return newInstance (location, null); - } + /** + * creates a prototype that is connected to an + * application object and resides in app's home dir. + * @param application + * @param name + */ + public static DocPrototype newInstance(File location, DocElement parent) { + DocPrototype pt = new DocPrototype(location.getName(), location, parent); - /** - * creates a prototype that is connected to an - * application object and resides in app's home dir. - * @param application - * @param name - */ - public static DocPrototype newInstance (File location, DocElement parent) { - DocPrototype pt = new DocPrototype (location.getName (), location, parent); - return pt; - } + return pt; + } - private DocPrototype (String name, File location, DocElement parent) { - super (name, location, PROTOTYPE); - this.parent = parent; - typeProperties = DocProperties.newInstance (new File (location, "type.properties")); - } + /** + * checks the type.properites for _extend values and connected a possible + * parent prototype with this prototype. this can't be successfull at construction + * time but only -after- all prototypes are parsed and attached to a parent + * DocApplication object. + */ + public void checkInheritance() { + // hopobject is the top prototype: + if (name.equals("hopobject")) { + return; + } + if (typeProperties != null) { + // check for "_extends" in the the type.properties + String ext = typeProperties.getProperties().getProperty("_extends"); - /** - * checks the type.properites for _extend values and connected a possible - * parent prototype with this prototype. this can't be successfull at construction - * time but only -after- all prototypes are parsed and attached to a parent - * DocApplication object. - */ - public void checkInheritance () { - // hopobject is the top prototype: - if (name.equals("hopobject")) - return; - if (typeProperties!=null) { - // check for "_extends" in the the type.properties - String ext = typeProperties.getProperties ().getProperty ("_extends"); - if (ext!=null && parent!=null) { - // try to get the prototype if available - parentPrototype = (DocPrototype) parent.getChildElement ("prototype_" + ext); - } - } - if (parentPrototype==null && parent!=null && !name.equals("global")) { - // if no _extend was set, get the hopobject prototype - parentPrototype = (DocPrototype) parent.getChildElement ("prototype_hopobject"); - } - } + if ((ext != null) && (parent != null)) { + // try to get the prototype if available + parentPrototype = (DocPrototype) parent.getChildElement("prototype_" + + ext); + } + } - public DocPrototype getParentPrototype () { - return parentPrototype; - } + if ((parentPrototype == null) && (parent != null) && !name.equals("global")) { + // if no _extend was set, get the hopobject prototype + parentPrototype = (DocPrototype) parent.getChildElement("prototype_hopobject"); + } + } + /** + * + * + * @return ... + */ + public DocPrototype getParentPrototype() { + return parentPrototype; + } - public DocProperties getTypeProperties () { - return typeProperties; - } + /** + * + * + * @return ... + */ + public DocProperties getTypeProperties() { + return typeProperties; + } + /** + * runs through the prototype directory and parses all helma files + */ + public void readFiles() { + children.clear(); - /** - * runs through the prototype directory and parses all helma files - */ - public void readFiles () { - children.clear (); - String arr[] = location.list (); - for (int i=0; i<arr.length; i++) { - if (Util.isExcluded (arr[i])) - continue; - File f = new File (location.getAbsolutePath (), arr[i]); - if (f.isDirectory ()) - continue; - try { - if (arr[i].endsWith (".skin")) { - addChild (DocSkin.newInstance (f, this)); - } else if (arr[i].endsWith (".properties")) { - continue; - } else if (arr[i].endsWith (".hac")) { - addChild (DocFunction.newAction (f, this)); - } else if (arr[i].endsWith (".hsp")) { - addChild (DocFunction.newTemplate (f, this)); - } else if (arr[i].endsWith (".js")) { - DocElement[] elements = DocFunction.newFunctions (f, this); - for (int j=0; j<elements.length; j++) { - addChild (elements[j]); - } - } - } catch (Exception ex) { - System.out.println ("couldn't parse file " + f.getAbsolutePath () + ": " + ex.toString ()); - ex.printStackTrace (); - } - } - } + String[] arr = location.list(); + for (int i = 0; i < arr.length; i++) { + if (getDocApplication().isExcluded(arr[i])) { + continue; + } + + File f = new File(location.getAbsolutePath(), arr[i]); + + if (f.isDirectory()) { + continue; + } + + try { + if (arr[i].endsWith(".skin")) { + addChild(DocSkin.newInstance(f, this)); + } else if (arr[i].endsWith(".properties")) { + continue; + } else if (arr[i].endsWith(".hac")) { + addChild(DocFunction.newAction(f, this)); + } else if (arr[i].endsWith(".hsp")) { + addChild(DocFunction.newTemplate(f, this)); + } else if (arr[i].endsWith(".js")) { + DocElement[] elements = DocFunction.newFunctions(f, this); + + for (int j = 0; j < elements.length; j++) { + addChild(elements[j]); + } + } + } catch (Exception ex) { + System.out.println("couldn't parse file " + f.getAbsolutePath() + ": " + + ex.toString()); + ex.printStackTrace(); + } catch (FESI.Parser.TokenMgrError err) { + System.out.println("couldn't parse file " + f.getAbsolutePath() + ": " + + err.toString()); + } + } + } } - diff --git a/src/helma/doc/DocSkin.java b/src/helma/doc/DocSkin.java index ff605cf2..d4b21259 100644 --- a/src/helma/doc/DocSkin.java +++ b/src/helma/doc/DocSkin.java @@ -1,87 +1,118 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.doc; import helma.framework.IPathElement; import java.io.*; import java.util.*; -public class DocSkin extends DocFileElement { +/** + * + */ +public class DocSkin extends DocFileElement { + protected DocSkin(String name, File location, DocElement parent) { + super(name, location, SKIN); + this.parent = parent; + content = readFile(location); + parseHandlers(); + } - /** - * creates a new independent DocSkin object - */ - public static DocSkin newInstance (File location) { - return newInstance (location, null); - } + /** + * creates a new independent DocSkin object + */ + public static DocSkin newInstance(File location) { + return newInstance(location, null); + } - /** - * creates a new DocSkin object connected to another DocElement - */ - public static DocSkin newInstance (File location, DocElement parent) { - String skinname = nameFromFile (location, ".skin"); - DocSkin skin = new DocSkin (skinname, location, parent); - return skin; - } + /** + * creates a new DocSkin object connected to another DocElement + */ + public static DocSkin newInstance(File location, DocElement parent) { + String skinname = nameFromFile(location, ".skin"); + DocSkin skin = new DocSkin(skinname, location, parent); - protected DocSkin (String name, File location, DocElement parent) { - super (name, location, SKIN); - this.parent = parent; - content = readFile (location); - parseHandlers (); - } + return skin; + } + /** + * parses the source code of the skin and + * extracts all included macros. code taken + * from helma.framework.core.Skin + * @see helma.framework.core.Skin + */ + private void parseHandlers() { + ArrayList partBuffer = new ArrayList(); + char[] source = content.toCharArray(); + int sourceLength = source.length; + int start = 0; - /** - * parses the source code of the skin and - * extracts all included macros. code taken - * from helma.framework.core.Skin - * @see helma.framework.core.Skin - */ - private void parseHandlers () { - ArrayList partBuffer = new ArrayList (); - char[] source = content.toCharArray (); - int sourceLength = source.length; - int start = 0; - for (int i = 0; i < sourceLength-1; i++) { - if (source[i] == '<' && source[i+1] == '%') { - // found macro start tag - int j = i+2; - // search macro end tag - while (j < sourceLength-1 && (source[j] != '%' || source[j+1] != '>')) { - j++; - } - if (j > i+2) { - String str = (new String (source, i+2, j-i)).trim (); - if (str.endsWith("%>")) - str = str.substring (0, str.length()-2); - if (str.indexOf (" ")>-1) - str = str.substring (0, str.indexOf(" ")); - if (str.indexOf(".")>-1 && - (str.startsWith ("param.") - || str.startsWith ("response.") - || str.startsWith("request.") - || str.startsWith ("session.") - ) && !partBuffer.contains(str)) { - partBuffer.add (str); - } - start = j+2; - } - i = j+1; - } - } - String[] strArr = (String[]) partBuffer.toArray (new String [0]); - Arrays.sort (strArr); - for (int i=0; i<strArr.length; i++) { - addParameter (strArr[i]); - } - } + for (int i = 0; i < (sourceLength - 1); i++) { + if ((source[i] == '<') && (source[i + 1] == '%')) { + // found macro start tag + int j = i + 2; - /** - * from helma.framework.IPathElement. Use the same prototype as functions etc. - */ - public java.lang.String getPrototype () { - return "docfunction"; - } + // search macro end tag + while ((j < (sourceLength - 1)) && + ((source[j] != '%') || (source[j + 1] != '>'))) { + j++; + } + if (j > (i + 2)) { + String str = (new String(source, i + 2, j - i)).trim(); + if (str.endsWith("%>")) { + str = str.substring(0, str.length() - 2); + } + + if (str.startsWith("//")) { + parseComment(str); + } else { + if (str.indexOf(" ") > -1) { + str = str.substring(0, str.indexOf(" ")); + } + + if ((str.indexOf(".") > -1) && + (str.startsWith("param.") || str.startsWith("response.") || + str.startsWith("request.") || str.startsWith("session.")) && + !partBuffer.contains(str)) { + partBuffer.add(str); + } + } + + start = j + 2; + } + + i = j + 1; + } + } + + String[] strArr = (String[]) partBuffer.toArray(new String[0]); + + Arrays.sort(strArr); + + for (int i = 0; i < strArr.length; i++) { + addParameter(strArr[i]); + } + } + + /** + * from helma.framework.IPathElement. Use the same prototype as functions etc. + */ + public java.lang.String getPrototype() { + return "docfunction"; + } } - diff --git a/src/helma/doc/DocTag.java b/src/helma/doc/DocTag.java index 690500ce..f713fb86 100644 --- a/src/helma/doc/DocTag.java +++ b/src/helma/doc/DocTag.java @@ -1,108 +1,176 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.doc; import java.util.*; -public final class DocTag { +/** + * + */ +public final class DocTag { + // for public use we have less types than + // internally. eg, we're combining "return" and "returns" + // or "arg" and "param". + // the values here have to match the index of + // the tags-array! + public static final int PARAMETER = 0; + public static final int RETURN = 2; + public static final int AUTHOR = 4; + public static final int VERSION = 5; + public static final int SEE = 6; + public static final int DEPRECATED = 7; + public static final int OVERRIDES = 8; + public static final String[][] tags = { + { "@arg", "Argument" }, + { "@param", "Parameter" }, + { "@return", "Returns" }, + { "@returns", "Returns" }, + { "@author", "Author" }, + { "@version", "Version" }, + { "@see", "See also" }, + { "@deprecated", "Deprecated" }, + { "@overrides", "Overrides" } + }; + private String name; - // for public use we have less types than - // internally. eg, we're combining "return" and "returns" - // or "arg" and "param". - // the values here have to match the index of - // the tags-array! - public static final int PARAMETER = 0; - public static final int RETURN = 2; - public static final int AUTHOR = 4; - public static final int VERSION = 5; - public static final int SEE = 6; - public static final int DEPRECATED = 7; - public static final int OVERRIDES = 8; + // "kind" is for internal use, "type" is external + private int kind; + private String text; - public static final String[][] tags = { - {"@arg","Argument"}, - {"@param","Parameter"}, - {"@return","Returns"}, - {"@returns","Returns"}, - {"@author","Author"}, - {"@version","Version"}, - {"@see","See also"}, - {"@deprecated", "Deprecated"}, - {"@overrides", "Overrides"} - }; + private DocTag(int kind, String name, String text) { + this.kind = kind; + this.name = (name != null) ? name : ""; + this.text = (text != null) ? text : ""; + } - private String name; - // "kind" is for internal use, "type" is external - private int kind; - private String text; + /** + * + * + * @param rawTag ... + * + * @return ... + */ + public static boolean isTagStart(String rawTag) { + if (getTagNumber(rawTag) > -1) { + return true; + } else { + return false; + } + } - public static boolean isTagStart (String rawTag) { - if (getTagNumber(rawTag) > -1) - return true; - else - return false; - } + /** + * + * + * @param rawTag ... + * + * @return ... + * + * @throws DocException ... + */ + public static DocTag parse(String rawTag) throws DocException { + int kind = getTagNumber(rawTag); - public static DocTag parse (String rawTag) throws DocException { - int kind = getTagNumber (rawTag); - if (kind == -1) - throw new DocException ("unsupported tag type: " + rawTag); - String content = rawTag.substring (tags[kind][0].length ()+1).trim (); - if (kind == 0 || kind==1) { - StringTokenizer tok = new StringTokenizer (content); - String name = ""; - if (tok.hasMoreTokens ()) - name = tok.nextToken (); - String comment = ""; - try { - comment = content.substring (name.length ()+1).trim (); - } catch (StringIndexOutOfBoundsException e) { } - return new DocTag (kind, name, comment); - } else { - return new DocTag (kind, "", content); - } - } + if (kind == -1) { + throw new DocException("unsupported tag type: " + rawTag); + } - private static int getTagNumber (String rawTag) { - rawTag = rawTag.trim ().toLowerCase (); - for (int i=0; i<tags.length; i++) { - if (rawTag.startsWith (tags[i][0])) { - return i; - } - } - return -1; - } + String content = rawTag.substring(tags[kind][0].length() + 1).trim(); + if ((kind == 0) || (kind == 1)) { + StringTokenizer tok = new StringTokenizer(content); + String name = ""; - private DocTag (int kind, String name, String text) { - this.kind = kind; - this.name = (name!=null) ? name : ""; - this.text = (text!=null) ? text : ""; - } + if (tok.hasMoreTokens()) { + name = tok.nextToken(); + } - public String getName () { - return name; - } + String comment = ""; - public int getType () { - if (kind==0 || kind==1) - return PARAMETER; - else if (kind==2 || kind==3) - return RETURN; - else - return kind; - } + try { + comment = content.substring(name.length() + 1).trim(); + } catch (StringIndexOutOfBoundsException e) { + } + return new DocTag(kind, name, comment); + } else { + return new DocTag(kind, "", content); + } + } - public String getTag () { - return tags[kind][0]; - } + private static int getTagNumber(String rawTag) { + rawTag = rawTag.trim().toLowerCase(); - public String getText () { - return text; - } + for (int i = 0; i < tags.length; i++) { + if (rawTag.startsWith(tags[i][0])) { + return i; + } + } - public String toString() { - return tags [kind][1] + ": " + name + " " + text; - } + return -1; + } + /** + * + * + * @return ... + */ + public String getName() { + return name; + } + + /** + * + * + * @return ... + */ + public int getType() { + if ((kind == 0) || (kind == 1)) { + return PARAMETER; + } else if ((kind == 2) || (kind == 3)) { + return RETURN; + } else { + return kind; + } + } + + /** + * + * + * @return ... + */ + public String getTag() { + return tags[kind][0]; + } + + /** + * + * + * @return ... + */ + public String getText() { + return text; + } + + /** + * + * + * @return ... + */ + public String toString() { + return tags[kind][1] + ": " + name + " " + text; + } } - diff --git a/src/helma/doc/Util.java b/src/helma/doc/Util.java index 102f9ad5..8db24a63 100644 --- a/src/helma/doc/Util.java +++ b/src/helma/doc/Util.java @@ -1,40 +1,50 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.doc; import java.io.*; import java.util.*; +/** + * + */ public final class Util { - - static Vector excluded = new Vector (); - - public static void addExlude (String str) { - excluded.add (str.toLowerCase ()); - } - - public static boolean isExcluded (String str) { - if (excluded.size ()==0) { - excluded.add ("cvs"); - excluded.add (".docs"); - } - return (excluded.contains (str.toLowerCase ())); - } - - public static String chopDelimiters (String line) { - if (line==null) - return null; - else if (line.startsWith("/**")) - return line.substring (3).trim (); - else if (line.startsWith("/*")) - return line.substring (2).trim (); - else if (line.endsWith ("*/")) - return line.substring (0, line.length ()-2); - else if (line.startsWith("*")) - return line.substring (1).trim (); - else if (line.startsWith("//")) - return line.substring (2).trim (); - else - return line; - } - - + /** + * + * + * @param line ... + * + * @return ... + */ + public static String chopDelimiters(String line) { + if (line == null) { + return null; + } else if (line.startsWith("/**")) { + return line.substring(3).trim(); + } else if (line.startsWith("/*")) { + return line.substring(2).trim(); + } else if (line.endsWith("*/")) { + return line.substring(0, line.length() - 2); + } else if (line.startsWith("*")) { + return line.substring(1).trim(); + } else if (line.startsWith("//")) { + return line.substring(2).trim(); + } else { + return line; + } + } } diff --git a/src/helma/extensions/ConfigurationException.java b/src/helma/extensions/ConfigurationException.java index 908c54a9..d134964d 100644 --- a/src/helma/extensions/ConfigurationException.java +++ b/src/helma/extensions/ConfigurationException.java @@ -1,9 +1,31 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.extensions; +/** + * + */ public class ConfigurationException extends RuntimeException { - - public ConfigurationException (String msg) { - super (msg); + /** + * Creates a new ConfigurationException object. + * + * @param msg ... + */ + public ConfigurationException(String msg) { + super(msg); } - } diff --git a/src/helma/extensions/HelmaExtension.java b/src/helma/extensions/HelmaExtension.java index 9c02c7f5..7bb0fa26 100644 --- a/src/helma/extensions/HelmaExtension.java +++ b/src/helma/extensions/HelmaExtension.java @@ -1,53 +1,71 @@ -package helma.extensions; +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ -import java.util.HashMap; +package helma.extensions; import helma.framework.core.Application; import helma.main.Server; import helma.scripting.ScriptingEngine; +import java.util.HashMap; /** - * Helma extensions have to subclass this. The extensions to be loaded are - * defined in <code>server.properties</code> by setting <code>extensions = - * packagename.classname, packagename.classname</code>. - */ - + * Helma extensions have to subclass this. The extensions to be loaded are + * defined in <code>server.properties</code> by setting <code>extensions = + * packagename.classname, packagename.classname</code>. + */ public abstract class HelmaExtension { + /** + * called by the Server at startup time. should check wheter the needed classes + * are present and throw a ConfigurationException if not. + */ + public abstract void init(Server server) throws ConfigurationException; - /** - * called by the Server at startup time. should check wheter the needed classes - * are present and throw a ConfigurationException if not. - */ - public abstract void init (Server server) throws ConfigurationException; + /** + * called when an Application is started. This should be <b>synchronized</b> when + * any self-initialization is performed. + */ + public abstract void applicationStarted(Application app) + throws ConfigurationException; - /** - * called when an Application is started. This should be <b>synchronized</b> when - * any self-initialization is performed. - */ - public abstract void applicationStarted (Application app) throws ConfigurationException; + /** + * called when an Application is stopped. + * This should be <b>synchronized</b> when any self-destruction is performed. + */ + public abstract void applicationStopped(Application app); - /** - * called when an Application is stopped. - * This should be <b>synchronized</b> when any self-destruction is performed. - */ - public abstract void applicationStopped (Application app); + /** + * called when an Application's properties are have been updated. + * note that this will be called at startup once *before* applicationStarted(). + */ + public abstract void applicationUpdated(Application app); - /** - * called when an Application's properties are have been updated. - * note that this will be called at startup once *before* applicationStarted(). - */ - public abstract void applicationUpdated (Application app); - - /** - * called by the ScriptingEngine when it is initizalized. Throws a ConfigurationException - * when this type of ScriptingEngine is not supported. New methods and prototypes can be - * added to the scripting environment. New global vars should be returned in a HashMap - * with pairs of varname and ESObjects. This method should be <b>synchronized</b>, if it - * performs any other self-initialization outside the scripting environment. - */ - public abstract HashMap initScripting (Application app, ScriptingEngine engine) throws ConfigurationException; - - public abstract String getName (); + /** + * called by the ScriptingEngine when it is initizalized. Throws a ConfigurationException + * when this type of ScriptingEngine is not supported. New methods and prototypes can be + * added to the scripting environment. New global vars should be returned in a HashMap + * with pairs of varname and ESObjects. This method should be <b>synchronized</b>, if it + * performs any other self-initialization outside the scripting environment. + */ + public abstract HashMap initScripting(Application app, ScriptingEngine engine) + throws ConfigurationException; + /** + * + * + * @return ... + */ + public abstract String getName(); } - diff --git a/src/helma/extensions/demo/DemoExtension.java b/src/helma/extensions/demo/DemoExtension.java index 2a946e06..115a6444 100644 --- a/src/helma/extensions/demo/DemoExtension.java +++ b/src/helma/extensions/demo/DemoExtension.java @@ -1,12 +1,21 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.extensions.demo; -import java.util.HashMap; - -import helma.extensions.HelmaExtension; -import helma.extensions.ConfigurationException; -import helma.framework.core.Application; -import helma.main.Server; -import helma.scripting.ScriptingEngine; // fesi-related stuff: import FESI.Data.ESObject; @@ -14,55 +23,104 @@ import FESI.Data.ESWrapper; import FESI.Data.GlobalObject; import FESI.Exceptions.EcmaScriptException; import FESI.Interpreter.Evaluator; +import helma.extensions.ConfigurationException; +import helma.extensions.HelmaExtension; +import helma.framework.core.Application; +import helma.main.Server; +import helma.scripting.ScriptingEngine; import helma.scripting.fesi.FesiEngine; - +import java.util.HashMap; /** - * a demo extension implementation, to activate this add <code>extensions = - * helma.extensions.demo.DemoExtensions</code> to your <code>server.properties</code>. - * a new global object <code>demo</code> that wraps helma.main.Server - * will be added to the scripting environment. - */ - + * a demo extension implementation, to activate this add <code>extensions = + * helma.extensions.demo.DemoExtensions</code> to your <code>server.properties</code>. + * a new global object <code>demo</code> that wraps helma.main.Server + * will be added to the scripting environment. + */ public class DemoExtension extends HelmaExtension { + /** + * + * + * @param server ... + * + * @throws ConfigurationException ... + */ + public void init(Server server) throws ConfigurationException { + try { + // just a demo with the server class itself (which is always there, obviously) + Class check = Class.forName("helma.main.Server"); + } catch (ClassNotFoundException e) { + throw new ConfigurationException("helma-library not present in classpath. make sure helma.jar is included. get it from http://www.helma.org/"); + } + } - public void init (Server server) throws ConfigurationException { - try { - // just a demo with the server class itself (which is always there, obviously) - Class check = Class.forName("helma.main.Server"); - } catch (ClassNotFoundException e) { - throw new ConfigurationException("helma-library not present in classpath. make sure helma.jar is included. get it from http://www.helma.org/"); - } - } + /** + * + * + * @param app ... + * + * @throws ConfigurationException ... + */ + public void applicationStarted(Application app) throws ConfigurationException { + app.logEvent("DemoExtension init with app " + app.getName()); + } - public void applicationStarted (Application app) throws ConfigurationException { - app.logEvent ("DemoExtension init with app " + app.getName () ); - } + /** + * + * + * @param app ... + */ + public void applicationStopped(Application app) { + app.logEvent("DemoExtension stopped on app " + app.getName()); + } - public void applicationStopped (Application app) { - app.logEvent ("DemoExtension stopped on app " + app.getName () ); - } + /** + * + * + * @param app ... + */ + public void applicationUpdated(Application app) { + app.logEvent("DemoExtension updated on app " + app.getName()); + } - public void applicationUpdated (Application app) { - app.logEvent ("DemoExtension updated on app " + app.getName () ); - } + /** + * + * + * @param app ... + * @param engine ... + * + * @return ... + * + * @throws ConfigurationException ... + */ + public HashMap initScripting(Application app, ScriptingEngine engine) + throws ConfigurationException { + if (!(engine instanceof FesiEngine)) { + throw new ConfigurationException("scripting engine " + engine.toString() + + " not supported in DemoExtension"); + } - public HashMap initScripting (Application app, ScriptingEngine engine) throws ConfigurationException { - if (!(engine instanceof FesiEngine)) - throw new ConfigurationException ("scripting engine " + engine.toString () + " not supported in DemoExtension"); - app.logEvent("initScripting DemoExtension with " + app.getName () + " and " + engine.toString() ); - // fesi-specific code: - Evaluator evaluator = ((FesiEngine)engine).getEvaluator (); - // initialize prototypes and global vars here, but don't add them to fesi's global object - ESWrapper demo = new ESWrapper(Server.getServer (), evaluator); - HashMap globals = new HashMap (); - globals.put ("demo",demo); - return globals; - } + app.logEvent("initScripting DemoExtension with " + app.getName() + " and " + + engine.toString()); - public String getName () { - return "DemoExtension"; - } + // fesi-specific code: + Evaluator evaluator = ((FesiEngine) engine).getEvaluator(); + // initialize prototypes and global vars here, but don't add them to fesi's global object + ESWrapper demo = new ESWrapper(Server.getServer(), evaluator); + HashMap globals = new HashMap(); + + globals.put("demo", demo); + + return globals; + } + + /** + * + * + * @return ... + */ + public String getName() { + return "DemoExtension"; + } } - diff --git a/src/helma/framework/ApplicationStoppedException.java b/src/helma/framework/ApplicationStoppedException.java index b1bbb0ac..a07f20fd 100644 --- a/src/helma/framework/ApplicationStoppedException.java +++ b/src/helma/framework/ApplicationStoppedException.java @@ -1,19 +1,31 @@ -// ApplicationStoppedException.java -// Copyright (c) Hannes Wallnöfer 1998-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.framework; + /** * This is thrown when a request is made to a stopped * application */ - public class ApplicationStoppedException extends RuntimeException { - - - public ApplicationStoppedException () { - super ("The application has been stopped"); + /** + * Creates a new ApplicationStoppedException object. + */ + public ApplicationStoppedException() { + super("The application has been stopped"); } - - } diff --git a/src/helma/framework/CookieTrans.java b/src/helma/framework/CookieTrans.java index ccb61d64..bf60d715 100644 --- a/src/helma/framework/CookieTrans.java +++ b/src/helma/framework/CookieTrans.java @@ -1,4 +1,18 @@ -// CookieTrans.java +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.framework; @@ -7,68 +21,110 @@ import java.util.HashMap; import javax.servlet.http.Cookie; /** - * Cookie Transmitter. A simple, serializable representation + * Cookie Transmitter. A simple, serializable representation * of an HTTP cookie. */ public final class CookieTrans implements Serializable { - - String name, value, path, domain; + String name; + String value; + String path; + String domain; int days; - CookieTrans (String name, String value) { - this.name = name; - this.value = value; + CookieTrans(String name, String value) { + this.name = name; + this.value = value; } - void setValue (String value) { - this.value = value; + void setValue(String value) { + this.value = value; } - void setDays (int days) { - this.days = days; + void setDays(int days) { + this.days = days; } - void setPath (String path) { - this.path = path; + void setPath(String path) { + this.path = path; } - void setDomain (String domain) { - this.domain = domain; + void setDomain(String domain) { + this.domain = domain; } + /** + * + * + * @return ... + */ public String getName() { - return name; + return name; } + /** + * + * + * @return ... + */ public String getValue() { - return value; + return value; } + /** + * + * + * @return ... + */ public int getDays() { - return days; + return days; } - public String getPath () { - return path; + /** + * + * + * @return ... + */ + public String getPath() { + return path; } - public String getDomain () { - return domain; + /** + * + * + * @return ... + */ + public String getDomain() { + return domain; } - public Cookie getCookie (String defaultPath, String defaultDomain) { - Cookie c = new Cookie (name, value); - if (days > 0) - // Cookie time to live, days -> seconds - c.setMaxAge (days*60*60*24); - if (path != null) - c.setPath (path); - else if (defaultPath != null) - c.setPath (defaultPath); - if (domain != null) - c.setDomain (domain); - else if (defaultDomain != null) - c.setDomain (defaultDomain); - return c; + /** + * + * + * @param defaultPath ... + * @param defaultDomain ... + * + * @return ... + */ + public Cookie getCookie(String defaultPath, String defaultDomain) { + Cookie c = new Cookie(name, value); + + if (days > 0) { + // Cookie time to live, days -> seconds + c.setMaxAge(days * 60 * 60 * 24); + } + + if (path != null) { + c.setPath(path); + } else if (defaultPath != null) { + c.setPath(defaultPath); + } + + if (domain != null) { + c.setDomain(domain); + } else if (defaultDomain != null) { + c.setDomain(defaultDomain); + } + + return c; } } diff --git a/src/helma/framework/FrameworkException.java b/src/helma/framework/FrameworkException.java index 847a497b..be0a48a0 100644 --- a/src/helma/framework/FrameworkException.java +++ b/src/helma/framework/FrameworkException.java @@ -1,17 +1,33 @@ -// FrameworkException.java -// Copyright (c) Hannes Wallnöfer 1998-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.framework; + /** - * The basic exception class used to tell when certain things go + * The basic exception class used to tell when certain things go * wrong in evaluation of requests. */ - public class FrameworkException extends RuntimeException { - - public FrameworkException (String msg) { - super (msg); + /** + * Creates a new FrameworkException object. + * + * @param msg ... + */ + public FrameworkException(String msg) { + super(msg); } - } diff --git a/src/helma/framework/IPathElement.java b/src/helma/framework/IPathElement.java index 7e0dd063..b56289e5 100644 --- a/src/helma/framework/IPathElement.java +++ b/src/helma/framework/IPathElement.java @@ -1,6 +1,19 @@ -// IPathElement.java -// Copyright (c) Hannes Wallnöfer 2001 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.framework; @@ -14,34 +27,26 @@ package helma.framework; * parent element. <p> * */ - public interface IPathElement { - /** * Return the name to be used to get this element from its parent */ - public String getElementName (); + public String getElementName(); /** * Retrieve a child element of this object by name. */ - public IPathElement getChildElement (String name); + public IPathElement getChildElement(String name); /** * Return the parent element of this object. */ - public IPathElement getParentElement (); - + public IPathElement getParentElement(); /** * Get the name of the prototype to be used for this object. This will * determine which scripts, actions and skins can be called on it * within the Helma scripting and rendering framework. */ - public String getPrototype (); - + public String getPrototype(); } - - - - diff --git a/src/helma/framework/IRemoteApp.java b/src/helma/framework/IRemoteApp.java index 3c1c18cb..b4ce5481 100644 --- a/src/helma/framework/IRemoteApp.java +++ b/src/helma/framework/IRemoteApp.java @@ -1,5 +1,18 @@ -// IRemoteApp.java -// Copyright (c) Hannes Wallnöfer 1998-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.framework; @@ -9,11 +22,22 @@ import java.util.Vector; /** * RMI interface for an application. Currently only execute is used and supported. */ - public interface IRemoteApp extends Remote { + /** + * + * + * @param param ... + * + * @return ... + * + * @throws RemoteException ... + */ + public ResponseTrans execute(RequestTrans param) throws RemoteException; - public ResponseTrans execute (RequestTrans param) throws RemoteException; - - public void ping () throws RemoteException; - - } + /** + * + * + * @throws RemoteException ... + */ + public void ping() throws RemoteException; +} diff --git a/src/helma/framework/RedirectException.java b/src/helma/framework/RedirectException.java index 1e43d979..4f29622f 100644 --- a/src/helma/framework/RedirectException.java +++ b/src/helma/framework/RedirectException.java @@ -1,5 +1,18 @@ -// RedirectException.java -// Copyright (c) Hannes Wallnöfer 1998-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.framework; @@ -8,26 +21,43 @@ package helma.framework; * RedirectException is thrown internally when a response is redirected to a * new URL. */ - public class RedirectException extends RuntimeException { - String url; - public RedirectException (String url) { - super ("Redirection Request to "+url); - this.url = url; + /** + * Creates a new RedirectException object. + * + * @param url ... + */ + public RedirectException(String url) { + super("Redirection Request to " + url); + this.url = url; } - public String getMessage () { - return url; + /** + * + * + * @return ... + */ + public String getMessage() { + return url; } + /** + * + * + * @param s ... + */ public void printStackTrace(java.io.PrintStream s) { - // do nothing + // do nothing } + /** + * + * + * @param w ... + */ public void printStackTrace(java.io.PrintWriter w) { - // do nothing + // do nothing } - } diff --git a/src/helma/framework/RequestBean.java b/src/helma/framework/RequestBean.java index d2589ad0..d49e69eb 100644 --- a/src/helma/framework/RequestBean.java +++ b/src/helma/framework/RequestBean.java @@ -1,74 +1,138 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.framework; +import helma.framework.core.Application; import java.io.Serializable; +import java.util.Date; import java.util.Map; -import helma.framework.core.Application; -import java.util.Date; - +/** + * + */ public class RequestBean implements Serializable { + RequestTrans req; - RequestTrans req; + /** + * Creates a new RequestBean object. + * + * @param req ... + */ + public RequestBean(RequestTrans req) { + this.req = req; + } - public RequestBean(RequestTrans req) { - this.req = req; - } + /** + * + * + * @param name ... + * + * @return ... + */ + public Object get(String name) { + return req.get(name); + } - public Object get (String name) { - return req.get (name); - } + /** + * + * + * @return ... + */ + public boolean isGet() { + return req.isGet(); + } - public boolean isGet () { - return req.isGet (); - } + /** + * + * + * @return ... + */ + public boolean isPost() { + return req.isPost(); + } - public boolean isPost () { - return req.isPost (); - } + /** + * + * + * @return ... + */ + public String toString() { + return "[Request]"; + } - public String toString() { - return "[Request]"; - } + // property related methods: + public String getaction() { + return req.action; + } - // property related methods: + /** + * + * + * @return ... + */ + public Map getdata() { + return req.getRequestData(); + } - public String getaction () { - return req.action; - } + /** + * + * + * @return ... + */ + public long getruntime() { + return (System.currentTimeMillis() - req.startTime); + } - public Map getdata () { - return req.getRequestData (); - } + /** + * + * + * @return ... + */ + public String getpassword() { + return req.getPassword(); + } - public long getruntime () { - return (System.currentTimeMillis() - req.startTime); - } + /** + * + * + * @return ... + */ + public String getpath() { + return req.path; + } - public String getpassword () { - return req.getPassword (); - } + /** + * + * + * @return ... + */ + public String getusername() { + return req.getUsername(); + } - public String getpath () { - return req.path; - } - - public String getusername () { - return req.getUsername (); - } - - /* public Date getLastModified () { - long since = req.getIfModifiedSince (); - if (since < 0) - return null; - else - return new Date (since); - } - - public void setLastModified () { - throw new RuntimeException ("The lastModified property of the Request object is read-only. "+ - "Set lastModified on the Response object if you want to mark the last modification date of a resource."); - } */ + /* public Date getLastModified () { + long since = req.getIfModifiedSince (); + if (since < 0) + return null; + else + return new Date (since); + } + public void setLastModified () { + throw new RuntimeException ("The lastModified property of the Request object is read-only. "+ + "Set lastModified on the Response object if you want to mark the last modification date of a resource."); + } */ } - - - diff --git a/src/helma/framework/RequestTrans.java b/src/helma/framework/RequestTrans.java index 89a33acf..3b4e8ba9 100644 --- a/src/helma/framework/RequestTrans.java +++ b/src/helma/framework/RequestTrans.java @@ -1,31 +1,48 @@ -// RequestTrans.java -// Copyright (c) Hannes Wallnöfer 1998-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.framework; -import java.io.*; -import java.util.*; import helma.objectmodel.*; import helma.util.Base64; +import java.io.*; +import java.util.*; /** - * A Transmitter for a request from the servlet client. Objects of this - * class are directly exposed to JavaScript as global property req. + * A Transmitter for a request from the servlet client. Objects of this + * class are directly exposed to JavaScript as global property req. */ - public class RequestTrans implements Externalizable { + static final long serialVersionUID = 5398880083482000580L; // the uri path of the request public String path; + // the request's session id public String session; + // the map of form and cookie data private Map values; + // the request method - 0 for GET, 1 for POST private byte httpMethod = 0; // timestamp of client-cached version, if present in request private long ifModifiedSince = -1; + // set of ETags the client sent with If-None-Match header private Set etags; @@ -34,185 +51,237 @@ public class RequestTrans implements Externalizable { // the name of the action being invoked public transient String action; - private transient String httpUsername; private transient String httpPassword; - static final long serialVersionUID = 5398880083482000580L; - /** * Create a new Request transmitter with an empty data map. */ - public RequestTrans () { - httpMethod = 0; - values = new HashMap (); + public RequestTrans() { + httpMethod = 0; + values = new HashMap(); } /** - * Create a new request transmitter with the given data map. - */ - public RequestTrans (byte method) { - httpMethod = method; - values = new HashMap (); + * Create a new request transmitter with the given data map. + */ + public RequestTrans(byte method) { + httpMethod = method; + values = new HashMap(); } /** * Set a parameter value in this request transmitter. */ - public void set (String name, Object value) { - values.put (name, value); + public void set(String name, Object value) { + values.put(name, value); } - /** * Get a value from the requests map by key. */ - public Object get (String name) { - try { - return values.get (name); - } catch (Exception x) { - return null; - } + public Object get(String name) { + try { + return values.get(name); + } catch (Exception x) { + return null; + } } /** * Get the data map for this request transmitter. */ - public Map getRequestData () { - return values; + public Map getRequestData() { + return values; } /** * The hash code is computed from the session id if available. This is used to * detect multiple identic requests. */ - public int hashCode () { - return session == null ? super.hashCode () : session.hashCode (); + public int hashCode() { + return (session == null) ? super.hashCode() : session.hashCode(); } - /** * A request is considered equal to another one if it has the same user, path, * and request data. This is used to evaluate multiple simultanous requests only once */ - public boolean equals (Object what) { - try { - RequestTrans other = (RequestTrans) what; - return (session.equals (other.session) && - path.equalsIgnoreCase (other.path) && - values.equals (other.getRequestData ())); - } catch (Exception x) { - return false; - } + public boolean equals(Object what) { + try { + RequestTrans other = (RequestTrans) what; + + return (session.equals(other.session) && path.equalsIgnoreCase(other.path) && + values.equals(other.getRequestData())); + } catch (Exception x) { + return false; + } } /** * Return true if this object represents a HTTP GET Request. */ - public boolean isGet () { - return httpMethod == 0; + public boolean isGet() { + return httpMethod == 0; } /** * Return true if this object represents a HTTP GET Request. */ - public boolean isPost () { - return httpMethod == 1; + public boolean isPost() { + return httpMethod == 1; } /** * Custom externalization code for quicker serialization. */ - public void readExternal (ObjectInput s) throws ClassNotFoundException, IOException { - path = s.readUTF (); - session = s.readUTF (); - values = (Map) s.readObject (); - httpMethod = s.readByte (); - ifModifiedSince = s.readLong (); - etags = (Set) s.readObject (); + public void readExternal(ObjectInput s) throws ClassNotFoundException, IOException { + path = s.readUTF(); + session = s.readUTF(); + values = (Map) s.readObject(); + httpMethod = s.readByte(); + ifModifiedSince = s.readLong(); + etags = (Set) s.readObject(); } /** * Custom externalization code for quicker serialization. */ - public void writeExternal (ObjectOutput s) throws IOException { - s.writeUTF (path); - s.writeUTF (session); - s.writeObject (values); - s.writeByte (httpMethod); - s.writeLong (ifModifiedSince); - s.writeObject (etags); + public void writeExternal(ObjectOutput s) throws IOException { + s.writeUTF(path); + s.writeUTF(session); + s.writeObject(values); + s.writeByte(httpMethod); + s.writeLong(ifModifiedSince); + s.writeObject(etags); } - public void setIfModifiedSince (long since) { - ifModifiedSince = since; + /** + * + * + * @param since ... + */ + public void setIfModifiedSince(long since) { + ifModifiedSince = since; } - public long getIfModifiedSince () { - return ifModifiedSince; + /** + * + * + * @return ... + */ + public long getIfModifiedSince() { + return ifModifiedSince; } - public void setETags (String etagHeader) { - etags = new HashSet(); - if (etagHeader.indexOf (",") > -1) { - StringTokenizer st = new StringTokenizer (etagHeader, ", \r\n"); - while (st.hasMoreTokens()) - etags.add (st.nextToken ()); - } else { - etags.add (etagHeader); - } + /** + * + * + * @param etagHeader ... + */ + public void setETags(String etagHeader) { + etags = new HashSet(); + + if (etagHeader.indexOf(",") > -1) { + StringTokenizer st = new StringTokenizer(etagHeader, ", \r\n"); + + while (st.hasMoreTokens()) + etags.add(st.nextToken()); + } else { + etags.add(etagHeader); + } } - public Set getETags () { - return etags; + /** + * + * + * @return ... + */ + public Set getETags() { + return etags; } - public boolean hasETag (String etag) { - if (etags == null || etag == null) - return false; - return etags.contains (etag); + /** + * + * + * @param etag ... + * + * @return ... + */ + public boolean hasETag(String etag) { + if ((etags == null) || (etag == null)) { + return false; + } + + return etags.contains(etag); } + /** + * + * + * @return ... + */ public String getUsername() { - if ( httpUsername!=null ) - return httpUsername; - String auth = (String)get("authorization"); - if ( auth==null || "".equals(auth) ) { - return null; - } - decodeHttpAuth(auth); - return httpUsername; + if (httpUsername != null) { + return httpUsername; + } + + String auth = (String) get("authorization"); + + if ((auth == null) || "".equals(auth)) { + return null; + } + + decodeHttpAuth(auth); + + return httpUsername; } - public String getPassword() { - if ( httpPassword!=null ) - return httpPassword; - String auth = (String)get("authorization"); - if ( auth==null || "".equals(auth) ) { - return null; - } - decodeHttpAuth(auth); - return httpPassword; + /** + * + * + * @return ... + */ + public String getPassword() { + if (httpPassword != null) { + return httpPassword; + } + + String auth = (String) get("authorization"); + + if ((auth == null) || "".equals(auth)) { + return null; + } + + decodeHttpAuth(auth); + + return httpPassword; } - private void decodeHttpAuth(String auth) { - if ( auth==null ) - return; - StringTokenizer tok; - if( auth.startsWith("Basic ") ) - tok = new StringTokenizer ( new String( Base64.decode((auth.substring(6)).toCharArray()) ), ":" ); - else - tok = new StringTokenizer ( new String( Base64.decode(auth.toCharArray()) ), ":" ); - try { - httpUsername = tok.nextToken(); - } catch ( NoSuchElementException e ) { - httpUsername = null; - } - try { - httpPassword = tok.nextToken(); - } catch ( NoSuchElementException e ) { - httpPassword = null; - } - } + private void decodeHttpAuth(String auth) { + if (auth == null) { + return; + } + StringTokenizer tok; + + if (auth.startsWith("Basic ")) { + tok = new StringTokenizer(new String(Base64.decode((auth.substring(6)).toCharArray())), + ":"); + } else { + tok = new StringTokenizer(new String(Base64.decode(auth.toCharArray())), ":"); + } + + try { + httpUsername = tok.nextToken(); + } catch (NoSuchElementException e) { + httpUsername = null; + } + + try { + httpPassword = tok.nextToken(); + } catch (NoSuchElementException e) { + httpPassword = null; + } + } } diff --git a/src/helma/framework/ResponseBean.java b/src/helma/framework/ResponseBean.java index b3803a9c..602b64a1 100644 --- a/src/helma/framework/ResponseBean.java +++ b/src/helma/framework/ResponseBean.java @@ -1,175 +1,386 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.framework; +import helma.framework.core.Application; import java.io.Serializable; +import java.util.Date; import java.util.Map; -import helma.framework.core.Application; -import java.util.Date; - +/** + * + */ public class ResponseBean implements Serializable { - ResponseTrans res; - public ResponseBean(ResponseTrans res) { - this.res = res; + /** + * Creates a new ResponseBean object. + * + * @param res ... + */ + public ResponseBean(ResponseTrans res) { + this.res = res; } - public void encode (Object what) { - res.encode (what); + /** + * + * + * @param what ... + */ + public void encode(Object what) { + res.encode(what); } - public void encodeXml (Object what) { - res.encodeXml (what); + /** + * + * + * @param what ... + */ + public void encodeXml(Object what) { + res.encodeXml(what); } - public void format (Object what) { - res.format (what); + /** + * + * + * @param what ... + */ + public void format(Object what) { + res.format(what); } - public void redirect (String url) throws RedirectException { - res.redirect (url); + /** + * + * + * @param url ... + * + * @throws RedirectException ... + */ + public void redirect(String url) throws RedirectException { + res.redirect(url); } - public void reset () { - res.reset (); + /** + * + */ + public void reset() { + res.reset(); } - public void setCookie (String key, String value) { - res.setCookie (key, value, -1, null, null); + /** + * + * + * @param key ... + * @param value ... + */ + public void setCookie(String key, String value) { + res.setCookie(key, value, -1, null, null); } - public void setCookie (String key, String value, int days) { - res.setCookie (key, value, days, null, null); - } - - public void setCookie (String key, String value, int days, String path) { - res.setCookie (key, value, days, path, null); + /** + * + * + * @param key ... + * @param value ... + * @param days ... + */ + public void setCookie(String key, String value, int days) { + res.setCookie(key, value, days, null, null); } - public void setCookie (String key, String value, int days, String path, String domain) { - res.setCookie (key, value, days, path, domain); + /** + * + * + * @param key ... + * @param value ... + * @param days ... + * @param path ... + */ + public void setCookie(String key, String value, int days, String path) { + res.setCookie(key, value, days, path, null); } - public void write (Object what) { - res.write (what); + /** + * + * + * @param key ... + * @param value ... + * @param days ... + * @param path ... + * @param domain ... + */ + public void setCookie(String key, String value, int days, String path, String domain) { + res.setCookie(key, value, days, path, domain); } - public void writeln (Object what) { - res.writeln (what); + /** + * + * + * @param what ... + */ + public void write(Object what) { + res.write(what); } - public void writeBinary (byte[] what) { - res.writeBinary (what); + /** + * + * + * @param what ... + */ + public void writeln(Object what) { + res.writeln(what); } - public void debug (Object message) { - res.debug (message); + /** + * + * + * @param what ... + */ + public void writeBinary(byte[] what) { + res.writeBinary(what); } + /** + * + * + * @param message ... + */ + public void debug(Object message) { + res.debug(message); + } + + /** + * + * + * @return ... + */ public String toString() { - return "[Response]"; + return "[Response]"; } - - // property-related methods: - - public boolean getcache () { - return res.cache; + // property-related methods: + public boolean getcache() { + return res.cache; } - public void setcache (boolean cache) { - res.cache = cache; + /** + * + * + * @param cache ... + */ + public void setcache(boolean cache) { + res.cache = cache; } - public String getcharset () { - return res.charset; + /** + * + * + * @return ... + */ + public String getcharset() { + return res.charset; } - public void setcharset (String charset) { - res.charset = charset; + /** + * + * + * @param charset ... + */ + public void setcharset(String charset) { + res.charset = charset; } - public String getcontentType () { - return res.contentType; + /** + * + * + * @return ... + */ + public String getcontentType() { + return res.contentType; } - public void setcontentType (String contentType) { - res.contentType = contentType; + /** + * + * + * @param contentType ... + */ + public void setcontentType(String contentType) { + res.contentType = contentType; } - public Map getdata () { - return res.getResponseData (); - } - - public Map gethandlers () { - return res.getMacroHandlers (); + /** + * + * + * @return ... + */ + public Map getdata() { + return res.getResponseData(); } - public String geterror () { - return res.error; + /** + * + * + * @return ... + */ + public Map gethandlers() { + return res.getMacroHandlers(); } - public String getmessage () { - return res.message; + /** + * + * + * @return ... + */ + public String geterror() { + return res.error; } - public void setmessage (String message) { - res.message = message; + /** + * + * + * @return ... + */ + public String getmessage() { + return res.message; } - public String getrealm () { - return res.realm; + /** + * + * + * @param message ... + */ + public void setmessage(String message) { + res.message = message; } - public void setrealm (String realm) { - res.realm = realm; + /** + * + * + * @return ... + */ + public String getrealm() { + return res.realm; } - public void setskinpath (Object[] arr) { - res.setSkinpath (arr); + /** + * + * + * @param realm ... + */ + public void setrealm(String realm) { + res.realm = realm; } - public Object[] getskinpath () { - return res.getSkinpath (); + /** + * + * + * @param arr ... + */ + public void setskinpath(Object[] arr) { + res.setSkinpath(arr); } - public int getstatus () { - return res.status; + /** + * + * + * @return ... + */ + public Object[] getskinpath() { + return res.getSkinpath(); } - public void setstatus (int status) { - res.status = status; + /** + * + * + * @return ... + */ + public int getstatus() { + return res.status; } - public Date getLastModified () { - long modified = res.getLastModified (); - if (modified > -1) - return new Date (modified); - else - return null; + /** + * + * + * @param status ... + */ + public void setstatus(int status) { + res.status = status; } - public void setLastModified (Date date) { - if (date == null) - res.setLastModified (-1); - else - res.setLastModified (date.getTime()); + /** + * + * + * @return ... + */ + public Date getLastModified() { + long modified = res.getLastModified(); + + if (modified > -1) { + return new Date(modified); + } else { + return null; + } } - public String getETag () { - return res.getETag (); - } - - public void setETag (String etag) { - res.setETag (etag); + /** + * + * + * @param date ... + */ + public void setLastModified(Date date) { + if (date == null) { + res.setLastModified(-1); + } else { + res.setLastModified(date.getTime()); + } } - public void dependsOn (Object what) { - res.dependsOn (what); + /** + * + * + * @return ... + */ + public String getETag() { + return res.getETag(); } - public void digest () { - res.digestDependencies (); + /** + * + * + * @param etag ... + */ + public void setETag(String etag) { + res.setETag(etag); + } + + /** + * + * + * @param what ... + */ + public void dependsOn(Object what) { + res.dependsOn(what); + } + + /** + * + */ + public void digest() { + res.digestDependencies(); } ///////////////////////////////////// @@ -177,14 +388,16 @@ public class ResponseBean implements Serializable { // Helma templates (*.hsp files) and shouldn't // be used otherwise. //////////////////////////////////// - - public void pushStringBuffer () { - res.pushStringBuffer (); + public void pushStringBuffer() { + res.pushStringBuffer(); } - public String popStringBuffer () { - return res.popStringBuffer (); + /** + * + * + * @return ... + */ + public String popStringBuffer() { + return res.popStringBuffer(); } - } - diff --git a/src/helma/framework/ResponseTrans.java b/src/helma/framework/ResponseTrans.java index e9cea874..c40b0c56 100644 --- a/src/helma/framework/ResponseTrans.java +++ b/src/helma/framework/ResponseTrans.java @@ -1,21 +1,35 @@ -// ResponseTrans.java -// Copyright (c) Hannes Wallnöfer 1998-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.framework; -import java.io.*; -import java.util.*; import helma.framework.core.Skin; import helma.objectmodel.*; import helma.util.*; +import java.io.*; import java.security.*; +import java.util.*; /** - * A Transmitter for a response to the servlet client. Objects of this - * class are directly exposed to JavaScript as global property res. + * A Transmitter for a response to the servlet client. Objects of this + * class are directly exposed to JavaScript as global property res. */ - public final class ResponseTrans implements Externalizable { + static final long serialVersionUID = -8627370766119740844L; + static final int INITIAL_BUFFER_SIZE = 2048; /** * Set the MIME content type of the response. @@ -50,11 +64,13 @@ public final class ResponseTrans implements Externalizable { // contains the redirect URL private String redir = null; - + // the last-modified date, if it should be set in the response private long lastModified = -1; + // flag to signal that resource has not been modified private boolean notModified = false; + // Entity Tag for this response, used for conditional GETs private String etag = null; @@ -63,19 +79,19 @@ public final class ResponseTrans implements Externalizable { // the buffer used to build the response private transient StringBuffer buffer = null; + // these are used to implement the _as_string variants for Hop templates. private transient Stack buffers; // the path used to tell where to look for skins private transient Object[] skinpath = null; + // hashmap for skin caching private transient HashMap skincache; - + // buffer for debug messages - will be automatically appended to response private transient StringBuffer debugBuffer; - static final long serialVersionUID = -8627370766119740844L; - /** * string fields that hold a user message */ @@ -85,147 +101,169 @@ public final class ResponseTrans implements Externalizable { * string fields that hold an error message */ public transient String error; - - static final int INITIAL_BUFFER_SIZE = 2048; // the map of form and cookie data private transient Map values; // the map of macro handlers private transient Map handlers; - + // the request trans for this response private transient RequestTrans reqtrans; // the message digest used to generate composed digests for ETag headers private transient MessageDigest digest; - + // the appliciation checksum to make ETag headers sensitive to app changes long applicationChecksum; - - public ResponseTrans () { - super (); - message = error = null; - values = new HashMap (); - handlers = new HashMap (); + /** + * Creates a new ResponseTrans object. + */ + public ResponseTrans() { + super(); + message = error = null; + values = new HashMap(); + handlers = new HashMap(); } - public ResponseTrans (RequestTrans req) { - this(); - reqtrans = req; + /** + * Creates a new ResponseTrans object. + * + * @param req ... + */ + public ResponseTrans(RequestTrans req) { + this(); + reqtrans = req; } - /** * Get a value from the responses map by key. */ - public Object get (String name) { - try { - return values.get (name); - } catch (Exception x) { - return null; - } + public Object get(String name) { + try { + return values.get(name); + } catch (Exception x) { + return null; + } } /** * Get the data map for this response transmitter. */ - public Map getResponseData () { - return values; + public Map getResponseData() { + return values; } /** * Get the macro handlers map for this response transmitter. */ - public Map getMacroHandlers () { - return handlers; + public Map getMacroHandlers() { + return handlers; } - /** * Reset the response object to its initial empty state. */ - public void reset () { - if (buffer != null) - buffer.setLength (0); - buffers = null; - response = null; - redir = null; - skin = null; - message = error = null; - values.clear (); - lastModified = -1; - notModified = false; - etag = null; - if (digest != null) - digest.reset(); - } + public void reset() { + if (buffer != null) { + buffer.setLength(0); + } + buffers = null; + response = null; + redir = null; + skin = null; + message = error = null; + values.clear(); + lastModified = -1; + notModified = false; + etag = null; + + if (digest != null) { + digest.reset(); + } + } /** * This is called before a skin is rendered as string (renderSkinAsString) to redirect the output * to a new string buffer. */ - public void pushStringBuffer () { - if (buffers == null) - buffers = new Stack(); - if (buffer != null) - buffers.push (buffer); - buffer = new StringBuffer (64); + public void pushStringBuffer() { + if (buffers == null) { + buffers = new Stack(); + } + + if (buffer != null) { + buffers.push(buffer); + } + + buffer = new StringBuffer(64); } /** * Returns the content of the current string buffer and switches back to the previos one. */ - public String popStringBuffer () { - StringBuffer b = buffer; - buffer = buffers.empty() ? null : (StringBuffer) buffers.pop (); - return b.toString (); + public String popStringBuffer() { + StringBuffer b = buffer; + + buffer = buffers.empty() ? null : (StringBuffer) buffers.pop(); + + return b.toString(); } /** * Get the response buffer, creating it if it doesn't exist */ - public StringBuffer getBuffer () { - if (buffer == null) - buffer = new StringBuffer (INITIAL_BUFFER_SIZE); - return buffer; + public StringBuffer getBuffer() { + if (buffer == null) { + buffer = new StringBuffer(INITIAL_BUFFER_SIZE); + } + + return buffer; } - /** - * Append a string to the response unchanged. This is often called + * Append a string to the response unchanged. This is often called * at the end of a request to write out the whole page, so if buffer * is uninitialized we just set it to the string argument. */ - public void write (Object what) { - if (what != null) { - String str = what.toString (); - if (buffer == null) - buffer = new StringBuffer (Math.max (str.length()+100, INITIAL_BUFFER_SIZE)); - buffer.append (what.toString ()); - } + public void write(Object what) { + if (what != null) { + String str = what.toString(); + + if (buffer == null) { + buffer = new StringBuffer(Math.max(str.length() + 100, INITIAL_BUFFER_SIZE)); + } + + buffer.append(what.toString()); + } } /** * Utility function that appends a <br> to whatever is written. */ - public void writeln (Object what) { - if (buffer == null) - buffer = new StringBuffer (INITIAL_BUFFER_SIZE); - if (what != null) - buffer.append (what.toString ()); - buffer.append ("<br />\r\n"); + public void writeln(Object what) { + if (buffer == null) { + buffer = new StringBuffer(INITIAL_BUFFER_SIZE); + } + + if (what != null) { + buffer.append(what.toString()); + } + + buffer.append("<br />\r\n"); } /** * Append a part from a char array to the response buffer. */ - public void writeCharArray (char[] c, int start, int length) { - if (buffer == null) - buffer = new StringBuffer (Math.max (length, INITIAL_BUFFER_SIZE)); - buffer.append (c, start, length); + public void writeCharArray(char[] c, int start, int length) { + if (buffer == null) { + buffer = new StringBuffer(Math.max(length, INITIAL_BUFFER_SIZE)); + } + + buffer.append(c, start, length); } /** @@ -233,83 +271,114 @@ public final class ResponseTrans implements Externalizable { * that buffer exists and its length is larger than offset. str may be null, in which * case nothing happens. */ - public void debug (Object message) { - if (debugBuffer == null) - debugBuffer = new StringBuffer (); - String str = message == null ? "null" : message.toString (); - debugBuffer.append ("<p><span style=\"background: yellow; color: black\">"); - debugBuffer.append (str); - debugBuffer.append ("</span></p>"); + public void debug(Object message) { + if (debugBuffer == null) { + debugBuffer = new StringBuffer(); + } + + String str = (message == null) ? "null" : message.toString(); + + debugBuffer.append("<p><span style=\"background: yellow; color: black\">"); + debugBuffer.append(str); + debugBuffer.append("</span></p>"); } /** * Replace special characters with entities, including <, > and ", thus allowing * no HTML tags. */ - public void encode (Object what) { - if (what != null) { - String str = what.toString (); - if (buffer == null) - buffer = new StringBuffer (Math.max (str.length()+100, INITIAL_BUFFER_SIZE)); - HtmlEncoder.encodeAll (str, buffer); - } + public void encode(Object what) { + if (what != null) { + String str = what.toString(); + + if (buffer == null) { + buffer = new StringBuffer(Math.max(str.length() + 100, INITIAL_BUFFER_SIZE)); + } + + HtmlEncoder.encodeAll(str, buffer); + } } /** * Replace special characters with entities but pass through HTML tags */ - public void format (Object what) { - if (what != null) { - String str = what.toString (); - if (buffer == null) - buffer = new StringBuffer (Math.max (str.length()+100, INITIAL_BUFFER_SIZE)); - HtmlEncoder.encode (str, buffer); - } - } + public void format(Object what) { + if (what != null) { + String str = what.toString(); + if (buffer == null) { + buffer = new StringBuffer(Math.max(str.length() + 100, INITIAL_BUFFER_SIZE)); + } + + HtmlEncoder.encode(str, buffer); + } + } /** * Replace special characters with entities, including <, > and ", thus allowing * no HTML tags. */ - public void encodeXml (Object what) { - if (what != null) { - String str = what.toString (); - if (buffer == null) - buffer = new StringBuffer (Math.max (str.length()+100, INITIAL_BUFFER_SIZE)); - HtmlEncoder.encodeXml (str, buffer); - } - } + public void encodeXml(Object what) { + if (what != null) { + String str = what.toString(); + if (buffer == null) { + buffer = new StringBuffer(Math.max(str.length() + 100, INITIAL_BUFFER_SIZE)); + } + + HtmlEncoder.encodeXml(str, buffer); + } + } /** * Encode HTML entities, but leave newlines alone. This is for the content of textarea forms. */ - public void encodeForm (Object what) { - if (what != null) { - String str = what.toString (); - if (buffer == null) - buffer = new StringBuffer (Math.max (str.length()+100, INITIAL_BUFFER_SIZE)); - HtmlEncoder.encodeAll (str, buffer, false); - } + public void encodeForm(Object what) { + if (what != null) { + String str = what.toString(); + + if (buffer == null) { + buffer = new StringBuffer(Math.max(str.length() + 100, INITIAL_BUFFER_SIZE)); + } + + HtmlEncoder.encodeAll(str, buffer, false); + } } + /** + * + * + * @param str ... + */ + public void append(String str) { + if (str != null) { + if (buffer == null) { + buffer = new StringBuffer(Math.max(str.length(), INITIAL_BUFFER_SIZE)); + } - public void append (String str) { - if (str != null) { - if (buffer == null) - buffer = new StringBuffer (Math.max (str.length(), INITIAL_BUFFER_SIZE)); - buffer.append (str); - } + buffer.append(str); + } } - public void redirect (String url) throws RedirectException { - redir = url; - throw new RedirectException (url); + /** + * + * + * @param url ... + * + * @throws RedirectException ... + */ + public void redirect(String url) throws RedirectException { + redir = url; + throw new RedirectException(url); } - public String getRedirect () { - return redir; + /** + * + * + * @return ... + */ + public String getRedirect() { + return redir; } /** @@ -317,251 +386,407 @@ public final class ResponseTrans implements Externalizable { * overwrite the previous output. We take a generic object as parameter to be able to * generate a better error message, but it must be byte[]. */ - public void writeBinary (byte[] what) { - response = what; + public void writeBinary(byte[] what) { + response = what; } - /** * This has to be called after writing to this response has finished and before it is shipped back to the * web server. Transforms the string buffer into a char array to minimize size. */ - public synchronized void close (String cset) throws UnsupportedEncodingException { - // only use default charset if not explicitly set for this response. - if (charset == null) - charset = cset; - // if charset is not set, use western encoding - if (charset == null) - charset = "ISO-8859-1"; - boolean encodingError = false; - // only close if the response hasn't been closed yet - if (response == null) { - // if debug buffer exists, append it to main buffer - if (debugBuffer != null) { - if (buffer == null) - buffer = debugBuffer; - else - buffer.append (debugBuffer); - } - // get the buffer's bytes in the specified encoding - if (buffer != null) { - try { - response = buffer.toString ().getBytes (charset); - } catch (UnsupportedEncodingException uee) { - encodingError = true; - response = buffer.toString ().getBytes (); - } - // make sure this is done only once, even with more requsts attached - buffer = null; - } else { - response = new byte[0]; - } - } - // if etag is not set, calc MD5 digest and check it - if (etag == null && lastModified == -1 && redir == null) try { - digest = MessageDigest.getInstance("MD5"); - // if (contentType != null) - // digest.update (contentType.getBytes()); - byte[] b = digest.digest(response); - etag = "\""+new String (Base64.encode(b))+"\""; - if (reqtrans != null && reqtrans.hasETag (etag)) { - response = new byte[0]; - notModified = true; - } - } catch (Exception ignore) { - // Etag creation failed for some reason. Ignore. - } - notifyAll (); - // if there was a problem with the encoding, let the app know - if (encodingError) - throw new UnsupportedEncodingException (charset); + public synchronized void close(String cset) throws UnsupportedEncodingException { + // only use default charset if not explicitly set for this response. + if (charset == null) { + charset = cset; + } + + // if charset is not set, use western encoding + if (charset == null) { + charset = "ISO-8859-1"; + } + + boolean encodingError = false; + + // only close if the response hasn't been closed yet + if (response == null) { + // if debug buffer exists, append it to main buffer + if (debugBuffer != null) { + if (buffer == null) { + buffer = debugBuffer; + } else { + buffer.append(debugBuffer); + } + } + + // get the buffer's bytes in the specified encoding + if (buffer != null) { + try { + response = buffer.toString().getBytes(charset); + } catch (UnsupportedEncodingException uee) { + encodingError = true; + response = buffer.toString().getBytes(); + } + + // make sure this is done only once, even with more requsts attached + buffer = null; + } else { + response = new byte[0]; + } + } + + // if etag is not set, calc MD5 digest and check it + if ((etag == null) && (lastModified == -1) && (redir == null)) { + try { + digest = MessageDigest.getInstance("MD5"); + + // if (contentType != null) + // digest.update (contentType.getBytes()); + byte[] b = digest.digest(response); + + etag = "\"" + new String(Base64.encode(b)) + "\""; + + if ((reqtrans != null) && reqtrans.hasETag(etag)) { + response = new byte[0]; + notModified = true; + } + } catch (Exception ignore) { + // Etag creation failed for some reason. Ignore. + } + } + + notifyAll(); + + // if there was a problem with the encoding, let the app know + if (encodingError) { + throw new UnsupportedEncodingException(charset); + } } /** * If we just attached to evaluation we call this instead of close because only the primary thread * is responsible for closing the result */ - public synchronized void waitForClose () { - try { - if (response == null) - wait (10000l); - } catch (InterruptedException ix) {} + public synchronized void waitForClose() { + try { + if (response == null) { + wait(10000L); + } + } catch (InterruptedException ix) { + } } - public byte[] getContent () { - return response == null ? new byte[0] : response; + /** + * + * + * @return ... + */ + public byte[] getContent() { + return (response == null) ? new byte[0] : response; } - public int getContentLength () { - if (response != null) - return response.length; - return 0; + /** + * + * + * @return ... + */ + public int getContentLength() { + if (response != null) { + return response.length; + } + + return 0; } - public String getContentType () { - if (charset != null) - return contentType+"; charset="+charset; - return contentType; + /** + * + * + * @return ... + */ + public String getContentType() { + if (charset != null) { + return contentType + "; charset=" + charset; + } + + return contentType; } - public void setLastModified (long modified) { - if (modified > -1 && reqtrans != null && - reqtrans.getIfModifiedSince() >= modified) - { - notModified = true; - throw new RedirectException (null); - } - lastModified = modified; + /** + * + * + * @param modified ... + */ + public void setLastModified(long modified) { + if ((modified > -1) && (reqtrans != null) && + (reqtrans.getIfModifiedSince() >= modified)) { + notModified = true; + throw new RedirectException(null); + } + + lastModified = modified; } - public long getLastModified () { - return lastModified; + /** + * + * + * @return ... + */ + public long getLastModified() { + return lastModified; } - public void setETag (String value) { - etag = value == null ? null : "\""+value+"\""; - if (etag != null && reqtrans != null && reqtrans.hasETag (etag)) { - notModified = true; - throw new RedirectException (null); - } - } - - public String getETag () { - return etag; - } - - public boolean getNotModified () { - return notModified; + /** + * + * + * @param value ... + */ + public void setETag(String value) { + etag = (value == null) ? null : ("\"" + value + "\""); + + if ((etag != null) && (reqtrans != null) && reqtrans.hasETag(etag)) { + notModified = true; + throw new RedirectException(null); + } } - public void dependsOn (Object what) { - if (digest == null) try { - digest = MessageDigest.getInstance ("MD5"); - } catch (NoSuchAlgorithmException nsa) { - // MD5 should always be available - } - if (what == null) { - digest.update (new byte[0]); - } else if (what instanceof Date) { - digest.update (MD5Encoder.toBytes(((Date) what).getTime())); - } else if (what instanceof byte[]) { - digest.update ((byte[]) what); - } else { - String str = what.toString(); - if (str != null) - digest.update (str.getBytes ()); - else - digest.update (new byte[0]); - } + /** + * + * + * @return ... + */ + public String getETag() { + return etag; } - public void digestDependencies () { - if (digest == null) - return; - byte[] b = digest.digest(MD5Encoder.toBytes (applicationChecksum)); - /* StringBuffer buf = new StringBuffer(b.length*2); - for ( int i=0; i<b.length; i++ ) { - int j = (b[i]<0) ? 256+b[i] : b[i]; - if ( j<16 ) buf.append("0"); - buf.append(Integer.toHexString(j)); - } - setETag (buf.toString ()); */ - setETag (new String (Base64.encode(b))); + /** + * + * + * @return ... + */ + public boolean getNotModified() { + return notModified; } - public void setApplicationChecksum (long n) { - applicationChecksum = n; + /** + * + * + * @param what ... + */ + public void dependsOn(Object what) { + if (digest == null) { + try { + digest = MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException nsa) { + // MD5 should always be available + } + } + + if (what == null) { + digest.update(new byte[0]); + } else if (what instanceof Date) { + digest.update(MD5Encoder.toBytes(((Date) what).getTime())); + } else if (what instanceof byte[]) { + digest.update((byte[]) what); + } else { + String str = what.toString(); + + if (str != null) { + digest.update(str.getBytes()); + } else { + digest.update(new byte[0]); + } + } } - public void setSkinpath (Object[] arr) { - this.skinpath = arr; - skincache = null; + /** + * + */ + public void digestDependencies() { + if (digest == null) { + return; + } + + byte[] b = digest.digest(MD5Encoder.toBytes(applicationChecksum)); + + /* StringBuffer buf = new StringBuffer(b.length*2); + for ( int i=0; i<b.length; i++ ) { + int j = (b[i]<0) ? 256+b[i] : b[i]; + if ( j<16 ) buf.append("0"); + buf.append(Integer.toHexString(j)); + } + setETag (buf.toString ()); */ + setETag(new String(Base64.encode(b))); } - public Object[] getSkinpath () { - if (skinpath == null) - skinpath = new Object[0]; - return skinpath; + /** + * + * + * @param n ... + */ + public void setApplicationChecksum(long n) { + applicationChecksum = n; } - public Skin getCachedSkin (String id) { - if (skincache == null) - return null; - return (Skin) skincache.get (id); + /** + * + * + * @param arr ... + */ + public void setSkinpath(Object[] arr) { + this.skinpath = arr; + skincache = null; } - public void cacheSkin (String id, Skin skin) { - if (skincache == null) - skincache = new HashMap (); - skincache.put (id, skin); + /** + * + * + * @return ... + */ + public Object[] getSkinpath() { + if (skinpath == null) { + skinpath = new Object[0]; + } + + return skinpath; } - public void setCookie (String key, String value, int days, String path, String domain) { - CookieTrans c = null; - if (cookies == null) { - cookies = new HashMap (); - } else { - c = (CookieTrans) cookies.get (key); - } - if (c == null) { - c = new CookieTrans (key, value); - cookies.put (key, c); - } else { - c.setValue (value); - } - c.setDays (days); - c.setPath (path); - c.setDomain (domain); + /** + * + * + * @param id ... + * + * @return ... + */ + public Skin getCachedSkin(String id) { + if (skincache == null) { + return null; + } + + return (Skin) skincache.get(id); } - public void resetCookies () { - if (cookies != null) - cookies.clear (); + /** + * + * + * @param id ... + * @param skin ... + */ + public void cacheSkin(String id, Skin skin) { + if (skincache == null) { + skincache = new HashMap(); + } + + skincache.put(id, skin); } - public int countCookies () { - if (cookies != null) - return cookies.size(); - return 0; + /** + * + * + * @param key ... + * @param value ... + * @param days ... + * @param path ... + * @param domain ... + */ + public void setCookie(String key, String value, int days, String path, String domain) { + CookieTrans c = null; + + if (cookies == null) { + cookies = new HashMap(); + } else { + c = (CookieTrans) cookies.get(key); + } + + if (c == null) { + c = new CookieTrans(key, value); + cookies.put(key, c); + } else { + c.setValue(value); + } + + c.setDays(days); + c.setPath(path); + c.setDomain(domain); } - public CookieTrans[] getCookies () { - if (cookies == null) - return new CookieTrans[0]; - CookieTrans[] c = new CookieTrans[cookies.size()]; - cookies.values().toArray (c); - return c; + /** + * + */ + public void resetCookies() { + if (cookies != null) { + cookies.clear(); + } } + /** + * + * + * @return ... + */ + public int countCookies() { + if (cookies != null) { + return cookies.size(); + } - public void readExternal (ObjectInput s) throws ClassNotFoundException, IOException { - contentType = (String) s.readObject (); - response = (byte[]) s.readObject (); - redir = (String) s.readObject (); - cookies = (Map) s.readObject (); - cache = s.readBoolean (); - status = s.readInt (); - realm = (String) s.readObject (); - lastModified = s.readLong (); - notModified = s.readBoolean (); - charset = (String) s.readObject (); - etag = (String) s.readObject (); + return 0; } - public void writeExternal (ObjectOutput s) throws IOException { - s.writeObject (contentType); - s.writeObject (response); - s.writeObject (redir); - s.writeObject (cookies); - s.writeBoolean (cache); - s.writeInt (status); - s.writeObject (realm); - s.writeLong (lastModified); - s.writeBoolean (notModified); - s.writeObject (charset); - s.writeObject (etag); + /** + * + * + * @return ... + */ + public CookieTrans[] getCookies() { + if (cookies == null) { + return new CookieTrans[0]; + } + + CookieTrans[] c = new CookieTrans[cookies.size()]; + + cookies.values().toArray(c); + + return c; } + /** + * + * + * @param s ... + * + * @throws ClassNotFoundException ... + * @throws IOException ... + */ + public void readExternal(ObjectInput s) throws ClassNotFoundException, IOException { + contentType = (String) s.readObject(); + response = (byte[]) s.readObject(); + redir = (String) s.readObject(); + cookies = (Map) s.readObject(); + cache = s.readBoolean(); + status = s.readInt(); + realm = (String) s.readObject(); + lastModified = s.readLong(); + notModified = s.readBoolean(); + charset = (String) s.readObject(); + etag = (String) s.readObject(); + } + + /** + * + * + * @param s ... + * + * @throws IOException ... + */ + public void writeExternal(ObjectOutput s) throws IOException { + s.writeObject(contentType); + s.writeObject(response); + s.writeObject(redir); + s.writeObject(cookies); + s.writeBoolean(cache); + s.writeInt(status); + s.writeObject(realm); + s.writeLong(lastModified); + s.writeBoolean(notModified); + s.writeObject(charset); + s.writeObject(etag); + } } - - diff --git a/src/helma/framework/TimeoutException.java b/src/helma/framework/TimeoutException.java index fed5079d..4a02afd6 100644 --- a/src/helma/framework/TimeoutException.java +++ b/src/helma/framework/TimeoutException.java @@ -1,18 +1,31 @@ -// TimeoutException.java -// Copyright (c) Hannes Wallnöfer 1998-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.framework; + /** - * TimeoutException is thrown by the request evaluator when a request could - * not be serviced within the timeout period specified for an application. + * TimeoutException is thrown by the request evaluator when a request could + * not be serviced within the timeout period specified for an application. */ - public class TimeoutException extends RuntimeException { - public TimeoutException () { - super ("Request timed out"); + /** + * Creates a new TimeoutException object. + */ + public TimeoutException() { + super("Request timed out"); } } - - - diff --git a/src/helma/framework/core/AppClassLoader.java b/src/helma/framework/core/AppClassLoader.java index b2ba2888..d9254888 100644 --- a/src/helma/framework/core/AppClassLoader.java +++ b/src/helma/framework/core/AppClassLoader.java @@ -1,37 +1,53 @@ -// ApplicationClassLoader.java +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.framework.core; import java.net.URL; import java.net.URLClassLoader; -import java.util.Enumeration; import java.security.CodeSource; import java.security.Permission; import java.security.PermissionCollection; import java.security.Permissions; - +import java.util.Enumeration; /** * ClassLoader subclass with package accessible addURL method. */ public class AppClassLoader extends URLClassLoader { - private final String appname; - /** - * Create a HelmaClassLoader with the given application name and the given URLs - */ + /** + * Create a HelmaClassLoader with the given application name and the given URLs + */ public AppClassLoader(String appname, URL[] urls) { - super ( urls, AppClassLoader.class.getClassLoader()); - this.appname = appname; + super(urls, AppClassLoader.class.getClassLoader()); + this.appname = appname; } - protected void addURL (URL url) { - super.addURL (url); + protected void addURL(URL url) { + super.addURL(url); } - public String getAppName () { - return appname; + /** + * + * + * @return ... + */ + public String getAppName() { + return appname; } - } diff --git a/src/helma/framework/core/Application.java b/src/helma/framework/core/Application.java index 1088bd3a..627ab771 100644 --- a/src/helma/framework/core/Application.java +++ b/src/helma/framework/core/Application.java @@ -1,24 +1,37 @@ -// Application.java -// Copyright (c) Hannes Wallnöfer 1998-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.framework.core; -import helma.extensions.HelmaExtension; import helma.extensions.ConfigurationException; +import helma.extensions.HelmaExtension; import helma.framework.*; import helma.main.Server; -import helma.scripting.*; import helma.objectmodel.*; import helma.objectmodel.db.*; +import helma.scripting.*; import helma.util.*; import org.apache.xmlrpc.*; -import java.util.*; import java.io.*; -import java.net.URLEncoder; -import java.net.MalformedURLException; import java.lang.reflect.*; +import java.net.MalformedURLException; +import java.net.URLEncoder; import java.rmi.*; import java.rmi.server.*; +import java.util.*; /** * The central class of a Helma application. This class keeps a pool of so-called @@ -27,14 +40,24 @@ import java.rmi.server.*; * the evaluators. */ public final class Application implements IPathElement, Runnable { - // the name of this application private String name; - + // properties and db-properties - SystemProperties props, dbProps; + SystemProperties props; + + // properties and db-properties + SystemProperties dbProps; + // home, app and data directories - File home, appDir, dbDir; + File home; + + // home, app and data directories + File appDir; + + // home, app and data directories + File dbDir; + // this application's node manager protected NodeManager nmgr; @@ -44,9 +67,9 @@ public final class Application implements IPathElement, Runnable { String rootObjectClass; /** - * The type manager checks if anything in the application's prototype definitions - * has been updated prior to each evaluation. - */ + * The type manager checks if anything in the application's prototype definitions + * has been updated prior to each evaluation. + */ public TypeManager typemgr; /** @@ -55,21 +78,19 @@ public final class Application implements IPathElement, Runnable { protected SkinManager skinmgr; /** - * Each application has one internal request evaluator for calling - * the scheduler and other internal functions. - */ + * Each application has one internal request evaluator for calling + * the scheduler and other internal functions. + */ RequestEvaluator eval; /** - * Collections for evaluator thread pooling - */ + * Collections for evaluator thread pooling + */ protected Stack freeThreads; protected Vector allThreads; - boolean stopped = false; boolean debug; long starttime; - Hashtable sessions; Hashtable dbSources; @@ -85,21 +106,24 @@ public final class Application implements IPathElement, Runnable { Hashtable activeRequests; // Two logs for each application: events and accesses - Logger eventLog, accessLog; + Logger eventLog; + + // Two logs for each application: events and accesses + Logger accessLog; // A transient node that is shared among all evaluators protected INode cachenode; - + // some fields for statistics protected volatile long requestCount = 0; protected volatile long xmlrpcCount = 0; protected volatile long errorCount = 0; - // the URL-prefix to use for links into this application private String baseURI; - - private DbMapping rootMapping, userRootMapping, userMapping; + private DbMapping rootMapping; + private DbMapping userRootMapping; + private DbMapping userMapping; // name of response encoding String charset; @@ -109,287 +133,338 @@ public final class Application implements IPathElement, Runnable { // Map of java class names to object prototypes Properties classMapping; + // Map of extensions allowed for public skins Properties skinExtensions; // time we last read the properties file - private long lastPropertyRead = 0l; - + private long lastPropertyRead = 0L; + // the set of prototype/function pairs which are allowed to be called via XML-RPC private HashSet xmlrpcAccess; // the name under which this app serves XML-RPC requests. Defaults to the app name private String xmlrpcHandlerName; + // the list of cron jobs + private Map activeCronJobs = null; + private Vector cronJobs = null; + Hashtable customCronJobs = null; /** * Build an application with the given name in the app directory. No Server-wide * properties are created or used. */ - public Application (String name, File appDir, File dbDir) - throws RemoteException, IllegalArgumentException { - this (name, null, appDir, dbDir); + public Application(String name, File appDir, File dbDir) + throws RemoteException, IllegalArgumentException { + this(name, null, appDir, dbDir); } /** * Build an application with the given name and server instance. The * app directories will be created if they don't exist already. */ - public Application (String name, Server server) - throws RemoteException, IllegalArgumentException { - - this (name, server, null, null); + public Application(String name, Server server) + throws RemoteException, IllegalArgumentException { + this(name, server, null, null); } /** * Build an application with the given name, server instance, app and * db directories. */ - public Application (String name, Server server, File customAppDir, File customDbDir) - throws RemoteException, IllegalArgumentException { + public Application(String name, Server server, File customAppDir, File customDbDir) + throws RemoteException, IllegalArgumentException { + if ((name == null) || (name.trim().length() == 0)) { + throw new IllegalArgumentException("Invalid application name: " + name); + } - if (name == null || name.trim().length() == 0) - throw new IllegalArgumentException ("Invalid application name: "+name); + this.name = name; + appDir = customAppDir; + dbDir = customDbDir; - this.name = name; - appDir = customAppDir; - dbDir = customDbDir; + // system-wide properties, default to null + SystemProperties sysProps; - // system-wide properties, default to null - SystemProperties sysProps, sysDbProps; - sysProps = sysDbProps = null; - home = null; + // system-wide properties, default to null + SystemProperties sysDbProps; - if (server != null) { - home = server.getHopHome (); - // if appDir and dbDir weren't explicitely passed, use the - // standard subdirectories of the Hop home directory - if (appDir == null) { - appDir = new File (home, "apps"); - appDir = new File (appDir, name); - } - if (dbDir == null) { - dbDir = new File (home, "db"); - dbDir = new File (dbDir, name); - } - // get system-wide properties - sysProps = server.getProperties (); - sysDbProps = server.getDbProperties (); - } - // create the directories if they do not exist already - if (!appDir.exists()) - appDir.mkdirs (); - if (!dbDir.exists()) - dbDir.mkdirs (); + sysProps = sysDbProps = null; + home = null; - // give the Helma Thread group a name so the threads can be recognized - threadgroup = new ThreadGroup ("TX-"+name); + if (server != null) { + home = server.getHopHome(); - // create app-level properties - File propfile = new File (appDir, "app.properties"); - props = new SystemProperties (propfile.getAbsolutePath (), sysProps); + // if appDir and dbDir weren't explicitely passed, use the + // standard subdirectories of the Hop home directory + if (appDir == null) { + appDir = new File(home, "apps"); + appDir = new File(appDir, name); + } - // create app-level db sources - File dbpropfile = new File (appDir, "db.properties"); - dbProps = new SystemProperties (dbpropfile.getAbsolutePath (), sysDbProps); + if (dbDir == null) { + dbDir = new File(home, "db"); + dbDir = new File(dbDir, name); + } - // the passwd file, to be used with the authenticate() function - CryptFile parentpwfile = null; - if (home != null) - parentpwfile = new CryptFile (new File (home, "passwd"), null); - pwfile = new CryptFile (new File (appDir, "passwd"), parentpwfile); + // get system-wide properties + sysProps = server.getProperties(); + sysDbProps = server.getDbProperties(); + } - // the properties that map java class names to prototype names - File classMappingFile = new File (appDir, "class.properties"); - classMapping = new SystemProperties (classMappingFile.getAbsolutePath ()); + // create the directories if they do not exist already + if (!appDir.exists()) { + appDir.mkdirs(); + } - // get class name of root object if defined. Otherwise native Helma objectmodel will be used. - rootObjectClass = classMapping.getProperty ("root"); + if (!dbDir.exists()) { + dbDir.mkdirs(); + } - updateProperties (); + // give the Helma Thread group a name so the threads can be recognized + threadgroup = new ThreadGroup("TX-" + name); - sessions = new Hashtable (); - dbSources = new Hashtable (); - modules = new Hashtable (); + // create app-level properties + File propfile = new File(appDir, "app.properties"); - cachenode = new TransientNode ("app"); + props = new SystemProperties(propfile.getAbsolutePath(), sysProps); + + // create app-level db sources + File dbpropfile = new File(appDir, "db.properties"); + + dbProps = new SystemProperties(dbpropfile.getAbsolutePath(), sysDbProps); + + // the passwd file, to be used with the authenticate() function + CryptFile parentpwfile = null; + + if (home != null) { + parentpwfile = new CryptFile(new File(home, "passwd"), null); + } + + pwfile = new CryptFile(new File(appDir, "passwd"), parentpwfile); + + // the properties that map java class names to prototype names + File classMappingFile = new File(appDir, "class.properties"); + + classMapping = new SystemProperties(classMappingFile.getAbsolutePath()); + + // get class name of root object if defined. Otherwise native Helma objectmodel will be used. + rootObjectClass = classMapping.getProperty("root"); + + updateProperties(); + + sessions = new Hashtable(); + dbSources = new Hashtable(); + modules = new Hashtable(); + + cachenode = new TransientNode("app"); } /** * Get the application ready to run, initializing the evaluators and type manager. */ - public void init () throws DatabaseException, ScriptingException, MalformedURLException { + public void init() + throws DatabaseException, ScriptingException, MalformedURLException { + Vector extensions = Server.getServer().getExtensions(); - Vector extensions = Server.getServer ().getExtensions (); - for (int i=0; i<extensions.size(); i++) { - HelmaExtension ext = (HelmaExtension)extensions.get(i); - try { - ext.applicationStarted (this); - } catch (ConfigurationException e) { - logEvent ("couldn't init extension " + ext.getName () + ": " + e.toString ()); - } - } + for (int i = 0; i < extensions.size(); i++) { + HelmaExtension ext = (HelmaExtension) extensions.get(i); - // read the sessions if wanted - if ("true".equalsIgnoreCase (getProperty("persistentSessions"))) { - loadSessionData (null); - } + try { + ext.applicationStarted(this); + } catch (ConfigurationException e) { + logEvent("couldn't init extension " + ext.getName() + ": " + + e.toString()); + } + } - typemgr = new TypeManager (this); - typemgr.createPrototypes (); - // logEvent ("Started type manager for "+name); + // read the sessions if wanted + if ("true".equalsIgnoreCase(getProperty("persistentSessions"))) { + loadSessionData(null); + } - // eval = new RequestEvaluator (this); - logEvent ("Starting evaluators for "+name); - freeThreads = new Stack (); - allThreads = new Vector (); - // allThreads.addElement (eval); - - // preallocate minThreads request evaluators - int minThreads = 0; - try { - minThreads = Integer.parseInt (props.getProperty ("minThreads")); - } catch (Exception ignore) {} - for (int i=0; i<minThreads; i++) { - RequestEvaluator ev = new RequestEvaluator (this); - ev.initScriptingEngine (); - freeThreads.push (ev); - allThreads.addElement (ev); - } - activeRequests = new Hashtable (); + typemgr = new TypeManager(this); + typemgr.createPrototypes(); - skinmgr = new SkinManager (this); + // logEvent ("Started type manager for "+name); + // eval = new RequestEvaluator (this); + logEvent("Starting evaluators for " + name); + freeThreads = new Stack(); + allThreads = new Vector(); - rootMapping = getDbMapping ("root"); - userMapping = getDbMapping ("user"); - SystemProperties p = new SystemProperties (); - String usernameField = userMapping.getNameField (); - if (usernameField == null) - usernameField = "name"; - p.put ("_children", "collection(user)"); - p.put ("_children.accessname", usernameField); - userRootMapping = new DbMapping (this, "__userroot__", p); - userRootMapping.update (); + // allThreads.addElement (eval); + // preallocate minThreads request evaluators + int minThreads = 0; - nmgr = new NodeManager (this, dbDir.getAbsolutePath (), props); + try { + minThreads = Integer.parseInt(props.getProperty("minThreads")); + } catch (Exception ignore) { + } + + for (int i = 0; i < minThreads; i++) { + RequestEvaluator ev = new RequestEvaluator(this); + + ev.initScriptingEngine(); + freeThreads.push(ev); + allThreads.addElement(ev); + } + + activeRequests = new Hashtable(); + activeCronJobs = new WeakHashMap(); + customCronJobs = new Hashtable(); + + skinmgr = new SkinManager(this); + + rootMapping = getDbMapping("root"); + userMapping = getDbMapping("user"); + + SystemProperties p = new SystemProperties(); + String usernameField = userMapping.getNameField(); + + if (usernameField == null) { + usernameField = "name"; + } + + p.put("_children", "collection(user)"); + p.put("_children.accessname", usernameField); + userRootMapping = new DbMapping(this, "__userroot__", p); + userRootMapping.update(); + + nmgr = new NodeManager(this, dbDir.getAbsolutePath(), props); } /** * Create and start scheduler and cleanup thread */ - public void start () { - starttime = System.currentTimeMillis(); - worker = new Thread (this, "Worker-"+name); - worker.setPriority (Thread.NORM_PRIORITY+2); - worker.start (); - // logEvent ("session cleanup and scheduler thread started"); + public void start() { + starttime = System.currentTimeMillis(); + worker = new Thread(this, "Worker-" + name); + worker.setPriority(Thread.NORM_PRIORITY + 2); + worker.start(); + + // logEvent ("session cleanup and scheduler thread started"); } /** * This is called to shut down a running application. */ - public void stop () { + public void stop() { + stopped = true; - stopped = true; + // stop all threads, this app is going down + if (worker != null) { + worker.interrupt(); + } - // stop all threads, this app is going down - if (worker != null) - worker.interrupt (); - worker = null; + worker = null; - // stop evaluators - if (allThreads != null) { - for (Enumeration e=allThreads.elements (); e.hasMoreElements (); ) { - RequestEvaluator ev = (RequestEvaluator) e.nextElement (); - ev.stopThread (); - } - } + // stop evaluators + if (allThreads != null) { + for (Enumeration e = allThreads.elements(); e.hasMoreElements();) { + RequestEvaluator ev = (RequestEvaluator) e.nextElement(); - // remove evaluators - allThreads.removeAllElements (); - freeThreads = null; + ev.stopThread(); + } + } - // shut down node manager and embedded db - try { - nmgr.shutdown (); - } catch (DatabaseException dbx) { - System.err.println ("Error shutting down embedded db: "+dbx); - } + // remove evaluators + allThreads.removeAllElements(); + freeThreads = null; - // null out type manager - typemgr = null; + // shut down node manager and embedded db + try { + nmgr.shutdown(); + } catch (DatabaseException dbx) { + System.err.println("Error shutting down embedded db: " + dbx); + } - // tell the extensions that we're stopped. - Vector extensions = Server.getServer ().getExtensions (); - for (int i=0; i<extensions.size(); i++) { - HelmaExtension ext = (HelmaExtension)extensions.get(i); - ext.applicationStopped (this); - } + // null out type manager + typemgr = null; - // store the sessions if wanted - if ("true".equalsIgnoreCase (getProperty("persistentSessions"))) { - storeSessionData (null); - } + // tell the extensions that we're stopped. + Vector extensions = Server.getServer().getExtensions(); - // stop logs if they exist - if (eventLog != null) { - eventLog.close (); - } - if (accessLog != null) { - accessLog.close (); - } + for (int i = 0; i < extensions.size(); i++) { + HelmaExtension ext = (HelmaExtension) extensions.get(i); + ext.applicationStopped(this); + } + + // store the sessions if wanted + if ("true".equalsIgnoreCase(getProperty("persistentSessions"))) { + storeSessionData(null); + } + + // stop logs if they exist + if (eventLog != null) { + eventLog.close(); + } + + if (accessLog != null) { + accessLog.close(); + } } /** * Returns a free evaluator to handle a request. */ - protected RequestEvaluator getEvaluator () { - if (stopped) - throw new ApplicationStoppedException (); - // first try - try { - return (RequestEvaluator) freeThreads.pop (); - } catch (EmptyStackException nothreads) { - int maxThreads = 12; - try { - maxThreads = Integer.parseInt (props.getProperty ("maxThreads")); - } catch (Exception ignore) { - // property not set, use default value - } - synchronized (this) { - // allocate a new evaluator - if (allThreads.size() < maxThreads) { - logEvent ("Starting evaluator "+(allThreads.size()+1) +" for application "+name); - RequestEvaluator ev = new RequestEvaluator (this); - allThreads.addElement (ev); - return (ev); - } - } - } - // we can't create a new evaluator, so we wait if one becomes available. - // give it 3 more tries, waiting 3 seconds each time. - for (int i=0; i<4; i++) { - try { - Thread.currentThread().sleep(3000); - return (RequestEvaluator) freeThreads.pop (); - } catch (EmptyStackException nothreads) { - // do nothing - } catch (InterruptedException inter) { - throw new RuntimeException ("Thread interrupted."); - } - } - // no luck, give up. - throw new RuntimeException ("Maximum Thread count reached."); + protected RequestEvaluator getEvaluator() { + if (stopped) { + throw new ApplicationStoppedException(); + } + + // first try + try { + return (RequestEvaluator) freeThreads.pop(); + } catch (EmptyStackException nothreads) { + int maxThreads = 12; + + try { + maxThreads = Integer.parseInt(props.getProperty("maxThreads")); + } catch (Exception ignore) { + // property not set, use default value + } + + synchronized (this) { + // allocate a new evaluator + if (allThreads.size() < maxThreads) { + logEvent("Starting evaluator " + (allThreads.size() + 1) + + " for application " + name); + + RequestEvaluator ev = new RequestEvaluator(this); + + allThreads.addElement(ev); + + return (ev); + } + } + } + + // we can't create a new evaluator, so we wait if one becomes available. + // give it 3 more tries, waiting 3 seconds each time. + for (int i = 0; i < 4; i++) { + try { + Thread.currentThread().sleep(3000); + + return (RequestEvaluator) freeThreads.pop(); + } catch (EmptyStackException nothreads) { + // do nothing + } catch (InterruptedException inter) { + throw new RuntimeException("Thread interrupted."); + } + } + + // no luck, give up. + throw new RuntimeException("Maximum Thread count reached."); } /** * Returns an evaluator back to the pool when the work is done. */ - protected void releaseEvaluator (RequestEvaluator ev) { + protected void releaseEvaluator(RequestEvaluator ev) { if (ev != null) { - ev.recycle (); - freeThreads.push (ev); + ev.recycle(); + freeThreads.push(ev); } } @@ -397,134 +472,154 @@ public final class Application implements IPathElement, Runnable { * This can be used to set the maximum number of evaluators which will be allocated. * If evaluators are required beyound this number, an error will be thrown. */ - public boolean setNumberOfEvaluators (int n) { - if (n < 2 || n > 511) - return false; - int current = allThreads.size(); - synchronized (allThreads) { - if (n > current) { - int toBeCreated = n - current; - for (int i=0; i<toBeCreated; i++) { - RequestEvaluator ev = new RequestEvaluator (this); - freeThreads.push (ev); - allThreads.addElement (ev); - } - } else if (n < current) { - int toBeDestroyed = current - n; - for (int i=0; i<toBeDestroyed; i++) { - try { - RequestEvaluator re = (RequestEvaluator) freeThreads.pop (); - allThreads.removeElement (re); - // typemgr.unregisterRequestEvaluator (re); - re.stopThread (); - } catch (EmptyStackException empty) { - return false; - } - } - } - } - return true; + public boolean setNumberOfEvaluators(int n) { + if ((n < 2) || (n > 511)) { + return false; + } + + int current = allThreads.size(); + + synchronized (allThreads) { + if (n > current) { + int toBeCreated = n - current; + + for (int i = 0; i < toBeCreated; i++) { + RequestEvaluator ev = new RequestEvaluator(this); + + freeThreads.push(ev); + allThreads.addElement(ev); + } + } else if (n < current) { + int toBeDestroyed = current - n; + + for (int i = 0; i < toBeDestroyed; i++) { + try { + RequestEvaluator re = (RequestEvaluator) freeThreads.pop(); + + allThreads.removeElement(re); + + // typemgr.unregisterRequestEvaluator (re); + re.stopThread(); + } catch (EmptyStackException empty) { + return false; + } + } + } + } + + return true; } /** * Return the number of currently active threads */ - public int getActiveThreads () { - return 0; + public int getActiveThreads() { + return 0; } /** * Execute a request coming in from a web client. */ - public ResponseTrans execute (RequestTrans req) { + public ResponseTrans execute(RequestTrans req) { + requestCount += 1; - requestCount += 1; + // get user for this request's session + Session session = checkSession(req.session); - // get user for this request's session - Session session = checkSession (req.session); - session.touch(); + session.touch(); - ResponseTrans res = null; - RequestEvaluator ev = null; - // are we responsible for releasing the evaluator and closing the result? - boolean primaryRequest = false; - try { - // first look if a request with same user/path/data is already being executed. - // if so, attach the request to its output instead of starting a new evaluation - // this helps to cleanly solve "doubleclick" kind of users - ev = (RequestEvaluator) activeRequests.get (req); - if (ev != null) { - res = ev.attachRequest (req); - } - if (res == null) { - primaryRequest = true; - // if attachRequest returns null this means we came too late - // and the other request was finished in the meantime + ResponseTrans res = null; + RequestEvaluator ev = null; - // check if the properties file has been updated - updateProperties (); - // get evaluator and invoke - ev = getEvaluator (); - res = ev.invoke (req, session); - } - } catch (ApplicationStoppedException stopped) { - // let the servlet know that this application has gone to heaven - throw stopped; - } catch (Exception x) { - errorCount += 1; - res = new ResponseTrans (); - res.write ("Error in application: <b>" + x.getMessage () + "</b>"); - } finally { - if (primaryRequest) { - activeRequests.remove (req); - releaseEvaluator (ev); - // response needs to be closed/encoded before sending it back - try { - res.close (charset); - } catch (UnsupportedEncodingException uee) { - logEvent ("Unsupported response encoding: "+uee.getMessage()); - } - } else { - res.waitForClose (); - } - } - return res; + // are we responsible for releasing the evaluator and closing the result? + boolean primaryRequest = false; + + try { + // first look if a request with same user/path/data is already being executed. + // if so, attach the request to its output instead of starting a new evaluation + // this helps to cleanly solve "doubleclick" kind of users + ev = (RequestEvaluator) activeRequests.get(req); + + if (ev != null) { + res = ev.attachRequest(req); + } + + if (res == null) { + primaryRequest = true; + + // if attachRequest returns null this means we came too late + // and the other request was finished in the meantime + // check if the properties file has been updated + updateProperties(); + + // get evaluator and invoke + ev = getEvaluator(); + res = ev.invoke(req, session); + } + } catch (ApplicationStoppedException stopped) { + // let the servlet know that this application has gone to heaven + throw stopped; + } catch (Exception x) { + errorCount += 1; + res = new ResponseTrans(); + res.write("Error in application: <b>" + x.getMessage() + "</b>"); + } finally { + if (primaryRequest) { + activeRequests.remove(req); + releaseEvaluator(ev); + + // response needs to be closed/encoded before sending it back + try { + res.close(charset); + } catch (UnsupportedEncodingException uee) { + logEvent("Unsupported response encoding: " + uee.getMessage()); + } + } else { + res.waitForClose(); + } + } + + return res; } - /** * Called to execute a method via XML-RPC, usally by helma.main.ApplicationManager * which acts as default handler/request dispatcher. */ - public Object executeXmlRpc (String method, Vector args) throws Exception { - xmlrpcCount += 1; - Object retval = null; - RequestEvaluator ev = null; - try { - // check if the properties file has been updated - updateProperties (); - // get evaluator and invoke - ev = getEvaluator (); - retval = ev.invokeXmlRpc (method, args.toArray()); - } finally { - releaseEvaluator (ev); - } - return retval; + public Object executeXmlRpc(String method, Vector args) + throws Exception { + xmlrpcCount += 1; + + Object retval = null; + RequestEvaluator ev = null; + + try { + // check if the properties file has been updated + updateProperties(); + + // get evaluator and invoke + ev = getEvaluator(); + retval = ev.invokeXmlRpc(method, args.toArray()); + } finally { + releaseEvaluator(ev); + } + + return retval; } /** * Reset the application's object cache, causing all objects to be refetched from * the database. */ - public void clearCache () { - nmgr.clearCache (); + public void clearCache() { + nmgr.clearCache(); } /** * Returns the number of elements in the NodeManager's cache */ - public int getCacheUsage () { - return nmgr.countCacheEntries (); + public int getCacheUsage() { + return nmgr.countCacheEntries(); } /** @@ -532,50 +627,59 @@ public final class Application implements IPathElement, Runnable { * with a non-null object, the helma node manager will be bypassed. This function * can be used to script and publish any Java object structure with Helma. */ - public void setDataRoot (Object root) { - this.rootObject = root; + public void setDataRoot(Object root) { + this.rootObject = root; } /** * This method returns the root object of this application's object tree. */ - public Object getDataRoot () { - // check if we have a custom root object class - if (rootObjectClass != null) { - // create custom root element. - if (rootObject == null) { - try { - if ( classMapping.containsKey("root.factory.class") && classMapping.containsKey("root.factory.method") ) { - Class c = typemgr.loader.loadClass( classMapping.getProperty("root.factory.class") ); - Method m = c.getMethod( classMapping.getProperty("root.factory.method"), null ); - rootObject = m.invoke(c, null); - } else { - Class c = typemgr.loader.loadClass( classMapping.getProperty("root") ); - rootObject = c.newInstance(); - } - } catch ( Exception e ) { - throw new RuntimeException ( "Error creating root object: " + e.toString() ); - } - } - return rootObject; - } - // no custom root object is defined - use standard helma objectmodel - else { - // INode root = nmgr.safe.getNode ("0", rootMapping); - // root.setDbMapping (rootMapping); - // rootObject = root; - rootObject = nmgr.safe.getNode ("0", rootMapping); - return rootObject; - } + public Object getDataRoot() { + // check if we have a custom root object class + if (rootObjectClass != null) { + // create custom root element. + if (rootObject == null) { + try { + if (classMapping.containsKey("root.factory.class") && + classMapping.containsKey("root.factory.method")) { + Class c = typemgr.loader.loadClass(classMapping.getProperty("root.factory.class")); + Method m = c.getMethod(classMapping.getProperty("root.factory.method"), + null); + + rootObject = m.invoke(c, null); + } else { + Class c = typemgr.loader.loadClass(classMapping.getProperty("root")); + + rootObject = c.newInstance(); + } + } catch (Exception e) { + throw new RuntimeException("Error creating root object: " + + e.toString()); + } + } + + return rootObject; + } + // no custom root object is defined - use standard helma objectmodel + else { + // INode root = nmgr.safe.getNode ("0", rootMapping); + // root.setDbMapping (rootMapping); + // rootObject = root; + rootObject = nmgr.safe.getNode("0", rootMapping); + + return rootObject; + } } /** * Returns the Object which contains registered users of this application. */ - public INode getUserRoot () { - INode users = nmgr.safe.getNode ("1", userRootMapping); - users.setDbMapping (userRootMapping); - return users; + public INode getUserRoot() { + INode users = nmgr.safe.getNode("1", userRootMapping); + + users.setDbMapping(userRootMapping); + + return users; } /** @@ -583,90 +687,100 @@ public final class Application implements IPathElement, Runnable { * the gateway to the helma.objectmodel packages, which perform the mapping of objects to * relational database tables or the embedded database. */ - public WrappedNodeManager getWrappedNodeManager () { - return nmgr.safe; + public WrappedNodeManager getWrappedNodeManager() { + return nmgr.safe; } /** * Return a transient node that is shared by all evaluators of this application ("app node") */ - public INode getCacheNode () { - return cachenode; + public INode getCacheNode() { + return cachenode; } - /** * Returns a Node representing a registered user of this application by his or her user name. */ - public INode getUserNode (String uid) { - try { - INode users = getUserRoot (); - return users.getNode (uid); - } catch (Exception x) { - return null; - } - } + public INode getUserNode(String uid) { + try { + INode users = getUserRoot(); + return users.getNode(uid); + } catch (Exception x) { + return null; + } + } /** * Return a prototype for a given node. If the node doesn't specify a prototype, * return the generic hopobject prototype. */ - public Prototype getPrototype (Object obj) { - String protoname = getPrototypeName (obj); - if (protoname == null) - return typemgr.getPrototype ("hopobject"); - Prototype p = typemgr.getPrototype (protoname); - if (p == null) - p = typemgr.getPrototype ("hopobject"); - return p; + public Prototype getPrototype(Object obj) { + String protoname = getPrototypeName(obj); + + if (protoname == null) { + return typemgr.getPrototype("hopobject"); + } + + Prototype p = typemgr.getPrototype(protoname); + + if (p == null) { + p = typemgr.getPrototype("hopobject"); + } + + return p; } /** * Return a collection containing all prototypes defined for this application */ - public Collection getPrototypes () { - return typemgr.prototypes.values (); + public Collection getPrototypes() { + return typemgr.prototypes.values(); } /** * Return a skin for a given object. The skin is found by determining the prototype * to use for the object, then looking up the skin for the prototype. */ - public Skin getSkin (Object object, String skinname, Object[] skinpath) { - Prototype proto = getPrototype (object); - if (proto == null) - return null; - return skinmgr.getSkin (proto, skinname, skinpath); + public Skin getSkin(Object object, String skinname, Object[] skinpath) { + Prototype proto = getPrototype(object); + + if (proto == null) { + return null; + } + + return skinmgr.getSkin(proto, skinname, skinpath); } /** * Return the session currently associated with a given Hop session ID. * Create a new session if necessary. */ - public Session checkSession (String sessionID) { - Session session = getSession(sessionID); - if ( session==null ) { - session = new Session (sessionID, this); - sessions.put (sessionID, session); - } - return session; + public Session checkSession(String sessionID) { + Session session = getSession(sessionID); + + if (session == null) { + session = new Session(sessionID, this); + sessions.put(sessionID, session); + } + + return session; } /** * Remove the session from the sessions-table and logout the user. */ - public void destroySession (String sessionID) { - logoutSession (getSession (sessionID)); - sessions.remove (sessionID); + public void destroySession(String sessionID) { + logoutSession(getSession(sessionID)); + sessions.remove(sessionID); } /** * Remove the session from the sessions-table and logout the user. */ - public void destroySession (Session session) { - logoutSession (session); - sessions.remove (session.getSessionID ()); + public void destroySession(Session session) { + logoutSession(session); + sessions.remove(session.getSessionID()); } /** @@ -674,158 +788,194 @@ public final class Application implements IPathElement, Runnable { * actual changes from the table itself, which is managed by the application. * It is safe and allowed to manipulate the session objects contained in the table, though. */ - public Map getSessions () { - return (Map) sessions.clone (); + public Map getSessions() { + return (Map) sessions.clone(); } - /** * Return a list of Helma nodes (HopObjects - the database object representing the user, * not the session object) representing currently logged in users. */ - public List getActiveUsers () { - ArrayList list = new ArrayList(); - // used to keep track of already added users - we only return - // one object per user, and users may have multiple sessions - HashSet usernames = new HashSet (); - for (Enumeration e=sessions.elements(); e.hasMoreElements(); ) { - Session s = (Session) e.nextElement (); - if(s==null) { - continue; - } else if (s.isLoggedIn() && !usernames.contains (s.getUID ()) ) { - // returns a session if it is logged in and has not been - // returned before (so for each logged-in user we get one - // session object, even if this user is logged in several - // times (used to retrieve the active users list). - INode node = s.getUserNode (); - // we check again because user may have been logged out between the first check - if (node != null) { - usernames.add (s.getUID ()); - list.add(node); - } - } - } - return list; - } + public List getActiveUsers() { + ArrayList list = new ArrayList(); + // used to keep track of already added users - we only return + // one object per user, and users may have multiple sessions + HashSet usernames = new HashSet(); + + for (Enumeration e = sessions.elements(); e.hasMoreElements();) { + Session s = (Session) e.nextElement(); + + if (s == null) { + continue; + } else if (s.isLoggedIn() && !usernames.contains(s.getUID())) { + // returns a session if it is logged in and has not been + // returned before (so for each logged-in user we get one + // session object, even if this user is logged in several + // times (used to retrieve the active users list). + INode node = s.getUserNode(); + + // we check again because user may have been logged out between the first check + if (node != null) { + usernames.add(s.getUID()); + list.add(node); + } + } + } + + return list; + } /** * Return a list of Helma nodes (HopObjects - the database object representing the user, * not the session object) representing registered users of this application. */ - public List getRegisteredUsers () { - ArrayList list = new ArrayList (); - INode users = getUserRoot (); - // first try to get them from subnodes (db) - for (Enumeration e=users.getSubnodes(); e.hasMoreElements(); ) { - list.add ((INode)e.nextElement ()); - } - // if none, try to get them from properties (internal db) - if (list.size()==0) { - for (Enumeration e=users.properties(); e.hasMoreElements(); ) { - list.add (users.getNode ((String)e.nextElement ())); - } - } - return list; - } + public List getRegisteredUsers() { + ArrayList list = new ArrayList(); + INode users = getUserRoot(); + // first try to get them from subnodes (db) + for (Enumeration e = users.getSubnodes(); e.hasMoreElements();) { + list.add((INode) e.nextElement()); + } + + // if none, try to get them from properties (internal db) + if (list.size() == 0) { + for (Enumeration e = users.properties(); e.hasMoreElements();) { + list.add(users.getNode((String) e.nextElement())); + } + } + + return list; + } /** * Return an array of <code>SessionBean</code> objects currently associated with a given * Helma user. */ - public List getSessionsForUsername (String username) { - ArrayList list = new ArrayList(); - if (username == null) - return list; - for (Enumeration e=sessions.elements(); e.hasMoreElements(); ) { - Session s = (Session) e.nextElement (); - if(s==null) { - continue; - } else if (username.equals (s.getUID ())) { - // append to list if session is logged in and fits the given username - list.add (new SessionBean (s)); - } - } - return list; - } + public List getSessionsForUsername(String username) { + ArrayList list = new ArrayList(); + if (username == null) { + return list; + } + + for (Enumeration e = sessions.elements(); e.hasMoreElements();) { + Session s = (Session) e.nextElement(); + + if (s == null) { + continue; + } else if (username.equals(s.getUID())) { + // append to list if session is logged in and fits the given username + list.add(new SessionBean(s)); + } + } + + return list; + } /** * Return the session currently associated with a given Hop session ID. */ - public Session getSession (String sessionID) { - if (sessionID == null) - return null; - return (Session) sessions.get (sessionID); - } + public Session getSession(String sessionID) { + if (sessionID == null) { + return null; + } + + return (Session) sessions.get(sessionID); + } /** * Register a user with the given user name and password. */ - public INode registerUser (String uname, String password) { - if (uname == null) - return null; - uname = uname.toLowerCase ().trim (); - if ("".equals (uname)) - return null; - INode unode = null; - try { - INode users = getUserRoot (); - unode = users.getNode (uname); - if (unode != null) - return null; + public INode registerUser(String uname, String password) { + if (uname == null) { + return null; + } - unode = users.createNode (uname); - unode.setPrototype ("user"); - unode.setDbMapping (userMapping); - String usernameField = userMapping.getNameField (); - String usernameProp = null; - if (usernameField != null) - usernameProp = userMapping.columnNameToProperty (usernameField); - if (usernameProp == null) - usernameProp = "name"; - unode.setName (uname); - unode.setString (usernameProp, uname); - unode.setString ("password", password); - return unode; - } catch (Exception x) { - logEvent ("Error registering User: "+x); - return null; - } + uname = uname.toLowerCase().trim(); + + if ("".equals(uname)) { + return null; + } + + INode unode = null; + + try { + INode users = getUserRoot(); + + unode = users.getNode(uname); + + if (unode != null) { + return null; + } + + unode = users.createNode(uname); + unode.setPrototype("user"); + unode.setDbMapping(userMapping); + + String usernameField = userMapping.getNameField(); + String usernameProp = null; + + if (usernameField != null) { + usernameProp = userMapping.columnNameToProperty(usernameField); + } + + if (usernameProp == null) { + usernameProp = "name"; + } + + unode.setName(uname); + unode.setString(usernameProp, uname); + unode.setString("password", password); + + return unode; + } catch (Exception x) { + logEvent("Error registering User: " + x); + + return null; + } } /** * Log in a user given his or her user name and password. */ - public boolean loginSession (String uname, String password, Session session) { - // Check the name/password of a user and log it in to the current session - if (uname == null) - return false; - uname = uname.toLowerCase ().trim (); - if ("".equals (uname)) - return false; - try { - INode users = getUserRoot (); - Node unode = (Node) users.getNode (uname); - String pw = unode.getString ("password"); - if (pw != null && pw.equals (password)) { - // let the old user-object forget about this session - logoutSession(session); - session.login (unode); - return true; - } - } catch (Exception x) { - return false; - } - return false; + public boolean loginSession(String uname, String password, Session session) { + // Check the name/password of a user and log it in to the current session + if (uname == null) { + return false; + } + + uname = uname.toLowerCase().trim(); + + if ("".equals(uname)) { + return false; + } + + try { + INode users = getUserRoot(); + Node unode = (Node) users.getNode(uname); + String pw = unode.getString("password"); + + if ((pw != null) && pw.equals(password)) { + // let the old user-object forget about this session + logoutSession(session); + session.login(unode); + + return true; + } + } catch (Exception x) { + return false; + } + + return false; } /** * Log out a session from this application. */ - public void logoutSession (Session session) { - session.logout(); + public void logoutSession(Session session) { + session.logout(); } /** @@ -833,118 +983,146 @@ public final class Application implements IPathElement, Runnable { * authenticated against a passwd file in the application directory. This is to have some sort of * authentication available *before* the application is up and running, i.e. for application setup tasks. */ - public boolean authenticate (String uname, String password) { - if (uname == null || password == null) - return false; - return pwfile.authenticate (uname, password); + public boolean authenticate(String uname, String password) { + if ((uname == null) || (password == null)) { + return false; + } + + return pwfile.authenticate(uname, password); } /** * Return the href to the root of this application. */ - public String getRootHref () { - return getNodeHref (getDataRoot(), null); + public String getRootHref() { + return getNodeHref(getDataRoot(), null); } - /** * Return a path to be used in a URL pointing to the given element and action */ - public String getNodeHref (Object elem, String actionName) { - // Object root = getDataRoot (); - // check optional root prototype from app.properties - String rootProto = props.getProperty ("rootPrototype"); + public String getNodeHref(Object elem, String actionName) { + // Object root = getDataRoot (); + // check optional root prototype from app.properties + String rootProto = props.getProperty("rootPrototype"); - StringBuffer b = new StringBuffer (baseURI); + StringBuffer b = new StringBuffer(baseURI); - composeHref (elem, b, rootProto, 0); + composeHref(elem, b, rootProto, 0); - if (actionName != null) - b.append (UrlEncoded.encode (actionName)); + if (actionName != null) { + b.append(UrlEncoded.encode(actionName)); + } - return b.toString (); + return b.toString(); } - private final void composeHref (Object elem, StringBuffer b, String rootProto, int pathCount) { - if (elem == null || pathCount > 20) - return; - if (rootProto != null && rootProto.equals (getPrototypeName (elem))) - return; - Object parent = getParentElement (elem); - if (parent == null) - return; - composeHref (getParentElement (elem), b, rootProto, pathCount++); - b.append (UrlEncoded.encode (getElementName (elem))); - b.append ("/"); + private final void composeHref(Object elem, StringBuffer b, String rootProto, + int pathCount) { + if ((elem == null) || (pathCount > 20)) { + return; + } + + if ((rootProto != null) && rootProto.equals(getPrototypeName(elem))) { + return; + } + + Object parent = getParentElement(elem); + + if (parent == null) { + return; + } + + composeHref(getParentElement(elem), b, rootProto, pathCount++); + b.append(UrlEncoded.encode(getElementName(elem))); + b.append("/"); } /** * This method sets the base URL of this application which will be prepended to * the actual object path. */ - public void setBaseURI (String uri) { - if (uri == null) - this.baseURI = "/"; - else if (!uri.endsWith ("/")) - this.baseURI = uri+"/"; - else - this.baseURI = uri; + public void setBaseURI(String uri) { + if (uri == null) { + this.baseURI = "/"; + } else if (!uri.endsWith("/")) { + this.baseURI = uri + "/"; + } else { + this.baseURI = uri; + } } /** - * Return true if the baseURI property is defined in the application + * Return true if the baseURI property is defined in the application * properties, false otherwise. */ - public boolean hasExplicitBaseURI () { - return props.containsKey ("baseuri"); + public boolean hasExplicitBaseURI() { + return props.containsKey("baseuri"); } /** * Tell other classes whether they should output logging information for this application. */ - public boolean debug () { - return debug; + public boolean debug() { + return debug; } - public RequestEvaluator getCurrentRequestEvaluator () { - Thread thread = Thread.currentThread (); - int l = allThreads.size(); - for (int i=0; i<l; i++) { - RequestEvaluator r = (RequestEvaluator) allThreads.get (i); - if (r != null && r.rtx == thread) - return r; - } - return null; + /** + * + * + * @return ... + */ + public RequestEvaluator getCurrentRequestEvaluator() { + Thread thread = Thread.currentThread(); + int l = allThreads.size(); + + for (int i = 0; i < l; i++) { + RequestEvaluator r = (RequestEvaluator) allThreads.get(i); + + if ((r != null) && (r.rtx == thread)) { + return r; + } + } + + return null; } /** * Utility function invoker for the methods below. This *must* be called * by an active RequestEvaluator thread. */ - private Object invokeFunction (Object obj, String func, Object[] args) { - Thread thread = Thread.currentThread (); - RequestEvaluator reval = null; - int l = allThreads.size(); - for (int i=0; i<l; i++) { - RequestEvaluator r = (RequestEvaluator) allThreads.get (i); - if (r != null && r.rtx == thread) - reval = r; - } - if (reval != null) try { - return reval.invokeDirectFunction (obj, func, args); - } catch (Exception x) { - if (debug) - System.err.println ("Error in Application.invokeFunction ("+func+"): "+x); - } - return null; + private Object invokeFunction(Object obj, String func, Object[] args) { + Thread thread = Thread.currentThread(); + RequestEvaluator reval = null; + int l = allThreads.size(); + + for (int i = 0; i < l; i++) { + RequestEvaluator r = (RequestEvaluator) allThreads.get(i); + + if ((r != null) && (r.rtx == thread)) { + reval = r; + } + } + + if (reval != null) { + try { + return reval.invokeDirectFunction(obj, func, args); + } catch (Exception x) { + if (debug) { + System.err.println("Error in Application.invokeFunction (" + func + + "): " + x); + } + } + } + + return null; } - /** * Return the application's classloader */ - public ClassLoader getClassLoader () { - return typemgr.loader; + public ClassLoader getClassLoader() { + return typemgr.loader; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -958,511 +1136,707 @@ public final class Application implements IPathElement, Runnable { /** * Return the name to be used to get this element from its parent */ - public String getElementName (Object obj) { - if (obj instanceof IPathElement) - return ((IPathElement) obj).getElementName (); - Object retval = invokeFunction (obj, "getElementName", null); - if (retval != null) - return retval.toString (); - return null; + public String getElementName(Object obj) { + if (obj instanceof IPathElement) { + return ((IPathElement) obj).getElementName(); + } + + Object retval = invokeFunction(obj, "getElementName", null); + + if (retval != null) { + return retval.toString(); + } + + return null; } /** * Retrieve a child element of this object by name. */ - public Object getChildElement (Object obj, String name) { - if (obj instanceof IPathElement) - return ((IPathElement) obj).getChildElement (name); - Object[] arg = new Object[1]; - arg[0] = name; - return invokeFunction (obj, "getChildElement", arg); + public Object getChildElement(Object obj, String name) { + if (obj instanceof IPathElement) { + return ((IPathElement) obj).getChildElement(name); + } + + Object[] arg = new Object[1]; + + arg[0] = name; + + return invokeFunction(obj, "getChildElement", arg); } /** * Return the parent element of this object. */ - public Object getParentElement (Object obj) { - if (obj instanceof IPathElement) - return ((IPathElement) obj).getParentElement (); - return invokeFunction (obj, "getParentElement", null); - } + public Object getParentElement(Object obj) { + if (obj instanceof IPathElement) { + return ((IPathElement) obj).getParentElement(); + } + return invokeFunction(obj, "getParentElement", null); + } /** * Get the name of the prototype to be used for this object. This will * determine which scripts, actions and skins can be called on it * within the Helma scripting and rendering framework. */ - public String getPrototypeName (Object obj) { - if (obj == null) - return "global"; - // check if e implements the IPathElement interface - if (obj instanceof IPathElement) - // e implements the getPrototype() method - return ((IPathElement) obj).getPrototype (); - else - // use java class name as prototype name - return classMapping.getProperty (obj.getClass ().getName ()); + public String getPrototypeName(Object obj) { + if (obj == null) { + return "global"; + } + + // check if e implements the IPathElement interface + if (obj instanceof IPathElement) { + // e implements the getPrototype() method + return ((IPathElement) obj).getPrototype(); + } else { + // use java class name as prototype name + return classMapping.getProperty(obj.getClass().getName()); + } } ////////////////////////////////////////////////////////////////////////////////////////////////////////// /// The following methods are the IPathElement interface for this application. /// this is useful for scripting and url-building in the base-app. ////////////////////////////////////////////////////////////////////////////////////////////////////////// - public String getElementName() { - return name; + return name; } + /** + * + * + * @param name ... + * + * @return ... + */ public IPathElement getChildElement(String name) { - // as Prototype and the helma.scripting-classes don't offer enough information - // we use the classes from helma.doc-pacakge for introspection. - // the first time an url like /appname/api/ is parsed, the application is read again - // parsed for comments and exposed as an IPathElement - if (name.equals("api")) { - return eval.scriptingEngine.getIntrospector (); - } - return null; + // as Prototype and the helma.scripting-classes don't offer enough information + // we use the classes from helma.doc-pacakge for introspection. + // the first time an url like /appname/api/ is parsed, the application is read again + // parsed for comments and exposed as an IPathElement + if (name.equals("api")) { + return eval.scriptingEngine.getIntrospector(); + } + + return null; } + /** + * + * + * @return ... + */ public IPathElement getParentElement() { - return helma.main.Server.getServer(); + return helma.main.Server.getServer(); } + /** + * + * + * @return ... + */ public String getPrototype() { - return "application"; + return "application"; } - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Get the logger object for logging generic events */ - public void logEvent (String msg) { - if (eventLog == null || eventLog.isClosed ()) - eventLog = getLogger ("event"); - eventLog.log (msg); + public void logEvent(String msg) { + if ((eventLog == null) || eventLog.isClosed()) { + eventLog = getLogger("event"); + } + + eventLog.log(msg); } /** * Get the logger object for logging access events */ - public void logAccess (String msg) { - if (accessLog == null || accessLog.isClosed ()) - accessLog = getLogger ("access"); - accessLog.log (msg); + public void logAccess(String msg) { + if ((accessLog == null) || accessLog.isClosed()) { + accessLog = getLogger("access"); + } + + accessLog.log(msg); } /** * Get a logger object to log events for this application. */ - public Logger getLogger (String logname) { - Logger log = null; - String logDir = props.getProperty ("logdir", "log"); - // allow log to be redirected to System.out by setting logdir to "console" - if ("console".equalsIgnoreCase (logDir)) - return new Logger (System.out); - File helper = new File (logDir); - // construct the fully qualified log name - String fullLogname = name +"_"+logname; - if (home != null && !helper.isAbsolute ()) - helper = new File (home, logDir); - logDir = helper.getAbsolutePath (); - log = Logger.getLogger (logDir, fullLogname); - return log; - } + public Logger getLogger(String logname) { + Logger log = null; + String logDir = props.getProperty("logdir", "log"); + // allow log to be redirected to System.out by setting logdir to "console" + if ("console".equalsIgnoreCase(logDir)) { + return new Logger(System.out); + } + + File helper = new File(logDir); + + // construct the fully qualified log name + String fullLogname = name + "_" + logname; + + if ((home != null) && !helper.isAbsolute()) { + helper = new File(home, logDir); + } + + logDir = helper.getAbsolutePath(); + log = Logger.getLogger(logDir, fullLogname); + + return log; + } /** * The run method performs periodic tasks like executing the scheduler method and * kicking out expired user sessions. */ - public void run () { - long cleanupSleep = 60000; // thread sleep interval (fixed) - long scheduleSleep = 60000; // interval for scheduler invocation - long lastScheduler = 0; // run scheduler immediately - long lastCleanup = System.currentTimeMillis (); + public void run() { + long cleanupSleep = 60000; // thread sleep interval (fixed) + long scheduleSleep = 60000; // interval for scheduler invocation + long lastScheduler = 0; // run scheduler immediately + long lastCleanup = System.currentTimeMillis(); - // logEvent ("Starting scheduler for "+name); - // as first thing, invoke function onStart in the root object + // logEvent ("Starting scheduler for "+name); + // as first thing, invoke function onStart in the root object + eval = new RequestEvaluator(this); + allThreads.addElement(eval); - eval = new RequestEvaluator (this); - allThreads.addElement (eval); + // read in standard prototypes to make first request go faster + typemgr.updatePrototype("root"); + typemgr.updatePrototype("global"); - // read in standard prototypes to make first request go faster - typemgr.updatePrototype ("root"); - typemgr.updatePrototype ("global"); + try { + eval.invokeFunction((INode) null, "onStart", new Object[0]); + } catch (Exception ignore) { + logEvent("Error in " + name + "/onStart(): " + ignore); + } - try { - eval.invokeFunction ((INode) null, "onStart", new Object[0]); - } catch (Exception ignore) { - logEvent ("Error in "+name+"/onStart(): "+ignore); - } + while (Thread.currentThread() == worker) { + // get session timeout + int sessionTimeout = 30; - while (Thread.currentThread () == worker) { - // get session timeout - int sessionTimeout = 30; - try { - sessionTimeout = Math.max (0, Integer.parseInt (props.getProperty ("sessionTimeout", "30"))); - } catch (Exception ignore) { - System.out.println(ignore.toString()); - } + try { + sessionTimeout = Math.max(0, + Integer.parseInt(props.getProperty("sessionTimeout", + "30"))); + } catch (Exception ignore) { + System.out.println(ignore.toString()); + } - long now = System.currentTimeMillis (); + long now = System.currentTimeMillis(); - // check if we should clean up user sessions - if (now - lastCleanup > cleanupSleep) try { - lastCleanup = now; - Hashtable cloned = (Hashtable) sessions.clone (); - for (Enumeration e = cloned.elements (); e.hasMoreElements (); ) { - Session session = (Session) e.nextElement (); - if (now - session.lastTouched () > sessionTimeout * 60000) { - NodeHandle userhandle = session.userHandle; - if (userhandle != null) { - try { - Object[] param = { session.getSessionID() }; - eval.invokeFunction (userhandle, "onLogout", param); - } catch (Exception ignore) {} - } - destroySession(session); - } - } - } catch (Exception cx) { - logEvent ("Error cleaning up sessions: "+cx); - cx.printStackTrace (); - } + // check if we should clean up user sessions + if ((now - lastCleanup) > cleanupSleep) { + try { + lastCleanup = now; - // check if we should call scheduler - if (now - lastScheduler > scheduleSleep) { - lastScheduler = now; - Object val = null; - try { - val = eval.invokeFunction ((INode) null, "scheduler", new Object[0]); - } catch (Exception ignore) {} - try { - int ret = ((Number) val).intValue (); - if (ret < 1000) - scheduleSleep = 60000l; - else - scheduleSleep = ret; - } catch (Exception ignore) {} - // logEvent ("Called scheduler for "+name+", will sleep for "+scheduleSleep+" millis"); - } + Hashtable cloned = (Hashtable) sessions.clone(); - // sleep until we have work to do - try { - worker.sleep (Math.min (cleanupSleep, scheduleSleep)); - } catch (InterruptedException x) { - logEvent ("Scheduler for "+name+" interrupted"); - worker = null; - break; - } - } - logEvent ("Scheduler for "+name+" exiting"); + for (Enumeration e = cloned.elements(); e.hasMoreElements();) { + Session session = (Session) e.nextElement(); + + if ((now - session.lastTouched()) > (sessionTimeout * 60000)) { + NodeHandle userhandle = session.userHandle; + + if (userhandle != null) { + try { + Object[] param = { session.getSessionID() }; + + eval.invokeFunction(userhandle, "onLogout", param); + } catch (Exception ignore) { + } + } + + destroySession(session); + } + } + } catch (Exception cx) { + logEvent("Error cleaning up sessions: " + cx); + cx.printStackTrace(); + } + } + + if ((cronJobs == null) || (props.lastModified() > lastPropertyRead)) { + updateProperties(); + cronJobs = CronJob.parse(props); + } + + Date d = new Date(); + List jobs = (List) cronJobs.clone(); + + jobs.addAll(customCronJobs.values()); + CronJob.sort(jobs); + + for (Iterator i = jobs.iterator(); i.hasNext();) { + CronJob j = (CronJob) i.next(); + + if (j.appliesToDate(d)) { + // check if the job is already active ... + if (activeCronJobs.containsKey(j.getName())) { + logEvent(j + " is still active, skipped in this minute"); + + continue; + } + + RequestEvaluator thisEvaluator; + + try { + thisEvaluator = getEvaluator(); + } catch (RuntimeException rt) { + if (stopped == false) { + logEvent("couldn't execute " + j + + ", maximum thread count reached"); + + continue; + } else { + break; + } + } + + // if the job has a long timeout or we're already late during this minute + // the job is run from an extra thread + if ((j.getTimeout() > 20000) || + (CronJob.millisToNextFullMinute() < 30000)) { + CronRunner r = new CronRunner(thisEvaluator, j); + + r.start(); + activeCronJobs.put(j.getName(), r); + } else { + try { + thisEvaluator.invokeFunction((INode) null, j.getFunction(), + new Object[0], j.getTimeout()); + } catch (Exception ex) { + logEvent("error running " + j + ": " + ex.toString()); + } finally { + if (stopped == false) { + releaseEvaluator(thisEvaluator); + } + } + } + + thisEvaluator = null; + } + } + + // sleep until the next full minute + try { + worker.sleep(CronJob.millisToNextFullMinute()); + } catch (InterruptedException x) { + logEvent("Scheduler for " + name + " interrupted"); + worker = null; + break; + } + } + + // when interrupted, shutdown running cron jobs + synchronized (activeCronJobs) { + for (Iterator i = activeCronJobs.keySet().iterator(); i.hasNext();) { + String jobname = (String) i.next(); + + ((CronRunner) activeCronJobs.get(jobname)).interrupt(); + activeCronJobs.remove(jobname); + } + } + + logEvent("Scheduler for " + name + " exiting"); } - /** * Check whether a prototype is for scripting a java class, i.e. if there's an entry * for it in the class.properties file. */ - public boolean isJavaPrototype (String typename) { - for (Enumeration en = classMapping.elements(); en.hasMoreElements(); ) { - String value = (String) en.nextElement (); - if (typename.equals (value)) - return true; - } - return false; + public boolean isJavaPrototype(String typename) { + for (Enumeration en = classMapping.elements(); en.hasMoreElements();) { + String value = (String) en.nextElement(); + + if (typename.equals(value)) { + return true; + } + } + + return false; } /** * Return a DbSource object for a given name. A DbSource is a relational database defined * in a db.properties file. */ - public DbSource getDbSource (String name) { - String dbSrcName = name.toLowerCase (); - DbSource dbs = (DbSource) dbSources.get (dbSrcName); - if (dbs != null) - return dbs; - if (dbProps.getProperty (dbSrcName+".url") != null && dbProps.getProperty (dbSrcName+".driver") != null) { - try { - dbs = new DbSource (name, dbProps); - dbSources.put (dbSrcName, dbs); - } catch (Exception problem) { - logEvent ("Error creating DbSource "+name); - logEvent ("Reason: "+problem); - } - } - return dbs; + public DbSource getDbSource(String name) { + String dbSrcName = name.toLowerCase(); + DbSource dbs = (DbSource) dbSources.get(dbSrcName); + + if (dbs != null) { + return dbs; + } + + if ((dbProps.getProperty(dbSrcName + ".url") != null) && + (dbProps.getProperty(dbSrcName + ".driver") != null)) { + try { + dbs = new DbSource(name, dbProps); + dbSources.put(dbSrcName, dbs); + } catch (Exception problem) { + logEvent("Error creating DbSource " + name); + logEvent("Reason: " + problem); + } + } + + return dbs; } /** * Return the name of this application */ - public String getName () { - return name; + public String getName() { + return name; } /** * Return the directory of this application */ public File getAppDir() { - return appDir; + return appDir; } /** * Return the directory of the Helma server */ public File getServerDir() { - return home; + return home; } - /** * Get the DbMapping associated with a prototype name in this application */ - public DbMapping getDbMapping (String typename) { - Prototype proto = typemgr.getPrototype (typename); - if (proto == null) - return null; - return proto.getDbMapping (); + public DbMapping getDbMapping(String typename) { + Prototype proto = typemgr.getPrototype(typename); + + if (proto == null) { + return null; + } + + return proto.getDbMapping(); } + private synchronized void updateProperties() { + // if so property file has been updated, re-read props. + if (props.lastModified() > lastPropertyRead) { + // character encoding to be used for responses + charset = props.getProperty("charset", "ISO-8859-1"); - private synchronized void updateProperties () { - // if so property file has been updated, re-read props. - if (props.lastModified () > lastPropertyRead) { - // character encoding to be used for responses - charset = props.getProperty ("charset", "ISO-8859-1"); - // debug flag - debug = "true".equalsIgnoreCase (props.getProperty ("debug")); - try { - requestTimeout = Long.parseLong (props.getProperty ("requestTimeout", "60"))*1000l; - } catch (Exception ignore) { - // go with default value - requestTimeout = 60000l; - } - // set base URI - String base = props.getProperty ("baseuri"); - if (base != null) - setBaseURI (base); - else if (baseURI == null) - baseURI = "/"; - // update the XML-RPC access list, containting prototype.method - // entries of functions that may be called via XML-RPC - String xmlrpcAccessProp = props.getProperty ("xmlrpcaccess"); - HashSet xra = new HashSet (); - if (xmlrpcAccessProp != null) { - StringTokenizer st = new StringTokenizer (xmlrpcAccessProp, ",; "); - while (st.hasMoreTokens ()) { - String token = st.nextToken ().trim (); - xra.add (token.toLowerCase()); - } - } - xmlrpcAccess = xra; - // if node manager exists, update it - if (nmgr != null) - nmgr.updateProperties (props); - // update extensions - Vector extensions = Server.getServer ().getExtensions (); - for (int i=0; i<extensions.size(); i++) { - HelmaExtension ext = (HelmaExtension)extensions.get(i); - try { - ext.applicationUpdated (this); - } catch (ConfigurationException e) { } - } - // set prop read timestamp - lastPropertyRead = props.lastModified (); - } + // debug flag + debug = "true".equalsIgnoreCase(props.getProperty("debug")); + + try { + requestTimeout = Long.parseLong(props.getProperty("requestTimeout", "60")) * 1000L; + } catch (Exception ignore) { + // go with default value + requestTimeout = 60000L; + } + + // set base URI + String base = props.getProperty("baseuri"); + + if (base != null) { + setBaseURI(base); + } else if (baseURI == null) { + baseURI = "/"; + } + + // update the XML-RPC access list, containting prototype.method + // entries of functions that may be called via XML-RPC + String xmlrpcAccessProp = props.getProperty("xmlrpcaccess"); + HashSet xra = new HashSet(); + + if (xmlrpcAccessProp != null) { + StringTokenizer st = new StringTokenizer(xmlrpcAccessProp, ",; "); + + while (st.hasMoreTokens()) { + String token = st.nextToken().trim(); + + xra.add(token.toLowerCase()); + } + } + + xmlrpcAccess = xra; + + // if node manager exists, update it + if (nmgr != null) { + nmgr.updateProperties(props); + } + + // update extensions + Vector extensions = Server.getServer().getExtensions(); + + for (int i = 0; i < extensions.size(); i++) { + HelmaExtension ext = (HelmaExtension) extensions.get(i); + + try { + ext.applicationUpdated(this); + } catch (ConfigurationException e) { + } + } + + // set prop read timestamp + lastPropertyRead = props.lastModified(); + } } - /** - * Get a checksum that mirrors the state of this application in the sense - * that if anything in the applciation changes, the checksum hopefully will + * Get a checksum that mirrors the state of this application in the sense + * that if anything in the applciation changes, the checksum hopefully will * change, too. */ - public long getChecksum () { - return starttime + typemgr.getChecksum() + props.getChecksum(); + public long getChecksum() { + return starttime + typemgr.getChecksum() + props.getChecksum(); } /** * Proxy method to get a property from the applications properties. */ - public String getProperty (String propname) { - return props.getProperty (propname); + public String getProperty(String propname) { + return props.getProperty(propname); } /** * Proxy method to get a property from the applications properties. */ - public String getProperty (String propname, String defvalue) { - return props.getProperty (propname, defvalue); - } - - public SystemProperties getProperties() { - return props; + public String getProperty(String propname, String defvalue) { + return props.getProperty(propname, defvalue); } /** - * Return the XML-RPC handler name for this app. The contract is to + * + * + * @return ... + */ + public SystemProperties getProperties() { + return props; + } + + /** + * Return the XML-RPC handler name for this app. The contract is to * always return the same string, even if it has been changed in the properties file * during runtime, so the app gets unregistered correctly. */ - public String getXmlRpcHandlerName () { - if (xmlrpcHandlerName == null) - xmlrpcHandlerName = props.getProperty ("xmlrpcHandlerName", this.name); - return xmlrpcHandlerName; + public String getXmlRpcHandlerName() { + if (xmlrpcHandlerName == null) { + xmlrpcHandlerName = props.getProperty("xmlrpcHandlerName", this.name); + } + + return xmlrpcHandlerName; } /** * */ - public int countThreads () { - return threadgroup.activeCount() -1; + public int countThreads() { + return threadgroup.activeCount() - 1; } /** * */ - public int countEvaluators () { - return allThreads.size()-1 ; + public int countEvaluators() { + return allThreads.size() - 1; } /** * */ - public int countFreeEvaluators () { - return freeThreads.size (); + public int countFreeEvaluators() { + return freeThreads.size(); } /** * */ - public int countActiveEvaluators () { - return allThreads.size() - freeThreads.size () -1; + public int countActiveEvaluators() { + return allThreads.size() - freeThreads.size() - 1; } /** * */ - public int countMaxActiveEvaluators () { - // return typemgr.countRegisteredRequestEvaluators () -1; - // not available due to framework refactoring - return -1; + public int countMaxActiveEvaluators() { + // return typemgr.countRegisteredRequestEvaluators () -1; + // not available due to framework refactoring + return -1; } /** * */ - public long getRequestCount () { - return requestCount; + public long getRequestCount() { + return requestCount; } /** * */ - public long getXmlrpcCount () { - return xmlrpcCount; + public long getXmlrpcCount() { + return xmlrpcCount; } /** * */ - public long getErrorCount () { - return errorCount; + public long getErrorCount() { + return errorCount; } - public long getStarttime () { - return starttime; + /** + * + * + * @return ... + */ + public long getStarttime() { + return starttime; } - public String getCharset () { - return props.getProperty ("charset", "ISO-8859-1"); + /** + * + * + * @return ... + */ + public String getCharset() { + return props.getProperty("charset", "ISO-8859-1"); } /** * Periodically called to log thread stats for this application */ - public void printThreadStats () { - logEvent ("Thread Stats for "+name+": "+threadgroup.activeCount()+" active"); - Runtime rt = Runtime.getRuntime (); - long free = rt.freeMemory (); - long total = rt.totalMemory (); - logEvent ("Free memory: "+(free/1024)+" kB"); - logEvent ("Total memory: "+(total/1024)+" kB"); + public void printThreadStats() { + logEvent("Thread Stats for " + name + ": " + threadgroup.activeCount() + + " active"); + + Runtime rt = Runtime.getRuntime(); + long free = rt.freeMemory(); + long total = rt.totalMemory(); + + logEvent("Free memory: " + (free / 1024) + " kB"); + logEvent("Total memory: " + (total / 1024) + " kB"); } /** * Check if a method may be invoked via XML-RPC on a prototype. */ - protected void checkXmlRpcAccess (String proto, String method) throws Exception { - String key = proto+"."+method; - // XML-RPC access items are case insensitive and stored in lower case - if (!xmlrpcAccess.contains (key.toLowerCase())) - throw new Exception ("Method "+key+" is not callable via XML-RPC"); + protected void checkXmlRpcAccess(String proto, String method) + throws Exception { + String key = proto + "." + method; + + // XML-RPC access items are case insensitive and stored in lower case + if (!xmlrpcAccess.contains(key.toLowerCase())) { + throw new Exception("Method " + key + " is not callable via XML-RPC"); + } } - public void storeSessionData (File f) { - if (f==null) - f = new File(dbDir, "sessions"); - try { - OutputStream ostream = new BufferedOutputStream (new FileOutputStream(f)); - ObjectOutputStream p = new ObjectOutputStream(ostream); - synchronized (sessions) { - p.writeInt (sessions.size ()); - for (Enumeration e=sessions.elements (); e.hasMoreElements ();) { - p.writeObject ((Session) e.nextElement ()); - } - } - p.flush(); - ostream.close(); - logEvent ("stored " + sessions.size () + " sessions in file"); - } catch (Exception e) { - logEvent ("error storing session data: " + e.toString ()); - } - } + /** + * + * + * @param f ... + */ + public void storeSessionData(File f) { + if (f == null) { + f = new File(dbDir, "sessions"); + } + try { + OutputStream ostream = new BufferedOutputStream(new FileOutputStream(f)); + ObjectOutputStream p = new ObjectOutputStream(ostream); + + synchronized (sessions) { + p.writeInt(sessions.size()); + + for (Enumeration e = sessions.elements(); e.hasMoreElements();) { + p.writeObject((Session) e.nextElement()); + } + } + + p.flush(); + ostream.close(); + logEvent("stored " + sessions.size() + " sessions in file"); + } catch (Exception e) { + logEvent("error storing session data: " + e.toString()); + } + } /** * loads the serialized session table from a given file or from dbdir/sessions */ - public void loadSessionData (File f) { - if (f==null) - f = new File(dbDir, "sessions"); - // compute session timeout value - int sessionTimeout = 30; - try { - sessionTimeout = Math.max (0, Integer.parseInt (props.getProperty ("sessionTimeout", "30"))); - } catch (Exception ignore) { - System.out.println(ignore.toString()); - } - long now = System.currentTimeMillis (); - try { - // load the stored data: - InputStream istream = new BufferedInputStream (new FileInputStream(f)); - ObjectInputStream p = new ObjectInputStream(istream); - int size = p.readInt (); - int ct = 0; - Hashtable newSessions = new Hashtable (); - while (ct < size) { - Session session = (Session) p.readObject (); - if (now - session.lastTouched () < sessionTimeout * 60000) { - session.setApp (this); - newSessions.put (session.getSessionID (), session); - } - ct++; - } - p.close (); - istream.close (); - sessions = newSessions; - logEvent ("loaded " + newSessions.size () + " sessions from file"); - } catch (Exception e) { - logEvent ("error loading session data: " + e.toString ()); - } + public void loadSessionData(File f) { + if (f == null) { + f = new File(dbDir, "sessions"); + } + + // compute session timeout value + int sessionTimeout = 30; + + try { + sessionTimeout = Math.max(0, + Integer.parseInt(props.getProperty("sessionTimeout", + "30"))); + } catch (Exception ignore) { + System.out.println(ignore.toString()); + } + + long now = System.currentTimeMillis(); + + try { + // load the stored data: + InputStream istream = new BufferedInputStream(new FileInputStream(f)); + ObjectInputStream p = new ObjectInputStream(istream); + int size = p.readInt(); + int ct = 0; + Hashtable newSessions = new Hashtable(); + + while (ct < size) { + Session session = (Session) p.readObject(); + + if ((now - session.lastTouched()) < (sessionTimeout * 60000)) { + session.setApp(this); + newSessions.put(session.getSessionID(), session); + } + + ct++; + } + + p.close(); + istream.close(); + sessions = newSessions; + logEvent("loaded " + newSessions.size() + " sessions from file"); + } catch (Exception e) { + logEvent("error loading session data: " + e.toString()); + } } + class CronRunner extends Thread { + RequestEvaluator thisEvaluator; + CronJob job; + + public CronRunner(RequestEvaluator thisEvaluator, CronJob job) { + this.thisEvaluator = thisEvaluator; + this.job = job; + } + + public void run() { + try { + thisEvaluator.invokeFunction((INode) null, job.getFunction(), + new Object[0], job.getTimeout()); + } catch (Exception ex) { + } + + if (stopped == false) { + releaseEvaluator(thisEvaluator); + } + + thisEvaluator = null; + activeCronJobs.remove(job.getName()); + } + } } - - diff --git a/src/helma/framework/core/ApplicationBean.java b/src/helma/framework/core/ApplicationBean.java index 02ed061f..ac585d4d 100644 --- a/src/helma/framework/core/ApplicationBean.java +++ b/src/helma/framework/core/ApplicationBean.java @@ -1,215 +1,497 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.framework.core; -import java.io.Serializable; +import helma.objectmodel.INode; +import helma.util.CronJob; import java.io.File; +import java.io.Serializable; import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; -import java.util.Map; import java.util.List; +import java.util.Map; -import helma.objectmodel.INode; - +/** + * + */ public class ApplicationBean implements Serializable { - Application app; + /** + * Creates a new ApplicationBean object. + * + * @param app ... + */ public ApplicationBean(Application app) { - this.app = app; + this.app = app; } - public void clearCache () { - app.clearCache (); + /** + * + */ + public void clearCache() { + app.clearCache(); } - public void log (Object msg) { - String str = msg == null ? "null" : msg.toString(); - app.logEvent (str); + /** + * + * + * @param msg ... + */ + public void log(Object msg) { + String str = (msg == null) ? "null" : msg.toString(); + + app.logEvent(str); } - public void log (String logname, Object msg) { - String str = msg == null ? "null" : msg.toString(); - app.getLogger (logname).log (str); + /** + * + * + * @param logname ... + * @param msg ... + */ + public void log(String logname, Object msg) { + String str = (msg == null) ? "null" : msg.toString(); + + app.getLogger(logname).log(str); } - public void debug (Object msg) { - if (app.debug()) { - String str = msg == null ? "null" : msg.toString(); - app.logEvent (str); - } + /** + * + * + * @param msg ... + */ + public void debug(Object msg) { + if (app.debug()) { + String str = (msg == null) ? "null" : msg.toString(); + + app.logEvent(str); + } } - public void debug (String logname, Object msg) { - if (app.debug()) { - String str = msg == null ? "null" : msg.toString(); - app.getLogger (logname).log (str); - } + /** + * + * + * @param logname ... + * @param msg ... + */ + public void debug(String logname, Object msg) { + if (app.debug()) { + String str = (msg == null) ? "null" : msg.toString(); + + app.getLogger(logname).log(str); + } } - public int countSessions () { - return app.sessions.size(); + /** + * + * + * @return ... + */ + public int countSessions() { + return app.sessions.size(); } - public SessionBean getSession (String sessionID) { - if (sessionID==null) - return null; - Session session = app.getSession (sessionID.trim ()); - if (session == null) - return null; - return new SessionBean (session); + /** + * + * + * @param sessionID ... + * + * @return ... + */ + public SessionBean getSession(String sessionID) { + if (sessionID == null) { + return null; + } + + Session session = app.getSession(sessionID.trim()); + + if (session == null) { + return null; + } + + return new SessionBean(session); } - public SessionBean createSession (String sessionID) { - if (sessionID==null) - return null; - Session session = session = app.checkSession (sessionID.trim ()); - if (session == null) - return null; - return new SessionBean (session); + /** + * + * + * @param sessionID ... + * + * @return ... + */ + public SessionBean createSession(String sessionID) { + if (sessionID == null) { + return null; + } + + Session session = session = app.checkSession(sessionID.trim()); + + if (session == null) { + return null; + } + + return new SessionBean(session); } - public SessionBean[] getSessions () { - SessionBean[] theArray = new SessionBean[app.sessions.size()]; - int i=0; - for (Enumeration e=app.sessions.elements(); e.hasMoreElements(); ) { - SessionBean sb = new SessionBean ((Session) e.nextElement ()); - theArray[i++] = sb; - } - return theArray; + /** + * + * + * @return ... + */ + public SessionBean[] getSessions() { + SessionBean[] theArray = new SessionBean[app.sessions.size()]; + int i = 0; + + for (Enumeration e = app.sessions.elements(); e.hasMoreElements();) { + SessionBean sb = new SessionBean((Session) e.nextElement()); + + theArray[i++] = sb; + } + + return theArray; } - public INode registerUser (String username, String password) { - if (username==null || password==null || "".equals (username.trim ()) || "".equals (password.trim ()) ) - return null; - else - return app.registerUser (username, password); + /** + * + * + * @param username ... + * @param password ... + * + * @return ... + */ + public INode registerUser(String username, String password) { + if ((username == null) || (password == null) || "".equals(username.trim()) || + "".equals(password.trim())) { + return null; + } else { + return app.registerUser(username, password); + } } - public INode getUser (String username) { - if (username==null || "".equals (username.trim()) ) - return null; - return app.getUserNode (username); + /** + * + * + * @param username ... + * + * @return ... + */ + public INode getUser(String username) { + if ((username == null) || "".equals(username.trim())) { + return null; + } + + return app.getUserNode(username); } - public INode[] getActiveUsers () { - List activeUsers = app.getActiveUsers (); - return (INode[]) activeUsers.toArray (new INode[0]); + /** + * + * + * @return ... + */ + public INode[] getActiveUsers() { + List activeUsers = app.getActiveUsers(); + + return (INode[]) activeUsers.toArray(new INode[0]); } - public INode[] getRegisteredUsers () { - List registeredUsers = app.getRegisteredUsers (); - return (INode[]) registeredUsers.toArray (new INode[0]); - } + /** + * + * + * @return ... + */ + public INode[] getRegisteredUsers() { + List registeredUsers = app.getRegisteredUsers(); - public SessionBean[] getSessionsForUser (INode usernode) { - if (usernode==null) - return new SessionBean[0]; - else - return getSessionsForUser(usernode.getName()); + return (INode[]) registeredUsers.toArray(new INode[0]); } - public SessionBean[] getSessionsForUser (String username) { - if (username==null || "".equals (username.trim ()) ) - return new SessionBean[0]; - List userSessions = app.getSessionsForUsername (username); - return (SessionBean[]) userSessions.toArray (new SessionBean[0]); + /** + * + * + * @param usernode ... + * + * @return ... + */ + public SessionBean[] getSessionsForUser(INode usernode) { + if (usernode == null) { + return new SessionBean[0]; + } else { + return getSessionsForUser(usernode.getName()); + } + } + + /** + * + * + * @param username ... + * + * @return ... + */ + public SessionBean[] getSessionsForUser(String username) { + if ((username == null) || "".equals(username.trim())) { + return new SessionBean[0]; + } + + List userSessions = app.getSessionsForUsername(username); + + return (SessionBean[]) userSessions.toArray(new SessionBean[0]); + } + + /** + * + * + * @param functionName ... + */ + public void addCronJob(String functionName) { + CronJob job = new CronJob(functionName); + + job.setFunction(functionName); + app.customCronJobs.put(functionName, job); + } + + /** + * + * + * @param functionName ... + * @param year ... + * @param month ... + * @param day ... + * @param weekday ... + * @param hour ... + * @param minute ... + */ + public void addCronJob(String functionName, String year, String month, String day, + String weekday, String hour, String minute) { + CronJob job = CronJob.newJob(functionName, year, month, day, weekday, hour, minute); + + app.customCronJobs.put(functionName, job); + } + + /** + * + * + * @param functionName ... + */ + public void removeCronJob(String functionName) { + app.customCronJobs.remove(functionName); } // getter methods for readonly properties of this application - - public int getcacheusage () { - return app.getCacheUsage (); + public int getcacheusage() { + return app.getCacheUsage(); } + /** + * + * + * @return ... + */ public INode getdata() { - return app.getCacheNode (); + return app.getCacheNode(); } - + + /** + * + * + * @return ... + */ public Map getmodules() { - return app.modules; + return app.modules; } - public String getdir () { - return app.getAppDir ().getAbsolutePath (); + /** + * + * + * @return ... + */ + public String getdir() { + return app.getAppDir().getAbsolutePath(); } - public Date getupSince () { - return new Date (app.starttime); + /** + * + * + * @return ... + */ + public String getname() { + return app.getName(); } - public long getrequestCount () { - return app.getRequestCount (); + /** + * + * + * @return ... + */ + public Date getupSince() { + return new Date(app.starttime); } - public long getxmlrpcCount () { - return app.getXmlrpcCount (); + /** + * + * + * @return ... + */ + public long getrequestCount() { + return app.getRequestCount(); } - public long geterrorCount () { - return app.getErrorCount (); + /** + * + * + * @return ... + */ + public long getxmlrpcCount() { + return app.getXmlrpcCount(); } - public Application get__app__ () { - return app; + /** + * + * + * @return ... + */ + public long geterrorCount() { + return app.getErrorCount(); } - public Map getproperties () { - return app.getProperties (); + /** + * + * + * @return ... + */ + public Application get__app__() { + return app; } - public int getfreeThreads () { - return app.countFreeEvaluators (); + /** + * + * + * @return ... + */ + public Map getproperties() { + return app.getProperties(); } - public int getactiveThreads () { - return app.countActiveEvaluators (); + /** + * + * + * @return ... + */ + public int getfreeThreads() { + return app.countFreeEvaluators(); } - public int getmaxThreads () { - return app.countEvaluators (); + /** + * + * + * @return ... + */ + public int getactiveThreads() { + return app.countActiveEvaluators(); } - public void setmaxThreads (int n) { - // add one to the number to compensate for the internal scheduler. - app.setNumberOfEvaluators (n+1); + /** + * + * + * @return ... + */ + public int getmaxThreads() { + return app.countEvaluators(); } - public Map getSkinfiles () { - Map skinz = new HashMap (); - for (Iterator it = app.getPrototypes().iterator(); it.hasNext(); ) { - Prototype p = (Prototype) it.next (); - skinz.put (p.getName(), p.getSkinMap()); - } - return skinz; + /** + * + * + * @param n ... + */ + public void setmaxThreads(int n) { + // add one to the number to compensate for the internal scheduler. + app.setNumberOfEvaluators(n + 1); } - public Map getSkinfiles (Object[] skinpath) { - Map skinz = new HashMap (); - for (Iterator it = app.getPrototypes().iterator(); it.hasNext(); ) { - Prototype p = (Prototype) it.next (); - skinz.put (p.getName(), p.getSkinMap(skinpath)); - } - return skinz; + /** + * + * + * @return ... + */ + public Map getSkinfiles() { + Map skinz = new HashMap(); + + for (Iterator it = app.getPrototypes().iterator(); it.hasNext();) { + Prototype p = (Prototype) it.next(); + + skinz.put(p.getName(), p.getSkinMap()); + } + + return skinz; } - public String getAppDir () { - return app.getAppDir().getAbsolutePath(); + /** + * + * + * @param skinpath ... + * + * @return ... + */ + public Map getSkinfiles(Object[] skinpath) { + Map skinz = new HashMap(); + + for (Iterator it = app.getPrototypes().iterator(); it.hasNext();) { + Prototype p = (Prototype) it.next(); + + skinz.put(p.getName(), p.getSkinMap(skinpath)); + } + + return skinz; } - public String getServerDir () { - File f = app.getServerDir(); - if (f == null) - f = app.getAppDir(); - return f.getAbsolutePath(); + /** + * + * + * @return ... + */ + public String getAppDir() { + return app.getAppDir().getAbsolutePath(); } + /** + * + * + * @return ... + */ + public String getServerDir() { + File f = app.getServerDir(); + + if (f == null) { + f = app.getAppDir(); + } + + return f.getAbsolutePath(); + } + + /** + * + * + * @return ... + */ public String toString() { - return "[Application " + app.getName() + "]"; + return "[Application " + app.getName() + "]"; } - } - - - diff --git a/src/helma/framework/core/Prototype.java b/src/helma/framework/core/Prototype.java index 9406f6b1..234726d3 100644 --- a/src/helma/framework/core/Prototype.java +++ b/src/helma/framework/core/Prototype.java @@ -1,16 +1,28 @@ -// Prototype.java -// Copyright (c) Hannes Wallnöfer 1998-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.framework.core; -import java.util.*; -import java.io.*; import helma.framework.*; -import helma.scripting.*; import helma.objectmodel.*; import helma.objectmodel.db.DbMapping; +import helma.scripting.*; import helma.util.Updatable; - +import java.io.*; +import java.util.*; /** * The Prototype class represents Script prototypes/type defined in a Helma @@ -18,161 +30,195 @@ import helma.util.Updatable; * as well as optional information about the mapping of this type to a * relational database table. */ - - public final class Prototype { - String name; Application app; File directory; - - File [] files; + File[] files; long lastDirectoryListing; long checksum; - - HashMap code, zippedCode; - HashMap skins, zippedSkins; + HashMap code; + HashMap zippedCode; + HashMap skins; + HashMap zippedSkins; HashMap updatables; // a map of this prototype's skins as raw strings // used for exposing skins to application (script) code (via app.skinfiles). SkinMap skinMap; - DbMapping dbmap; // lastCheck is the time the prototype's files were last checked private long lastChecksum; + // lastUpdate is the time at which any of the prototype's files were // found updated the last time private long lastUpdate; - private Prototype parent; // Tells us whether this prototype is used to script a generic Java object, // as opposed to a Helma objectmodel node object. boolean isJavaPrototype; - public Prototype (String name, File dir, Application app) { - // app.logEvent ("Constructing Prototype "+app.getName()+"/"+name); - this.app = app; - this.name = name; - this.directory = dir; + /** + * Creates a new Prototype object. + * + * @param name ... + * @param dir ... + * @param app ... + */ + public Prototype(String name, File dir, Application app) { + // app.logEvent ("Constructing Prototype "+app.getName()+"/"+name); + this.app = app; + this.name = name; + this.directory = dir; - code = new HashMap (); - zippedCode = new HashMap (); - skins = new HashMap (); - zippedSkins = new HashMap (); - updatables = new HashMap (); + code = new HashMap(); + zippedCode = new HashMap(); + skins = new HashMap(); + zippedSkins = new HashMap(); + updatables = new HashMap(); - skinMap = new SkinMap (); + skinMap = new SkinMap(); - isJavaPrototype = app.isJavaPrototype (name); - lastUpdate = lastChecksum = 0; + isJavaPrototype = app.isJavaPrototype(name); + lastUpdate = lastChecksum = 0; } /** * Return the application this prototype is a part of */ - public Application getApplication () { - return app; + public Application getApplication() { + return app; } /** * Return this prototype's directory. */ - public File getDirectory () { - return directory; + public File getDirectory() { + return directory; } /** * Get the list of files in this prototype's directory */ - public File[] getFiles () { - if (files == null || directory.lastModified() != lastDirectoryListing) { - lastDirectoryListing = directory.lastModified (); - files = directory.listFiles(); - if (files == null) - files = new File[0]; - } - return files; + public File[] getFiles() { + if ((files == null) || (directory.lastModified() != lastDirectoryListing)) { + lastDirectoryListing = directory.lastModified(); + files = directory.listFiles(); + + if (files == null) { + files = new File[0]; + } + } + + return files; } /** * Get a checksum over the files in this prototype's directory */ - public long getChecksum () { - // long start = System.currentTimeMillis(); - File[] f = getFiles (); - long c = 0; - for (int i=0; i<f.length; i++) - c += f[i].lastModified(); - checksum = c; - // System.err.println ("CHECKSUM "+name+": "+(System.currentTimeMillis()-start)); - return checksum; + public long getChecksum() { + // long start = System.currentTimeMillis(); + File[] f = getFiles(); + long c = 0; + + for (int i = 0; i < f.length; i++) + c += f[i].lastModified(); + + checksum = c; + + // System.err.println ("CHECKSUM "+name+": "+(System.currentTimeMillis()-start)); + return checksum; } - - public boolean isUpToDate () { - return checksum == lastChecksum; + + /** + * + * + * @return ... + */ + public boolean isUpToDate() { + return checksum == lastChecksum; } /** * Set the parent prototype of this prototype, i.e. the prototype this * prototype inherits from. */ - public void setParentPrototype (Prototype parent) { - // this is not allowed for the hopobject and global prototypes - if ("hopobject".equalsIgnoreCase (name) || "global".equalsIgnoreCase (name)) - return; - this.parent = parent; + public void setParentPrototype(Prototype parent) { + // this is not allowed for the hopobject and global prototypes + if ("hopobject".equalsIgnoreCase(name) || "global".equalsIgnoreCase(name)) { + return; + } + + this.parent = parent; } /** * Get the parent prototype from which we inherit, or null * if we are top of the line. */ - public Prototype getParentPrototype () { - return parent; + public Prototype getParentPrototype() { + return parent; } - + /** * Check if the given prototype is within this prototype's parent chain. */ - public final boolean isInstanceOf (String pname) { - if (name.equals (pname)) - return true; - if (parent != null && !"hopobject".equalsIgnoreCase (parent.getName())) - return parent.isInstanceOf (pname); - return false; + public final boolean isInstanceOf(String pname) { + if (name.equals(pname)) { + return true; + } + + if ((parent != null) && !"hopobject".equalsIgnoreCase(parent.getName())) { + return parent.isInstanceOf(pname); + } + + return false; } - + /** * Register an object as handler for this prototype and all our parent prototypes. */ - public final void addToHandlerMap (Map handlers, Object obj) { - if (parent != null && !"hopobject".equalsIgnoreCase (parent.getName())) - parent.addToHandlerMap (handlers, obj); - handlers.put (name, obj); + public final void addToHandlerMap(Map handlers, Object obj) { + if ((parent != null) && !"hopobject".equalsIgnoreCase(parent.getName())) { + parent.addToHandlerMap(handlers, obj); + } + + handlers.put(name, obj); } - public void setDbMapping (DbMapping dbmap) { - this.dbmap = dbmap; + /** + * + * + * @param dbmap ... + */ + public void setDbMapping(DbMapping dbmap) { + this.dbmap = dbmap; } - public DbMapping getDbMapping () { - return dbmap; + /** + * + * + * @return ... + */ + public DbMapping getDbMapping() { + return dbmap; } - /** * Get a Skinfile for this prototype. This only works for skins * residing in the prototype directory, not for skin files in * other locations or database stored skins. */ - public SkinFile getSkinFile (String sfname) { - SkinFile sf = (SkinFile) skins.get (sfname); - if (sf == null) - sf = (SkinFile) zippedSkins.get (sfname); - return sf; + public SkinFile getSkinFile(String sfname) { + SkinFile sf = (SkinFile) skins.get(sfname); + + if (sf == null) { + sf = (SkinFile) zippedSkins.get(sfname); + } + + return sf; } /** @@ -180,25 +226,30 @@ public final class Prototype { * residing in the prototype directory, not for skins files in * other locations or database stored skins. */ - public Skin getSkin (String sfname) { - SkinFile sf = getSkinFile (sfname); - if (sf != null) - return sf.getSkin (); - else - return null; + public Skin getSkin(String sfname) { + SkinFile sf = getSkinFile(sfname); + + if (sf != null) { + return sf.getSkin(); + } else { + return null; + } } - - public String getName () { - return name; + /** + * + * + * @return ... + */ + public String getName() { + return name; } - /** * Get the last time any script has been re-read for this prototype. */ - public long getLastUpdate () { - return lastUpdate; + public long getLastUpdate() { + return lastUpdate; } /** @@ -206,35 +257,35 @@ public final class Prototype { * re-read from disk and needs to be re-compiled by * the evaluators. */ - public void markUpdated () { - lastUpdate = System.currentTimeMillis (); + public void markUpdated() { + lastUpdate = System.currentTimeMillis(); } /** * Get the time at which this prototype's scripts were checked * for changes for the last time. */ + /* public long getLastCheck () { - return lastCheck; - } */ + return lastCheck; + } */ /** * Signal that the prototype's scripts have been checked for * changes. */ - public void markChecked () { - // lastCheck = System.currentTimeMillis (); - lastChecksum = checksum; + public void markChecked() { + // lastCheck = System.currentTimeMillis (); + lastChecksum = checksum; } - /** * Return a clone of this prototype's actions container. Synchronized * to not return a map in a transient state where it is just being * updated by the type manager. */ - public synchronized Map getCode () { - return (Map) code.clone(); + public synchronized Map getCode() { + return (Map) code.clone(); } /** @@ -242,232 +293,304 @@ public final class Prototype { * to not return a map in a transient state where it is just being * updated by the type manager. */ - public synchronized Map getZippedCode () { - return (Map) zippedCode.clone(); + public synchronized Map getZippedCode() { + return (Map) zippedCode.clone(); } + /** + * + * + * @param action ... + */ + public synchronized void addActionFile(ActionFile action) { + File f = action.getFile(); - public synchronized void addActionFile (ActionFile action) { - File f = action.getFile (); - if (f != null) { - code.put (action.getSourceName(), action); - updatables.put (f.getName(), action); - } else { - zippedCode.put (action.getSourceName(), action); - } + if (f != null) { + code.put(action.getSourceName(), action); + updatables.put(f.getName(), action); + } else { + zippedCode.put(action.getSourceName(), action); + } } - public synchronized void addTemplate (Template template) { - File f = template.getFile (); - if (f != null) { - code.put (template.getSourceName(), template); - updatables.put (f.getName(), template); - } else { - zippedCode.put (template.getSourceName(), template); - } + /** + * + * + * @param template ... + */ + public synchronized void addTemplate(Template template) { + File f = template.getFile(); + + if (f != null) { + code.put(template.getSourceName(), template); + updatables.put(f.getName(), template); + } else { + zippedCode.put(template.getSourceName(), template); + } } - public synchronized void addFunctionFile (FunctionFile funcfile) { - File f = funcfile.getFile (); - if (f != null) { - code.put (funcfile.getSourceName(), funcfile); - updatables.put (f.getName(), funcfile); - } else { - zippedCode.put (funcfile.getSourceName(), funcfile); - } + /** + * + * + * @param funcfile ... + */ + public synchronized void addFunctionFile(FunctionFile funcfile) { + File f = funcfile.getFile(); + + if (f != null) { + code.put(funcfile.getSourceName(), funcfile); + updatables.put(f.getName(), funcfile); + } else { + zippedCode.put(funcfile.getSourceName(), funcfile); + } } - public synchronized void addSkinFile (SkinFile skinfile) { - File f = skinfile.getFile (); - if (f != null) { - skins.put (skinfile.getName(), skinfile); - updatables.put (f.getName(), skinfile); - } else { - zippedSkins.put (skinfile.getName(), skinfile); - } + /** + * + * + * @param skinfile ... + */ + public synchronized void addSkinFile(SkinFile skinfile) { + File f = skinfile.getFile(); + + if (f != null) { + skins.put(skinfile.getName(), skinfile); + updatables.put(f.getName(), skinfile); + } else { + zippedSkins.put(skinfile.getName(), skinfile); + } } + /** + * + * + * @param action ... + */ + public synchronized void removeActionFile(ActionFile action) { + File f = action.getFile(); - public synchronized void removeActionFile (ActionFile action) { - File f = action.getFile (); - if (f != null) { - code.remove (action.getSourceName()); - updatables.remove (f.getName()); - } else { - zippedCode.remove (action.getSourceName()); - } + if (f != null) { + code.remove(action.getSourceName()); + updatables.remove(f.getName()); + } else { + zippedCode.remove(action.getSourceName()); + } } - public synchronized void removeFunctionFile (FunctionFile funcfile) { - File f = funcfile.getFile (); - if (f != null) { - code.remove (funcfile.getSourceName()); - updatables.remove (f.getName()); - } else { - zippedCode.remove (funcfile.getSourceName()); - } + /** + * + * + * @param funcfile ... + */ + public synchronized void removeFunctionFile(FunctionFile funcfile) { + File f = funcfile.getFile(); + + if (f != null) { + code.remove(funcfile.getSourceName()); + updatables.remove(f.getName()); + } else { + zippedCode.remove(funcfile.getSourceName()); + } } - public synchronized void removeTemplate (Template template) { - File f = template.getFile (); - if (f != null) { - code.remove (template.getSourceName()); - updatables.remove (f.getName()); - } else { - zippedCode.remove (template.getSourceName()); - } + /** + * + * + * @param template ... + */ + public synchronized void removeTemplate(Template template) { + File f = template.getFile(); + + if (f != null) { + code.remove(template.getSourceName()); + updatables.remove(f.getName()); + } else { + zippedCode.remove(template.getSourceName()); + } } - public synchronized void removeSkinFile (SkinFile skinfile) { - File f = skinfile.getFile (); - if (f != null) { - skins.remove (skinfile.getName()); - updatables.remove (f.getName()); - } else { - zippedSkins.remove (skinfile.getName()); - } + /** + * + * + * @param skinfile ... + */ + public synchronized void removeSkinFile(SkinFile skinfile) { + File f = skinfile.getFile(); + + if (f != null) { + skins.remove(skinfile.getName()); + updatables.remove(f.getName()); + } else { + zippedSkins.remove(skinfile.getName()); + } } - - /** - * Return a string representing this prototype. - */ - public String toString () { - return "[Prototype "+ app.getName()+"/"+name+"]"; + /** + * Return a string representing this prototype. + */ + public String toString() { + return "[Prototype " + app.getName() + "/" + name + "]"; } - - public SkinMap getSkinMap () { - return skinMap; + /** + * + * + * @return ... + */ + public SkinMap getSkinMap() { + return skinMap; } // not yet implemented - public SkinMap getSkinMap (Object[] skinpath) { - return new SkinMap (skinpath); + public SkinMap getSkinMap(Object[] skinpath) { + return new SkinMap(skinpath); } // a map that dynamically expands to all skins in this prototype final class SkinMap extends HashMap { + long lastSkinmapLoad = 0; + Object[] skinpath; - long lastSkinmapLoad = 0; + SkinMap() { + super(); + skinpath = null; + } - Object[] skinpath; + SkinMap(Object[] path) { + super(); + skinpath = path; + } - SkinMap () { - super (); - skinpath = null; - } + public boolean containsKey(Object key) { + checkForUpdates(); - SkinMap (Object[] path) { - super (); - skinpath = path; - } + return super.containsKey(key); + } - public boolean containsKey (Object key) { - checkForUpdates (); - return super.containsKey (key); - } + public boolean containsValue(Object value) { + checkForUpdates(); - public boolean containsValue (Object value) { - checkForUpdates (); - return super.containsValue (value); - } + return super.containsValue(value); + } - public Set entrySet () { - checkForUpdates (); - return super.entrySet (); - } + public Set entrySet() { + checkForUpdates(); - public boolean equals (Object obj) { - checkForUpdates (); - return super.equals (obj); - } + return super.entrySet(); + } - public Object get (Object key) { - if (key == null) - return null; - checkForUpdates (); - SkinFile sf = (SkinFile) super.get (key); - if (sf == null) - return null; - return sf.getSkin().getSource (); - } + public boolean equals(Object obj) { + checkForUpdates(); - public int hashCode () { - checkForUpdates (); - return super.hashCode (); - } + return super.equals(obj); + } - public boolean isEmpty () { - checkForUpdates (); - return super.isEmpty (); - } + public Object get(Object key) { + if (key == null) { + return null; + } - public Set keySet () { - checkForUpdates (); - return super.keySet (); - } + checkForUpdates(); - public Object put (Object key, Object value) { - // checkForUpdates (); - return super.put (key, value); - } + SkinFile sf = (SkinFile) super.get(key); - public void putAll (Map t) { - // checkForUpdates (); - super.putAll (t); - } + if (sf == null) { + return null; + } - public Object remove (Object key) { - checkForUpdates (); - return super.remove (key); - } + return sf.getSkin().getSource(); + } - public int size () { - checkForUpdates (); - return super.size (); - } + public int hashCode() { + checkForUpdates(); - public Collection values () { - checkForUpdates (); - return super.values (); - } + return super.hashCode(); + } + public boolean isEmpty() { + checkForUpdates(); - private void checkForUpdates () { - if (/* lastCheck < System.currentTimeMillis()- 2000l*/ !isUpToDate()) - app.typemgr.updatePrototype (Prototype.this); - if (lastUpdate > lastSkinmapLoad) - load (); - } + return super.isEmpty(); + } - private synchronized void load () { - if (lastUpdate == lastSkinmapLoad) - return; - super.clear (); - // System.err.println ("LOADING SKIN VALUES: "+Prototype.this); - for (Iterator i = skins.entrySet().iterator(); i.hasNext(); ) { - Map.Entry e = (Map.Entry) i.next (); - super.put (e.getKey(), e.getValue()); - } - // if skinpath is not null, overload/add skins from there - if (skinpath != null) { - for (int i=skinpath.length-1; i>=0; i--) { - if (skinpath[i] != null && skinpath[i] instanceof String) { - Map m = app.skinmgr.getSkinFiles ((String) skinpath[i], Prototype.this); - if (m != null) - super.putAll (m); - } - } - } - lastSkinmapLoad = lastUpdate; - } - - public String toString () { - return "[SkinMap "+name+"]"; - } + public Set keySet() { + checkForUpdates(); + return super.keySet(); + } + + public Object put(Object key, Object value) { + // checkForUpdates (); + return super.put(key, value); + } + + public void putAll(Map t) { + // checkForUpdates (); + super.putAll(t); + } + + public Object remove(Object key) { + checkForUpdates(); + + return super.remove(key); + } + + public int size() { + checkForUpdates(); + + return super.size(); + } + + public Collection values() { + checkForUpdates(); + + return super.values(); + } + + private void checkForUpdates() { + if ( /* lastCheck < System.currentTimeMillis()- 2000l*/ + !isUpToDate()) { + app.typemgr.updatePrototype(Prototype.this); + } + + if (lastUpdate > lastSkinmapLoad) { + load(); + } + } + + private synchronized void load() { + if (lastUpdate == lastSkinmapLoad) { + return; + } + + super.clear(); + + // System.err.println ("LOADING SKIN VALUES: "+Prototype.this); + for (Iterator i = skins.entrySet().iterator(); i.hasNext();) { + Map.Entry e = (Map.Entry) i.next(); + + super.put(e.getKey(), e.getValue()); + } + + // if skinpath is not null, overload/add skins from there + if (skinpath != null) { + for (int i = skinpath.length - 1; i >= 0; i--) { + if ((skinpath[i] != null) && skinpath[i] instanceof String) { + Map m = app.skinmgr.getSkinFiles((String) skinpath[i], + Prototype.this); + + if (m != null) { + super.putAll(m); + } + } + } + } + + lastSkinmapLoad = lastUpdate; + } + + public String toString() { + return "[SkinMap " + name + "]"; + } } - } - diff --git a/src/helma/framework/core/RemoteApplication.java b/src/helma/framework/core/RemoteApplication.java index f854b4d0..10a7ec6d 100644 --- a/src/helma/framework/core/RemoteApplication.java +++ b/src/helma/framework/core/RemoteApplication.java @@ -1,5 +1,18 @@ -// RemoteApplication.java -// Copyright (c) Hannes Wallnöfer 2002 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.framework.core; @@ -12,43 +25,45 @@ import java.util.Vector; /** * Proxy class for Aplication that listens to requests via RMI. */ - -public class RemoteApplication - extends UnicastRemoteObject - implements IRemoteApp, IReplicationListener { - +public class RemoteApplication extends UnicastRemoteObject implements IRemoteApp, + IReplicationListener { Application app; - - public RemoteApplication (Application app) throws RemoteException { - this.app = app; + /** + * Creates a new RemoteApplication object. + * + * @param app ... + * + * @throws RemoteException ... + */ + public RemoteApplication(Application app) throws RemoteException { + this.app = app; } - /** * ping method to let clients know if the server is reachable */ - public void ping () { - // do nothing + public void ping() { + // do nothing } /** * Execute a request coming in from a web client. */ - public ResponseTrans execute (RequestTrans req) { - return app.execute (req); + public ResponseTrans execute(RequestTrans req) { + return app.execute(req); } - /** * Update HopObjects in this application's cache. This is used to replicate * application caches in a distributed app environment */ - public void replicateCache (Vector add, Vector delete) { - if (!"true".equalsIgnoreCase (app.getProperty ("allowReplication"))) { - app.logEvent ("Rejecting cache replication event: allowReplication property is not set to true"); - throw new RuntimeException ("Replication event rejected: setup does not allow replication."); - } - app.nmgr.replicateCache (add, delete); + public void replicateCache(Vector add, Vector delete) { + if (!"true".equalsIgnoreCase(app.getProperty("allowReplication"))) { + app.logEvent("Rejecting cache replication event: allowReplication property is not set to true"); + throw new RuntimeException("Replication event rejected: setup does not allow replication."); + } + + app.nmgr.replicateCache(add, delete); } } diff --git a/src/helma/framework/core/RequestEvaluator.java b/src/helma/framework/core/RequestEvaluator.java index e9f31ae4..029d599d 100644 --- a/src/helma/framework/core/RequestEvaluator.java +++ b/src/helma/framework/core/RequestEvaluator.java @@ -1,15 +1,28 @@ -// RequestEvaluator.java -// Copyright (c) Hannes Wallnöfer 1998-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.framework.core; +import helma.framework.*; import helma.objectmodel.*; import helma.objectmodel.db.*; -import helma.framework.*; import helma.scripting.*; import helma.util.*; -import java.util.*; import java.lang.reflect.*; +import java.util.*; /** * This class does the work for incoming requests. It holds a transactor thread @@ -18,17 +31,15 @@ import java.lang.reflect.*; * specified by the application has passed. In the latter case, the evaluator thread * is killed and an error message is returned. */ - public final class RequestEvaluator implements Runnable { - - + static final int NONE = 0; // no request + static final int HTTP = 1; // via HTTP gateway + static final int XMLRPC = 2; // via XML-RPC + static final int INTERNAL = 3; // generic function call, e.g. by scheduler public final Application app; - protected ScriptingEngine scriptingEngine; - public RequestTrans req; public ResponseTrans res; - volatile Transactor rtx; // the object on which to invoke a function, if specified @@ -54,631 +65,815 @@ public final class RequestEvaluator implements Runnable { // the type of request to be serviced int reqtype; - static final int NONE = 0; // no request - static final int HTTP = 1; // via HTTP gateway - static final int XMLRPC = 2; // via XML-RPC - static final int INTERNAL = 3; // generic function call, e.g. by scheduler - protected int skinDepth; /** * Create a new RequestEvaluator for this application. */ - public RequestEvaluator (Application app) { - this.app = app; + public RequestEvaluator(Application app) { + this.app = app; } - protected void initScriptingEngine () { - if (scriptingEngine == null) { - String engineClassName = app.getProperty ( - "scriptingEngine", - "helma.scripting.fesi.PhantomEngine"); - try { - Class clazz = app.getClassLoader().loadClass (engineClassName); - scriptingEngine = (ScriptingEngine) clazz.newInstance (); - scriptingEngine.init (app, this); - } catch (Exception x) { - Throwable t = x; - if (x instanceof InvocationTargetException) - t = ((InvocationTargetException) x).getTargetException (); - app.logEvent ("******************************************"); - app.logEvent ("*** Error creating scripting engine: "); - app.logEvent ("*** "+t.toString()); - app.logEvent ("******************************************"); - } - } + protected void initScriptingEngine() { + if (scriptingEngine == null) { + String engineClassName = app.getProperty("scriptingEngine", + "helma.scripting.fesi.PhantomEngine"); + + try { + Class clazz = app.getClassLoader().loadClass(engineClassName); + + scriptingEngine = (ScriptingEngine) clazz.newInstance(); + scriptingEngine.init(app, this); + } catch (Exception x) { + Throwable t = x; + + if (x instanceof InvocationTargetException) { + t = ((InvocationTargetException) x).getTargetException(); + } + + app.logEvent("******************************************"); + app.logEvent("*** Error creating scripting engine: "); + app.logEvent("*** " + t.toString()); + app.logEvent("******************************************"); + } + } } - public void run () { - + /** + * + */ + public void run() { int txcount = 0; + // first, set a local variable to the current transactor thread so we know // when it's time to quit because another thread took over. - Transactor localrtx = (Transactor) Thread.currentThread (); + Transactor localrtx = (Transactor) Thread.currentThread(); try { - do { - - // long startCheck = System.currentTimeMillis (); - app.typemgr.checkPrototypes (); - initScriptingEngine (); - scriptingEngine.updatePrototypes (); - // System.err.println ("Type check overhead: "+(System.currentTimeMillis ()-startCheck)+" millis"); - - // object refs to ressolve request path - Object root, currentElement; - - requestPath = new ArrayList (); - - switch (reqtype) { - case HTTP: - int tries = 0; - boolean done = false; - String error = null; - - while (!done) { - - currentElement = null; - - try { - - // used for logging - StringBuffer txname = new StringBuffer(app.getName()); - txname.append ("/"); - txname.append (error == null ? req.path : "error"); - // begin transaction - localrtx.begin (txname.toString()); - - String action = null; - - root = app.getDataRoot (); - - HashMap globals = new HashMap (); - globals.put ("root", root); - globals.put ("session", new SessionBean (session)); - globals.put ("req", new RequestBean (req)); - globals.put ("res", new ResponseBean (res)); - globals.put ("app", new ApplicationBean (app)); - globals.put ("path", requestPath); - req.startTime = System.currentTimeMillis (); - if (error != null) - res.error = error; - if (session.message != null) { - // bring over the message from a redirect - res.message = session.message; - session.message = null; - } - Map macroHandlers = res.getMacroHandlers (); - - try { - - if (error != null) { - // there was an error in the previous loop, call error handler - currentElement = root; - // do not reset the requestPath so error handler can use the original one - // get error handler action - String errorAction = app.props.getProperty ("error", "error"); - action = getAction (currentElement, errorAction); - if (action == null) - throw new RuntimeException (error); - - } else if (req.path == null || "".equals (req.path.trim ())) { - currentElement = root; - requestPath.add (currentElement); - macroHandlers.put ("root", root); - action = getAction (currentElement, null); - if (action == null) - throw new FrameworkException ("Action not found"); - - } else { - - // march down request path... - StringTokenizer st = new StringTokenizer (req.path, "/"); - int ntokens = st.countTokens (); - // limit path to < 50 tokens - if (ntokens > 50) - throw new RuntimeException ("Path too long"); - String[] pathItems = new String [ntokens]; - for (int i=0; i<ntokens; i++) - pathItems[i] = st.nextToken (); - - currentElement = root; - requestPath.add (currentElement); - macroHandlers.put ("root", root); - - for (int i=0; i<ntokens; i++) { - - if (currentElement == null) - throw new FrameworkException ("Object not found."); - - if (pathItems[i].length () == 0) - continue; - - // we used to do special processing for /user and /users - // here but with the framework cleanup, this stuff has to be - // mounted manually. - - // if we're at the last element of the path, - // try to interpret it as action name. - if (i == ntokens-1) { - action = getAction (currentElement, pathItems[i]); - } - - if (action == null) { - - currentElement = app.getChildElement (currentElement, pathItems[i]); - - // add object to request path if suitable - if (currentElement != null) { - // add to requestPath array - requestPath.add (currentElement); - Prototype proto = app.getPrototype (currentElement); - if (proto != null) - proto.addToHandlerMap (macroHandlers, currentElement); - } - } - } - - if (currentElement == null) - throw new FrameworkException ("Object not found."); - - if (action == null) - action = getAction (currentElement, null); - - if (action == null) - throw new FrameworkException ("Action not found"); - } - - } catch (FrameworkException notfound) { - if (error != null) - // we already have an error and the error template wasn't found, - // display it instead of notfound message - throw new RuntimeException (); - // The path could not be resolved. Check if there is a "not found" action - // specified in the property file. - res.status = 404; - String notFoundAction = app.props.getProperty ("notFound", "notfound"); - currentElement = root; - action = getAction (currentElement, notFoundAction); - if (action == null) - throw new FrameworkException (notfound.getMessage ()); - } - - ///////////////////////////////////////////////////////////////////////////// - // end of path resolution section - - ///////////////////////////////////////////////////////////////////////////// - // beginning of execution section - try { - // enter execution context - scriptingEngine.enterContext (globals); - - // set the req.action property, cutting off the _action suffix - req.action = action.substring (0, action.length()-7); - // set the application checksum in response to make ETag - // generation sensitive to changes in the app - res.setApplicationChecksum (app.getChecksum ()); - - // reset skin recursion detection counter - skinDepth = 0; - - // try calling onRequest() function on object before - // calling the actual action - try { - if (scriptingEngine.hasFunction (currentElement, "onRequest")) - scriptingEngine.invoke (currentElement, "onRequest", new Object[0], false); - } catch (RedirectException redir) { - throw redir; - } - - // reset skin recursion detection counter - skinDepth = 0; - - // do the actual action invocation - scriptingEngine.invoke (currentElement, action, new Object[0], false); - - } catch (RedirectException redirect) { - // res.redirect = redirect.getMessage (); - // if there is a message set, save it on the user object for the next request - if (res.message != null) - session.message = res.message; - done = true; - } - - // check if we're still the one and only or if the waiting thread has given up on us already - commitTransaction (); - done = true; - - } catch (ConcurrencyException x) { - - res.reset (); - if (++tries < 8) { - // try again after waiting some period - abortTransaction (true); - try { - // wait a bit longer with each try - int base = 800 * tries; - Thread.currentThread ().sleep ((long) (base + Math.random ()*base*2)); - } catch (Exception ignore) {} - continue; - } else { - abortTransaction (false); - if (error == null) { - app.errorCount += 1; - // set done to false so that the error will be processed - done = false; - error = "Couldn't complete transaction due to heavy object traffic (tried "+tries+" times)"; - } else { - // error in error action. use traditional minimal error message - res.write ("<b>Error in application '"+app.getName()+"':</b> <br><br><pre>"+error+"</pre>"); - done = true; - } - } - - } catch (Exception x) { - - abortTransaction (false); - - // If the transactor thread has been killed by the invoker thread we don't have to - // bother for the error message, just quit. - if (localrtx != rtx) { - break; - } - - res.reset (); - - // check if we tried to process the error already - if (error == null) { - app.errorCount += 1; - app.logEvent ("Exception in "+Thread.currentThread()+": "+x); - // set done to false so that the error will be processed - done = false; - error = x.getMessage (); - if (error == null || error.length() == 0) - error = x.toString (); - if (error == null) - error = "Unspecified error"; - } else { - // error in error action. use traditional minimal error message - res.write ("<b>Error in application '"+app.getName()+"':</b> <br><br><pre>"+error+"</pre>"); - done = true; - } - - } - } - break; - case XMLRPC: - try { - localrtx.begin (app.getName()+":xmlrpc:"+method); - - root = app.getDataRoot (); - - HashMap globals = new HashMap (); - globals.put ("root", root); - globals.put ("res", new ResponseBean (res)); - globals.put ("app", new ApplicationBean (app)); - - scriptingEngine.enterContext (globals); - - currentElement = root; - - if (method.indexOf (".") > -1) { - StringTokenizer st = new StringTokenizer (method, "."); - int cnt = st.countTokens (); - for (int i=1; i<cnt; i++) { - String next = st.nextToken (); - currentElement = app.getChildElement (currentElement, next); - } - - if (currentElement == null) - throw new FrameworkException ("Method name \""+method+"\" could not be resolved."); - method = st.nextToken (); - } - - // check XML-RPC access permissions - String proto = app.getPrototypeName (currentElement); - app.checkXmlRpcAccess (proto, method); - // reset skin recursion detection counter - skinDepth = 0; - - result = scriptingEngine.invoke (currentElement, method, args, true); - commitTransaction (); - - } catch (Exception x) { - - abortTransaction (false); - - app.logEvent ("Exception in "+Thread.currentThread()+": "+x); - - // If the transactor thread has been killed by the invoker thread we don't have to - // bother for the error message, just quit. - if (localrtx != rtx) { - return; - } - - this.exception = x; - } - - break; - case INTERNAL: - // Just a human readable descriptor of this invocation - String funcdesc = app.getName()+":internal:"+method; - - // if thisObject is an instance of NodeHandle, get the node object itself. - if (thisObject != null && thisObject instanceof NodeHandle) { - thisObject = ((NodeHandle) thisObject).getNode (app.nmgr.safe); - // see if a valid node was returned - if (thisObject == null) { - reqtype = NONE; - break; - } - } + do { + // long startCheck = System.currentTimeMillis (); + app.typemgr.checkPrototypes(); + initScriptingEngine(); + scriptingEngine.updatePrototypes(); + + // System.err.println ("Type check overhead: "+(System.currentTimeMillis ()-startCheck)+" millis"); + // object refs to ressolve request path + Object root; + + // System.err.println ("Type check overhead: "+(System.currentTimeMillis ()-startCheck)+" millis"); + // object refs to ressolve request path + Object currentElement; + + requestPath = new ArrayList(); + + switch (reqtype) { + case HTTP: + + int tries = 0; + boolean done = false; + String error = null; + + while (!done) { + currentElement = null; + + try { + // used for logging + StringBuffer txname = new StringBuffer(app.getName()); + + txname.append("/"); + txname.append((error == null) ? req.path : "error"); + + // begin transaction + localrtx.begin(txname.toString()); + + String action = null; + + root = app.getDataRoot(); + + HashMap globals = new HashMap(); + + globals.put("root", root); + globals.put("session", new SessionBean(session)); + globals.put("req", new RequestBean(req)); + globals.put("res", new ResponseBean(res)); + globals.put("app", new ApplicationBean(app)); + globals.put("path", requestPath); + req.startTime = System.currentTimeMillis(); + + if (error != null) { + res.error = error; + } + + if (session.message != null) { + // bring over the message from a redirect + res.message = session.message; + session.message = null; + } + + Map macroHandlers = res.getMacroHandlers(); + + try { + if (error != null) { + // there was an error in the previous loop, call error handler + currentElement = root; + + // do not reset the requestPath so error handler can use the original one + // get error handler action + String errorAction = app.props.getProperty("error", + "error"); + + action = getAction(currentElement, errorAction); + + if (action == null) { + throw new RuntimeException(error); + } + } else if ((req.path == null) || + "".equals(req.path.trim())) { + currentElement = root; + requestPath.add(currentElement); + macroHandlers.put("root", root); + action = getAction(currentElement, null); + + if (action == null) { + throw new FrameworkException("Action not found"); + } + } else { + // march down request path... + StringTokenizer st = new StringTokenizer(req.path, + "/"); + int ntokens = st.countTokens(); + + // limit path to < 50 tokens + if (ntokens > 50) { + throw new RuntimeException("Path too long"); + } + + String[] pathItems = new String[ntokens]; + + for (int i = 0; i < ntokens; i++) + pathItems[i] = st.nextToken(); + + currentElement = root; + requestPath.add(currentElement); + macroHandlers.put("root", root); + + for (int i = 0; i < ntokens; i++) { + if (currentElement == null) { + throw new FrameworkException("Object not found."); + } + + if (pathItems[i].length() == 0) { + continue; + } + + // we used to do special processing for /user and /users + // here but with the framework cleanup, this stuff has to be + // mounted manually. + // if we're at the last element of the path, + // try to interpret it as action name. + if (i == (ntokens - 1)) { + action = getAction(currentElement, + pathItems[i]); + } + + if (action == null) { + currentElement = app.getChildElement(currentElement, + pathItems[i]); + + // add object to request path if suitable + if (currentElement != null) { + // add to requestPath array + requestPath.add(currentElement); + + Prototype proto = app.getPrototype(currentElement); + + if (proto != null) { + proto.addToHandlerMap(macroHandlers, + currentElement); + } + } + } + } + + if (currentElement == null) { + throw new FrameworkException("Object not found."); + } + + if (action == null) { + action = getAction(currentElement, null); + } + + if (action == null) { + throw new FrameworkException("Action not found"); + } + } + } catch (FrameworkException notfound) { + if (error != null) { + + // we already have an error and the error template wasn't found, + // display it instead of notfound message + throw new RuntimeException(); + } + + // The path could not be resolved. Check if there is a "not found" action + // specified in the property file. + res.status = 404; + + String notFoundAction = app.props.getProperty("notFound", + "notfound"); + + currentElement = root; + action = getAction(currentElement, notFoundAction); + + if (action == null) { + throw new FrameworkException(notfound.getMessage()); + } + } + + ///////////////////////////////////////////////////////////////////////////// + // end of path resolution section + ///////////////////////////////////////////////////////////////////////////// + // beginning of execution section + try { + // enter execution context + scriptingEngine.enterContext(globals); + + // set the req.action property, cutting off the _action suffix + req.action = action.substring(0, action.length() - 7); + + // set the application checksum in response to make ETag + // generation sensitive to changes in the app + res.setApplicationChecksum(app.getChecksum()); + + // reset skin recursion detection counter + skinDepth = 0; + + // try calling onRequest() function on object before + // calling the actual action + try { + if (scriptingEngine.hasFunction(currentElement, + "onRequest")) { + scriptingEngine.invoke(currentElement, + "onRequest", + new Object[0], false); + } + } catch (RedirectException redir) { + throw redir; + } + + // reset skin recursion detection counter + skinDepth = 0; + + // do the actual action invocation + scriptingEngine.invoke(currentElement, action, + new Object[0], false); + } catch (RedirectException redirect) { + // res.redirect = redirect.getMessage (); + // if there is a message set, save it on the user object for the next request + if (res.message != null) { + session.message = res.message; + } + + done = true; + } + + // check if we're still the one and only or if the waiting thread has given up on us already + commitTransaction(); + done = true; + } catch (ConcurrencyException x) { + res.reset(); + + if (++tries < 8) { + // try again after waiting some period + abortTransaction(true); + + try { + // wait a bit longer with each try + int base = 800 * tries; + + Thread.currentThread().sleep((long) (base + + (Math.random() * base * 2))); + } catch (Exception ignore) { + } + + continue; + } else { + abortTransaction(false); + + if (error == null) { + app.errorCount += 1; + + // set done to false so that the error will be processed + done = false; + error = "Couldn't complete transaction due to heavy object traffic (tried " + + tries + " times)"; + } else { + // error in error action. use traditional minimal error message + res.write("<b>Error in application '" + + app.getName() + "':</b> <br><br><pre>" + + error + "</pre>"); + done = true; + } + } + } catch (Exception x) { + abortTransaction(false); + + // If the transactor thread has been killed by the invoker thread we don't have to + // bother for the error message, just quit. + if (localrtx != rtx) { + break; + } + + res.reset(); + + // check if we tried to process the error already + if (error == null) { + app.errorCount += 1; + app.logEvent("Exception in " + + Thread.currentThread() + ": " + x); + + // set done to false so that the error will be processed + done = false; + error = x.getMessage(); + + if ((error == null) || (error.length() == 0)) { + error = x.toString(); + } + + if (error == null) { + error = "Unspecified error"; + } + } else { + // error in error action. use traditional minimal error message + res.write("<b>Error in application '" + + app.getName() + "':</b> <br><br><pre>" + + error + "</pre>"); + done = true; + } + } + } + + break; + + case XMLRPC: + + try { + localrtx.begin(app.getName() + ":xmlrpc:" + method); - // avoid going into transaction if called function doesn't exist - boolean functionexists = true; - functionexists = scriptingEngine.hasFunction (thisObject, method); - - if (!functionexists) { - // function doesn't exist, nothing to do here. - reqtype = NONE; - } else try { - localrtx.begin (funcdesc); - - root = app.getDataRoot (); - - HashMap globals = new HashMap (); - globals.put ("root", root); - globals.put ("res", new ResponseBean (res)); - globals.put ("app", new ApplicationBean (app)); - - scriptingEngine.enterContext (globals); - // reset skin recursion detection counter - skinDepth = 0; + root = app.getDataRoot(); - result = scriptingEngine.invoke (thisObject, method, args, false); - commitTransaction (); + HashMap globals = new HashMap(); - } catch (Exception x) { + globals.put("root", root); + globals.put("res", new ResponseBean(res)); + globals.put("app", new ApplicationBean(app)); - abortTransaction (false); + scriptingEngine.enterContext(globals); - app.logEvent ("Exception in "+Thread.currentThread()+": "+x); + currentElement = root; - // If the transactor thread has been killed by the invoker thread we don't have to - // bother for the error message, just quit. - if (localrtx != rtx) { - return; - } + if (method.indexOf(".") > -1) { + StringTokenizer st = new StringTokenizer(method, "."); + int cnt = st.countTokens(); - this.exception = x; - } + for (int i = 1; i < cnt; i++) { + String next = st.nextToken(); - break; + currentElement = app.getChildElement(currentElement, + next); + } - } + if (currentElement == null) { + throw new FrameworkException("Method name \"" + + method + + "\" could not be resolved."); + } - // exit execution context - scriptingEngine.exitContext (); + method = st.nextToken(); + } - // make sure there is only one thread running per instance of this class - // if localrtx != rtx, the current thread has been aborted and there's no need to notify - if (localrtx != rtx) { - localrtx.closeConnections (); - return; - } + // check XML-RPC access permissions + String proto = app.getPrototypeName(currentElement); - notifyAndWait (); + app.checkXmlRpcAccess(proto, method); - } while (localrtx == rtx); + // reset skin recursion detection counter + skinDepth = 0; + result = scriptingEngine.invoke(currentElement, method, args, + true); + commitTransaction(); + } catch (Exception x) { + abortTransaction(false); + + app.logEvent("Exception in " + Thread.currentThread() + ": " + + x); + + // If the transactor thread has been killed by the invoker thread we don't have to + // bother for the error message, just quit. + if (localrtx != rtx) { + return; + } + + this.exception = x; + } + + break; + + case INTERNAL: + + // Just a human readable descriptor of this invocation + String funcdesc = app.getName() + ":internal:" + method; + + // if thisObject is an instance of NodeHandle, get the node object itself. + if ((thisObject != null) && thisObject instanceof NodeHandle) { + thisObject = ((NodeHandle) thisObject).getNode(app.nmgr.safe); + + // see if a valid node was returned + if (thisObject == null) { + reqtype = NONE; + + break; + } + } + + // avoid going into transaction if called function doesn't exist + boolean functionexists = true; + + functionexists = scriptingEngine.hasFunction(thisObject, method); + + if (!functionexists) { + // function doesn't exist, nothing to do here. + reqtype = NONE; + } else { + try { + localrtx.begin(funcdesc); + + root = app.getDataRoot(); + + HashMap globals = new HashMap(); + + globals.put("root", root); + globals.put("res", new ResponseBean(res)); + globals.put("app", new ApplicationBean(app)); + + scriptingEngine.enterContext(globals); + + // reset skin recursion detection counter + skinDepth = 0; + + result = scriptingEngine.invoke(thisObject, method, args, + false); + commitTransaction(); + } catch (Exception x) { + abortTransaction(false); + + app.logEvent("Exception in " + Thread.currentThread() + + ": " + x); + + // If the transactor thread has been killed by the invoker thread we don't have to + // bother for the error message, just quit. + if (localrtx != rtx) { + return; + } + + this.exception = x; + } + } + + break; + } + + // exit execution context + scriptingEngine.exitContext(); + + // make sure there is only one thread running per instance of this class + // if localrtx != rtx, the current thread has been aborted and there's no need to notify + if (localrtx != rtx) { + localrtx.closeConnections(); + + return; + } + + notifyAndWait(); + } while (localrtx == rtx); } finally { - localrtx.closeConnections (); + localrtx.closeConnections(); } } /** * Called by the transactor thread when it has successfully fulfilled a request. */ - synchronized void commitTransaction () throws Exception { - Transactor localrtx = (Transactor) Thread.currentThread (); - if (localrtx == rtx) { - reqtype = NONE; - localrtx.commit (); - } else { - throw new TimeoutException (); - } + synchronized void commitTransaction() throws Exception { + Transactor localrtx = (Transactor) Thread.currentThread(); + + if (localrtx == rtx) { + reqtype = NONE; + localrtx.commit(); + } else { + throw new TimeoutException(); + } } - synchronized void abortTransaction (boolean retry) { - Transactor localrtx = (Transactor) Thread.currentThread (); - if (!retry && localrtx == rtx) - reqtype = NONE; - try { - localrtx.abort (); - } catch (Exception ignore) {} + synchronized void abortTransaction(boolean retry) { + Transactor localrtx = (Transactor) Thread.currentThread(); + + if (!retry && (localrtx == rtx)) { + reqtype = NONE; + } + + try { + localrtx.abort(); + } catch (Exception ignore) { + } } /** * Tell waiting thread that we're done, then wait for next request */ - synchronized void notifyAndWait () { - Transactor localrtx = (Transactor) Thread.currentThread (); - if (reqtype != NONE) - return; // is there a new request already? + synchronized void notifyAndWait() { + Transactor localrtx = (Transactor) Thread.currentThread(); - notifyAll (); - try { - // wait for request, max 10 min - wait (1000*60*10); - // if no request arrived, release ressources and thread - if (reqtype == NONE && rtx == localrtx) { - // comment this in to release not just the thread, but also the scripting engine. - // currently we don't do this because of the risk of memory leaks (objects from - // framework referencing into the scripting engine) - // scriptingEngine = null; - rtx = null; - } - } catch (InterruptedException ir) {} + if (reqtype != NONE) { + return; // is there a new request already? + } + + notifyAll(); + + try { + // wait for request, max 10 min + wait(1000 * 60 * 10); + + // if no request arrived, release ressources and thread + if ((reqtype == NONE) && (rtx == localrtx)) { + // comment this in to release not just the thread, but also the scripting engine. + // currently we don't do this because of the risk of memory leaks (objects from + // framework referencing into the scripting engine) + // scriptingEngine = null; + rtx = null; + } + } catch (InterruptedException ir) { + } } - public synchronized ResponseTrans invoke (RequestTrans req, Session session) throws Exception { - this.reqtype = HTTP; - this.req = req; - this.session = session; - this.res = new ResponseTrans (req); + /** + * + * + * @param req ... + * @param session ... + * + * @return ... + * + * @throws Exception ... + */ + public synchronized ResponseTrans invoke(RequestTrans req, Session session) + throws Exception { + this.reqtype = HTTP; + this.req = req; + this.session = session; + this.res = new ResponseTrans(req); - app.activeRequests.put (req, this); + app.activeRequests.put(req, this); - checkThread (); - wait (app.requestTimeout); - if (reqtype != NONE) { - app.logEvent ("Stopping Thread for Request "+app.getName()+"/"+req.path); - stopThread (); - res.reset (); - res.write ("<b>Error in application '" + - app.getName() + - "':</b> <br><br><pre>Request timed out.</pre>"); - } - return res; + checkThread(); + wait(app.requestTimeout); + + if (reqtype != NONE) { + app.logEvent("Stopping Thread for Request " + app.getName() + "/" + req.path); + stopThread(); + res.reset(); + res.write("<b>Error in application '" + app.getName() + + "':</b> <br><br><pre>Request timed out.</pre>"); + } + + return res; } /** * This checks if the Evaluator is already executing an equal request. If so, attach to it and * wait for it to complete. Otherwise return null, so the application knows it has to run the request. */ - public synchronized ResponseTrans attachRequest (RequestTrans req) throws InterruptedException { - if (this.req == null || res == null || !this.req.equals (req)) - return null; - // we already know our response object - ResponseTrans r = res; - if (reqtype != NONE) - wait (app.requestTimeout); - return r; + public synchronized ResponseTrans attachRequest(RequestTrans req) + throws InterruptedException { + if ((this.req == null) || (res == null) || !this.req.equals(req)) { + return null; + } + + // we already know our response object + ResponseTrans r = res; + + if (reqtype != NONE) { + wait(app.requestTimeout); + } + + return r; } + /** + * + * + * @param method ... + * @param args ... + * + * @return ... + * + * @throws Exception ... + */ + public synchronized Object invokeXmlRpc(String method, Object[] args) + throws Exception { + this.reqtype = XMLRPC; + this.session = null; + this.method = method; + this.args = args; + this.res = new ResponseTrans(); + result = null; + exception = null; - public synchronized Object invokeXmlRpc (String method, Object[] args) throws Exception { - this.reqtype = XMLRPC; - this.session = null; - this.method = method; - this.args = args; - this.res = new ResponseTrans (); - result = null; - exception = null; + checkThread(); + wait(app.requestTimeout); - checkThread (); - wait (app.requestTimeout); - if (reqtype != NONE) { - stopThread (); - } + if (reqtype != NONE) { + stopThread(); + } - // reset res for garbage collection (res.data may hold reference to evaluator) - res = null; - if (exception != null) - throw (exception); - return result; + // reset res for garbage collection (res.data may hold reference to evaluator) + res = null; + + if (exception != null) { + throw (exception); + } + + return result; } - public Object invokeDirectFunction (Object obj, String functionName, Object[] args) throws Exception { - return scriptingEngine.invoke (obj, functionName, args, false); + /** + * + * + * @param obj ... + * @param functionName ... + * @param args ... + * + * @return ... + * + * @throws Exception ... + */ + public Object invokeDirectFunction(Object obj, String functionName, Object[] args) + throws Exception { + return scriptingEngine.invoke(obj, functionName, args, false); } - public synchronized Object invokeFunction (Object object, String functionName, Object[] args) - throws Exception { - reqtype = INTERNAL; - session = null; - thisObject = object; - method = functionName; - this.args =args; - this.res = new ResponseTrans (); - result = null; - exception = null; - - checkThread (); - wait (60000l*15); // give internal call more time (15 minutes) to complete - - if (reqtype != NONE) { - stopThread (); - } - - // reset res for garbage collection (res.data may hold reference to evaluator) - res = null; - if (exception != null) - throw (exception); - return result; + /** + * + * + * @param object ... + * @param functionName ... + * @param args ... + * + * @return ... + * + * @throws Exception ... + */ + public synchronized Object invokeFunction(Object object, String functionName, + Object[] args) + throws Exception { + // give internal call more time (15 minutes) to complete + return invokeFunction(object, functionName, args, 60000L * 15); } - public synchronized Object invokeFunction (Session session, String functionName, Object[] args) - throws Exception { - reqtype = INTERNAL; - this.session = session; - thisObject = null; - method = functionName; - this.args = args; - res = new ResponseTrans (); - result = null; - exception = null; + /** + * + * + * @param object ... + * @param functionName ... + * @param args ... + * @param timeout ... + * + * @return ... + * + * @throws Exception ... + */ + public synchronized Object invokeFunction(Object object, String functionName, + Object[] args, long timeout) + throws Exception { + reqtype = INTERNAL; + session = null; + thisObject = object; + method = functionName; + this.args = args; + this.res = new ResponseTrans(); + result = null; + exception = null; - checkThread (); - wait (app.requestTimeout); + checkThread(); + wait(timeout); - if (reqtype != NONE) { - stopThread (); - } + if (reqtype != NONE) { + stopThread(); + } - // reset res for garbage collection (res.data may hold reference to evaluator) - res = null; - if (exception != null) - throw (exception); - return result; + // reset res for garbage collection (res.data may hold reference to evaluator) + res = null; + + if (exception != null) { + throw (exception); + } + + return result; } + /** + * + * + * @param session ... + * @param functionName ... + * @param args ... + * + * @return ... + * + * @throws Exception ... + */ + public synchronized Object invokeFunction(Session session, String functionName, + Object[] args) + throws Exception { + reqtype = INTERNAL; + this.session = session; + thisObject = null; + method = functionName; + this.args = args; + res = new ResponseTrans(); + result = null; + exception = null; + + checkThread(); + wait(app.requestTimeout); + + if (reqtype != NONE) { + stopThread(); + } + + // reset res for garbage collection (res.data may hold reference to evaluator) + res = null; + + if (exception != null) { + throw (exception); + } + return result; + } /** * Stop this request evaluator's current thread. If currently active kill the request, otherwise just * notify. */ - public synchronized void stopThread () { - app.logEvent ("Stopping Thread "+rtx); - Transactor t = rtx; - // let the scripting engine know that the - // current transaction is being aborted. - if (scriptingEngine != null) - scriptingEngine.abort (); - rtx = null; - if (t != null) { - if (reqtype != NONE) { - reqtype = NONE; - t.kill (); - try { - t.abort (); - } catch (Exception ignore) {} - } else { - notifyAll (); - } - t.closeConnections (); - } + public synchronized void stopThread() { + app.logEvent("Stopping Thread " + rtx); + + Transactor t = rtx; + + // let the scripting engine know that the + // current transaction is being aborted. + if (scriptingEngine != null) { + scriptingEngine.abort(); + } + + rtx = null; + + if (t != null) { + if (reqtype != NONE) { + reqtype = NONE; + t.kill(); + + try { + t.abort(); + } catch (Exception ignore) { + } + } else { + notifyAll(); + } + + t.closeConnections(); + } } - private synchronized void checkThread () throws InterruptedException { + private synchronized void checkThread() throws InterruptedException { + if (app.stopped) { + throw new ApplicationStoppedException(); + } - if (app.stopped) - throw new ApplicationStoppedException (); - - if (rtx == null || !rtx.isAlive()) { - // app.logEvent ("Starting Thread"); - rtx = new Transactor (this, app.threadgroup, app.nmgr); - rtx.setContextClassLoader (app.getClassLoader ()); - rtx.start (); - } else { - notifyAll (); - } + if ((rtx == null) || !rtx.isAlive()) { + // app.logEvent ("Starting Thread"); + rtx = new Transactor(this, app.threadgroup, app.nmgr); + rtx.setContextClassLoader(app.getClassLoader()); + rtx.start(); + } else { + notifyAll(); + } } /** * Null out some fields, mostly for the sake of garbage collection. */ - public void recycle () { + public void recycle() { res = null; req = null; session = null; @@ -692,14 +887,17 @@ public final class RequestEvaluator implements Runnable { * Check if an action with a given name is defined for a scripted object. If it is, * return the action's function name. Otherwise, return null. */ - public String getAction (Object obj, String action) { - if (obj == null) - return null; - String act = action == null ? "main_action" : action+"_action"; - if (scriptingEngine.hasFunction (obj, act)) - return act; - return null; + public String getAction(Object obj, String action) { + if (obj == null) { + return null; + } + + String act = (action == null) ? "main_action" : (action + "_action"); + + if (scriptingEngine.hasFunction(obj, act)) { + return act; + } + + return null; } - } - diff --git a/src/helma/framework/core/Session.java b/src/helma/framework/core/Session.java index d9a8acde..f6c6e149 100644 --- a/src/helma/framework/core/Session.java +++ b/src/helma/framework/core/Session.java @@ -1,12 +1,26 @@ -// Session.java +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.framework.core; -import java.io.*; -import java.util.*; -import java.net.URLEncoder; import helma.objectmodel.*; import helma.objectmodel.db.*; +import java.io.*; +import java.net.URLEncoder; +import java.util.*; /** * This represents a session currently using the Hop application. @@ -14,9 +28,7 @@ import helma.objectmodel.db.*; * Depending on whether the user is logged in or not, the user object holds a * persistent user node. */ - public class Session implements Serializable { - transient Application app; String sessionID; @@ -29,118 +41,175 @@ public class Session implements Serializable { // the transient cache node that is exposed to javascript // this stays the same across logins and logouts. public TransientNode cacheNode; - - long onSince, lastTouched, lastModified; + long onSince; + long lastTouched; + long lastModified; // used to remember messages to the user between requests - // used for redirects. String message; - public Session (String sessionID, Application app) { - this.sessionID = sessionID; - this.app = app; - this.uid = null; - this.userHandle = null; - cacheNode = new TransientNode ("session"); - onSince = System.currentTimeMillis (); - lastTouched = lastModified = onSince; + /** + * Creates a new Session object. + * + * @param sessionID ... + * @param app ... + */ + public Session(String sessionID, Application app) { + this.sessionID = sessionID; + this.app = app; + this.uid = null; + this.userHandle = null; + cacheNode = new TransientNode("session"); + onSince = System.currentTimeMillis(); + lastTouched = lastModified = onSince; } /** * attach the given user node to this session. */ - public void login (INode usernode) { - if (usernode==null) { - userHandle = null; - uid = null; - } else { - userHandle = ((Node)usernode).getHandle(); - uid = usernode.getElementName(); - } - lastModified = System.currentTimeMillis (); + public void login(INode usernode) { + if (usernode == null) { + userHandle = null; + uid = null; + } else { + userHandle = ((Node) usernode).getHandle(); + uid = usernode.getElementName(); + } + + lastModified = System.currentTimeMillis(); } /** * remove this sessions's user node. */ public void logout() { - userHandle = null; - uid = null; - lastModified = System.currentTimeMillis (); + userHandle = null; + uid = null; + lastModified = System.currentTimeMillis(); } + /** + * + * + * @return ... + */ public boolean isLoggedIn() { - if (userHandle!=null && uid!=null) { - return true; - } else { - return false; - } + if ((userHandle != null) && (uid != null)) { + return true; + } else { + return false; + } } /** * Gets the user Node from this Application's NodeManager. */ public INode getUserNode() { - if (userHandle!=null) - return userHandle.getNode (app.getWrappedNodeManager()); - else - return null; + if (userHandle != null) { + return userHandle.getNode(app.getWrappedNodeManager()); + } else { + return null; + } } /** * Gets the transient cache node. */ - public INode getCacheNode () { - return cacheNode; + public INode getCacheNode() { + return cacheNode; } - public Application getApp () { - return app; + /** + * + * + * @return ... + */ + public Application getApp() { + return app; } - public void setApp (Application app) { - this.app = app; + /** + * + * + * @param app ... + */ + public void setApp(Application app) { + this.app = app; } - public String getSessionID () { - return sessionID; + /** + * + * + * @return ... + */ + public String getSessionID() { + return sessionID; } - public void touch () { - lastTouched = System.currentTimeMillis (); + /** + * + */ + public void touch() { + lastTouched = System.currentTimeMillis(); } - public long lastTouched () { - return lastTouched; + /** + * + * + * @return ... + */ + public long lastTouched() { + return lastTouched; } - public long lastModified () { - return lastModified; - } - - public void setLastModified (Date date) { - if (date != null) - lastModified = date.getTime (); + /** + * + * + * @return ... + */ + public long lastModified() { + return lastModified; } - public long onSince () { - return onSince; + /** + * + * + * @param date ... + */ + public void setLastModified(Date date) { + if (date != null) { + lastModified = date.getTime(); + } } - public String toString () { - if ( uid!=null ) - return "[Session for user " + uid + "]"; - else - return "[Anonymous Session]"; + /** + * + * + * @return ... + */ + public long onSince() { + return onSince; + } + + /** + * + * + * @return ... + */ + public String toString() { + if (uid != null) { + return "[Session for user " + uid + "]"; + } else { + return "[Anonymous Session]"; + } } /** * Get the persistent user id of a registered user. This is usually the user name, or * null if the user is not logged in. */ - public String getUID () { - return uid; + public String getUID() { + return uid; } - } - diff --git a/src/helma/framework/core/SessionBean.java b/src/helma/framework/core/SessionBean.java index 35f1c175..925756c9 100644 --- a/src/helma/framework/core/SessionBean.java +++ b/src/helma/framework/core/SessionBean.java @@ -1,79 +1,163 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.framework.core; +import helma.objectmodel.INode; +import helma.scripting.fesi.*; import java.io.Serializable; import java.util.Date; import java.util.HashMap; -import helma.objectmodel.INode; -import helma.scripting.fesi.*; - +/** + * + */ public class SessionBean implements Serializable { - // the wrapped session object Session session; - public SessionBean(Session session) { - this.session = session; + /** + * Creates a new SessionBean object. + * + * @param session ... + */ + public SessionBean(Session session) { + this.session = session; } - public String toString() { - return session.toString (); + /** + * + * + * @return ... + */ + public String toString() { + return session.toString(); } - public boolean login (String username, String password) { - boolean success = session.getApp().loginSession (username, password, session); - return success; + /** + * + * + * @param username ... + * @param password ... + * + * @return ... + */ + public boolean login(String username, String password) { + boolean success = session.getApp().loginSession(username, password, session); + + return success; } - public void logout () { - session.getApp().logoutSession (session); + /** + * + */ + public void logout() { + session.getApp().logoutSession(session); } - public void touch () { - session.touch (); + /** + * + */ + public void touch() { + session.touch(); } + /** + * + * + * @return ... + */ public Date lastActive() { - return new Date (session.lastTouched ()); + return new Date(session.lastTouched()); } + /** + * + * + * @return ... + */ public Date onSince() { - return new Date (session.onSince ()); + return new Date(session.onSince()); } // property-related methods: - public INode getdata() { - return session.getCacheNode (); + return session.getCacheNode(); } + /** + * + * + * @return ... + */ public INode getuser() { - return session.getUserNode(); + return session.getUserNode(); } - public String get_id () { - return session.getSessionID (); + /** + * + * + * @return ... + */ + public String get_id() { + return session.getSessionID(); } + /** + * + * + * @return ... + */ public String getcookie() { - return session.getSessionID (); + return session.getSessionID(); } + /** + * + * + * @return ... + */ public Date getlastActive() { - return new Date (session.lastTouched ()); + return new Date(session.lastTouched()); } + /** + * + * + * @return ... + */ public Date getonSince() { - return new Date (session.onSince ()); - } - - public Date getLastModified () { - return new Date (session.lastModified ()); + return new Date(session.onSince()); } - public void setLastModified (Date date) { - session.setLastModified (date); + /** + * + * + * @return ... + */ + public Date getLastModified() { + return new Date(session.lastModified()); } + /** + * + * + * @param date ... + */ + public void setLastModified(Date date) { + session.setLastModified(date); + } } - diff --git a/src/helma/framework/core/Skin.java b/src/helma/framework/core/Skin.java index 7febc3d5..bf561f54 100644 --- a/src/helma/framework/core/Skin.java +++ b/src/helma/framework/core/Skin.java @@ -1,15 +1,28 @@ -// Skin.java -// Copyright (c) Hannes Wallnöfer 2001 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.framework.core; import helma.framework.*; -import helma.scripting.*; -import helma.objectmodel.INode; import helma.objectmodel.ConcurrencyException; +import helma.objectmodel.INode; +import helma.scripting.*; import helma.util.HtmlEncoder; -import java.net.URLEncoder; import java.io.*; +import java.net.URLEncoder; import java.util.*; /** @@ -17,540 +30,641 @@ import java.util.*; * that will be dynamically evaluated.. It uses the request path array * from the RequestEvaluator object to resolve Macro handlers by type name. */ - public final class Skin { - - private Macro[] macros; - private Application app; - private char[] source; - private int sourceLength; - private HashSet sandbox; - - - /** - * Create a skin without any restrictions on which macros are allowed to be called from it - */ - public Skin (String content, Application app) { - this.app = app; - sandbox = null; - source = content.toCharArray (); - sourceLength = source.length; - parse (); - } - - /** - * Create a skin with a sandbox which contains the names of macros allowed to be called - */ - public Skin (String content, Application app, HashSet sandbox) { - this.app = app; - this.sandbox = sandbox; - source = content.toCharArray (); - sourceLength = source.length; - parse (); - } - - /** - * Create a skin without any restrictions on the macros from a char array. - */ - public Skin (char[] content, int length, Application app) { - this.app = app; - this.sandbox = null; - source = content; - sourceLength = length; - parse (); - } - - /** - * Parse a skin object from source text - */ - private void parse () { - - ArrayList partBuffer = new ArrayList (); - - int start = 0; - for (int i = 0; i < sourceLength-1; i++) { - if (source[i] == '<' && source[i+1] == '%') { - // found macro start tag - int j = i+2; - // search macr end tag - while (j < sourceLength-1 && (source[j] != '%' || source[j+1] != '>')) { - j++; - } - if (j > i+2) { - partBuffer.add (new Macro (i, j+2)); - start = j+2; - } - i = j+1; - } - } - - macros = new Macro[partBuffer.size()]; - partBuffer.toArray (macros); - } - - /** - * Get the raw source text this skin was parsed from - */ - public String getSource () { - return new String (source, 0, sourceLength); - } - - /** - * Render this skin - */ - public void render (RequestEvaluator reval, Object thisObject, Map paramObject) throws RedirectException { - - // check for endless skin recursion - if (++reval.skinDepth > 50) - throw new RuntimeException ("Recursive skin invocation suspected"); - - if (macros == null) { - reval.res.writeCharArray (source, 0, sourceLength); - reval.skinDepth--; - return; - } - - try { - int written = 0; - Map handlerCache = null; - if (macros.length > 3) { - handlerCache = new HashMap(); - } - for (int i=0; i<macros.length; i++) { - if (macros[i].start > written) - reval.res.writeCharArray (source, written, macros[i].start-written); - macros[i].render (reval, thisObject, paramObject, handlerCache); - written = macros[i].end; - } - if (written < sourceLength) - reval.res.writeCharArray (source, written, sourceLength-written); - } finally { - reval.skinDepth--; - } - } - - /** - * Check if a certain macro is present in this skin. The macro name is in handler.name notation - */ - public boolean containsMacro (String macroname) { - for (int i=0; i<macros.length; i++) { - if (macros[i] instanceof Macro) { - Macro m = (Macro) macros[i]; - if (macroname.equals (m.fullName)) - return true; - } - } - return false; - } - - /** - * Adds a macro to the list of allowed macros. The macro is in handler.name notation. - */ - public void allowMacro (String macroname) { - if (sandbox == null) { - sandbox = new HashSet (); - } - sandbox.add (macroname); - } - static final int HANDLER = 0; static final int MACRO = 1; static final int PARAMNAME = 2; static final int PARAMVALUE = 3; - static final int ENCODE_NONE = 0; static final int ENCODE_HTML = 1; static final int ENCODE_XML = 2; static final int ENCODE_FORM = 3; static final int ENCODE_URL = 4; static final int ENCODE_ALL = 5; + private Macro[] macros; + private Application app; + private char[] source; + private int sourceLength; + private HashSet sandbox; - class Macro { - - final int start, end; - String handler; - String name; - String fullName; - String prefix; - String suffix; - String defaultValue; - int encoding = ENCODE_NONE; - Map parameters = null; - - public Macro (int start, int end) { - - this.start = start; - this.end = end; - int state = HANDLER; - boolean escape = false; - char quotechar = '\u0000'; - String lastParamName = null; - StringBuffer b = new StringBuffer(); - - for (int i=start+2; i<end-2; i++) { - switch (source[i]) { - case '.': - if (state == HANDLER) { - handler = b.toString ().trim(); - b.setLength (0); - state = MACRO; - } else - b.append (source[i]); - break; - case '\\': - if (escape) - b.append (source[i]); - escape = !escape; - break; - case '"': - case '\'': - if (!escape && state == PARAMVALUE) { - if (quotechar == source[i]) { - String paramValue = b.toString(); - if (!setSpecialParameter (lastParamName, paramValue)) - addGenericParameter (lastParamName, paramValue); - lastParamName = null; - b.setLength (0); - state = PARAMNAME; - quotechar = '\u0000'; - } else if (quotechar == '\u0000') { - quotechar = source[i]; - b.setLength (0); - } else - b.append (source[i]); - } else - b.append (source[i]); - escape = false; - break; - case ' ': - case '\t': - case '\n': - case '\r': - case '\f': - if (state == MACRO || (state == HANDLER && b.length() > 0)) { - name = b.toString().trim(); - b.setLength (0); - state = PARAMNAME; - } else if (state == PARAMVALUE && quotechar == '\u0000') { - String paramValue = b.toString(); - if (!setSpecialParameter (lastParamName, paramValue)) - addGenericParameter (lastParamName, paramValue); - lastParamName = null; - b.setLength (0); - state = PARAMNAME; - } else if (state == PARAMVALUE) - b.append (source[i]); - else - b.setLength (0); - break; - case '=': - if (state == PARAMNAME) { - lastParamName = b.toString().trim(); - b.setLength (0); - state = PARAMVALUE; - } else - b.append (source[i]); - break; - default: - b.append (source[i]); - escape = false; - } - } - if (b.length() > 0) { - if (lastParamName != null && b.length() > 0) { - String paramValue = b.toString(); - if (!setSpecialParameter (lastParamName, paramValue)) - addGenericParameter (lastParamName, paramValue); - } else if (state <= MACRO) - name = b.toString().trim(); - } - if (handler == null) - fullName = name; - else - fullName = handler+"."+name; - - } - - - private boolean setSpecialParameter (String name, String value) { - if ("prefix".equals (name)) { - prefix = value; - return true; - } else if ("suffix".equals (name)) { - suffix = value; - return true; - } else if ("encoding".equals (name)) { - if ("html".equalsIgnoreCase (value)) - encoding = ENCODE_HTML; - else if ("xml".equalsIgnoreCase (value)) - encoding = ENCODE_XML; - else if ("form".equalsIgnoreCase (value)) - encoding = ENCODE_FORM; - else if ("url".equalsIgnoreCase (value)) - encoding = ENCODE_URL; - else if ("all".equalsIgnoreCase (value)) - encoding = ENCODE_ALL; - return true; - } else if ("default".equals (name)) { - defaultValue = value; - return true; - } - return false; - } - - private void addGenericParameter (String name, String value) { - if (parameters == null) - parameters = new HashMap (); - parameters.put (name, value); - } - - /** - * Render the macro given a handler object - */ - public void render (RequestEvaluator reval, Object thisObject, Map paramObject, Map handlerCache) throws RedirectException { - - if (sandbox != null && !sandbox.contains (fullName)) { - String h = handler == null ? "global" : handler; - reval.res.write ("[Macro "+fullName+" not allowed in sandbox]"); - return; - } else if ("response".equalsIgnoreCase (handler)) { - renderFromResponse (reval); - return; - } else if ("request".equalsIgnoreCase (handler)) { - renderFromRequest (reval); - return; - } else if ("param".equalsIgnoreCase (handler)) { - renderFromParam (reval, paramObject); - return; - } else if ("session".equalsIgnoreCase (handler)) { - renderFromSession (reval); - return; - } - - try { - - Object handlerObject = null; - - // flag to tell whether we found our invocation target object - boolean objectFound = true; - - if (handler != null) { - // try to get handler from handlerCache first - if (handlerCache != null) - handlerObject = handlerCache.get (handler); - - if (handlerObject == null) { - - // if handler object wasn't found in cache retrieve it - if (handlerObject == null && thisObject != null) { - // not a global macro - need to find handler object - // was called with this object - check it or its parents for matching prototype - if (!handler.equals ("this") && !handler.equals (app.getPrototypeName (thisObject))) { - // the handler object is not what we want - Object n = thisObject; - // walk down parent chain to find handler object - while (n != null) { - Prototype proto = app.getPrototype (n); - if (proto != null && proto.isInstanceOf (handler)) { - handlerObject = n; - break; - } - n = app.getParentElement (n); - } - } else { - // we already have the right handler object - handlerObject = thisObject; - } - } - - if (handlerObject == null) { - // eiter because thisObject == null or the right object wasn't found - // in the object's parent path. Check if a matching macro handler - // is registered with the response object (res.handlers). - handlerObject = reval.res.getMacroHandlers().get (handler); - } - - // the macro handler object couldn't be found - if (handlerObject == null) - objectFound = false; - // else put the found handler object into the cache so we don't have to look again - else if (handlerCache != null) - handlerCache.put (handler, handlerObject); - } - - } else { - // this is a global macro with no handler specified - handlerObject = null; - } - - if (objectFound) { - // check if a function called name_macro is defined. - // if so, the macro evaluates to the function. Otherwise, - // a property/field with the name is used, if defined. - - String funcName = name+"_macro"; - if (reval.scriptingEngine.hasFunction (handlerObject, funcName)) { - - StringBuffer buffer = reval.res.getBuffer(); - // remember length of response buffer before calling macro - int bufLength = buffer.length(); - // remember length of buffer with prefix written out - int preLength = 0; - if (prefix != null) { - buffer.append (prefix); - preLength = prefix.length(); - } - - // System.err.println ("Getting macro from function"); - // pass a clone of the parameter map so if the script changes it, - // Map param = ; - // if (parameters == null) - // parameters = new HashMap (); - Object[] arguments = { parameters == null ? - new HashMap () : - new HashMap (parameters) - }; - - Object value = reval.scriptingEngine.invoke (handlerObject, funcName, arguments, false); - - // check if macro wrote out to response buffer - if (buffer.length () == bufLength + preLength) { - // function didn't write out anything itself. - // erase previously written prefix - if (preLength > 0) - buffer.setLength (bufLength); - // write out macro's return value - writeResponse (value, buffer, true); - } else { - if (encoding != ENCODE_NONE) { - // if an encoding is specified, re-encode the macro's output - String output = buffer.substring (bufLength + preLength); - buffer.setLength (bufLength); - writeResponse (output, buffer, false); - } else { - // no re-encoding needed, just append suffix - if (suffix != null) - buffer.append (suffix); - } - writeResponse (value, buffer, false); - } - } else { - // System.err.println ("Getting macro from property"); - Object value = reval.scriptingEngine.get (handlerObject, name); - writeResponse (value, reval.res.getBuffer(), true); - } - } else { - String msg = "[HopMacro unhandled: "+fullName+"]"; - reval.res.write (" "+msg+" "); - app.logEvent (msg); - } - } catch (RedirectException redir) { - throw redir; - } catch (ConcurrencyException concur) { - throw concur; - } catch (TimeoutException timeout) { - throw timeout; - } catch (Exception x) { - // x.printStackTrace(); - String msg = x.getMessage(); - if (msg == null || msg.length() < 10) - msg = x.toString(); - msg = "[HopMacro error in "+fullName+": "+msg+"]"; - reval.res.write (" "+msg+" "); - app.logEvent (msg); - } - } - - private void renderFromResponse (RequestEvaluator reval) { - Object value = null; - if ("message".equals (name)) - value = reval.res.message; - else if ("error".equals (name)) - value = reval.res.error; - if (value == null) - value = reval.res.get (name); - writeResponse (value, reval.res.getBuffer(), true); - } - - private void renderFromRequest (RequestEvaluator reval) { - if (reval.req == null) - return; - Object value = reval.req.get (name); - writeResponse (value, reval.res.getBuffer(), true); - } - - private void renderFromSession (RequestEvaluator reval) { - if (reval.session == null) - return; - Object value = reval.session.getCacheNode().getString (name); - writeResponse (value, reval.res.getBuffer(), true); - } - - private void renderFromParam (RequestEvaluator reval, Map paramObject) { - if (paramObject == null) - reval.res.write ("[HopMacro error: Skin requires a parameter object]"); - else { - Object value = paramObject.get (name); - writeResponse (value, reval.res.getBuffer(), true); - } - } - - /** - * Utility method for writing text out to the response object. - */ - void writeResponse (Object value, StringBuffer buffer, boolean useDefault) { - String text; - if (value == null) { - if (useDefault) - text = defaultValue; - else - return; - } else { - text = value.toString (); - } - if (text != null && text.length() > 0) { - if (prefix != null) - buffer.append (prefix); - switch (encoding) { - case ENCODE_NONE: - buffer.append (text); - break; - case ENCODE_HTML: - HtmlEncoder.encode (text, buffer); - break; - case ENCODE_XML: - HtmlEncoder.encodeXml (text, buffer); - break; - case ENCODE_FORM: - HtmlEncoder.encodeFormValue (text, buffer); - break; - case ENCODE_URL: - buffer.append (URLEncoder.encode (text)); - break; - case ENCODE_ALL: - HtmlEncoder.encodeAll (text, buffer); - break; - } - if (suffix != null) - buffer.append (suffix); - } - } - - - public String toString () { - return "[HopMacro: "+fullName+"]"; - } - - - /** - * Return the full name of the macro in handler.name notation - */ - public String getFullName () { - return fullName; - } - + /** + * Create a skin without any restrictions on which macros are allowed to be called from it + */ + public Skin(String content, Application app) { + this.app = app; + sandbox = null; + source = content.toCharArray(); + sourceLength = source.length; + parse(); } + /** + * Create a skin with a sandbox which contains the names of macros allowed to be called + */ + public Skin(String content, Application app, HashSet sandbox) { + this.app = app; + this.sandbox = sandbox; + source = content.toCharArray(); + sourceLength = source.length; + parse(); + } + + /** + * Create a skin without any restrictions on the macros from a char array. + */ + public Skin(char[] content, int length, Application app) { + this.app = app; + this.sandbox = null; + source = content; + sourceLength = length; + parse(); + } + + /** + * Parse a skin object from source text + */ + private void parse() { + ArrayList partBuffer = new ArrayList(); + + int start = 0; + + for (int i = 0; i < (sourceLength - 1); i++) { + if ((source[i] == '<') && (source[i + 1] == '%')) { + // found macro start tag + int j = i + 2; + + // search macr end tag + while ((j < (sourceLength - 1)) && + ((source[j] != '%') || (source[j + 1] != '>'))) { + j++; + } + + if (j > (i + 2)) { + partBuffer.add(new Macro(i, j + 2)); + start = j + 2; + } + + i = j + 1; + } + } + + macros = new Macro[partBuffer.size()]; + partBuffer.toArray(macros); + } + + /** + * Get the raw source text this skin was parsed from + */ + public String getSource() { + return new String(source, 0, sourceLength); + } + + /** + * Render this skin + */ + public void render(RequestEvaluator reval, Object thisObject, Map paramObject) + throws RedirectException { + // check for endless skin recursion + if (++reval.skinDepth > 50) { + throw new RuntimeException("Recursive skin invocation suspected"); + } + + if (macros == null) { + reval.res.writeCharArray(source, 0, sourceLength); + reval.skinDepth--; + + return; + } + + try { + int written = 0; + Map handlerCache = null; + + if (macros.length > 3) { + handlerCache = new HashMap(); + } + + for (int i = 0; i < macros.length; i++) { + if (macros[i].start > written) { + reval.res.writeCharArray(source, written, macros[i].start - written); + } + + macros[i].render(reval, thisObject, paramObject, handlerCache); + written = macros[i].end; + } + + if (written < sourceLength) { + reval.res.writeCharArray(source, written, sourceLength - written); + } + } finally { + reval.skinDepth--; + } + } + + /** + * Check if a certain macro is present in this skin. The macro name is in handler.name notation + */ + public boolean containsMacro(String macroname) { + for (int i = 0; i < macros.length; i++) { + if (macros[i] instanceof Macro) { + Macro m = (Macro) macros[i]; + + if (macroname.equals(m.fullName)) { + return true; + } + } + } + + return false; + } + + /** + * Adds a macro to the list of allowed macros. The macro is in handler.name notation. + */ + public void allowMacro(String macroname) { + if (sandbox == null) { + sandbox = new HashSet(); + } + + sandbox.add(macroname); + } + + class Macro { + final int start; + final int end; + String handler; + String name; + String fullName; + String prefix; + String suffix; + String defaultValue; + int encoding = ENCODE_NONE; + Map parameters = null; + + public Macro(int start, int end) { + this.start = start; + this.end = end; + + int state = HANDLER; + boolean escape = false; + char quotechar = '\u0000'; + String lastParamName = null; + StringBuffer b = new StringBuffer(); + + for (int i = start + 2; i < (end - 2); i++) { + switch (source[i]) { + case '.': + + if (state == HANDLER) { + handler = b.toString().trim(); + b.setLength(0); + state = MACRO; + } else { + b.append(source[i]); + } + + break; + + case '\\': + + if (escape) { + b.append(source[i]); + } + + escape = !escape; + + break; + + case '"': + case '\'': + + if (!escape && (state == PARAMVALUE)) { + if (quotechar == source[i]) { + String paramValue = b.toString(); + + if (!setSpecialParameter(lastParamName, paramValue)) { + addGenericParameter(lastParamName, paramValue); + } + + lastParamName = null; + b.setLength(0); + state = PARAMNAME; + quotechar = '\u0000'; + } else if (quotechar == '\u0000') { + quotechar = source[i]; + b.setLength(0); + } else { + b.append(source[i]); + } + } else { + b.append(source[i]); + } + + escape = false; + + break; + + case ' ': + case '\t': + case '\n': + case '\r': + case '\f': + + if ((state == MACRO) || ((state == HANDLER) && (b.length() > 0))) { + name = b.toString().trim(); + b.setLength(0); + state = PARAMNAME; + } else if ((state == PARAMVALUE) && (quotechar == '\u0000')) { + String paramValue = b.toString(); + + if (!setSpecialParameter(lastParamName, paramValue)) { + addGenericParameter(lastParamName, paramValue); + } + + lastParamName = null; + b.setLength(0); + state = PARAMNAME; + } else if (state == PARAMVALUE) { + b.append(source[i]); + } else { + b.setLength(0); + } + + break; + + case '=': + + if (state == PARAMNAME) { + lastParamName = b.toString().trim(); + b.setLength(0); + state = PARAMVALUE; + } else { + b.append(source[i]); + } + + break; + + default: + b.append(source[i]); + escape = false; + } + } + + if (b.length() > 0) { + if ((lastParamName != null) && (b.length() > 0)) { + String paramValue = b.toString(); + + if (!setSpecialParameter(lastParamName, paramValue)) { + addGenericParameter(lastParamName, paramValue); + } + } else if (state <= MACRO) { + name = b.toString().trim(); + } + } + + if (handler == null) { + fullName = name; + } else { + fullName = handler + "." + name; + } + } + + private boolean setSpecialParameter(String name, String value) { + if ("prefix".equals(name)) { + prefix = value; + + return true; + } else if ("suffix".equals(name)) { + suffix = value; + + return true; + } else if ("encoding".equals(name)) { + if ("html".equalsIgnoreCase(value)) { + encoding = ENCODE_HTML; + } else if ("xml".equalsIgnoreCase(value)) { + encoding = ENCODE_XML; + } else if ("form".equalsIgnoreCase(value)) { + encoding = ENCODE_FORM; + } else if ("url".equalsIgnoreCase(value)) { + encoding = ENCODE_URL; + } else if ("all".equalsIgnoreCase(value)) { + encoding = ENCODE_ALL; + } + + return true; + } else if ("default".equals(name)) { + defaultValue = value; + + return true; + } + + return false; + } + + private void addGenericParameter(String name, String value) { + if (parameters == null) { + parameters = new HashMap(); + } + + parameters.put(name, value); + } + + /** + * Render the macro given a handler object + */ + public void render(RequestEvaluator reval, Object thisObject, Map paramObject, + Map handlerCache) throws RedirectException { + if ((sandbox != null) && !sandbox.contains(fullName)) { + String h = (handler == null) ? "global" : handler; + + reval.res.write("[Macro " + fullName + " not allowed in sandbox]"); + + return; + } else if ("response".equalsIgnoreCase(handler)) { + renderFromResponse(reval); + + return; + } else if ("request".equalsIgnoreCase(handler)) { + renderFromRequest(reval); + + return; + } else if ("param".equalsIgnoreCase(handler)) { + renderFromParam(reval, paramObject); + + return; + } else if ("session".equalsIgnoreCase(handler)) { + renderFromSession(reval); + + return; + } + + try { + Object handlerObject = null; + + // flag to tell whether we found our invocation target object + boolean objectFound = true; + + if (handler != null) { + // try to get handler from handlerCache first + if (handlerCache != null) { + handlerObject = handlerCache.get(handler); + } + + if (handlerObject == null) { + // if handler object wasn't found in cache retrieve it + if ((handlerObject == null) && (thisObject != null)) { + // not a global macro - need to find handler object + // was called with this object - check it or its parents for matching prototype + if (!handler.equals("this") && + !handler.equals(app.getPrototypeName(thisObject))) { + // the handler object is not what we want + Object n = thisObject; + + // walk down parent chain to find handler object + while (n != null) { + Prototype proto = app.getPrototype(n); + + if ((proto != null) && proto.isInstanceOf(handler)) { + handlerObject = n; + + break; + } + + n = app.getParentElement(n); + } + } else { + // we already have the right handler object + handlerObject = thisObject; + } + } + + if (handlerObject == null) { + // eiter because thisObject == null or the right object wasn't found + // in the object's parent path. Check if a matching macro handler + // is registered with the response object (res.handlers). + handlerObject = reval.res.getMacroHandlers().get(handler); + } + + // the macro handler object couldn't be found + if (handlerObject == null) { + objectFound = false; + } + // else put the found handler object into the cache so we don't have to look again + else if (handlerCache != null) { + handlerCache.put(handler, handlerObject); + } + } + } else { + // this is a global macro with no handler specified + handlerObject = null; + } + + if (objectFound) { + // check if a function called name_macro is defined. + // if so, the macro evaluates to the function. Otherwise, + // a property/field with the name is used, if defined. + String funcName = name + "_macro"; + + if (reval.scriptingEngine.hasFunction(handlerObject, funcName)) { + StringBuffer buffer = reval.res.getBuffer(); + + // remember length of response buffer before calling macro + int bufLength = buffer.length(); + + // remember length of buffer with prefix written out + int preLength = 0; + + if (prefix != null) { + buffer.append(prefix); + preLength = prefix.length(); + } + + // System.err.println ("Getting macro from function"); + // pass a clone of the parameter map so if the script changes it, + // Map param = ; + // if (parameters == null) + // parameters = new HashMap (); + Object[] arguments = { + (parameters == null) ? new HashMap() + : new HashMap(parameters) + }; + + Object value = reval.scriptingEngine.invoke(handlerObject, + funcName, arguments, + false); + + // check if macro wrote out to response buffer + if (buffer.length() == (bufLength + preLength)) { + // function didn't write out anything itself. + // erase previously written prefix + if (preLength > 0) { + buffer.setLength(bufLength); + } + + // write out macro's return value + writeResponse(value, buffer, true); + } else { + if (encoding != ENCODE_NONE) { + // if an encoding is specified, re-encode the macro's output + String output = buffer.substring(bufLength + preLength); + + buffer.setLength(bufLength); + writeResponse(output, buffer, false); + } else { + // no re-encoding needed, just append suffix + if (suffix != null) { + buffer.append(suffix); + } + } + + writeResponse(value, buffer, false); + } + } else { + // System.err.println ("Getting macro from property"); + Object value = reval.scriptingEngine.get(handlerObject, name); + + writeResponse(value, reval.res.getBuffer(), true); + } + } else { + String msg = "[HopMacro unhandled: " + fullName + "]"; + + reval.res.write(" " + msg + " "); + app.logEvent(msg); + } + } catch (RedirectException redir) { + throw redir; + } catch (ConcurrencyException concur) { + throw concur; + } catch (TimeoutException timeout) { + throw timeout; + } catch (Exception x) { + // x.printStackTrace(); + String msg = x.getMessage(); + + if ((msg == null) || (msg.length() < 10)) { + msg = x.toString(); + } + + msg = "[HopMacro error in " + fullName + ": " + msg + "]"; + reval.res.write(" " + msg + " "); + app.logEvent(msg); + } + } + + private void renderFromResponse(RequestEvaluator reval) { + Object value = null; + + if ("message".equals(name)) { + value = reval.res.message; + } else if ("error".equals(name)) { + value = reval.res.error; + } + + if (value == null) { + value = reval.res.get(name); + } + + writeResponse(value, reval.res.getBuffer(), true); + } + + private void renderFromRequest(RequestEvaluator reval) { + if (reval.req == null) { + return; + } + + Object value = reval.req.get(name); + + writeResponse(value, reval.res.getBuffer(), true); + } + + private void renderFromSession(RequestEvaluator reval) { + if (reval.session == null) { + return; + } + + Object value = reval.session.getCacheNode().getString(name); + + writeResponse(value, reval.res.getBuffer(), true); + } + + private void renderFromParam(RequestEvaluator reval, Map paramObject) { + if (paramObject == null) { + reval.res.write("[HopMacro error: Skin requires a parameter object]"); + } else { + Object value = paramObject.get(name); + + writeResponse(value, reval.res.getBuffer(), true); + } + } + + /** + * Utility method for writing text out to the response object. + */ + void writeResponse(Object value, StringBuffer buffer, boolean useDefault) { + String text; + + if (value == null) { + if (useDefault) { + text = defaultValue; + } else { + return; + } + } else { + text = value.toString(); + } + + if ((text != null) && (text.length() > 0)) { + if (prefix != null) { + buffer.append(prefix); + } + + switch (encoding) { + case ENCODE_NONE: + buffer.append(text); + + break; + + case ENCODE_HTML: + HtmlEncoder.encode(text, buffer); + + break; + + case ENCODE_XML: + HtmlEncoder.encodeXml(text, buffer); + + break; + + case ENCODE_FORM: + HtmlEncoder.encodeFormValue(text, buffer); + + break; + + case ENCODE_URL: + buffer.append(URLEncoder.encode(text)); + + break; + + case ENCODE_ALL: + HtmlEncoder.encodeAll(text, buffer); + + break; + } + + if (suffix != null) { + buffer.append(suffix); + } + } + } + + public String toString() { + return "[HopMacro: " + fullName + "]"; + } + + /** + * Return the full name of the macro in handler.name notation + */ + public String getFullName() { + return fullName; + } + } } - - diff --git a/src/helma/framework/core/SkinFile.java b/src/helma/framework/core/SkinFile.java index bd793fc8..8b681df4 100644 --- a/src/helma/framework/core/SkinFile.java +++ b/src/helma/framework/core/SkinFile.java @@ -1,20 +1,29 @@ -// SkinFile.java -// Copyright (c) Hannes Wallnöfer 2001 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.framework.core; -import java.util.*; -import java.io.*; import helma.util.Updatable; - +import java.io.*; +import java.util.*; /** * This represents a File containing a Hop skin */ - - public final class SkinFile implements Updatable { - String name; Prototype prototype; Application app; @@ -22,12 +31,19 @@ public final class SkinFile implements Updatable { Skin skin; long lastmod = 0; - public SkinFile (File file, String name, Prototype proto) { - this.prototype = proto; - this.file = file; - this.name = name; - this.app = proto.app; - skin = null; + /** + * Creates a new SkinFile object. + * + * @param file ... + * @param name ... + * @param proto ... + */ + public SkinFile(File file, String name, Prototype proto) { + this.prototype = proto; + this.file = file; + this.name = name; + this.app = proto.app; + skin = null; } /** @@ -35,88 +51,113 @@ public final class SkinFile implements Updatable { * Skins contained in zipped applications. The whole update mechanism is bypassed * by immediately setting the skin member. */ - public SkinFile (String body, String name, Prototype proto) { - this.prototype = proto; - this.app = proto.app; - this.name = name; - this.file = null; - skin = new Skin (body, app); + public SkinFile(String body, String name, Prototype proto) { + this.prototype = proto; + this.app = proto.app; + this.name = name; + this.file = null; + skin = new Skin(body, app); } /** * Create a skinfile that doesn't belong to a prototype, or at * least it doesn't know about its prototype and isn't managed by the prototype. */ - public SkinFile (File file, String name, Application app) { - this.app = app; - this.file = file; - this.name = name; - this.prototype = null; - skin = null; + public SkinFile(File file, String name, Application app) { + this.app = app; + this.file = file; + this.name = name; + this.prototype = null; + skin = null; } - - /** + /** * Tell the type manager whether we need an update. this is the case when * the file has been modified or deleted. */ - public boolean needsUpdate () { - // if skin object is null we only need to call update if the file doesn't - // exist anymore, while if the skin is initialized, we'll catch both - // cases (file deleted and file changed) by just calling lastModified(). - return skin != null ? lastmod != file.lastModified () : !file.exists (); + public boolean needsUpdate() { + // if skin object is null we only need to call update if the file doesn't + // exist anymore, while if the skin is initialized, we'll catch both + // cases (file deleted and file changed) by just calling lastModified(). + return (skin != null) ? (lastmod != file.lastModified()) : (!file.exists()); } - - public void update () { - if (!file.exists ()) { - // remove skin from prototype - remove (); - } else { - // we only need to update if the skin has already been initialized - if (skin != null) - read (); - } + /** + * + */ + public void update() { + if (!file.exists()) { + // remove skin from prototype + remove(); + } else { + // we only need to update if the skin has already been initialized + if (skin != null) { + read(); + } + } } - private void read () { - try { - FileReader reader = new FileReader (file); - char c[] = new char[(int) file.length()]; - int length = reader.read (c); - reader.close(); - skin = new Skin (c, length, app); - } catch (IOException x) { - app.logEvent ("Error reading Skin "+file+": "+x); - } - lastmod = file.lastModified (); + private void read() { + try { + FileReader reader = new FileReader(file); + char[] c = new char[(int) file.length()]; + int length = reader.read(c); + + reader.close(); + skin = new Skin(c, length, app); + } catch (IOException x) { + app.logEvent("Error reading Skin " + file + ": " + x); + } + + lastmod = file.lastModified(); } - public void remove () { - if (prototype != null) { - prototype.removeSkinFile (this); - } + /** + * + */ + public void remove() { + if (prototype != null) { + prototype.removeSkinFile(this); + } } - - public File getFile () { - return file; + /** + * + * + * @return ... + */ + public File getFile() { + return file; } - public Skin getSkin () { - if (skin == null) - read (); - return skin; + /** + * + * + * @return ... + */ + public Skin getSkin() { + if (skin == null) { + read(); + } + + return skin; } - public String getName () { - return name; + /** + * + * + * @return ... + */ + public String getName() { + return name; } - public String toString () { - return prototype.getName()+"/"+file.getName(); + /** + * + * + * @return ... + */ + public String toString() { + return prototype.getName() + "/" + file.getName(); } - } - - diff --git a/src/helma/framework/core/SkinManager.java b/src/helma/framework/core/SkinManager.java index 2fef823b..b28a4fb2 100644 --- a/src/helma/framework/core/SkinManager.java +++ b/src/helma/framework/core/SkinManager.java @@ -1,107 +1,140 @@ -// SkinManager.java -// Copyright (c) Hannes Wallnöfer 2002 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.framework.core; -import java.util.*; import helma.objectmodel.INode; import java.io.*; - +import java.util.*; /** * Manages skins for a Helma application */ - - public final class SkinManager implements FilenameFilter { - Application app; - public SkinManager (Application app) { - this.app = app; + /** + * Creates a new SkinManager object. + * + * @param app ... + */ + public SkinManager(Application app) { + this.app = app; } + protected Skin getSkin(Prototype proto, String skinname, Object[] skinpath) { + if (proto == null) { + return null; + } - protected Skin getSkin (Prototype proto, String skinname, Object[] skinpath) { - if (proto == null) - return null; - Skin skin = null; - // First check if the skin has been already used within the execution of this request - // check for skinsets set via res.skinpath property - do { - if (skinpath != null) { - for (int i=0; i<skinpath.length; i++) { - skin = getSkinInternal (skinpath[i], proto.getName (), skinname); - if (skin != null) { - return skin; - } - } - } - // skin for this prototype wasn't found in the skinsets. - // the next step is to look if it is defined as skin file in the application directory - skin = proto.getSkin (skinname); - if (skin != null) { - return skin; - } - // still not found. See if there is a parent prototype which might define the skin. - proto = proto.getParentPrototype (); - } while (proto != null); - // looked every where, nothing to be found - return null; + Skin skin = null; + + // First check if the skin has been already used within the execution of this request + // check for skinsets set via res.skinpath property + do { + if (skinpath != null) { + for (int i = 0; i < skinpath.length; i++) { + skin = getSkinInternal(skinpath[i], proto.getName(), skinname); + + if (skin != null) { + return skin; + } + } + } + + // skin for this prototype wasn't found in the skinsets. + // the next step is to look if it is defined as skin file in the application directory + skin = proto.getSkin(skinname); + + if (skin != null) { + return skin; + } + + // still not found. See if there is a parent prototype which might define the skin. + proto = proto.getParentPrototype(); + } while (proto != null); + + // looked every where, nothing to be found + return null; } + protected Skin getSkinInternal(Object skinset, String prototype, String skinname) { + if ((prototype == null) || (skinset == null)) { + return null; + } - protected Skin getSkinInternal (Object skinset, String prototype, String skinname) { - if (prototype == null || skinset == null) - return null; - // check if the skinset object is a HopObject (db based skin) - // or a String (file based skin) - if (skinset instanceof INode) { - INode n = ((INode) skinset).getNode (prototype); - if (n != null) { - n = n.getNode (skinname); - if (n != null) { - String skin = n.getString ("skin"); - if (skin != null) { - return new Skin (skin, app); - } - } - } - } else { - // Skinset is interpreted as directory name from which to - // retrieve the skin - File f = new File (skinset.toString (), prototype); - f = new File (f, skinname+".skin"); - if (f.exists() && f.canRead()) { - SkinFile sf = new SkinFile (f, skinname, app); - return sf.getSkin (); - } - } - // Inheritance is taken care of in the above getSkin method. - // the sequence is prototype.skin-from-db, prototype.skin-from-file, parent.from-db, parent.from-file etc. - return null; + // check if the skinset object is a HopObject (db based skin) + // or a String (file based skin) + if (skinset instanceof INode) { + INode n = ((INode) skinset).getNode(prototype); + + if (n != null) { + n = n.getNode(skinname); + + if (n != null) { + String skin = n.getString("skin"); + + if (skin != null) { + return new Skin(skin, app); + } + } + } + } else { + // Skinset is interpreted as directory name from which to + // retrieve the skin + File f = new File(skinset.toString(), prototype); + + f = new File(f, skinname + ".skin"); + + if (f.exists() && f.canRead()) { + SkinFile sf = new SkinFile(f, skinname, app); + + return sf.getSkin(); + } + } + + // Inheritance is taken care of in the above getSkin method. + // the sequence is prototype.skin-from-db, prototype.skin-from-file, parent.from-db, parent.from-file etc. + return null; } + protected Map getSkinFiles(String skinDir, Prototype proto) { + File dir = new File(skinDir.toString(), proto.getName()); + String[] skinNames = dir.list(this); - protected Map getSkinFiles (String skinDir, Prototype proto) { - File dir = new File (skinDir.toString (), proto.getName ()); - String[] skinNames = dir.list (this); - if (skinNames == null || skinNames.length == 0) - return null; - HashMap map = new HashMap (); - for (int i=0; i<skinNames.length; i++) { - String name = skinNames[i].substring (0, skinNames[i].length()-5); - File file = new File (dir, skinNames[i]); - map.put (name, new SkinFile(file, name, proto)); - } - return map; + if ((skinNames == null) || (skinNames.length == 0)) { + return null; + } + + HashMap map = new HashMap(); + + for (int i = 0; i < skinNames.length; i++) { + String name = skinNames[i].substring(0, skinNames[i].length() - 5); + File file = new File(dir, skinNames[i]); + + map.put(name, new SkinFile(file, name, proto)); + } + + return map; } - /** + /** * Implements java.io.FilenameFilter.accept() */ - public boolean accept (File d, String n) { - return n.endsWith (".skin"); + public boolean accept(File d, String n) { + return n.endsWith(".skin"); } - } diff --git a/src/helma/framework/core/TypeManager.java b/src/helma/framework/core/TypeManager.java index cb7e3ddd..9f84c062 100644 --- a/src/helma/framework/core/TypeManager.java +++ b/src/helma/framework/core/TypeManager.java @@ -1,230 +1,300 @@ -// TypeManager.java -// Copyright (c) Hannes Wallnöfer 1998-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.framework.core; import helma.objectmodel.*; import helma.objectmodel.db.DbMapping; import helma.scripting.*; import helma.util.*; -import java.util.*; import java.io.*; +import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; -import java.net.MalformedURLException; +import java.util.*; /** - * The type manager periodically checks the prototype definitions for its + * The type manager periodically checks the prototype definitions for its * applications and updates the evaluators if anything has changed. */ - public final class TypeManager { - + final static String[] standardTypes = { "user", "global", "root", "hopobject" }; + final static String templateExtension = ".hsp"; + final static String scriptExtension = ".js"; + final static String actionExtension = ".hac"; + final static String skinExtension = ".skin"; Application app; File appDir; - HashMap prototypes; // map of prototypes - HashMap zipfiles; // map of zipped script files - HashSet jarfiles; // set of Java archives + HashMap prototypes; // map of prototypes + HashMap zipfiles; // map of zipped script files + HashSet jarfiles; // set of Java archives long lastCheck = 0; long appDirMod = 0; + // a checksum that changes whenever something in the application files changes. long checksum; // the hopobject prototype Prototype hopobjectProto; + // the global prototype Prototype globalProto; // app specific class loader, includes jar files in the app directory AppClassLoader loader; - - final static String[] standardTypes = {"user", "global", "root", "hopobject"}; - final static String templateExtension = ".hsp"; - final static String scriptExtension = ".js"; - final static String actionExtension = ".hac"; - final static String skinExtension = ".skin"; - - public TypeManager (Application app) throws MalformedURLException { + /** + * Creates a new TypeManager object. + * + * @param app ... + * + * @throws MalformedURLException ... + * @throws RuntimeException ... + */ + public TypeManager(Application app) throws MalformedURLException { this.app = app; appDir = app.appDir; + // make sure the directories for the standard prototypes exist, and lament otherwise if (appDir.list().length == 0) { - for (int i=0; i<standardTypes.length; i++) { - File f = new File (appDir, standardTypes[i]); - if (!f.exists() && !f.mkdir ()) - app.logEvent ("Warning: directory "+f.getAbsolutePath ()+" could not be created."); - else if (!f.isDirectory ()) - app.logEvent ("Warning: "+f.getAbsolutePath ()+" is not a directory."); + for (int i = 0; i < standardTypes.length; i++) { + File f = new File(appDir, standardTypes[i]); + + if (!f.exists() && !f.mkdir()) { + app.logEvent("Warning: directory " + f.getAbsolutePath() + + " could not be created."); + } else if (!f.isDirectory()) { + app.logEvent("Warning: " + f.getAbsolutePath() + + " is not a directory."); + } } } - prototypes = new HashMap (); - zipfiles = new HashMap (); - jarfiles = new HashSet (); + + prototypes = new HashMap(); + zipfiles = new HashMap(); + jarfiles = new HashSet(); + URL[] urls = ((URLClassLoader) TypeManager.class.getClassLoader()).getURLs(); URL helmajar = null; - for (int i=0; i<urls.length; i++) { + + for (int i = 0; i < urls.length; i++) { String url = urls[i].toString().toLowerCase(); - if (url.endsWith ("helma.jar")) { + + if (url.endsWith("helma.jar")) { helmajar = urls[i]; + break; } } - if (helmajar == null) - throw new RuntimeException ("helma.jar not found in embedding classpath"); + + if (helmajar == null) { + throw new RuntimeException("helma.jar not found in embedding classpath"); + } + loader = new AppClassLoader(app.getName(), new URL[] { helmajar }); } - /** * Run through application's prototype directories and create prototypes, but don't * compile or evaluate any scripts. */ - public void createPrototypes () { + public void createPrototypes() { // create standard prototypes. - createPrototype ("root"); - createPrototype ("user"); + createPrototype("root"); + createPrototype("user"); + // get references to hopobject and global protos, // since we need it regularly when setting parent prototypes. - hopobjectProto = createPrototype ("hopobject"); - globalProto = createPrototype ("global"); - // loop through directories and create prototypes - checkFiles (); - } + hopobjectProto = createPrototype("hopobject"); + globalProto = createPrototype("global"); + // loop through directories and create prototypes + checkFiles(); + } /** * Run through application's prototype directories and check if anything has been updated. * If so, update prototypes and scripts. */ - public synchronized void checkPrototypes () { - if (System.currentTimeMillis () - lastCheck < 1000l) - return; - try { - checkFiles (); - } catch (Exception ignore) {} - lastCheck = System.currentTimeMillis (); + public synchronized void checkPrototypes() { + if ((System.currentTimeMillis() - lastCheck) < 1000L) { + return; + } + + try { + checkFiles(); + } catch (Exception ignore) { + } + + lastCheck = System.currentTimeMillis(); } /** * Run through application's prototype directories and check if * there are any prototypes to be created. */ - public void checkFiles () { - // check if any files have been created/removed since last time we - // checked... - if (appDir.lastModified() > appDirMod) { - appDirMod = appDir.lastModified (); - String[] list = appDir.list (); - if (list == null) - throw new RuntimeException ("Can't read app directory "+appDir+" - check permissions"); - for (int i=0; i<list.length; i++) { - if (list[i].endsWith (".zip")) { - ZippedAppFile zipped = (ZippedAppFile) zipfiles.get (list[i]); - if (zipped == null) { - File f = new File (appDir, list[i]); - if (!f.isDirectory ()) { - zipped = new ZippedAppFile (f, app); - zipfiles.put (list[i], zipped); - } - } - continue; - } - if (list[i].endsWith (".jar")) { - if (!jarfiles.contains (list[i])) { - jarfiles.add (list[i]); - File f = new File (appDir, list[i]); - try { - loader.addURL (new URL ("file:"+f.getAbsolutePath())); - } catch (MalformedURLException ignore) {} - } - continue; - } - if (list[i].indexOf ('.') > -1) - continue; - Prototype proto = getPrototype (list[i]); - // if prototype doesn't exist, create it - if (proto == null && isValidTypeName (list[i])) { - File f = new File (appDir, list[i]); - if (f.isDirectory ()) { - // create new prototype - createPrototype (list[i], f); - } - } - } - } + public void checkFiles() { + // check if any files have been created/removed since last time we + // checked... + if (appDir.lastModified() > appDirMod) { + appDirMod = appDir.lastModified(); - // calculate this app's checksum by adding all checksums from all prototypes - long newChecksum = 0; + String[] list = appDir.list(); - // loop through zip files to check for updates - for (Iterator it=zipfiles.values ().iterator (); it.hasNext (); ) { - ZippedAppFile zipped = (ZippedAppFile) it.next (); - if (zipped.needsUpdate ()) { - zipped.update (); - } - newChecksum += zipped.lastmod; - } + if (list == null) { + throw new RuntimeException("Can't read app directory " + appDir + + " - check permissions"); + } - // loop through prototypes and check if type.properties needs updates - // it's important that we do this _after_ potentially new prototypes - // have been created in the previous loop. - for (Iterator i=prototypes.values().iterator(); i.hasNext(); ) { - Prototype proto = (Prototype) i.next (); - // calculate this app's type checksum - newChecksum += proto.getChecksum(); - // update prototype's type mapping - DbMapping dbmap = proto.getDbMapping (); - if (dbmap != null && dbmap.needsUpdate ()) { - dbmap.update (); - if (proto != hopobjectProto && proto != globalProto) { - // set parent prototype, in case it has changed. - String parentName = dbmap.getExtends (); - if (parentName != null) - proto.setParentPrototype (getPrototype (parentName)); - else if (!app.isJavaPrototype (proto.getName())) - proto.setParentPrototype (hopobjectProto); - } - } - } - checksum = newChecksum; + for (int i = 0; i < list.length; i++) { + if (list[i].endsWith(".zip")) { + ZippedAppFile zipped = (ZippedAppFile) zipfiles.get(list[i]); + + if (zipped == null) { + File f = new File(appDir, list[i]); + + if (!f.isDirectory()) { + zipped = new ZippedAppFile(f, app); + zipfiles.put(list[i], zipped); + } + } + + continue; + } + + if (list[i].endsWith(".jar")) { + if (!jarfiles.contains(list[i])) { + jarfiles.add(list[i]); + + File f = new File(appDir, list[i]); + + try { + loader.addURL(new URL("file:" + f.getAbsolutePath())); + } catch (MalformedURLException ignore) { + } + } + + continue; + } + + if (list[i].indexOf('.') > -1) { + continue; + } + + Prototype proto = getPrototype(list[i]); + + // if prototype doesn't exist, create it + if ((proto == null) && isValidTypeName(list[i])) { + File f = new File(appDir, list[i]); + + if (f.isDirectory()) { + // create new prototype + createPrototype(list[i], f); + } + } + } + } + + // calculate this app's checksum by adding all checksums from all prototypes + long newChecksum = 0; + + // loop through zip files to check for updates + for (Iterator it = zipfiles.values().iterator(); it.hasNext();) { + ZippedAppFile zipped = (ZippedAppFile) it.next(); + + if (zipped.needsUpdate()) { + zipped.update(); + } + + newChecksum += zipped.lastmod; + } + + // loop through prototypes and check if type.properties needs updates + // it's important that we do this _after_ potentially new prototypes + // have been created in the previous loop. + for (Iterator i = prototypes.values().iterator(); i.hasNext();) { + Prototype proto = (Prototype) i.next(); + + // calculate this app's type checksum + newChecksum += proto.getChecksum(); + + // update prototype's type mapping + DbMapping dbmap = proto.getDbMapping(); + + if ((dbmap != null) && dbmap.needsUpdate()) { + dbmap.update(); + + if ((proto != hopobjectProto) && (proto != globalProto)) { + // set parent prototype, in case it has changed. + String parentName = dbmap.getExtends(); + + if (parentName != null) { + proto.setParentPrototype(getPrototype(parentName)); + } else if (!app.isJavaPrototype(proto.getName())) { + proto.setParentPrototype(hopobjectProto); + } + } + } + } + + checksum = newChecksum; } - protected void removeZipFile (String zipname) { - zipfiles.remove (zipname); - for (Iterator i=prototypes.values().iterator(); i.hasNext(); ) { - Prototype proto = (Prototype) i.next (); - // update prototype's type mapping - DbMapping dbmap = proto.getDbMapping (); - SystemProperties props = dbmap.getProperties(); - props.removeProps (zipname); - } + protected void removeZipFile(String zipname) { + zipfiles.remove(zipname); + + for (Iterator i = prototypes.values().iterator(); i.hasNext();) { + Prototype proto = (Prototype) i.next(); + + // update prototype's type mapping + DbMapping dbmap = proto.getDbMapping(); + SystemProperties props = dbmap.getProperties(); + + props.removeProps(zipname); + } } + private boolean isValidTypeName(String str) { + if (str == null) { + return false; + } - private boolean isValidTypeName (String str) { - if (str == null) - return false; - char[] c = str.toCharArray (); - for (int i=0; i<c.length; i++) - if (!Character.isJavaIdentifierPart (c[i])) - return false; - return true; - } + char[] c = str.toCharArray(); - /** - * Return a checksum over all files in all prototypes in this application. - * The checksum can be used to find out quickly if any file has changed. - */ - public long getChecksum () { - return checksum; + for (int i = 0; i < c.length; i++) + if (!Character.isJavaIdentifierPart(c[i])) { + return false; + } + + return true; } /** - * Get a prototype defined for this application - */ - public Prototype getPrototype (String typename) { - return (Prototype) prototypes.get (typename); + * Return a checksum over all files in all prototypes in this application. + * The checksum can be used to find out quickly if any file has changed. + */ + public long getChecksum() { + return checksum; + } + + /** + * Get a prototype defined for this application + */ + public Prototype getPrototype(String typename) { + return (Prototype) prototypes.get(typename); } /** @@ -232,152 +302,167 @@ public final class TypeManager { * that it doesn't create a DbMapping - this is left to the * caller (e.g. ZippedAppFile). */ - public Prototype createPrototype (String typename) { - return createPrototype (typename, new File (appDir, typename)); + public Prototype createPrototype(String typename) { + return createPrototype(typename, new File(appDir, typename)); } - /** * Create a prototype from a directory containing scripts and other stuff */ - public Prototype createPrototype (String typename, File dir) { - Prototype proto = new Prototype (typename, dir, app); - // Create and register type properties file - File propfile = new File (dir, "type.properties"); - SystemProperties props = new SystemProperties (propfile.getAbsolutePath ()); - DbMapping dbmap = new DbMapping (app, typename, props); - // we don't need to put the DbMapping into proto.updatables, because - // dbmappings are checked separately in checkFiles for each request - // proto.updatables.put ("type.properties", dbmap); - proto.setDbMapping (dbmap); - // put the prototype into our map - prototypes.put (typename, proto); - return proto; + public Prototype createPrototype(String typename, File dir) { + Prototype proto = new Prototype(typename, dir, app); + + // Create and register type properties file + File propfile = new File(dir, "type.properties"); + SystemProperties props = new SystemProperties(propfile.getAbsolutePath()); + DbMapping dbmap = new DbMapping(app, typename, props); + + // we don't need to put the DbMapping into proto.updatables, because + // dbmappings are checked separately in checkFiles for each request + // proto.updatables.put ("type.properties", dbmap); + proto.setDbMapping(dbmap); + + // put the prototype into our map + prototypes.put(typename, proto); + + return proto; } - /** - * Update a prototype to the files in the prototype directory. - */ - public void updatePrototype (String name) { + * Update a prototype to the files in the prototype directory. + */ + public void updatePrototype(String name) { // System.err.println ("UPDATE PROTO: "+app.getName()+"/"+name); - Prototype proto = getPrototype (name); - updatePrototype (proto); + Prototype proto = getPrototype(name); + + updatePrototype(proto); } /** - * Update a prototype to the files in the prototype directory. - */ - public void updatePrototype (Prototype proto) { - if (proto == null || proto.isUpToDate()) + * Update a prototype to the files in the prototype directory. + */ + public void updatePrototype(Prototype proto) { + if ((proto == null) || proto.isUpToDate()) { return; + } synchronized (proto) { // check again because another thread may have checked the // prototype while we were waiting for access to the synchronized section - /* if (System.currentTimeMillis() - proto.getLastCheck() < 1000) - return; */ - File dir = proto.getDirectory (); + /* if (System.currentTimeMillis() - proto.getLastCheck() < 1000) + return; */ + File dir = proto.getDirectory(); HashSet updateSet = null; HashSet createSet = null; // our plan is to do as little as possible, so first check if // anything the prototype knows about has changed on disk - for (Iterator i = proto.updatables.values().iterator(); i.hasNext(); ) { + for (Iterator i = proto.updatables.values().iterator(); i.hasNext();) { Updatable upd = (Updatable) i.next(); - if (upd.needsUpdate ()) { - if (updateSet == null) - updateSet = new HashSet (); - updateSet.add (upd); + + if (upd.needsUpdate()) { + if (updateSet == null) { + updateSet = new HashSet(); + } + + updateSet.add(upd); } } // next we check if files have been created or removed since last update // if (proto.getLastCheck() < dir.lastModified ()) { - File[] list = proto.getFiles(); - for (int i=0; i<list.length; i++) { - String fn = list[i].getName(); - if (!proto.updatables.containsKey (fn)) { - if (fn.endsWith (templateExtension) || - fn.endsWith (scriptExtension) || - fn.endsWith (actionExtension) || - fn.endsWith (skinExtension) || - "type.properties".equalsIgnoreCase (fn)) - { - if (createSet == null) - createSet = new HashSet (); - createSet.add (list[i]); + File[] list = proto.getFiles(); + + for (int i = 0; i < list.length; i++) { + String fn = list[i].getName(); + + if (!proto.updatables.containsKey(fn)) { + if (fn.endsWith(templateExtension) || fn.endsWith(scriptExtension) || + fn.endsWith(actionExtension) || fn.endsWith(skinExtension) || + "type.properties".equalsIgnoreCase(fn)) { + if (createSet == null) { + createSet = new HashSet(); } + + createSet.add(list[i]); } } - // } + } + // } // if nothing needs to be updated, mark prototype as checked and return - if (updateSet == null && createSet == null) { - proto.markChecked (); + if ((updateSet == null) && (createSet == null)) { + proto.markChecked(); + return; } // first go through new files and create new items if (createSet != null) { - Object[] newFiles = createSet.toArray (); - for (int i=0; i<newFiles.length; i++) { + Object[] newFiles = createSet.toArray(); + + for (int i = 0; i < newFiles.length; i++) { File file = (File) newFiles[i]; - String filename = file.getName (); - int dot = filename.lastIndexOf ("."); + String filename = file.getName(); + int dot = filename.lastIndexOf("."); String tmpname = filename.substring(0, dot); - if (filename.endsWith (templateExtension)) { + if (filename.endsWith(templateExtension)) { try { - Template t = new Template (file, tmpname, proto); - proto.addTemplate (t); + Template t = new Template(file, tmpname, proto); + + proto.addTemplate(t); } catch (Throwable x) { - app.logEvent ("Error updating prototype: "+x); + app.logEvent("Error updating prototype: " + x); } - } else if (filename.endsWith (scriptExtension)) { + } else if (filename.endsWith(scriptExtension)) { try { - FunctionFile ff = new FunctionFile (file, proto); - proto.addFunctionFile (ff); + FunctionFile ff = new FunctionFile(file, proto); + + proto.addFunctionFile(ff); } catch (Throwable x) { - app.logEvent ("Error updating prototype: "+x); + app.logEvent("Error updating prototype: " + x); } - } else if (filename.endsWith (actionExtension)) { + } else if (filename.endsWith(actionExtension)) { try { - ActionFile af = new ActionFile (file, tmpname, proto); - proto.addActionFile (af); + ActionFile af = new ActionFile(file, tmpname, proto); + + proto.addActionFile(af); } catch (Throwable x) { - app.logEvent ("Error updating prototype: "+x); + app.logEvent("Error updating prototype: " + x); } - } else if (filename.endsWith (skinExtension)) { - SkinFile sf = new SkinFile (file, tmpname, proto); - proto.addSkinFile (sf); + } else if (filename.endsWith(skinExtension)) { + SkinFile sf = new SkinFile(file, tmpname, proto); + + proto.addSkinFile(sf); } } } // next go through existing updatables if (updateSet != null) { - for (Iterator i = updateSet.iterator(); i.hasNext(); ) { + for (Iterator i = updateSet.iterator(); i.hasNext();) { Updatable upd = (Updatable) i.next(); + try { - upd.update (); + upd.update(); } catch (Exception x) { - if (upd instanceof DbMapping) - app.logEvent ("Error updating db mapping for type "+proto.getName()+": "+x); - else - app.logEvent ("Error updating "+upd+" of prototye type "+proto.getName()+": "+x); + if (upd instanceof DbMapping) { + app.logEvent("Error updating db mapping for type " + + proto.getName() + ": " + x); + } else { + app.logEvent("Error updating " + upd + " of prototye type " + + proto.getName() + ": " + x); + } } } } // mark prototype as checked and updated. - proto.markChecked (); + proto.markChecked(); proto.markUpdated(); - - } // end of synchronized (proto) - + } + // end of synchronized (proto) } - } - diff --git a/src/helma/framework/core/ZippedAppFile.java b/src/helma/framework/core/ZippedAppFile.java index 494c126e..85d18374 100644 --- a/src/helma/framework/core/ZippedAppFile.java +++ b/src/helma/framework/core/ZippedAppFile.java @@ -1,160 +1,208 @@ -// ZippedFile.java -// Copyright (c) Hannes Wallnöfer 2001 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.framework.core; +import helma.framework.*; +import helma.objectmodel.db.DbMapping; +import helma.scripting.*; +import helma.util.SystemProperties; +import helma.util.Updatable; +import java.io.*; import java.util.*; import java.util.zip.*; -import java.io.*; -import helma.framework.*; -import helma.scripting.*; -import helma.util.Updatable; -import helma.util.SystemProperties; -import helma.objectmodel.db.DbMapping; /** * This represents a Zip-File which may contain other Updatables for one or more prototypes. */ - - public class ZippedAppFile implements Updatable { - Application app; File file; long lastmod; Set updatables; + /** + * Creates a new ZippedAppFile object. + * + * @param file ... + * @param app ... + */ + public ZippedAppFile(File file, Application app) { + this.app = app; + this.file = file; - public ZippedAppFile (File file, Application app) { - this.app = app; - this.file = file; - // System.err.println ("CREATING ZIP FILE "+this); + // System.err.println ("CREATING ZIP FILE "+this); } - /** * Tell the type manager whether we need an update. this is the case when * the file has been modified or deleted. */ - public boolean needsUpdate () { - return !file.exists () || lastmod != file.lastModified (); + public boolean needsUpdate() { + return !file.exists() || (lastmod != file.lastModified()); } + /** + * + */ + public void update() { + if (!file.exists()) { + remove(); + } else { + ZipFile zip = null; - public void update () { + // collect created protos - we need this to check DbMappings for each created + // prototype afterwards + HashSet newPrototypes = new HashSet(); - if (!file.exists ()) { - remove (); + try { + lastmod = file.lastModified(); - } else { + // System.err.println ("UPDATING ZIP FILE "+this); + zip = new ZipFile(file); + updatables = new HashSet(); - ZipFile zip = null; - // collect created protos - we need this to check DbMappings for each created - // prototype afterwards - HashSet newPrototypes = new HashSet (); - try { - lastmod = file.lastModified (); - // System.err.println ("UPDATING ZIP FILE "+this); - zip = new ZipFile (file); - updatables = new HashSet (); - for (Enumeration en = zip.entries (); en.hasMoreElements (); ) { - ZipEntry entry = (ZipEntry) en.nextElement (); - String ename = entry.getName (); - StringTokenizer st = new StringTokenizer (ename, "/"); - if (st.countTokens () == 2) { - String dir = st.nextToken (); - String fname = st.nextToken (); - // System.err.println ("ZIPENTRY: "+ dir +" ~ "+fname); - Prototype proto = app.typemgr.getPrototype (dir); - if (proto == null) { - proto = app.typemgr.createPrototype (dir); - newPrototypes.add (proto); - } - if (fname.endsWith (".hac")) { - String name = fname.substring (0, fname.lastIndexOf (".")); - String sourceName = file.getName()+"/"+ename; - String content = getZipEntryContent (zip, entry); - // System.err.println ("["+content+"]"); - ActionFile act = new ActionFile (content, name, sourceName, proto); - proto.addActionFile (act); - updatables.add (act); - // mark prototype as updated - proto.markUpdated (); - } - else if (fname.endsWith (".hsp")) { - String name = fname.substring (0, fname.lastIndexOf (".")); - String sourceName = file.getName()+"/"+ename; - String content = getZipEntryContent (zip, entry); - // System.err.println ("["+content+"]"); - Template tmp = new Template (content, name, sourceName, proto); - proto.addTemplate (tmp); - updatables.add (tmp); - // mark prototype as updated - proto.markUpdated (); - } - else if (fname.endsWith (".skin")) { - String name = fname.substring (0, fname.lastIndexOf (".")); - String content = getZipEntryContent (zip, entry); - // System.err.println ("["+content+"]"); - SkinFile skin = new SkinFile (content, name, proto); - proto.addSkinFile (skin); - updatables.add (skin); - } - else if (fname.endsWith (".js")) { - String sourceName = file.getName()+"/"+ename; - String content = getZipEntryContent (zip, entry); - // System.err.println ("["+content+"]"); - FunctionFile ff = new FunctionFile (content, sourceName, proto); - proto.addFunctionFile (ff); - updatables.add (ff); - // mark prototype as updated - proto.markUpdated (); - } - else if ("type.properties".equalsIgnoreCase (fname)) { - DbMapping dbmap = proto.getDbMapping (); - SystemProperties props = dbmap.getProperties (); - props.addProps (file.getName(), zip.getInputStream (entry)); - // mark prototype as updated - proto.markUpdated (); - } - } - } - } catch (Throwable x) { - System.err.println ("Error updating ZipFile: "+x); - } finally { - try { - zip.close (); - } catch (Exception ignore) {} - } - } + for (Enumeration en = zip.entries(); en.hasMoreElements();) { + ZipEntry entry = (ZipEntry) en.nextElement(); + String ename = entry.getName(); + StringTokenizer st = new StringTokenizer(ename, "/"); + if (st.countTokens() == 2) { + String dir = st.nextToken(); + String fname = st.nextToken(); + + // System.err.println ("ZIPENTRY: "+ dir +" ~ "+fname); + Prototype proto = app.typemgr.getPrototype(dir); + + if (proto == null) { + proto = app.typemgr.createPrototype(dir); + newPrototypes.add(proto); + } + + if (fname.endsWith(".hac")) { + String name = fname.substring(0, fname.lastIndexOf(".")); + String sourceName = file.getName() + "/" + ename; + String content = getZipEntryContent(zip, entry); + + // System.err.println ("["+content+"]"); + ActionFile act = new ActionFile(content, name, sourceName, + proto); + + proto.addActionFile(act); + updatables.add(act); + + // mark prototype as updated + proto.markUpdated(); + } else if (fname.endsWith(".hsp")) { + String name = fname.substring(0, fname.lastIndexOf(".")); + String sourceName = file.getName() + "/" + ename; + String content = getZipEntryContent(zip, entry); + + // System.err.println ("["+content+"]"); + Template tmp = new Template(content, name, sourceName, proto); + + proto.addTemplate(tmp); + updatables.add(tmp); + + // mark prototype as updated + proto.markUpdated(); + } else if (fname.endsWith(".skin")) { + String name = fname.substring(0, fname.lastIndexOf(".")); + String content = getZipEntryContent(zip, entry); + + // System.err.println ("["+content+"]"); + SkinFile skin = new SkinFile(content, name, proto); + + proto.addSkinFile(skin); + updatables.add(skin); + } else if (fname.endsWith(".js")) { + String sourceName = file.getName() + "/" + ename; + String content = getZipEntryContent(zip, entry); + + // System.err.println ("["+content+"]"); + FunctionFile ff = new FunctionFile(content, sourceName, proto); + + proto.addFunctionFile(ff); + updatables.add(ff); + + // mark prototype as updated + proto.markUpdated(); + } else if ("type.properties".equalsIgnoreCase(fname)) { + DbMapping dbmap = proto.getDbMapping(); + SystemProperties props = dbmap.getProperties(); + + props.addProps(file.getName(), zip.getInputStream(entry)); + + // mark prototype as updated + proto.markUpdated(); + } + } + } + } catch (Throwable x) { + System.err.println("Error updating ZipFile: " + x); + } finally { + try { + zip.close(); + } catch (Exception ignore) { + } + } + } } - public void remove () { - if (updatables != null) { - for (Iterator it = updatables.iterator(); it.hasNext(); ) - ((Updatable) it.next()).remove (); - } - app.typemgr.removeZipFile (file.getName()); - // System.err.println ("REMOVING ZIP FILE "+this); + /** + * + */ + public void remove() { + if (updatables != null) { + for (Iterator it = updatables.iterator(); it.hasNext();) + ((Updatable) it.next()).remove(); + } + + app.typemgr.removeZipFile(file.getName()); + + // System.err.println ("REMOVING ZIP FILE "+this); } + /** + * + * + * @param zip ... + * @param entry ... + * + * @return ... + * + * @throws IOException ... + */ + public String getZipEntryContent(ZipFile zip, ZipEntry entry) + throws IOException { + int size = (int) entry.getSize(); + char[] c = new char[size]; + InputStreamReader reader = new InputStreamReader(zip.getInputStream(entry)); - public String getZipEntryContent (ZipFile zip, ZipEntry entry) throws IOException { - int size = (int) entry.getSize (); - char[] c = new char[size]; - InputStreamReader reader = new InputStreamReader (zip.getInputStream (entry)); - reader.read (c); - return new String (c); + reader.read(c); + + return new String(c); } - - public String toString () { - return file.getName(); + /** + * + * + * @return ... + */ + public String toString() { + return file.getName(); } - - } - - - diff --git a/src/helma/image/ImageGenerator.java b/src/helma/image/ImageGenerator.java index 3602c822..148c2e51 100644 --- a/src/helma/image/ImageGenerator.java +++ b/src/helma/image/ImageGenerator.java @@ -1,198 +1,295 @@ -// ImageGenerator.java -// Copyright (c) Hannes Wallnöfer 1999-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.image; import java.awt.*; import java.awt.image.*; -import java.net.URL; import java.net.MalformedURLException; +import java.net.URL; /** * Factory class for generating Image objects from various sources. * */ - public class ImageGenerator { - - public ImageGenerator () { - // nothing to do + /** + * Creates a new ImageGenerator object. + */ + public ImageGenerator() { + // nothing to do } - public ImageWrapper createPaintableImage (int w, int h) { - BufferedImage img = new BufferedImage (w, h, BufferedImage.TYPE_INT_RGB); - Graphics g = img.getGraphics (); - ImageWrapper rimg = new SunImageWrapper (img, g, w, h, this); - return rimg; + /** + * + * + * @param w ... + * @param h ... + * + * @return ... + */ + public ImageWrapper createPaintableImage(int w, int h) { + BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); + Graphics g = img.getGraphics(); + ImageWrapper rimg = new SunImageWrapper(img, g, w, h, this); + + return rimg; } - public ImageWrapper createPaintableImage (byte src[]) { - ImageWrapper rimg = null; - Image img1 = Toolkit.getDefaultToolkit ().createImage (src); - ImageLoader loader = new ImageLoader (img1); - try { - loader.getDimensions (); - int w = loader.getWidth (); - int h = loader.getHeight (); - Image img = new BufferedImage (w, h, BufferedImage.TYPE_INT_RGB); - Graphics g = img.getGraphics (); - g.drawImage (img1, 0, 0, null); - rimg = new SunImageWrapper (img, g, w, h, this); - } finally { - loader.done(); - } - return rimg; - } + /** + * + * + * @param src ... + * + * @return ... + */ + public ImageWrapper createPaintableImage(byte[] src) { + ImageWrapper rimg = null; + Image img1 = Toolkit.getDefaultToolkit().createImage(src); + ImageLoader loader = new ImageLoader(img1); - public ImageWrapper createImage (byte src[]) { - ImageWrapper rimg = null; - Image img = Toolkit.getDefaultToolkit ().createImage (src); - ImageLoader loader = new ImageLoader (img); - try { - loader.getDimensions (); - int w = loader.getWidth (); - int h = loader.getHeight (); - rimg = new SunImageWrapper (img, null, w, h, this); - } finally { - loader.done(); - } - return rimg; - } + try { + loader.getDimensions(); + int w = loader.getWidth(); + int h = loader.getHeight(); + Image img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); + Graphics g = img.getGraphics(); - public ImageWrapper createPaintableImage (String urlstring) throws MalformedURLException { - ImageWrapper rimg = null; - URL url = new URL (urlstring); - Image img1 = Toolkit.getDefaultToolkit ().createImage (url); - ImageLoader loader = new ImageLoader (img1); - try { - loader.getDimensions (); - int w = loader.getWidth (); - int h = loader.getHeight (); - Image img = new BufferedImage (w, h, BufferedImage.TYPE_INT_RGB); - Graphics g = img.getGraphics (); - g.drawImage (img1, 0, 0, null); - rimg = new SunImageWrapper (img, g, w, h, this); - } finally { + g.drawImage(img1, 0, 0, null); + rimg = new SunImageWrapper(img, g, w, h, this); + } finally { loader.done(); } - return rimg; + + return rimg; } - public ImageWrapper createPaintableImage (ImageWrapper iw, ImageFilter filter) { - ImageWrapper rimg = null; - FilteredImageSource fis = new FilteredImageSource (iw.getSource(), filter); - Image img1 = Toolkit.getDefaultToolkit().createImage (fis); - ImageLoader loader = new ImageLoader (img1); - try { - loader.getDimensions (); - int w = loader.getWidth (); - int h = loader.getHeight (); - Image img = new BufferedImage (w, h, BufferedImage.TYPE_INT_RGB); - Graphics g = img.getGraphics (); - g.drawImage (img1, 0, 0, null); - rimg = new SunImageWrapper (img, g, w, h, this); - } finally { + /** + * + * + * @param src ... + * + * @return ... + */ + public ImageWrapper createImage(byte[] src) { + ImageWrapper rimg = null; + Image img = Toolkit.getDefaultToolkit().createImage(src); + ImageLoader loader = new ImageLoader(img); + + try { + loader.getDimensions(); + + int w = loader.getWidth(); + int h = loader.getHeight(); + + rimg = new SunImageWrapper(img, null, w, h, this); + } finally { loader.done(); } - return rimg; + + return rimg; } + /** + * + * + * @param urlstring ... + * + * @return ... + * + * @throws MalformedURLException ... + */ + public ImageWrapper createPaintableImage(String urlstring) + throws MalformedURLException { + ImageWrapper rimg = null; + URL url = new URL(urlstring); + Image img1 = Toolkit.getDefaultToolkit().createImage(url); + ImageLoader loader = new ImageLoader(img1); - public Image createImage (String filename) { - Image img = null; - img = Toolkit.getDefaultToolkit ().createImage (filename); - ImageLoader loader = new ImageLoader (img); - loader.getDimensions (); - loader.done(); - return img; + try { + loader.getDimensions(); + + int w = loader.getWidth(); + int h = loader.getHeight(); + Image img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); + Graphics g = img.getGraphics(); + + g.drawImage(img1, 0, 0, null); + rimg = new SunImageWrapper(img, g, w, h, this); + } finally { + loader.done(); + } + + return rimg; } - public Image createImage (ImageProducer producer) { - Image img = null; - img = Toolkit.getDefaultToolkit ().createImage (producer); - ImageLoader loader = new ImageLoader (img); - loader.getDimensions (); - loader.done(); - return img; + /** + * + * + * @param iw ... + * @param filter ... + * + * @return ... + */ + public ImageWrapper createPaintableImage(ImageWrapper iw, ImageFilter filter) { + ImageWrapper rimg = null; + FilteredImageSource fis = new FilteredImageSource(iw.getSource(), filter); + Image img1 = Toolkit.getDefaultToolkit().createImage(fis); + ImageLoader loader = new ImageLoader(img1); + + try { + loader.getDimensions(); + + int w = loader.getWidth(); + int h = loader.getHeight(); + Image img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); + Graphics g = img.getGraphics(); + + g.drawImage(img1, 0, 0, null); + rimg = new SunImageWrapper(img, g, w, h, this); + } finally { + loader.done(); + } + + return rimg; + } + + /** + * + * + * @param filename ... + * + * @return ... + */ + public Image createImage(String filename) { + Image img = null; + + img = Toolkit.getDefaultToolkit().createImage(filename); + + ImageLoader loader = new ImageLoader(img); + + loader.getDimensions(); + loader.done(); + + return img; + } + + /** + * + * + * @param producer ... + * + * @return ... + */ + public Image createImage(ImageProducer producer) { + Image img = null; + + img = Toolkit.getDefaultToolkit().createImage(producer); + + ImageLoader loader = new ImageLoader(img); + + loader.getDimensions(); + loader.done(); + + return img; } class ImageLoader implements ImageObserver { + Image img; + int w; + int h; + boolean waiting; + boolean firstFrameLoaded; - Image img; - int w, h; - boolean waiting; - boolean firstFrameLoaded; + ImageLoader(Image img) { + this.img = img; + waiting = true; + firstFrameLoaded = false; + } - ImageLoader (Image img) { - this.img = img; - waiting = true; - firstFrameLoaded = false; - } + synchronized void getDimensions() { + w = img.getWidth(this); + h = img.getHeight(this); - synchronized void getDimensions () { - w = img.getWidth(this); - h = img.getHeight (this); - if (w == -1 || h == -1) { - try { - wait (45000); - } catch (InterruptedException x) { - waiting = false; - return; - } finally { - waiting = false; - } - } - // if width and height haven't been set, throw tantrum - if (w == -1 || h == -1) { - throw new RuntimeException ("Error loading image"); - } - } + if ((w == -1) || (h == -1)) { + try { + wait(45000); + } catch (InterruptedException x) { + waiting = false; - synchronized void done () { - waiting = false; - notifyAll (); - } + return; + } finally { + waiting = false; + } + } - int getWidth () { - return w; - } + // if width and height haven't been set, throw tantrum + if ((w == -1) || (h == -1)) { + throw new RuntimeException("Error loading image"); + } + } - int getHeight () { - return h; - } + synchronized void done() { + waiting = false; + notifyAll(); + } - public synchronized boolean imageUpdate(Image img, - int infoflags, - int x, - int y, - int width, - int height) { - // check if there was an error - if (!waiting || (infoflags & ERROR) > 0 || (infoflags & ABORT) > 0) { - // we either timed out or there was an error. - notifyAll (); - return false; - } - if ((infoflags & WIDTH) > 0 || (infoflags & HEIGHT) > 0) { - if ((infoflags & WIDTH) > 0) - w = width; - if ((infoflags & HEIGHT) > 0) - h = height; - if (w > -1 && h > -1 && firstFrameLoaded) { - notifyAll (); - return false; - } - } - if ((infoflags & ALLBITS) > 0 || (infoflags & FRAMEBITS) > 0) { - firstFrameLoaded = true; - notifyAll (); - return false; - } - return true; - } + int getWidth() { + return w; + } + int getHeight() { + return h; + } + public synchronized boolean imageUpdate(Image img, int infoflags, int x, int y, + int width, int height) { + // check if there was an error + if (!waiting || ((infoflags & ERROR) > 0) || ((infoflags & ABORT) > 0)) { + // we either timed out or there was an error. + notifyAll(); + + return false; + } + + if (((infoflags & WIDTH) > 0) || ((infoflags & HEIGHT) > 0)) { + if ((infoflags & WIDTH) > 0) { + w = width; + } + + if ((infoflags & HEIGHT) > 0) { + h = height; + } + + if ((w > -1) && (h > -1) && firstFrameLoaded) { + notifyAll(); + + return false; + } + } + + if (((infoflags & ALLBITS) > 0) || ((infoflags & FRAMEBITS) > 0)) { + firstFrameLoaded = true; + notifyAll(); + + return false; + } + + return true; + } } - } diff --git a/src/helma/image/ImageWrapper.java b/src/helma/image/ImageWrapper.java index b5531fa8..f59fa4d9 100644 --- a/src/helma/image/ImageWrapper.java +++ b/src/helma/image/ImageWrapper.java @@ -1,247 +1,396 @@ -// ImageWrapper.java -// Copyright (c) Hannes Wallnöfer 1999-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.image; import java.awt.*; import java.awt.image.*; -import java.util.*; +import java.io.*; import java.rmi.*; import java.rmi.server.*; -import java.io.*; +import java.util.*; -/** +/** * Abstract base class for Image Wrappers. */ - public abstract class ImageWrapper { - Image img; Graphics g; - int width, height; - int fontstyle, fontsize; + int width; + int height; + int fontstyle; + int fontsize; String fontname; ImageGenerator imggen; - public ImageWrapper (Image img, Graphics g, int width, int height, ImageGenerator imggen) { - this.img = img; - this.g = g; - this.width = width; - this.height = height; - this.imggen = imggen; - if (g != null) { - Font f = g.getFont (); - fontname = f.getName (); - fontstyle = f.getStyle (); - fontsize = f.getSize (); - } + /** + * Creates a new ImageWrapper object. + * + * @param img ... + * @param g ... + * @param width ... + * @param height ... + * @param imggen ... + */ + public ImageWrapper(Image img, Graphics g, int width, int height, + ImageGenerator imggen) { + this.img = img; + this.g = g; + this.width = width; + this.height = height; + this.imggen = imggen; + + if (g != null) { + Font f = g.getFont(); + + fontname = f.getName(); + fontstyle = f.getStyle(); + fontsize = f.getSize(); + } } /** * image manipulation methods - */ - - public void setFont (String name, int style, int size) { - this.fontname = name; - this.fontstyle = style; - this.fontsize = size; - g.setFont (new Font (name, style, size)); - } - - public void setColor (int red, int green, int blue) { - g.setColor (new Color (red, green, blue)); - } - - public void setColor (int color) { - g.setColor (new Color (color)); + */ + public void setFont(String name, int style, int size) { + this.fontname = name; + this.fontstyle = style; + this.fontsize = size; + g.setFont(new Font(name, style, size)); } - public void drawString (String str, int x, int y) { - g.drawString (str, x, y); + /** + * + * + * @param red ... + * @param green ... + * @param blue ... + */ + public void setColor(int red, int green, int blue) { + g.setColor(new Color(red, green, blue)); } - public void drawLine (int x1, int y1, int x2, int y2) { - g.drawLine (x1, y1, x2, y2); + /** + * + * + * @param color ... + */ + public void setColor(int color) { + g.setColor(new Color(color)); } - public void drawRect (int x, int y, int w, int h) { - g.drawRect (x, y, w, h); - } - - public void drawImage (String filename, int x, int y) { - try { - Image i = imggen.createImage (filename); - g.drawImage (i, x, y, null); - } catch (Exception ignore) {} + /** + * + * + * @param str ... + * @param x ... + * @param y ... + */ + public void drawString(String str, int x, int y) { + g.drawString(str, x, y); } - public void fillRect (int x, int y, int w, int h) { - g.fillRect (x, y, w, h); + /** + * + * + * @param x1 ... + * @param y1 ... + * @param x2 ... + * @param y2 ... + */ + public void drawLine(int x1, int y1, int x2, int y2) { + g.drawLine(x1, y1, x2, y2); } - public int getWidth () { - return width; + /** + * + * + * @param x ... + * @param y ... + * @param w ... + * @param h ... + */ + public void drawRect(int x, int y, int w, int h) { + g.drawRect(x, y, w, h); } - public int getHeight () { - return height; + /** + * + * + * @param filename ... + * @param x ... + * @param y ... + */ + public void drawImage(String filename, int x, int y) { + try { + Image i = imggen.createImage(filename); + + g.drawImage(i, x, y, null); + } catch (Exception ignore) { + } } - public void crop (int x, int y, int w, int h) { - ImageFilter filter = new CropImageFilter (x, y, w, h); - img = Toolkit.getDefaultToolkit ().createImage(new FilteredImageSource(img.getSource(), filter)); - + /** + * + * + * @param x ... + * @param y ... + * @param w ... + * @param h ... + */ + public void fillRect(int x, int y, int w, int h) { + g.fillRect(x, y, w, h); } - public void resize (int w, int h) { - img = img.getScaledInstance (w, h, Image.SCALE_SMOOTH); - width = w; - height = h; - } - - public void resizeFast (int w, int h) { - img = img.getScaledInstance (w, h, Image.SCALE_FAST); - width = w; - height = h; + /** + * + * + * @return ... + */ + public int getWidth() { + return width; } - public abstract void reduceColors (int colors); + /** + * + * + * @return ... + */ + public int getHeight() { + return height; + } - public abstract void saveAs (String filename); + /** + * + * + * @param x ... + * @param y ... + * @param w ... + * @param h ... + */ + public void crop(int x, int y, int w, int h) { + ImageFilter filter = new CropImageFilter(x, y, w, h); + + img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(img.getSource(), + filter)); + } + + /** + * + * + * @param w ... + * @param h ... + */ + public void resize(int w, int h) { + img = img.getScaledInstance(w, h, Image.SCALE_SMOOTH); + width = w; + height = h; + } + + /** + * + * + * @param w ... + * @param h ... + */ + public void resizeFast(int w, int h) { + img = img.getScaledInstance(w, h, Image.SCALE_FAST); + width = w; + height = h; + } + + /** + * + * + * @param colors ... + */ + public abstract void reduceColors(int colors); + + /** + * + * + * @param filename ... + */ + public abstract void saveAs(String filename); /** * Get ImageProducer of the wrapped image */ - public ImageProducer getSource () { - return img.getSource (); + public ImageProducer getSource() { + return img.getSource(); } - public void fillString (String str) { - Filler filler = new Filler (0, 0, width, height); - filler.layout (str); + /** + * + * + * @param str ... + */ + public void fillString(String str) { + Filler filler = new Filler(0, 0, width, height); + + filler.layout(str); } - public void fillString (String str, int x, int y, int w, int h) { - Filler filler = new Filler (x, y, w, h); - filler.layout (str); + /** + * + * + * @param str ... + * @param x ... + * @param y ... + * @param w ... + * @param h ... + */ + public void fillString(String str, int x, int y, int w, int h) { + Filler filler = new Filler(x, y, w, h); + + filler.layout(str); } - + class Filler { + int x; + int y; + int w; + int h; + int addedSpace = 0; + int xLeft; + int yLeft; + int realHeight; + transient Vector lines; - int x, y, w, h; - int addedSpace = 0; - int xLeft, yLeft; - int realHeight; - transient Vector lines; - - public Filler (int x, int y, int w, int h) { - this.x = x; - this.y = y; - this.w = w; - this.h = h; + public Filler(int x, int y, int w, int h) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + } + + public void layout(String str) { + int size = fontsize; + + lines = new Vector(); + + while (!splitMessage(str, size) && (size > 10)) { + lines.setSize(0); + size = Math.max(2, size - 1); + } + + Font oldfont = g.getFont(); + + g.setFont(new Font(fontname, fontstyle, size)); + + int l = lines.size(); + + for (int i = 0; i < l; i++) { + ((Line) lines.elementAt(i)).paint(g, xLeft / 2, (yLeft / 2) + y); + } + + g.setFont(oldfont); + } + + private boolean splitMessage(String string, int size) { + Font font = new Font(fontname, fontstyle, size); + FontMetrics metrics = Toolkit.getDefaultToolkit().getFontMetrics(font); + int longestLine = 0; + int heightSoFar = 0; + int heightIncrement = (int) (0.84f * metrics.getHeight()); + StringTokenizer tk = new StringTokenizer(string); + StringBuffer buffer = new StringBuffer(); + int spaceWidth = metrics.stringWidth(" "); + int currentLine = 0; + int currentWidth = 0; + int maxWidth = w - 2; + int maxHeight = (h + addedSpace) - 2; + + while (tk.hasMoreTokens()) { + String nextToken = tk.nextToken(); + int nextWidth = metrics.stringWidth(nextToken); + + if ((((currentWidth + nextWidth) >= maxWidth) && (currentWidth != 0))) { + Line line = new Line(buffer.toString(), x, heightSoFar, metrics); + + lines.addElement(line); + + if (line.textwidth > longestLine) { + longestLine = line.textwidth; + } + + buffer = new StringBuffer(); + + currentWidth = 0; + heightSoFar += heightIncrement; + } + + buffer.append(nextToken); + buffer.append(" "); + currentWidth += (nextWidth + spaceWidth); + + if (((1.18 * heightSoFar) > maxHeight) && (fontsize > 10)) { + return false; + } + } + + if (!"".equals(buffer.toString().trim())) { + Line line = new Line(buffer.toString(), x, heightSoFar, metrics); + + lines.addElement(line); + + if (line.textwidth > longestLine) { + longestLine = line.textwidth; + } + + if ((longestLine > maxWidth) && (fontsize > 10)) { + return false; + } + + heightSoFar += heightIncrement; + } + + xLeft = w - longestLine; + yLeft = (addedSpace + h) - heightSoFar; + realHeight = heightSoFar; + + return ((1.18 * heightSoFar) <= maxHeight); + } } - - public void layout (String str) { - int size = fontsize; - lines = new Vector (); - while (!splitMessage (str, size) && size > 10) { - lines.setSize (0); - size = Math.max (2, size-1); - } - Font oldfont = g.getFont (); - g.setFont (new Font (fontname, fontstyle, size)); - int l = lines.size(); - for (int i = 0; i < l; i++) { - ((Line) lines.elementAt (i)).paint (g, xLeft/2, yLeft/2 + y); - } - g.setFont (oldfont); - } - - private boolean splitMessage (String string, int size) { - - Font font = new Font (fontname, fontstyle, size); - FontMetrics metrics = Toolkit.getDefaultToolkit ().getFontMetrics (font); - int longestLine = 0; - int heightSoFar = 0; - int heightIncrement = (int) (0.84f * metrics.getHeight ()); - StringTokenizer tk = new StringTokenizer (string); - StringBuffer buffer = new StringBuffer(); - int spaceWidth = metrics.stringWidth(" "); - int currentLine = 0; - int currentWidth = 0; - int maxWidth = w - 2, maxHeight = h + addedSpace - 2; - while (tk.hasMoreTokens()) { - String nextToken = tk.nextToken(); - int nextWidth = metrics.stringWidth(nextToken); - if ((currentWidth + nextWidth >= maxWidth && currentWidth != 0)) { - Line line = new Line (buffer.toString(), x, heightSoFar, metrics); - lines.addElement (line); - if (line.textwidth > longestLine) - longestLine = line.textwidth; - buffer = new StringBuffer(); - - currentWidth = 0; - heightSoFar += heightIncrement; - } - buffer.append (nextToken); - buffer.append (" "); - currentWidth += (nextWidth + spaceWidth); - if (1.18*heightSoFar > maxHeight && fontsize > 10) - return false; - } - if (! "".equals (buffer.toString().trim())) { - Line line = new Line (buffer.toString(), x, heightSoFar, metrics); - lines.addElement (line); - - if (line.textwidth > longestLine) - longestLine = line.textwidth; - if (longestLine > maxWidth && fontsize > 10) - return false; - heightSoFar += heightIncrement; - } - xLeft = w - longestLine; - yLeft = addedSpace + h - heightSoFar; - realHeight = heightSoFar; - return (1.18*heightSoFar <= maxHeight); - } - - } - class Line implements Serializable { + String text; + int xoff; + int yoff; + FontMetrics fm; + public int textwidth; + public int len; + int ascent; - String text; - int xoff, yoff; - FontMetrics fm; - public int textwidth, len; - int ascent; + public Line(String text, int xoff, int yoff, FontMetrics fm) { + this.text = text.trim(); + len = text.length(); + this.xoff = xoff; + this.yoff = yoff; + this.fm = fm; + textwidth = (len == 0) ? 0 : fm.stringWidth(this.text); + ascent = (int) (0.9f * fm.getAscent()); + } + public void paint(Graphics g, int xadd, int yadd) { + g.drawString(text, xoff + xadd, yoff + ascent + yadd); + } - public Line (String text, int xoff, int yoff, FontMetrics fm) { - this.text = text.trim(); - len = text.length(); - this.xoff = xoff; - this.yoff = yoff; - this.fm = fm; - textwidth = (len == 0) ? 0 : fm.stringWidth(this.text); - ascent = (int) (0.9f * fm.getAscent()); + public boolean contains(int y) { + return (y < (yoff + fm.getHeight())) ? true : false; + } } - - public void paint (Graphics g, int xadd, int yadd) { - g.drawString (text, xoff+xadd, yoff+ascent+yadd); - } - - - public boolean contains (int y) { - return (y < yoff+fm.getHeight()) ? true : false; - } - - - } - } - - - - - diff --git a/src/helma/image/SunImageWrapper.java b/src/helma/image/SunImageWrapper.java index d4bc82a8..30db9dfb 100644 --- a/src/helma/image/SunImageWrapper.java +++ b/src/helma/image/SunImageWrapper.java @@ -1,87 +1,121 @@ -// ActivatedImageWrapper.java -// Copyright (c) Hannes Wallnöfer 1999-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.image; -import java.awt.*; -import java.awt.image.*; +import Acme.JPM.Encoders.GifEncoder; import com.sun.jimi.core.*; import com.sun.jimi.core.util.*; -import Acme.JPM.Encoders.GifEncoder; -import java.io.IOException; +import java.awt.*; +import java.awt.image.*; import java.io.FileOutputStream; +import java.io.IOException; /** * A wrapper for an image that uses the Sun version of JIMI available at * http://java.sun.com/products/jimi. */ - public class SunImageWrapper extends ImageWrapper { - - public SunImageWrapper (Image img, Graphics g, int width, int height, - ImageGenerator imggen) { - super (img, g, width, height, imggen); - } - - - public void reduceColors (int colors) { - try { - int pixels[][] = getPixels(); - int palette[] = Quantize.quantizeImage(pixels, colors); - int w = pixels.length; - int h = pixels[0].length; - int pix[] = new int[w * h]; - // convert to RGB - for (int x = w; x-- > 0; ) { - for (int y = h; y-- > 0; ) { - pix[y * w + x] = palette[pixels[x][y]]; - } - } - img = imggen.createImage (new MemoryImageSource(w, h, pix, 0, w)); - } catch (Exception x) { - // throw new RuntimeException (x.getMessage ()); - } + /** + * Creates a new SunImageWrapper object. + * + * @param img ... + * @param g ... + * @param width ... + * @param height ... + * @param imggen ... + */ + public SunImageWrapper(Image img, Graphics g, int width, int height, + ImageGenerator imggen) { + super(img, g, width, height, imggen); } /** - * Snag the pixels from an image. + * + * + * @param colors ... */ - int[][] getPixels () throws IOException { - int pix[] = new int[width * height]; - PixelGrabber grabber = new PixelGrabber(img, 0, 0, width, height, pix, 0, width); - try { - if (grabber.grabPixels() != true) { - throw new IOException("Grabber returned false: " + grabber.status()); - } - } catch (InterruptedException e) { - e.printStackTrace(); - } - int pixels[][] = new int[width][height]; - for (int x = width; x-- > 0; ) { - for (int y = height; y-- > 0; ) { - pixels[x][y] = pix[y * width + x]; - } - } - return pixels; + public void reduceColors(int colors) { + try { + int[][] pixels = getPixels(); + int[] palette = Quantize.quantizeImage(pixels, colors); + int w = pixels.length; + int h = pixels[0].length; + int[] pix = new int[w * h]; + + // convert to RGB + for (int x = w; x-- > 0;) { + for (int y = h; y-- > 0;) { + pix[(y * w) + x] = palette[pixels[x][y]]; + } + } + + img = imggen.createImage(new MemoryImageSource(w, h, pix, 0, w)); + } catch (Exception x) { + // throw new RuntimeException (x.getMessage ()); + } } + /** + * Snag the pixels from an image. + */ + int[][] getPixels() throws IOException { + int[] pix = new int[width * height]; + PixelGrabber grabber = new PixelGrabber(img, 0, 0, width, height, pix, 0, width); - public void saveAs (String filename) { - try { - if (filename.toLowerCase().endsWith (".gif")) { - // sun's jimi package doesn't encode gifs, use Acme encoder - FileOutputStream fout = new FileOutputStream (filename); - // Acme gif encoder - GifEncoder enc = new GifEncoder (img, fout); - enc.encode (); - fout.close (); - } else { - Jimi.putImage (img, filename); - } - } catch (Exception x) { - throw new RuntimeException (x.getMessage ()); - } + try { + if (grabber.grabPixels() != true) { + throw new IOException("Grabber returned false: " + grabber.status()); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + + int[][] pixels = new int[width][height]; + + for (int x = width; x-- > 0;) { + for (int y = height; y-- > 0;) { + pixels[x][y] = pix[(y * width) + x]; + } + } + + return pixels; } + /** + * + * + * @param filename ... + */ + public void saveAs(String filename) { + try { + if (filename.toLowerCase().endsWith(".gif")) { + // sun's jimi package doesn't encode gifs, use Acme encoder + FileOutputStream fout = new FileOutputStream(filename); + // Acme gif encoder + GifEncoder enc = new GifEncoder(img, fout); + + enc.encode(); + fout.close(); + } else { + Jimi.putImage(img, filename); + } + } catch (Exception x) { + throw new RuntimeException(x.getMessage()); + } + } } diff --git a/src/helma/main/ApplicationManager.java b/src/helma/main/ApplicationManager.java index 349a91da..af14b15e 100644 --- a/src/helma/main/ApplicationManager.java +++ b/src/helma/main/ApplicationManager.java @@ -1,33 +1,43 @@ -// ApplicationManager.java -// Copyright (c) Hannes Wallnöfer 1998-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.main; -import java.util.*; -import java.io.*; -import java.lang.reflect.*; -import java.rmi.*; -import java.rmi.server.*; -import java.net.URLEncoder; import helma.framework.*; import helma.framework.core.*; import helma.objectmodel.*; import helma.servlet.*; import helma.util.SystemProperties; +import org.apache.xmlrpc.XmlRpcHandler; import org.mortbay.http.*; import org.mortbay.http.handler.*; import org.mortbay.jetty.servlet.*; import org.mortbay.util.*; +import java.io.*; +import java.lang.reflect.*; +import java.net.URLEncoder; +import java.rmi.*; +import java.rmi.server.*; +import java.util.*; import javax.servlet.Servlet; -import org.apache.xmlrpc.XmlRpcHandler; - /** * This class is responsible for starting and stopping Helma applications. */ - public class ApplicationManager implements XmlRpcHandler { - private Hashtable applications; private Hashtable xmlrpcHandlers; private Properties mountpoints; @@ -37,258 +47,368 @@ public class ApplicationManager implements XmlRpcHandler { private Server server; private long lastModified; - public ApplicationManager (int port, File hopHome, SystemProperties props, Server server) { - this.port = port; - this.hopHome = hopHome; - this.props = props; - this.server = server; - applications = new Hashtable (); - xmlrpcHandlers = new Hashtable (); - mountpoints = new Properties (); - lastModified = 0; + /** + * Creates a new ApplicationManager object. + * + * @param port ... + * @param hopHome ... + * @param props ... + * @param server ... + */ + public ApplicationManager(int port, File hopHome, SystemProperties props, + Server server) { + this.port = port; + this.hopHome = hopHome; + this.props = props; + this.server = server; + applications = new Hashtable(); + xmlrpcHandlers = new Hashtable(); + mountpoints = new Properties(); + lastModified = 0; } - // regularely check applications property file to create and start new applications - protected void checkForChanges () { - if (props.lastModified () > lastModified) { - try { - for (Enumeration e = props.keys(); e.hasMoreElements (); ) { - String appName = (String) e.nextElement (); - if (appName.indexOf (".") == -1 && applications.get (appName) == null) { - start (appName); - register (appName); - } - } - // then stop deleted ones - for (Enumeration e = applications.keys(); e.hasMoreElements (); ) { - String appName = (String) e.nextElement (); - // check if application has been removed and should be stopped - if (!props.containsKey (appName)) { - stop (appName); - } else if (server.http != null) { - // check if application should be remounted at a - // different location on embedded web server - String oldMountpoint = mountpoints.getProperty (appName); - String mountpoint = getMountpoint (appName); - String pattern = getPathPattern (mountpoint); - if (!pattern.equals (oldMountpoint)) { - Server.getLogger().log("Moving application "+appName+" from "+oldMountpoint+" to "+pattern); - HttpContext oldContext = server.http.getContext (null, oldMountpoint); - if (oldContext != null) { - // oldContext.setContextPath(pattern); - oldContext.stop (); - oldContext.destroy (); - } - Application app = (Application) applications.get (appName); - if (!app.hasExplicitBaseURI()) - app.setBaseURI (mountpoint); - ServletHttpContext context = new ServletHttpContext (); - context.setContextPath(pattern); - server.http.addContext (context); - ServletHolder holder = context.addServlet (appName, "/*", "helma.servlet.EmbeddedServletClient"); - holder.setInitParameter ("application", appName); - holder.setInitParameter ("mountpoint", mountpoint); - if ("true".equalsIgnoreCase (props.getProperty (appName+".responseEncoding"))) - context.addHandler(new ContentEncodingHandler()); - String cookieDomain = props.getProperty (appName+".cookieDomain"); - if (cookieDomain != null) - holder.setInitParameter ("cookieDomain", cookieDomain); - String uploadLimit = props.getProperty (appName+".uploadLimit"); - if (uploadLimit != null) - holder.setInitParameter ("uploadLimit", uploadLimit); - // holder.start (); - context.start (); - mountpoints.setProperty (appName, pattern); - } - } - } - } catch (Exception mx) { - Server.getLogger().log ("Error checking applications: "+mx); - } + protected void checkForChanges() { + if (props.lastModified() > lastModified) { + try { + for (Enumeration e = props.keys(); e.hasMoreElements();) { + String appName = (String) e.nextElement(); - lastModified = System.currentTimeMillis (); - } + if ((appName.indexOf(".") == -1) && + (applications.get(appName) == null)) { + start(appName); + register(appName); + } + } + + // then stop deleted ones + for (Enumeration e = applications.keys(); e.hasMoreElements();) { + String appName = (String) e.nextElement(); + + // check if application has been removed and should be stopped + if (!props.containsKey(appName)) { + stop(appName); + } else if (server.http != null) { + // check if application should be remounted at a + // different location on embedded web server + String oldMountpoint = mountpoints.getProperty(appName); + String mountpoint = getMountpoint(appName); + String pattern = getPathPattern(mountpoint); + + if (!pattern.equals(oldMountpoint)) { + Server.getLogger().log("Moving application " + appName + + " from " + oldMountpoint + " to " + + pattern); + + HttpContext oldContext = server.http.getContext(null, + oldMountpoint); + + if (oldContext != null) { + // oldContext.setContextPath(pattern); + oldContext.stop(); + oldContext.destroy(); + } + + Application app = (Application) applications.get(appName); + + if (!app.hasExplicitBaseURI()) { + app.setBaseURI(mountpoint); + } + + ServletHttpContext context = new ServletHttpContext(); + + context.setContextPath(pattern); + server.http.addContext(context); + + ServletHolder holder = context.addServlet(appName, "/*", + "helma.servlet.EmbeddedServletClient"); + + holder.setInitParameter("application", appName); + holder.setInitParameter("mountpoint", mountpoint); + + if ("true".equalsIgnoreCase(props.getProperty(appName + + ".responseEncoding"))) { + context.addHandler(new ContentEncodingHandler()); + } + + String cookieDomain = props.getProperty(appName + + ".cookieDomain"); + + if (cookieDomain != null) { + holder.setInitParameter("cookieDomain", cookieDomain); + } + + String uploadLimit = props.getProperty(appName + + ".uploadLimit"); + + if (uploadLimit != null) { + holder.setInitParameter("uploadLimit", uploadLimit); + } + + // holder.start (); + context.start(); + mountpoints.setProperty(appName, pattern); + } + } + } + } catch (Exception mx) { + Server.getLogger().log("Error checking applications: " + mx); + } + + lastModified = System.currentTimeMillis(); + } } - void start (String appName) { - Server.getLogger().log ("Building application "+appName); - try { - // check if application and db dirs are set, otherwise go with - // the defaults, passing null dirs to the constructor. - String appDirName = props.getProperty (appName+".appdir"); - File appDir = appDirName == null ? null : new File (appDirName); - String dbDirName = props.getProperty (appName+".dbdir"); - File dbDir = dbDirName == null ? null : new File (dbDirName); - // create the application instance - Application app = new Application (appName, server, appDir, dbDir); - applications.put (appName, app); - // the application is started later in the register method, when it's bound - app.init (); - } catch (Exception x) { - Server.getLogger().log ("Error creating application "+appName+": "+x); - x.printStackTrace (); - } + void start(String appName) { + Server.getLogger().log("Building application " + appName); + + try { + // check if application and db dirs are set, otherwise go with + // the defaults, passing null dirs to the constructor. + String appDirName = props.getProperty(appName + ".appdir"); + File appDir = (appDirName == null) ? null : new File(appDirName); + String dbDirName = props.getProperty(appName + ".dbdir"); + File dbDir = (dbDirName == null) ? null : new File(dbDirName); + + // create the application instance + Application app = new Application(appName, server, appDir, dbDir); + + applications.put(appName, app); + + // the application is started later in the register method, when it's bound + app.init(); + } catch (Exception x) { + Server.getLogger().log("Error creating application " + appName + ": " + x); + x.printStackTrace(); + } } - void stop (String appName) { - Server.getLogger().log ("Stopping application "+appName); - try { - Application app = (Application) applications.get (appName); - // unbind from RMI server - if (port > 0) { - Naming.unbind ("//:"+port+"/"+appName); - } - // unbind from Jetty HTTP server - if (server.http != null) { - String mountpoint = mountpoints.getProperty (appName); - HttpContext context = server.http.getContext (null, mountpoint); - if (context != null) { - context.stop (); - context.destroy (); - } - } - // unregister as XML-RPC handler - xmlrpcHandlers.remove (app.getXmlRpcHandlerName()); - app.stop (); - Server.getLogger().log ("Unregistered application "+appName); - } catch (Exception x) { - Server.getLogger().log ("Couldn't unregister app: "+x); - } - applications.remove (appName); + void stop(String appName) { + Server.getLogger().log("Stopping application " + appName); + + try { + Application app = (Application) applications.get(appName); + + // unbind from RMI server + if (port > 0) { + Naming.unbind("//:" + port + "/" + appName); + } + + // unbind from Jetty HTTP server + if (server.http != null) { + String mountpoint = mountpoints.getProperty(appName); + HttpContext context = server.http.getContext(null, mountpoint); + + if (context != null) { + context.stop(); + context.destroy(); + } + } + + // unregister as XML-RPC handler + xmlrpcHandlers.remove(app.getXmlRpcHandlerName()); + app.stop(); + Server.getLogger().log("Unregistered application " + appName); + } catch (Exception x) { + Server.getLogger().log("Couldn't unregister app: " + x); + } + + applications.remove(appName); } - void register (String appName) { - try { - Server.getLogger().log ("Binding application "+appName); - Application app = (Application) applications.get (appName); - // bind to RMI server - if (port > 0) { - Naming.rebind ("//:"+port+"/"+appName, new RemoteApplication (app)); - } - // bind to Jetty HTTP server - if (server.http != null) { - String mountpoint = getMountpoint (appName); - // if using embedded webserver (not AJP) set application URL prefix - if (!app.hasExplicitBaseURI ()) - app.setBaseURI (mountpoint); - String pattern = getPathPattern (mountpoint); - ServletHttpContext context = new ServletHttpContext (); - context.setContextPath(pattern); - server.http.addContext (context); - ServletHolder holder = context.addServlet (appName, "/*", "helma.servlet.EmbeddedServletClient"); - holder.setInitParameter ("application", appName); - holder.setInitParameter ("mountpoint", mountpoint); - if ("true".equalsIgnoreCase (props.getProperty (appName+".responseEncoding"))) - context.addHandler(new ContentEncodingHandler()); - String cookieDomain = props.getProperty (appName+".cookieDomain"); - if (cookieDomain != null) - holder.setInitParameter ("cookieDomain", cookieDomain); - String uploadLimit = props.getProperty (appName+".uploadLimit"); - if (uploadLimit != null) - holder.setInitParameter ("uploadLimit", uploadLimit); - String debug = props.getProperty (appName+".debug"); - if (debug != null) - holder.setInitParameter ("debug", debug); - // holder.start (); - context.start (); - mountpoints.setProperty (appName, pattern); - } - // register as XML-RPC handler - xmlrpcHandlers.put (app.getXmlRpcHandlerName(), app); - app.start (); - } catch (Exception x) { - Server.getLogger().log ("Couldn't register and start app: "+x); - x.printStackTrace (); - } + void register(String appName) { + try { + Server.getLogger().log("Binding application " + appName); + + Application app = (Application) applications.get(appName); + + // bind to RMI server + if (port > 0) { + Naming.rebind("//:" + port + "/" + appName, new RemoteApplication(app)); + } + + // bind to Jetty HTTP server + if (server.http != null) { + String mountpoint = getMountpoint(appName); + + // if using embedded webserver (not AJP) set application URL prefix + if (!app.hasExplicitBaseURI()) { + app.setBaseURI(mountpoint); + } + + String pattern = getPathPattern(mountpoint); + ServletHttpContext context = new ServletHttpContext(); + + context.setContextPath(pattern); + server.http.addContext(context); + + ServletHolder holder = context.addServlet(appName, "/*", + "helma.servlet.EmbeddedServletClient"); + + holder.setInitParameter("application", appName); + holder.setInitParameter("mountpoint", mountpoint); + + if ("true".equalsIgnoreCase(props.getProperty(appName + + ".responseEncoding"))) { + context.addHandler(new ContentEncodingHandler()); + } + + String cookieDomain = props.getProperty(appName + ".cookieDomain"); + + if (cookieDomain != null) { + holder.setInitParameter("cookieDomain", cookieDomain); + } + + String uploadLimit = props.getProperty(appName + ".uploadLimit"); + + if (uploadLimit != null) { + holder.setInitParameter("uploadLimit", uploadLimit); + } + + String debug = props.getProperty(appName + ".debug"); + + if (debug != null) { + holder.setInitParameter("debug", debug); + } + + // holder.start (); + context.start(); + mountpoints.setProperty(appName, pattern); + } + + // register as XML-RPC handler + xmlrpcHandlers.put(app.getXmlRpcHandlerName(), app); + app.start(); + } catch (Exception x) { + Server.getLogger().log("Couldn't register and start app: " + x); + x.printStackTrace(); + } } - public void startAll () { - try { - for (Enumeration e = props.keys(); e.hasMoreElements (); ) { - String appName = (String) e.nextElement (); - if (appName.indexOf (".") == -1) - start (appName); - } - for (Enumeration e = props.keys(); e.hasMoreElements (); ) { - String appName = (String) e.nextElement (); - if (appName.indexOf (".") == -1) - register (appName); - } - if (server.http != null) { - // add handler for static files. - File staticContent = new File (server.getHopHome(), "static"); - Server.getLogger().log("Serving static content from "+staticContent.getAbsolutePath()); - HttpContext context = server.http.addContext ("/static/*"); - context.setResourceBase (staticContent.getAbsolutePath()); - ResourceHandler handler = new ResourceHandler(); - context.addHandler(handler); - context.start (); - } - lastModified = System.currentTimeMillis (); - } catch (Exception mx) { - Server.getLogger().log ("Error starting applications: "+mx); - mx.printStackTrace (); - } + /** + * + */ + public void startAll() { + try { + for (Enumeration e = props.keys(); e.hasMoreElements();) { + String appName = (String) e.nextElement(); + + if (appName.indexOf(".") == -1) { + start(appName); + } + } + + for (Enumeration e = props.keys(); e.hasMoreElements();) { + String appName = (String) e.nextElement(); + + if (appName.indexOf(".") == -1) { + register(appName); + } + } + + if (server.http != null) { + // add handler for static files. + File staticContent = new File(server.getHopHome(), "static"); + + Server.getLogger().log("Serving static content from " + + staticContent.getAbsolutePath()); + + HttpContext context = server.http.addContext("/static/*"); + + context.setResourceBase(staticContent.getAbsolutePath()); + + ResourceHandler handler = new ResourceHandler(); + + context.addHandler(handler); + context.start(); + } + + lastModified = System.currentTimeMillis(); + } catch (Exception mx) { + Server.getLogger().log("Error starting applications: " + mx); + mx.printStackTrace(); + } } - public void stopAll () { - for (Enumeration en=applications.keys(); en.hasMoreElements(); ) { - String appName = (String) en.nextElement(); - stop (appName); - } + /** + * + */ + public void stopAll() { + for (Enumeration en = applications.keys(); en.hasMoreElements();) { + String appName = (String) en.nextElement(); + + stop(appName); + } } /** * Get an array containing all currently running applications. */ - public Object[] getApplications () { - return applications.values ().toArray (); + public Object[] getApplications() { + return applications.values().toArray(); } /** - * Get an application by name. - */ - public Application getApplication(String name) { - return (Application)applications.get(name); + * Get an application by name. + */ + public Application getApplication(String name) { + return (Application) applications.get(name); } /** * Implements org.apache.xmlrpc.XmlRpcHandler.execute() */ - public Object execute (String method, Vector params) throws Exception { - int dot = method.indexOf ("."); - if (dot == -1) - throw new Exception ("Method name \""+method+"\" does not specify a handler application"); - if (dot == 0 || dot == method.length()-1) - throw new Exception ("\""+method+"\" is not a valid XML-RPC method name"); - String handler = method.substring (0, dot); - String method2 = method.substring (dot+1); - Application app = (Application) xmlrpcHandlers.get (handler); - if (app == null) - throw new Exception ("Handler \""+handler+"\" not found for "+method); - return app.executeXmlRpc (method2, params); + public Object execute(String method, Vector params) + throws Exception { + int dot = method.indexOf("."); + + if (dot == -1) { + throw new Exception("Method name \"" + method + + "\" does not specify a handler application"); + } + + if ((dot == 0) || (dot == (method.length() - 1))) { + throw new Exception("\"" + method + "\" is not a valid XML-RPC method name"); + } + + String handler = method.substring(0, dot); + String method2 = method.substring(dot + 1); + Application app = (Application) xmlrpcHandlers.get(handler); + + if (app == null) { + throw new Exception("Handler \"" + handler + "\" not found for " + method); + } + + return app.executeXmlRpc(method2, params); } + private String getMountpoint(String appName) { + String mountpoint = props.getProperty(appName + ".mountpoint"); - private String getMountpoint (String appName) { - String mountpoint = props.getProperty (appName+".mountpoint"); - if (mountpoint == null) - return "/"+URLEncoder.encode(appName); - mountpoint = mountpoint.trim (); - if ("".equals (mountpoint)) - return "/"; - else if (!mountpoint.startsWith ("/")) - return "/"+mountpoint; - return mountpoint; + if (mountpoint == null) { + return "/" + URLEncoder.encode(appName); + } + + mountpoint = mountpoint.trim(); + + if ("".equals(mountpoint)) { + return "/"; + } else if (!mountpoint.startsWith("/")) { + return "/" + mountpoint; + } + + return mountpoint; } - private String getPathPattern (String mountpoint) { - if ("/".equals (mountpoint)) - return "/"; - if (!mountpoint.endsWith ("/")) - return mountpoint+"/*"; - return mountpoint+"*"; - } + private String getPathPattern(String mountpoint) { + if ("/".equals(mountpoint)) { + return "/"; + } + if (!mountpoint.endsWith("/")) { + return mountpoint + "/*"; + } + + return mountpoint + "*"; + } } diff --git a/src/helma/main/HelmaSecurityManager.java b/src/helma/main/HelmaSecurityManager.java index e617e4ad..31a32c6e 100644 --- a/src/helma/main/HelmaSecurityManager.java +++ b/src/helma/main/HelmaSecurityManager.java @@ -1,94 +1,327 @@ -// HelmaSecurityManager.java +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.main; -import java.security.Permission; +import helma.framework.core.AppClassLoader; import java.io.FileDescriptor; import java.net.InetAddress; +import java.security.Permission; import java.util.HashSet; -import helma.framework.core.AppClassLoader; /** - * Liberal security manager for Helma system that makes sure application code + * Liberal security manager for Helma system that makes sure application code * is not allowed to exit the VM and set a security manager. * * This class can be subclassed to implement actual security policies. It contains - * a utility method <code>getApplication</code> that can be used to determine + * a utility method <code>getApplication</code> that can be used to determine * the name of the application trying to execute the action in question, if any. */ public class HelmaSecurityManager extends SecurityManager { - // The set of actions forbidden to application code. // We are pretty permissive, forbidding only System.exit() // and setting the security manager. - private final static HashSet forbidden = new HashSet (); + private final static HashSet forbidden = new HashSet(); + static { - forbidden.add ("exitVM"); - forbidden.add ("setSecurityManager"); + forbidden.add("exitVM"); + forbidden.add("setSecurityManager"); } + /** + * + * + * @param p ... + */ public void checkPermission(Permission p) { - if (p instanceof RuntimePermission) { - if (forbidden.contains (p.getName())) { - Class[] classes = getClassContext(); - for (int i=0; i<classes.length; i++) { - if (classes[i].getClassLoader() instanceof AppClassLoader) - throw new SecurityException (p.getName()+" not allowed for application code"); - } - } - } + if (p instanceof RuntimePermission) { + if (forbidden.contains(p.getName())) { + Class[] classes = getClassContext(); + + for (int i = 0; i < classes.length; i++) { + if (classes[i].getClassLoader() instanceof AppClassLoader) { + throw new SecurityException(p.getName() + + " not allowed for application code"); + } + } + } + } } + + /** + * + * + * @param p ... + * @param context ... + */ public void checkPermission(Permission p, Object context) { } - public void checkCreateClassLoader() {} - public void checkAccess(Thread thread) {} - public void checkAccess(ThreadGroup group) {} - public void checkExit(int status) { - Class[] classes = getClassContext(); - for (int i=0; i<classes.length; i++) { - if (classes[i].getClassLoader() instanceof AppClassLoader) - throw new SecurityException ("operation not allowed for application code"); - } + + /** + * + */ + public void checkCreateClassLoader() { + } + + /** + * + * + * @param thread ... + */ + public void checkAccess(Thread thread) { + } + + /** + * + * + * @param group ... + */ + public void checkAccess(ThreadGroup group) { + } + + /** + * + * + * @param status ... + */ + public void checkExit(int status) { + Class[] classes = getClassContext(); + + for (int i = 0; i < classes.length; i++) { + if (classes[i].getClassLoader() instanceof AppClassLoader) { + throw new SecurityException("operation not allowed for application code"); + } + } + } + + /** + * + * + * @param cmd ... + */ + public void checkExec(String cmd) { + } + + /** + * + * + * @param lib ... + */ + public void checkLink(String lib) { + } + + /** + * + * + * @param fdesc ... + */ + public void checkRead(FileDescriptor fdesc) { + } + + /** + * + * + * @param file ... + */ + public void checkRead(String file) { + } + + /** + * + * + * @param file ... + * @param context ... + */ + public void checkRead(String file, Object context) { + } + + /** + * + * + * @param fdesc ... + */ + public void checkWrite(FileDescriptor fdesc) { + } + + /** + * + * + * @param file ... + */ + public void checkWrite(String file) { + } + + /** + * + * + * @param file ... + */ + public void checkDelete(String file) { + } + + /** + * + * + * @param host ... + * @param port ... + */ + public void checkConnect(String host, int port) { + } + + /** + * + * + * @param host ... + * @param port ... + * @param context ... + */ + public void checkConnect(String host, int port, Object context) { + } + + /** + * + * + * @param port ... + */ + public void checkListen(int port) { + } + + /** + * + * + * @param host ... + * @param port ... + */ + public void checkAccept(String host, int port) { + } + + /** + * + * + * @param addr ... + */ + public void checkMulticast(InetAddress addr) { + } + + /** + * + * + * @param addr ... + * @param ttl ... + */ + public void checkMulticast(InetAddress addr, byte ttl) { + } + + /** + * + */ + public void checkPropertiesAccess() { + } + + /** + * + * + * @param key ... + */ + public void checkPropertyAccess(String key) { + } + + /** + * + * + * @param window ... + * + * @return ... + */ + public boolean checkTopLevelWindow(Object window) { + return true; + } + + /** + * + */ + public void checkPrintJobAccess() { + } + + /** + * + */ + public void checkSystemClipboardAccess() { + } + + /** + * + */ + public void checkAwtEventQueueAccess() { + } + + /** + * + * + * @param pkg ... + */ + public void checkPackageAccess(String pkg) { + } + + /** + * + * + * @param pkg ... + */ + public void checkPackageDefinition(String pkg) { + } + + /** + * + */ + public void checkSetFactory() { + } + + /** + * + * + * @param clazz ... + * @param which ... + */ + public void checkMemberAccess(Class clazz, int which) { + } + + /** + * + * + * @param target ... + */ + public void checkSecurityAccess(String target) { } - public void checkExec(String cmd) {} - public void checkLink(String lib) {} - public void checkRead(FileDescriptor fdesc) {} - public void checkRead(String file) {} - public void checkRead(String file, Object context) {} - public void checkWrite(FileDescriptor fdesc) {} - public void checkWrite(String file) {} - public void checkDelete(String file) {} - public void checkConnect(String host, int port) {} - public void checkConnect(String host, int port, Object context) {} - public void checkListen(int port) {} - public void checkAccept(String host, int port) {} - public void checkMulticast(InetAddress addr) {} - public void checkMulticast(InetAddress addr, byte ttl) {} - public void checkPropertiesAccess() {} - public void checkPropertyAccess(String key) {} - public boolean checkTopLevelWindow(Object window) { return true; } - public void checkPrintJobAccess() {} - public void checkSystemClipboardAccess() {} - public void checkAwtEventQueueAccess() {} - public void checkPackageAccess(String pkg) {} - public void checkPackageDefinition(String pkg) {} - public void checkSetFactory() {} - public void checkMemberAccess(Class clazz, int which) {} - public void checkSecurityAccess(String target) {} /** * Utility method that returns the name of the application trying - * to execute the code in question. Returns null if the current code + * to execute the code in question. Returns null if the current code * does not belong to any application. */ - protected String getApplication () { - Class[] classes = getClassContext(); - for (int i=0; i<classes.length; i++) { - if (classes[i].getClassLoader() instanceof AppClassLoader) - return ((AppClassLoader) classes[i].getClassLoader()).getAppName (); - } - // no application class loader found in stack - return null - return null; - } + protected String getApplication() { + Class[] classes = getClassContext(); + for (int i = 0; i < classes.length; i++) { + if (classes[i].getClassLoader() instanceof AppClassLoader) { + return ((AppClassLoader) classes[i].getClassLoader()).getAppName(); + } + } + + // no application class loader found in stack - return null + return null; + } } diff --git a/src/helma/main/HelmaShutdownHook.java b/src/helma/main/HelmaShutdownHook.java index 1c0d83f1..e613492d 100644 --- a/src/helma/main/HelmaShutdownHook.java +++ b/src/helma/main/HelmaShutdownHook.java @@ -1,4 +1,19 @@ -// HelmaShutdownHook.java +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.main; import helma.util.Logger; @@ -8,23 +23,35 @@ import java.util.List; * ShutdownHook that shuts down all running Helma applications on exit. */ public class HelmaShutdownHook extends Thread { - ApplicationManager appmgr; - public HelmaShutdownHook (ApplicationManager appmgr) { - this.appmgr = appmgr; + /** + * Creates a new HelmaShutdownHook object. + * + * @param appmgr ... + */ + public HelmaShutdownHook(ApplicationManager appmgr) { + this.appmgr = appmgr; } - public void run () { - Logger logger = Server.getLogger(); - if (logger != null) - logger.log ("Shutting down Helma"); - appmgr.stopAll (); - List loggers = Logger.getLoggers(); - int l = loggers.size(); - for (int i=0; i<l; i++) - ((Logger) loggers.get(i)).close(); - Logger.wakeup(); - } + /** + * + */ + public void run() { + Logger logger = Server.getLogger(); + if (logger != null) { + logger.log("Shutting down Helma"); + } + + appmgr.stopAll(); + + List loggers = Logger.getLoggers(); + int l = loggers.size(); + + for (int i = 0; i < l; i++) + ((Logger) loggers.get(i)).close(); + + Logger.wakeup(); + } } diff --git a/src/helma/main/HelmaSocketFactory.java b/src/helma/main/HelmaSocketFactory.java index bdf674f3..7968d61a 100644 --- a/src/helma/main/HelmaSocketFactory.java +++ b/src/helma/main/HelmaSocketFactory.java @@ -1,42 +1,79 @@ -// HopSocketFactory.java -// Copyright (c) Hannes Wallnöfer 1999-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.main; import helma.util.*; +import java.io.IOException; import java.net.*; import java.rmi.server.*; -import java.io.IOException; /** * An RMI socket factory that has a "paranoid" option to filter clients. * We only do direct connections, no HTTP proxy stuff, since this is * server-to-server. */ - public class HelmaSocketFactory extends RMISocketFactory { - private InetAddressFilter filter; - public HelmaSocketFactory () { - filter = new InetAddressFilter (); + /** + * Creates a new HelmaSocketFactory object. + */ + public HelmaSocketFactory() { + filter = new InetAddressFilter(); } - public void addAddress (String address) { - try { - filter.addAddress (address); - } catch (IOException x) { - Server.getLogger().log ("Could not add "+address+" to Socket Filter: invalid address."); - } + /** + * + * + * @param address ... + */ + public void addAddress(String address) { + try { + filter.addAddress(address); + } catch (IOException x) { + Server.getLogger().log("Could not add " + address + + " to Socket Filter: invalid address."); + } } + /** + * + * + * @param host ... + * @param port ... + * + * @return ... + * + * @throws IOException ... + */ public Socket createSocket(String host, int port) throws IOException { - return new Socket (host, port); + return new Socket(host, port); } + /** + * + * + * @param port ... + * + * @return ... + * + * @throws IOException ... + */ public ServerSocket createServerSocket(int port) throws IOException { - return new ParanoidServerSocket (port, filter); + return new ParanoidServerSocket(port, filter); } - } diff --git a/src/helma/main/Server.java b/src/helma/main/Server.java index 8b46440b..7cc2622f 100644 --- a/src/helma/main/Server.java +++ b/src/helma/main/Server.java @@ -1,48 +1,63 @@ -// Server.java -// Copyright (c) Hannes Wallnöfer 1998-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.main; -import java.io.*; -import java.rmi.*; -import java.rmi.server.*; -import java.rmi.registry.*; -import java.net.*; -import java.util.*; import helma.extensions.HelmaExtension; -import helma.objectmodel.db.DbSource; import helma.framework.*; import helma.framework.core.*; +import helma.objectmodel.db.DbSource; import helma.util.*; -import org.mortbay.http.*; -import org.mortbay.util.*; -import org.mortbay.http.ajp.*; import org.apache.xmlrpc.*; +import org.mortbay.http.*; +import org.mortbay.http.ajp.*; +import org.mortbay.util.*; +import java.io.*; +import java.net.*; +import java.rmi.*; +import java.rmi.registry.*; +import java.rmi.server.*; +import java.util.*; /** * Helma server main class. */ - - public class Server implements IPathElement, Runnable { - - public static final String version = "1.2.3 RC1 (2003/03/05)"; - public final long starttime; - - // if true we only accept RMI and XML-RPC connections from - // explicitly listed hosts. - public boolean paranoid; - - private ApplicationManager appManager; - - private Vector extensions; - - private Thread mainThread; +public class Server implements IPathElement, Runnable { + public static final String version = "1.2.4 (2003/04/16)"; // server-wide properties static SystemProperties appsProps; static SystemProperties dbProps; static SystemProperties sysProps; + // static server instance + private static Server server; + protected static File hopHome = null; + + // our logger + private static Logger logger; + public final long starttime; + + // if true we only accept RMI and XML-RPC connections from + // explicitly listed hosts. + public boolean paranoid; + private ApplicationManager appManager; + private Vector extensions; + private Thread mainThread; + // server ports int rmiPort = 0; int xmlrpcPort = 0; @@ -52,14 +67,6 @@ import org.apache.xmlrpc.*; // map of server-wide database sources Hashtable dbSources; - // static server instance - private static Server server; - - protected static File hopHome = null; - - // our logger - private static Logger logger; - // the embedded web server // protected Serve websrv; protected HttpServer http; @@ -70,246 +77,286 @@ import org.apache.xmlrpc.*; // the XML-RPC server protected WebServer xmlrpc; + /** + * Constructs a new Server instance with an array of command line options. + */ + public Server(String[] args) { + starttime = System.currentTimeMillis(); + String homeDir = null; + + boolean usageError = false; + + // file names of various property files + String propfile = null; + String dbPropfile = "db.properties"; + String appsPropfile = null; + + // parse arguments + for (int i = 0; i < args.length; i++) { + if (args[i].equals("-h") && ((i + 1) < args.length)) { + homeDir = args[++i]; + } else if (args[i].equals("-f") && ((i + 1) < args.length)) { + propfile = args[++i]; + } else if (args[i].equals("-p") && ((i + 1) < args.length)) { + try { + rmiPort = Integer.parseInt(args[++i]); + } catch (Exception portx) { + usageError = true; + } + } else if (args[i].equals("-x") && ((i + 1) < args.length)) { + try { + xmlrpcPort = Integer.parseInt(args[++i]); + } catch (Exception portx) { + usageError = true; + } + } else if (args[i].equals("-w") && ((i + 1) < args.length)) { + try { + websrvPort = Integer.parseInt(args[++i]); + } catch (Exception portx) { + usageError = true; + } + } else if (args[i].equals("-jk") && ((i + 1) < args.length)) { + try { + ajp13Port = Integer.parseInt(args[++i]); + } catch (Exception portx) { + usageError = true; + } + } else if (args[i].equals("-i") && ((i + 1) < args.length)) { + // eat away the -i parameter which is meant for helma.main.launcher.Main + i++; + } else { + System.err.println("Unknown command line token: " + args[i]); + usageError = true; + } + } + + // get main property file from home dir or vice versa, depending on what we have. + // get property file from hopHome + if (propfile == null) { + if (homeDir != null) { + propfile = new File(homeDir, "server.properties").getAbsolutePath(); + } else { + propfile = new File("server.properties").getAbsolutePath(); + } + } + + // create system properties + sysProps = new SystemProperties(propfile); + + // check if there's a property setting for those ports not specified via command line + if ((websrvPort == 0) && (sysProps.getProperty("webPort") != null)) { + try { + websrvPort = Integer.parseInt(sysProps.getProperty("webPort")); + } catch (NumberFormatException fmt) { + System.err.println("Error parsing web server port property: " + fmt); + } + } + + if ((ajp13Port == 0) && (sysProps.getProperty("ajp13Port") != null)) { + try { + ajp13Port = Integer.parseInt(sysProps.getProperty("ajp13Port")); + } catch (NumberFormatException fmt) { + System.err.println("Error parsing AJP1.3 server port property: " + fmt); + } + } + + if ((rmiPort == 0) && (sysProps.getProperty("rmiPort") != null)) { + try { + rmiPort = Integer.parseInt(sysProps.getProperty("rmiPort")); + } catch (NumberFormatException fmt) { + System.err.println("Error parsing RMI server port property: " + fmt); + } + } + + if ((xmlrpcPort == 0) && (sysProps.getProperty("xmlrpcPort") != null)) { + try { + xmlrpcPort = Integer.parseInt(sysProps.getProperty("xmlrpcPort")); + } catch (NumberFormatException fmt) { + System.err.println("Error parsing XML-RPC server port property: " + fmt); + } + } + + // check server ports. If no port is set, issue a warning and exit. + if (!usageError && ((websrvPort | ajp13Port | rmiPort | xmlrpcPort) == 0)) { + System.out.println(" Error: No server port specified."); + usageError = true; + } + + // if there's a usage error, output message and exit + if (usageError) { + System.out.println("usage: java helma.main.Server [-h dir] [-f file] [-p port] [-w port] [-x port]"); + System.out.println(" -h dir Specify hop home directory"); + System.out.println(" -f file Specify server.properties file"); + System.out.println(" -p port Specify RMI port number"); + System.out.println(" -w port Specify port number for embedded Web server"); + System.out.println(" -x port Specify XML-RPC port number"); + System.out.println(" -jk port Specify AJP13 port number"); + System.err.println("Usage Error - exiting"); + System.exit(0); + } + + // check if any of the specified server ports is in use already + try { + if (websrvPort > 0) { + checkRunning(websrvPort); + } + + if (rmiPort > 0) { + checkRunning(rmiPort); + } + + if (xmlrpcPort > 0) { + checkRunning(xmlrpcPort); + } + + if (ajp13Port > 0) { + checkRunning(ajp13Port); + } + } catch (Exception running) { + System.out.println(running.getMessage()); + System.exit(1); + } + + // get hopHome from property file + if (homeDir == null) { + homeDir = sysProps.getProperty("hophome"); + } + + if (homeDir == null) { + homeDir = new File(propfile).getParent(); + } + + // create hopHome File object + hopHome = new File(homeDir); + + // try to transform hopHome directory to its cononical representation + try { + hopHome = hopHome.getCanonicalFile(); + } catch (IOException iox) { + System.err.println("Error calling getCanonicalFile() on hopHome: " + iox); + } + + // set the current working directory to the helma home dir. + // note that this is not a real cwd, which is not supported + // by java. It makes sure relative to absolute path name + // conversion is done right, so for Helma code, this should + // work. + System.setProperty("user.dir", hopHome.getPath()); + + // from now on it's safe to call getLogger() because hopHome is set up + String startMessage = "Starting Helma " + version + " on Java " + + System.getProperty("java.version"); + + getLogger().log(startMessage); + + // also print a msg to System.out + System.out.println(startMessage); + + getLogger().log("propfile = " + propfile); + getLogger().log("hopHome = " + hopHome); + + File helper = new File(hopHome, "db.properties"); + + dbPropfile = helper.getAbsolutePath(); + dbProps = new SystemProperties(dbPropfile); + DbSource.setDefaultProps(dbProps); + getLogger().log("dbPropfile = " + dbPropfile); + + appsPropfile = sysProps.getProperty("appsPropFile"); + + if ((appsPropfile != null) && !"".equals(appsPropfile.trim())) { + helper = new File(appsPropfile); + } else { + helper = new File(hopHome, "apps.properties"); + } + + appsPropfile = helper.getAbsolutePath(); + appsProps = new SystemProperties(appsPropfile); + getLogger().log("appsPropfile = " + appsPropfile); + + paranoid = "true".equalsIgnoreCase(sysProps.getProperty("paranoid")); + + String language = sysProps.getProperty("language"); + String country = sysProps.getProperty("country"); + String timezone = sysProps.getProperty("timezone"); + + if ((language != null) && (country != null)) { + Locale.setDefault(new Locale(language, country)); + } + + if (timezone != null) { + TimeZone.setDefault(TimeZone.getTimeZone(timezone)); + } + + getLogger().log("Locale = " + Locale.getDefault()); + getLogger().log("TimeZone = " + + TimeZone.getDefault().getDisplayName(Locale.getDefault())); + + dbSources = new Hashtable(); + + // try to load the extensions + extensions = new Vector(); + + if (sysProps.getProperty("extensions") != null) { + StringTokenizer tok = new StringTokenizer(sysProps.getProperty("extensions"), + ","); + + while (tok.hasMoreTokens()) { + String extClassName = tok.nextToken().trim(); + + try { + Class extClass = Class.forName(extClassName); + HelmaExtension ext = (HelmaExtension) extClass.newInstance(); + + ext.init(this); + extensions.add(ext); + getLogger().log("loaded: " + extClassName); + } catch (Exception e) { + getLogger().log("error: " + extClassName + " (" + e.toString() + + ")"); + } + } + } + } /** * static main entry point. */ - public static void main (String args[]) throws IOException { + public static void main(String[] args) throws IOException { + // check if we are running on a Java 2 VM - otherwise exit with an error message + String javaVersion = System.getProperty("java.version"); - // check if we are running on a Java 2 VM - otherwise exit with an error message - String javaVersion = System.getProperty ("java.version"); - if (javaVersion == null || javaVersion.startsWith ("1.1") || javaVersion.startsWith ("1.0")) { - System.err.println ("This version of Helma requires Java 1.2 or greater."); - if (javaVersion == null) // don't think this will ever happen, but you never know - System.err.println ("Your Java Runtime did not provide a version number. Please update to a more recent version."); - else - System.err.println ("Your Java Runtime is version "+javaVersion+". Please update to a more recent version."); - System.exit (1); - } + if ((javaVersion == null) || javaVersion.startsWith("1.1") || + javaVersion.startsWith("1.0")) { + System.err.println("This version of Helma requires Java 1.2 or greater."); - // create new server instance - server = new Server (args); + if (javaVersion == null) { // don't think this will ever happen, but you never know + System.err.println("Your Java Runtime did not provide a version number. Please update to a more recent version."); + } else { + System.err.println("Your Java Runtime is version " + javaVersion + + ". Please update to a more recent version."); + } - // start the server main thread - server.start (); + System.exit(1); + } + + // create new server instance + server = new Server(args); + + // start the server main thread + server.start(); } - /** - * Constructs a new Server instance with an array of command line options. - */ - public Server (String[] args) { - - starttime = System.currentTimeMillis(); - String homeDir = null; - - boolean usageError = false; - - // file names of various property files - String propfile = null; - String dbPropfile = "db.properties"; - String appsPropfile = null; - - // parse arguments - for (int i=0; i<args.length; i++) { - if (args[i].equals ("-h") && i+1<args.length) - homeDir = args[++i]; - else if (args[i].equals ("-f") && i+1<args.length) - propfile = args[++i]; - else if (args[i].equals ("-p") && i+1<args.length) { - try { - rmiPort = Integer.parseInt (args[++i]); - } catch (Exception portx) { - usageError = true; - } - } else if (args[i].equals ("-x") && i+1<args.length) { - try { - xmlrpcPort = Integer.parseInt (args[++i]); - } catch (Exception portx) { - usageError = true; - } - } else if (args[i].equals ("-w") && i+1<args.length) { - try { - websrvPort = Integer.parseInt (args[++i]); - } catch (Exception portx) { - usageError = true; - } - } else if (args[i].equals ("-jk") && i+1<args.length) { - try { - ajp13Port = Integer.parseInt (args[++i]); - } catch (Exception portx) { - usageError = true; - } - } else if (args[i].equals ("-i") && i+1<args.length) { - // eat away the -i parameter which is meant for helma.main.launcher.Main - i++; - } else { - System.err.println ("Unknown command line token: "+args[i]); - usageError = true; - } - } - - // get main property file from home dir or vice versa, depending on what we have. - // get property file from hopHome - if (propfile == null) { - if (homeDir != null) - propfile = new File (homeDir, "server.properties").getAbsolutePath (); - else - propfile = new File ("server.properties").getAbsolutePath (); - } - // create system properties - sysProps = new SystemProperties (propfile); - - // check if there's a property setting for those ports not specified via command line - if (websrvPort == 0 && sysProps.getProperty ("webPort") != null) try { - websrvPort = Integer.parseInt (sysProps.getProperty ("webPort")); - } catch (NumberFormatException fmt) { - System.err.println ("Error parsing web server port property: "+fmt); - } - if (ajp13Port == 0 && sysProps.getProperty ("ajp13Port") != null) try { - ajp13Port = Integer.parseInt (sysProps.getProperty ("ajp13Port")); - } catch (NumberFormatException fmt) { - System.err.println ("Error parsing AJP1.3 server port property: "+fmt); - } - if (rmiPort == 0 && sysProps.getProperty ("rmiPort") != null) try { - rmiPort = Integer.parseInt (sysProps.getProperty ("rmiPort")); - } catch (NumberFormatException fmt) { - System.err.println ("Error parsing RMI server port property: "+fmt); - } - if (xmlrpcPort == 0 && sysProps.getProperty ("xmlrpcPort") != null) try { - xmlrpcPort = Integer.parseInt (sysProps.getProperty ("xmlrpcPort")); - } catch (NumberFormatException fmt) { - System.err.println ("Error parsing XML-RPC server port property: "+fmt); - } - - // check server ports. If no port is set, issue a warning and exit. - if (!usageError && (websrvPort | ajp13Port | rmiPort | xmlrpcPort) == 0) { - System.out.println (" Error: No server port specified."); - usageError = true; - } - - // if there's a usage error, output message and exit - if (usageError ) { - System.out.println ("usage: java helma.main.Server [-h dir] [-f file] [-p port] [-w port] [-x port]"); - System.out.println (" -h dir Specify hop home directory"); - System.out.println (" -f file Specify server.properties file"); - System.out.println (" -p port Specify RMI port number"); - System.out.println (" -w port Specify port number for embedded Web server"); - System.out.println (" -x port Specify XML-RPC port number"); - System.out.println (" -jk port Specify AJP13 port number"); - System.err.println ("Usage Error - exiting"); - System.exit (0); - } - - // check if any of the specified server ports is in use already - try { - if (websrvPort > 0) - checkRunning (websrvPort); - if (rmiPort > 0) - checkRunning (rmiPort); - if (xmlrpcPort > 0) - checkRunning (xmlrpcPort); - if (ajp13Port > 0) - checkRunning (ajp13Port); - } catch (Exception running) { - System.out.println (running.getMessage ()); - System.exit (1); - } - - // get hopHome from property file - if (homeDir == null) - homeDir = sysProps.getProperty ("hophome"); - if (homeDir == null) - homeDir = new File (propfile).getParent (); - - // create hopHome File object - hopHome = new File (homeDir); - // try to transform hopHome directory to its cononical representation - try { - hopHome = hopHome.getCanonicalFile (); - } catch (IOException iox) { - System.err.println ("Error calling getCanonicalFile() on hopHome: "+iox); - } - - // set the current working directory to the helma home dir. - // note that this is not a real cwd, which is not supported - // by java. It makes sure relative to absolute path name - // conversion is done right, so for Helma code, this should - // work. - System.setProperty ("user.dir", hopHome.getPath()); - - // from now on it's safe to call getLogger() because hopHome is set up - - String startMessage = "Starting Helma "+version+ - " on Java "+System.getProperty ("java.version"); - getLogger().log (startMessage); - // also print a msg to System.out - System.out.println (startMessage); - - getLogger().log ("propfile = "+propfile); - getLogger().log ("hopHome = "+hopHome); - - - File helper = new File (hopHome, "db.properties"); - dbPropfile = helper.getAbsolutePath (); - dbProps = new SystemProperties (dbPropfile); - DbSource.setDefaultProps (dbProps); - getLogger().log ("dbPropfile = "+dbPropfile); - - appsPropfile = sysProps.getProperty ("appsPropFile"); - if (appsPropfile != null && !"".equals (appsPropfile.trim())) - helper = new File (appsPropfile); - else - helper = new File (hopHome, "apps.properties"); - appsPropfile = helper.getAbsolutePath (); - appsProps = new SystemProperties (appsPropfile); - getLogger().log ("appsPropfile = "+appsPropfile); - - paranoid = "true".equalsIgnoreCase (sysProps.getProperty ("paranoid")); - - String language = sysProps.getProperty ("language"); - String country = sysProps.getProperty ("country"); - String timezone = sysProps.getProperty ("timezone"); - - if (language != null && country != null) - Locale.setDefault (new Locale (language, country)); - if (timezone != null) - TimeZone.setDefault (TimeZone.getTimeZone (timezone)); - - getLogger().log ("Locale = "+Locale.getDefault()); - getLogger().log ("TimeZone = "+TimeZone.getDefault().getDisplayName (Locale.getDefault ())); - - dbSources = new Hashtable (); - - // try to load the extensions - extensions = new Vector (); - if (sysProps.getProperty ("extensions")!=null) { - StringTokenizer tok=new StringTokenizer (sysProps.getProperty ("extensions"),","); - while(tok.hasMoreTokens ()) { - String extClassName = tok.nextToken ().trim (); - try { - Class extClass = Class.forName (extClassName); - HelmaExtension ext = (HelmaExtension) extClass.newInstance (); - ext.init (this); - extensions.add (ext); - getLogger ().log ("loaded: " + extClassName); - } catch (Exception e) { - getLogger ().log ("error: " + extClassName + " (" + e.toString () + ")"); - } - } - } - + protected void start() { + // Start running, finishing setup and then entering a loop to check changes + // in the apps.properties file. + mainThread = new Thread(this); + mainThread.start(); } - protected void start () { - // Start running, finishing setup and then entering a loop to check changes - // in the apps.properties file. - mainThread = new Thread (this); - mainThread.start (); - } - - protected void stop () { - mainThread = null; + protected void stop() { + mainThread = null; } /** @@ -317,271 +364,354 @@ import org.apache.xmlrpc.*; * periodically check for changes in the apps.properties file, shutting down * apps or starting new ones. */ - public void run () { + public void run() { + try { + if ((websrvPort > 0) || (ajp13Port > 0)) { + http = new HttpServer(); - try { + // disable Jetty logging FIXME: seems to be a jetty bug; as soon + // as the logging is disabled, the more is logged + Log.instance().disableLog(); + Log.instance().add(new LogSink() { + public String getOptions() { + return null; + } - if (websrvPort > 0 || ajp13Port > 0) { - http = new HttpServer (); - // disable Jetty logging FIXME: seems to be a jetty bug; as soon - // as the logging is disabled, the more is logged - Log.instance().disableLog (); - Log.instance().add (new LogSink () - { - public String getOptions () { return null; } - public void log (String formattedLog) {} - public void log (String tag, Object msg, Frame frame, long time) {} - public void setOptions (String options) {} - public boolean isStarted () { return true; } - public void start () {} - public void stop () {} - } - ); - } + public void log(String formattedLog) { + } - // start embedded web server if port is specified - if (websrvPort > 0) { - http.addListener (new InetAddrPort (websrvPort)); - } + public void log(String tag, Object msg, Frame frame, long time) { + } - // activate the ajp13-listener - if (ajp13Port > 0) { - // create AJP13Listener - ajp13 = new AJP13Listener(new InetAddrPort (ajp13Port)); - ajp13.setHttpServer(http); - String jkallow = sysProps.getProperty ("allowAJP13"); - // by default the AJP13-connection just accepts requests from 127.0.0.1 - if (jkallow == null) - jkallow = "127.0.0.1"; - StringTokenizer st = new StringTokenizer (jkallow, " ,;"); - String[] jkallowarr = new String [st.countTokens()]; - int cnt = 0; - while (st.hasMoreTokens ()) { - jkallowarr[cnt] = st.nextToken(); - cnt++; - } - ajp13.setRemoteServers(jkallowarr); - getLogger().log ("Starting AJP13-Listener on port "+(ajp13Port)); - } + public void setOptions(String options) { + } - if (xmlrpcPort > 0) { - String xmlparser = sysProps.getProperty ("xmlparser"); - if (xmlparser != null) - XmlRpc.setDriver (xmlparser); + public boolean isStarted() { + return true; + } - xmlrpc = new WebServer (xmlrpcPort); - if (paranoid) { - xmlrpc.setParanoid (true); - String xallow = sysProps.getProperty ("allowXmlRpc"); - if (xallow != null) { - StringTokenizer st = new StringTokenizer (xallow, " ,;"); - while (st.hasMoreTokens ()) - xmlrpc.acceptClient (st.nextToken ()); - } - } - getLogger().log ("Starting XML-RPC server on port "+(xmlrpcPort)); - } + public void start() { + } + public void stop() { + } + }); + } - if (rmiPort > 0) { - if (paranoid) { - HelmaSocketFactory factory = new HelmaSocketFactory (); - String rallow = sysProps.getProperty ("allowWeb"); - if (rallow != null) { - StringTokenizer st = new StringTokenizer (rallow, " ,;"); - while (st.hasMoreTokens ()) - factory.addAddress (st.nextToken ()); - } - RMISocketFactory.setSocketFactory (factory); - } - getLogger().log ("Starting RMI server on port "+rmiPort); - LocateRegistry.createRegistry (rmiPort); - } + // start embedded web server if port is specified + if (websrvPort > 0) { + http.addListener(new InetAddrPort(websrvPort)); + } - // create application manager - appManager = new ApplicationManager (rmiPort, hopHome, appsProps, this); - if (xmlrpc != null) - xmlrpc.addHandler ("$default", appManager); + // activate the ajp13-listener + if (ajp13Port > 0) { + // create AJP13Listener + ajp13 = new AJP13Listener(new InetAddrPort(ajp13Port)); + ajp13.setHttpServer(http); - // add shutdown hook to close running apps and servers on exit - Runtime.getRuntime().addShutdownHook (new HelmaShutdownHook(appManager)); + String jkallow = sysProps.getProperty("allowAJP13"); - } catch (Exception gx) { - getLogger().log ("Error initializing embedded database: "+gx); - gx.printStackTrace (); - return; - } + // by default the AJP13-connection just accepts requests from 127.0.0.1 + if (jkallow == null) { + jkallow = "127.0.0.1"; + } - // set the security manager. - // the default implementation is helma.main.HelmaSecurityManager. - try { - String secManClass = sysProps.getProperty ("securityManager"); - if (secManClass != null) { - SecurityManager secMan = (SecurityManager) Class.forName(secManClass).newInstance (); - System.setSecurityManager (secMan); - getLogger().log ("Setting security manager to "+secManClass); - } - } catch (Exception x) { - getLogger().log ("Error setting security manager: "+x); - } + StringTokenizer st = new StringTokenizer(jkallow, " ,;"); + String[] jkallowarr = new String[st.countTokens()]; + int cnt = 0; - // start applications - appManager.startAll (); + while (st.hasMoreTokens()) { + jkallowarr[cnt] = st.nextToken(); + cnt++; + } - // start embedded web server - if (http != null) try { - http.start (); - } catch (MultiException m) { - getLogger().log ("Error starting embedded web server: "+m); - } + ajp13.setRemoteServers(jkallowarr); + getLogger().log("Starting AJP13-Listener on port " + (ajp13Port)); + } - if (ajp13 != null) try { - ajp13.start (); - } catch (Exception m) { - getLogger().log ("Error starting AJP13 listener: "+m); - } + if (xmlrpcPort > 0) { + String xmlparser = sysProps.getProperty("xmlparser"); - int count = 0; - while (Thread.currentThread () == mainThread) { - try { - mainThread.sleep (3000l); - } catch (InterruptedException ie) {} - try { - appManager.checkForChanges (); - } catch (Exception x) { - getLogger().log ("Caught in app manager loop: "+x); - } - } + if (xmlparser != null) { + XmlRpc.setDriver(xmlparser); + } + + xmlrpc = new WebServer(xmlrpcPort); + + if (paranoid) { + xmlrpc.setParanoid(true); + + String xallow = sysProps.getProperty("allowXmlRpc"); + + if (xallow != null) { + StringTokenizer st = new StringTokenizer(xallow, " ,;"); + + while (st.hasMoreTokens()) + xmlrpc.acceptClient(st.nextToken()); + } + } + + getLogger().log("Starting XML-RPC server on port " + (xmlrpcPort)); + } + + if (rmiPort > 0) { + if (paranoid) { + HelmaSocketFactory factory = new HelmaSocketFactory(); + String rallow = sysProps.getProperty("allowWeb"); + + if (rallow != null) { + StringTokenizer st = new StringTokenizer(rallow, " ,;"); + + while (st.hasMoreTokens()) + factory.addAddress(st.nextToken()); + } + + RMISocketFactory.setSocketFactory(factory); + } + + getLogger().log("Starting RMI server on port " + rmiPort); + LocateRegistry.createRegistry(rmiPort); + } + + // create application manager + appManager = new ApplicationManager(rmiPort, hopHome, appsProps, this); + + if (xmlrpc != null) { + xmlrpc.addHandler("$default", appManager); + } + + // add shutdown hook to close running apps and servers on exit + Runtime.getRuntime().addShutdownHook(new HelmaShutdownHook(appManager)); + } catch (Exception gx) { + getLogger().log("Error initializing embedded database: " + gx); + gx.printStackTrace(); + + return; + } + + // set the security manager. + // the default implementation is helma.main.HelmaSecurityManager. + try { + String secManClass = sysProps.getProperty("securityManager"); + + if (secManClass != null) { + SecurityManager secMan = (SecurityManager) Class.forName(secManClass) + .newInstance(); + + System.setSecurityManager(secMan); + getLogger().log("Setting security manager to " + secManClass); + } + } catch (Exception x) { + getLogger().log("Error setting security manager: " + x); + } + + // start applications + appManager.startAll(); + + // start embedded web server + if (http != null) { + try { + http.start(); + } catch (MultiException m) { + getLogger().log("Error starting embedded web server: " + m); + } + } + + if (ajp13 != null) { + try { + ajp13.start(); + } catch (Exception m) { + getLogger().log("Error starting AJP13 listener: " + m); + } + } + + int count = 0; + + while (Thread.currentThread() == mainThread) { + try { + mainThread.sleep(3000L); + } catch (InterruptedException ie) { + } + + try { + appManager.checkForChanges(); + } catch (Exception x) { + getLogger().log("Caught in app manager loop: " + x); + } + } } /** * Get an Iterator over the applications currently running on this Server. */ - public Object[] getApplications () { - return appManager.getApplications (); + public Object[] getApplications() { + return appManager.getApplications(); } /** * Get an Application by name */ - public Application getApplication(String name) { - return appManager.getApplication(name); + public Application getApplication(String name) { + return appManager.getApplication(name); } /** * Get a logger to use for output in this server. */ - public static Logger getLogger () { - if (logger == null) { - String logDir = sysProps.getProperty ("logdir", "log"); - if ("console".equalsIgnoreCase (logDir)) { - logger = new Logger (System.out); - } else { - File helper = new File (logDir); - if (hopHome != null && !helper.isAbsolute ()) - helper = new File (hopHome, logDir); - logDir = helper.getAbsolutePath (); - logger = Logger.getLogger (logDir, "hop"); - } - } - return logger; + public static Logger getLogger() { + if (logger == null) { + String logDir = sysProps.getProperty("logdir", "log"); + + if ("console".equalsIgnoreCase(logDir)) { + logger = new Logger(System.out); + } else { + File helper = new File(logDir); + + if ((hopHome != null) && !helper.isAbsolute()) { + helper = new File(hopHome, logDir); + } + + logDir = helper.getAbsolutePath(); + logger = Logger.getLogger(logDir, "hop"); + } + } + + return logger; } /** * Get the Home directory of this server. */ - public File getHopHome () { - return hopHome; + public File getHopHome() { + return hopHome; } /** * Get the main Server instance. */ - public static Server getServer() { - return server; + public static Server getServer() { + return server; } /** - * Get the Server's XML-RPC web server. - */ + * Get the Server's XML-RPC web server. + */ public static WebServer getXmlRpcServer() { - return server.xmlrpc; + return server.xmlrpc; } /** * A primitive method to check whether a server is already running on our port. */ - private void checkRunning (int portNumber) throws Exception { - try { - java.net.Socket socket = new java.net.Socket ("localhost", portNumber); - } catch (Exception x) { - return; - } - // if we got so far, another server is already running on this port and db - throw new Exception ("Error: Server already running on this port: " + portNumber); + private void checkRunning(int portNumber) throws Exception { + try { + java.net.Socket socket = new java.net.Socket("localhost", portNumber); + } catch (Exception x) { + return; + } + + // if we got so far, another server is already running on this port and db + throw new Exception("Error: Server already running on this port: " + portNumber); } - public String getProperty( String key ) { - return (String)sysProps.get(key); - } + /** + * + * + * @param key ... + * + * @return ... + */ + public String getProperty(String key) { + return (String) sysProps.get(key); + } - public SystemProperties getProperties() { - return sysProps; - } - - public SystemProperties getDbProperties() { - return dbProps; - } + /** + * + * + * @return ... + */ + public SystemProperties getProperties() { + return sysProps; + } - public File getAppsHome() { - String appHome = sysProps.getProperty ("appHome"); - if (appHome != null && !"".equals (appHome.trim())) - return new File (appHome); - else - return new File (hopHome, "apps"); - } + /** + * + * + * @return ... + */ + public SystemProperties getDbProperties() { + return dbProps; + } - public Vector getExtensions () { - return extensions; - } + /** + * + * + * @return ... + */ + public File getAppsHome() { + String appHome = sysProps.getProperty("appHome"); - public void startApplication(String name) { - appManager.start (name); - appManager.register (name); - } + if ((appHome != null) && !"".equals(appHome.trim())) { + return new File(appHome); + } else { + return new File(hopHome, "apps"); + } + } - public void stopApplication(String name) { - appManager.stop (name); - } + /** + * + * + * @return ... + */ + public Vector getExtensions() { + return extensions; + } - /** - * method from helma.framework.IPathElement - */ - public String getElementName() { - return "root"; - } + /** + * + * + * @param name ... + */ + public void startApplication(String name) { + appManager.start(name); + appManager.register(name); + } - /** - * method from helma.framework.IPathElement, - * returning active applications - */ - public IPathElement getChildElement(String name) { - return appManager.getApplication(name); - } + /** + * + * + * @param name ... + */ + public void stopApplication(String name) { + appManager.stop(name); + } - /** - * method from helma.framework.IPathElement - */ - public IPathElement getParentElement() { - return null; - } + /** + * method from helma.framework.IPathElement + */ + public String getElementName() { + return "root"; + } - /** - * method from helma.framework.IPathElement - */ - public String getPrototype() { - return "root"; - } - + /** + * method from helma.framework.IPathElement, + * returning active applications + */ + public IPathElement getChildElement(String name) { + return appManager.getApplication(name); + } + + /** + * method from helma.framework.IPathElement + */ + public IPathElement getParentElement() { + return null; + } + + /** + * method from helma.framework.IPathElement + */ + public String getPrototype() { + return "root"; + } } - diff --git a/src/helma/main/launcher/FilteredClassLoader.java b/src/helma/main/launcher/FilteredClassLoader.java index 07802996..4e2ceef4 100644 --- a/src/helma/main/launcher/FilteredClassLoader.java +++ b/src/helma/main/launcher/FilteredClassLoader.java @@ -1,36 +1,51 @@ -// FilteredClassLoader.java +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.main.launcher; import java.net.URL; import java.net.URLClassLoader; -import java.util.Hashtable; +import java.security.CodeSource; import java.security.PermissionCollection; import java.security.Permissions; import java.security.Policy; -import java.security.CodeSource; +import java.util.Hashtable; /** * ClassLoader that is able to exclude certain packages from loading. */ public class FilteredClassLoader extends URLClassLoader { - - /** - * Create a server wide class loader that doesn't see the scripting engine(s) - * embedded in helma.jar. These files should be loaded by the per-application - * class loaders so that special security policies can be applied to them and - * so that they can load classes from jar files in the app directories. - */ + /** + * Create a server wide class loader that doesn't see the scripting engine(s) + * embedded in helma.jar. These files should be loaded by the per-application + * class loaders so that special security policies can be applied to them and + * so that they can load classes from jar files in the app directories. + */ public FilteredClassLoader(URL[] urls) { - super (urls); + super(urls); } /** * Mask classes that implement the scripting engine(s) contained in helma.jar */ - protected Class findClass (String name) throws ClassNotFoundException { - if (name != null && "helma.scripting.fesi.PhantomEngine".equals (name)) - throw new ClassNotFoundException (name); - return super.findClass (name); + protected Class findClass(String name) throws ClassNotFoundException { + if ((name != null) && "helma.scripting.fesi.PhantomEngine".equals(name)) { + throw new ClassNotFoundException(name); + } + + return super.findClass(name); } } diff --git a/src/helma/main/launcher/Main.java b/src/helma/main/launcher/Main.java index e09f94f9..256f129b 100644 --- a/src/helma/main/launcher/Main.java +++ b/src/helma/main/launcher/Main.java @@ -1,114 +1,145 @@ -// helma.main.Main +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.main.launcher; -import java.net.URLClassLoader; -import java.net.URL; -import java.net.URLDecoder; import java.io.File; import java.io.FilenameFilter; import java.lang.reflect.Method; -import java.util.ArrayList; +import java.net.URL; +import java.net.URLClassLoader; +import java.net.URLDecoder; import java.security.Policy; +import java.util.ArrayList; -/** - * Helma bootstrap class. Figures out Helma home directory, sets up class path and +/** + * Helma bootstrap class. Figures out Helma home directory, sets up class path and * lauchnes main class. */ public class Main { - public static final String[] jars = { - "helma.jar", - "jetty.jar", - "crimson.jar", - "xmlrpc.jar", - "servlet.jar", - "regexp.jar", - "mail.jar", - "activation.jar", - "netcomponents.jar", - "jimi.jar", - "apache-dom.jar", - "jdom.jar" - }; + "helma.jar", "jetty.jar", "crimson.jar", + "xmlrpc.jar", "servlet.jar", "regexp.jar", + "mail.jar", "activation.jar", + "netcomponents.jar", "jimi.jar", + "apache-dom.jar", "jdom.jar" + }; + /** + * + * + * @param args ... + * + * @throws Exception ... + */ + public static void main(String[] args) throws Exception { + // check if home directory is set via command line arg. If not, + // we'll get it from the location of the jar file this class + // has been loaded from. + String installDir = null; - public static void main (String[] args) throws Exception { + // first, try to get helma home dir from command line options + for (int i = 0; i < args.length; i++) { + if (args[i].equals("-i") && ((i + 1) < args.length)) { + installDir = args[i + 1]; + } + } - // check if home directory is set via command line arg. If not, - // we'll get it from the location of the jar file this class - // has been loaded from. - String installDir = null; - // first, try to get helma home dir from command line options - for (int i=0; i<args.length; i++) { - if (args[i].equals ("-i") && i+1<args.length) { - installDir = args[i+1]; - } - } - URLClassLoader apploader = (URLClassLoader) ClassLoader.getSystemClassLoader(); - // try to get Helma installation directory - if (installDir == null) { - try { - URL launcherUrl = apploader.findResource("helma/main/launcher/Main.class"); - // this is a JAR URL of the form - // jar:<url>!/{entry} - // we strip away the jar: prefix and the !/{entry} suffix - // to get the original jar file URL - installDir = launcherUrl.toString().substring(4); - int excl = installDir.indexOf ("!"); - if (excl > -1) { - installDir = installDir.substring(0, excl); - launcherUrl = new URL (installDir); - File f = new File (launcherUrl.getPath()); - installDir = f.getParentFile().getCanonicalPath(); - } - } catch (Exception x) { - // unable to get Helma installation dir from launcher jar - System.err.println ("Unable to get Helma installation directory: "+x); - System.exit (2); - } - } + URLClassLoader apploader = (URLClassLoader) ClassLoader.getSystemClassLoader(); - // decode installDir in case it is URL-encoded - installDir = URLDecoder.decode (installDir); + // try to get Helma installation directory + if (installDir == null) { + try { + URL launcherUrl = apploader.findResource("helma/main/launcher/Main.class"); - // set up the class path - File libdir = new File (installDir, "lib"); - ArrayList jarlist = new ArrayList (); - for (int i=0;i<jars.length;i++) { - File jar = new File (libdir, jars[i]); - jarlist.add (new URL ("file:" + jar.getAbsolutePath())); - } - // add all jar files from the lib/ext directory - File extdir =new File (libdir, "ext"); - File[] files = extdir.listFiles (new FilenameFilter() { - public boolean accept (File dir, String name) { - String n = name.toLowerCase(); - return n.endsWith (".jar") || n.endsWith (".zip"); - } - }); - if (files != null) - for (int i=0;i<files.length; i++) { - // WORKAROUND: add the files in lib/ext before - // lib/apache-dom.jar, since otherwise putting a full version - // of Xerces in lib/ext would cause a version conflict with the - // xerces classes in lib/apache-dom.jar. Generally, having some pieces - // of Xerces in lib/apache-dom.jar is kind of problematic. - jarlist.add (jars.length-3, new URL ("file:" + files[i].getAbsolutePath())); - System.err.println ("Adding to classpath: "+files[i].getAbsolutePath()); - } - URL[] urls = new URL[jarlist.size()]; - jarlist.toArray (urls); - FilteredClassLoader loader = new FilteredClassLoader (urls); - // set the new class loader as context class loader - Thread.currentThread().setContextClassLoader (loader); - // get the main server class - Class clazz = loader.loadClass ("helma.main.Server"); - Class[] cargs = new Class[] { args.getClass() }; - Method main = clazz.getMethod ("main", cargs); - Object[] nargs = new Object[] { args }; - // run - main.invoke (null, nargs); + // this is a JAR URL of the form + // jar:<url>!/{entry} + // we strip away the jar: prefix and the !/{entry} suffix + // to get the original jar file URL + installDir = launcherUrl.toString().substring(4); + + int excl = installDir.indexOf("!"); + + if (excl > -1) { + installDir = installDir.substring(0, excl); + launcherUrl = new URL(installDir); + + File f = new File(launcherUrl.getPath()); + + installDir = f.getParentFile().getCanonicalPath(); + } + } catch (Exception x) { + // unable to get Helma installation dir from launcher jar + System.err.println("Unable to get Helma installation directory: " + x); + System.exit(2); + } + } + + // decode installDir in case it is URL-encoded + installDir = URLDecoder.decode(installDir); + + // set up the class path + File libdir = new File(installDir, "lib"); + ArrayList jarlist = new ArrayList(); + + for (int i = 0; i < jars.length; i++) { + File jar = new File(libdir, jars[i]); + + jarlist.add(new URL("file:" + jar.getAbsolutePath())); + } + + // add all jar files from the lib/ext directory + File extdir = new File(libdir, "ext"); + File[] files = extdir.listFiles(new FilenameFilter() { + public boolean accept(File dir, String name) { + String n = name.toLowerCase(); + + return n.endsWith(".jar") || n.endsWith(".zip"); + } + }); + + if (files != null) { + for (int i = 0; i < files.length; i++) { + // WORKAROUND: add the files in lib/ext before + // lib/apache-dom.jar, since otherwise putting a full version + // of Xerces in lib/ext would cause a version conflict with the + // xerces classes in lib/apache-dom.jar. Generally, having some pieces + // of Xerces in lib/apache-dom.jar is kind of problematic. + jarlist.add(jars.length - 3, new URL("file:" + + files[i].getAbsolutePath())); + System.err.println("Adding to classpath: " + files[i].getAbsolutePath()); + } + } + + URL[] urls = new URL[jarlist.size()]; + + jarlist.toArray(urls); + + FilteredClassLoader loader = new FilteredClassLoader(urls); + + // set the new class loader as context class loader + Thread.currentThread().setContextClassLoader(loader); + + // get the main server class + Class clazz = loader.loadClass("helma.main.Server"); + Class[] cargs = new Class[] { args.getClass() }; + Method main = clazz.getMethod("main", cargs); + Object[] nargs = new Object[] { args }; + + // run + main.invoke(null, nargs); } - } diff --git a/src/helma/objectmodel/ConcurrencyException.java b/src/helma/objectmodel/ConcurrencyException.java index f6684b5d..d495e9c2 100644 --- a/src/helma/objectmodel/ConcurrencyException.java +++ b/src/helma/objectmodel/ConcurrencyException.java @@ -1,51 +1,33 @@ -// ConcurrencyException.java -// Copyright (c) Hannes Wallnöfer 1998-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel; /** - * Thrown when more than one thrad tries to modify a Node. The evaluator - * will normally catch this and try again after a period of time. + * Thrown when more than one thrad tries to modify a Node. The evaluator + * will normally catch this and try again after a period of time. */ - public class ConcurrencyException extends RuntimeException { - - public ConcurrencyException (String msg) { - super (msg); + /** + * Creates a new ConcurrencyException object. + * + * @param msg ... + */ + public ConcurrencyException(String msg) { + super(msg); } - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/helma/objectmodel/DatabaseException.java b/src/helma/objectmodel/DatabaseException.java index dbd794a3..1dfe2396 100644 --- a/src/helma/objectmodel/DatabaseException.java +++ b/src/helma/objectmodel/DatabaseException.java @@ -1,49 +1,32 @@ -// DatabaseException.java - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel; /** * Thrown on any kind of Database-Error */ - public class DatabaseException extends RuntimeException { - - public DatabaseException (String msg) { - super (msg); + /** + * Creates a new DatabaseException object. + * + * @param msg ... + */ + public DatabaseException(String msg) { + super(msg); } - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/helma/objectmodel/IDatabase.java b/src/helma/objectmodel/IDatabase.java index 2618d621..a9a7e2da 100644 --- a/src/helma/objectmodel/IDatabase.java +++ b/src/helma/objectmodel/IDatabase.java @@ -1,35 +1,108 @@ -// IDatabase.java +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.objectmodel; -import helma.objectmodel.db.IDGenerator; import helma.objectmodel.INode; +import helma.objectmodel.db.IDGenerator; +import java.io.IOException; +import org.xml.sax.SAXException; +import javax.xml.parsers.ParserConfigurationException; /** * Interface that is implemented by Database wrappers */ - public interface IDatabase { + // db-related + public void shutdown(); - // db-related - public void shutdown (); + // id-related + public String nextID() throws ObjectNotFoundException; - // id-related - public String nextID() throws ObjectNotFoundException; - public IDGenerator getIDGenerator (ITransaction transaction) throws Exception; - public void saveIDGenerator (ITransaction transaction, IDGenerator idgen) throws Exception; + /** + * + * + * @param transaction ... + * + * @return ... + * + * @throws IOException ... + */ + public IDGenerator getIDGenerator(ITransaction transaction) + throws IOException, ObjectNotFoundException; - // node-related - public INode getNode (ITransaction transaction, String key) throws Exception; - public void saveNode (ITransaction transaction, String key, INode node) throws Exception; - public void deleteNode (ITransaction transaction, String key) throws Exception; + /** + * + * + * @param transaction ... + * @param idgen ... + * + * @throws IOException ... + */ + public void saveIDGenerator(ITransaction transaction, IDGenerator idgen) + throws IOException; - // transaction-related - public ITransaction beginTransaction (); - public void commitTransaction (ITransaction transaction) throws DatabaseException; - public void abortTransaction (ITransaction transaction) throws DatabaseException; + // node-related + public INode getNode(ITransaction transaction, String key) + throws IOException, ObjectNotFoundException, + SAXException, ParserConfigurationException; + /** + * + * + * @param transaction ... + * @param key ... + * @param node ... + * + * @throws IOException ... + */ + public void saveNode(ITransaction transaction, String key, INode node) + throws IOException; + + /** + * + * + * @param transaction ... + * @param key ... + * + * @throws IOException ... + */ + public void deleteNode(ITransaction transaction, String key) + throws IOException; + + // transaction-related + public ITransaction beginTransaction(); + + /** + * + * + * @param transaction ... + * + * @throws DatabaseException ... + */ + public void commitTransaction(ITransaction transaction) + throws DatabaseException; + + /** + * + * + * @param transaction ... + * + * @throws DatabaseException ... + */ + public void abortTransaction(ITransaction transaction) + throws DatabaseException; } - - - diff --git a/src/helma/objectmodel/INode.java b/src/helma/objectmodel/INode.java index 4bab60c2..d03cb6bd 100644 --- a/src/helma/objectmodel/INode.java +++ b/src/helma/objectmodel/INode.java @@ -1,88 +1,391 @@ -// INode.java -// Copyright (c) Hannes Wallnöfer 1998-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel; -import java.util.*; -import java.io.*; import helma.framework.IPathElement; import helma.objectmodel.db.DbMapping; +import java.io.*; +import java.util.*; /** * Interface that all Nodes implement. Currently, there are two implementations: * Transient nodes which only exist in memory, and persistent Nodes, which are * stored in a database (either the internal Object DB or an external relational DB). */ - public interface INode extends INodeState, IPathElement { - - - /** + /** * id-related methods */ + public String getID(); - public String getID (); - public String getName (); - public void setDbMapping (DbMapping dbmap); - public DbMapping getDbMapping (); - public int getState (); - public void setState (int s); - public void setName (String name); - public long lastModified (); - public long created (); - public boolean isAnonymous (); // is this a named node, or an anonymous node in a collection? - public String getPrototype (); - public void setPrototype (String prototype); - public INode getCacheNode (); - public void clearCacheNode (); - public String getFullName (); - public String getFullName (INode root); + /** + * + * + * @return ... + */ + public String getName(); + + /** + * + * + * @param dbmap ... + */ + public void setDbMapping(DbMapping dbmap); + + /** + * + * + * @return ... + */ + public DbMapping getDbMapping(); + + /** + * + * + * @return ... + */ + public int getState(); + + /** + * + * + * @param s ... + */ + public void setState(int s); + + /** + * + * + * @param name ... + */ + public void setName(String name); + + /** + * + * + * @return ... + */ + public long lastModified(); + + /** + * + * + * @return ... + */ + public long created(); + + /** + * + * + * @return ... + */ + public boolean isAnonymous(); // is this a named node, or an anonymous node in a collection? + + /** + * + * + * @return ... + */ + public String getPrototype(); + + /** + * + * + * @param prototype ... + */ + public void setPrototype(String prototype); + + /** + * + * + * @return ... + */ + public INode getCacheNode(); + + /** + * + */ + public void clearCacheNode(); + + /** + * + * + * @return ... + */ + public String getFullName(); + + /** + * + * + * @param root ... + * + * @return ... + */ + public String getFullName(INode root); /** * node-related methods */ + public INode getParent(); - public INode getParent (); - public void setSubnodeRelation (String rel); - public String getSubnodeRelation (); - public int numberOfNodes (); - public INode addNode (INode node); - public INode addNode (INode node, int where); - public INode createNode (String name); - public INode createNode (String name, int where); - public Enumeration getSubnodes (); - public INode getSubnode (String name); - public INode getSubnodeAt (int index); - public int contains (INode node); - public boolean remove (); - public void removeNode (INode node); + /** + * + * + * @param rel ... + */ + public void setSubnodeRelation(String rel); + + /** + * + * + * @return ... + */ + public String getSubnodeRelation(); + + /** + * + * + * @return ... + */ + public int numberOfNodes(); + + /** + * + * + * @param node ... + * + * @return ... + */ + public INode addNode(INode node); + + /** + * + * + * @param node ... + * @param where ... + * + * @return ... + */ + public INode addNode(INode node, int where); + + /** + * + * + * @param name ... + * + * @return ... + */ + public INode createNode(String name); + + /** + * + * + * @param name ... + * @param where ... + * + * @return ... + */ + public INode createNode(String name, int where); + + /** + * + * + * @return ... + */ + public Enumeration getSubnodes(); + + /** + * + * + * @param name ... + * + * @return ... + */ + public INode getSubnode(String name); + + /** + * + * + * @param index ... + * + * @return ... + */ + public INode getSubnodeAt(int index); + + /** + * + * + * @param node ... + * + * @return ... + */ + public int contains(INode node); + + /** + * + * + * @return ... + */ + public boolean remove(); + + /** + * + * + * @param node ... + */ + public void removeNode(INode node); /** * property-related methods */ + public Enumeration properties(); - public Enumeration properties (); - public IProperty get (String name); - public String getString (String name); - public boolean getBoolean (String name); - public Date getDate (String name); - public long getInteger (String name); - public double getFloat (String name); - public INode getNode (String name); - public Object getJavaObject (String name); + /** + * + * + * @param name ... + * + * @return ... + */ + public IProperty get(String name); - public void setString (String name, String value); - public void setBoolean (String name, boolean value); - public void setDate (String name, Date value); - public void setInteger (String name, long value); - public void setFloat (String name, double value); - public void setNode (String name, INode value); - public void setJavaObject (String name, Object value); + /** + * + * + * @param name ... + * + * @return ... + */ + public String getString(String name); - public void unset (String name); + /** + * + * + * @param name ... + * + * @return ... + */ + public boolean getBoolean(String name); + /** + * + * + * @param name ... + * + * @return ... + */ + public Date getDate(String name); + + /** + * + * + * @param name ... + * + * @return ... + */ + public long getInteger(String name); + + /** + * + * + * @param name ... + * + * @return ... + */ + public double getFloat(String name); + + /** + * + * + * @param name ... + * + * @return ... + */ + public INode getNode(String name); + + /** + * + * + * @param name ... + * + * @return ... + */ + public Object getJavaObject(String name); + + /** + * + * + * @param name ... + * @param value ... + */ + public void setString(String name, String value); + + /** + * + * + * @param name ... + * @param value ... + */ + public void setBoolean(String name, boolean value); + + /** + * + * + * @param name ... + * @param value ... + */ + public void setDate(String name, Date value); + + /** + * + * + * @param name ... + * @param value ... + */ + public void setInteger(String name, long value); + + /** + * + * + * @param name ... + * @param value ... + */ + public void setFloat(String name, double value); + + /** + * + * + * @param name ... + * @param value ... + */ + public void setNode(String name, INode value); + + /** + * + * + * @param name ... + * @param value ... + */ + public void setJavaObject(String name, Object value); + + /** + * + * + * @param name ... + */ + public void unset(String name); } - - - - diff --git a/src/helma/objectmodel/INodeState.java b/src/helma/objectmodel/INodeState.java index 71d29773..df91a6a6 100644 --- a/src/helma/objectmodel/INodeState.java +++ b/src/helma/objectmodel/INodeState.java @@ -1,17 +1,28 @@ -// INodeState.java -// Copyright (c) Hannes Wallnöfer 2001 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel; -import java.util.*; import java.io.*; +import java.util.*; /** * Interface that defines states of nodes */ - public interface INodeState { - public final static int TRANSIENT = -3; public final static int VIRTUAL = -2; public final static int INVALID = -1; @@ -19,9 +30,4 @@ public interface INodeState { public final static int NEW = 1; public final static int MODIFIED = 2; public final static int DELETED = 3; - } - - - - diff --git a/src/helma/objectmodel/IProperty.java b/src/helma/objectmodel/IProperty.java index 3016fac5..95198079 100644 --- a/src/helma/objectmodel/IProperty.java +++ b/src/helma/objectmodel/IProperty.java @@ -1,5 +1,18 @@ -// IProperty.java -// Copyright (c) Hannes Wallnöfer 1997-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.objectmodel; @@ -8,9 +21,7 @@ import java.util.Date; /** * Interface that is implemented by node properties. */ - public interface IProperty { - public static final int STRING = 1; public static final int BOOLEAN = 2; public static final int DATE = 3; @@ -19,16 +30,73 @@ public interface IProperty { public static final int NODE = 6; public static final int JAVAOBJECT = 7; - public String getName (); - public int getType (); - public Object getValue (); + /** + * + * + * @return ... + */ + public String getName(); - public INode getNodeValue (); - public String getStringValue (); - public boolean getBooleanValue (); - public long getIntegerValue (); - public double getFloatValue (); - public Date getDateValue (); - public Object getJavaObjectValue (); + /** + * + * + * @return ... + */ + public int getType(); - } \ No newline at end of file + /** + * + * + * @return ... + */ + public Object getValue(); + + /** + * + * + * @return ... + */ + public INode getNodeValue(); + + /** + * + * + * @return ... + */ + public String getStringValue(); + + /** + * + * + * @return ... + */ + public boolean getBooleanValue(); + + /** + * + * + * @return ... + */ + public long getIntegerValue(); + + /** + * + * + * @return ... + */ + public double getFloatValue(); + + /** + * + * + * @return ... + */ + public Date getDateValue(); + + /** + * + * + * @return ... + */ + public Object getJavaObjectValue(); +} diff --git a/src/helma/objectmodel/ITransaction.java b/src/helma/objectmodel/ITransaction.java index 1d617a9f..6455926d 100644 --- a/src/helma/objectmodel/ITransaction.java +++ b/src/helma/objectmodel/ITransaction.java @@ -1,18 +1,27 @@ -// ITransaction.java - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel; + /** - * This interface is kept for databases that are able - * to run transactions. Transactions were used for the - * Berkeley database and might be used in other future - * databases, so we leave transactions in. - */ - + * This interface is kept for databases that are able + * to run transactions. Transactions were used for the + * Berkeley database and might be used in other future + * databases, so we leave transactions in. + */ public interface ITransaction { - } - - - - diff --git a/src/helma/objectmodel/NodeEvent.java b/src/helma/objectmodel/NodeEvent.java index b62bea67..d4e3f5a2 100644 --- a/src/helma/objectmodel/NodeEvent.java +++ b/src/helma/objectmodel/NodeEvent.java @@ -1,59 +1,92 @@ -// NodeEvent.java -// Copyright (c) Hannes Wallnöfer 1998-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.objectmodel; import java.io.*; -/** +/** * This is passed to NodeListeners when a node is modified. */ - public class NodeEvent implements Serializable { - public static final int CONTENT_CHANGED = 0; public static final int PROPERTIES_CHANGED = 1; public static final int NODE_REMOVED = 2; public static final int NODE_RENAMED = 3; public static final int SUBNODE_ADDED = 4; public static final int SUBNODE_REMOVED = 5; - public int type; public String id; public transient INode node; public transient Object arg; - public NodeEvent (INode node, int type) { - super (); - this.node = node; - this.id = node.getID (); - this.type = type; + /** + * Creates a new NodeEvent object. + * + * @param node ... + * @param type ... + */ + public NodeEvent(INode node, int type) { + super(); + this.node = node; + this.id = node.getID(); + this.type = type; } - public NodeEvent (INode node, int type, Object arg) { - super (); - this.node = node; - this.id = node.getID (); - this.type = type; - this.arg = arg; + /** + * Creates a new NodeEvent object. + * + * @param node ... + * @param type ... + * @param arg ... + */ + public NodeEvent(INode node, int type, Object arg) { + super(); + this.node = node; + this.id = node.getID(); + this.type = type; + this.arg = arg; } - public String toString () { - switch (type) { - case CONTENT_CHANGED: - return "NodeEvent: content changed"; - case PROPERTIES_CHANGED: - return "NodeEvent: properties changed"; - case NODE_REMOVED: - return "NodeEvent: node removed"; - case NODE_RENAMED: - return "NodeEvent: node moved"; - case SUBNODE_ADDED: - return "NodeEvent: subnode added"; - case SUBNODE_REMOVED: - return "NodeEvent: subnode removed"; - } - return "NodeEvent: invalid type"; - } + /** + * + * + * @return ... + */ + public String toString() { + switch (type) { + case CONTENT_CHANGED: + return "NodeEvent: content changed"; -} \ No newline at end of file + case PROPERTIES_CHANGED: + return "NodeEvent: properties changed"; + + case NODE_REMOVED: + return "NodeEvent: node removed"; + + case NODE_RENAMED: + return "NodeEvent: node moved"; + + case SUBNODE_ADDED: + return "NodeEvent: subnode added"; + + case SUBNODE_REMOVED: + return "NodeEvent: subnode removed"; + } + + return "NodeEvent: invalid type"; + } +} diff --git a/src/helma/objectmodel/ObjectNotFoundException.java b/src/helma/objectmodel/ObjectNotFoundException.java index e58d19bb..81e44f94 100644 --- a/src/helma/objectmodel/ObjectNotFoundException.java +++ b/src/helma/objectmodel/ObjectNotFoundException.java @@ -1,6 +1,19 @@ -// ObjectNotFoundException.java -// Copyright (c) Hannes Wallnöfer 1998-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel; @@ -8,42 +21,13 @@ package helma.objectmodel; * Thrown when an object could not found in the database where * it was expected. */ - public class ObjectNotFoundException extends Exception { - - public ObjectNotFoundException (String msg) { - super (msg); + /** + * Creates a new ObjectNotFoundException object. + * + * @param msg ... + */ + public ObjectNotFoundException(String msg) { + super(msg); } - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/helma/objectmodel/Property.java b/src/helma/objectmodel/Property.java index 5c8df5c7..3fca8396 100644 --- a/src/helma/objectmodel/Property.java +++ b/src/helma/objectmodel/Property.java @@ -1,195 +1,350 @@ -// Property.java -// Copyright (c) Hannes Wallnöfer 1997-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.objectmodel; import helma.util.*; -import java.util.Vector; -import java.util.Hashtable; -import java.util.Date; -import java.util.Enumeration; import java.io.*; import java.text.*; +import java.util.Date; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; /** - * A property implementation for Nodes stored inside a database. + * A property implementation for Nodes stored inside a database. */ - public final class Property implements IProperty, Serializable { - - protected String propname; protected TransientNode node; - public String svalue; public boolean bvalue; public long lvalue; public double dvalue; public INode nvalue; public Object jvalue; - public int type; - - public Property (TransientNode node) { - this.node = node; + /** + * Creates a new Property object. + * + * @param node ... + */ + public Property(TransientNode node) { + this.node = node; } - public Property (String propname, TransientNode node) { - this.propname = propname; - this.node = node; + /** + * Creates a new Property object. + * + * @param propname ... + * @param node ... + */ + public Property(String propname, TransientNode node) { + this.propname = propname; + this.node = node; } - public String getName () { - return propname; + /** + * + * + * @return ... + */ + public String getName() { + return propname; } - public Object getValue () { - switch (type) { - case STRING: - return svalue; - case BOOLEAN: - return new Boolean (bvalue); - case INTEGER: - return new Long (lvalue); - case FLOAT: - return new Double (dvalue); - case DATE: - return new Date (lvalue); - case NODE: - return nvalue; - case JAVAOBJECT: - return jvalue; - } - return null; + /** + * + * + * @return ... + */ + public Object getValue() { + switch (type) { + case STRING: + return svalue; + + case BOOLEAN: + return new Boolean(bvalue); + + case INTEGER: + return new Long(lvalue); + + case FLOAT: + return new Double(dvalue); + + case DATE: + return new Date(lvalue); + + case NODE: + return nvalue; + + case JAVAOBJECT: + return jvalue; + } + + return null; } - public void setStringValue (String value) { - if (type == NODE) - this.nvalue = null; - if (type == JAVAOBJECT) - this.jvalue = null; - type = STRING; - this.svalue = value; + /** + * + * + * @param value ... + */ + public void setStringValue(String value) { + if (type == NODE) { + this.nvalue = null; + } + + if (type == JAVAOBJECT) { + this.jvalue = null; + } + + type = STRING; + this.svalue = value; } - public void setIntegerValue (long value) { - if (type == NODE) - this.nvalue = null; - if (type == JAVAOBJECT) - this.jvalue = null; - type = INTEGER; - this.lvalue = value; + /** + * + * + * @param value ... + */ + public void setIntegerValue(long value) { + if (type == NODE) { + this.nvalue = null; + } + + if (type == JAVAOBJECT) { + this.jvalue = null; + } + + type = INTEGER; + this.lvalue = value; } - public void setFloatValue (double value) { - if (type == NODE) - this.nvalue = null; - if (type == JAVAOBJECT) - this.jvalue = null; - type = FLOAT; - this.dvalue = value; + /** + * + * + * @param value ... + */ + public void setFloatValue(double value) { + if (type == NODE) { + this.nvalue = null; + } + + if (type == JAVAOBJECT) { + this.jvalue = null; + } + + type = FLOAT; + this.dvalue = value; } - public void setDateValue (Date value) { - if (type == NODE) - this.nvalue = null; - if (type == JAVAOBJECT) - this.jvalue = null; - type = DATE; - this.lvalue = value.getTime(); + /** + * + * + * @param value ... + */ + public void setDateValue(Date value) { + if (type == NODE) { + this.nvalue = null; + } + + if (type == JAVAOBJECT) { + this.jvalue = null; + } + + type = DATE; + this.lvalue = value.getTime(); } - public void setBooleanValue (boolean value) { - if (type == NODE) - this.nvalue = null; - if (type == JAVAOBJECT) - this.jvalue = null; - type = BOOLEAN; - this.bvalue = value; + /** + * + * + * @param value ... + */ + public void setBooleanValue(boolean value) { + if (type == NODE) { + this.nvalue = null; + } + + if (type == JAVAOBJECT) { + this.jvalue = null; + } + + type = BOOLEAN; + this.bvalue = value; } - public void setNodeValue (INode value) { - if (type == JAVAOBJECT) - this.jvalue = null; - type = NODE; - this.nvalue = value; + /** + * + * + * @param value ... + */ + public void setNodeValue(INode value) { + if (type == JAVAOBJECT) { + this.jvalue = null; + } + + type = NODE; + this.nvalue = value; } + /** + * + * + * @param value ... + */ + public void setJavaObjectValue(Object value) { + if (type == NODE) { + this.nvalue = null; + } - public void setJavaObjectValue (Object value) { - if (type == NODE) - this.nvalue = null; - type = JAVAOBJECT; - this.jvalue = value; + type = JAVAOBJECT; + this.jvalue = value; } + /** + * + * + * @return ... + */ + public String getStringValue() { + switch (type) { + case STRING: + return svalue; - public String getStringValue () { - switch (type) { - case STRING: - return svalue; - case BOOLEAN: - return "" + bvalue; - case DATE: - SimpleDateFormat format = new SimpleDateFormat ("dd.MM.yy HH:mm"); - return format.format (new Date (lvalue)); - case INTEGER: - return Long.toString (lvalue); - case FLOAT: - return Double.toString (dvalue); - case NODE: - return nvalue.getName (); - case JAVAOBJECT: - return jvalue == null ? null : jvalue.toString (); - } - return ""; + case BOOLEAN: + return "" + bvalue; + + case DATE: + + SimpleDateFormat format = new SimpleDateFormat("dd.MM.yy HH:mm"); + + return format.format(new Date(lvalue)); + + case INTEGER: + return Long.toString(lvalue); + + case FLOAT: + return Double.toString(dvalue); + + case NODE: + return nvalue.getName(); + + case JAVAOBJECT: + return (jvalue == null) ? null : jvalue.toString(); + } + + return ""; } - public String toString () { - return getStringValue (); + /** + * + * + * @return ... + */ + public String toString() { + return getStringValue(); } - public long getIntegerValue () { - if (type == INTEGER) - return lvalue; - return 0; + /** + * + * + * @return ... + */ + public long getIntegerValue() { + if (type == INTEGER) { + return lvalue; + } + + return 0; } - public double getFloatValue () { - if (type == FLOAT) - return dvalue; - return 0.0; + /** + * + * + * @return ... + */ + public double getFloatValue() { + if (type == FLOAT) { + return dvalue; + } + + return 0.0; } + /** + * + * + * @return ... + */ + public Date getDateValue() { + if (type == DATE) { + return new Date(lvalue); + } - public Date getDateValue () { - if (type == DATE) - return new Date (lvalue); - return null; + return null; } - public boolean getBooleanValue () { - if (type == BOOLEAN) - return bvalue; - return false; + /** + * + * + * @return ... + */ + public boolean getBooleanValue() { + if (type == BOOLEAN) { + return bvalue; + } + + return false; } - public INode getNodeValue () { - if (type == NODE) - return nvalue; - return null; + /** + * + * + * @return ... + */ + public INode getNodeValue() { + if (type == NODE) { + return nvalue; + } + + return null; } - public Object getJavaObjectValue () { - if (type == JAVAOBJECT) - return jvalue; - return null; + /** + * + * + * @return ... + */ + public Object getJavaObjectValue() { + if (type == JAVAOBJECT) { + return jvalue; + } + + return null; } - - public int getType () { - return type; + /** + * + * + * @return ... + */ + public int getType() { + return type; } - } diff --git a/src/helma/objectmodel/TransientNode.java b/src/helma/objectmodel/TransientNode.java index 2c453e0e..6ef62cd1 100644 --- a/src/helma/objectmodel/TransientNode.java +++ b/src/helma/objectmodel/TransientNode.java @@ -1,588 +1,977 @@ -// TransientNode.java -// Copyright (c) Hannes Wallnöfer 1997-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel; - -import java.util.Vector; -import java.util.Hashtable; -import java.util.Enumeration; -import java.util.Date; -import java.util.StringTokenizer; -import java.io.*; -import helma.util.*; import helma.framework.IPathElement; import helma.objectmodel.db.DbMapping; import helma.objectmodel.db.Relation; +import helma.util.*; +import java.io.*; +import java.util.Date; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.StringTokenizer; +import java.util.Vector; /** * A transient implementation of INode. An instance of this class can't be * made persistent by reachability from a persistent node. To make a persistent-capable * object, class helma.objectmodel.db.Node has to be used. */ - public class TransientNode implements INode, Serializable { - - - protected Hashtable propMap, nodeMap; + private static long idgen = 0; + protected Hashtable propMap; + protected Hashtable nodeMap; protected Vector nodes; protected TransientNode parent; - protected Vector links; // links to this node - protected Vector proplinks; // nodes using this node as property - + protected Vector links; // links to this node + protected Vector proplinks; // nodes using this node as property transient String prototype; - protected long created; protected long lastmodified; + protected String id; + protected String name; - protected String id, name; // is the main identity a named property or an anonymous node in a collection? protected boolean anonymous = false; - transient DbMapping dbmap; + INode cacheNode; - private static long idgen = 0; - - public static String generateID () { - // make transient ids differ from persistent ones - // and are unique within on runtime session - return "t"+idgen++; - } - - public TransientNode () { - id = generateID (); - name = id; - created = lastmodified = System.currentTimeMillis (); + /** + * Creates a new TransientNode object. + */ + public TransientNode() { + id = generateID(); + name = id; + created = lastmodified = System.currentTimeMillis(); } /** * Make a new TransientNode object with a given name */ - public TransientNode (String n) { - id = generateID (); - name = n == null || "".equals (n) ? id : n; - created = lastmodified = System.currentTimeMillis (); + public TransientNode(String n) { + id = generateID(); + name = ((n == null) || "".equals(n)) ? id : n; + created = lastmodified = System.currentTimeMillis(); } - - public void setDbMapping (DbMapping dbmap) { - this.dbmap = dbmap; + /** + * + * + * @return ... + */ + public static String generateID() { + // make transient ids differ from persistent ones + // and are unique within on runtime session + return "t" + idgen++; } - public DbMapping getDbMapping () { - return dbmap; + /** + * + * + * @param dbmap ... + */ + public void setDbMapping(DbMapping dbmap) { + this.dbmap = dbmap; } + /** + * + * + * @return ... + */ + public DbMapping getDbMapping() { + return dbmap; + } - /** + /** * navigation-related */ - - public String getID () { - return id; - } - - public boolean isAnonymous () { - return anonymous; - } - - - public String getName () { - return name; - } - - public String getElementName () { - return anonymous ? id : name; + public String getID() { + return id; } - public int getState () { - return TRANSIENT; + /** + * + * + * @return ... + */ + public boolean isAnonymous() { + return anonymous; } - public void setState (int s) { - // state always is TRANSIENT on this kind of node + /** + * + * + * @return ... + */ + public String getName() { + return name; } - public String getFullName () { - return getFullName (null); + /** + * + * + * @return ... + */ + public String getElementName() { + return anonymous ? id : name; } - public String getFullName (INode root) { - String fullname = ""; - String divider = null; - StringBuffer b = new StringBuffer (); - TransientNode p = this; - while (p != null && p.parent != null && p != root) { - if (divider != null) - b.insert (0, divider); - else - divider = "/"; - b.insert (0, p.getElementName ()); - p = p.parent; - } - return b.toString (); + /** + * + * + * @return ... + */ + public int getState() { + return TRANSIENT; } - - public void setName (String name) { - // if (name.indexOf('/') > -1) - // throw new RuntimeException ("The name of the node must not contain \"/\"."); - if (name == null || name.trim().length() == 0) - this.name = id; - else - this.name = name; + /** + * + * + * @param s ... + */ + public void setState(int s) { + // state always is TRANSIENT on this kind of node } - public String getPrototype () { - // if prototype is null, it's a vanilla HopObject. - if (prototype == null) - return "hopobject"; - return prototype; + /** + * + * + * @return ... + */ + public String getFullName() { + return getFullName(null); } - public void setPrototype (String proto) { - this.prototype = proto; + /** + * + * + * @param root ... + * + * @return ... + */ + public String getFullName(INode root) { + String fullname = ""; + String divider = null; + StringBuffer b = new StringBuffer(); + TransientNode p = this; + + while ((p != null) && (p.parent != null) && (p != root)) { + if (divider != null) { + b.insert(0, divider); + } else { + divider = "/"; + } + + b.insert(0, p.getElementName()); + p = p.parent; + } + + return b.toString(); } - - public INode getParent () { - return parent; + /** + * + * + * @param name ... + */ + public void setName(String name) { + // if (name.indexOf('/') > -1) + // throw new RuntimeException ("The name of the node must not contain \"/\"."); + if ((name == null) || (name.trim().length() == 0)) { + this.name = id; + } else { + this.name = name; + } } + /** + * + * + * @return ... + */ + public String getPrototype() { + // if prototype is null, it's a vanilla HopObject. + if (prototype == null) { + return "hopobject"; + } + + return prototype; + } + + /** + * + * + * @param proto ... + */ + public void setPrototype(String proto) { + this.prototype = proto; + } + + /** + * + * + * @return ... + */ + public INode getParent() { + return parent; + } /** * INode-related */ - - public void setSubnodeRelation (String rel) { - throw new RuntimeException ("Can't set subnode relation for non-persistent Node."); + public void setSubnodeRelation(String rel) { + throw new RuntimeException("Can't set subnode relation for non-persistent Node."); } - public String getSubnodeRelation () { - return null; + /** + * + * + * @return ... + */ + public String getSubnodeRelation() { + return null; } - public int numberOfNodes () { - return nodes == null ? 0 : nodes.size (); + /** + * + * + * @return ... + */ + public int numberOfNodes() { + return (nodes == null) ? 0 : nodes.size(); } - public INode addNode (INode elem) { - return addNode (elem, numberOfNodes ()); + /** + * + * + * @param elem ... + * + * @return ... + */ + public INode addNode(INode elem) { + return addNode(elem, numberOfNodes()); } - public INode addNode (INode elem, int where) { + /** + * + * + * @param elem ... + * @param where ... + * + * @return ... + */ + public INode addNode(INode elem, int where) { + if ((where < 0) || (where > numberOfNodes())) { + where = numberOfNodes(); + } - if (where < 0 || where > numberOfNodes ()) - where = numberOfNodes (); + String n = elem.getName(); - String n = elem.getName(); - if (n.indexOf('/') > -1) - throw new RuntimeException ("The name of a node must not contain \"/\" (slash)."); - - // IServer.getLogger().log ("adding: "+node+" -- "+node.getContentLength ()); - if (nodeMap != null && nodeMap.get (elem.getID ()) != null) { - nodes.removeElement (elem); - where = Math.min (where, numberOfNodes ()); - nodes.insertElementAt (elem, where); - return elem; - } + if (n.indexOf('/') > -1) { + throw new RuntimeException("The name of a node must not contain \"/\" (slash)."); + } - if (nodeMap == null) nodeMap = new Hashtable (); - if (nodes == null) nodes = new Vector (); + // IServer.getLogger().log ("adding: "+node+" -- "+node.getContentLength ()); + if ((nodeMap != null) && (nodeMap.get(elem.getID()) != null)) { + nodes.removeElement(elem); + where = Math.min(where, numberOfNodes()); + nodes.insertElementAt(elem, where); - nodeMap.put (elem.getID (), elem); - nodes.insertElementAt (elem, where); + return elem; + } - if (elem instanceof TransientNode) { - TransientNode node = (TransientNode) elem; - if (node.parent == null) { - node.parent = this; - node.anonymous = true; - } - } - - lastmodified = System.currentTimeMillis (); - // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.SUBNODE_ADDED, node)); - return elem; + if (nodeMap == null) { + nodeMap = new Hashtable(); + } + + if (nodes == null) { + nodes = new Vector(); + } + + nodeMap.put(elem.getID(), elem); + nodes.insertElementAt(elem, where); + + if (elem instanceof TransientNode) { + TransientNode node = (TransientNode) elem; + + if (node.parent == null) { + node.parent = this; + node.anonymous = true; + } + } + + lastmodified = System.currentTimeMillis(); + + // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.SUBNODE_ADDED, node)); + return elem; } - public INode createNode () { - return createNode (null, 0); // where is ignored since this is an anonymous node + /** + * + * + * @return ... + */ + public INode createNode() { + return createNode(null, 0); // where is ignored since this is an anonymous node } - public INode createNode (int where) { - return createNode (null, where); + /** + * + * + * @param where ... + * + * @return ... + */ + public INode createNode(int where) { + return createNode(null, where); } - public INode createNode (String nm) { - return createNode (nm, numberOfNodes ()); // where is usually ignored (if nm != null) + /** + * + * + * @param nm ... + * + * @return ... + */ + public INode createNode(String nm) { + return createNode(nm, numberOfNodes()); // where is usually ignored (if nm != null) } - public INode createNode (String nm, int where) { - boolean anon = false; - if (nm == null || "".equals (nm.trim ())) - anon = true; - INode n = new TransientNode (nm); - if (anon) - addNode (n, where); - else - setNode (nm, n); - return n; - } + /** + * + * + * @param nm ... + * @param where ... + * + * @return ... + */ + public INode createNode(String nm, int where) { + boolean anon = false; + if ((nm == null) || "".equals(nm.trim())) { + anon = true; + } + + INode n = new TransientNode(nm); + + if (anon) { + addNode(n, where); + } else { + setNode(nm, n); + } + + return n; + } /** * register a node that links to this node. */ + /* protected void registerLink (TransientNode from) { - if (links == null) - links = new Vector (); - if (!links.contains (from)) - links.addElement (from); - } */ - - public IPathElement getParentElement () { - return getParent (); - } - - public IPathElement getChildElement (String name) { - return getNode (name); - } - - public INode getSubnode (String name) { - StringTokenizer st = new StringTokenizer (name, "/"); - TransientNode retval = this, runner; - while (st.hasMoreTokens () && retval != null) { - runner = retval; - String next = st.nextToken().trim().toLowerCase (); - if ("".equals (next)) - retval = this; - else - retval = runner.nodeMap == null ? null : (TransientNode) runner.nodeMap.get (next); - if (retval == null) - retval = (TransientNode) runner.getNode (next); - } - return retval; - } - - - public INode getSubnodeAt (int index) { - return nodes == null ? null : (INode) nodes.elementAt (index); - } - - public int contains (INode n) { - if (n == null || nodes == null) - return -1; - return nodes.indexOf (n); - } - - public boolean remove () { - if (anonymous) - parent.unset (name); - else - parent.removeNode (this); - return true; - } - - - public void removeNode (INode node) { - // IServer.getLogger().log ("removing: "+ node); - releaseNode (node); - TransientNode n = (TransientNode) node; - if (n.getParent () == this && n.anonymous) { - int l = n.links == null ? 0 : n.links.size (); // notify nodes that link to n that n is going down. - for (int i = 0; i < l; i++) { - TransientNode link = (TransientNode) n.links.elementAt (i); - link.releaseNode (n); - } - if (n.proplinks != null) { - // clean up all nodes that use n as a property - for (Enumeration e1 = n.proplinks.elements (); e1.hasMoreElements (); ) try { - Property p = (Property) e1.nextElement (); - p.node.propMap.remove (p.propname.toLowerCase ()); - } catch (Exception ignore) {} - } - // remove all subnodes, giving them a chance to destroy themselves. - Vector v = new Vector (); // removeElement modifies the Vector we are enumerating, so we are extra careful. - for (Enumeration e3 = n.getSubnodes (); e3.hasMoreElements (); ) { - v.addElement (e3.nextElement ()); - } - int m = v.size (); - for (int i=0; i<m; i++) { - n.removeNode ((TransientNode) v.elementAt (i)); - } - } else { - // - n.links.removeElement (this); - } + if (links == null) + links = new Vector (); + if (!links.contains (from)) + links.addElement (from); + } */ + public IPathElement getParentElement() { + return getParent(); } /** - * "Physically" remove a subnode from the subnodes table. + * + * + * @param name ... + * + * @return ... + */ + public IPathElement getChildElement(String name) { + return getNode(name); + } + + /** + * + * + * @param name ... + * + * @return ... + */ + public INode getSubnode(String name) { + StringTokenizer st = new StringTokenizer(name, "/"); + TransientNode retval = this; + TransientNode runner; + + while (st.hasMoreTokens() && (retval != null)) { + runner = retval; + + String next = st.nextToken().trim().toLowerCase(); + + if ("".equals(next)) { + retval = this; + } else { + retval = (runner.nodeMap == null) ? null + : (TransientNode) runner.nodeMap.get(next); + } + + if (retval == null) { + retval = (TransientNode) runner.getNode(next); + } + } + + return retval; + } + + /** + * + * + * @param index ... + * + * @return ... + */ + public INode getSubnodeAt(int index) { + return (nodes == null) ? null : (INode) nodes.elementAt(index); + } + + /** + * + * + * @param n ... + * + * @return ... + */ + public int contains(INode n) { + if ((n == null) || (nodes == null)) { + return -1; + } + + return nodes.indexOf(n); + } + + /** + * + * + * @return ... + */ + public boolean remove() { + if (anonymous) { + parent.unset(name); + } else { + parent.removeNode(this); + } + + return true; + } + + /** + * + * + * @param node ... + */ + public void removeNode(INode node) { + // IServer.getLogger().log ("removing: "+ node); + releaseNode(node); + + TransientNode n = (TransientNode) node; + + if ((n.getParent() == this) && n.anonymous) { + int l = (n.links == null) ? 0 : n.links.size(); // notify nodes that link to n that n is going down. + + for (int i = 0; i < l; i++) { + TransientNode link = (TransientNode) n.links.elementAt(i); + + link.releaseNode(n); + } + + if (n.proplinks != null) { + // clean up all nodes that use n as a property + for (Enumeration e1 = n.proplinks.elements(); e1.hasMoreElements();) + try { + Property p = (Property) e1.nextElement(); + + p.node.propMap.remove(p.propname.toLowerCase()); + } catch (Exception ignore) { + } + } + + // remove all subnodes, giving them a chance to destroy themselves. + Vector v = new Vector(); // removeElement modifies the Vector we are enumerating, so we are extra careful. + + for (Enumeration e3 = n.getSubnodes(); e3.hasMoreElements();) { + v.addElement(e3.nextElement()); + } + + int m = v.size(); + + for (int i = 0; i < m; i++) { + n.removeNode((TransientNode) v.elementAt(i)); + } + } else { + // + n.links.removeElement(this); + } + } + + /** + * "Physically" remove a subnode from the subnodes table. * the logical stuff necessary for keeping data consistent is done elsewhere (in removeNode). */ - protected void releaseNode (INode node) { - if (nodes == null || nodeMap == null) + protected void releaseNode(INode node) { + if ((nodes == null) || (nodeMap == null)) { - return; - int runner = nodes.indexOf (node); - // this is due to difference between .equals() and == - while (runner > -1 && nodes.elementAt (runner) != node) - runner = nodes.indexOf (node, Math.min (nodes.size()-1, runner+1)); - if (runner > -1) - nodes.removeElementAt (runner); - // nodes.remove (node); - Object what = nodeMap.remove (node.getName ().toLowerCase ()); - // Server.throwNodeEvent (new NodeEvent (node, NodeEvent.NODE_REMOVED)); - // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.SUBNODE_REMOVED, node)); - lastmodified = System.currentTimeMillis (); - // IServer.getLogger().log ("released node "+node +" from "+this+" oldobj = "+what); + return; + } + + int runner = nodes.indexOf(node); + + // this is due to difference between .equals() and == + while ((runner > -1) && (nodes.elementAt(runner) != node)) + runner = nodes.indexOf(node, Math.min(nodes.size() - 1, runner + 1)); + + if (runner > -1) { + nodes.removeElementAt(runner); + } + + // nodes.remove (node); + Object what = nodeMap.remove(node.getName().toLowerCase()); + + // Server.throwNodeEvent (new NodeEvent (node, NodeEvent.NODE_REMOVED)); + // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.SUBNODE_REMOVED, node)); + lastmodified = System.currentTimeMillis(); + + // IServer.getLogger().log ("released node "+node +" from "+this+" oldobj = "+what); } - public Enumeration getSubnodes () { - return nodes == null ? new Vector ().elements () : nodes.elements (); + /** + * + * + * @return ... + */ + public Enumeration getSubnodes() { + return (nodes == null) ? new Vector().elements() : nodes.elements(); } - /** * property-related - */ - - public Enumeration properties () { - return propMap == null ? new EmptyEnumeration () : propMap.keys (); + */ + public Enumeration properties() { + return (propMap == null) ? new EmptyEnumeration() : propMap.keys(); } + private Property getProperty(String propname) { + Property prop = (propMap == null) ? null : (Property) propMap.get(propname); - private Property getProperty (String propname) { - Property prop = propMap == null ? null : (Property) propMap.get (propname); - // check if we have to create a virtual node - if (prop == null && dbmap != null) { - Relation rel = dbmap.getPropertyRelation (propname); - if (rel != null && rel.isVirtual ()) { - prop = makeVirtualNode (propname, rel); - } - } - return prop; + // check if we have to create a virtual node + if ((prop == null) && (dbmap != null)) { + Relation rel = dbmap.getPropertyRelation(propname); + + if ((rel != null) && rel.isVirtual()) { + prop = makeVirtualNode(propname, rel); + } + } + + return prop; } - private Property makeVirtualNode (String propname, Relation rel) { - INode node = new helma.objectmodel.db.Node (rel.getPropName (), rel.getPrototype (), dbmap.getWrappedNodeManager()); - // node.setState (TRANSIENT); - // make a db mapping good enough that the virtual node finds its subnodes - // DbMapping dbm = new DbMapping (); - // dbm.setSubnodeRelation (rel); - // dbm.setPropertyRelation (rel); - node.setDbMapping (rel.getVirtualMapping ()); - setNode (propname, node); - return (Property) propMap.get (propname); + private Property makeVirtualNode(String propname, Relation rel) { + INode node = new helma.objectmodel.db.Node(rel.getPropName(), rel.getPrototype(), + dbmap.getWrappedNodeManager()); + + // node.setState (TRANSIENT); + // make a db mapping good enough that the virtual node finds its subnodes + // DbMapping dbm = new DbMapping (); + // dbm.setSubnodeRelation (rel); + // dbm.setPropertyRelation (rel); + node.setDbMapping(rel.getVirtualMapping()); + setNode(propname, node); + + return (Property) propMap.get(propname); } + /** + * + * + * @param propname ... + * + * @return ... + */ + public IProperty get(String propname) { + propname = propname.toLowerCase(); - public IProperty get (String propname) { - propname = propname.toLowerCase (); - return getProperty (propname); + return getProperty(propname); } - public String getString (String propname, String defaultValue) { - String propValue = getString (propname); - return propValue == null ? defaultValue : propValue; + /** + * + * + * @param propname ... + * @param defaultValue ... + * + * @return ... + */ + public String getString(String propname, String defaultValue) { + String propValue = getString(propname); + + return (propValue == null) ? defaultValue : propValue; } - public String getString (String propname) { - propname = propname.toLowerCase (); - Property prop = getProperty (propname); - try { - return prop.getStringValue (); - } catch (Exception ignore) {} - return null; + /** + * + * + * @param propname ... + * + * @return ... + */ + public String getString(String propname) { + propname = propname.toLowerCase(); + + Property prop = getProperty(propname); + + try { + return prop.getStringValue(); + } catch (Exception ignore) { + } + + return null; } - public long getInteger (String propname) { - propname = propname.toLowerCase (); - Property prop = getProperty (propname); - try { - return prop.getIntegerValue (); - } catch (Exception ignore) {} - return 0; + /** + * + * + * @param propname ... + * + * @return ... + */ + public long getInteger(String propname) { + propname = propname.toLowerCase(); + + Property prop = getProperty(propname); + + try { + return prop.getIntegerValue(); + } catch (Exception ignore) { + } + + return 0; } - public double getFloat (String propname) { - propname = propname.toLowerCase (); - Property prop = getProperty (propname); - try { - return prop.getFloatValue (); - } catch (Exception ignore) {} - return 0.0; + /** + * + * + * @param propname ... + * + * @return ... + */ + public double getFloat(String propname) { + propname = propname.toLowerCase(); + + Property prop = getProperty(propname); + + try { + return prop.getFloatValue(); + } catch (Exception ignore) { + } + + return 0.0; } - public Date getDate (String propname) { - propname = propname.toLowerCase (); - Property prop = getProperty (propname); - try { - return prop.getDateValue (); - } catch (Exception ignore) {} - return null; + /** + * + * + * @param propname ... + * + * @return ... + */ + public Date getDate(String propname) { + propname = propname.toLowerCase(); + + Property prop = getProperty(propname); + + try { + return prop.getDateValue(); + } catch (Exception ignore) { + } + + return null; } + /** + * + * + * @param propname ... + * + * @return ... + */ + public boolean getBoolean(String propname) { + propname = propname.toLowerCase(); - public boolean getBoolean (String propname) { - propname = propname.toLowerCase (); - Property prop = getProperty (propname); - try { - return prop.getBooleanValue (); - } catch (Exception ignore) {} - return false; + Property prop = getProperty(propname); + + try { + return prop.getBooleanValue(); + } catch (Exception ignore) { + } + + return false; } - public INode getNode (String propname) { - propname = propname.toLowerCase (); - Property prop = getProperty (propname); - try { - return prop.getNodeValue (); - } catch (Exception ignore) {} - return null; + /** + * + * + * @param propname ... + * + * @return ... + */ + public INode getNode(String propname) { + propname = propname.toLowerCase(); + + Property prop = getProperty(propname); + + try { + return prop.getNodeValue(); + } catch (Exception ignore) { + } + + return null; } - public Object getJavaObject (String propname) { - propname = propname.toLowerCase (); - Property prop = getProperty (propname); - try { - return prop.getJavaObjectValue (); - } catch (Exception ignore) {} - return null; + /** + * + * + * @param propname ... + * + * @return ... + */ + public Object getJavaObject(String propname) { + propname = propname.toLowerCase(); + + Property prop = getProperty(propname); + + try { + return prop.getJavaObjectValue(); + } catch (Exception ignore) { + } + + return null; } // create a property if it doesn't exist for this name - private Property initProperty (String propname) { - if (propMap == null) - propMap = new Hashtable (); - propname = propname.trim (); - String p2 = propname.toLowerCase (); - Property prop = (Property) propMap.get (p2); - if (prop == null) { - prop = new Property (propname, this); - propMap.put (p2, prop); - } - return prop; + private Property initProperty(String propname) { + if (propMap == null) { + propMap = new Hashtable(); + } + + propname = propname.trim(); + + String p2 = propname.toLowerCase(); + Property prop = (Property) propMap.get(p2); + + if (prop == null) { + prop = new Property(propname, this); + propMap.put(p2, prop); + } + + return prop; } - public void setString (String propname, String value) { - // IServer.getLogger().log ("setting String prop"); - Property prop = initProperty (propname); - prop.setStringValue (value); - // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); - lastmodified = System.currentTimeMillis (); + /** + * + * + * @param propname ... + * @param value ... + */ + public void setString(String propname, String value) { + // IServer.getLogger().log ("setting String prop"); + Property prop = initProperty(propname); + + prop.setStringValue(value); + + // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); + lastmodified = System.currentTimeMillis(); } - public void setInteger (String propname, long value) { - // IServer.getLogger().log ("setting bool prop"); - Property prop = initProperty (propname); - prop.setIntegerValue (value); - // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); - lastmodified = System.currentTimeMillis (); + /** + * + * + * @param propname ... + * @param value ... + */ + public void setInteger(String propname, long value) { + // IServer.getLogger().log ("setting bool prop"); + Property prop = initProperty(propname); + + prop.setIntegerValue(value); + + // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); + lastmodified = System.currentTimeMillis(); } - public void setFloat (String propname, double value) { - // IServer.getLogger().log ("setting bool prop"); - Property prop = initProperty (propname); - prop.setFloatValue (value); - // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); - lastmodified = System.currentTimeMillis (); + /** + * + * + * @param propname ... + * @param value ... + */ + public void setFloat(String propname, double value) { + // IServer.getLogger().log ("setting bool prop"); + Property prop = initProperty(propname); + + prop.setFloatValue(value); + + // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); + lastmodified = System.currentTimeMillis(); } - public void setBoolean (String propname, boolean value) { - // IServer.getLogger().log ("setting bool prop"); - Property prop = initProperty (propname); - prop.setBooleanValue (value); - // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); - lastmodified = System.currentTimeMillis (); + /** + * + * + * @param propname ... + * @param value ... + */ + public void setBoolean(String propname, boolean value) { + // IServer.getLogger().log ("setting bool prop"); + Property prop = initProperty(propname); + + prop.setBooleanValue(value); + + // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); + lastmodified = System.currentTimeMillis(); } + /** + * + * + * @param propname ... + * @param value ... + */ + public void setDate(String propname, Date value) { + // IServer.getLogger().log ("setting date prop"); + Property prop = initProperty(propname); - public void setDate (String propname, Date value) { - // IServer.getLogger().log ("setting date prop"); - Property prop = initProperty (propname); - prop.setDateValue (value); - // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); - lastmodified = System.currentTimeMillis (); + prop.setDateValue(value); + + // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); + lastmodified = System.currentTimeMillis(); } - public void setJavaObject (String propname, Object value) { - // IServer.getLogger().log ("setting date prop"); - Property prop = initProperty (propname); - prop.setJavaObjectValue (value); - // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); - lastmodified = System.currentTimeMillis (); + /** + * + * + * @param propname ... + * @param value ... + */ + public void setJavaObject(String propname, Object value) { + // IServer.getLogger().log ("setting date prop"); + Property prop = initProperty(propname); + + prop.setJavaObjectValue(value); + + // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); + lastmodified = System.currentTimeMillis(); } - public void setNode (String propname, INode value) { - // IServer.getLogger().log ("setting date prop"); - Property prop = initProperty (propname); - prop.setNodeValue (value); - - // check if the main identity of this node is as a named property - // or as an anonymous node in a collection - if (value instanceof TransientNode) { - TransientNode n = (TransientNode) value; - if (n.parent == null) { - n.name = propname; - n.parent = this; - n.anonymous = false; - } - } - - lastmodified = System.currentTimeMillis (); + /** + * + * + * @param propname ... + * @param value ... + */ + public void setNode(String propname, INode value) { + // IServer.getLogger().log ("setting date prop"); + Property prop = initProperty(propname); + + prop.setNodeValue(value); + + // check if the main identity of this node is as a named property + // or as an anonymous node in a collection + if (value instanceof TransientNode) { + TransientNode n = (TransientNode) value; + + if (n.parent == null) { + n.name = propname; + n.parent = this; + n.anonymous = false; + } + } + + lastmodified = System.currentTimeMillis(); } - public void unset (String propname) { - if (propMap == null) - return; - try { - Property p = (Property) propMap.remove (propname.toLowerCase ()); - lastmodified = System.currentTimeMillis (); - } catch (Exception ignore) {} - } + /** + * + * + * @param propname ... + */ + public void unset(String propname) { + if (propMap == null) { + return; + } + try { + Property p = (Property) propMap.remove(propname.toLowerCase()); + + lastmodified = System.currentTimeMillis(); + } catch (Exception ignore) { + } + } /* public String getUrl (INode root, INode users, String tmpname, String rootproto) { - throw new RuntimeException ("HREFs on transient (non-db based) Nodes not supported"); - } */ - - - public long lastModified () { - return lastmodified; + throw new RuntimeException ("HREFs on transient (non-db based) Nodes not supported"); + } */ + public long lastModified() { + return lastmodified; } - public long created () { - return created; + /** + * + * + * @return ... + */ + public long created() { + return created; } - public String toString () { - return "TransientNode " + name; + /** + * + * + * @return ... + */ + public String toString() { + return "TransientNode " + name; } - - INode cacheNode; /** * Get the cache node for this node. This can * be used to store transient cache data per node * from Javascript. */ - public synchronized INode getCacheNode () { - if (cacheNode == null) - cacheNode = new TransientNode(); - return cacheNode; + public synchronized INode getCacheNode() { + if (cacheNode == null) { + cacheNode = new TransientNode(); + } + + return cacheNode; } /** * Reset the cache node for this node. */ - public synchronized void clearCacheNode () { - cacheNode = null; + public synchronized void clearCacheNode() { + cacheNode = null; } - } - - - - diff --git a/src/helma/objectmodel/db/DbColumn.java b/src/helma/objectmodel/db/DbColumn.java index df98a7bd..51c15b16 100644 --- a/src/helma/objectmodel/db/DbColumn.java +++ b/src/helma/objectmodel/db/DbColumn.java @@ -1,48 +1,62 @@ -// DbColumn.java -// Copyright 2002 Hannes Wallnoefer, Helma.org +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.objectmodel.db; -/** - * A class that encapsulates the Column name and data type of a + +/** + * A class that encapsulates the Column name and data type of a * column in a relational table. */ public final class DbColumn { - private final String name; private final int type; private final Relation relation; - + /** * Constructor */ - public DbColumn (String name, int type, Relation rel) { - this.name = name; - this.type = type; - this.relation = rel; - if (relation != null) - relation.setColumnType (type); + public DbColumn(String name, int type, Relation rel) { + this.name = name; + this.type = type; + this.relation = rel; + + if (relation != null) { + relation.setColumnType(type); + } } /** * Get the column name. */ public String getName() { - return name; + return name; } /** * Get this columns SQL data type. */ public int getType() { - return type; + return type; } /** * Return the relation associated with this column. May be null. */ public Relation getRelation() { - return relation; + return relation; } - } diff --git a/src/helma/objectmodel/db/DbKey.java b/src/helma/objectmodel/db/DbKey.java index 6043f5e8..8f947bbb 100644 --- a/src/helma/objectmodel/db/DbKey.java +++ b/src/helma/objectmodel/db/DbKey.java @@ -1,22 +1,34 @@ -// DbKey.java -// Copyright (c) Hannes Wallnöfer 1998-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.objectmodel.db; import java.io.Serializable; - /** * This is the internal representation of a database key. It is constructed * from the logical table (type) name and the object's primary key * within the table. Currently only single keys are supported. */ public final class DbKey implements Key, Serializable { - // the name of the prototype which defines the storage of this object. // this is the name of the object's prototype, or one of its ancestors. // If null, the object is stored in the embedded db. private final String storageName; + // the id that defines this key's object within the above storage space private final String id; @@ -26,50 +38,82 @@ public final class DbKey implements Key, Serializable { /** * make a key for a persistent Object, describing its datasource and id. */ - public DbKey (DbMapping dbmap, String id) { - this.id = id; - this.storageName = dbmap == null ? null : dbmap.getStorageTypeName (); - } - - - - public boolean equals (Object what) { - if (what == this) - return true; - if (!(what instanceof DbKey)) - return false; - DbKey k = (DbKey) what; - // storageName is an interned string (by DbMapping, from where we got it) - // so we can compare by using == instead of the equals method. - return storageName == k.storageName && (id == k.id || id.equals (k.id)); + public DbKey(DbMapping dbmap, String id) { + this.id = id; + this.storageName = (dbmap == null) ? null : dbmap.getStorageTypeName(); } - public int hashCode () { - if (hashcode == 0) { - hashcode = storageName == null ? - 17 + 37*id.hashCode () : - 17 + 37*storageName.hashCode() + +37*id.hashCode (); - } - return hashcode; + /** + * + * + * @param what ... + * + * @return ... + */ + public boolean equals(Object what) { + if (what == this) { + return true; + } + + if (!(what instanceof DbKey)) { + return false; + } + + DbKey k = (DbKey) what; + + // storageName is an interned string (by DbMapping, from where we got it) + // so we can compare by using == instead of the equals method. + return (storageName == k.storageName) && ((id == k.id) || id.equals(k.id)); } - public Key getParentKey () { - return null; + /** + * + * + * @return ... + */ + public int hashCode() { + if (hashcode == 0) { + hashcode = (storageName == null) ? (17 + (37 * id.hashCode())) + : (17 + (37 * storageName.hashCode()) + + (+37 * id.hashCode())); + } + + return hashcode; } - public String getStorageName () { - return storageName; + /** + * + * + * @return ... + */ + public Key getParentKey() { + return null; } - public String getID () { - return id; + /** + * + * + * @return ... + */ + public String getStorageName() { + return storageName; } - public String toString () { - return storageName == null ? "["+id+"]" : storageName+"["+id+"]"; + /** + * + * + * @return ... + */ + public String getID() { + return id; } - + /** + * + * + * @return ... + */ + public String toString() { + return (storageName == null) ? ("[" + id + "]") : (storageName + "[" + id + "]"); + } } - - diff --git a/src/helma/objectmodel/db/DbMapping.java b/src/helma/objectmodel/db/DbMapping.java index f8995ee8..a4487f8e 100644 --- a/src/helma/objectmodel/db/DbMapping.java +++ b/src/helma/objectmodel/db/DbMapping.java @@ -1,28 +1,40 @@ -// DbMapping.java -// Copyright (c) Hannes Wallnöfer 1998-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.objectmodel.db; import helma.framework.core.Application; -import helma.util.Updatable; import helma.util.SystemProperties; +import helma.util.Updatable; +import java.sql.*; +import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; -import java.util.Enumeration; import java.util.Iterator; import java.util.StringTokenizer; -import java.sql.*; /** - * A DbMapping describes how a certain type of Nodes is to mapped to a - * relational database table. Basically it consists of a set of JavaScript property-to- - * Database row bindings which are represented by instances of the Relation class. - */ - + * A DbMapping describes how a certain type of Nodes is to mapped to a + * relational database table. Basically it consists of a set of JavaScript property-to- + * Database row bindings which are represented by instances of the Relation class. + */ public final class DbMapping implements Updatable { - // DbMappings belong to an application Application app; + // prototype name of this mapping String typename; @@ -31,8 +43,10 @@ public final class DbMapping implements Updatable { // name of data dbSource to which this mapping writes DbSource dbSource; + // name of datasource String dbSourceName; + // name of db table String tableName; @@ -47,8 +61,9 @@ public final class DbMapping implements Updatable { // we need a DbMapping for those groupby nodes DbMapping groupbyMapping; - // Map of property names to Relations objects + // Map of property names to Relations objects HashMap prop2db; + // Map of db columns to Relations objects. // Case insensitive, keys are stored in upper case so // lookups must do a toUpperCase(). @@ -56,6 +71,7 @@ public final class DbMapping implements Updatable { // list of columns to fetch from db DbColumn[] columns = null; + // Map of db columns by name HashMap columnMap; @@ -66,13 +82,16 @@ public final class DbMapping implements Updatable { // db field used as primary key private String idField; + // db field used as object name String nameField; + // db field used to identify name of prototype to use for object instantiation String protoField; // name of parent prototype, if any String extendsProto; + // dbmapping of parent prototype, if any DbMapping parentMapping; @@ -81,6 +100,7 @@ public final class DbMapping implements Updatable { // descriptor for key generation method private String idgen; + // remember last key generated for this table long lastID; @@ -88,483 +108,646 @@ public final class DbMapping implements Updatable { // init value is -1 so we know we have to run update once even if // the underlying properties file is non-existent long lastTypeChange = -1; + // timestamp of last modification of an object of this type long lastDataChange; /** * Create an empty DbMapping */ - public DbMapping (Application app) { + public DbMapping(Application app) { + this.app = app; + this.typename = null; - this.app = app; - this.typename = null; + prop2db = new HashMap(); + db2prop = new HashMap(); - prop2db = new HashMap (); - db2prop = new HashMap (); + parentInfo = null; - parentInfo = null; - - idField = null; + idField = null; } /** * Create a DbMapping from a type.properties property file */ - public DbMapping (Application app, String typename, SystemProperties props) { + public DbMapping(Application app, String typename, SystemProperties props) { + this.app = app; + this.typename = typename; - this.app = app; - this.typename = typename; - // create a unique instance of the string. This is useful so - // we can compare types just by using == instead of equals. - if (typename != null) - typename = typename.intern (); + // create a unique instance of the string. This is useful so + // we can compare types just by using == instead of equals. + if (typename != null) { + typename = typename.intern(); + } - prop2db = new HashMap (); - db2prop = new HashMap (); - - columnMap = new HashMap (); + prop2db = new HashMap(); + db2prop = new HashMap(); - parentInfo = null; + columnMap = new HashMap(); - idField = null; + parentInfo = null; - this.props = props; + idField = null; + + this.props = props; } /** * Tell the type manager whether we need update() to be called */ - public boolean needsUpdate () { - return props.lastModified () != lastTypeChange; + public boolean needsUpdate() { + return props.lastModified() != lastTypeChange; } - /** * Read the mapping from the Properties. Return true if the properties were changed. * The read is split in two, this method and the rewire method. The reason is that in order * for rewire to work, all other db mappings must have been initialized and registered. */ - public synchronized void update () { - // read in properties - tableName = props.getProperty ("_table"); - idgen = props.getProperty ("_idgen"); - // see if there is a field which specifies the prototype of objects, if different prototypes - // can be stored in this table - prototypeField = props.getProperty ("_prototypefield"); - // see if this prototype extends (inherits from) any other prototype - extendsProto = props.getProperty ("_extends"); + public synchronized void update() { + // read in properties + tableName = props.getProperty("_table"); + idgen = props.getProperty("_idgen"); - dbSourceName = props.getProperty ("_db"); - if (dbSourceName != null) { - dbSource = app.getDbSource (dbSourceName); - if (dbSource == null) { - app.logEvent ("*** Data Source for prototype "+typename+" does not exist: "+dbSourceName); - app.logEvent ("*** accessing or storing a "+typename+" object will cause an error."); - } else if (tableName == null) { - app.logEvent ("*** No table name specified for prototype "+typename); - app.logEvent ("*** accessing or storing a "+typename+" object will cause an error."); - // mark mapping as invalid by nulling the dbSource field - dbSource = null; - } - } + // see if there is a field which specifies the prototype of objects, if different prototypes + // can be stored in this table + prototypeField = props.getProperty("_prototypefield"); - // if id field is null, we assume "ID" as default. We don't set it - // however, so that if null we check the parent prototype first. - idField = props.getProperty ("_id"); + // see if this prototype extends (inherits from) any other prototype + extendsProto = props.getProperty("_extends"); - nameField = props.getProperty ("_name"); + dbSourceName = props.getProperty("_db"); - protoField = props.getProperty ("_prototype"); + if (dbSourceName != null) { + dbSource = app.getDbSource(dbSourceName); - String parentSpec = props.getProperty ("_parent"); - if (parentSpec != null) { - // comma-separated list of properties to be used as parent - StringTokenizer st = new StringTokenizer (parentSpec, ",;"); - parentInfo = new ParentInfo[st.countTokens()]; - for (int i=0; i<parentInfo.length; i++) - parentInfo[i] = new ParentInfo (st.nextToken().trim()); - } else { - parentInfo = null; - } + if (dbSource == null) { + app.logEvent("*** Data Source for prototype " + typename + + " does not exist: " + dbSourceName); + app.logEvent("*** accessing or storing a " + typename + + " object will cause an error."); + } else if (tableName == null) { + app.logEvent("*** No table name specified for prototype " + typename); + app.logEvent("*** accessing or storing a " + typename + + " object will cause an error."); - lastTypeChange = props.lastModified (); - // null the cached columns and select string - columns = null; - columnMap.clear(); - selectString = insertString = updateString = null; + // mark mapping as invalid by nulling the dbSource field + dbSource = null; + } + } + // if id field is null, we assume "ID" as default. We don't set it + // however, so that if null we check the parent prototype first. + idField = props.getProperty("_id"); - if (extendsProto != null) { - parentMapping = app.getDbMapping (extendsProto); - } + nameField = props.getProperty("_name"); - // if (tableName != null && dbSource != null) { - // app.logEvent ("set data dbSource for "+typename+" to "+dbSource); - HashMap p2d = new HashMap (); - HashMap d2p = new HashMap (); + protoField = props.getProperty("_prototype"); - for (Enumeration e=props.keys(); e.hasMoreElements(); ) { - String propName = (String) e.nextElement (); + String parentSpec = props.getProperty("_parent"); - try { - // ignore internal properties (starting with "_") and sub-options (containing a ".") - if (!propName.startsWith ("_") && propName.indexOf (".") < 0) { - String dbField = props.getProperty (propName); - // check if a relation for this propery already exists. If so, reuse it - Relation rel = (Relation) prop2db.get (propName.toLowerCase()); - if (rel == null) - rel = new Relation (dbField, propName, this, props); - rel.update (dbField, props); - // key enumerations from SystemProperties are all lower case, which is why - // even though we don't do a toLowerCase() here, - // we have to when we lookup things in p2d later. - p2d.put (propName, rel); - if (rel.columnName != null && - (rel.reftype == Relation.PRIMITIVE || - rel.reftype == Relation.REFERENCE)) - d2p.put (rel.columnName.toUpperCase (), rel); - // app.logEvent ("Mapping "+propName+" -> "+dbField); - } - } catch (Exception x) { - app.logEvent ("Error in type.properties: "+x.getMessage ()); - } - } + if (parentSpec != null) { + // comma-separated list of properties to be used as parent + StringTokenizer st = new StringTokenizer(parentSpec, ",;"); - prop2db = p2d; - db2prop = d2p; + parentInfo = new ParentInfo[st.countTokens()]; - String subnodeMapping = props.getProperty ("_children"); - if (subnodeMapping != null) { - try { - // check if subnode relation already exists. If so, reuse it - if (subRelation == null) - subRelation = new Relation (subnodeMapping, "_children", this, props); - subRelation.update (subnodeMapping, props); - // if subnodes are accessed via access name or group name, - // the subnode relation is also the property relation. - if (subRelation.accessName != null || subRelation.groupby != null) - propRelation = subRelation; - } catch (Exception x) { - app.logEvent ("Error reading _subnodes relation for "+typename+": "+x.getMessage ()); - // subRelation = null; - } - } else { - subRelation = propRelation = null; - } + for (int i = 0; i < parentInfo.length; i++) + parentInfo[i] = new ParentInfo(st.nextToken().trim()); + } else { + parentInfo = null; + } - if (groupbyMapping != null) { - initGroupbyMapping (); - groupbyMapping.lastTypeChange = this.lastTypeChange; - } + lastTypeChange = props.lastModified(); + + // null the cached columns and select string + columns = null; + columnMap.clear(); + selectString = insertString = updateString = null; + + if (extendsProto != null) { + parentMapping = app.getDbMapping(extendsProto); + } + + // if (tableName != null && dbSource != null) { + // app.logEvent ("set data dbSource for "+typename+" to "+dbSource); + HashMap p2d = new HashMap(); + HashMap d2p = new HashMap(); + + for (Enumeration e = props.keys(); e.hasMoreElements();) { + String propName = (String) e.nextElement(); + + try { + // ignore internal properties (starting with "_") and sub-options (containing a ".") + if (!propName.startsWith("_") && (propName.indexOf(".") < 0)) { + String dbField = props.getProperty(propName); + + // check if a relation for this propery already exists. If so, reuse it + Relation rel = (Relation) prop2db.get(propName.toLowerCase()); + + if (rel == null) { + rel = new Relation(dbField, propName, this, props); + } + + rel.update(dbField, props); + + // key enumerations from SystemProperties are all lower case, which is why + // even though we don't do a toLowerCase() here, + // we have to when we lookup things in p2d later. + p2d.put(propName, rel); + + if ((rel.columnName != null) && + ((rel.reftype == Relation.PRIMITIVE) || + (rel.reftype == Relation.REFERENCE))) { + d2p.put(rel.columnName.toUpperCase(), rel); + } + + // app.logEvent ("Mapping "+propName+" -> "+dbField); + } + } catch (Exception x) { + app.logEvent("Error in type.properties: " + x.getMessage()); + } + } + + prop2db = p2d; + db2prop = d2p; + + String subnodeMapping = props.getProperty("_children"); + + if (subnodeMapping != null) { + try { + // check if subnode relation already exists. If so, reuse it + if (subRelation == null) { + subRelation = new Relation(subnodeMapping, "_children", this, props); + } + + subRelation.update(subnodeMapping, props); + + // if subnodes are accessed via access name or group name, + // the subnode relation is also the property relation. + if ((subRelation.accessName != null) || (subRelation.groupby != null)) { + propRelation = subRelation; + } + } catch (Exception x) { + app.logEvent("Error reading _subnodes relation for " + typename + ": " + + x.getMessage()); + + // subRelation = null; + } + } else { + subRelation = propRelation = null; + } + + if (groupbyMapping != null) { + initGroupbyMapping(); + groupbyMapping.lastTypeChange = this.lastTypeChange; + } } - /** * Method in interface Updatable. */ - public void remove () { - // do nothing, removing of type properties is not implemented. + public void remove() { + // do nothing, removing of type properties is not implemented. } /** * Get a JDBC connection for this DbMapping. */ - public Connection getConnection () throws ClassNotFoundException, SQLException { - if (dbSourceName == null) { - if (parentMapping != null) - return parentMapping.getConnection (); - else - throw new SQLException ("Tried to get Connection from non-relational embedded data source."); - } - if (tableName == null) { - throw new SQLException ("Invalid DbMapping, _table not specified: "+this); - } - // if dbSource was previously not available, check again - if (dbSource == null) { - dbSource = app.getDbSource (dbSourceName); - } - if (dbSource == null) { - throw new SQLException ("Datasource is not defined: "+dbSourceName+"."); - } - return dbSource.getConnection (); + public Connection getConnection() throws ClassNotFoundException, SQLException { + if (dbSourceName == null) { + if (parentMapping != null) { + return parentMapping.getConnection(); + } else { + throw new SQLException("Tried to get Connection from non-relational embedded data source."); + } + } + + if (tableName == null) { + throw new SQLException("Invalid DbMapping, _table not specified: " + this); + } + + // if dbSource was previously not available, check again + if (dbSource == null) { + dbSource = app.getDbSource(dbSourceName); + } + + if (dbSource == null) { + throw new SQLException("Datasource is not defined: " + dbSourceName + "."); + } + + return dbSource.getConnection(); } /** * Get the DbSource object for this DbMapping. The DbSource describes a JDBC * data source including URL, JDBC driver, username and password. */ - public DbSource getDbSource () { - if (dbSource == null) { - if (tableName != null && dbSourceName != null) - dbSource = app.getDbSource (dbSourceName); - else if (parentMapping != null) - return parentMapping.getDbSource (); - } - return dbSource; - } + public DbSource getDbSource() { + if (dbSource == null) { + if ((tableName != null) && (dbSourceName != null)) { + dbSource = app.getDbSource(dbSourceName); + } else if (parentMapping != null) { + return parentMapping.getDbSource(); + } + } + return dbSource; + } /** * Get the table name used for this type mapping. */ - public String getTableName () { - if (tableName == null && parentMapping != null) - return parentMapping.getTableName (); - return tableName; + public String getTableName() { + if ((tableName == null) && (parentMapping != null)) { + return parentMapping.getTableName(); + } + + return tableName; } /** * Get the application this DbMapping belongs to. */ - public Application getApplication () { - return app; + public Application getApplication() { + return app; } /** * Get the name of this mapping's application */ - public String getAppName () { - return app.getName(); + public String getAppName() { + return app.getName(); } /** * Get the name of the object type this DbMapping belongs to. */ - public String getTypeName () { - return typename; + public String getTypeName() { + return typename; } /** * Get the name of this type's parent type, if any. */ - public String getExtends () { - return extendsProto; + public String getExtends() { + return extendsProto; } /** * Get the primary key column name for objects using this mapping. */ - public String getIDField () { - if (idField == null && parentMapping != null) - return parentMapping.getIDField (); - return idField == null ? "ID" : idField; + public String getIDField() { + if ((idField == null) && (parentMapping != null)) { + return parentMapping.getIDField(); + } + + return (idField == null) ? "ID" : idField; } /** * Get the column used for (internal) names of objects of this type. */ - public String getNameField () { - if (nameField == null && parentMapping != null) - return parentMapping.getNameField (); - return nameField; + public String getNameField() { + if ((nameField == null) && (parentMapping != null)) { + return parentMapping.getNameField(); + } + + return nameField; } /** * Get the column used for names of prototype. */ - public String getPrototypeField () { - if (protoField == null && parentMapping != null) - return parentMapping.getPrototypeField (); - return protoField; - } + public String getPrototypeField() { + if ((protoField == null) && (parentMapping != null)) { + return parentMapping.getPrototypeField(); + } - - /** - * Translate a database column name to an object property name according to this mapping. - */ - public String columnNameToProperty (String columnName) { - if (columnName == null) - return null; - return _columnNameToProperty (columnName.toUpperCase()); - } - - private String _columnNameToProperty (final String columnName) { - Relation rel = (Relation) db2prop.get (columnName); - if (rel == null && parentMapping != null) - return parentMapping._columnNameToProperty (columnName); - if (rel != null && (rel.reftype == Relation.PRIMITIVE || rel.reftype == Relation.REFERENCE)) - return rel.propName; - return null; - } - - /** - * Translate an object property name to a database column name according to this mapping. - */ - public String propertyToColumnName (String propName) { - if (propName == null) - return null; - // FIXME: prop2db stores keys in lower case, because it gets them - // from a SystemProperties object which converts keys to lower case. - return _propertyToColumnName (propName.toLowerCase ()); - } - - private String _propertyToColumnName (final String propName) { - Relation rel = (Relation) prop2db.get (propName); - if (rel == null && parentMapping != null) - return parentMapping._propertyToColumnName (propName); - if (rel != null && (rel.reftype == Relation.PRIMITIVE || rel.reftype == Relation.REFERENCE)) - return rel.columnName; - return null; + return protoField; } /** * Translate a database column name to an object property name according to this mapping. */ - public Relation columnNameToRelation (String columnName) { - if (columnName == null) - return null; - return _columnNameToRelation (columnName.toUpperCase()); + public String columnNameToProperty(String columnName) { + if (columnName == null) { + return null; + } + + return _columnNameToProperty(columnName.toUpperCase()); } - - private Relation _columnNameToRelation (final String columnName) { - Relation rel = (Relation) db2prop.get (columnName); - if (rel == null && parentMapping != null) - return parentMapping._columnNameToRelation (columnName); - return rel; + + private String _columnNameToProperty(final String columnName) { + Relation rel = (Relation) db2prop.get(columnName); + + if ((rel == null) && (parentMapping != null)) { + return parentMapping._columnNameToProperty(columnName); + } + + if ((rel != null) && + ((rel.reftype == Relation.PRIMITIVE) || + (rel.reftype == Relation.REFERENCE))) { + return rel.propName; + } + + return null; } /** * Translate an object property name to a database column name according to this mapping. */ - public Relation propertyToRelation (String propName) { - if (propName == null) - return null; - // FIXME: prop2db stores keys in lower case, because it gets them - // from a SystemProperties object which converts keys to lower case. - return _propertyToRelation (propName.toLowerCase()); + public String propertyToColumnName(String propName) { + if (propName == null) { + return null; + } + + // FIXME: prop2db stores keys in lower case, because it gets them + // from a SystemProperties object which converts keys to lower case. + return _propertyToColumnName(propName.toLowerCase()); } - private Relation _propertyToRelation (String propName) { - Relation rel = (Relation) prop2db.get (propName); - if (rel == null && parentMapping != null) - return parentMapping._propertyToRelation (propName); - return rel; + private String _propertyToColumnName(final String propName) { + Relation rel = (Relation) prop2db.get(propName); + + if ((rel == null) && (parentMapping != null)) { + return parentMapping._propertyToColumnName(propName); + } + + if ((rel != null) && + ((rel.reftype == Relation.PRIMITIVE) || + (rel.reftype == Relation.REFERENCE))) { + return rel.columnName; + } + + return null; } + /** + * Translate a database column name to an object property name according to this mapping. + */ + public Relation columnNameToRelation(String columnName) { + if (columnName == null) { + return null; + } + + return _columnNameToRelation(columnName.toUpperCase()); + } + + private Relation _columnNameToRelation(final String columnName) { + Relation rel = (Relation) db2prop.get(columnName); + + if ((rel == null) && (parentMapping != null)) { + return parentMapping._columnNameToRelation(columnName); + } + + return rel; + } + + /** + * Translate an object property name to a database column name according to this mapping. + */ + public Relation propertyToRelation(String propName) { + if (propName == null) { + return null; + } + + // FIXME: prop2db stores keys in lower case, because it gets them + // from a SystemProperties object which converts keys to lower case. + return _propertyToRelation(propName.toLowerCase()); + } + + private Relation _propertyToRelation(String propName) { + Relation rel = (Relation) prop2db.get(propName); + + if ((rel == null) && (parentMapping != null)) { + return parentMapping._propertyToRelation(propName); + } + + return rel; + } /** * This returns the parent info array, which tells an object of this type how to * determine its parent object. */ - public synchronized ParentInfo[] getParentInfo () { - if (parentInfo == null && parentMapping != null) - return parentMapping.getParentInfo (); - return parentInfo; + public synchronized ParentInfo[] getParentInfo() { + if ((parentInfo == null) && (parentMapping != null)) { + return parentMapping.getParentInfo(); + } + + return parentInfo; } + /** + * + * + * @return ... + */ + public DbMapping getSubnodeMapping() { + if (subRelation != null) { + return subRelation.otherType; + } - public DbMapping getSubnodeMapping () { - if (subRelation != null) - return subRelation.otherType; - if (parentMapping != null) - return parentMapping.getSubnodeMapping (); - return null; + if (parentMapping != null) { + return parentMapping.getSubnodeMapping(); + } + + return null; } + /** + * + * + * @param propname ... + * + * @return ... + */ + public DbMapping getExactPropertyMapping(String propname) { + Relation rel = getExactPropertyRelation(propname); - public DbMapping getExactPropertyMapping (String propname) { - Relation rel = getExactPropertyRelation (propname); - return rel != null ? rel.otherType : null; + return (rel != null) ? rel.otherType : null; } - public DbMapping getPropertyMapping (String propname) { - Relation rel = getPropertyRelation (propname); - if (rel != null) { - // if this is a virtual node, it doesn't have a dbmapping - if (rel.virtual && rel.prototype == null) - return null; - else - return rel.otherType; - } - return null; + /** + * + * + * @param propname ... + * + * @return ... + */ + public DbMapping getPropertyMapping(String propname) { + Relation rel = getPropertyRelation(propname); + + if (rel != null) { + // if this is a virtual node, it doesn't have a dbmapping + if (rel.virtual && (rel.prototype == null)) { + return null; + } else { + return rel.otherType; + } + } + + return null; } /** * If subnodes are grouped by one of their properties, return the * db-mapping with the right relations to create the group-by nodes */ - public synchronized DbMapping getGroupbyMapping () { - if (subRelation == null || subRelation.groupby == null) - return null; - if (groupbyMapping == null) { - initGroupbyMapping (); - } - return groupbyMapping; + public synchronized DbMapping getGroupbyMapping() { + if ((subRelation == null) || (subRelation.groupby == null)) { + return null; + } + + if (groupbyMapping == null) { + initGroupbyMapping(); + } + + return groupbyMapping; } /** * Initialize the dbmapping used for group-by nodes. */ - private void initGroupbyMapping () { - // if a prototype is defined for groupby nodes, use that - // if mapping doesn' exist or isn't defined, create a new (anonymous internal) one - groupbyMapping = new DbMapping (app); - // If a mapping is defined, make the internal mapping inherit from - // the defined named prototype. - if (subRelation.groupbyPrototype != null) - groupbyMapping.parentMapping = app.getDbMapping (subRelation.groupbyPrototype); - groupbyMapping.subRelation = subRelation.getGroupbySubnodeRelation (); - if (propRelation != null) - groupbyMapping.propRelation = propRelation.getGroupbyPropertyRelation (); - else - groupbyMapping.propRelation = subRelation.getGroupbyPropertyRelation (); - groupbyMapping.typename = subRelation.groupbyPrototype; + private void initGroupbyMapping() { + // if a prototype is defined for groupby nodes, use that + // if mapping doesn' exist or isn't defined, create a new (anonymous internal) one + groupbyMapping = new DbMapping(app); + + // If a mapping is defined, make the internal mapping inherit from + // the defined named prototype. + if (subRelation.groupbyPrototype != null) { + groupbyMapping.parentMapping = app.getDbMapping(subRelation.groupbyPrototype); + } + + groupbyMapping.subRelation = subRelation.getGroupbySubnodeRelation(); + + if (propRelation != null) { + groupbyMapping.propRelation = propRelation.getGroupbyPropertyRelation(); + } else { + groupbyMapping.propRelation = subRelation.getGroupbyPropertyRelation(); + } + + groupbyMapping.typename = subRelation.groupbyPrototype; } - - public void setPropertyRelation (Relation rel) { - propRelation = rel; + /** + * + * + * @param rel ... + */ + public void setPropertyRelation(Relation rel) { + propRelation = rel; } - public Relation getSubnodeRelation () { - if (subRelation == null && parentMapping != null) - return parentMapping.getSubnodeRelation (); - return subRelation; + /** + * + * + * @return ... + */ + public Relation getSubnodeRelation() { + if ((subRelation == null) && (parentMapping != null)) { + return parentMapping.getSubnodeRelation(); + } + + return subRelation; } - public Relation getPropertyRelation () { - if (propRelation == null && parentMapping != null) - return parentMapping.getPropertyRelation (); - return propRelation; + /** + * + * + * @return ... + */ + public Relation getPropertyRelation() { + if ((propRelation == null) && (parentMapping != null)) { + return parentMapping.getPropertyRelation(); + } + + return propRelation; } - public Relation getPropertyRelation (String propname) { - if (propname == null) - return getPropertyRelation (); - // first try finding an exact match for the property name - Relation rel = getExactPropertyRelation (propname); - // if not defined, return the generic property mapping - if (rel == null) - rel = getPropertyRelation (); - return rel; + /** + * + * + * @param propname ... + * + * @return ... + */ + public Relation getPropertyRelation(String propname) { + if (propname == null) { + return getPropertyRelation(); + } + + // first try finding an exact match for the property name + Relation rel = getExactPropertyRelation(propname); + + // if not defined, return the generic property mapping + if (rel == null) { + rel = getPropertyRelation(); + } + + return rel; } - public Relation getExactPropertyRelation (String propname) { - if (propname == null) - return null; - Relation rel = (Relation) prop2db.get (propname.toLowerCase()); - if (rel == null && parentMapping != null) - rel = parentMapping.getExactPropertyRelation (propname); - return rel; + /** + * + * + * @param propname ... + * + * @return ... + */ + public Relation getExactPropertyRelation(String propname) { + if (propname == null) { + return null; + } + + Relation rel = (Relation) prop2db.get(propname.toLowerCase()); + + if ((rel == null) && (parentMapping != null)) { + rel = parentMapping.getExactPropertyRelation(propname); + } + + return rel; } - public String getSubnodeGroupby () { - if (subRelation == null && parentMapping != null) - return parentMapping.getSubnodeGroupby (); - return subRelation == null ? null : subRelation.groupby; + /** + * + * + * @return ... + */ + public String getSubnodeGroupby() { + if ((subRelation == null) && (parentMapping != null)) { + return parentMapping.getSubnodeGroupby(); + } + + return (subRelation == null) ? null : subRelation.groupby; } - public String getIDgen () { - if (idgen == null && parentMapping != null) - return parentMapping.getIDgen (); - return idgen; + /** + * + * + * @return ... + */ + public String getIDgen() { + if ((idgen == null) && (parentMapping != null)) { + return parentMapping.getIDgen(); + } + + return idgen; } + /** + * + * + * @return ... + */ + public WrappedNodeManager getWrappedNodeManager() { + if (app == null) { + throw new RuntimeException("Can't get node manager from internal db mapping"); + } - public WrappedNodeManager getWrappedNodeManager () { - if (app == null) - throw new RuntimeException ("Can't get node manager from internal db mapping"); - return app.getWrappedNodeManager (); + return app.getWrappedNodeManager(); } /** @@ -573,186 +756,305 @@ public final class DbMapping implements Updatable { * mappings would be stored in the embedded db instead of an error being thrown, which is * not what we want. */ - public boolean isRelational () { - if (dbSourceName != null) - return true; - if (parentMapping != null) - return parentMapping.isRelational (); - return false; - } + public boolean isRelational() { + if (dbSourceName != null) { + return true; + } + if (parentMapping != null) { + return parentMapping.isRelational(); + } + + return false; + } /** * Return an array of DbColumns for the relational table mapped by this DbMapping. */ - public synchronized DbColumn[] getColumns() throws ClassNotFoundException, SQLException { - if (!isRelational ()) - throw new SQLException ("Can't get columns for non-relational data mapping "+this); - if (dbSource == null && parentMapping != null) - return parentMapping.getColumns (); - // Use local variable cols to avoid synchronization (schema may be nulled elsewhere) - if (columns == null) { - // we do two things here: set the SQL type on the Relation mappings - // and build a string of column names. - Connection con = getConnection (); - Statement stmt = con.createStatement (); - String t = getTableName(); - if (t == null) - throw new SQLException ("Table name is null in getColumns() for "+this); - ResultSet rs = stmt.executeQuery ( - new StringBuffer("SELECT * FROM ") - .append(t).append(" WHERE 1 = 0").toString()); - if (rs == null) - throw new SQLException ("Error retrieving columns for "+this); - ResultSetMetaData meta = rs.getMetaData (); - // ok, we have the meta data, now loop through mapping... - int ncols = meta.getColumnCount (); - columns = new DbColumn[ncols]; - for (int i=0; i<ncols; i++) { - String colName = meta.getColumnName (i+1); - Relation rel = columnNameToRelation (colName); - columns[i] = new DbColumn (colName, meta.getColumnType (i+1), rel); - } - } - return columns; + public synchronized DbColumn[] getColumns() + throws ClassNotFoundException, SQLException { + if (!isRelational()) { + throw new SQLException("Can't get columns for non-relational data mapping " + + this); + } + + if ((dbSource == null) && (parentMapping != null)) { + return parentMapping.getColumns(); + } + + // Use local variable cols to avoid synchronization (schema may be nulled elsewhere) + if (columns == null) { + // we do two things here: set the SQL type on the Relation mappings + // and build a string of column names. + Connection con = getConnection(); + Statement stmt = con.createStatement(); + String t = getTableName(); + + if (t == null) { + throw new SQLException("Table name is null in getColumns() for " + this); + } + + ResultSet rs = stmt.executeQuery(new StringBuffer("SELECT * FROM ").append(t) + .append(" WHERE 1 = 0") + .toString()); + + if (rs == null) { + throw new SQLException("Error retrieving columns for " + this); + } + + ResultSetMetaData meta = rs.getMetaData(); + + // ok, we have the meta data, now loop through mapping... + int ncols = meta.getColumnCount(); + + columns = new DbColumn[ncols]; + + for (int i = 0; i < ncols; i++) { + String colName = meta.getColumnName(i + 1); + Relation rel = columnNameToRelation(colName); + + columns[i] = new DbColumn(colName, meta.getColumnType(i + 1), rel); + } + } + + return columns; } - public DbColumn getColumn (String columnName) throws ClassNotFoundException, SQLException { - DbColumn col = (DbColumn) columnMap.get(columnName); - if (col == null) { - DbColumn[] cols = columns; - if (cols == null) - cols = getColumns(); - for (int i=0; i<cols.length; i++) { - if (columnName.equalsIgnoreCase (cols[i].getName())) { - col = cols[i]; - break; - } - } - if (col == null) - throw new SQLException ("Column "+columnName+" not found in "+this); - columnMap.put (columnName, col); - } - return col; + /** + * + * + * @param columnName ... + * + * @return ... + * + * @throws ClassNotFoundException ... + * @throws SQLException ... + */ + public DbColumn getColumn(String columnName) + throws ClassNotFoundException, SQLException { + DbColumn col = (DbColumn) columnMap.get(columnName); + + if (col == null) { + DbColumn[] cols = columns; + + if (cols == null) { + cols = getColumns(); + } + + for (int i = 0; i < cols.length; i++) { + if (columnName.equalsIgnoreCase(cols[i].getName())) { + col = cols[i]; + + break; + } + } + + if (col == null) { + throw new SQLException("Column " + columnName + " not found in " + this); + } + + columnMap.put(columnName, col); + } + + return col; } - public StringBuffer getSelect () throws SQLException, ClassNotFoundException { - String sel = selectString; - if (sel != null) - return new StringBuffer (sel); - StringBuffer s = new StringBuffer ("SELECT * FROM "); - s.append (getTableName ()); - s.append (" "); - // cache rendered string for later calls. - selectString = s.toString(); - return s; + /** + * + * + * @return ... + * + * @throws SQLException ... + * @throws ClassNotFoundException ... + */ + public StringBuffer getSelect() throws SQLException, ClassNotFoundException { + String sel = selectString; + + if (sel != null) { + return new StringBuffer(sel); + } + + StringBuffer s = new StringBuffer("SELECT * FROM "); + + s.append(getTableName()); + s.append(" "); + + // cache rendered string for later calls. + selectString = s.toString(); + + return s; } + /** + * + * + * @return ... + */ + public StringBuffer getInsert() { + String ins = insertString; - public StringBuffer getInsert () { - String ins = insertString; - if (ins != null) - return new StringBuffer (ins); - StringBuffer s = new StringBuffer ("INSERT INTO "); - s.append (getTableName ()); - s.append (" ( "); - s.append (getIDField()); - // cache rendered string for later calls. - insertString = s.toString(); - return s; + if (ins != null) { + return new StringBuffer(ins); + } + + StringBuffer s = new StringBuffer("INSERT INTO "); + + s.append(getTableName()); + s.append(" ( "); + s.append(getIDField()); + + // cache rendered string for later calls. + insertString = s.toString(); + + return s; } - public StringBuffer getUpdate () { - String upd = updateString; - if (upd != null) - return new StringBuffer (upd); - StringBuffer s = new StringBuffer ("UPDATE "); - s.append (getTableName ()); - s.append (" SET "); - // cache rendered string for later calls. - updateString = s.toString(); - return s; + /** + * + * + * @return ... + */ + public StringBuffer getUpdate() { + String upd = updateString; + + if (upd != null) { + return new StringBuffer(upd); + } + + StringBuffer s = new StringBuffer("UPDATE "); + + s.append(getTableName()); + s.append(" SET "); + + // cache rendered string for later calls. + updateString = s.toString(); + + return s; } /** * Return true if values for the column identified by the parameter need * to be quoted in SQL queries. */ - public boolean needsQuotes (String columnName) throws SQLException { - if (tableName == null && parentMapping != null) - return parentMapping.needsQuotes (columnName); - try { - DbColumn col = getColumn (columnName); - switch (col.getType()) { - case Types.CHAR: - case Types.VARCHAR: - case Types.LONGVARCHAR: - case Types.BINARY: - case Types.VARBINARY: - case Types.LONGVARBINARY: - case Types.DATE: - case Types.TIME: - case Types.TIMESTAMP: - return true; - default: - return false; - } - } catch (Exception x) { - throw new SQLException (x.getMessage ()); - } + public boolean needsQuotes(String columnName) throws SQLException { + if ((tableName == null) && (parentMapping != null)) { + return parentMapping.needsQuotes(columnName); + } + + try { + DbColumn col = getColumn(columnName); + + switch (col.getType()) { + case Types.CHAR: + case Types.VARCHAR: + case Types.LONGVARCHAR: + case Types.BINARY: + case Types.VARBINARY: + case Types.LONGVARBINARY: + case Types.DATE: + case Types.TIME: + case Types.TIMESTAMP: + return true; + + default: + return false; + } + } catch (Exception x) { + throw new SQLException(x.getMessage()); + } } - - public String toString () { - if (typename == null) - return "[unspecified internal DbMapping]"; - else - return ("["+app.getName()+"."+typename+"]"); + /** + * + * + * @return ... + */ + public String toString() { + if (typename == null) { + return "[unspecified internal DbMapping]"; + } else { + return ("[" + app.getName() + "." + typename + "]"); + } } - public long getLastTypeChange () { - return lastTypeChange; + /** + * + * + * @return ... + */ + public long getLastTypeChange() { + return lastTypeChange; } - - public long getLastDataChange () { - return lastDataChange; + /** + * + * + * @return ... + */ + public long getLastDataChange() { + return lastDataChange; } - public void notifyDataChange () { - lastDataChange = System.currentTimeMillis (); - if (parentMapping != null && dbSource == null) - parentMapping.notifyDataChange (); + /** + * + */ + public void notifyDataChange() { + lastDataChange = System.currentTimeMillis(); + + if ((parentMapping != null) && (dbSource == null)) { + parentMapping.notifyDataChange(); + } } - public synchronized long getNewID (long dbmax) { - if (parentMapping != null && dbSource == null) - return parentMapping.getNewID (dbmax); - lastID = Math.max (dbmax+1, lastID+1); - return lastID; + /** + * + * + * @param dbmax ... + * + * @return ... + */ + public synchronized long getNewID(long dbmax) { + if ((parentMapping != null) && (dbSource == null)) { + return parentMapping.getNewID(dbmax); + } + + lastID = Math.max(dbmax + 1, lastID + 1); + + return lastID; } - - public Enumeration getPropertyEnumeration () { - HashSet set = new HashSet (); - collectPropertyNames (set); - final Iterator it = set.iterator(); - return new Enumeration () { - public boolean hasMoreElements() { - return it.hasNext(); - } - public Object nextElement() { - return it.next(); - } - }; + /** + * + * + * @return ... + */ + public Enumeration getPropertyEnumeration() { + HashSet set = new HashSet(); + + collectPropertyNames(set); + + final Iterator it = set.iterator(); + + return new Enumeration() { + public boolean hasMoreElements() { + return it.hasNext(); + } + + public Object nextElement() { + return it.next(); + } + }; } - private void collectPropertyNames (HashSet basket) { - // fetch propnames from parent mapping first, than add our own. - if (parentMapping != null) - parentMapping.collectPropertyNames (basket); - if (!prop2db.isEmpty()) - basket.addAll (prop2db.keySet()); + private void collectPropertyNames(HashSet basket) { + // fetch propnames from parent mapping first, than add our own. + if (parentMapping != null) { + parentMapping.collectPropertyNames(basket); + } + + if (!prop2db.isEmpty()) { + basket.addAll(prop2db.keySet()); + } } /** @@ -760,49 +1062,68 @@ public final class DbMapping implements Updatable { * (dbsource + tablename) for this type, or null if it is stored in the embedded * db. */ - public String getStorageTypeName () { - if (tableName == null && parentMapping != null) - return parentMapping.getStorageTypeName (); - return dbSourceName == null ? null : typename; + public String getStorageTypeName() { + if ((tableName == null) && (parentMapping != null)) { + return parentMapping.getStorageTypeName(); + } + + return (dbSourceName == null) ? null : typename; } /** * Tell if another DbMapping is storage-compatible to this one, i.e. it is stored in the same table or * embedded database. */ - public boolean isStorageCompatible (DbMapping other) { - if (other == null) - return !isRelational (); - if (isRelational ()) - return getTableName().equals (other.getTableName ()) && - getDbSource().equals (other.getDbSource ()); - return !other.isRelational (); + public boolean isStorageCompatible(DbMapping other) { + if (other == null) { + return !isRelational(); + } + + if (isRelational()) { + return getTableName().equals(other.getTableName()) && + getDbSource().equals(other.getDbSource()); + } + + return !other.isRelational(); } /** * Return true if this db mapping represents the prototype indicated * by the string argument, either itself or via one of its parent prototypes. */ - public boolean isInstanceOf (String other) { - if (typename != null && typename.equals (other)) - return true; - DbMapping p = parentMapping; - while (p != null) { - if (p.typename != null && p.typename.equals (other)) - return true; - p = p.parentMapping; - } - return false; + public boolean isInstanceOf(String other) { + if ((typename != null) && typename.equals(other)) { + return true; + } + + DbMapping p = parentMapping; + + while (p != null) { + if ((p.typename != null) && p.typename.equals(other)) { + return true; + } + + p = p.parentMapping; + } + + return false; } - - public DbMapping getParentMapping () { - return parentMapping; - } - - public SystemProperties getProperties () { - return props; + /** + * + * + * @return ... + */ + public DbMapping getParentMapping() { + return parentMapping; } + /** + * + * + * @return ... + */ + public SystemProperties getProperties() { + return props; + } } - diff --git a/src/helma/objectmodel/db/DbSource.java b/src/helma/objectmodel/db/DbSource.java index 5e0a5c4c..b5a2a627 100644 --- a/src/helma/objectmodel/db/DbSource.java +++ b/src/helma/objectmodel/db/DbSource.java @@ -1,120 +1,119 @@ -// DbSource.java -// Copyright (c) Hannes Wallnöfer 1999-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.objectmodel.db; +import helma.util.SystemProperties; import java.sql.*; import java.util.Hashtable; -import helma.util.SystemProperties; - + /** * This class describes a releational data source (URL, driver, user and password). */ - public class DbSource { - + private static SystemProperties defaultProps = null; private String name; private SystemProperties props; - private static SystemProperties defaultProps = null; protected String url; private String driver; protected String user; private String password; + private long lastRead = 0L; - private long lastRead = 0l; - - public DbSource (String name, SystemProperties props) throws ClassNotFoundException { - this.name = name; - this.props = props; - init (); + /** + * Creates a new DbSource object. + * + * @param name ... + * @param props ... + * + * @throws ClassNotFoundException ... + */ + public DbSource(String name, SystemProperties props) + throws ClassNotFoundException { + this.name = name; + this.props = props; + init(); } - public Connection getConnection () throws ClassNotFoundException, SQLException { - Transactor tx = (Transactor) Thread.currentThread (); - Connection con = tx.getConnection (this); - boolean fileUpdated = props.lastModified () > lastRead; - if (!fileUpdated && defaultProps != null) - fileUpdated = defaultProps.lastModified () > lastRead; - if (con == null || con.isClosed () || fileUpdated) { - init (); - Class.forName (driver); - con = DriverManager.getConnection (url, user, password); - // If we wanted to use SQL transactions, we'd set autoCommit to - // false here and make commit/rollback invocations in Transactor methods; - // System.err.println ("Created new Connection to "+url); - tx.registerConnection (this, con); - ////////////////////////////////////////////// - /* DatabaseMetaData meta = con.getMetaData (); - ResultSet tables = meta.getCatalogs (); - while (tables.next()) - System.err.println ("********* TABLE: "+ tables.getObject (1)); - ResultSet types = meta.getTypeInfo (); - while (types.next()) - System.err.println ("******* TYPE: "+types.getObject(1) +" - "+types.getObject(2)+" - "+types.getObject(6)); - */ - } - return con; + /** + * + * + * @return ... + * + * @throws ClassNotFoundException ... + * @throws SQLException ... + */ + public Connection getConnection() throws ClassNotFoundException, SQLException { + Transactor tx = (Transactor) Thread.currentThread(); + Connection con = tx.getConnection(this); + boolean fileUpdated = props.lastModified() > lastRead; + + if (!fileUpdated && (defaultProps != null)) { + fileUpdated = defaultProps.lastModified() > lastRead; + } + + if ((con == null) || con.isClosed() || fileUpdated) { + init(); + Class.forName(driver); + con = DriverManager.getConnection(url, user, password); + + // If we wanted to use SQL transactions, we'd set autoCommit to + // false here and make commit/rollback invocations in Transactor methods; + // System.err.println ("Created new Connection to "+url); + tx.registerConnection(this, con); + } + + return con; } - private void init () throws ClassNotFoundException { - lastRead = defaultProps == null ? props.lastModified () : Math.max (props.lastModified (), defaultProps.lastModified ()); - url = props.getProperty (name+".url"); - driver = props.getProperty (name+".driver"); - Class.forName (driver); - user = props.getProperty (name+".user"); - password = props.getProperty (name+".password"); + private void init() throws ClassNotFoundException { + lastRead = (defaultProps == null) ? props.lastModified() + : Math.max(props.lastModified(), + defaultProps.lastModified()); + url = props.getProperty(name + ".url"); + driver = props.getProperty(name + ".driver"); + Class.forName(driver); + user = props.getProperty(name + ".user"); + password = props.getProperty(name + ".password"); } - public String getDriverName () { - return driver; + /** + * + * + * @return ... + */ + public String getDriverName() { + return driver; } - public String getName () { - return name; + /** + * + * + * @return ... + */ + public String getName() { + return name; } - public static void setDefaultProps (SystemProperties props) { - defaultProps = props; + /** + * + * + * @param props ... + */ + public static void setDefaultProps(SystemProperties props) { + defaultProps = props; } - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/helma/objectmodel/db/ExternalizableVector.java b/src/helma/objectmodel/db/ExternalizableVector.java index bcea489d..04e1bbe9 100644 --- a/src/helma/objectmodel/db/ExternalizableVector.java +++ b/src/helma/objectmodel/db/ExternalizableVector.java @@ -1,5 +1,18 @@ -// ExternalizableVector.java -// Copyright (c) Hannes Wallnöfer 1999-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.objectmodel.db; @@ -7,33 +20,45 @@ import java.io.*; import java.util.ArrayList; /** - * A subclass of Vector that implements the Externalizable interface in order + * A subclass of Vector that implements the Externalizable interface in order * to be able to control how it is serialized and deserialized. */ - public class ExternalizableVector extends ArrayList implements Externalizable { - static final long serialVersionUID = 2316243615310540423L; - public synchronized void readExternal (ObjectInput in) throws IOException { - try { - int size = in.readInt (); - for (int i=0; i<size; i++) - add (in.readObject ()); - } catch (ClassNotFoundException x) { - throw new IOException (x.toString ()); - } + /** + * + * + * @param in ... + * + * @throws IOException ... + */ + public synchronized void readExternal(ObjectInput in) + throws IOException { + try { + int size = in.readInt(); + + for (int i = 0; i < size; i++) + add(in.readObject()); + } catch (ClassNotFoundException x) { + throw new IOException(x.toString()); + } } - public synchronized void writeExternal (ObjectOutput out) throws IOException { - int size = size (); - out.writeInt (size); - for (int i=0; i<size; i++) - out.writeObject (get (i)); - } + /** + * + * + * @param out ... + * + * @throws IOException ... + */ + public synchronized void writeExternal(ObjectOutput out) + throws IOException { + int size = size(); + out.writeInt(size); + + for (int i = 0; i < size; i++) + out.writeObject(get(i)); + } } - - - - diff --git a/src/helma/objectmodel/db/IDGenerator.java b/src/helma/objectmodel/db/IDGenerator.java index 414b573e..68fd7006 100644 --- a/src/helma/objectmodel/db/IDGenerator.java +++ b/src/helma/objectmodel/db/IDGenerator.java @@ -1,73 +1,84 @@ -// IDGenerator.java -// Copyright (c) Hannes Wallnöfer 1997-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.objectmodel.db; import java.io.Serializable; /** - * An object that generates IDs (Strings) that are unique across the whole system. - * It does this keeping a simple long value which is incremented for each new ID. - * This is the key generation for nodes stored in the internal database, but it can - * also be used for relational nodes if no other mechanism is available. (Sequences + * An object that generates IDs (Strings) that are unique across the whole system. + * It does this keeping a simple long value which is incremented for each new ID. + * This is the key generation for nodes stored in the internal database, but it can + * also be used for relational nodes if no other mechanism is available. (Sequences * in Oracle are supported, while auto-IDs are not, since the HOP has to know * the keys of new objects.) */ - public final class IDGenerator implements Serializable { - + static final long serialVersionUID = 753408631669789263L; private long counter; transient volatile boolean dirty; - - static final long serialVersionUID = 753408631669789263L; - /** * Builds a new IDGenerator starting with 0. - */ - public IDGenerator () { - this.counter = 0l; - dirty = false; + */ + public IDGenerator() { + this.counter = 0L; + dirty = false; } /** * Builds a new IDGenerator starting with value. - */ - public IDGenerator (long value) { - this.counter = value; - dirty = false; + */ + public IDGenerator(long value) { + this.counter = value; + dirty = false; } /** - * Delivers a unique id and increases counter by 1. - */ - public synchronized String newID () { - counter += 1l; - dirty = true; - return Long.toString (counter); + * Delivers a unique id and increases counter by 1. + */ + public synchronized String newID() { + counter += 1L; + dirty = true; + + return Long.toString(counter); } /** * Set the counter to a new value */ - protected synchronized void setValue (long value) { - counter = value; - dirty = true; + protected synchronized void setValue(long value) { + counter = value; + dirty = true; } /** * Get the current counter value */ - public long getValue () { - return counter; + public long getValue() { + return counter; } - - public String toString () { - return "helma.objectmodel.db.IDGenerator[counter="+counter+",dirty="+dirty+"]"; + /** + * + * + * @return ... + */ + public String toString() { + return "helma.objectmodel.db.IDGenerator[counter=" + counter + ",dirty=" + dirty + + "]"; } - } - - - diff --git a/src/helma/objectmodel/db/IReplicationListener.java b/src/helma/objectmodel/db/IReplicationListener.java index 18eeff59..55e0ee58 100644 --- a/src/helma/objectmodel/db/IReplicationListener.java +++ b/src/helma/objectmodel/db/IReplicationListener.java @@ -1,5 +1,18 @@ -// IReplicationListener.java -// Copyright (c) Hannes Wallnöfer 2002 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.objectmodel.db; @@ -9,13 +22,11 @@ import java.util.Vector; /** * RMI interface for an application. Currently only execute is used and supported. */ - public interface IReplicationListener extends Remote { - /** * Update HopObjects in this application's cache. This is used to replicate * application caches in a distributed app environment */ - public void replicateCache (Vector add, Vector delete) throws RemoteException; - + public void replicateCache(Vector add, Vector delete) + throws RemoteException; } diff --git a/src/helma/objectmodel/db/Key.java b/src/helma/objectmodel/db/Key.java index f48d66ab..850450eb 100644 --- a/src/helma/objectmodel/db/Key.java +++ b/src/helma/objectmodel/db/Key.java @@ -1,6 +1,19 @@ -// Key.java -// Copyright (c) Hannes Wallnöfer 1998-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel.db; @@ -9,66 +22,24 @@ package helma.objectmodel.db; * */ public interface Key { + /** + * + * + * @return ... + */ + public Key getParentKey(); + /** + * + * + * @return ... + */ + public String getID(); - public Key getParentKey (); - - public String getID (); - - public String getStorageName (); - + /** + * + * + * @return ... + */ + public String getStorageName(); } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/helma/objectmodel/db/Node.java b/src/helma/objectmodel/db/Node.java index a7775c68..c9e85186 100644 --- a/src/helma/objectmodel/db/Node.java +++ b/src/helma/objectmodel/db/Node.java @@ -1,175 +1,86 @@ -// Node.java -// Copyright (c) Hannes Wallnöfer 1997-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel.db; - -import java.util.Vector; -import java.util.Hashtable; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.Date; -import java.util.List; -import java.util.StringTokenizer; -import java.io.*; -import java.sql.*; +import helma.framework.IPathElement; import helma.objectmodel.*; import helma.util.*; -import helma.framework.IPathElement; +import java.io.*; import java.math.BigDecimal; - +import java.sql.*; +import java.util.Date; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.StringTokenizer; +import java.util.Vector; /** * An implementation of INode that can be stored in the internal database or - * an external relational database. + * an external relational database. */ - public final class Node implements INode, Serializable { + static final long serialVersionUID = -3740339688506633675L; // The handle to the node's parent protected NodeHandle parentHandle; + // Ordered list of subnodes of this node private List subnodes; + // Named subnodes (properties) of this node private Hashtable propMap; + // Other nodes that link to this node. Used for reference counting/checking private List links; - protected long created; protected long lastmodified; + private String id; + private String name; - private String id, name; // is this node's main identity as a named property or an // anonymous node in a subnode collection? protected boolean anonymous = false; // the serialization version this object was read from (see readObject()) protected short version = 0; - - /** - * Read this object instance from a stream. This does some smart conversion to - * update from previous serialization formats. - */ - private void readObject (ObjectInputStream in) throws IOException { - try { - // as a general rule of thumb, if a string can be null use read/writeObject, - // if not it's save to use read/writeUTF. - // version indicates the serialization version - version = in.readShort (); - String rawParentID = null; - id = in.readUTF (); - name = in.readUTF (); - if (version < 5) - rawParentID = (String) in.readObject (); - else - parentHandle = (NodeHandle) in.readObject (); - created = in.readLong (); - lastmodified = in.readLong (); - if (version < 4) { - // read away content and contentType, which were dropped - in.readObject (); - in.readObject (); - } - subnodes = (ExternalizableVector) in.readObject (); - links = (ExternalizableVector) in.readObject (); - if (version < 6) - // read away obsolete proplinks list - in.readObject (); - propMap = (Hashtable) in.readObject (); - anonymous = in.readBoolean (); - if (version == 2) - prototype = in.readUTF (); - else if (version >= 3) - prototype = (String) in.readObject (); - // if the input version is < 5, we have to do some conversion to make this object work - if (version < 5) { - if (rawParentID != null) - parentHandle = new NodeHandle (new DbKey (null, rawParentID)); - if (subnodes != null) { - for (int i=0; i<subnodes.size(); i++) { - String s = (String) subnodes.get (i); - subnodes.set (i, new NodeHandle (new DbKey (null, s))); - } - } - if (links != null) { - for (int i=0; i<links.size(); i++) { - String s = (String) links.get (i); - links.set (i, new NodeHandle (new DbKey (null, s))); - } - } - } - } catch (ClassNotFoundException x) { - throw new IOException (x.toString ()); - } - } - - /** - * Write out this instance to a stream - */ - private void writeObject (ObjectOutputStream out) throws IOException { - out.writeShort (7); // serialization version - out.writeUTF (id); - out.writeUTF (name); - out.writeObject (parentHandle); - out.writeLong (created); - out.writeLong (lastmodified); - DbMapping smap = dbmap == null ? null : dbmap.getSubnodeMapping (); - if (smap != null && smap.isRelational ()) - out.writeObject (null); - else - out.writeObject (subnodes); - out.writeObject (links); - out.writeObject (propMap); - out.writeBoolean (anonymous); - out.writeObject (prototype); - } - - /** - * used by Xml deserialization - */ - public void setPropMap (Hashtable propMap) { - this.propMap = propMap; - } - - /** - * used by Xml deserialization - */ - public void setSubnodes (List subnodes) { - this.subnodes = subnodes; - } - private transient String prototype; - private transient NodeHandle handle; - private transient INode cacheNode; - transient WrappedNodeManager nmgr; - transient DbMapping dbmap; - transient Key primaryKey = null; - transient String subnodeRelation = null; transient long lastSubnodeFetch = 0; transient long lastSubnodeChange = 0; transient long lastNameCheck = 0; transient long lastParentSet = 0; - - transient long lastSubnodeCount = 0; // these two are only used - transient int subnodeCount = -1; // for aggressive loading relational subnodes - + transient long lastSubnodeCount = 0; // these two are only used + transient int subnodeCount = -1; // for aggressive loading relational subnodes transient private volatile Transactor lock; transient private int state; - static final long serialVersionUID = -3740339688506633675L; - /** * This constructor is only used for instances of the NullNode subclass. Do not use for ordinary Nodes. */ - Node () { - created = lastmodified = System.currentTimeMillis (); - nmgr = null; + Node() { + created = lastmodified = System.currentTimeMillis(); + nmgr = null; } /** @@ -177,464 +88,722 @@ public final class Node implements INode, Serializable { * not in a Transaction context, which is why we can immediately mark it as CLEAN. * ADD: used by wrapped database to re-create an existing Node. */ - public Node (String name, String id, String prototype, WrappedNodeManager nmgr) { - this.nmgr = nmgr; - this.id = id; - this.name = name == null || "".equals (name) ? id : name; - if (prototype != null) - setPrototype (prototype); - created = lastmodified = System.currentTimeMillis (); - markAs (CLEAN); - } + public Node(String name, String id, String prototype, WrappedNodeManager nmgr) { + this.nmgr = nmgr; + this.id = id; + this.name = ((name == null) || "".equals(name)) ? id : name; + if (prototype != null) { + setPrototype(prototype); + } + + created = lastmodified = System.currentTimeMillis(); + markAs(CLEAN); + } /** * Constructor used to create a Node with a given name from a wrapped database. */ - public Node (String name, String id, String prototype, WrappedNodeManager nmgr, long created, long lastmodified) { - this (name,id,prototype,nmgr); - this.created = created; - this.lastmodified = lastmodified; + public Node(String name, String id, String prototype, WrappedNodeManager nmgr, + long created, long lastmodified) { + this(name, id, prototype, nmgr); + this.created = created; + this.lastmodified = lastmodified; } - - /** * Constructor used for virtual nodes. */ - public Node (Node home, String propname, WrappedNodeManager nmgr, String prototype) { - this.nmgr = nmgr; - setParent (home); - // this.dbmap = null; - // generate a key for the virtual node that can't be mistaken for a Database Key - primaryKey = new SyntheticKey (home.getKey (), propname); - this.id = primaryKey.getID (); - this.name = propname; - this.anonymous = false; - setPrototype (prototype); - this.state = VIRTUAL; + public Node(Node home, String propname, WrappedNodeManager nmgr, String prototype) { + this.nmgr = nmgr; + setParent(home); + + // this.dbmap = null; + // generate a key for the virtual node that can't be mistaken for a Database Key + primaryKey = new SyntheticKey(home.getKey(), propname); + this.id = primaryKey.getID(); + this.name = propname; + this.anonymous = false; + setPrototype(prototype); + this.state = VIRTUAL; } /** * Creates a new Node with the given name. This is used for ordinary transient nodes. */ - public Node (String n, String prototype, WrappedNodeManager nmgr) { - this.nmgr = nmgr; - this.prototype = prototype; - dbmap = nmgr.getDbMapping (prototype); - // the id is only generated when the node is actually checked into db, - // or when it's explicitly requested. - id = null; - this.name = n == null ? "" : n; - created = lastmodified = System.currentTimeMillis (); - state = TRANSIENT; - } + public Node(String n, String prototype, WrappedNodeManager nmgr) { + this.nmgr = nmgr; + this.prototype = prototype; + dbmap = nmgr.getDbMapping(prototype); + // the id is only generated when the node is actually checked into db, + // or when it's explicitly requested. + id = null; + this.name = (n == null) ? "" : n; + created = lastmodified = System.currentTimeMillis(); + state = TRANSIENT; + } /** * Constructor used for nodes being stored in a relational database table. */ - public Node (DbMapping dbm, ResultSet rs, DbColumn[] columns, WrappedNodeManager nmgr) - throws SQLException, IOException { + public Node(DbMapping dbm, ResultSet rs, DbColumn[] columns, WrappedNodeManager nmgr) + throws SQLException, IOException { + this.nmgr = nmgr; - this.nmgr = nmgr; - // see what prototype/DbMapping this object should use - dbmap = dbm; - String protoField= dbmap.getPrototypeField (); - if (protoField != null) { - String protoName = rs.getString (protoField); - if (protoName != null) { - dbmap = nmgr.getDbMapping (protoName); - if (dbmap == null) { - // invalid prototype name! - System.err.println ("Warning: Invalid prototype name: "+protoName+" - using default"); - dbmap = dbm; - } - } - } - setPrototype (dbmap.getTypeName ()); + // see what prototype/DbMapping this object should use + dbmap = dbm; - id = rs.getString (dbmap.getIDField ()); - // checkWriteLock (); - String nameField = dbmap.getNameField (); - name = nameField == null ? id : rs.getString (nameField); - if (name == null || name.length() == 0) - name = dbmap.getTypeName() + " " + id; + String protoField = dbmap.getPrototypeField(); - created = lastmodified = System.currentTimeMillis (); + if (protoField != null) { + String protoName = rs.getString(protoField); - for (int i=0; i<columns.length; i++) { + if (protoName != null) { + dbmap = nmgr.getDbMapping(protoName); - Relation rel = columns[i].getRelation(); - if (rel == null || (rel.reftype != Relation.PRIMITIVE && - rel.reftype != Relation.REFERENCE)) - continue; + if (dbmap == null) { + // invalid prototype name! + System.err.println("Warning: Invalid prototype name: " + protoName + + " - using default"); + dbmap = dbm; + } + } + } - Property newprop = new Property (rel.propName, this); + setPrototype(dbmap.getTypeName()); - switch (columns[i].getType()) { + id = rs.getString(dbmap.getIDField()); - case Types.BIT: - newprop.setBooleanValue (rs.getBoolean(columns[i].getName())); - break; + // checkWriteLock (); + String nameField = dbmap.getNameField(); - case Types.TINYINT: - case Types.BIGINT: - case Types.SMALLINT: - case Types.INTEGER: - newprop.setIntegerValue (rs.getLong(columns[i].getName())); - break; + name = (nameField == null) ? id : rs.getString(nameField); - case Types.REAL: - case Types.FLOAT: - case Types.DOUBLE: - newprop.setFloatValue (rs.getDouble(columns[i].getName())); - break; + if ((name == null) || (name.length() == 0)) { + name = dbmap.getTypeName() + " " + id; + } - case Types.DECIMAL: - case Types.NUMERIC: - BigDecimal num = rs.getBigDecimal (columns[i].getName()); - if (num == null) - break; - if (num.scale() > 0) - newprop.setFloatValue (num.doubleValue ()); - else - newprop.setIntegerValue (num.longValue ()); - break; + created = lastmodified = System.currentTimeMillis(); - case Types.VARBINARY: - case Types.BINARY: - newprop.setStringValue (rs.getString(columns[i].getName())); - break; + for (int i = 0; i < columns.length; i++) { + Relation rel = columns[i].getRelation(); - case Types.LONGVARBINARY: - case Types.LONGVARCHAR: - try { - newprop.setStringValue (rs.getString(columns[i].getName())); - } catch (SQLException x) { - Reader in = rs.getCharacterStream(columns[i].getName()); - char[] buffer = new char[2048]; - int read = 0, r = 0; - while ((r = in.read (buffer, read, buffer.length-read)) > -1) { - read += r; - if (read == buffer.length) { - // grow input buffer - char[] newBuffer = new char[buffer.length*2]; - System.arraycopy (buffer, 0, newBuffer, 0, buffer.length); - buffer = newBuffer; - } - } - newprop.setStringValue (new String(buffer, 0, read)); - } - break; + if ((rel == null) || + ((rel.reftype != Relation.PRIMITIVE) && + (rel.reftype != Relation.REFERENCE))) { + continue; + } - case Types.CHAR: - case Types.VARCHAR: - case Types.OTHER: - newprop.setStringValue (rs.getString(columns[i].getName())); - break; + Property newprop = new Property(rel.propName, this); - case Types.DATE: - case Types.TIME: - case Types.TIMESTAMP: - newprop.setDateValue (rs.getTimestamp(columns[i].getName())); - break; + switch (columns[i].getType()) { + case Types.BIT: + newprop.setBooleanValue(rs.getBoolean(columns[i].getName())); - case Types.NULL: - newprop.setStringValue (null); - break; - // continue; + break; - default: - newprop.setStringValue (rs.getString(columns[i].getName())); - break; - } + case Types.TINYINT: + case Types.BIGINT: + case Types.SMALLINT: + case Types.INTEGER: + newprop.setIntegerValue(rs.getLong(columns[i].getName())); - if (rs.wasNull()) - newprop.setStringValue (null); + break; - if(propMap == null) - propMap = new Hashtable (); - propMap.put (rel.propName.toLowerCase(), newprop); + case Types.REAL: + case Types.FLOAT: + case Types.DOUBLE: + newprop.setFloatValue(rs.getDouble(columns[i].getName())); - // if the property is a pointer to another node, change the property type to NODE - if (rel.reftype == Relation.REFERENCE && rel.usesPrimaryKey ()) { - // FIXME: References to anything other than the primary key are not supported - newprop.convertToNodeReference (rel.otherType); - // newprop.nhandle = new NodeHandle (new DbKey (rel.otherType, newprop.getStringValue ())); - // newprop.type = IProperty.NODE; - } + break; - // mark property as clean, since it's fresh from the db - newprop.dirty = false; - } - // again set created and lastmodified. This is because - // lastmodified has been been updated, and we want both values to - // be identical to show that the node hasn't been changed since - // it was first created. - created = lastmodified = System.currentTimeMillis (); - markAs (CLEAN); + case Types.DECIMAL: + case Types.NUMERIC: + + BigDecimal num = rs.getBigDecimal(columns[i].getName()); + + if (num == null) { + break; + } + + if (num.scale() > 0) { + newprop.setFloatValue(num.doubleValue()); + } else { + newprop.setIntegerValue(num.longValue()); + } + + break; + + case Types.VARBINARY: + case Types.BINARY: + newprop.setStringValue(rs.getString(columns[i].getName())); + + break; + + case Types.LONGVARBINARY: + case Types.LONGVARCHAR: + + try { + newprop.setStringValue(rs.getString(columns[i].getName())); + } catch (SQLException x) { + Reader in = rs.getCharacterStream(columns[i].getName()); + char[] buffer = new char[2048]; + int read = 0; + int r = 0; + + while ((r = in.read(buffer, read, buffer.length - read)) > -1) { + read += r; + + if (read == buffer.length) { + // grow input buffer + char[] newBuffer = new char[buffer.length * 2]; + + System.arraycopy(buffer, 0, newBuffer, 0, buffer.length); + buffer = newBuffer; + } + } + + newprop.setStringValue(new String(buffer, 0, read)); + } + + break; + + case Types.CHAR: + case Types.VARCHAR: + case Types.OTHER: + newprop.setStringValue(rs.getString(columns[i].getName())); + + break; + + case Types.DATE: + case Types.TIME: + case Types.TIMESTAMP: + newprop.setDateValue(rs.getTimestamp(columns[i].getName())); + + break; + + case Types.NULL: + newprop.setStringValue(null); + + break; + + // continue; + default: + newprop.setStringValue(rs.getString(columns[i].getName())); + + break; + } + + if (rs.wasNull()) { + newprop.setStringValue(null); + } + + if (propMap == null) { + propMap = new Hashtable(); + } + + propMap.put(rel.propName.toLowerCase(), newprop); + + // if the property is a pointer to another node, change the property type to NODE + if ((rel.reftype == Relation.REFERENCE) && rel.usesPrimaryKey()) { + // FIXME: References to anything other than the primary key are not supported + newprop.convertToNodeReference(rel.otherType); + + // newprop.nhandle = new NodeHandle (new DbKey (rel.otherType, newprop.getStringValue ())); + // newprop.type = IProperty.NODE; + } + + // mark property as clean, since it's fresh from the db + newprop.dirty = false; + } + + // again set created and lastmodified. This is because + // lastmodified has been been updated, and we want both values to + // be identical to show that the node hasn't been changed since + // it was first created. + created = lastmodified = System.currentTimeMillis(); + markAs(CLEAN); } + /** + * Read this object instance from a stream. This does some smart conversion to + * update from previous serialization formats. + */ + private void readObject(ObjectInputStream in) throws IOException { + try { + // as a general rule of thumb, if a string can be null use read/writeObject, + // if not it's save to use read/writeUTF. + // version indicates the serialization version + version = in.readShort(); + String rawParentID = null; - protected synchronized void checkWriteLock () { - // System.err.println ("registering writelock for "+this.getName ()+" ("+lock+") to "+Thread.currentThread ()); - if (state == TRANSIENT) - return; // no need to lock transient node - Transactor current = (Transactor) Thread.currentThread (); + id = in.readUTF(); + name = in.readUTF(); - if (!current.isActive ()) - throw new helma.framework.TimeoutException (); - if (state == INVALID) { - nmgr.logEvent ("Got Invalid Node: "+this); - Thread.dumpStack (); - throw new ConcurrencyException ("Node "+this+" was invalidated by another thread."); - } + if (version < 5) { + rawParentID = (String) in.readObject(); + } else { + parentHandle = (NodeHandle) in.readObject(); + } - if (lock != null && lock != current && lock.isAlive () && lock.isActive ()) { - nmgr.logEvent ("Concurrency conflict for "+this+", lock held by "+lock); - throw new ConcurrencyException ("Tried to modify "+this+" from two threads at the same time."); - } + created = in.readLong(); + lastmodified = in.readLong(); - current.visitNode (this); - lock = current; + if (version < 4) { + // read away content and contentType, which were dropped + in.readObject(); + in.readObject(); + } + + subnodes = (ExternalizableVector) in.readObject(); + links = (ExternalizableVector) in.readObject(); + + if (version < 6) { + // read away obsolete proplinks list + in.readObject(); + } + + propMap = (Hashtable) in.readObject(); + anonymous = in.readBoolean(); + + if (version == 2) { + prototype = in.readUTF(); + } else if (version >= 3) { + prototype = (String) in.readObject(); + } + + // if the input version is < 5, we have to do some conversion to make this object work + if (version < 5) { + if (rawParentID != null) { + parentHandle = new NodeHandle(new DbKey(null, rawParentID)); + } + + if (subnodes != null) { + for (int i = 0; i < subnodes.size(); i++) { + String s = (String) subnodes.get(i); + + subnodes.set(i, new NodeHandle(new DbKey(null, s))); + } + } + + if (links != null) { + for (int i = 0; i < links.size(); i++) { + String s = (String) links.get(i); + + links.set(i, new NodeHandle(new DbKey(null, s))); + } + } + } + } catch (ClassNotFoundException x) { + throw new IOException(x.toString()); + } } - protected synchronized void clearWriteLock () { - lock = null; + /** + * Write out this instance to a stream + */ + private void writeObject(ObjectOutputStream out) throws IOException { + out.writeShort(7); // serialization version + out.writeUTF(id); + out.writeUTF(name); + out.writeObject(parentHandle); + out.writeLong(created); + out.writeLong(lastmodified); + + DbMapping smap = (dbmap == null) ? null : dbmap.getSubnodeMapping(); + + if ((smap != null) && smap.isRelational()) { + out.writeObject(null); + } else { + out.writeObject(subnodes); + } + + out.writeObject(links); + out.writeObject(propMap); + out.writeBoolean(anonymous); + out.writeObject(prototype); } - - protected void markAs (int s) { - if (state == INVALID || state == VIRTUAL || state == TRANSIENT) - return; - state = s; - if (Thread.currentThread () instanceof Transactor) { - Transactor tx = (Transactor) Thread.currentThread (); - if (s == CLEAN) { - clearWriteLock (); - tx.dropNode (this); - } else { - tx.visitNode (this); - if (s == NEW) { - clearWriteLock (); - tx.visitCleanNode (this); - } - } - } + /** + * used by Xml deserialization + */ + public void setPropMap(Hashtable propMap) { + this.propMap = propMap; } - public int getState () { - return state; + /** + * used by Xml deserialization + */ + public void setSubnodes(List subnodes) { + this.subnodes = subnodes; } - public void setState (int s) { - this.state = s; + protected synchronized void checkWriteLock() { + // System.err.println ("registering writelock for "+this.getName ()+" ("+lock+") to "+Thread.currentThread ()); + if (state == TRANSIENT) { + return; // no need to lock transient node + } + + Transactor current = (Transactor) Thread.currentThread(); + + if (!current.isActive()) { + throw new helma.framework.TimeoutException(); + } + + if (state == INVALID) { + nmgr.logEvent("Got Invalid Node: " + this); + Thread.dumpStack(); + throw new ConcurrencyException("Node " + this + + " was invalidated by another thread."); + } + + if ((lock != null) && (lock != current) && lock.isAlive() && lock.isActive()) { + nmgr.logEvent("Concurrency conflict for " + this + ", lock held by " + lock); + throw new ConcurrencyException("Tried to modify " + this + + " from two threads at the same time."); + } + + current.visitNode(this); + lock = current; + } + + protected synchronized void clearWriteLock() { + lock = null; + } + + protected void markAs(int s) { + if ((state == INVALID) || (state == VIRTUAL) || (state == TRANSIENT)) { + return; + } + + state = s; + + if (Thread.currentThread() instanceof Transactor) { + Transactor tx = (Transactor) Thread.currentThread(); + + if (s == CLEAN) { + clearWriteLock(); + tx.dropNode(this); + } else { + tx.visitNode(this); + + if (s == NEW) { + clearWriteLock(); + tx.visitCleanNode(this); + } + } + } + } + + /** + * + * + * @return ... + */ + public int getState() { + return state; + } + + /** + * + * + * @param s ... + */ + public void setState(int s) { + this.state = s; } /** * Mark node as invalid so it is re-fetched from the database */ - public void invalidate () { - // This doesn't make sense for transient nodes - if (state == TRANSIENT || state == NEW) - return; - checkWriteLock (); - nmgr.evictNode (this); + public void invalidate() { + // This doesn't make sense for transient nodes + if ((state == TRANSIENT) || (state == NEW)) { + return; + } + + checkWriteLock(); + nmgr.evictNode(this); } /** * Check for a child mapping and evict the object specified by key from the cache */ - public void invalidateNode (String key) { - // This doesn't make sense for transient nodes - if (state == TRANSIENT || state == NEW) - return; - Relation rel = getDbMapping ().getSubnodeRelation (); - if (rel != null) { - if (rel.usesPrimaryKey()) { - nmgr.evictNodeByKey (new DbKey (getDbMapping().getSubnodeMapping(), key)); - } else { - nmgr.evictNodeByKey (new SyntheticKey (getKey(), key)); - } - } + public void invalidateNode(String key) { + // This doesn't make sense for transient nodes + if ((state == TRANSIENT) || (state == NEW)) { + return; + } + + Relation rel = getDbMapping().getSubnodeRelation(); + + if (rel != null) { + if (rel.usesPrimaryKey()) { + nmgr.evictNodeByKey(new DbKey(getDbMapping().getSubnodeMapping(), key)); + } else { + nmgr.evictNodeByKey(new SyntheticKey(getKey(), key)); + } + } } - - /** + /** * Get the ID of this Node. This is the primary database key and used as part of the * key for the internal node cache. */ - public String getID () { - // if we are transient, we generate an id on demand. It's possible that we'll never need - // it, but if we do it's important to keep the one we have. - if (state == TRANSIENT && id == null) { - id = TransientNode.generateID (); - } - return id; + public String getID() { + // if we are transient, we generate an id on demand. It's possible that we'll never need + // it, but if we do it's important to keep the one we have. + if ((state == TRANSIENT) && (id == null)) { + id = TransientNode.generateID(); + } + + return id; } /** * Returns true if this node is accessed by id from its aprent, false if it * is accessed by name */ - public boolean isAnonymous () { - return anonymous; + public boolean isAnonymous() { + return anonymous; } /** * Return this node' name, which may or may not have some meaning */ - public String getName () { - return name; + public String getName() { + return name; } - + /** * Get something to identify this node within a URL. This is the ID for anonymous nodes * and a property value for named properties. */ - public String getElementName () { - // if subnodes are also mounted as properties, try to get the "nice" prop value - // instead of the id by turning the anonymous flag off. - if (parentHandle != null && lastNameCheck < Math.max (dbmap.getLastTypeChange(), lastmodified)) { - try { - Node p = parentHandle.getNode (nmgr); - DbMapping parentmap = p.getDbMapping (); - Relation prel = parentmap.getPropertyRelation(); - if (prel != null && prel.hasAccessName()) { - String propname = dbmap.columnNameToProperty (prel.accessName); - String propvalue = getString (propname); - if (propvalue != null && propvalue.length() > 0) { - setName (propvalue); - anonymous = false; - // nameProp = localrel.propName; - } else { - anonymous = true; - } - } else if (!anonymous && p.contains (this) > -1) { - anonymous = true; - } - } catch (Exception ignore) { - // just fall back to default method - } - lastNameCheck = System.currentTimeMillis (); - } - return anonymous || name == null || name.length() == 0 ? id : name; + public String getElementName() { + // if subnodes are also mounted as properties, try to get the "nice" prop value + // instead of the id by turning the anonymous flag off. + if ((parentHandle != null) && + (lastNameCheck < Math.max(dbmap.getLastTypeChange(), lastmodified))) { + try { + Node p = parentHandle.getNode(nmgr); + DbMapping parentmap = p.getDbMapping(); + Relation prel = parentmap.getPropertyRelation(); + + if ((prel != null) && prel.hasAccessName()) { + String propname = dbmap.columnNameToProperty(prel.accessName); + String propvalue = getString(propname); + + if ((propvalue != null) && (propvalue.length() > 0)) { + setName(propvalue); + anonymous = false; + + // nameProp = localrel.propName; + } else { + anonymous = true; + } + } else if (!anonymous && (p.contains(this) > -1)) { + anonymous = true; + } + } catch (Exception ignore) { + // just fall back to default method + } + + lastNameCheck = System.currentTimeMillis(); + } + + return (anonymous || (name == null) || (name.length() == 0)) ? id : name; } - - public String getFullName () { - return getFullName (null); + /** + * + * + * @return ... + */ + public String getFullName() { + return getFullName(null); } - public String getFullName (INode root) { - String fullname = ""; - String divider = null; - StringBuffer b = new StringBuffer (); - INode p = this; - int loopWatch = 0; + /** + * + * + * @param root ... + * + * @return ... + */ + public String getFullName(INode root) { + String fullname = ""; + String divider = null; + StringBuffer b = new StringBuffer(); + INode p = this; + int loopWatch = 0; - while (p != null && p.getParent () != null && p != root) { - if (divider != null) - b.insert (0, divider); - else - divider = "/"; - b.insert (0, p.getElementName ()); - p = p.getParent (); + while ((p != null) && (p.getParent() != null) && (p != root)) { + if (divider != null) { + b.insert(0, divider); + } else { + divider = "/"; + } - loopWatch++; - if (loopWatch > 10) { - b.insert (0, "..."); - break; - } - } - return b.toString (); + b.insert(0, p.getElementName()); + p = p.getParent(); + + loopWatch++; + + if (loopWatch > 10) { + b.insert(0, "..."); + + break; + } + } + + return b.toString(); } + /** + * + * + * @return ... + */ + public String getPrototype() { + // if prototype is null, it's a vanilla HopObject. + if (prototype == null) { + return "hopobject"; + } - public String getPrototype () { - // if prototype is null, it's a vanilla HopObject. - if (prototype == null) - return "hopobject"; - return prototype; + return prototype; } - public void setPrototype (String proto) { - this.prototype = proto; + /** + * + * + * @param proto ... + */ + public void setPrototype(String proto) { + this.prototype = proto; } + /** + * + * + * @param dbmap ... + */ + public void setDbMapping(DbMapping dbmap) { + if (this.dbmap != dbmap) { + this.dbmap = dbmap; - public void setDbMapping (DbMapping dbmap) { - if (this.dbmap != dbmap) { - this.dbmap = dbmap; - // primaryKey = null; - } + // primaryKey = null; + } } - public DbMapping getDbMapping () { - return dbmap; + /** + * + * + * @return ... + */ + public DbMapping getDbMapping() { + return dbmap; } - public Key getKey () { - if (state == TRANSIENT) { - Thread.dumpStack (); - throw new RuntimeException ("getKey called on transient Node: "+this); - } - if (dbmap == null && prototype != null && nmgr != null) - dbmap = nmgr.getDbMapping (prototype); - if (primaryKey == null) - primaryKey = new DbKey (dbmap, id); - return primaryKey; + /** + * + * + * @return ... + */ + public Key getKey() { + if (state == TRANSIENT) { + Thread.dumpStack(); + throw new RuntimeException("getKey called on transient Node: " + this); + } + + if ((dbmap == null) && (prototype != null) && (nmgr != null)) { + dbmap = nmgr.getDbMapping(prototype); + } + + if (primaryKey == null) { + primaryKey = new DbKey(dbmap, id); + } + + return primaryKey; } - public NodeHandle getHandle () { - if (handle == null) - handle = new NodeHandle (this); - return handle; + /** + * + * + * @return ... + */ + public NodeHandle getHandle() { + if (handle == null) { + handle = new NodeHandle(this); + } + + return handle; } - public void setSubnodeRelation (String rel) { - if ((rel == null && this.subnodeRelation == null) - || (rel != null && rel.equalsIgnoreCase (this.subnodeRelation))) - return; - checkWriteLock (); - this.subnodeRelation = rel; - DbMapping smap = dbmap == null ? null : dbmap.getSubnodeMapping (); - if (smap != null && smap.isRelational ()) { - subnodes = null; - subnodeCount = -1; - } + /** + * + * + * @param rel ... + */ + public void setSubnodeRelation(String rel) { + if (((rel == null) && (this.subnodeRelation == null)) || + ((rel != null) && rel.equalsIgnoreCase(this.subnodeRelation))) { + return; + } + + checkWriteLock(); + this.subnodeRelation = rel; + + DbMapping smap = (dbmap == null) ? null : dbmap.getSubnodeMapping(); + + if ((smap != null) && smap.isRelational()) { + subnodes = null; + subnodeCount = -1; + } } - public String getSubnodeRelation () { - return subnodeRelation; + /** + * + * + * @return ... + */ + public String getSubnodeRelation() { + return subnodeRelation; } - public void setName (String name) { - // "/" is used as delimiter, so it's not a legal char - if (name.indexOf('/') > -1) - return; - // throw new RuntimeException ("The name of the node must not contain \"/\"."); - if (name == null || name.trim().length() == 0) - this.name = id; // use id as name - else - this.name = name; + /** + * + * + * @param name ... + */ + public void setName(String name) { + // "/" is used as delimiter, so it's not a legal char + if (name.indexOf('/') > -1) { + return; + } + + // throw new RuntimeException ("The name of the node must not contain \"/\"."); + if ((name == null) || (name.trim().length() == 0)) { + this.name = id; // use id as name + } else { + this.name = name; + } } /** * Register a node as parent of the present node. We can't refer to the node directly, so we use * the ID + DB map combo. */ - protected void setParent (Node parent) { - parentHandle = parent == null ? null : parent.getHandle (); + protected void setParent(Node parent) { + parentHandle = (parent == null) ? null : parent.getHandle(); } /** * Set the parent handle which can be used to get the actual parent node. */ - public void setParentHandle (NodeHandle parent) { - parentHandle = parent; + public void setParentHandle(NodeHandle parent) { + parentHandle = parent; } /** @@ -642,593 +811,799 @@ public final class Node implements INode, Serializable { * depending on the string argument. This is the version called from the scripting framework, * while the one argument version is called from within the objectmodel classes only. */ - public void setParent (Node parent, String propertyName) { - // we only do that for relational nodes. - if (!isRelational ()) - return; + public void setParent(Node parent, String propertyName) { + // we only do that for relational nodes. + if (!isRelational()) { + return; + } - NodeHandle oldParentHandle = parentHandle; - parentHandle = parent == null ? null : parent.getHandle (); - // mark parent as set, otherwise getParent will try to - // determine the parent again when called. - lastParentSet = System.currentTimeMillis (); - if (parentHandle == null || parentHandle.equals (oldParentHandle)) - // nothing changed, no need to find access property - return; + NodeHandle oldParentHandle = parentHandle; - if (parent != null && propertyName == null) { - // see if we can find out the propertyName by ourselfes by looking at the - // parent's property relation - String newname = null; - DbMapping parentmap = parent.getDbMapping (); - if (parentmap != null) { - // first try to retrieve name via generic property relation of parent - Relation prel = parentmap.getPropertyRelation (); - if (prel != null && prel.otherType == dbmap && prel.accessName != null) { - // reverse look up property used to access this via parent - Relation proprel = dbmap.columnNameToRelation (prel.accessName); - if (proprel != null && proprel.propName != null) - newname = getString (proprel.propName); - } - } + parentHandle = (parent == null) ? null : parent.getHandle(); - // did we find a new name for this - if (newname == null) { - this.anonymous = true; - } else { - this.anonymous = false; - this.name = newname; - } - } else { - this.anonymous = false; - this.name = propertyName; - } + // mark parent as set, otherwise getParent will try to + // determine the parent again when called. + lastParentSet = System.currentTimeMillis(); + + if ((parentHandle == null) || parentHandle.equals(oldParentHandle)) { + // nothing changed, no need to find access property + return; + } + + if ((parent != null) && (propertyName == null)) { + // see if we can find out the propertyName by ourselfes by looking at the + // parent's property relation + String newname = null; + DbMapping parentmap = parent.getDbMapping(); + + if (parentmap != null) { + // first try to retrieve name via generic property relation of parent + Relation prel = parentmap.getPropertyRelation(); + + if ((prel != null) && (prel.otherType == dbmap) && + (prel.accessName != null)) { + // reverse look up property used to access this via parent + Relation proprel = dbmap.columnNameToRelation(prel.accessName); + + if ((proprel != null) && (proprel.propName != null)) { + newname = getString(proprel.propName); + } + } + } + + // did we find a new name for this + if (newname == null) { + this.anonymous = true; + } else { + this.anonymous = false; + this.name = newname; + } + } else { + this.anonymous = false; + this.name = propertyName; + } } - /** * Get parent, retrieving it if necessary. */ - public INode getParent () { + public INode getParent() { + // check what's specified in the type.properties for this node. + ParentInfo[] parentInfo = null; - // check what's specified in the type.properties for this node. - ParentInfo[] parentInfo = null; - if (isRelational () && lastParentSet < Math.max (dbmap.getLastTypeChange(), lastmodified)) - parentInfo = dbmap.getParentInfo (); + if (isRelational() && + (lastParentSet < Math.max(dbmap.getLastTypeChange(), lastmodified))) { + parentInfo = dbmap.getParentInfo(); + } - // check if current parent candidate matches presciption, - // if not, try to get one that does. - if (parentInfo != null && state != TRANSIENT) { - for (int i=0; i<parentInfo.length; i++) { - ParentInfo pinfo = parentInfo[i]; - INode pn = null; - // see if there is an explicit relation defined for this parent info - // we only try to fetch a node if an explicit relation is specified for the prop name - Relation rel = dbmap.propertyToRelation (pinfo.propname); - if (rel != null && rel.reftype == Relation.REFERENCE) - pn = getNode (pinfo.propname); - // the parent of this node is the app's root node... - if (pn == null && pinfo.isroot) - pn = nmgr.getNode ("0", nmgr.getDbMapping ("root")); - // if we found a parent node, check if we ought to use a virtual or groupby node as parent - if (pn != null) { - // see if dbmapping specifies anonymity for this node - if (pinfo.virtualname != null) - pn = pn.getNode (pinfo.virtualname); - DbMapping dbm = pn == null ? null : pn.getDbMapping (); - try { - if (dbm != null && dbm.getSubnodeGroupby () != null) { - // check for groupby - rel = dbmap.columnNameToRelation (dbm.getSubnodeGroupby()); - pn = pn.getSubnode (getString (rel.propName)); - } - if (pn != null) { - setParent ((Node) pn); - anonymous = !pinfo.named; - lastParentSet = System.currentTimeMillis (); - return pn; - } - } catch (Exception ignore) {} - } - } - } + // check if current parent candidate matches presciption, + // if not, try to get one that does. + if ((parentInfo != null) && (state != TRANSIENT)) { + for (int i = 0; i < parentInfo.length; i++) { + ParentInfo pinfo = parentInfo[i]; + INode pn = null; - // fall back to heuristic parent (the node that fetched this one from db) - if (parentHandle == null) - return null; - return parentHandle.getNode (nmgr); + // see if there is an explicit relation defined for this parent info + // we only try to fetch a node if an explicit relation is specified for the prop name + Relation rel = dbmap.propertyToRelation(pinfo.propname); + + if ((rel != null) && (rel.reftype == Relation.REFERENCE)) { + pn = getNode(pinfo.propname); + } + + // the parent of this node is the app's root node... + if ((pn == null) && pinfo.isroot) { + pn = nmgr.getNode("0", nmgr.getDbMapping("root")); + } + + // if we found a parent node, check if we ought to use a virtual or groupby node as parent + if (pn != null) { + // see if dbmapping specifies anonymity for this node + if (pinfo.virtualname != null) { + pn = pn.getNode(pinfo.virtualname); + } + + DbMapping dbm = (pn == null) ? null : pn.getDbMapping(); + + try { + if ((dbm != null) && (dbm.getSubnodeGroupby() != null)) { + // check for groupby + rel = dbmap.columnNameToRelation(dbm.getSubnodeGroupby()); + pn = pn.getSubnode(getString(rel.propName)); + } + + if (pn != null) { + setParent((Node) pn); + anonymous = !pinfo.named; + lastParentSet = System.currentTimeMillis(); + + return pn; + } + } catch (Exception ignore) { + } + } + } + } + + // fall back to heuristic parent (the node that fetched this one from db) + if (parentHandle == null) { + return null; + } + + return parentHandle.getNode(nmgr); } - /** * Get parent, using cached info if it exists. */ - public Node getCachedParent () { - if (parentHandle == null) - return null; - return parentHandle.getNode (nmgr); - } + public Node getCachedParent() { + if (parentHandle == null) { + return null; + } + return parentHandle.getNode(nmgr); + } /** * INode-related */ - - public INode addNode (INode elem) { - return addNode (elem, numberOfNodes ()); + public INode addNode(INode elem) { + return addNode(elem, numberOfNodes()); } - public INode addNode (INode elem, int where) { + /** + * + * + * @param elem ... + * @param where ... + * + * @return ... + */ + public INode addNode(INode elem, int where) { + Node node = null; - Node node = null; - if (elem instanceof Node) - node = (Node) elem; - else - throw new RuntimeException ("Can't add fixed-transient node to a persistent node"); + if (elem instanceof Node) { + node = (Node) elem; + } else { + throw new RuntimeException("Can't add fixed-transient node to a persistent node"); + } - // only lock nodes if parent node is not transient - if (state != TRANSIENT) { - // only lock parent if it has to be modified for a change in subnodes - if (!ignoreSubnodeChange ()) - checkWriteLock (); - node.checkWriteLock (); - } + // only lock nodes if parent node is not transient + if (state != TRANSIENT) { + // only lock parent if it has to be modified for a change in subnodes + if (!ignoreSubnodeChange()) { + checkWriteLock(); + } - // if subnodes are defined via realation, make sure its constraints are enforced. - if (dbmap != null && dbmap.getSubnodeRelation () != null) { - dbmap.getSubnodeRelation ().setConstraints (this, node); - } + node.checkWriteLock(); + } - // if the new node is marked as TRANSIENT and this node is not, mark new node as NEW - if (state != TRANSIENT && node.state == TRANSIENT) - node.makePersistentCapable (); + // if subnodes are defined via realation, make sure its constraints are enforced. + if ((dbmap != null) && (dbmap.getSubnodeRelation() != null)) { + dbmap.getSubnodeRelation().setConstraints(this, node); + } - String n = node.getName(); + // if the new node is marked as TRANSIENT and this node is not, mark new node as NEW + if ((state != TRANSIENT) && (node.state == TRANSIENT)) { + node.makePersistentCapable(); + } - // if (n.indexOf('/') > -1) - // throw new RuntimeException ("\"/\" found in Node name."); + String n = node.getName(); - // only mark this node as modified if subnodes are not in relational db - // pointing to this node. - if (!ignoreSubnodeChange () && (state == CLEAN || state == DELETED)) - markAs (MODIFIED); - if (node.state == CLEAN || node.state == DELETED) - node.markAs (MODIFIED); + // if (n.indexOf('/') > -1) + // throw new RuntimeException ("\"/\" found in Node name."); + // only mark this node as modified if subnodes are not in relational db + // pointing to this node. + if (!ignoreSubnodeChange() && ((state == CLEAN) || (state == DELETED))) { + markAs(MODIFIED); + } - loadNodes (); + if ((node.state == CLEAN) || (node.state == DELETED)) { + node.markAs(MODIFIED); + } - // check if this node has a group-by subnode-relation - if (dbmap != null) { - Relation srel = dbmap.getSubnodeRelation (); - if (srel != null && srel.groupby != null) try { - Relation groupbyRel = srel.otherType.columnNameToRelation (srel.groupby); - String groupbyProp = (groupbyRel != null) ? - groupbyRel.propName : srel.groupby; - String groupbyValue = node.getString (groupbyProp); - INode groupbyNode = getNode (groupbyValue); - // if group-by node doesn't exist, we'll create it - if (groupbyNode == null) - groupbyNode = getGroupbySubnode (groupbyValue, true); - groupbyNode.addNode (node); + loadNodes(); - return node; - } catch (Exception x) { - System.err.println ("Error adding groupby: "+x); - // x.printStackTrace (); - return null; - } - } + // check if this node has a group-by subnode-relation + if (dbmap != null) { + Relation srel = dbmap.getSubnodeRelation(); + if ((srel != null) && (srel.groupby != null)) { + try { + Relation groupbyRel = srel.otherType.columnNameToRelation(srel.groupby); + String groupbyProp = (groupbyRel != null) ? groupbyRel.propName + : srel.groupby; + String groupbyValue = node.getString(groupbyProp); + INode groupbyNode = getNode(groupbyValue); - if (where < 0 || where > numberOfNodes ()) - where = numberOfNodes (); + // if group-by node doesn't exist, we'll create it + if (groupbyNode == null) { + groupbyNode = getGroupbySubnode(groupbyValue, true); + } - NodeHandle nhandle = node.getHandle (); - if (subnodes != null && subnodes.contains (nhandle)) { - // Node is already subnode of this - just move to new position - subnodes.remove (nhandle); - where = Math.min (where, numberOfNodes ()); - subnodes.add (where, nhandle); - } else { - if (subnodes == null) - subnodes = new ExternalizableVector (); - subnodes.add (where, nhandle); + groupbyNode.addNode(node); - // check if properties are subnodes (_properties.aresubnodes=true) - if (dbmap != null && node.dbmap != null) { - Relation prel = dbmap.getPropertyRelation(); - if (prel != null && prel.accessName != null) { - Relation localrel = node.dbmap.columnNameToRelation (prel.accessName); - // if no relation from db column to prop name is found, assume that both are equal - String propname = localrel == null ? prel.accessName : localrel.propName; - String prop = node.getString (propname); - if (prop != null && prop.length() > 0) { - INode old = getNode (prop); - if (old != null && old != node) { - unset (prop); - removeNode (old); - } - setNode (prop, node); - } - } - } + return node; + } catch (Exception x) { + System.err.println("Error adding groupby: " + x); - if (!"root".equalsIgnoreCase (node.getPrototype ())) { - // avoid calling getParent() because it would return bogus results for the not-anymore transient node - Node nparent = node.parentHandle == null ? null : node.parentHandle.getNode (nmgr); - // if the node doesn't have a parent yet, or it has one but it's transient while we are - // persistent, make this the nodes new parent. - if (nparent == null || (state != TRANSIENT && nparent.getState () == TRANSIENT)) { - node.setParent (this); - node.anonymous = true; - } else if (nparent != null && (nparent != this || !node.anonymous)) { - // this makes the additional job of addLink, registering that we have a link to a node in our - // subnodes that actually sits somewhere else. This means that addLink and addNode - // are actually the same now. - node.registerLinkFrom (this); - } - } - } + // x.printStackTrace (); + return null; + } + } + } - lastmodified = System.currentTimeMillis (); - lastSubnodeChange = lastmodified; - // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.SUBNODE_ADDED, node)); - return node; + if ((where < 0) || (where > numberOfNodes())) { + where = numberOfNodes(); + } + + NodeHandle nhandle = node.getHandle(); + + if ((subnodes != null) && subnodes.contains(nhandle)) { + // Node is already subnode of this - just move to new position + subnodes.remove(nhandle); + where = Math.min(where, numberOfNodes()); + subnodes.add(where, nhandle); + } else { + if (subnodes == null) { + subnodes = new ExternalizableVector(); + } + + subnodes.add(where, nhandle); + + // check if properties are subnodes (_properties.aresubnodes=true) + if ((dbmap != null) && (node.dbmap != null)) { + Relation prel = dbmap.getPropertyRelation(); + + if ((prel != null) && (prel.accessName != null)) { + Relation localrel = node.dbmap.columnNameToRelation(prel.accessName); + + // if no relation from db column to prop name is found, assume that both are equal + String propname = (localrel == null) ? prel.accessName + : localrel.propName; + String prop = node.getString(propname); + + if ((prop != null) && (prop.length() > 0)) { + INode old = getNode(prop); + + if ((old != null) && (old != node)) { + unset(prop); + removeNode(old); + } + + setNode(prop, node); + } + } + } + + if (!"root".equalsIgnoreCase(node.getPrototype())) { + // avoid calling getParent() because it would return bogus results for the not-anymore transient node + Node nparent = (node.parentHandle == null) ? null + : node.parentHandle.getNode(nmgr); + + // if the node doesn't have a parent yet, or it has one but it's transient while we are + // persistent, make this the nodes new parent. + if ((nparent == null) || + ((state != TRANSIENT) && (nparent.getState() == TRANSIENT))) { + node.setParent(this); + node.anonymous = true; + } else if ((nparent != null) && ((nparent != this) || !node.anonymous)) { + // this makes the additional job of addLink, registering that we have a link to a node in our + // subnodes that actually sits somewhere else. This means that addLink and addNode + // are actually the same now. + node.registerLinkFrom(this); + } + } + } + + lastmodified = System.currentTimeMillis(); + lastSubnodeChange = lastmodified; + + // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.SUBNODE_ADDED, node)); + return node; } - - public INode createNode () { - // create new node at end of subnode array - return createNode (null, numberOfNodes ()); + /** + * + * + * @return ... + */ + public INode createNode() { + // create new node at end of subnode array + return createNode(null, numberOfNodes()); } - public INode createNode (int where) { - return createNode (null, where); + /** + * + * + * @param where ... + * + * @return ... + */ + public INode createNode(int where) { + return createNode(null, where); } - public INode createNode (String nm) { - // parameter where is ignored if nm != null so we try to avoid calling numberOfNodes() - return createNode (nm, nm == null ? numberOfNodes () : 0); + /** + * + * + * @param nm ... + * + * @return ... + */ + public INode createNode(String nm) { + // parameter where is ignored if nm != null so we try to avoid calling numberOfNodes() + return createNode(nm, (nm == null) ? numberOfNodes() : 0); } - public INode createNode (String nm, int where) { - checkWriteLock (); - boolean anon = false; - if (nm == null || "".equals (nm.trim ())) - anon = true; - Node n = new Node (nm, null, nmgr); - if (anon) - addNode (n, where); - else - setNode (nm, n); - return n; - } + /** + * + * + * @param nm ... + * @param where ... + * + * @return ... + */ + public INode createNode(String nm, int where) { + checkWriteLock(); + boolean anon = false; + + if ((nm == null) || "".equals(nm.trim())) { + anon = true; + } + + Node n = new Node(nm, null, nmgr); + + if (anon) { + addNode(n, where); + } else { + setNode(nm, n); + } + + return n; + } /** * register a node that links to this node so we can notify it when we cease to exist. * this is only necessary if we are a non-relational node, since for relational nodes * the referring object will notice that we've gone at runtime. */ - protected void registerLinkFrom (Node from) { - if (isRelational ()) - return; - if (from.getState () == TRANSIENT) - return; - if (links == null) - links = new ExternalizableVector (); - Object fromHandle = from.getHandle (); - if (!links.contains (fromHandle)) - links.add (fromHandle); + protected void registerLinkFrom(Node from) { + if (isRelational()) { + return; + } + + if (from.getState() == TRANSIENT) { + return; + } + + if (links == null) { + links = new ExternalizableVector(); + } + + Object fromHandle = from.getHandle(); + + if (!links.contains(fromHandle)) { + links.add(fromHandle); + } } /** * This implements the getChild() method of the IPathElement interface */ - public IPathElement getChildElement (String name) { - if (dbmap != null) { - // if a dbmapping is provided, check what it tells us about - // getting this specific child element - Relation rel = dbmap.getExactPropertyRelation (name); - if (rel != null) - return (IPathElement) getNode (name); - rel = dbmap.getSubnodeRelation (); - if (rel != null && rel.groupby == null && rel.accessName != null) { - if (rel.otherType != null && rel.otherType.isRelational ()) - return (IPathElement) nmgr.getNode (this, name, rel); - else - return (IPathElement) getNode (name); - } - return (IPathElement) getSubnode (name); - } else { - // no dbmapping - just try child collection first, then named property. - IPathElement child = (IPathElement) getSubnode (name); - if (child == null) - child = (IPathElement) getNode (name); - return child; - } + public IPathElement getChildElement(String name) { + if (dbmap != null) { + // if a dbmapping is provided, check what it tells us about + // getting this specific child element + Relation rel = dbmap.getExactPropertyRelation(name); + + if (rel != null) { + return (IPathElement) getNode(name); + } + + rel = dbmap.getSubnodeRelation(); + + if ((rel != null) && (rel.groupby == null) && (rel.accessName != null)) { + if ((rel.otherType != null) && rel.otherType.isRelational()) { + return (IPathElement) nmgr.getNode(this, name, rel); + } else { + return (IPathElement) getNode(name); + } + } + + return (IPathElement) getSubnode(name); + } else { + // no dbmapping - just try child collection first, then named property. + IPathElement child = (IPathElement) getSubnode(name); + + if (child == null) { + child = (IPathElement) getNode(name); + } + + return child; + } } /** * This implements the getParentElement() method of the IPathElement interface */ - public IPathElement getParentElement () { - return getParent (); + public IPathElement getParentElement() { + return getParent(); } + /** + * + * + * @param subid ... + * + * @return ... + */ + public INode getSubnode(String subid) { + // System.err.println ("GETSUBNODE : "+this+" > "+subid); + if ("".equals(subid)) { + return this; + } - public INode getSubnode (String subid) { - // System.err.println ("GETSUBNODE : "+this+" > "+subid); - if ("".equals (subid)) { - return this; - } - - Node retval = null; + Node retval = null; - if (subid != null) { + if (subid != null) { + loadNodes(); - loadNodes (); - if (subnodes == null || subnodes.size() == 0) - return null; - - NodeHandle nhandle = null; - int l = subnodes.size (); - for (int i=0; i<l; i++) try { - NodeHandle shandle = (NodeHandle) subnodes.get (i); - if (subid.equals (shandle.getID ())) { - // System.err.println ("FOUND SUBNODE: "+shandle); - nhandle = shandle; - break; - } - } catch (Exception x) { - break; - } - - if (nhandle != null) { - retval = nhandle.getNode (nmgr); - } - - // This would be an alternative way to do it, without loading the subnodes: - // if (dbmap != null && dbmap.getSubnodeRelation () != null) - // retval = nmgr.getNode (this, subid, dbmap.getSubnodeRelation ()); + if ((subnodes == null) || (subnodes.size() == 0)) { + return null; + } - if (retval != null && retval.parentHandle == null && !"root".equalsIgnoreCase (retval.getPrototype ())) { - retval.setParent (this); - retval.anonymous = true; - } - - } - return retval; + NodeHandle nhandle = null; + int l = subnodes.size(); + + for (int i = 0; i < l; i++) + try { + NodeHandle shandle = (NodeHandle) subnodes.get(i); + + if (subid.equals(shandle.getID())) { + // System.err.println ("FOUND SUBNODE: "+shandle); + nhandle = shandle; + + break; + } + } catch (Exception x) { + break; + } + + if (nhandle != null) { + retval = nhandle.getNode(nmgr); + } + + // This would be an alternative way to do it, without loading the subnodes: + // if (dbmap != null && dbmap.getSubnodeRelation () != null) + // retval = nmgr.getNode (this, subid, dbmap.getSubnodeRelation ()); + if ((retval != null) && (retval.parentHandle == null) && + !"root".equalsIgnoreCase(retval.getPrototype())) { + retval.setParent(this); + retval.anonymous = true; + } + } + + return retval; } + /** + * + * + * @param index ... + * + * @return ... + */ + public INode getSubnodeAt(int index) { + loadNodes(); - public INode getSubnodeAt (int index) { - loadNodes (); + if (subnodes == null) { + return null; + } - if (subnodes == null) - return null; + DbMapping smap = null; - DbMapping smap = null; - if (dbmap != null) - smap = dbmap.getSubnodeMapping (); - - Node retval = null; - if (subnodes.size () > index) { - // check if there is a group-by relation - retval = ((NodeHandle) subnodes.get (index)).getNode (nmgr); - - if (retval != null && retval.parentHandle == null && !"root".equalsIgnoreCase (retval.getPrototype ())) { - retval.setParent (this); - retval.anonymous = true; - } - } - return retval; + if (dbmap != null) { + smap = dbmap.getSubnodeMapping(); + } + + Node retval = null; + + if (subnodes.size() > index) { + // check if there is a group-by relation + retval = ((NodeHandle) subnodes.get(index)).getNode(nmgr); + + if ((retval != null) && (retval.parentHandle == null) && + !"root".equalsIgnoreCase(retval.getPrototype())) { + retval.setParent(this); + retval.anonymous = true; + } + } + + return retval; } - public Node getGroupbySubnode (String sid, boolean create) { - loadNodes (); - if (subnodes == null) - subnodes = new ExternalizableVector (); + /** + * + * + * @param sid ... + * @param create ... + * + * @return ... + */ + public Node getGroupbySubnode(String sid, boolean create) { + loadNodes(); - NodeHandle ghandle = new NodeHandle (new SyntheticKey (getKey(), sid)); - if (subnodes.contains (ghandle) || create) try { - DbMapping groupbyMapping = dbmap.getGroupbyMapping (); - boolean relational = groupbyMapping.getSubnodeMapping ().isRelational (); + if (subnodes == null) { + subnodes = new ExternalizableVector(); + } - if (relational || create) { - Node node = relational ? new Node (this, sid, nmgr, null) : new Node ("groupby-"+sid, null, nmgr); - // set "groupname" property to value of groupby field - node.setString ("groupname", sid); + NodeHandle ghandle = new NodeHandle(new SyntheticKey(getKey(), sid)); - if (relational) { - node.setDbMapping (groupbyMapping); - } else { - setNode (sid, node); - subnodes.add (node.getHandle ()); - } - node.setPrototype (groupbyMapping.getTypeName ()); - nmgr.evictKey (node.getKey ()); - return node; - } - } catch (Exception noluck) { - nmgr.logEvent ("Error creating group-by node for "+sid+": "+noluck); - noluck.printStackTrace(); - } - return null; + if (subnodes.contains(ghandle) || create) { + try { + DbMapping groupbyMapping = dbmap.getGroupbyMapping(); + boolean relational = groupbyMapping.getSubnodeMapping().isRelational(); + + if (relational || create) { + Node node = relational ? new Node(this, sid, nmgr, null) + : new Node("groupby-" + sid, null, nmgr); + + // set "groupname" property to value of groupby field + node.setString("groupname", sid); + + if (relational) { + node.setDbMapping(groupbyMapping); + } else { + setNode(sid, node); + subnodes.add(node.getHandle()); + } + + node.setPrototype(groupbyMapping.getTypeName()); + nmgr.evictKey(node.getKey()); + + return node; + } + } catch (Exception noluck) { + nmgr.logEvent("Error creating group-by node for " + sid + ": " + noluck); + noluck.printStackTrace(); + } + } + + return null; } - public boolean remove () { - checkWriteLock (); - try { - if (!anonymous) - getParent ().unset (name); - else - getParent ().removeNode (this); - } catch (Exception x) { - return false; - } - return true; + /** + * + * + * @return ... + */ + public boolean remove() { + checkWriteLock(); + + try { + if (!anonymous) { + getParent().unset(name); + } else { + getParent().removeNode(this); + } + } catch (Exception x) { + return false; + } + + return true; } + /** + * + * + * @param node ... + */ + public void removeNode(INode node) { + // nmgr.logEvent ("removing: "+ node); + Node n = (Node) node; - public void removeNode (INode node) { - // nmgr.logEvent ("removing: "+ node); - Node n = (Node) node; - checkWriteLock (); - n.checkWriteLock (); - - // need to query parent before releaseNode is called, since this may change the parent - // to the next option described in the type.properties _parent info - INode parent = n.getParent (); + checkWriteLock(); + n.checkWriteLock(); - releaseNode (n); + // need to query parent before releaseNode is called, since this may change the parent + // to the next option described in the type.properties _parent info + INode parent = n.getParent(); - if (parent == this) { - n.deepRemoveNode (); - } else { - // removed just a link, not the main node. - if (n.links != null) { - n.links.remove (getHandle ()); - if (n.state == CLEAN) n.markAs (MODIFIED); - } - } + releaseNode(n); + + if (parent == this) { + n.deepRemoveNode(); + } else { + // removed just a link, not the main node. + if (n.links != null) { + n.links.remove(getHandle()); + + if (n.state == CLEAN) { + n.markAs(MODIFIED); + } + } + } } /** * "Locally" remove a subnode from the subnodes table. * The logical stuff necessary for keeping data consistent is done in removeNode(). */ - protected void releaseNode (Node node) { - if (subnodes != null) - subnodes.remove (node.getHandle ()); + protected void releaseNode(Node node) { + if (subnodes != null) { + subnodes.remove(node.getHandle()); + } - lastSubnodeChange = System.currentTimeMillis (); + lastSubnodeChange = System.currentTimeMillis(); - // check if the subnode is in relational db and has a link back to this - // which needs to be unset - if (dbmap != null) { - Relation srel = dbmap.getSubnodeRelation (); - } + // check if the subnode is in relational db and has a link back to this + // which needs to be unset + if (dbmap != null) { + Relation srel = dbmap.getSubnodeRelation(); + } - // check if subnodes are also accessed as properties. If so, also unset the property - if (dbmap != null && node.dbmap != null) { - Relation prel = dbmap.getPropertyRelation(); - if (prel != null && prel.accessName != null) { - Relation localrel = node.dbmap.columnNameToRelation (prel.accessName); - // if no relation from db column to prop name is found, assume that both are equal - String propname = localrel == null ? prel.accessName : localrel.propName; - String prop = node.getString (propname); - if (prop != null && getNode (prop) == node) - unset (prop); - } - } + // check if subnodes are also accessed as properties. If so, also unset the property + if ((dbmap != null) && (node.dbmap != null)) { + Relation prel = dbmap.getPropertyRelation(); - // If subnodes are relational no need to mark this node as modified - if (ignoreSubnodeChange ()) - return; - - // Server.throwNodeEvent (new NodeEvent (node, NodeEvent.NODE_REMOVED)); - // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.SUBNODE_REMOVED, node)); - lastmodified = System.currentTimeMillis (); - // nmgr.logEvent ("released node "+node +" from "+this+" oldobj = "+what); - if (state == CLEAN) markAs (MODIFIED); + if ((prel != null) && (prel.accessName != null)) { + Relation localrel = node.dbmap.columnNameToRelation(prel.accessName); + + // if no relation from db column to prop name is found, assume that both are equal + String propname = (localrel == null) ? prel.accessName : localrel.propName; + String prop = node.getString(propname); + + if ((prop != null) && (getNode(prop) == node)) { + unset(prop); + } + } + } + + // If subnodes are relational no need to mark this node as modified + if (ignoreSubnodeChange()) { + return; + } + + // Server.throwNodeEvent (new NodeEvent (node, NodeEvent.NODE_REMOVED)); + // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.SUBNODE_REMOVED, node)); + lastmodified = System.currentTimeMillis(); + + // nmgr.logEvent ("released node "+node +" from "+this+" oldobj = "+what); + if (state == CLEAN) { + markAs(MODIFIED); + } } - /** - * Delete the node from the db. This mainly tries to notify all nodes referring to this that - * it's going away. For nodes from the embedded db it also does a cascading delete, since - * it can tell which nodes are actual children and which are just linked in. - */ - protected void deepRemoveNode () { + /** + * Delete the node from the db. This mainly tries to notify all nodes referring to this that + * it's going away. For nodes from the embedded db it also does a cascading delete, since + * it can tell which nodes are actual children and which are just linked in. + */ + protected void deepRemoveNode() { + // notify nodes that link to this node being deleted. + int l = (links == null) ? 0 : links.size(); - // notify nodes that link to this node being deleted. - int l = links == null ? 0 : links.size (); - for (int i = 0; i < l; i++) { - NodeHandle lhandle = (NodeHandle) links.get (i); - Node link = lhandle.getNode (nmgr); - if (link != null) - link.releaseNode (this); - } + for (int i = 0; i < l; i++) { + NodeHandle lhandle = (NodeHandle) links.get(i); + Node link = lhandle.getNode(nmgr); - // tell all nodes that are properties of n that they are no longer used as such - if (propMap != null) { - for (Enumeration e2 = propMap.elements (); e2.hasMoreElements (); ) { - Property p = (Property) e2.nextElement (); - if (p != null && p.getType() == Property.NODE) - p.unregisterNode (); - } - } + if (link != null) { + link.releaseNode(this); + } + } - // cascading delete of all subnodes. This is never done for relational subnodes, because - // the parent info is not 100% accurate for them. - if (subnodes != null) { - Vector v = new Vector (); - // remove modifies the Vector we are enumerating, so we are extra careful. - for (Enumeration e3 = getSubnodes (); e3.hasMoreElements(); ) { - v.add (e3.nextElement()); - } - int m = v.size (); - for (int i=0; i<m; i++) { - // getParent() is heuristical/implicit for relational nodes, so we don't base - // a cascading delete on that criterium for relational nodes. - Node n = (Node) v.get (i); - if (!n.isRelational()) - removeNode (n); - } - } + // tell all nodes that are properties of n that they are no longer used as such + if (propMap != null) { + for (Enumeration e2 = propMap.elements(); e2.hasMoreElements();) { + Property p = (Property) e2.nextElement(); - // mark the node as deleted - setParent (null); - markAs (DELETED); + if ((p != null) && (p.getType() == Property.NODE)) { + p.unregisterNode(); + } + } + } + + // cascading delete of all subnodes. This is never done for relational subnodes, because + // the parent info is not 100% accurate for them. + if (subnodes != null) { + Vector v = new Vector(); + + // remove modifies the Vector we are enumerating, so we are extra careful. + for (Enumeration e3 = getSubnodes(); e3.hasMoreElements();) { + v.add(e3.nextElement()); + } + + int m = v.size(); + + for (int i = 0; i < m; i++) { + // getParent() is heuristical/implicit for relational nodes, so we don't base + // a cascading delete on that criterium for relational nodes. + Node n = (Node) v.get(i); + + if (!n.isRelational()) { + removeNode(n); + } + } + } + + // mark the node as deleted + setParent(null); + markAs(DELETED); } - public int contains (INode n) { - if (n == null) - return -1; - loadNodes (); - if (subnodes == null) - return -1; - // if the node contains relational groupby subnodes, the subnodes vector contains the names instead of ids. - if (!(n instanceof Node)) - return -1; - Node node = (Node) n; - return subnodes.indexOf (node.getHandle ()); - } + /** + * + * + * @param n ... + * + * @return ... + */ + public int contains(INode n) { + if (n == null) { + return -1; + } + loadNodes(); + + if (subnodes == null) { + return -1; + } + + // if the node contains relational groupby subnodes, the subnodes vector contains the names instead of ids. + if (!(n instanceof Node)) { + return -1; + } + + Node node = (Node) n; + + return subnodes.indexOf(node.getHandle()); + } /** * Count the subnodes of this node. If they're stored in a relational data source, we * may actually load their IDs in order to do this. */ - public int numberOfNodes () { - // If the subnodes are loaded aggressively, we really just - // do a count statement, otherwise we just return the size of the id index. - // (after loading it, if it's coming from a relational data source). - DbMapping smap = dbmap == null ? null : dbmap.getSubnodeMapping (); - if (smap != null && smap.isRelational ()) { - // check if subnodes need to be rechecked - Relation subRel = dbmap.getSubnodeRelation (); - // do not fetch subnodes for nodes that haven't been persisted yet or are in - // the process of being persistified - except if "manual" subnoderelation is set. - if (subRel.aggressiveLoading && ((state != TRANSIENT && state != NEW) || subnodeRelation != null)) { - // we don't want to load *all* nodes if we just want to count them - long lastChange = subRel.aggressiveCaching ? lastSubnodeChange : smap.getLastDataChange (); - // also reload if the type mapping has changed. - lastChange = Math.max (lastChange, dbmap.getLastTypeChange ()); - if (lastChange < lastSubnodeFetch && subnodes != null) { - // we can use the nodes vector to determine number of subnodes - subnodeCount = subnodes.size(); - lastSubnodeCount = System.currentTimeMillis (); - } else if (lastChange >= lastSubnodeCount || subnodeCount < 0) { - // count nodes in db without fetching anything - subnodeCount = nmgr.countNodes (this, subRel); - lastSubnodeCount = System.currentTimeMillis (); - } - return subnodeCount; - } - } - loadNodes (); - return subnodes == null ? 0 : subnodes.size (); + public int numberOfNodes() { + // If the subnodes are loaded aggressively, we really just + // do a count statement, otherwise we just return the size of the id index. + // (after loading it, if it's coming from a relational data source). + DbMapping smap = (dbmap == null) ? null : dbmap.getSubnodeMapping(); + + if ((smap != null) && smap.isRelational()) { + // check if subnodes need to be rechecked + Relation subRel = dbmap.getSubnodeRelation(); + + // do not fetch subnodes for nodes that haven't been persisted yet or are in + // the process of being persistified - except if "manual" subnoderelation is set. + if (subRel.aggressiveLoading && + (((state != TRANSIENT) && (state != NEW)) || + (subnodeRelation != null))) { + // we don't want to load *all* nodes if we just want to count them + long lastChange = subRel.aggressiveCaching ? lastSubnodeChange + : smap.getLastDataChange(); + + // also reload if the type mapping has changed. + lastChange = Math.max(lastChange, dbmap.getLastTypeChange()); + + if ((lastChange < lastSubnodeFetch) && (subnodes != null)) { + // we can use the nodes vector to determine number of subnodes + subnodeCount = subnodes.size(); + lastSubnodeCount = System.currentTimeMillis(); + } else if ((lastChange >= lastSubnodeCount) || (subnodeCount < 0)) { + // count nodes in db without fetching anything + subnodeCount = nmgr.countNodes(this, subRel); + lastSubnodeCount = System.currentTimeMillis(); + } + + return subnodeCount; + } + } + + loadNodes(); + + return (subnodes == null) ? 0 : subnodes.size(); } /** @@ -1236,566 +1611,860 @@ public final class Node implements INode, Serializable { * Depending on the subnode.loadmode specified in the type.properties, we'll load just the * ID index or the actual nodes. */ - protected void loadNodes () { - // Don't do this for transient nodes which don't have an explicit subnode relation set - if ((state == TRANSIENT || state == NEW) && subnodeRelation == null) - return; - - DbMapping smap = dbmap == null ? null : dbmap.getSubnodeMapping (); - if (smap != null && smap.isRelational ()) { - // check if subnodes need to be reloaded - Relation subRel = dbmap.getSubnodeRelation (); - synchronized (this) { - long lastChange = subRel.aggressiveCaching ? lastSubnodeChange : smap.getLastDataChange (); - // also reload if the type mapping has changed. - lastChange = Math.max (lastChange, dbmap.getLastTypeChange ()); - if (lastChange >= lastSubnodeFetch || subnodes == null) { - if (subRel.aggressiveLoading) - subnodes = nmgr.getNodes (this, dbmap.getSubnodeRelation()); - else - subnodes = nmgr.getNodeIDs (this, dbmap.getSubnodeRelation()); - lastSubnodeFetch = System.currentTimeMillis (); - } - } - } + protected void loadNodes() { + // Don't do this for transient nodes which don't have an explicit subnode relation set + if (((state == TRANSIENT) || (state == NEW)) && (subnodeRelation == null)) { + return; + } + + DbMapping smap = (dbmap == null) ? null : dbmap.getSubnodeMapping(); + + if ((smap != null) && smap.isRelational()) { + // check if subnodes need to be reloaded + Relation subRel = dbmap.getSubnodeRelation(); + + synchronized (this) { + long lastChange = subRel.aggressiveCaching ? lastSubnodeChange + : smap.getLastDataChange(); + + // also reload if the type mapping has changed. + lastChange = Math.max(lastChange, dbmap.getLastTypeChange()); + + if ((lastChange >= lastSubnodeFetch) || (subnodes == null)) { + if (subRel.aggressiveLoading) { + subnodes = nmgr.getNodes(this, dbmap.getSubnodeRelation()); + } else { + subnodes = nmgr.getNodeIDs(this, dbmap.getSubnodeRelation()); + } + + lastSubnodeFetch = System.currentTimeMillis(); + } + } + } } - public void prefetchChildren (int startIndex, int length) throws Exception { - if (length < 1) - return; - if (startIndex < 0) - return; - loadNodes (); - if (subnodes == null) - return; - if (startIndex >= subnodes.size()) - return; - int l = Math.min (subnodes.size()-startIndex, length); - if (l < 1) - return; - Key[] keys = new Key[l]; - for (int i=0; i<l; i++) { - keys[i] = ((NodeHandle) subnodes.get (i+startIndex)).getKey (); - } - nmgr.nmgr.prefetchNodes (this, dbmap.getSubnodeRelation (), keys); + /** + * + * + * @param startIndex ... + * @param length ... + * + * @throws Exception ... + */ + public void prefetchChildren(int startIndex, int length) + throws Exception { + if (length < 1) { + return; + } + + if (startIndex < 0) { + return; + } + + loadNodes(); + + if (subnodes == null) { + return; + } + + if (startIndex >= subnodes.size()) { + return; + } + + int l = Math.min(subnodes.size() - startIndex, length); + + if (l < 1) { + return; + } + + Key[] keys = new Key[l]; + + for (int i = 0; i < l; i++) { + keys[i] = ((NodeHandle) subnodes.get(i + startIndex)).getKey(); + } + + nmgr.nmgr.prefetchNodes(this, dbmap.getSubnodeRelation(), keys); } - public Enumeration getSubnodes () { - loadNodes (); - class Enum implements Enumeration { - int count = 0; - public boolean hasMoreElements () { - return count < numberOfNodes (); - } - public Object nextElement () { - return getSubnodeAt (count++); - } - } - return new Enum (); + /** + * + * + * @return ... + */ + public Enumeration getSubnodes() { + loadNodes(); + class Enum implements Enumeration { + int count = 0; + + public boolean hasMoreElements() { + return count < numberOfNodes(); + } + + public Object nextElement() { + return getSubnodeAt(count++); + } + } + + return new Enum(); } + /** + * + * + * @return ... + */ public List getSubnodeList() { - return subnodes; + return subnodes; } - private boolean ignoreSubnodeChange () { - // return true if a change in subnodes can be ignored because it is - // stored in the subnodes themselves. - Relation rel = dbmap == null ? null : dbmap.getSubnodeRelation(); - return (rel != null && rel.otherType != null && rel.otherType.isRelational()); + private boolean ignoreSubnodeChange() { + // return true if a change in subnodes can be ignored because it is + // stored in the subnodes themselves. + Relation rel = (dbmap == null) ? null : dbmap.getSubnodeRelation(); + + return ((rel != null) && (rel.otherType != null) && rel.otherType.isRelational()); } /** * Get all properties of this node. */ - public Enumeration properties () { + public Enumeration properties() { + if ((dbmap != null) && dbmap.isRelational()) { + // return the properties defined in type.properties, if there are any + return dbmap.getPropertyEnumeration(); + } - if (dbmap != null && dbmap.isRelational()) - // return the properties defined in type.properties, if there are any - return dbmap.getPropertyEnumeration(); + Relation prel = (dbmap == null) ? null : dbmap.getPropertyRelation(); - Relation prel = dbmap == null ? null : dbmap.getPropertyRelation (); - if (prel != null && prel.hasAccessName() - && prel.otherType != null && prel.otherType.isRelational ()) - // return names of objects from a relational db table - return nmgr.getPropertyNames (this, prel).elements (); - else if (propMap != null) - // return the actually explicitly stored properties - return propMap.keys (); + if ((prel != null) && prel.hasAccessName() && (prel.otherType != null) && + prel.otherType.isRelational()) { + // return names of objects from a relational db table + return nmgr.getPropertyNames(this, prel).elements(); + } else if (propMap != null) { + // return the actually explicitly stored properties + return propMap.keys(); + } - // sorry, no properties for this Node - return new EmptyEnumeration (); + // sorry, no properties for this Node + return new EmptyEnumeration(); - // NOTE: we don't enumerate node properties here - // return propMap == null ? new Vector ().elements () : propMap.elements (); + // NOTE: we don't enumerate node properties here + // return propMap == null ? new Vector ().elements () : propMap.elements (); } - public Hashtable getPropMap() { - return propMap; + /** + * + * + * @return ... + */ + public Hashtable getPropMap() { + return propMap; } - public IProperty get (String propname) { - return getProperty (propname); + /** + * + * + * @param propname ... + * + * @return ... + */ + public IProperty get(String propname) { + return getProperty(propname); } - public String getParentInfo () { - return "anonymous:"+anonymous+",parentHandle"+parentHandle+",parent:"+getParent(); + /** + * + * + * @return ... + */ + public String getParentInfo() { + return "anonymous:" + anonymous + ",parentHandle" + parentHandle + ",parent:" + + getParent(); } - protected Property getProperty (String propname) { - // nmgr.logEvent ("GETTING PROPERTY: "+propname); - if (propname == null) - return null; - Property prop = propMap == null ? null : (Property) propMap.get (propname.toLowerCase ()); + protected Property getProperty(String propname) { + // nmgr.logEvent ("GETTING PROPERTY: "+propname); + if (propname == null) { + return null; + } - // See if this could be a relationally linked node which still doesn't know - // (i.e, still thinks it's just the key as a string) - DbMapping pmap = dbmap == null ? null : dbmap.getExactPropertyMapping (propname); - if (pmap != null && prop != null && prop.getType() != IProperty.NODE) { - // this is a relational node stored by id but we still think it's just a string. Fix it - prop.convertToNodeReference (pmap); - } + Property prop = (propMap == null) ? null + : (Property) propMap.get(propname.toLowerCase()); - // the property does not exist in our propmap - see if we should create it on the fly, - // either because it is mapped to an object from relational database or defined as - // collection aka virtual node - if (prop == null && dbmap != null) { - Relation propRel = dbmap.getPropertyRelation (propname); - // if no property relation is defined for this specific property name, - // use the generic property relation, if one is defined. - if (propRel == null) - propRel = dbmap.getPropertyRelation (); - // so if we have a property relation and it does in fact link to another object... - if (propRel != null && propRel.isCollection ()) { - // in some cases we just want to create and set a generic node without consulting - // the NodeManager if it exists: When we get a collection (aka virtual node) - // from a transient node for the first time, or when we get a collection whose - // content objects are stored in the embedded XML data storage. - if (state == TRANSIENT && propRel.virtual) { - INode node = new Node (propname, propRel.getPrototype (), nmgr); - node.setDbMapping (propRel.getVirtualMapping ()); - setNode (propname, node); - prop = (Property) propMap.get (propname); - } - // if this is from relational database only fetch if this node - // is itself persistent. - else if (state != TRANSIENT && propRel.createPropertyOnDemand ()) { - // this may be a relational node stored by property name - try { - Node pn = nmgr.getNode (this, propname, propRel); - if (pn != null) { - if (pn.parentHandle == null && !"root".equalsIgnoreCase (pn.getPrototype ())) { - pn.setParent (this); - pn.name = propname; - pn.anonymous = false; - } - prop = new Property (propname, this, pn); - } - } catch (RuntimeException nonode) { - // wasn't a node after all - } - } - } - } + // See if this could be a relationally linked node which still doesn't know + // (i.e, still thinks it's just the key as a string) + DbMapping pmap = (dbmap == null) ? null : dbmap.getExactPropertyMapping(propname); - return prop; + if ((pmap != null) && (prop != null) && (prop.getType() != IProperty.NODE)) { + // this is a relational node stored by id but we still think it's just a string. Fix it + prop.convertToNodeReference(pmap); + } + + // the property does not exist in our propmap - see if we should create it on the fly, + // either because it is mapped to an object from relational database or defined as + // collection aka virtual node + if ((prop == null) && (dbmap != null)) { + Relation propRel = dbmap.getPropertyRelation(propname); + + // if no property relation is defined for this specific property name, + // use the generic property relation, if one is defined. + if (propRel == null) { + propRel = dbmap.getPropertyRelation(); + } + + // so if we have a property relation and it does in fact link to another object... + if ((propRel != null) && propRel.isCollection()) { + // in some cases we just want to create and set a generic node without consulting + // the NodeManager if it exists: When we get a collection (aka virtual node) + // from a transient node for the first time, or when we get a collection whose + // content objects are stored in the embedded XML data storage. + if ((state == TRANSIENT) && propRel.virtual) { + INode node = new Node(propname, propRel.getPrototype(), nmgr); + + node.setDbMapping(propRel.getVirtualMapping()); + setNode(propname, node); + prop = (Property) propMap.get(propname); + } + // if this is from relational database only fetch if this node + // is itself persistent. + else if ((state != TRANSIENT) && propRel.createPropertyOnDemand()) { + // this may be a relational node stored by property name + try { + Node pn = nmgr.getNode(this, propname, propRel); + + if (pn != null) { + if ((pn.parentHandle == null) && + !"root".equalsIgnoreCase(pn.getPrototype())) { + pn.setParent(this); + pn.name = propname; + pn.anonymous = false; + } + + prop = new Property(propname, this, pn); + } + } catch (RuntimeException nonode) { + // wasn't a node after all + } + } + } + } + + return prop; } - public String getString (String propname) { - // propname = propname.toLowerCase (); - Property prop = getProperty (propname); - try { - return prop.getStringValue (); - } catch (Exception ignore) {} - return null; + /** + * + * + * @param propname ... + * + * @return ... + */ + public String getString(String propname) { + // propname = propname.toLowerCase (); + Property prop = getProperty(propname); + + try { + return prop.getStringValue(); + } catch (Exception ignore) { + } + + return null; } - public long getInteger (String propname) { - // propname = propname.toLowerCase (); - Property prop = getProperty (propname); - try { - return prop.getIntegerValue (); - } catch (Exception ignore) {} - return 0; + /** + * + * + * @param propname ... + * + * @return ... + */ + public long getInteger(String propname) { + // propname = propname.toLowerCase (); + Property prop = getProperty(propname); + + try { + return prop.getIntegerValue(); + } catch (Exception ignore) { + } + + return 0; } - public double getFloat (String propname) { - // propname = propname.toLowerCase (); - Property prop = getProperty (propname); - try { - return prop.getFloatValue (); - } catch (Exception ignore) {} - return 0.0; + /** + * + * + * @param propname ... + * + * @return ... + */ + public double getFloat(String propname) { + // propname = propname.toLowerCase (); + Property prop = getProperty(propname); + + try { + return prop.getFloatValue(); + } catch (Exception ignore) { + } + + return 0.0; } - public Date getDate (String propname) { - // propname = propname.toLowerCase (); - Property prop = getProperty (propname); - try { - return prop.getDateValue (); - } catch (Exception ignore) {} - return null; + /** + * + * + * @param propname ... + * + * @return ... + */ + public Date getDate(String propname) { + // propname = propname.toLowerCase (); + Property prop = getProperty(propname); + + try { + return prop.getDateValue(); + } catch (Exception ignore) { + } + + return null; } + /** + * + * + * @param propname ... + * + * @return ... + */ + public boolean getBoolean(String propname) { + // propname = propname.toLowerCase (); + Property prop = getProperty(propname); - public boolean getBoolean (String propname) { - // propname = propname.toLowerCase (); - Property prop = getProperty (propname); - try { - return prop.getBooleanValue (); - } catch (Exception ignore) {} - return false; + try { + return prop.getBooleanValue(); + } catch (Exception ignore) { + } + + return false; } - public INode getNode (String propname) { - // propname = propname.toLowerCase (); - Property prop = getProperty (propname); - try { - return prop.getNodeValue (); - } catch (Exception ignore) {} - return null; + /** + * + * + * @param propname ... + * + * @return ... + */ + public INode getNode(String propname) { + // propname = propname.toLowerCase (); + Property prop = getProperty(propname); + + try { + return prop.getNodeValue(); + } catch (Exception ignore) { + } + + return null; } - public Object getJavaObject (String propname) { - // propname = propname.toLowerCase (); - Property prop = getProperty (propname); - try { - return prop.getJavaObjectValue (); - } catch (Exception ignore) {} - return null; + /** + * + * + * @param propname ... + * + * @return ... + */ + public Object getJavaObject(String propname) { + // propname = propname.toLowerCase (); + Property prop = getProperty(propname); + + try { + return prop.getJavaObjectValue(); + } catch (Exception ignore) { + } + + return null; } - public void setString (String propname, String value) { - // nmgr.logEvent ("setting String prop"); - checkWriteLock (); + /** + * + * + * @param propname ... + * @param value ... + */ + public void setString(String propname, String value) { + // nmgr.logEvent ("setting String prop"); + checkWriteLock(); - if (propMap == null) - propMap = new Hashtable (); + if (propMap == null) { + propMap = new Hashtable(); + } - propname = propname.trim (); - String p2 = propname.toLowerCase (); + propname = propname.trim(); - Property prop = (Property) propMap.get (p2); - String oldvalue = null; + String p2 = propname.toLowerCase(); - if (prop != null) { - oldvalue = prop.getStringValue (); - // check if the value has changed - if (value != null && value.equals (oldvalue)) - return; - prop.setStringValue (value); - } else { - prop = new Property (propname, this); - prop.setStringValue (value); - propMap.put (p2, prop); - } + Property prop = (Property) propMap.get(p2); + String oldvalue = null; - // check if this may have an effect on the node's URL when using accessname - // but only do this if we already have a parent set, i.e. if we are already stored in the db - Node parent = parentHandle == null ? null : (Node) getParent (); + if (prop != null) { + oldvalue = prop.getStringValue(); - if (dbmap != null && parent != null && parent.getDbMapping() != null) { - // check if this node is already registered with the old name; if so, remove it. - // then set parent's property to this node for the new name value - DbMapping parentmap = parent.getDbMapping (); - Relation propRel = parentmap.getPropertyRelation (); - String dbcolumn = dbmap.propertyToColumnName (propname); + // check if the value has changed + if ((value != null) && value.equals(oldvalue)) { + return; + } - if (propRel != null && propRel.accessName != null && propRel.accessName.equals (dbcolumn)) { - INode n = parent.getNode (value); - if (n != null && n != this) { - parent.unset (value); - parent.removeNode (n); - } + prop.setStringValue(value); + } else { + prop = new Property(propname, this); + prop.setStringValue(value); + propMap.put(p2, prop); + } - if (oldvalue != null) { - n = parent.getNode (oldvalue); - if (n == this) { - parent.unset (oldvalue); - parent.addNode (this); - // let the node cache know this key's not for this node anymore. - nmgr.evictKey (new SyntheticKey (parent.getKey (), oldvalue)); - } - } - parent.setNode (value, this); - setName (value); - } - } + // check if this may have an effect on the node's URL when using accessname + // but only do this if we already have a parent set, i.e. if we are already stored in the db + Node parent = (parentHandle == null) ? null : (Node) getParent(); - // check if the property we're setting specifies the prototype of this object. - if (dbmap != null && dbmap.getPrototypeField () != null) { - String pn = dbmap.columnNameToProperty (dbmap.getPrototypeField ()); - if (propname.equals (pn)) { - DbMapping newmap = nmgr.getDbMapping (value); - if (newmap != null) { - // see if old and new prototypes have same storage - otherwise type change is ignored - String oldStorage = dbmap.getStorageTypeName (); - String newStorage = newmap.getStorageTypeName (); - if ((oldStorage == null && newStorage == null) || - (oldStorage != null && oldStorage.equals (newStorage))) { - dbmap.notifyDataChange (); - newmap.notifyDataChange (); - this.dbmap = newmap; - this.prototype = value; - } - } - } - } + if ((dbmap != null) && (parent != null) && (parent.getDbMapping() != null)) { + // check if this node is already registered with the old name; if so, remove it. + // then set parent's property to this node for the new name value + DbMapping parentmap = parent.getDbMapping(); + Relation propRel = parentmap.getPropertyRelation(); + String dbcolumn = dbmap.propertyToColumnName(propname); - // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); - lastmodified = System.currentTimeMillis (); - if (state == CLEAN) markAs (MODIFIED); + if ((propRel != null) && (propRel.accessName != null) && + propRel.accessName.equals(dbcolumn)) { + INode n = parent.getNode(value); + if ((n != null) && (n != this)) { + parent.unset(value); + parent.removeNode(n); + } + + if (oldvalue != null) { + n = parent.getNode(oldvalue); + + if (n == this) { + parent.unset(oldvalue); + parent.addNode(this); + + // let the node cache know this key's not for this node anymore. + nmgr.evictKey(new SyntheticKey(parent.getKey(), oldvalue)); + } + } + + parent.setNode(value, this); + setName(value); + } + } + + // check if the property we're setting specifies the prototype of this object. + if ((dbmap != null) && (dbmap.getPrototypeField() != null)) { + String pn = dbmap.columnNameToProperty(dbmap.getPrototypeField()); + + if (propname.equals(pn)) { + DbMapping newmap = nmgr.getDbMapping(value); + + if (newmap != null) { + // see if old and new prototypes have same storage - otherwise type change is ignored + String oldStorage = dbmap.getStorageTypeName(); + String newStorage = newmap.getStorageTypeName(); + + if (((oldStorage == null) && (newStorage == null)) || + ((oldStorage != null) && oldStorage.equals(newStorage))) { + dbmap.notifyDataChange(); + newmap.notifyDataChange(); + this.dbmap = newmap; + this.prototype = value; + } + } + } + } + + // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); + lastmodified = System.currentTimeMillis(); + + if (state == CLEAN) { + markAs(MODIFIED); + } } - public void setInteger (String propname, long value) { - // nmgr.logEvent ("setting bool prop"); - checkWriteLock (); + /** + * + * + * @param propname ... + * @param value ... + */ + public void setInteger(String propname, long value) { + // nmgr.logEvent ("setting bool prop"); + checkWriteLock(); - if (propMap == null) - propMap = new Hashtable (); - propname = propname.trim (); - String p2 = propname.toLowerCase (); + if (propMap == null) { + propMap = new Hashtable(); + } - Property prop = (Property) propMap.get (p2); - if (prop != null) { - prop.setIntegerValue (value); - } else { - prop = new Property (propname, this); - prop.setIntegerValue (value); - propMap.put (p2, prop); - } + propname = propname.trim(); - // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); - lastmodified = System.currentTimeMillis (); - if (state == CLEAN) markAs (MODIFIED); + String p2 = propname.toLowerCase(); + + Property prop = (Property) propMap.get(p2); + + if (prop != null) { + prop.setIntegerValue(value); + } else { + prop = new Property(propname, this); + prop.setIntegerValue(value); + propMap.put(p2, prop); + } + + // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); + lastmodified = System.currentTimeMillis(); + + if (state == CLEAN) { + markAs(MODIFIED); + } } - public void setFloat (String propname, double value) { - // nmgr.logEvent ("setting bool prop"); - checkWriteLock (); + /** + * + * + * @param propname ... + * @param value ... + */ + public void setFloat(String propname, double value) { + // nmgr.logEvent ("setting bool prop"); + checkWriteLock(); - if (propMap == null) - propMap = new Hashtable (); - propname = propname.trim (); - String p2 = propname.toLowerCase (); + if (propMap == null) { + propMap = new Hashtable(); + } - Property prop = (Property) propMap.get (p2); - if (prop != null) { - prop.setFloatValue (value); - } else { - prop = new Property (propname, this); - prop.setFloatValue (value); - propMap.put (p2, prop); - } + propname = propname.trim(); - // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); - lastmodified = System.currentTimeMillis (); - if (state == CLEAN) markAs (MODIFIED); + String p2 = propname.toLowerCase(); + + Property prop = (Property) propMap.get(p2); + + if (prop != null) { + prop.setFloatValue(value); + } else { + prop = new Property(propname, this); + prop.setFloatValue(value); + propMap.put(p2, prop); + } + + // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); + lastmodified = System.currentTimeMillis(); + + if (state == CLEAN) { + markAs(MODIFIED); + } } - public void setBoolean (String propname, boolean value) { - // nmgr.logEvent ("setting bool prop"); - checkWriteLock (); + /** + * + * + * @param propname ... + * @param value ... + */ + public void setBoolean(String propname, boolean value) { + // nmgr.logEvent ("setting bool prop"); + checkWriteLock(); - if (propMap == null) - propMap = new Hashtable (); - propname = propname.trim (); - String p2 = propname.toLowerCase (); + if (propMap == null) { + propMap = new Hashtable(); + } - Property prop = (Property) propMap.get (p2); - if (prop != null) { - prop.setBooleanValue (value); - } else { - prop = new Property (propname, this); - prop.setBooleanValue (value); - propMap.put (p2, prop); - } + propname = propname.trim(); - // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); - lastmodified = System.currentTimeMillis (); - if (state == CLEAN) markAs (MODIFIED); + String p2 = propname.toLowerCase(); + + Property prop = (Property) propMap.get(p2); + + if (prop != null) { + prop.setBooleanValue(value); + } else { + prop = new Property(propname, this); + prop.setBooleanValue(value); + propMap.put(p2, prop); + } + + // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); + lastmodified = System.currentTimeMillis(); + + if (state == CLEAN) { + markAs(MODIFIED); + } } + /** + * + * + * @param propname ... + * @param value ... + */ + public void setDate(String propname, Date value) { + // nmgr.logEvent ("setting date prop"); + checkWriteLock(); - public void setDate (String propname, Date value) { - // nmgr.logEvent ("setting date prop"); - checkWriteLock (); + if (propMap == null) { + propMap = new Hashtable(); + } - if (propMap == null) - propMap = new Hashtable (); - propname = propname.trim (); - String p2 = propname.toLowerCase (); + propname = propname.trim(); - Property prop = (Property) propMap.get (p2); - if (prop != null) { - prop.setDateValue (value); - } else { - prop = new Property (propname, this); - prop.setDateValue (value); - propMap.put (p2, prop); - } + String p2 = propname.toLowerCase(); - // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); - lastmodified = System.currentTimeMillis (); - if (state == CLEAN) markAs (MODIFIED); + Property prop = (Property) propMap.get(p2); + + if (prop != null) { + prop.setDateValue(value); + } else { + prop = new Property(propname, this); + prop.setDateValue(value); + propMap.put(p2, prop); + } + + // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); + lastmodified = System.currentTimeMillis(); + + if (state == CLEAN) { + markAs(MODIFIED); + } } - public void setJavaObject (String propname, Object value) { - // nmgr.logEvent ("setting jobject prop"); - checkWriteLock (); + /** + * + * + * @param propname ... + * @param value ... + */ + public void setJavaObject(String propname, Object value) { + // nmgr.logEvent ("setting jobject prop"); + checkWriteLock(); - if (propMap == null) - propMap = new Hashtable (); - propname = propname.trim (); - String p2 = propname.toLowerCase (); + if (propMap == null) { + propMap = new Hashtable(); + } - Property prop = (Property) propMap.get (p2); - if (prop != null) { - prop.setJavaObjectValue (value); - } else { - prop = new Property (propname, this); - prop.setJavaObjectValue (value); - propMap.put (p2, prop); - } + propname = propname.trim(); - // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); - lastmodified = System.currentTimeMillis (); - if (state == CLEAN) markAs (MODIFIED); + String p2 = propname.toLowerCase(); + + Property prop = (Property) propMap.get(p2); + + if (prop != null) { + prop.setJavaObjectValue(value); + } else { + prop = new Property(propname, this); + prop.setJavaObjectValue(value); + propMap.put(p2, prop); + } + + // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); + lastmodified = System.currentTimeMillis(); + + if (state == CLEAN) { + markAs(MODIFIED); + } } - public void setNode (String propname, INode value) { - // nmgr.logEvent ("setting node prop"); + /** + * + * + * @param propname ... + * @param value ... + */ + public void setNode(String propname, INode value) { + // nmgr.logEvent ("setting node prop"); + // check if types match, otherwise throw exception + DbMapping nmap = (dbmap == null) ? null : dbmap.getPropertyMapping(propname); - // check if types match, otherwise throw exception - DbMapping nmap = dbmap == null ? null : dbmap.getPropertyMapping (propname); - if (nmap != null && nmap != value.getDbMapping()) { - if (value.getDbMapping () == null) - value.setDbMapping (nmap); - else if (!nmap.isStorageCompatible (value.getDbMapping ())) - throw new RuntimeException ("Can't set "+propname+" to object with prototype "+value.getPrototype()+", was expecting "+nmap.getTypeName()); - } + if ((nmap != null) && (nmap != value.getDbMapping())) { + if (value.getDbMapping() == null) { + value.setDbMapping(nmap); + } else if (!nmap.isStorageCompatible(value.getDbMapping())) { + throw new RuntimeException("Can't set " + propname + + " to object with prototype " + + value.getPrototype() + ", was expecting " + + nmap.getTypeName()); + } + } - if (state != TRANSIENT) - checkWriteLock (); + if (state != TRANSIENT) { + checkWriteLock(); + } - Node n = null; - if (value instanceof Node) - n = (Node) value; - else - throw new RuntimeException ("Can't add fixed-transient node to a persistent node"); + Node n = null; - // if the new node is marked as TRANSIENT and this node is not, mark new node as NEW - if (state != TRANSIENT && n.state == TRANSIENT) - n.makePersistentCapable (); + if (value instanceof Node) { + n = (Node) value; + } else { + throw new RuntimeException("Can't add fixed-transient node to a persistent node"); + } - if (state != TRANSIENT) - n.checkWriteLock (); + // if the new node is marked as TRANSIENT and this node is not, mark new node as NEW + if ((state != TRANSIENT) && (n.state == TRANSIENT)) { + n.makePersistentCapable(); + } - // check if the main identity of this node is as a named property - // or as an anonymous node in a collection - if (n.parentHandle == null && !"root".equalsIgnoreCase (n.getPrototype ())) { - n.setParent (this); - n.name = propname; - n.anonymous = false; - } + if (state != TRANSIENT) { + n.checkWriteLock(); + } - propname = propname.trim (); - String p2 = propname.toLowerCase (); + // check if the main identity of this node is as a named property + // or as an anonymous node in a collection + if ((n.parentHandle == null) && !"root".equalsIgnoreCase(n.getPrototype())) { + n.setParent(this); + n.name = propname; + n.anonymous = false; + } - Property prop = propMap == null ? null : (Property) propMap.get (p2); - if (prop != null) { - if (prop.getType() == IProperty.NODE && n.getHandle ().equals (prop.getNodeHandle())) { - // nothing to do, just clean up locks and return - if (state == CLEAN) clearWriteLock (); - if (n.state == CLEAN) n.clearWriteLock (); - return; - } - } else { - prop = new Property (propname, this); - } + propname = propname.trim(); - prop.setNodeValue (n); - Relation rel = dbmap == null ? null : dbmap.getPropertyRelation (propname); + String p2 = propname.toLowerCase(); - if (rel == null || rel.reftype == Relation.REFERENCE || rel.virtual || - rel.otherType == null || !rel.otherType.isRelational()) { - // the node must be stored as explicit property - if (propMap == null) - propMap = new Hashtable (); - propMap.put (p2, prop); - if (state == CLEAN) markAs (MODIFIED); - } - - /* if (rel != null && rel.reftype == Relation.REFERENCE && !rel.usesPrimaryKey ()) { - // if the relation for this property doesn't use the primary key of the value object, make a - // secondary key object with the proper db column - String kval = n.getString (rel.otherType.columnNameToProperty (rel.getRemoteField ()), false); - prop.nhandle = new NodeHandle (new DbKey (n.getDbMapping (), kval, rel.getRemoteField ())); - } */ - - // don't check node in transactor cache if node is transient - - // this is done anyway when the node becomes persistent. - if (n.state != TRANSIENT) { - // check node in with transactor cache - // String nID = n.getID(); - // DbMapping dbm = n.getDbMapping (); - Transactor tx = (Transactor) Thread.currentThread (); - // tx.visitCleanNode (new DbKey (dbm, nID), n); - // UPDATE: using n.getKey() instead of manually constructing key. HW 2002/09/13 - tx.visitCleanNode (n.getKey(), n); - // if the field is not the primary key of the property, also register it - if (rel != null && rel.accessName != null && state != TRANSIENT) { - Key secKey = new SyntheticKey (getKey (), propname); - nmgr.evictKey (secKey); - tx.visitCleanNode (secKey, n); - } - } + Property prop = (propMap == null) ? null : (Property) propMap.get(p2); - lastmodified = System.currentTimeMillis (); - if (n.state == DELETED) n.markAs (MODIFIED); + if (prop != null) { + if ((prop.getType() == IProperty.NODE) && + n.getHandle().equals(prop.getNodeHandle())) { + // nothing to do, just clean up locks and return + if (state == CLEAN) { + clearWriteLock(); + } + + if (n.state == CLEAN) { + n.clearWriteLock(); + } + + return; + } + } else { + prop = new Property(propname, this); + } + + prop.setNodeValue(n); + + Relation rel = (dbmap == null) ? null : dbmap.getPropertyRelation(propname); + + if ((rel == null) || (rel.reftype == Relation.REFERENCE) || rel.virtual || + (rel.otherType == null) || !rel.otherType.isRelational()) { + // the node must be stored as explicit property + if (propMap == null) { + propMap = new Hashtable(); + } + + propMap.put(p2, prop); + + if (state == CLEAN) { + markAs(MODIFIED); + } + } + + /* if (rel != null && rel.reftype == Relation.REFERENCE && !rel.usesPrimaryKey ()) { + // if the relation for this property doesn't use the primary key of the value object, make a + // secondary key object with the proper db column + String kval = n.getString (rel.otherType.columnNameToProperty (rel.getRemoteField ()), false); + prop.nhandle = new NodeHandle (new DbKey (n.getDbMapping (), kval, rel.getRemoteField ())); + } */ + + // don't check node in transactor cache if node is transient - + // this is done anyway when the node becomes persistent. + if (n.state != TRANSIENT) { + // check node in with transactor cache + // String nID = n.getID(); + // DbMapping dbm = n.getDbMapping (); + Transactor tx = (Transactor) Thread.currentThread(); + + // tx.visitCleanNode (new DbKey (dbm, nID), n); + // UPDATE: using n.getKey() instead of manually constructing key. HW 2002/09/13 + tx.visitCleanNode(n.getKey(), n); + + // if the field is not the primary key of the property, also register it + if ((rel != null) && (rel.accessName != null) && (state != TRANSIENT)) { + Key secKey = new SyntheticKey(getKey(), propname); + + nmgr.evictKey(secKey); + tx.visitCleanNode(secKey, n); + } + } + + lastmodified = System.currentTimeMillis(); + + if (n.state == DELETED) { + n.markAs(MODIFIED); + } } /** * Remove a property. Note that this works only for explicitly set properties, not for those * specified via property relation. */ - public void unset (String propname) { - if (propMap == null) - return; - try { - // if node is relational, leave a null property so that it is - // updated in the DB. Otherwise, remove the property. - Property p; - boolean relational = dbmap != null && dbmap.isRelational(); - if (relational) - p = (Property) propMap.get (propname.toLowerCase ()); - else - p = (Property) propMap.remove (propname.toLowerCase ()); - if (p != null) { - checkWriteLock (); - if (p.getType() == Property.NODE) - p.unregisterNode (); - if (relational) - p.setStringValue (null); - // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); - lastmodified = System.currentTimeMillis (); - if (state == CLEAN) - markAs (MODIFIED); - } - } catch (Exception ignore) {} + public void unset(String propname) { + if (propMap == null) { + return; + } + + try { + // if node is relational, leave a null property so that it is + // updated in the DB. Otherwise, remove the property. + Property p; + boolean relational = (dbmap != null) && dbmap.isRelational(); + + if (relational) { + p = (Property) propMap.get(propname.toLowerCase()); + } else { + p = (Property) propMap.remove(propname.toLowerCase()); + } + + if (p != null) { + checkWriteLock(); + + if (p.getType() == Property.NODE) { + p.unregisterNode(); + } + + if (relational) { + p.setStringValue(null); + } + + // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.PROPERTIES_CHANGED)); + lastmodified = System.currentTimeMillis(); + + if (state == CLEAN) { + markAs(MODIFIED); + } + } + } catch (Exception ignore) { + } } - public long lastModified () { - return lastmodified; + /** + * + * + * @return ... + */ + public long lastModified() { + return lastmodified; } - public long created () { - return created; + /** + * + * + * @return ... + */ + public long created() { + return created; } - public String toString () { - return "HopObject " + name; + /** + * + * + * @return ... + */ + public String toString() { + return "HopObject " + name; } /** @@ -1803,81 +2472,96 @@ public final class Node implements INode, Serializable { * it actually is stored in a relational db, just that it would be, if the node was * persistent */ - public boolean isRelational () { - return dbmap != null && dbmap.isRelational (); + public boolean isRelational() { + return (dbmap != null) && dbmap.isRelational(); } - /** * Recursively turn node status from TRANSIENT to NEW so that the Transactor will * know it has to insert this node. */ - protected void makePersistentCapable () { - if (state == TRANSIENT) { - state = NEW; - // generate a real, persistent ID for this object - id = nmgr.generateID (dbmap); - getHandle ().becomePersistent (); - Transactor current = (Transactor) Thread.currentThread (); - current.visitNode (this); - current.visitCleanNode (this); - for (Enumeration e = getSubnodes (); e.hasMoreElements (); ) { - Node n = (Node) e.nextElement (); - if (n.state == TRANSIENT) - n.makePersistentCapable (); - } - for (Enumeration e = properties (); e.hasMoreElements (); ) { - IProperty next = get ((String) e.nextElement ()); - if (next != null && next.getType () == IProperty.NODE) { - Node n = (Node) next.getNodeValue (); - if (n != null && n.state == TRANSIENT) - n.makePersistentCapable (); - } - } - } - } + protected void makePersistentCapable() { + if (state == TRANSIENT) { + state = NEW; + // generate a real, persistent ID for this object + id = nmgr.generateID(dbmap); + getHandle().becomePersistent(); + + Transactor current = (Transactor) Thread.currentThread(); + + current.visitNode(this); + current.visitCleanNode(this); + + for (Enumeration e = getSubnodes(); e.hasMoreElements();) { + Node n = (Node) e.nextElement(); + + if (n.state == TRANSIENT) { + n.makePersistentCapable(); + } + } + + for (Enumeration e = properties(); e.hasMoreElements();) { + IProperty next = get((String) e.nextElement()); + + if ((next != null) && (next.getType() == IProperty.NODE)) { + Node n = (Node) next.getNodeValue(); + + if ((n != null) && (n.state == TRANSIENT)) { + n.makePersistentCapable(); + } + } + } + } + } /** * Get the cache node for this node. This can be * used to store transient cache data per node from Javascript. */ - public synchronized INode getCacheNode () { - if (cacheNode == null) - cacheNode = new TransientNode(); - return cacheNode; + public synchronized INode getCacheNode() { + if (cacheNode == null) { + cacheNode = new TransientNode(); + } + + return cacheNode; } /** * Reset the cache node for this node. */ - public synchronized void clearCacheNode () { - cacheNode = null; + public synchronized void clearCacheNode() { + cacheNode = null; } - /** * This method walks down node path to the first non-virtual node and return it. * limit max depth to 3, since there shouldn't be more then 2 layers of virtual nodes. */ - public INode getNonVirtualParent () { - INode node = this; - for (int i=0; i<5; i++) { - if (node == null) break; - if (node.getState() != Node.VIRTUAL) - return node; - node = node.getParent (); - } - return null; - } + public INode getNonVirtualParent() { + INode node = this; + for (int i = 0; i < 5; i++) { + if (node == null) { + break; + } + + if (node.getState() != Node.VIRTUAL) { + return node; + } + + node = node.getParent(); + } + + return null; + } /** * Instances of this class may be used to mark an entry in the object cache as null. * This method tells the caller whether this is the case. */ - public boolean isNullNode () { - return nmgr == null; + public boolean isNullNode() { + return nmgr == null; } /** @@ -1885,19 +2569,20 @@ public final class Node implements INode, Serializable { * changes, the node will automatically get a new ESNode wrapper, since they're cached in a hashtable. * You gotta love these hash code tricks ;-) */ - public int hashCode () { - if (prototype == null) - return super.hashCode (); - else - return super.hashCode () + prototype.hashCode (); + public int hashCode() { + if (prototype == null) { + return super.hashCode(); + } else { + return super.hashCode() + prototype.hashCode(); + } } - public void dump () { - System.err.println ("subnodes: "+subnodes); - System.err.println ("properties: "+propMap); - System.err.println ("links: "+links); + /** + * + */ + public void dump() { + System.err.println("subnodes: " + subnodes); + System.err.println("properties: " + propMap); + System.err.println("links: " + links); } - } - - diff --git a/src/helma/objectmodel/db/NodeHandle.java b/src/helma/objectmodel/db/NodeHandle.java index 297126f6..35610fa2 100644 --- a/src/helma/objectmodel/db/NodeHandle.java +++ b/src/helma/objectmodel/db/NodeHandle.java @@ -1,6 +1,19 @@ -// NodeHandle.java -// Copyright (c) Hannes Wallnöfer 1998-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel.db; import helma.objectmodel.*; @@ -16,8 +29,8 @@ import java.io.Serializable; * and reinstanciated since being set, NodeHandle will always return an up-to-date * instance of its node. */ - public final class NodeHandle implements INodeState, Serializable { + static final long serialVersionUID = 3067763116576910931L; // direct reference to the node private Node node; @@ -25,20 +38,19 @@ public final class NodeHandle implements INodeState, Serializable { // the node's key private Key key; - static final long serialVersionUID = 3067763116576910931L; - /** * Builds a handle for a node */ - public NodeHandle (Node node) { - int state = node.getState (); - if (state == TRANSIENT) { - this.node = node; - key = null; - } else { - this.node = null; - key = node.getKey (); - } + public NodeHandle(Node node) { + int state = node.getState(); + + if (state == TRANSIENT) { + this.node = node; + key = null; + } else { + this.node = null; + key = node.getKey(); + } } /** @@ -46,73 +58,90 @@ public final class NodeHandle implements INodeState, Serializable { * the node is ususally not yet created. It will be fetched on demand when accessed by * application code. */ - public NodeHandle (Key key) { - this.node = null; - this.key = key; + public NodeHandle(Key key) { + this.node = null; + this.key = key; } /** * Get the node described by this node handle */ - public Node getNode (WrappedNodeManager nodemgr) { - if (node != null) - return node; - return nodemgr.getNode (key); + public Node getNode(WrappedNodeManager nodemgr) { + if (node != null) { + return node; + } + + return nodemgr.getNode(key); } /** - * Get the key for the node described by this handle. + * Get the key for the node described by this handle. * This may only be called on persistent Nodes. */ - public Key getKey () { - if (key == null) - throw new RuntimeException ("getKey called on transient Node"); - return key; + public Key getKey() { + if (key == null) { + throw new RuntimeException("getKey called on transient Node"); + } + + return key; } /** - * Get the ID for the node described by this handle. + * Get the ID for the node described by this handle. * This may only be called on persistent Nodes. */ - public String getID () { - if (key == null) - return node.getID (); - return key.getID (); + public String getID() { + if (key == null) { + return node.getID(); + } + + return key.getID(); } - private Object getObject () { - if (node != null) - return node; - else - return key; + private Object getObject() { + if (node != null) { + return node; + } else { + return key; + } } - public boolean equals (Object other) { - try { - return getObject ().equals (((NodeHandle) other).getObject ()); - } catch (Exception x) { - return false; - } + /** + * + * + * @param other ... + * + * @return ... + */ + public boolean equals(Object other) { + try { + return getObject().equals(((NodeHandle) other).getObject()); + } catch (Exception x) { + return false; + } } /** * This is to notify the handle that the underlying node is becoming * persistent and we have to refer to it via the key from now on. */ - protected void becomePersistent () { - if (node != null) { - key = node.getKey (); - node = null; - } - } - - - public String toString () { - if (node != null) - return "NodeHandle[transient:"+node+"]"; - else - return "NodeHandle["+key+"]"; + protected void becomePersistent() { + if (node != null) { + key = node.getKey(); + node = null; + } } + /** + * + * + * @return ... + */ + public String toString() { + if (node != null) { + return "NodeHandle[transient:" + node + "]"; + } else { + return "NodeHandle[" + key + "]"; + } + } } - diff --git a/src/helma/objectmodel/db/NodeManager.java b/src/helma/objectmodel/db/NodeManager.java index 87134589..d40c7d7a 100644 --- a/src/helma/objectmodel/db/NodeManager.java +++ b/src/helma/objectmodel/db/NodeManager.java @@ -1,903 +1,1054 @@ -// NodeManager.java -// Copyright (c) Hannes Wallnöfer 1998-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.objectmodel.db; -import helma.util.CacheMap; -import helma.objectmodel.*; import helma.framework.core.Application; -import java.sql.*; +import helma.objectmodel.*; +import helma.util.CacheMap; import java.io.*; +import java.sql.*; import java.util.*; /** - * The NodeManager is responsible for fetching Nodes from the internal or - * external data sources, caching them in a least-recently-used Hashtable, + * The NodeManager is responsible for fetching Nodes from the internal or + * external data sources, caching them in a least-recently-used Hashtable, * and writing changes back to the databases. */ - public final class NodeManager { protected Application app; - private CacheMap cache; - private Replicator replicator; - protected IDatabase db; - protected IDGenerator idgen; - - private long idBaseValue = 1l; - + private long idBaseValue = 1L; private boolean logSql; protected boolean logReplication; // a wrapper that catches some Exceptions while accessing this NM public final WrappedNodeManager safe; - /** - * Create a new NodeManager for Application app. An embedded database will be - * created in dbHome if one doesn't already exist. - */ - public NodeManager (Application app, String dbHome, Properties props) throws DatabaseException { - this.app = app; - int cacheSize = Integer.parseInt (props.getProperty ("cachesize", "1000")); - // Make actual cache size bigger, since we use it only up to the threshold - // cache = new CacheMap ((int) Math.ceil (cacheSize/0.75f), 0.75f); - cache = new CacheMap (cacheSize, 0.75f); - cache.setLogger (app.getLogger ("event")); - app.logEvent ("Setting up node cache ("+cacheSize+")"); + * Create a new NodeManager for Application app. An embedded database will be + * created in dbHome if one doesn't already exist. + */ + public NodeManager(Application app, String dbHome, Properties props) + throws DatabaseException { + this.app = app; - safe = new WrappedNodeManager (this); - // nullNode = new Node (); + int cacheSize = Integer.parseInt(props.getProperty("cachesize", "1000")); - logSql = "true".equalsIgnoreCase(props.getProperty ("logsql")); - logReplication = "true".equalsIgnoreCase(props.getProperty ("logReplication")); + // Make actual cache size bigger, since we use it only up to the threshold + // cache = new CacheMap ((int) Math.ceil (cacheSize/0.75f), 0.75f); + cache = new CacheMap(cacheSize, 0.75f); + cache.setLogger(app.getLogger("event")); + app.logEvent("Setting up node cache (" + cacheSize + ")"); + safe = new WrappedNodeManager(this); - String replicationUrl = props.getProperty ("replicationUrl"); - if (replicationUrl != null) { - if (logReplication) - app.logEvent ("Setting up replication listener at "+replicationUrl); - replicator = new Replicator (this); - replicator.addUrl (replicationUrl); - } else { - replicator = null; - } + // nullNode = new Node (); + logSql = "true".equalsIgnoreCase(props.getProperty("logsql")); + logReplication = "true".equalsIgnoreCase(props.getProperty("logReplication")); - // get the initial id generator value - String idb = props.getProperty ("idBaseValue"); - if (idb != null) try { - idBaseValue = Long.parseLong (idb); - idBaseValue = Math.max (1l, idBaseValue); // 0 and 1 are reserved for root nodes - } catch (NumberFormatException ignore) {} + String replicationUrl = props.getProperty("replicationUrl"); - db = new XmlDatabase (dbHome, null, this); - initDb (); + if (replicationUrl != null) { + if (logReplication) { + app.logEvent("Setting up replication listener at " + replicationUrl); + } + + replicator = new Replicator(this); + replicator.addUrl(replicationUrl); + } else { + replicator = null; + } + + // get the initial id generator value + String idb = props.getProperty("idBaseValue"); + + if (idb != null) { + try { + idBaseValue = Long.parseLong(idb); + idBaseValue = Math.max(1L, idBaseValue); // 0 and 1 are reserved for root nodes + } catch (NumberFormatException ignore) { + } + } + + db = new XmlDatabase(dbHome, null, this); + initDb(); } /** * app.properties file has been updated. Reread some settings. */ - public void updateProperties (Properties props) { - int cacheSize = Integer.parseInt (props.getProperty ("cachesize", "1000")); - cache.setCapacity (cacheSize); - logSql = "true".equalsIgnoreCase(props.getProperty ("logsql")); - logReplication = "true".equalsIgnoreCase(props.getProperty ("logReplication")); - } + public void updateProperties(Properties props) { + int cacheSize = Integer.parseInt(props.getProperty("cachesize", "1000")); - /** - * Method used to create the root node and id-generator, if they don't exist already. - */ - public void initDb () throws DatabaseException { - - ITransaction txn = null; - try { - txn = db.beginTransaction (); - - try { - idgen = db.getIDGenerator (txn); - if (idgen.getValue() < idBaseValue) { - idgen.setValue (idBaseValue); - db.saveIDGenerator (txn, idgen); - } - } catch (ObjectNotFoundException notfound) { - // will start with idBaseValue+1 - idgen = new IDGenerator (idBaseValue); - db.saveIDGenerator (txn, idgen); - } - - // check if we need to set the id generator to a base value - - Node node = null; - try { - node = (Node)db.getNode (txn, "0"); - node.nmgr = safe; - } catch (ObjectNotFoundException notfound) { - node = new Node ("root", "0", "root", safe); - node.setDbMapping (app.getDbMapping ("root")); - db.saveNode (txn, node.getID (), node); - registerNode (node); // register node with nodemanager cache - } - - try { - node = (Node)db.getNode (txn, "1"); - node.nmgr = safe; - } catch (ObjectNotFoundException notfound) { - node = new Node ("users", "1", null, safe); - node.setDbMapping (app.getDbMapping ("__userroot__")); - db.saveNode (txn, node.getID (), node); - registerNode (node); // register node with nodemanager cache - } - - db.commitTransaction (txn); - } catch (Exception x) { - System.err.println (">> "+x); - x.printStackTrace (); - try { - db.abortTransaction (txn); - } catch (Exception ignore) {} - throw (new DatabaseException ("Error initializing db")); - } - } - - - /** - * Shut down this node manager. This is called when the application using this - * node manager is stopped. - */ - public void shutdown () throws DatabaseException { - db.shutdown (); - if (cache != null) { - synchronized (cache) { - cache.clear (); - cache = null; - } - } + cache.setCapacity(cacheSize); + logSql = "true".equalsIgnoreCase(props.getProperty("logsql")); + logReplication = "true".equalsIgnoreCase(props.getProperty("logReplication")); } /** - * Delete a node from the database. - */ - public void deleteNode (Node node) throws Exception { - if (node != null) { - String id = node.getID (); - synchronized (this) { - Transactor tx = (Transactor) Thread.currentThread (); - node.setState (Node.INVALID); - deleteNode (db, tx.txn, node); - } - } - } + * Method used to create the root node and id-generator, if they don't exist already. + */ + public void initDb() throws DatabaseException { + ITransaction txn = null; + try { + txn = db.beginTransaction(); - /** - * Get a node by key. This is called from a node that already holds - * a reference to another node via a NodeHandle/Key. - */ - public Node getNode (Key key) throws Exception { + try { + idgen = db.getIDGenerator(txn); - Transactor tx = (Transactor) Thread.currentThread (); - // tx.timer.beginEvent ("getNode "+kstr); + if (idgen.getValue() < idBaseValue) { + idgen.setValue(idBaseValue); + db.saveIDGenerator(txn, idgen); + } + } catch (ObjectNotFoundException notfound) { + // will start with idBaseValue+1 + idgen = new IDGenerator(idBaseValue); + db.saveIDGenerator(txn, idgen); + } - // it would be a good idea to reuse key objects one day. - // Key key = new Key (dbmap, kstr); + // check if we need to set the id generator to a base value + Node node = null; - // See if Transactor has already come across this node - Node node = tx.getVisitedNode (key); + try { + node = (Node) db.getNode(txn, "0"); + node.nmgr = safe; + } catch (ObjectNotFoundException notfound) { + node = new Node("root", "0", "root", safe); + node.setDbMapping(app.getDbMapping("root")); + db.saveNode(txn, node.getID(), node); + registerNode(node); // register node with nodemanager cache + } - if (node != null && node.getState() != Node.INVALID) { - // tx.timer.endEvent ("getNode "+kstr); - return node; - } + try { + node = (Node) db.getNode(txn, "1"); + node.nmgr = safe; + } catch (ObjectNotFoundException notfound) { + node = new Node("users", "1", null, safe); + node.setDbMapping(app.getDbMapping("__userroot__")); + db.saveNode(txn, node.getID(), node); + registerNode(node); // register node with nodemanager cache + } - // try to get the node from the shared cache - node = (Node) cache.get (key); - if (node == null || node.getState() == Node.INVALID) { + db.commitTransaction(txn); + } catch (Exception x) { + System.err.println(">> " + x); + x.printStackTrace(); - // The requested node isn't in the shared cache. Synchronize with key to make sure only one - // version is fetched from the database. - if (key instanceof SyntheticKey) { - Node parent = getNode (key.getParentKey ()); - Relation rel = parent.dbmap.getPropertyRelation (key.getID()); - if (rel == null || rel.groupby != null) - node = parent.getGroupbySubnode (key.getID (), true); - else if (rel != null) - node = getNode (parent, key.getID (), rel); - else - node = null; - } else - node = getNodeByKey (tx.txn, (DbKey) key); - - if (node != null) { - synchronized (cache) { - Node oldnode = (Node) cache.put (node.getKey (), node); - if (oldnode != null && !oldnode.isNullNode() && oldnode.getState () != Node.INVALID) { - cache.put (node.getKey (), oldnode); - node = oldnode; - } - } // synchronized - } - } + try { + db.abortTransaction(txn); + } catch (Exception ignore) { + } - if (node != null) { - tx.visitCleanNode (key, node); - } - - // tx.timer.endEvent ("getNode "+kstr); - return node; - } - - - /** - * Get a node by relation, using the home node, the relation and a key to apply. - * In contrast to getNode (Key key), this is usually called when we don't yet know - * whether such a node exists. - */ - public Node getNode (Node home, String kstr, Relation rel) throws Exception { - - if (kstr == null) - return null; - - Transactor tx = (Transactor) Thread.currentThread (); - - Key key = null; - // check what kind of object we're looking for and make an apropriate key - if (rel.virtual || rel.groupby != null || !rel.usesPrimaryKey()) - // a key for a virtually defined object that's never actually stored in the db - // or a key for an object that represents subobjects grouped by some property, generated on the fly - key = new SyntheticKey (home.getKey (), kstr); - else - // if a key for a node from within the DB - // FIXME: This should never apply, since for every relation-based loading Synthetic Keys are used. Right? - key = new DbKey (rel.otherType, kstr); - - // See if Transactor has already come across this node - Node node = tx.getVisitedNode (key); - - if (node != null && node.getState() != Node.INVALID) { - // we used to refresh the node in the main cache here to avoid the primary key entry being - // flushed from cache before the secondary one (risking duplicate nodes in cache) but - // we don't need to since we fetched the node from the threadlocal transactor cache and - // didn't refresh it in the main cache. - return node; - } - - // try to get the node from the shared cache - node = (Node) cache.get (key); - - // check if we can use the cached node without further checks. - // we need further checks for subnodes fetched by name if the subnodes were changed. - if (node != null && node.getState() != Node.INVALID) { - // check if node is null node (cached null) - if (node.isNullNode ()) { - if (node.created < rel.otherType.getLastDataChange () || - node.created < rel.ownType.getLastTypeChange()) - node = null; // cached null not valid anymore - } else if (!rel.virtual) { - // apply different consistency checks for groupby nodes and database nodes: - // for group nodes, check if they're contained - if (rel.groupby != null) { - if (home.contains (node) < 0) - node = null; - // for database nodes, check if constraints are fulfilled - } else if (!rel.usesPrimaryKey ()) { - if (!rel.checkConstraints (home, node)) - node = null; - } - } - } - - if (node == null || node.getState() == Node.INVALID) { - - // The requested node isn't in the shared cache. Synchronize with key to make sure only one - // version is fetched from the database. - node = getNodeByRelation (tx.txn, home, kstr, rel); - - if (node != null) { - - Key primKey = node.getKey (); - boolean keyIsPrimary = primKey.equals (key); - synchronized (cache) { - // check if node is already in cache with primary key - Node oldnode = (Node) cache.put (primKey, node); - // no need to check for oldnode != node because we fetched a new node from db - if (oldnode != null && !oldnode.isNullNode() && oldnode.getState () != Node.INVALID) { - // reset create time of old node, otherwise Relation.checkConstraints - // will reject it under certain circumstances. - oldnode.created = oldnode.lastmodified; - cache.put (primKey, oldnode); - if (!keyIsPrimary) { - cache.put (key, oldnode); - } - node = oldnode; - } else if (!keyIsPrimary) { - // cache node with secondary key - cache.put (key, node); - } - } // synchronized - } else { - // node fetched from db is null, cache result using nullNode - synchronized (cache) { - Node oldnode = (Node) cache.put (key, new Node ()); - // we ignore the case that onother thread has created the node in the meantime - return null; - } - } - } else if (node.isNullNode ()) { - // the nullNode caches a null value, i.e. an object that doesn't exist - return null; - } else { - // update primary key in cache to keep it from being flushed, see above - if (!rel.usesPrimaryKey ()) { - synchronized (cache) { - Node oldnode = (Node) cache.put (node.getKey (), node); - if (oldnode != node && oldnode != null && oldnode.getState () != Node.INVALID) { - cache.put (node.getKey (), oldnode); - cache.put (key, oldnode); - node = oldnode; - } - } - } - } - - if (node != null) { - tx.visitCleanNode (key, node); - } - - // tx.timer.endEvent ("getNode "+kstr); - return node; + throw (new DatabaseException("Error initializing db")); + } } /** - * Register a node in the node cache. - */ - public void registerNode (Node node) { - cache.put (node.getKey (), node); + * Shut down this node manager. This is called when the application using this + * node manager is stopped. + */ + public void shutdown() throws DatabaseException { + db.shutdown(); + + if (cache != null) { + synchronized (cache) { + cache.clear(); + cache = null; + } + } } /** - * Remove a node from the node cache. If at a later time it is accessed again, - * it will be refetched from the database. - */ - public void evictNode (Node node) { - node.setState (INode.INVALID); - cache.remove (node.getKey ()); + * Delete a node from the database. + */ + public void deleteNode(Node node) throws Exception { + if (node != null) { + String id = node.getID(); + + synchronized (this) { + Transactor tx = (Transactor) Thread.currentThread(); + + node.setState(Node.INVALID); + deleteNode(db, tx.txn, node); + } + } } /** - * Remove a node from the node cache. If at a later time it is accessed again, - * it will be refetched from the database. - */ - public void evictNodeByKey (Key key) { - Node n = (Node) cache.remove (key); - if (n != null) { - n.setState (INode.INVALID); - if (!(key instanceof DbKey)) - cache.remove (n.getKey ()); - } + * Get a node by key. This is called from a node that already holds + * a reference to another node via a NodeHandle/Key. + */ + public Node getNode(Key key) throws Exception { + Transactor tx = (Transactor) Thread.currentThread(); + + // tx.timer.beginEvent ("getNode "+kstr); + // it would be a good idea to reuse key objects one day. + // Key key = new Key (dbmap, kstr); + // See if Transactor has already come across this node + Node node = tx.getVisitedNode(key); + + if ((node != null) && (node.getState() != Node.INVALID)) { + // tx.timer.endEvent ("getNode "+kstr); + return node; + } + + // try to get the node from the shared cache + node = (Node) cache.get(key); + + if ((node == null) || (node.getState() == Node.INVALID)) { + // The requested node isn't in the shared cache. Synchronize with key to make sure only one + // version is fetched from the database. + if (key instanceof SyntheticKey) { + Node parent = getNode(key.getParentKey()); + Relation rel = parent.dbmap.getPropertyRelation(key.getID()); + + if ((rel == null) || (rel.groupby != null)) { + node = parent.getGroupbySubnode(key.getID(), true); + } else if (rel != null) { + node = getNode(parent, key.getID(), rel); + } else { + node = null; + } + } else { + node = getNodeByKey(tx.txn, (DbKey) key); + } + + if (node != null) { + synchronized (cache) { + Node oldnode = (Node) cache.put(node.getKey(), node); + + if ((oldnode != null) && !oldnode.isNullNode() && + (oldnode.getState() != Node.INVALID)) { + cache.put(node.getKey(), oldnode); + node = oldnode; + } + } + // synchronized + } + } + + if (node != null) { + tx.visitCleanNode(key, node); + } + + // tx.timer.endEvent ("getNode "+kstr); + return node; + } + + /** + * Get a node by relation, using the home node, the relation and a key to apply. + * In contrast to getNode (Key key), this is usually called when we don't yet know + * whether such a node exists. + */ + public Node getNode(Node home, String kstr, Relation rel) + throws Exception { + if (kstr == null) { + return null; + } + + Transactor tx = (Transactor) Thread.currentThread(); + + Key key = null; + + // check what kind of object we're looking for and make an apropriate key + if (rel.virtual || (rel.groupby != null) || !rel.usesPrimaryKey()) { + // a key for a virtually defined object that's never actually stored in the db + // or a key for an object that represents subobjects grouped by some property, generated on the fly + key = new SyntheticKey(home.getKey(), kstr); + } else { + // if a key for a node from within the DB + // FIXME: This should never apply, since for every relation-based loading Synthetic Keys are used. Right? + key = new DbKey(rel.otherType, kstr); + } + + // See if Transactor has already come across this node + Node node = tx.getVisitedNode(key); + + if ((node != null) && (node.getState() != Node.INVALID)) { + // we used to refresh the node in the main cache here to avoid the primary key entry being + // flushed from cache before the secondary one (risking duplicate nodes in cache) but + // we don't need to since we fetched the node from the threadlocal transactor cache and + // didn't refresh it in the main cache. + return node; + } + + // try to get the node from the shared cache + node = (Node) cache.get(key); + + // check if we can use the cached node without further checks. + // we need further checks for subnodes fetched by name if the subnodes were changed. + if ((node != null) && (node.getState() != Node.INVALID)) { + // check if node is null node (cached null) + if (node.isNullNode()) { + if ((node.created < rel.otherType.getLastDataChange()) || + (node.created < rel.ownType.getLastTypeChange())) { + node = null; // cached null not valid anymore + } + } else if (!rel.virtual) { + // apply different consistency checks for groupby nodes and database nodes: + // for group nodes, check if they're contained + if (rel.groupby != null) { + if (home.contains(node) < 0) { + node = null; + } + + // for database nodes, check if constraints are fulfilled + } else if (!rel.usesPrimaryKey()) { + if (!rel.checkConstraints(home, node)) { + node = null; + } + } + } + } + + if ((node == null) || (node.getState() == Node.INVALID)) { + // The requested node isn't in the shared cache. Synchronize with key to make sure only one + // version is fetched from the database. + node = getNodeByRelation(tx.txn, home, kstr, rel); + + if (node != null) { + Key primKey = node.getKey(); + boolean keyIsPrimary = primKey.equals(key); + + synchronized (cache) { + // check if node is already in cache with primary key + Node oldnode = (Node) cache.put(primKey, node); + + // no need to check for oldnode != node because we fetched a new node from db + if ((oldnode != null) && !oldnode.isNullNode() && + (oldnode.getState() != Node.INVALID)) { + // reset create time of old node, otherwise Relation.checkConstraints + // will reject it under certain circumstances. + oldnode.created = oldnode.lastmodified; + cache.put(primKey, oldnode); + + if (!keyIsPrimary) { + cache.put(key, oldnode); + } + + node = oldnode; + } else if (!keyIsPrimary) { + // cache node with secondary key + cache.put(key, node); + } + } + // synchronized + } else { + // node fetched from db is null, cache result using nullNode + synchronized (cache) { + Node oldnode = (Node) cache.put(key, new Node()); + + // we ignore the case that onother thread has created the node in the meantime + return null; + } + } + } else if (node.isNullNode()) { + // the nullNode caches a null value, i.e. an object that doesn't exist + return null; + } else { + // update primary key in cache to keep it from being flushed, see above + if (!rel.usesPrimaryKey()) { + synchronized (cache) { + Node oldnode = (Node) cache.put(node.getKey(), node); + + if ((oldnode != node) && (oldnode != null) && + (oldnode.getState() != Node.INVALID)) { + cache.put(node.getKey(), oldnode); + cache.put(key, oldnode); + node = oldnode; + } + } + } + } + + if (node != null) { + tx.visitCleanNode(key, node); + } + + // tx.timer.endEvent ("getNode "+kstr); + return node; + } + + /** + * Register a node in the node cache. + */ + public void registerNode(Node node) { + cache.put(node.getKey(), node); + } + + /** + * Remove a node from the node cache. If at a later time it is accessed again, + * it will be refetched from the database. + */ + public void evictNode(Node node) { + node.setState(INode.INVALID); + cache.remove(node.getKey()); + } + + /** + * Remove a node from the node cache. If at a later time it is accessed again, + * it will be refetched from the database. + */ + public void evictNodeByKey(Key key) { + Node n = (Node) cache.remove(key); + + if (n != null) { + n.setState(INode.INVALID); + + if (!(key instanceof DbKey)) { + cache.remove(n.getKey()); + } + } } /** * Used when a key stops being valid for a node. The cached node itself * remains valid, if it is present in the cache by other keys. */ - public void evictKey (Key key) { - cache.remove (key); + public void evictKey(Key key) { + cache.remove(key); } - //////////////////////////////////////////////////////////////////////// // methods to do the actual db work //////////////////////////////////////////////////////////////////////// - /** - * Insert a new node in the embedded database or a relational database table, depending - * on its db mapping. - */ - public void insertNode (IDatabase db, ITransaction txn, Node node) throws Exception { + * Insert a new node in the embedded database or a relational database table, + * depending on its db mapping. + */ + public void insertNode(IDatabase db, ITransaction txn, Node node) + throws IOException, SQLException, ClassNotFoundException { + // Transactor tx = (Transactor) Thread.currentThread (); + // tx.timer.beginEvent ("insertNode "+node); + DbMapping dbm = node.getDbMapping(); - // Transactor tx = (Transactor) Thread.currentThread (); - // tx.timer.beginEvent ("insertNode "+node); + if ((dbm == null) || !dbm.isRelational()) { + db.saveNode(txn, node.getID(), node); + } else { + insertRelationalNode(node, dbm, dbm.getConnection()); + dbm.notifyDataChange(); + } - DbMapping dbm = node.getDbMapping (); - - if (dbm == null || !dbm.isRelational ()) { - db.saveNode (txn, node.getID (), node); - } else { - // app.logEvent ("inserting relational node: "+node.getID ()); - - DbColumn[] columns = dbm.getColumns (); - - StringBuffer b1 = dbm.getInsert (); - StringBuffer b2 = new StringBuffer (" ) VALUES ( ?"); - - String nameField = dbm.getNameField (); - String prototypeField = dbm.getPrototypeField (); - - for (int i=0; i<columns.length; i++) { - Relation rel = columns[i].getRelation(); - String name = columns[i].getName(); - if ((rel != null && (rel.isPrimitive() || rel.isReference())) || - name.equals (nameField) || name.equals (prototypeField)) - { - b1.append (", "+columns[i].getName()); - b2.append (", ?"); - } - } - - b1.append (b2.toString()); - b1.append (" )"); - - Connection con = dbm.getConnection (); - PreparedStatement stmt = con.prepareStatement (b1.toString ()); - - if (logSql) - app.logEvent ("### insertNode: "+b1.toString ()); - - try { - - int stmtNumber = 1; - stmt.setString (stmtNumber, node.getID()); - - Hashtable propMap = node.getPropMap (); - for (int i=0; i<columns.length; i++) { - Relation rel = columns[i].getRelation(); - Property p = null; - if (rel != null && (rel.isPrimitive() || rel.isReference())) - p = (Property) propMap.get (rel.getPropName ()); - String name = columns[i].getName (); - if (!(rel != null && (rel.isPrimitive() || rel.isReference())) && !name.equals (nameField) && !name.equals (prototypeField)) - continue; - - stmtNumber++; - if (p != null) { - if (p.getValue() == null) { - stmt.setNull (stmtNumber, columns[i].getType ()); - } else { - switch (columns[i].getType ()) { - - case Types.BIT: - case Types.TINYINT: - case Types.BIGINT: - case Types.SMALLINT: - case Types.INTEGER: - stmt.setLong (stmtNumber, p.getIntegerValue()); - break; - - case Types.REAL: - case Types.FLOAT: - case Types.DOUBLE: - case Types.NUMERIC: - case Types.DECIMAL: - stmt.setDouble (stmtNumber, p.getFloatValue()); - break; - - case Types.VARBINARY: - case Types.BINARY: - case Types.BLOB: - stmt.setString (stmtNumber, p.getStringValue()); - break; - - case Types.LONGVARBINARY: - case Types.LONGVARCHAR: - try { - stmt.setString (stmtNumber, p.getStringValue()); - } catch (SQLException x) { - String str = p.getStringValue(); - Reader r = new StringReader (str); - stmt.setCharacterStream (stmtNumber, r, str.length()); - } - break; - - case Types.CHAR: - case Types.VARCHAR: - case Types.OTHER: - stmt.setString (stmtNumber, p.getStringValue()); - break; - - case Types.DATE: - case Types.TIME: - case Types.TIMESTAMP: - stmt.setTimestamp (stmtNumber, p.getTimestampValue()); - break; - - case Types.NULL: - stmt.setNull (stmtNumber, 0); - break; - - default: - stmt.setString (stmtNumber, p.getStringValue()); - break; - } - } - } else { - if (name.equals (nameField)) - stmt.setString (stmtNumber, node.getName()); - else if (name.equals (prototypeField)) - stmt.setString (stmtNumber, node.getPrototype ()); - else - stmt.setNull (stmtNumber, columns[i].getType()); - } - } - stmt.executeUpdate (); - - - } catch (Exception x) { - x.printStackTrace (); - throw x; - } finally { - if (stmt != null) try { - stmt.close (); - } catch (Exception ignore) {} - } - dbm.notifyDataChange (); - } - // tx.timer.endEvent ("insertNode "+node); + // tx.timer.endEvent ("insertNode "+node); } /** - * Updates a modified node in the embedded db or an external relational database, depending - * on its database mapping. - */ - public void updateNode (IDatabase db, ITransaction txn, Node node) throws Exception { + * Insert a node into a different (relational) database than its default one. + */ + public void exportNode(Node node, DbSource dbs) + throws IOException, SQLException, ClassNotFoundException { + if (node == null) { + throw new IllegalArgumentException("Node can't be null in exportNode"); + } - // Transactor tx = (Transactor) Thread.currentThread (); - // tx.timer.beginEvent ("updateNode "+node); + DbMapping dbm = node.getDbMapping(); - DbMapping dbm = node.getDbMapping (); - boolean markMappingAsUpdated = false; - - if (dbm == null || !dbm.isRelational ()) { - db.saveNode (txn, node.getID (), node); - } else { - - Hashtable propMap = node.getPropMap (); - Property[] props = new Property[propMap.size()]; - propMap.values().toArray (props); - - // make sure table meta info is loaded by dbmapping - dbm.getColumns (); - - StringBuffer b = dbm.getUpdate (); - - boolean comma = false; - for (int i=0; i<props.length; i++) { - // skip clean properties - if (props[i] == null || !props[i].dirty) { - // null out clean property so we don't consider it later - props[i] = null; - continue; - } - Relation rel = dbm.propertyToRelation (props[i].getName()); - // skip readonly, virtual and collection relations - if (rel == null || rel.readonly || rel.virtual || - (rel.reftype != Relation.REFERENCE && rel.reftype != Relation.PRIMITIVE)) - { - // null out property so we don't consider it later - props[i] = null; - continue; - } - if (comma) - b.append (", "); - else - comma = true; - b.append (rel.getDbField()); - b.append (" = ?"); - - } - // if no columns were updated, return - if (!comma) - return; - - b.append (" WHERE "); - b.append (dbm.getIDField ()); - b.append (" = "); - if (dbm.needsQuotes (dbm.getIDField ())) { - b.append ("'"); - b.append (escape(node.getID())); - b.append ("'"); - } else { - b.append (node.getID()); - } - - Connection con = dbm.getConnection (); - PreparedStatement stmt = con.prepareStatement (b.toString ()); - - if (logSql) - app.logEvent ("### updateNode: "+b.toString ()); - - int stmtNumber = 0; - try { - for (int i=0; i<props.length; i++) { - Property p = props[i]; - if (p == null) - continue; - Relation rel = dbm.propertyToRelation (p.getName()); - - stmtNumber++; - - if (p.getValue() == null) { - stmt.setNull (stmtNumber, rel.getColumnType ()); - } else { - switch (rel.getColumnType ()) { - case Types.BIT: - case Types.TINYINT: - case Types.BIGINT: - case Types.SMALLINT: - case Types.INTEGER: - stmt.setLong (stmtNumber, p.getIntegerValue()); - break; - - case Types.REAL: - case Types.FLOAT: - case Types.DOUBLE: - case Types.NUMERIC: - case Types.DECIMAL: - stmt.setDouble (stmtNumber, p.getFloatValue()); - break; - - case Types.VARBINARY: - case Types.BINARY: - case Types.BLOB: - stmt.setString (stmtNumber, p.getStringValue()); - break; - - case Types.LONGVARBINARY: - case Types.LONGVARCHAR: - try { - stmt.setString (stmtNumber, p.getStringValue()); - } catch (SQLException x) { - String str = p.getStringValue(); - Reader r = new StringReader (str); - stmt.setCharacterStream (stmtNumber, r, str.length()); - } - break; - - case Types.CHAR: - case Types.VARCHAR: - case Types.OTHER: - stmt.setString (stmtNumber, p.getStringValue()); - break; - - case Types.DATE: - case Types.TIME: - case Types.TIMESTAMP: - stmt.setTimestamp (stmtNumber, p.getTimestampValue()); - break; - - case Types.NULL: - stmt.setNull (stmtNumber, 0); - break; - - default: - stmt.setString (stmtNumber, p.getStringValue()); - break; - } - } - p.dirty = false; - if (!rel.isPrivate()) - markMappingAsUpdated = true; - - } - - stmt.executeUpdate (); - - } catch (Exception x) { - x.printStackTrace (); - throw x; - } finally { - if (stmt != null) try { - stmt.close (); - } catch (Exception ignore) {} - } - - if (markMappingAsUpdated) - dbm.notifyDataChange (); - } - // update may cause changes in the node's parent subnode array - if (node.isAnonymous()) { - Node parent = node.getCachedParent (); - if (parent != null) - parent.lastSubnodeChange = System.currentTimeMillis (); - } - // tx.timer.endEvent ("updateNode "+node); + if (dbs == null) { + throw new IllegalArgumentException("DbSource can't be null in exportNode"); + } else if ((dbm == null) || !dbm.isRelational()) { + throw new SQLException("Can't export into non-relational database"); + } else { + insertRelationalNode(node, dbm, dbs.getConnection()); + } } /** - * Performs the actual deletion of a node from either the embedded or an external SQL database. - */ - public void deleteNode (IDatabase db, ITransaction txn, Node node) throws Exception { + * Insert a node into a relational database. + */ + protected void insertRelationalNode(Node node, DbMapping dbm, Connection con) + throws ClassNotFoundException, SQLException { - // Transactor tx = (Transactor) Thread.currentThread (); - // tx.timer.beginEvent ("deleteNode "+node); + if (con == null) { + throw new NullPointerException("Error inserting relational node: Connection is null"); + } - DbMapping dbm = node.getDbMapping (); + // app.logEvent ("inserting relational node: "+node.getID ()); + DbColumn[] columns = dbm.getColumns(); - if (dbm == null || !dbm.isRelational ()) { - db.deleteNode (txn, node.getID ()); - } else { - Statement st = null; - try { - Connection con = dbm.getConnection (); - String str = new StringBuffer ("DELETE FROM ") - .append(dbm.getTableName ()) - .append(" WHERE ") - .append(dbm.getIDField()) - .append(" = ") - .append(node.getID()) - .toString(); - st = con.createStatement (); - st.executeUpdate (str); - if (logSql) - app.logEvent ("### deleteNode: "+str); - } finally { - if (st != null) try { - st.close (); - } catch (Exception ignore) {} - } - dbm.notifyDataChange (); - } - // node may still be cached via non-primary keys. mark as invalid - node.setState (Node.INVALID); - // tx.timer.endEvent ("deleteNode "+node); + StringBuffer b1 = dbm.getInsert(); + StringBuffer b2 = new StringBuffer(" ) VALUES ( ?"); + + String nameField = dbm.getNameField(); + String prototypeField = dbm.getPrototypeField(); + + for (int i = 0; i < columns.length; i++) { + Relation rel = columns[i].getRelation(); + String name = columns[i].getName(); + + if (((rel != null) && (rel.isPrimitive() || rel.isReference())) || + name.equals(nameField) || name.equals(prototypeField)) { + b1.append(", " + columns[i].getName()); + b2.append(", ?"); + } + } + + b1.append(b2.toString()); + b1.append(" )"); + + // Connection con = dbm.getConnection(); + PreparedStatement stmt = con.prepareStatement(b1.toString()); + + if (logSql) { + app.logEvent("### insertNode: " + b1.toString()); + } + + try { + int stmtNumber = 1; + + stmt.setString(stmtNumber, node.getID()); + + Hashtable propMap = node.getPropMap(); + + for (int i = 0; i < columns.length; i++) { + Relation rel = columns[i].getRelation(); + Property p = null; + + if ((rel != null) && (rel.isPrimitive() || rel.isReference())) { + p = (Property) propMap.get(rel.getPropName()); + } + + String name = columns[i].getName(); + + if (!((rel != null) && (rel.isPrimitive() || rel.isReference())) && + !name.equals(nameField) && !name.equals(prototypeField)) { + continue; + } + + stmtNumber++; + + if (p != null) { + if (p.getValue() == null) { + stmt.setNull(stmtNumber, columns[i].getType()); + } else { + switch (columns[i].getType()) { + case Types.BIT: + case Types.TINYINT: + case Types.BIGINT: + case Types.SMALLINT: + case Types.INTEGER: + stmt.setLong(stmtNumber, p.getIntegerValue()); + + break; + + case Types.REAL: + case Types.FLOAT: + case Types.DOUBLE: + case Types.NUMERIC: + case Types.DECIMAL: + stmt.setDouble(stmtNumber, p.getFloatValue()); + + break; + + case Types.VARBINARY: + case Types.BINARY: + case Types.BLOB: + stmt.setString(stmtNumber, p.getStringValue()); + + break; + + case Types.LONGVARBINARY: + case Types.LONGVARCHAR: + + try { + stmt.setString(stmtNumber, p.getStringValue()); + } catch (SQLException x) { + String str = p.getStringValue(); + Reader r = new StringReader(str); + + stmt.setCharacterStream(stmtNumber, r, + str.length()); + } + + break; + + case Types.CHAR: + case Types.VARCHAR: + case Types.OTHER: + stmt.setString(stmtNumber, p.getStringValue()); + + break; + + case Types.DATE: + case Types.TIME: + case Types.TIMESTAMP: + stmt.setTimestamp(stmtNumber, p.getTimestampValue()); + + break; + + case Types.NULL: + stmt.setNull(stmtNumber, 0); + + break; + + default: + stmt.setString(stmtNumber, p.getStringValue()); + + break; + } + } + } else { + if (name.equals(nameField)) { + stmt.setString(stmtNumber, node.getName()); + } else if (name.equals(prototypeField)) { + stmt.setString(stmtNumber, node.getPrototype()); + } else { + stmt.setNull(stmtNumber, columns[i].getType()); + } + } + } + + stmt.executeUpdate(); + } finally { + if (stmt != null) { + try { + stmt.close(); + } catch (Exception ignore) {} + } + } + + } + + /** + * Updates a modified node in the embedded db or an external relational database, depending + * on its database mapping. + */ + public void updateNode(IDatabase db, ITransaction txn, Node node) + throws IOException, SQLException, ClassNotFoundException { + // Transactor tx = (Transactor) Thread.currentThread (); + // tx.timer.beginEvent ("updateNode "+node); + DbMapping dbm = node.getDbMapping(); + boolean markMappingAsUpdated = false; + + if ((dbm == null) || !dbm.isRelational()) { + db.saveNode(txn, node.getID(), node); + } else { + Hashtable propMap = node.getPropMap(); + Property[] props = new Property[propMap.size()]; + + propMap.values().toArray(props); + + // make sure table meta info is loaded by dbmapping + dbm.getColumns(); + + StringBuffer b = dbm.getUpdate(); + + boolean comma = false; + + for (int i = 0; i < props.length; i++) { + // skip clean properties + if ((props[i] == null) || !props[i].dirty) { + // null out clean property so we don't consider it later + props[i] = null; + + continue; + } + + Relation rel = dbm.propertyToRelation(props[i].getName()); + + // skip readonly, virtual and collection relations + if ((rel == null) || rel.readonly || rel.virtual || + ((rel.reftype != Relation.REFERENCE) && + (rel.reftype != Relation.PRIMITIVE))) { + // null out property so we don't consider it later + props[i] = null; + + continue; + } + + if (comma) { + b.append(", "); + } else { + comma = true; + } + + b.append(rel.getDbField()); + b.append(" = ?"); + } + + // if no columns were updated, return + if (!comma) { + return; + } + + b.append(" WHERE "); + b.append(dbm.getIDField()); + b.append(" = "); + + if (dbm.needsQuotes(dbm.getIDField())) { + b.append("'"); + b.append(escape(node.getID())); + b.append("'"); + } else { + b.append(node.getID()); + } + + Connection con = dbm.getConnection(); + PreparedStatement stmt = con.prepareStatement(b.toString()); + + if (logSql) { + app.logEvent("### updateNode: " + b.toString()); + } + + int stmtNumber = 0; + + try { + for (int i = 0; i < props.length; i++) { + Property p = props[i]; + + if (p == null) { + continue; + } + + Relation rel = dbm.propertyToRelation(p.getName()); + + stmtNumber++; + + if (p.getValue() == null) { + stmt.setNull(stmtNumber, rel.getColumnType()); + } else { + switch (rel.getColumnType()) { + case Types.BIT: + case Types.TINYINT: + case Types.BIGINT: + case Types.SMALLINT: + case Types.INTEGER: + stmt.setLong(stmtNumber, p.getIntegerValue()); + + break; + + case Types.REAL: + case Types.FLOAT: + case Types.DOUBLE: + case Types.NUMERIC: + case Types.DECIMAL: + stmt.setDouble(stmtNumber, p.getFloatValue()); + + break; + + case Types.VARBINARY: + case Types.BINARY: + case Types.BLOB: + stmt.setString(stmtNumber, p.getStringValue()); + + break; + + case Types.LONGVARBINARY: + case Types.LONGVARCHAR: + + try { + stmt.setString(stmtNumber, p.getStringValue()); + } catch (SQLException x) { + String str = p.getStringValue(); + Reader r = new StringReader(str); + + stmt.setCharacterStream(stmtNumber, r, str.length()); + } + + break; + + case Types.CHAR: + case Types.VARCHAR: + case Types.OTHER: + stmt.setString(stmtNumber, p.getStringValue()); + + break; + + case Types.DATE: + case Types.TIME: + case Types.TIMESTAMP: + stmt.setTimestamp(stmtNumber, p.getTimestampValue()); + + break; + + case Types.NULL: + stmt.setNull(stmtNumber, 0); + + break; + + default: + stmt.setString(stmtNumber, p.getStringValue()); + + break; + } + } + + p.dirty = false; + + if (!rel.isPrivate()) { + markMappingAsUpdated = true; + } + } + + stmt.executeUpdate(); + } finally { + if (stmt != null) { + try { + stmt.close(); + } catch (Exception ignore) { + } + } + } + + if (markMappingAsUpdated) { + dbm.notifyDataChange(); + } + } + + // update may cause changes in the node's parent subnode array + if (node.isAnonymous()) { + Node parent = node.getCachedParent(); + + if (parent != null) { + parent.lastSubnodeChange = System.currentTimeMillis(); + } + } + + // tx.timer.endEvent ("updateNode "+node); + } + + /** + * Performs the actual deletion of a node from either the embedded or an external SQL database. + */ + public void deleteNode(IDatabase db, ITransaction txn, Node node) + throws Exception { + // Transactor tx = (Transactor) Thread.currentThread (); + // tx.timer.beginEvent ("deleteNode "+node); + DbMapping dbm = node.getDbMapping(); + + if ((dbm == null) || !dbm.isRelational()) { + db.deleteNode(txn, node.getID()); + } else { + Statement st = null; + + try { + Connection con = dbm.getConnection(); + String str = new StringBuffer("DELETE FROM ").append(dbm.getTableName()) + .append(" WHERE ") + .append(dbm.getIDField()) + .append(" = ") + .append(node.getID()) + .toString(); + + st = con.createStatement(); + st.executeUpdate(str); + + if (logSql) { + app.logEvent("### deleteNode: " + str); + } + } finally { + if (st != null) { + try { + st.close(); + } catch (Exception ignore) { + } + } + } + + dbm.notifyDataChange(); + } + + // node may still be cached via non-primary keys. mark as invalid + node.setState(Node.INVALID); + + // tx.timer.endEvent ("deleteNode "+node); } /** * Generates an ID for the table by finding out the maximum current value */ - public synchronized String generateMaxID (DbMapping map) throws Exception { + public synchronized String generateMaxID(DbMapping map) + throws Exception { + // Transactor tx = (Transactor) Thread.currentThread (); + // tx.timer.beginEvent ("generateID "+map); + String retval = null; + Statement stmt = null; - // Transactor tx = (Transactor) Thread.currentThread (); - // tx.timer.beginEvent ("generateID "+map); + try { + Connection con = map.getConnection(); + String q = new StringBuffer("SELECT MAX(").append(map.getIDField()) + .append(") FROM ") + .append(map.getTableName()) + .toString(); - String retval = null; - Statement stmt = null; - try { - Connection con = map.getConnection (); - String q = new StringBuffer("SELECT MAX(") - .append(map.getIDField()) - .append(") FROM ") - .append(map.getTableName()) - .toString(); - stmt = con.createStatement (); - ResultSet rs = stmt.executeQuery (q); - // check for empty table - if (!rs.next()) { - long currMax = map.getNewID (0); - retval = Long.toString (currMax); - } else { - long currMax = rs.getLong (1); - currMax = map.getNewID (currMax); - retval = Long.toString (currMax); - } - } finally { - // tx.timer.endEvent ("generateID "+map); - if (stmt != null) try { - stmt.close (); - } catch (Exception ignore) {} - } - return retval; + stmt = con.createStatement(); + + ResultSet rs = stmt.executeQuery(q); + + // check for empty table + if (!rs.next()) { + long currMax = map.getNewID(0); + + retval = Long.toString(currMax); + } else { + long currMax = rs.getLong(1); + + currMax = map.getNewID(currMax); + retval = Long.toString(currMax); + } + } finally { + // tx.timer.endEvent ("generateID "+map); + if (stmt != null) { + try { + stmt.close(); + } catch (Exception ignore) { + } + } + } + + return retval; } - /** * Generate a new ID from an Oracle sequence. */ - public String generateID (DbMapping map) throws Exception { + public String generateID(DbMapping map) throws Exception { + // Transactor tx = (Transactor) Thread.currentThread (); + // tx.timer.beginEvent ("generateID "+map); + Statement stmt = null; + String retval = null; - // Transactor tx = (Transactor) Thread.currentThread (); - // tx.timer.beginEvent ("generateID "+map); + try { + Connection con = map.getConnection(); + String q = new StringBuffer("SELECT ").append(map.getIDgen()) + .append(".nextval FROM dual").toString(); - Statement stmt = null; - String retval = null; - try { - Connection con = map.getConnection (); - String q = new StringBuffer("SELECT ") - .append(map.getIDgen()) - .append(".nextval FROM dual") - .toString(); - stmt = con.createStatement(); - ResultSet rs = stmt.executeQuery (q); - if (!rs.next ()) - throw new SQLException ("Error creating ID from Sequence: empty recordset"); - retval = rs.getString (1); - } finally { - // tx.timer.endEvent ("generateID "+map); - if (stmt != null) try { - stmt.close (); - } catch (Exception ignore) {} - } - return retval; + stmt = con.createStatement(); + + ResultSet rs = stmt.executeQuery(q); + + if (!rs.next()) { + throw new SQLException("Error creating ID from Sequence: empty recordset"); + } + + retval = rs.getString(1); + } finally { + // tx.timer.endEvent ("generateID "+map); + if (stmt != null) { + try { + stmt.close(); + } catch (Exception ignore) { + } + } + } + + return retval; } - /** * Loades subnodes via subnode relation. Only the ID index is loaded, the nodes are * loaded later on demand. */ - public List getNodeIDs (Node home, Relation rel) throws Exception { + public List getNodeIDs(Node home, Relation rel) throws Exception { + // Transactor tx = (Transactor) Thread.currentThread (); + // tx.timer.beginEvent ("getNodeIDs "+home); + if ((rel == null) || (rel.otherType == null) || !rel.otherType.isRelational()) { + // this should never be called for embedded nodes + throw new RuntimeException("NodeMgr.getNodeIDs called for non-relational node " + + home); + } else { + List retval = new ArrayList(); - // Transactor tx = (Transactor) Thread.currentThread (); - // tx.timer.beginEvent ("getNodeIDs "+home); + // if we do a groupby query (creating an intermediate layer of groupby nodes), + // retrieve the value of that field instead of the primary key + String idfield = (rel.groupby == null) ? rel.otherType.getIDField() + : rel.groupby; + Connection con = rel.otherType.getConnection(); + String table = rel.otherType.getTableName(); - if (rel == null || rel.otherType == null || !rel.otherType.isRelational ()) { - // this should never be called for embedded nodes - throw new RuntimeException ("NodeMgr.getNodeIDs called for non-relational node "+home); - } else { - List retval = new ArrayList (); - // if we do a groupby query (creating an intermediate layer of groupby nodes), - // retrieve the value of that field instead of the primary key - String idfield = rel.groupby == null ? rel.otherType.getIDField () : rel.groupby; - Connection con = rel.otherType.getConnection (); - String table = rel.otherType.getTableName (); + Statement stmt = null; - Statement stmt = null; - try { + try { + String q = null; - String q = null; + if (home.getSubnodeRelation() != null) { + // subnode relation was explicitly set + q = new StringBuffer("SELECT ").append(idfield).append(" FROM ") + .append(table).append(" ") + .append(home.getSubnodeRelation()) + .toString(); + } else { + // let relation object build the query + q = new StringBuffer("SELECT ").append(idfield).append(" FROM ") + .append(table) + .append(rel.buildQuery(home, + home.getNonVirtualParent(), + null, + " WHERE ", true)) + .toString(); + } - if (home.getSubnodeRelation() != null) { - // subnode relation was explicitly set - q = new StringBuffer("SELECT ") - .append(idfield) - .append(" FROM ") - .append(table) - .append(" ") - .append(home.getSubnodeRelation()) - .toString(); - } else { - // let relation object build the query - q = new StringBuffer("SELECT ") - .append(idfield) - .append(" FROM ") - .append(table) - .append(rel.buildQuery (home, - home.getNonVirtualParent (), null, - " WHERE ", true)) - .toString(); - } + if (logSql) { + app.logEvent("### getNodeIDs: " + q); + } - if (logSql) - app.logEvent ("### getNodeIDs: "+q); + stmt = con.createStatement(); - stmt = con.createStatement (); - if (rel.maxSize > 0) - stmt.setMaxRows (rel.maxSize); - ResultSet result = stmt.executeQuery (q); + if (rel.maxSize > 0) { + stmt.setMaxRows(rel.maxSize); + } - // problem: how do we derive a SyntheticKey from a not-yet-persistent Node? - Key k = rel.groupby != null ? home.getKey (): null; - while (result.next ()) { - String kstr = result.getString (1); - // jump over null values - this can happen especially when the selected - // column is a group-by column. - if (kstr == null) - continue; - // make the proper key for the object, either a generic DB key or a groupby key - Key key = rel.groupby == null ? - (Key) new DbKey (rel.otherType, kstr) : - (Key) new SyntheticKey (k, kstr); - retval.add (new NodeHandle (key)); - // if these are groupby nodes, evict nullNode keys - if (rel.groupby != null) { - Node n = (Node) cache.get (key); - if (n != null && n.isNullNode ()) - evictKey (key); - } - } + ResultSet result = stmt.executeQuery(q); - } finally { - // tx.timer.endEvent ("getNodeIDs "+home); - if (stmt != null) try { - stmt.close (); - } catch (Exception ignore) {} - } - return retval; - } + // problem: how do we derive a SyntheticKey from a not-yet-persistent Node? + Key k = (rel.groupby != null) ? home.getKey() : null; + + while (result.next()) { + String kstr = result.getString(1); + + // jump over null values - this can happen especially when the selected + // column is a group-by column. + if (kstr == null) { + continue; + } + + // make the proper key for the object, either a generic DB key or a groupby key + Key key = (rel.groupby == null) + ? (Key) new DbKey(rel.otherType, kstr) + : (Key) new SyntheticKey(k, kstr); + + retval.add(new NodeHandle(key)); + + // if these are groupby nodes, evict nullNode keys + if (rel.groupby != null) { + Node n = (Node) cache.get(key); + + if ((n != null) && n.isNullNode()) { + evictKey(key); + } + } + } + } finally { + // tx.timer.endEvent ("getNodeIDs "+home); + if (stmt != null) { + try { + stmt.close(); + } catch (Exception ignore) { + } + } + } + + return retval; + } } /** @@ -905,528 +1056,636 @@ public final class NodeManager { * actually loades all nodes in one go, which is better for small node collections. * This method is used when xxx.loadmode=aggressive is specified. */ - public List getNodes (Node home, Relation rel) throws Exception { + public List getNodes(Node home, Relation rel) throws Exception { + // This does not apply for groupby nodes - use getNodeIDs instead + if (rel.groupby != null) { + return getNodeIDs(home, rel); + } - // This does not apply for groupby nodes - use getNodeIDs instead - if (rel.groupby != null) - return getNodeIDs (home, rel); + // Transactor tx = (Transactor) Thread.currentThread (); + // tx.timer.beginEvent ("getNodes "+home); + if ((rel == null) || (rel.otherType == null) || !rel.otherType.isRelational()) { + // this should never be called for embedded nodes + throw new RuntimeException("NodeMgr.countNodes called for non-relational node " + + home); + } else { + List retval = new ArrayList(); + DbMapping dbm = rel.otherType; - // Transactor tx = (Transactor) Thread.currentThread (); - // tx.timer.beginEvent ("getNodes "+home); + Connection con = dbm.getConnection(); + Statement stmt = con.createStatement(); + DbColumn[] columns = dbm.getColumns(); + StringBuffer q = dbm.getSelect(); - if (rel == null || rel.otherType == null || !rel.otherType.isRelational ()) { - // this should never be called for embedded nodes - throw new RuntimeException ("NodeMgr.countNodes called for non-relational node "+home); - } else { - List retval = new ArrayList (); - DbMapping dbm = rel.otherType; + try { + if (home.getSubnodeRelation() != null) { + q.append(home.getSubnodeRelation()); + } else { + // let relation object build the query + q.append(rel.buildQuery(home, home.getNonVirtualParent(), null, + " WHERE ", false)); - Connection con = dbm.getConnection (); - Statement stmt = con.createStatement (); - DbColumn[] columns = dbm.getColumns (); - StringBuffer q = dbm.getSelect (); - try { - if (home.getSubnodeRelation() != null) { - q.append (home.getSubnodeRelation()); - } else { - // let relation object build the query - q.append (rel.buildQuery (home, home.getNonVirtualParent (), null, " WHERE ", false)); - if (rel.getOrder () != null) - q.append (" order by "+rel.getOrder ()); - } + if (rel.getOrder() != null) { + q.append(" order by " + rel.getOrder()); + } + } - if (logSql) - app.logEvent ("### getNodes: "+q.toString()); + if (logSql) { + app.logEvent("### getNodes: " + q.toString()); + } - if (rel.maxSize > 0) - stmt.setMaxRows (rel.maxSize); + if (rel.maxSize > 0) { + stmt.setMaxRows(rel.maxSize); + } - ResultSet rs = stmt.executeQuery (q.toString ()); + ResultSet rs = stmt.executeQuery(q.toString()); - while (rs.next()) { - // create new Nodes. - Node node = new Node (rel.otherType, rs, columns, safe); - Key primKey = node.getKey (); - retval.add (new NodeHandle (primKey)); - // do we need to synchronize on primKey here? - synchronized (cache) { - Node oldnode = (Node) cache.put (primKey, node); - if (oldnode != null && oldnode.getState() != INode.INVALID) { - cache.put (primKey, oldnode); - } - } - } + while (rs.next()) { + // create new Nodes. + Node node = new Node(rel.otherType, rs, columns, safe); + Key primKey = node.getKey(); - } finally { - // tx.timer.endEvent ("getNodes "+home); - if (stmt != null) try { - stmt.close (); - } catch (Exception ignore) {} - } - return retval; - } + retval.add(new NodeHandle(primKey)); + + // do we need to synchronize on primKey here? + synchronized (cache) { + Node oldnode = (Node) cache.put(primKey, node); + + if ((oldnode != null) && (oldnode.getState() != INode.INVALID)) { + cache.put(primKey, oldnode); + } + } + } + } finally { + // tx.timer.endEvent ("getNodes "+home); + if (stmt != null) { + try { + stmt.close(); + } catch (Exception ignore) { + } + } + } + + return retval; + } } /** * */ - public void prefetchNodes (Node home, Relation rel, Key[] keys) throws Exception { + public void prefetchNodes(Node home, Relation rel, Key[] keys) + throws Exception { + DbMapping dbm = rel.otherType; - DbMapping dbm = rel.otherType; - if (dbm == null || !dbm.isRelational ()) { - // this does nothing for objects in the embedded database - return; - } else { - int missing = cache.containsKeys (keys); - if (missing > 0) { - Connection con = dbm.getConnection (); - Statement stmt = con.createStatement (); - DbColumn[] columns = dbm.getColumns (); - StringBuffer q = dbm.getSelect (); - try { - String idfield = rel.groupby != null ? rel.groupby : dbm.getIDField (); - boolean needsQuotes = dbm.needsQuotes (idfield); - q.append ("WHERE "); - q.append (idfield); - q.append (" IN ("); - boolean first = true; - for (int i=0; i<keys.length; i++) { - if (keys[i] != null) { - if (!first) - q.append (','); - else - first = false; - if (needsQuotes) { - q.append ("'"); - q.append (escape (keys[i].getID ())); - q.append ("'"); - } else { - q.append (keys[i].getID ()); - } - } - } - q.append (") "); - if (rel.groupby != null) { - q.append (rel.renderConstraints (home, home.getNonVirtualParent ())); - if (rel.order != null) { - q.append (" ORDER BY "); - q.append (rel.order); - } - } + if ((dbm == null) || !dbm.isRelational()) { + // this does nothing for objects in the embedded database + return; + } else { + int missing = cache.containsKeys(keys); - if (logSql) - app.logEvent ("### prefetchNodes: "+q.toString()); + if (missing > 0) { + Connection con = dbm.getConnection(); + Statement stmt = con.createStatement(); + DbColumn[] columns = dbm.getColumns(); + StringBuffer q = dbm.getSelect(); - ResultSet rs = stmt.executeQuery (q.toString());; + try { + String idfield = (rel.groupby != null) ? rel.groupby : dbm.getIDField(); + boolean needsQuotes = dbm.needsQuotes(idfield); - String groupbyProp = null; - HashMap groupbySubnodes = null; - if (rel.groupby != null) { - groupbyProp = dbm.columnNameToProperty (rel.groupby); - groupbySubnodes = new HashMap(); - } + q.append("WHERE "); + q.append(idfield); + q.append(" IN ("); - String accessProp = null; - if (rel.accessName != null && !rel.usesPrimaryKey ()) - accessProp = dbm.columnNameToProperty (rel.accessName); + boolean first = true; - while (rs.next ()) { - // create new Nodes. - Node node = new Node (dbm, rs, columns, safe); - Key primKey = node.getKey (); + for (int i = 0; i < keys.length; i++) { + if (keys[i] != null) { + if (!first) { + q.append(','); + } else { + first = false; + } - // for grouped nodes, collect subnode lists for the intermediary - // group nodes. - String groupName = null; - if (groupbyProp != null) { - groupName = node.getString (groupbyProp); - List sn = (List) groupbySubnodes.get (groupName); - if (sn == null) { - sn = new ExternalizableVector (); - groupbySubnodes.put (groupName, sn); - } - sn.add (new NodeHandle (primKey)); - } + if (needsQuotes) { + q.append("'"); + q.append(escape(keys[i].getID())); + q.append("'"); + } else { + q.append(keys[i].getID()); + } + } + } - // if relation doesn't use primary key as accessName, get accessName value - String accessName = null; - if (accessProp != null) { - accessName = node.getString (accessProp); - } + q.append(") "); - // register new nodes with the cache. If an up-to-date copy - // existed in the cache, use that. - synchronized (cache) { - Node oldnode = (Node) cache.put (primKey, node); - if (oldnode != null && oldnode.getState() != INode.INVALID) { - // found an ok version in the cache, use it. - cache.put (primKey, oldnode); - } else if (accessName != null) { - // put the node into cache with its secondary key - if (groupName != null) - cache.put (new SyntheticKey (new SyntheticKey (home.getKey(), groupName), accessName), node); - else - cache.put (new SyntheticKey (home.getKey(), accessName), node); - } - } - } - // If these are grouped nodes, build the intermediary group nodes - // with the subnod lists we created - if (groupbyProp != null) { - for (Iterator i=groupbySubnodes.keySet().iterator(); i.hasNext(); ) { - String groupname = (String) i.next(); - if (groupname == null) continue; - Node groupnode = home.getGroupbySubnode (groupname, true); - cache.put (groupnode.getKey(), groupnode); - groupnode.setSubnodes ((List) groupbySubnodes.get(groupname)); - groupnode.lastSubnodeFetch = System.currentTimeMillis (); - } - } - } finally { - if (stmt != null) try { - stmt.close (); - } catch (Exception ignore) {} - } - } - } + if (rel.groupby != null) { + q.append(rel.renderConstraints(home, home.getNonVirtualParent())); + + if (rel.order != null) { + q.append(" ORDER BY "); + q.append(rel.order); + } + } + + if (logSql) { + app.logEvent("### prefetchNodes: " + q.toString()); + } + + ResultSet rs = stmt.executeQuery(q.toString()); + + ; + + String groupbyProp = null; + HashMap groupbySubnodes = null; + + if (rel.groupby != null) { + groupbyProp = dbm.columnNameToProperty(rel.groupby); + groupbySubnodes = new HashMap(); + } + + String accessProp = null; + + if ((rel.accessName != null) && !rel.usesPrimaryKey()) { + accessProp = dbm.columnNameToProperty(rel.accessName); + } + + while (rs.next()) { + // create new Nodes. + Node node = new Node(dbm, rs, columns, safe); + Key primKey = node.getKey(); + + // for grouped nodes, collect subnode lists for the intermediary + // group nodes. + String groupName = null; + + if (groupbyProp != null) { + groupName = node.getString(groupbyProp); + + List sn = (List) groupbySubnodes.get(groupName); + + if (sn == null) { + sn = new ExternalizableVector(); + groupbySubnodes.put(groupName, sn); + } + + sn.add(new NodeHandle(primKey)); + } + + // if relation doesn't use primary key as accessName, get accessName value + String accessName = null; + + if (accessProp != null) { + accessName = node.getString(accessProp); + } + + // register new nodes with the cache. If an up-to-date copy + // existed in the cache, use that. + synchronized (cache) { + Node oldnode = (Node) cache.put(primKey, node); + + if ((oldnode != null) && + (oldnode.getState() != INode.INVALID)) { + // found an ok version in the cache, use it. + cache.put(primKey, oldnode); + } else if (accessName != null) { + // put the node into cache with its secondary key + if (groupName != null) { + cache.put(new SyntheticKey(new SyntheticKey(home.getKey(), + groupName), + accessName), node); + } else { + cache.put(new SyntheticKey(home.getKey(), accessName), + node); + } + } + } + } + + // If these are grouped nodes, build the intermediary group nodes + // with the subnod lists we created + if (groupbyProp != null) { + for (Iterator i = groupbySubnodes.keySet().iterator(); + i.hasNext();) { + String groupname = (String) i.next(); + + if (groupname == null) { + continue; + } + + Node groupnode = home.getGroupbySubnode(groupname, true); + + cache.put(groupnode.getKey(), groupnode); + groupnode.setSubnodes((List) groupbySubnodes.get(groupname)); + groupnode.lastSubnodeFetch = System.currentTimeMillis(); + } + } + } finally { + if (stmt != null) { + try { + stmt.close(); + } catch (Exception ignore) { + } + } + } + } + } } - - /** * Count the nodes contained in the child collection of the home node * which is defined by Relation rel. */ - public int countNodes (Node home, Relation rel) throws Exception { + public int countNodes(Node home, Relation rel) throws Exception { + // Transactor tx = (Transactor) Thread.currentThread (); + // tx.timer.beginEvent ("countNodes "+home); + if ((rel == null) || (rel.otherType == null) || !rel.otherType.isRelational()) { + // this should never be called for embedded nodes + throw new RuntimeException("NodeMgr.countNodes called for non-relational node " + + home); + } else { + int retval = 0; + Connection con = rel.otherType.getConnection(); + String table = rel.otherType.getTableName(); - // Transactor tx = (Transactor) Thread.currentThread (); - // tx.timer.beginEvent ("countNodes "+home); + Statement stmt = null; - if (rel == null || rel.otherType == null || !rel.otherType.isRelational ()) { - // this should never be called for embedded nodes - throw new RuntimeException ("NodeMgr.countNodes called for non-relational node "+home); - } else { - int retval = 0; - Connection con = rel.otherType.getConnection (); - String table = rel.otherType.getTableName (); + try { + String q = null; - Statement stmt = null; - try { + if (home.getSubnodeRelation() != null) { + // use the manually set subnoderelation of the home node + q = new StringBuffer("SELECT count(*) FROM ").append(table).append(" ") + .append(home.getSubnodeRelation()) + .toString(); + } else { + // let relation object build the query + q = new StringBuffer("SELECT count(*) FROM ").append(table) + .append(rel.buildQuery(home, + home.getNonVirtualParent(), + null, + " WHERE ", + false)) + .toString(); + } - String q = null; - if (home.getSubnodeRelation() != null) { - // use the manually set subnoderelation of the home node - q = new StringBuffer("SELECT count(*) FROM ") - .append(table) - .append(" ") - .append(home.getSubnodeRelation()) - .toString(); - } else { - // let relation object build the query - q = new StringBuffer("SELECT count(*) FROM ") - .append(table) - .append(rel.buildQuery (home, home.getNonVirtualParent(), - null, " WHERE ", false)) - .toString(); - } + if (logSql) { + app.logEvent("### countNodes: " + q); + } - if (logSql) - app.logEvent ("### countNodes: "+q); + stmt = con.createStatement(); - stmt = con.createStatement(); + ResultSet rs = stmt.executeQuery(q); - ResultSet rs = stmt.executeQuery (q); - if (!rs.next()) - retval = 0; - else - retval = rs.getInt (1); + if (!rs.next()) { + retval = 0; + } else { + retval = rs.getInt(1); + } + } finally { + // tx.timer.endEvent ("countNodes "+home); + if (stmt != null) { + try { + stmt.close(); + } catch (Exception ignore) { + } + } + } - } finally { - // tx.timer.endEvent ("countNodes "+home); - if (stmt != null) try { - stmt.close (); - } catch (Exception ignore) {} - } - return rel.maxSize > 0 ? Math.min (rel.maxSize, retval) : retval; - } + return (rel.maxSize > 0) ? Math.min(rel.maxSize, retval) : retval; + } } /** * Similar to getNodeIDs, but returns a Vector that return's the nodes property names instead of IDs */ - public Vector getPropertyNames (Node home, Relation rel) throws Exception { + public Vector getPropertyNames(Node home, Relation rel) + throws Exception { + // Transactor tx = (Transactor) Thread.currentThread (); + // tx.timer.beginEvent ("getNodeIDs "+home); + if ((rel == null) || (rel.otherType == null) || !rel.otherType.isRelational()) { + // this should never be called for embedded nodes + throw new RuntimeException("NodeMgr.getPropertyNames called for non-relational node " + + home); + } else { + Vector retval = new Vector(); - // Transactor tx = (Transactor) Thread.currentThread (); - // tx.timer.beginEvent ("getNodeIDs "+home); + // if we do a groupby query (creating an intermediate layer of groupby nodes), + // retrieve the value of that field instead of the primary key + String namefield = rel.accessName; + Connection con = rel.otherType.getConnection(); + String table = rel.otherType.getTableName(); - if (rel == null || rel.otherType == null || !rel.otherType.isRelational ()) { - // this should never be called for embedded nodes - throw new RuntimeException ("NodeMgr.getPropertyNames called for non-relational node "+home); - } else { - Vector retval = new Vector (); - // if we do a groupby query (creating an intermediate layer of groupby nodes), - // retrieve the value of that field instead of the primary key - String namefield = rel.accessName; - Connection con = rel.otherType.getConnection (); - String table = rel.otherType.getTableName (); + Statement stmt = null; - Statement stmt = null; + try { + String q = new StringBuffer("SELECT ").append(namefield).append(" FROM ") + .append(table).append(" ORDER BY ") + .append(namefield).toString(); - try { - String q = new StringBuffer("SELECT ") - .append(namefield) - .append(" FROM ") - .append(table) - .append(" ORDER BY ") - .append(namefield) - .toString(); - stmt = con.createStatement (); + stmt = con.createStatement(); - if (logSql) - app.logEvent ("### getPropertyNames: "+q); + if (logSql) { + app.logEvent("### getPropertyNames: " + q); + } - ResultSet rs = stmt.executeQuery (q); - while (rs.next()) { - String n = rs.getString (1); - if (n != null) - retval.addElement (n); - } + ResultSet rs = stmt.executeQuery(q); - } finally { - // tx.timer.endEvent ("getNodeIDs "+home); - if (stmt != null) try { - stmt.close (); - } catch (Exception ignore) {} - } - return retval; - } + while (rs.next()) { + String n = rs.getString(1); + + if (n != null) { + retval.addElement(n); + } + } + } finally { + // tx.timer.endEvent ("getNodeIDs "+home); + if (stmt != null) { + try { + stmt.close(); + } catch (Exception ignore) { + } + } + } + + return retval; + } } - /////////////////////////////////////////////////////////////////////////////////////// // private getNode methods /////////////////////////////////////////////////////////////////////////////////////// + private Node getNodeByKey(ITransaction txn, DbKey key) + throws Exception { + // Note: Key must be a DbKey, otherwise will not work for relational objects + Node node = null; + DbMapping dbm = app.getDbMapping(key.getStorageName()); + String kstr = key.getID(); - private Node getNodeByKey (ITransaction txn, DbKey key) throws Exception { - // Note: Key must be a DbKey, otherwise will not work for relational objects - Node node = null; - DbMapping dbm = app.getDbMapping (key.getStorageName ()); - String kstr = key.getID (); + if ((dbm == null) || !dbm.isRelational()) { + node = (Node) db.getNode(txn, kstr); + node.nmgr = safe; - if (dbm == null || !dbm.isRelational ()) { - node = (Node)db.getNode (txn, kstr); - node.nmgr = safe; - if (node != null && dbm != null) - node.setDbMapping (dbm); - } else { - String idfield =dbm.getIDField (); + if ((node != null) && (dbm != null)) { + node.setDbMapping(dbm); + } + } else { + String idfield = dbm.getIDField(); - Statement stmt = null; - try { - Connection con = dbm.getConnection (); - stmt = con.createStatement (); + Statement stmt = null; - DbColumn[] columns = dbm.getColumns (); - StringBuffer q = dbm.getSelect (); - q.append ("WHERE "); - q.append (idfield); - q.append (" = "); - if (dbm.needsQuotes (idfield)) { - q.append ("'"); - q.append (escape(kstr)); - q.append ("'"); - } else { - q.append (kstr); - } + try { + Connection con = dbm.getConnection(); - if (logSql) - app.logEvent ("### getNodeByKey: "+q.toString()); + stmt = con.createStatement(); - ResultSet rs = stmt.executeQuery (q.toString()); + DbColumn[] columns = dbm.getColumns(); + StringBuffer q = dbm.getSelect(); - if (!rs.next ()) - return null; - node = new Node (dbm, rs, columns, safe); - if (rs.next ()) - throw new RuntimeException ("More than one value returned by query."); + q.append("WHERE "); + q.append(idfield); + q.append(" = "); - } finally { - if (stmt != null) try { - stmt.close (); - } catch (Exception ignore) {} - } - } - return node; + if (dbm.needsQuotes(idfield)) { + q.append("'"); + q.append(escape(kstr)); + q.append("'"); + } else { + q.append(kstr); + } + + if (logSql) { + app.logEvent("### getNodeByKey: " + q.toString()); + } + + ResultSet rs = stmt.executeQuery(q.toString()); + + if (!rs.next()) { + return null; + } + + node = new Node(dbm, rs, columns, safe); + + if (rs.next()) { + throw new RuntimeException("More than one value returned by query."); + } + } finally { + if (stmt != null) { + try { + stmt.close(); + } catch (Exception ignore) { + } + } + } + } + + return node; } - private Node getNodeByRelation (ITransaction txn, Node home, String kstr, Relation rel) throws Exception { - Node node = null; + private Node getNodeByRelation(ITransaction txn, Node home, String kstr, Relation rel) + throws Exception { + Node node = null; - if (rel != null && rel.virtual) { - if (rel.needsPersistence ()) - node = (Node) home.createNode (kstr); - else - node = new Node (home, kstr, safe, rel.prototype); - // set prototype and dbmapping on the newly created virtual/collection node - node.setPrototype (rel.prototype); - node.setDbMapping (rel.getVirtualMapping ()); + if ((rel != null) && rel.virtual) { + if (rel.needsPersistence()) { + node = (Node) home.createNode(kstr); + } else { + node = new Node(home, kstr, safe, rel.prototype); + } - } else if (rel != null && rel.groupby != null) { - node = home.getGroupbySubnode (kstr, false); - if (node == null && (rel.otherType == null || !rel.otherType.isRelational ())) { - node = (Node)db.getNode (txn, kstr); - node.nmgr = safe; - } - return node; + // set prototype and dbmapping on the newly created virtual/collection node + node.setPrototype(rel.prototype); + node.setDbMapping(rel.getVirtualMapping()); + } else if ((rel != null) && (rel.groupby != null)) { + node = home.getGroupbySubnode(kstr, false); - } else if (rel == null || rel.otherType == null || !rel.otherType.isRelational ()) { - node = (Node)db.getNode (txn, kstr); - node.nmgr = safe; - node.setDbMapping (rel.otherType); - return node; + if ((node == null) && + ((rel.otherType == null) || !rel.otherType.isRelational())) { + node = (Node) db.getNode(txn, kstr); + node.nmgr = safe; + } - } else { - Statement stmt = null; - try { - DbMapping dbm = rel.otherType; + return node; + } else if ((rel == null) || (rel.otherType == null) || + !rel.otherType.isRelational()) { + node = (Node) db.getNode(txn, kstr); + node.nmgr = safe; + node.setDbMapping(rel.otherType); - Connection con = dbm.getConnection (); - DbColumn[] columns = dbm.getColumns (); - StringBuffer q = dbm.getSelect (); - if (home.getSubnodeRelation () != null) { - // combine our key with the constraints in the manually set subnode relation - q.append ("WHERE "); - q.append (rel.accessName); - q.append (" = '"); - q.append (escape(kstr)); - q.append ("'"); - q.append (" AND "); - q.append (home.getSubnodeRelation().trim().substring(5)); - } else { - q.append (rel.buildQuery (home, home.getNonVirtualParent (), kstr, "WHERE ", false)); - } - if (logSql) - app.logEvent ("### getNodeByRelation: "+q.toString()); + return node; + } else { + Statement stmt = null; - stmt = con.createStatement (); - ResultSet rs = stmt.executeQuery (q.toString()); + try { + DbMapping dbm = rel.otherType; - if (!rs.next ()) - return null; - node = new Node (rel.otherType, rs, columns, safe); - if (rs.next ()) - throw new RuntimeException ("More than one value returned by query."); + Connection con = dbm.getConnection(); + DbColumn[] columns = dbm.getColumns(); + StringBuffer q = dbm.getSelect(); - // Check if node is already cached with primary Key. - if (!rel.usesPrimaryKey()) { - Key pk = node.getKey(); - Node existing = (Node) cache.get (pk); - if (existing != null && existing.getState() != Node.INVALID) { - node = existing; - } - } + if (home.getSubnodeRelation() != null) { + // combine our key with the constraints in the manually set subnode relation + q.append("WHERE "); + q.append(rel.accessName); + q.append(" = '"); + q.append(escape(kstr)); + q.append("'"); + q.append(" AND "); + q.append(home.getSubnodeRelation().trim().substring(5)); + } else { + q.append(rel.buildQuery(home, home.getNonVirtualParent(), kstr, + "WHERE ", false)); + } - } finally { - if (stmt != null) try { - stmt.close (); - } catch (Exception ignore) {} - } - } - return node; + if (logSql) { + app.logEvent("### getNodeByRelation: " + q.toString()); + } + + stmt = con.createStatement(); + + ResultSet rs = stmt.executeQuery(q.toString()); + + if (!rs.next()) { + return null; + } + + node = new Node(rel.otherType, rs, columns, safe); + + if (rs.next()) { + throw new RuntimeException("More than one value returned by query."); + } + + // Check if node is already cached with primary Key. + if (!rel.usesPrimaryKey()) { + Key pk = node.getKey(); + Node existing = (Node) cache.get(pk); + + if ((existing != null) && (existing.getState() != Node.INVALID)) { + node = existing; + } + } + } finally { + if (stmt != null) { + try { + stmt.close(); + } catch (Exception ignore) { + } + } + } + } + + return node; } /** * Get a DbMapping for a given prototype name. This is just a proxy * method to the app's getDbMapping() method. */ - public DbMapping getDbMapping (String protoname) { - return app.getDbMapping (protoname); + public DbMapping getDbMapping(String protoname) { + return app.getDbMapping(protoname); } // a utility method to escape single quotes - private String escape (String str) { - if (str == null) + private String escape(String str) { + if (str == null) { return null; - if (str.indexOf ("'") < 0) - return str; - int l = str.length(); - StringBuffer sbuf = new StringBuffer (l + 10); - for (int i=0; i<l; i++) { - char c = str.charAt (i); - if (c == '\'') - sbuf.append ('\''); - sbuf.append (c); } - return sbuf.toString (); - } + if (str.indexOf("'") < 0) { + return str; + } + + int l = str.length(); + StringBuffer sbuf = new StringBuffer(l + 10); + + for (int i = 0; i < l; i++) { + char c = str.charAt(i); + + if (c == '\'') { + sbuf.append('\''); + } + + sbuf.append(c); + } + + return sbuf.toString(); + } /** * Get an array of the the keys currently held in the object cache */ - public Object[] getCacheEntries () { - return cache.getEntryArray (); + public Object[] getCacheEntries() { + return cache.getEntryArray(); } /** * Get the number of elements in the object cache */ - public int countCacheEntries () { - return cache.size (); + public int countCacheEntries() { + return cache.size(); } /** - * Clear the object cache, causing all objects to be recreated. - */ - public void clearCache () { - synchronized (cache) { - cache.clear (); - } + * Clear the object cache, causing all objects to be recreated. + */ + public void clearCache() { + synchronized (cache) { + cache.clear(); + } } /** * Get a replicator for this node cache. A replicator is used to transfer updates * in this node manager to other node managers in remote servers via RMI. */ - protected Replicator getReplicator () { - return replicator; + protected Replicator getReplicator() { + return replicator; } - /** - * Receive notification from a remote app that objects in its cache have been - * modified. - */ - public void replicateCache (Vector add, Vector delete) { - if (logReplication) - app.logEvent ("Received cache replication event: "+add.size()+ - " added, "+delete.size()+" deleted"); - synchronized (cache) { - for (Enumeration en=add.elements(); en.hasMoreElements(); ) { - Node n = (Node) en.nextElement (); - DbMapping dbm = app.getDbMapping (n.getPrototype ()); - if (dbm != null) - dbm.notifyDataChange (); - n.lastParentSet = -1; - n.setDbMapping (dbm); - n.nmgr = safe; - cache.put (n.getKey(), n); - } - for (Enumeration en=delete.elements(); en.hasMoreElements(); ) { - // NOTE: it would be more efficient to transfer just the keys - // of nodes that are to be deleted. - Node n = (Node) en.nextElement (); - DbMapping dbm = app.getDbMapping (n.getPrototype ()); - if (dbm != null) - dbm.notifyDataChange (); - n.setDbMapping (dbm); - n.nmgr = safe; - Node oldNode = (Node) cache.get (n.getKey()); - if (oldNode != null) - evictNode (oldNode); - } - } + * Receive notification from a remote app that objects in its cache have been + * modified. + */ + public void replicateCache(Vector add, Vector delete) { + if (logReplication) { + app.logEvent("Received cache replication event: " + add.size() + " added, " + + delete.size() + " deleted"); + } + + synchronized (cache) { + for (Enumeration en = add.elements(); en.hasMoreElements();) { + Node n = (Node) en.nextElement(); + DbMapping dbm = app.getDbMapping(n.getPrototype()); + + if (dbm != null) { + dbm.notifyDataChange(); + } + + n.lastParentSet = -1; + n.setDbMapping(dbm); + n.nmgr = safe; + cache.put(n.getKey(), n); + } + + for (Enumeration en = delete.elements(); en.hasMoreElements();) { + // NOTE: it would be more efficient to transfer just the keys + // of nodes that are to be deleted. + Node n = (Node) en.nextElement(); + DbMapping dbm = app.getDbMapping(n.getPrototype()); + + if (dbm != null) { + dbm.notifyDataChange(); + } + + n.setDbMapping(dbm); + n.nmgr = safe; + + Node oldNode = (Node) cache.get(n.getKey()); + + if (oldNode != null) { + evictNode(oldNode); + } + } + } } - } - diff --git a/src/helma/objectmodel/db/ParentInfo.java b/src/helma/objectmodel/db/ParentInfo.java index 4931e013..b572a74e 100644 --- a/src/helma/objectmodel/db/ParentInfo.java +++ b/src/helma/objectmodel/db/ParentInfo.java @@ -1,5 +1,18 @@ -// ParentInfo.java -// Copyright (c) Hannes Wallnöfer 1999-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.objectmodel.db; @@ -7,35 +20,45 @@ package helma.objectmodel.db; /** * This class describes a parent relation between releational nodes. */ - public class ParentInfo { - public final String propname; public final String virtualname; public final boolean named; public final boolean isroot; + /** + * Creates a new ParentInfo object. + * + * @param desc ... + */ + public ParentInfo(String desc) { + int n = desc.indexOf("[named]"); - public ParentInfo (String desc) { - int n = desc.indexOf ("[named]"); - named = n > -1; - String d = named ? desc.substring (0, n) : desc; + named = n > -1; - int dot = d.indexOf ("."); - if (dot > -1) { - propname = d.substring (0, dot).trim(); - virtualname = d.substring (dot+1).trim(); - } else { - propname = d.trim(); - virtualname = null; - } - - isroot = "root".equals (propname); - // System.err.println ("created "+this); - } + String d = named ? desc.substring(0, n) : desc; - public String toString () { - return "ParentInfo["+propname+","+virtualname+","+named+"]"; + int dot = d.indexOf("."); + + if (dot > -1) { + propname = d.substring(0, dot).trim(); + virtualname = d.substring(dot + 1).trim(); + } else { + propname = d.trim(); + virtualname = null; + } + + isroot = "root".equals(propname); + + // System.err.println ("created "+this); } + /** + * + * + * @return ... + */ + public String toString() { + return "ParentInfo[" + propname + "," + virtualname + "," + named + "]"; + } } diff --git a/src/helma/objectmodel/db/Property.java b/src/helma/objectmodel/db/Property.java index beabe7fa..bd513008 100644 --- a/src/helma/objectmodel/db/Property.java +++ b/src/helma/objectmodel/db/Property.java @@ -1,342 +1,558 @@ -// Property.java -// Copyright (c) Hannes Wallnöfer 1997-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel.db; -import helma.util.*; -import java.util.*; -import java.io.*; -import java.text.*; import helma.objectmodel.*; +import helma.util.*; +import java.io.*; import java.sql.Timestamp; +import java.text.*; +import java.util.*; /** * A property implementation for Nodes stored inside a database. Basically * the same as for transient nodes, with a few hooks added. */ public final class Property implements IProperty, Serializable, Cloneable { - - + static final long serialVersionUID = -1022221688349192379L; private String propname; private Node node; - private Object value; - private int type; - transient boolean dirty; - static final long serialVersionUID = -1022221688349192379L; - - private void readObject (ObjectInputStream in) throws IOException { - try { - propname = in.readUTF (); - node = (Node) in.readObject (); - type = in.readInt (); - switch (type) { - case STRING: - // try to convert from old format - if (node.version < 7) - value = in.readUTF (); - else - value = in.readObject (); - break; - case BOOLEAN: - value = in.readBoolean () ? Boolean.TRUE : Boolean.FALSE; - break; - case INTEGER: - value = new Long (in.readLong ()); - break; - case DATE: - value = new Date (in.readLong ()); - break; - case FLOAT: - value = new Double (in.readDouble ()); - break; - case NODE: - // try to convert from old format - if (node.version > 4) - value = (NodeHandle) in.readObject (); - else - value = new NodeHandle (new DbKey (null, in.readUTF ())); - break; - case JAVAOBJECT: - value = in.readObject (); - break; - } - } catch (ClassNotFoundException x) { - throw new IOException (x.toString ()); - } + /** + * Creates a new Property object. + * + * @param node ... + */ + public Property(Node node) { + this.node = node; + dirty = true; } - private void writeObject (ObjectOutputStream out) throws IOException { - out.writeUTF (propname); - out.writeObject (node); - out.writeInt (type); - switch (type) { - case STRING: - out.writeObject (value); - break; - case BOOLEAN: - out.writeBoolean (((Boolean) value).booleanValue()); - break; - case INTEGER: - out.writeLong (((Long) value).longValue()); - break; - case DATE: - out.writeLong (((Date) value).getTime()); - break; - case FLOAT: - out.writeDouble (((Double) value).doubleValue()); - break; - case NODE: - out.writeObject (value); - break; - case JAVAOBJECT: - if (value != null && !(value instanceof Serializable)) - out.writeObject (null); - else - out.writeObject (value); - break; - } + /** + * Creates a new Property object. + * + * @param propname ... + * @param node ... + */ + public Property(String propname, Node node) { + this.propname = propname; + this.node = node; + dirty = true; } - - public Property (Node node) { - this.node = node; - dirty = true; + /** + * Creates a new Property object. + * + * @param propname ... + * @param node ... + * @param valueNode ... + */ + public Property(String propname, Node node, Node valueNode) { + this(propname, node); + type = NODE; + value = (valueNode == null) ? null : valueNode.getHandle(); + dirty = true; } - public Property (String propname, Node node) { - this.propname = propname; - this.node = node; - dirty = true; + private void readObject(ObjectInputStream in) throws IOException { + try { + propname = in.readUTF(); + node = (Node) in.readObject(); + type = in.readInt(); + + switch (type) { + case STRING: + + // try to convert from old format + if (node.version < 7) { + value = in.readUTF(); + } else { + value = in.readObject(); + } + + break; + + case BOOLEAN: + value = in.readBoolean() ? Boolean.TRUE : Boolean.FALSE; + + break; + + case INTEGER: + value = new Long(in.readLong()); + + break; + + case DATE: + value = new Date(in.readLong()); + + break; + + case FLOAT: + value = new Double(in.readDouble()); + + break; + + case NODE: + + // try to convert from old format + if (node.version > 4) { + value = (NodeHandle) in.readObject(); + } else { + value = new NodeHandle(new DbKey(null, in.readUTF())); + } + + break; + + case JAVAOBJECT: + value = in.readObject(); + + break; + } + } catch (ClassNotFoundException x) { + throw new IOException(x.toString()); + } } - public Property (String propname, Node node, Node valueNode) { - this (propname, node); - type = NODE; - value = valueNode == null ? null : valueNode.getHandle (); - dirty = true; + private void writeObject(ObjectOutputStream out) throws IOException { + out.writeUTF(propname); + out.writeObject(node); + out.writeInt(type); + + switch (type) { + case STRING: + out.writeObject(value); + + break; + + case BOOLEAN: + out.writeBoolean(((Boolean) value).booleanValue()); + + break; + + case INTEGER: + out.writeLong(((Long) value).longValue()); + + break; + + case DATE: + out.writeLong(((Date) value).getTime()); + + break; + + case FLOAT: + out.writeDouble(((Double) value).doubleValue()); + + break; + + case NODE: + out.writeObject(value); + + break; + + case JAVAOBJECT: + + if ((value != null) && !(value instanceof Serializable)) { + out.writeObject(null); + } else { + out.writeObject(value); + } + + break; + } } - public String getName () { - return propname; + /** + * + * + * @return ... + */ + public String getName() { + return propname; } - public Object getValue () { - return value; + /** + * + * + * @return ... + */ + public Object getValue() { + return value; } - public int getType () { - return type; + /** + * + * + * @return ... + */ + public int getType() { + return type; } - public void setStringValue (String str) { - if (type == NODE) - unregisterNode (); - type = STRING; - value = str; - dirty = true; + /** + * + * + * @param str ... + */ + public void setStringValue(String str) { + if (type == NODE) { + unregisterNode(); + } + + type = STRING; + value = str; + dirty = true; } + /** + * + * + * @param l ... + */ + public void setIntegerValue(long l) { + if (type == NODE) { + unregisterNode(); + } - public void setIntegerValue (long l) { - if (type == NODE) - unregisterNode (); - type = INTEGER; - value = new Long(l); - dirty = true; + type = INTEGER; + value = new Long(l); + dirty = true; } - public void setFloatValue (double d) { - if (type == NODE) - unregisterNode (); - type = FLOAT; - value = new Double(d); - dirty = true; + /** + * + * + * @param d ... + */ + public void setFloatValue(double d) { + if (type == NODE) { + unregisterNode(); + } + + type = FLOAT; + value = new Double(d); + dirty = true; } - public void setDateValue (Date date) { - if (type == NODE) - unregisterNode (); - type = DATE; - value = date; - dirty = true; + /** + * + * + * @param date ... + */ + public void setDateValue(Date date) { + if (type == NODE) { + unregisterNode(); + } + + type = DATE; + value = date; + dirty = true; } - public void setBooleanValue (boolean bool) { - if (type == NODE) - unregisterNode (); - type = BOOLEAN; - value = bool ? Boolean.TRUE : Boolean.FALSE; - dirty = true; + /** + * + * + * @param bool ... + */ + public void setBooleanValue(boolean bool) { + if (type == NODE) { + unregisterNode(); + } + + type = BOOLEAN; + value = bool ? Boolean.TRUE : Boolean.FALSE; + dirty = true; } - public void setNodeValue (Node node) { - // value.checkWriteLock (); - if (type == NODE) - unregisterNode (); + /** + * + * + * @param node ... + */ + public void setNodeValue(Node node) { + // value.checkWriteLock (); + if (type == NODE) { + unregisterNode(); + } - // registerNode (value); - type = NODE; + // registerNode (value); + type = NODE; - value = node == null ? null : node.getHandle (); - dirty = true; + value = (node == null) ? null : node.getHandle(); + dirty = true; } - public void setNodeHandle (NodeHandle handle) { - if (type == NODE) - unregisterNode (); - // registerNode (value); - type = NODE; - value = handle; - dirty = true; + /** + * + * + * @param handle ... + */ + public void setNodeHandle(NodeHandle handle) { + if (type == NODE) { + unregisterNode(); + } + + // registerNode (value); + type = NODE; + value = handle; + dirty = true; } - public NodeHandle getNodeHandle () { - if (type == NODE) - return (NodeHandle) value; - return null; + /** + * + * + * @return ... + */ + public NodeHandle getNodeHandle() { + if (type == NODE) { + return (NodeHandle) value; + } + + return null; } - public void convertToNodeReference (DbMapping dbm) { - if (value != null && !(value instanceof NodeHandle)) - value = new NodeHandle (new DbKey (dbm, value.toString ())); - type = NODE; + /** + * + * + * @param dbm ... + */ + public void convertToNodeReference(DbMapping dbm) { + if ((value != null) && !(value instanceof NodeHandle)) { + value = new NodeHandle(new DbKey(dbm, value.toString())); + } + + type = NODE; } - public void setJavaObjectValue (Object obj) { - if (type == NODE) - unregisterNode (); - type = JAVAOBJECT; - value = obj; - } + /** + * + * + * @param obj ... + */ + public void setJavaObjectValue(Object obj) { + if (type == NODE) { + unregisterNode(); + } + type = JAVAOBJECT; + value = obj; + } /** * tell a the value node that it is no longer used as a property. * If this was the "main" property for the node, also remove all other references. */ - protected void unregisterNode () { - if (value == null || !(value instanceof NodeHandle)) - return; - NodeHandle nhandle = (NodeHandle) value; - Node nvalue = nhandle.getNode (node.nmgr); + protected void unregisterNode() { + if ((value == null) || !(value instanceof NodeHandle)) { + return; + } - DbMapping nvmap = null; - Relation nvrel = null; - if (node.dbmap != null) { - nvmap = node.dbmap.getPropertyMapping (propname); - nvrel = node.dbmap.getPropertyRelation (propname); - } + NodeHandle nhandle = (NodeHandle) value; + Node nvalue = nhandle.getNode(node.nmgr); - if (nvalue == null) - return; + DbMapping nvmap = null; + Relation nvrel = null; - nvalue.checkWriteLock (); - // check if the property node is also a subnode - // BUG: this doesn't work because properties for subnode/properties are never stored and therefore - // never reused. - if (nvrel != null && nvrel.hasAccessName()) { - node.removeNode (nvalue); - } - // only need to call unregisterPropLink if the value node is not stored in a relational db - // also, getParent is heuristical/implicit for relational nodes, so we don't do deepRemoveNode - // based on that for relational nodes. - if (nvmap == null || !nvmap.isRelational()) { - if (!nvalue.isAnonymous() && propname.equals (nvalue.getName()) && this.node == nvalue.getParent()) { - // this is the "main" property of a named node, so handle this as a cascading delete. - nvalue.deepRemoveNode (); - } - } + if (node.dbmap != null) { + nvmap = node.dbmap.getPropertyMapping(propname); + nvrel = node.dbmap.getPropertyRelation(propname); + } + + if (nvalue == null) { + return; + } + + nvalue.checkWriteLock(); + + // check if the property node is also a subnode + // BUG: this doesn't work because properties for subnode/properties are never stored and therefore + // never reused. + if ((nvrel != null) && nvrel.hasAccessName()) { + node.removeNode(nvalue); + } + + // only need to call unregisterPropLink if the value node is not stored in a relational db + // also, getParent is heuristical/implicit for relational nodes, so we don't do deepRemoveNode + // based on that for relational nodes. + if ((nvmap == null) || !nvmap.isRelational()) { + if (!nvalue.isAnonymous() && propname.equals(nvalue.getName()) && + (this.node == nvalue.getParent())) { + // this is the "main" property of a named node, so handle this as a cascading delete. + nvalue.deepRemoveNode(); + } + } } + /** + * + * + * @return ... + */ + public String getStringValue() { + if (value == null) { + return null; + } - public String getStringValue () { - if (value == null) - return null; - switch (type) { - case STRING: - case BOOLEAN: - case INTEGER: - case FLOAT: - case JAVAOBJECT: - return value.toString (); - case DATE: - SimpleDateFormat format = new SimpleDateFormat ("dd.MM.yy hh:mm:ss"); - return format.format ((Date) value); - case NODE: - return ((NodeHandle) value).getID (); - } - return ""; + switch (type) { + case STRING: + case BOOLEAN: + case INTEGER: + case FLOAT: + case JAVAOBJECT: + return value.toString(); + + case DATE: + + SimpleDateFormat format = new SimpleDateFormat("dd.MM.yy hh:mm:ss"); + + return format.format((Date) value); + + case NODE: + return ((NodeHandle) value).getID(); + } + + return ""; } - public String toString () { - return getStringValue (); + /** + * + * + * @return ... + */ + public String toString() { + return getStringValue(); } - public long getIntegerValue () { - if (type == INTEGER) - return ((Long) value).longValue (); - if (type == FLOAT) - return ((Double) value).longValue (); - if (type == BOOLEAN) - return ((Boolean) value).booleanValue() ? 1 : 0; - try { - return Long.parseLong (getStringValue()); - } catch (Exception x) { - return 0; - } + /** + * + * + * @return ... + */ + public long getIntegerValue() { + if (type == INTEGER) { + return ((Long) value).longValue(); + } + + if (type == FLOAT) { + return ((Double) value).longValue(); + } + + if (type == BOOLEAN) { + return ((Boolean) value).booleanValue() ? 1 : 0; + } + + try { + return Long.parseLong(getStringValue()); + } catch (Exception x) { + return 0; + } } - public double getFloatValue () { - if (type == FLOAT) - return ((Double) value).doubleValue(); - if (type == INTEGER) - return ((Long) value).doubleValue (); - try { - return Double.parseDouble (getStringValue()); - } catch (Exception x) { - return 0.0; - } + /** + * + * + * @return ... + */ + public double getFloatValue() { + if (type == FLOAT) { + return ((Double) value).doubleValue(); + } + + if (type == INTEGER) { + return ((Long) value).doubleValue(); + } + + try { + return Double.parseDouble(getStringValue()); + } catch (Exception x) { + return 0.0; + } } + /** + * + * + * @return ... + */ + public Date getDateValue() { + if (type == DATE) { + return (Date) value; + } - public Date getDateValue () { - if (type == DATE) - return (Date) value; - return null; + return null; } - public Timestamp getTimestampValue () { - if (type == DATE && value != null) - return new Timestamp (((Date) value).getTime()); - return null; + /** + * + * + * @return ... + */ + public Timestamp getTimestampValue() { + if ((type == DATE) && (value != null)) { + return new Timestamp(((Date) value).getTime()); + } + + return null; } - public boolean getBooleanValue () { - if (type == BOOLEAN) - return ((Boolean) value).booleanValue(); - if (type == INTEGER) - return !(0 == getIntegerValue()); - return false; + /** + * + * + * @return ... + */ + public boolean getBooleanValue() { + if (type == BOOLEAN) { + return ((Boolean) value).booleanValue(); + } + + if (type == INTEGER) { + return !(0 == getIntegerValue()); + } + + return false; } - public INode getNodeValue () { - if (type == NODE && value != null) { - NodeHandle nhandle = (NodeHandle) value; - return nhandle.getNode (node.nmgr); - } - return null; + /** + * + * + * @return ... + */ + public INode getNodeValue() { + if ((type == NODE) && (value != null)) { + NodeHandle nhandle = (NodeHandle) value; + + return nhandle.getNode(node.nmgr); + } + + return null; } - public Object getJavaObjectValue () { - if (type == JAVAOBJECT) - return value; - return null; - } + /** + * + * + * @return ... + */ + public Object getJavaObjectValue() { + if (type == JAVAOBJECT) { + return value; + } + return null; + } } - - diff --git a/src/helma/objectmodel/db/Relation.java b/src/helma/objectmodel/db/Relation.java index b744e588..1a93f497 100644 --- a/src/helma/objectmodel/db/Relation.java +++ b/src/helma/objectmodel/db/Relation.java @@ -1,13 +1,26 @@ -// Relation.java -// Copyright (c) Hannes Wallnöfer 1997-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.objectmodel.db; -import helma.objectmodel.*; import helma.framework.core.Application; +import helma.objectmodel.*; +import java.sql.SQLException; import java.util.Properties; import java.util.Vector; -import java.sql.SQLException; /** * This describes how a property of a persistent Object is stored in a @@ -15,23 +28,25 @@ import java.sql.SQLException; * or a reference to one or more other objects. */ public final class Relation { - // these constants define different type of property-to-db-mappings - // there is an error in the description of this relation public final static int INVALID = -1; - // a mapping of a non-object, scalar type + + // a mapping of a non-object, scalar type public final static int PRIMITIVE = 0; - // a 1-to-1 relation, i.e. a field in the table is a foreign key to another object + + // a 1-to-1 relation, i.e. a field in the table is a foreign key to another object public final static int REFERENCE = 1; + // a 1-to-many relation, a field in another table points to objects of this type public final static int COLLECTION = 2; + // direct mapping is a very powerful feature: objects of some types can be directly accessed // by one of their properties/db fields. // public final static int DIRECT = 3; - // the DbMapping of the type we come from DbMapping ownType; + // the DbMapping of the prototype we link to, unless this is a "primitive" (non-object) relation DbMapping otherType; @@ -40,20 +55,15 @@ public final class Relation { // if this relation defines a virtual node, we need to provide a DbMapping for these virtual nodes DbMapping virtualMapping; - String propName; String columnName; - int reftype; - Constraint[] constraints; - boolean virtual; boolean readonly; boolean aggressiveLoading; boolean aggressiveCaching; boolean isPrivate; - String accessName; // db column used to access objects through this relation String order; String groupbyOrder; @@ -63,187 +73,222 @@ public final class Relation { String filter; int maxSize = 0; - /** * This constructor makes a copy of an existing relation. Not all fields are copied, just those * which are needed in groupby- and virtual nodes defined by this relation. */ - public Relation (Relation rel) { - this.ownType = rel.ownType; - this.otherType = rel.otherType; - this.propName = rel.propName; - this.columnName = rel.columnName; - this.reftype = rel.reftype; - this.constraints = rel.constraints; - this.accessName = rel.accessName; - this.maxSize = rel.maxSize; + public Relation(Relation rel) { + this.ownType = rel.ownType; + this.otherType = rel.otherType; + this.propName = rel.propName; + this.columnName = rel.columnName; + this.reftype = rel.reftype; + this.constraints = rel.constraints; + this.accessName = rel.accessName; + this.maxSize = rel.maxSize; } /** * Reads a relation entry from a line in a properties file. */ - public Relation (String desc, String propName, DbMapping ownType, Properties props) { - this.ownType = ownType; - this.propName = propName; - otherType = null; + public Relation(String desc, String propName, DbMapping ownType, Properties props) { + this.ownType = ownType; + this.propName = propName; + otherType = null; } - //////////////////////////////////////////////////////////////////////////////////////////// // parse methods for new file format //////////////////////////////////////////////////////////////////////////////////////////// + public void update(String desc, Properties props) { + Application app = ownType.getApplication(); - public void update (String desc, Properties props) { - Application app = ownType.getApplication (); - if (desc == null || "".equals (desc.trim ())) { - if (propName != null) { - reftype = PRIMITIVE; - columnName = propName; - } else { - reftype = INVALID; - columnName = propName; - } - } else { - desc = desc.trim (); - int open = desc.indexOf ("("); - int close = desc.indexOf (")"); - if (open > -1 && close > open) { - String ref = desc.substring (0, open).trim (); - String proto = desc.substring (open+1, close).trim (); - if ("collection".equalsIgnoreCase (ref)) { - virtual = !"_children".equalsIgnoreCase (propName); - reftype = COLLECTION; - } else if ("mountpoint".equalsIgnoreCase (ref)) { - virtual = true; - reftype = COLLECTION; - prototype = proto; - } else if ("object".equalsIgnoreCase (ref)) { - virtual = false; - reftype = REFERENCE; - } else { - throw new RuntimeException ("Invalid property Mapping: "+desc); - } - otherType = app.getDbMapping (proto); - if (otherType == null) - throw new RuntimeException ("DbMapping for "+proto+" not found from "+ownType.typename); - } else { - virtual = false; - columnName = desc; - reftype = PRIMITIVE; - } - } - String rdonly = props.getProperty (propName+".readonly"); - if (rdonly != null && "true".equalsIgnoreCase (rdonly)) { - readonly = true; - } else { - readonly = false; - } - isPrivate = "true".equalsIgnoreCase (props.getProperty (propName+".private")); + if ((desc == null) || "".equals(desc.trim())) { + if (propName != null) { + reftype = PRIMITIVE; + columnName = propName; + } else { + reftype = INVALID; + columnName = propName; + } + } else { + desc = desc.trim(); - // the following options only apply to object and collection relations - if (reftype != PRIMITIVE && reftype != INVALID) { + int open = desc.indexOf("("); + int close = desc.indexOf(")"); - Vector newConstraints = new Vector (); - parseOptions (newConstraints, props); + if ((open > -1) && (close > open)) { + String ref = desc.substring(0, open).trim(); + String proto = desc.substring(open + 1, close).trim(); - constraints = new Constraint[newConstraints.size()]; - newConstraints.copyInto (constraints); - // if DbMapping for virtual nodes has already been created, - // update its subnode relation. - // FIXME: needs to be synchronized? - if (virtualMapping != null) { - virtualMapping.lastTypeChange = ownType.lastTypeChange; - virtualMapping.subRelation = getVirtualSubnodeRelation (); - virtualMapping.propRelation = getVirtualPropertyRelation (); - } - } + if ("collection".equalsIgnoreCase(ref)) { + virtual = !"_children".equalsIgnoreCase(propName); + reftype = COLLECTION; + } else if ("mountpoint".equalsIgnoreCase(ref)) { + virtual = true; + reftype = COLLECTION; + prototype = proto; + } else if ("object".equalsIgnoreCase(ref)) { + virtual = false; + reftype = REFERENCE; + } else { + throw new RuntimeException("Invalid property Mapping: " + desc); + } + + otherType = app.getDbMapping(proto); + + if (otherType == null) { + throw new RuntimeException("DbMapping for " + proto + + " not found from " + ownType.typename); + } + } else { + virtual = false; + columnName = desc; + reftype = PRIMITIVE; + } + } + + String rdonly = props.getProperty(propName + ".readonly"); + + if ((rdonly != null) && "true".equalsIgnoreCase(rdonly)) { + readonly = true; + } else { + readonly = false; + } + + isPrivate = "true".equalsIgnoreCase(props.getProperty(propName + ".private")); + + // the following options only apply to object and collection relations + if ((reftype != PRIMITIVE) && (reftype != INVALID)) { + Vector newConstraints = new Vector(); + + parseOptions(newConstraints, props); + + constraints = new Constraint[newConstraints.size()]; + newConstraints.copyInto(constraints); + + // if DbMapping for virtual nodes has already been created, + // update its subnode relation. + // FIXME: needs to be synchronized? + if (virtualMapping != null) { + virtualMapping.lastTypeChange = ownType.lastTypeChange; + virtualMapping.subRelation = getVirtualSubnodeRelation(); + virtualMapping.propRelation = getVirtualPropertyRelation(); + } + } } + protected void parseOptions(Vector cnst, Properties props) { + String loading = props.getProperty(propName + ".loadmode"); - protected void parseOptions (Vector cnst, Properties props) { - String loading = props.getProperty (propName+".loadmode"); - aggressiveLoading = loading != null && "aggressive".equalsIgnoreCase (loading.trim()); - String caching = props.getProperty (propName+".cachemode"); - aggressiveCaching = caching != null && "aggressive".equalsIgnoreCase (caching.trim()); - // get order property - order = props.getProperty (propName+".order"); - if (order != null && order.trim().length() == 0) - order = null; - // get additional filter property - filter = props.getProperty (propName+".filter"); - if (filter != null && filter.trim().length() == 0) - filter = null; - // get max size of collection - String max = props.getProperty (propName+".maxSize"); - if (max != null) try { - maxSize = Integer.parseInt (max); - } catch (NumberFormatException nfe) { - maxSize = 0; - } else { - maxSize = 0; - } - // get group by property - groupby = props.getProperty (propName+".group"); - if (groupby != null && groupby.trim().length() == 0) - groupby = null; - if (groupby != null) { - groupbyOrder = props.getProperty (propName+".group.order"); - if (groupbyOrder != null && groupbyOrder.trim().length() == 0) - groupbyOrder = null; - groupbyPrototype = props.getProperty (propName+".group.prototype"); - if (groupbyPrototype != null && groupbyPrototype.trim().length() == 0) - groupbyPrototype = null; - // aggressive loading and caching is not supported for groupby-nodes - aggressiveLoading = aggressiveCaching = false; - } - // check if subnode condition should be applied for property relations - accessName = props.getProperty (propName+".accessname"); - // parse contstraints - String local = props.getProperty (propName+".local"); - String foreign = props.getProperty (propName+".foreign"); - if (local != null && foreign != null) { - cnst.addElement (new Constraint (local, otherType.getTableName (), foreign, false)); - columnName = local; - } + aggressiveLoading = (loading != null) && + "aggressive".equalsIgnoreCase(loading.trim()); + + String caching = props.getProperty(propName + ".cachemode"); + + aggressiveCaching = (caching != null) && + "aggressive".equalsIgnoreCase(caching.trim()); + + // get order property + order = props.getProperty(propName + ".order"); + + if ((order != null) && (order.trim().length() == 0)) { + order = null; + } + + // get additional filter property + filter = props.getProperty(propName + ".filter"); + + if ((filter != null) && (filter.trim().length() == 0)) { + filter = null; + } + + // get max size of collection + String max = props.getProperty(propName + ".maxSize"); + + if (max != null) { + try { + maxSize = Integer.parseInt(max); + } catch (NumberFormatException nfe) { + maxSize = 0; + } + } else { + maxSize = 0; + } + + // get group by property + groupby = props.getProperty(propName + ".group"); + + if ((groupby != null) && (groupby.trim().length() == 0)) { + groupby = null; + } + + if (groupby != null) { + groupbyOrder = props.getProperty(propName + ".group.order"); + + if ((groupbyOrder != null) && (groupbyOrder.trim().length() == 0)) { + groupbyOrder = null; + } + + groupbyPrototype = props.getProperty(propName + ".group.prototype"); + + if ((groupbyPrototype != null) && (groupbyPrototype.trim().length() == 0)) { + groupbyPrototype = null; + } + + // aggressive loading and caching is not supported for groupby-nodes + aggressiveLoading = aggressiveCaching = false; + } + + // check if subnode condition should be applied for property relations + accessName = props.getProperty(propName + ".accessname"); + + // parse contstraints + String local = props.getProperty(propName + ".local"); + String foreign = props.getProperty(propName + ".foreign"); + + if ((local != null) && (foreign != null)) { + cnst.addElement(new Constraint(local, otherType.getTableName(), foreign, false)); + columnName = local; + } } - /////////////////////////////////////////////////////////////////////////////////////////// /** * Does this relation describe a virtual (collection) node? */ - public boolean isVirtual () { - return virtual; + public boolean isVirtual() { + return virtual; } /** * Tell if this relation represents a primitive (scalar) value mapping. */ - public boolean isPrimitive () { - return reftype == PRIMITIVE; + public boolean isPrimitive() { + return reftype == PRIMITIVE; } /** * Returns true if this Relation describes an object reference property */ - public boolean isReference () { - return reftype == REFERENCE; + public boolean isReference() { + return reftype == REFERENCE; } /** * Returns true if this Relation describes a collection object property */ - public boolean isCollection () { - return reftype == COLLECTION; + public boolean isCollection() { + return reftype == COLLECTION; } /** * Tell wether the property described by this relation is to be handled as private, i.e. * a change on it should not result in any changed object/collection relations. */ - public boolean isPrivate () { - return isPrivate; + public boolean isPrivate() { + return isPrivate; } /** @@ -252,8 +297,8 @@ public final class Relation { * node. Virtual nodes are objects which are only generated on demand * and never stored to a persistent storage. */ - public boolean createPropertyOnDemand () { - return virtual || accessName != null || groupby != null; + public boolean createPropertyOnDemand() { + return virtual || (accessName != null) || (groupby != null); } /** @@ -264,355 +309,470 @@ public final class Relation { * object stored in the db, since a virtual collection would lose its * its content after restarts. */ - public boolean needsPersistence () { - if (!virtual) - return false; - if (prototype == null) - return !otherType.isRelational (); - DbMapping sub = otherType.getSubnodeMapping (); - return sub != null && !sub.isRelational (); + public boolean needsPersistence() { + if (!virtual) { + return false; + } + + if (prototype == null) { + return !otherType.isRelational(); + } + + DbMapping sub = otherType.getSubnodeMapping(); + + return (sub != null) && !sub.isRelational(); } /** * Return the prototype to be used for object reached by this relation */ - public String getPrototype () { - return prototype; + public String getPrototype() { + return prototype; } /** * Return the name of the local property this relation is defined for */ - public String getPropName () { - return propName; + public String getPropName() { + return propName; } - public void setColumnType (int ct) { - columnType = ct; + /** + * + * + * @param ct ... + */ + public void setColumnType(int ct) { + columnType = ct; } - public int getColumnType () { - return columnType; + /** + * + * + * @return ... + */ + public int getColumnType() { + return columnType; } - /** * Add a constraint to the current list of constraints */ - protected void addConstraint (Constraint c) { - if (constraints == null) { - constraints = new Constraint[1]; - constraints[0] = c; - } else { - Constraint[] nc = new Constraint[constraints.length+1]; - System.arraycopy (constraints, 0, nc, 0, constraints.length); - nc[nc.length-1] = c; - constraints = nc; - } + protected void addConstraint(Constraint c) { + if (constraints == null) { + constraints = new Constraint[1]; + constraints[0] = c; + } else { + Constraint[] nc = new Constraint[constraints.length + 1]; + + System.arraycopy(constraints, 0, nc, 0, constraints.length); + nc[nc.length - 1] = c; + constraints = nc; + } } + /** + * + * + * @return ... + */ + public boolean usesPrimaryKey() { + if (otherType != null) { + if (reftype == REFERENCE) { + return (constraints.length == 1) && constraints[0].foreignKeyIsPrimary(); + } - public boolean usesPrimaryKey () { - if (otherType != null) { - if (reftype == REFERENCE) - return constraints.length == 1 && constraints[0].foreignKeyIsPrimary (); - if (reftype == COLLECTION) - return accessName == null || accessName.equalsIgnoreCase (otherType.getIDField ()); - } - return false; + if (reftype == COLLECTION) { + return (accessName == null) || + accessName.equalsIgnoreCase(otherType.getIDField()); + } + } + + return false; } - public boolean hasAccessName () { - return accessName != null; + /** + * + * + * @return ... + */ + public boolean hasAccessName() { + return accessName != null; } - public String getAccessName () { - return accessName; + /** + * + * + * @return ... + */ + public String getAccessName() { + return accessName; } - public Relation getSubnodeRelation () { - // return subnoderelation; - return null; + /** + * + * + * @return ... + */ + public Relation getSubnodeRelation() { + // return subnoderelation; + return null; } - /** * Return the local field name for updates. */ - public String getDbField () { - return columnName; + public String getDbField() { + return columnName; } - /** * get a DbMapping to use for virtual aka collection nodes. */ - public DbMapping getVirtualMapping () { - // return null unless this relation describes a virtual/collection node. - if (!virtual) - return null; - // if the collection node is prototyped, return the app's DbMapping - // for that prototype - if (prototype != null) { - return otherType; - } - // create a synthetic DbMapping that describes how to fetch the - // collection's child objects. - if (virtualMapping == null) { - virtualMapping = new DbMapping (ownType.app); - virtualMapping.subRelation = getVirtualSubnodeRelation (); - virtualMapping.propRelation = getVirtualPropertyRelation (); - } - return virtualMapping; - } + public DbMapping getVirtualMapping() { + // return null unless this relation describes a virtual/collection node. + if (!virtual) { + return null; + } + // if the collection node is prototyped, return the app's DbMapping + // for that prototype + if (prototype != null) { + return otherType; + } + + // create a synthetic DbMapping that describes how to fetch the + // collection's child objects. + if (virtualMapping == null) { + virtualMapping = new DbMapping(ownType.app); + virtualMapping.subRelation = getVirtualSubnodeRelation(); + virtualMapping.propRelation = getVirtualPropertyRelation(); + } + + return virtualMapping; + } /** * Return a Relation that defines the subnodes of a virtual node. */ - Relation getVirtualSubnodeRelation () { - if (!virtual) - throw new RuntimeException ("getVirtualSubnodeRelation called on non-virtual relation"); - Relation vr = new Relation (this); - vr.groupby = groupby; - vr.groupbyOrder = groupbyOrder; - vr.groupbyPrototype = groupbyPrototype; - vr.order = order; - vr.filter = filter; - vr.maxSize = maxSize; - vr.constraints = constraints; - vr.aggressiveLoading = aggressiveLoading; - vr.aggressiveCaching = aggressiveCaching; - return vr; + Relation getVirtualSubnodeRelation() { + if (!virtual) { + throw new RuntimeException("getVirtualSubnodeRelation called on non-virtual relation"); + } + + Relation vr = new Relation(this); + + vr.groupby = groupby; + vr.groupbyOrder = groupbyOrder; + vr.groupbyPrototype = groupbyPrototype; + vr.order = order; + vr.filter = filter; + vr.maxSize = maxSize; + vr.constraints = constraints; + vr.aggressiveLoading = aggressiveLoading; + vr.aggressiveCaching = aggressiveCaching; + + return vr; } /** * Return a Relation that defines the properties of a virtual node. */ - Relation getVirtualPropertyRelation () { - if (!virtual) - throw new RuntimeException ("getVirtualPropertyRelation called on non-virtual relation"); - Relation vr = new Relation (this); - vr.groupby = groupby; - vr.groupbyOrder = groupbyOrder; - vr.groupbyPrototype = groupbyPrototype; - vr.order = order; - vr.filter = filter; - vr.maxSize = maxSize; - vr.constraints = constraints; - return vr; + Relation getVirtualPropertyRelation() { + if (!virtual) { + throw new RuntimeException("getVirtualPropertyRelation called on non-virtual relation"); + } + + Relation vr = new Relation(this); + + vr.groupby = groupby; + vr.groupbyOrder = groupbyOrder; + vr.groupbyPrototype = groupbyPrototype; + vr.order = order; + vr.filter = filter; + vr.maxSize = maxSize; + vr.constraints = constraints; + + return vr; } /** * Return a Relation that defines the subnodes of a group-by node. */ - Relation getGroupbySubnodeRelation () { - if (groupby == null) - throw new RuntimeException ("getGroupbySubnodeRelation called on non-group-by relation"); - Relation vr = new Relation (this); - vr.order = order; - vr.prototype = groupbyPrototype; - vr.filter = filter; - vr.constraints = constraints; - vr.addConstraint (new Constraint (null, null, groupby, true)); - vr.aggressiveLoading = aggressiveLoading; - vr.aggressiveCaching = aggressiveCaching; - return vr; + Relation getGroupbySubnodeRelation() { + if (groupby == null) { + throw new RuntimeException("getGroupbySubnodeRelation called on non-group-by relation"); + } + + Relation vr = new Relation(this); + + vr.order = order; + vr.prototype = groupbyPrototype; + vr.filter = filter; + vr.constraints = constraints; + vr.addConstraint(new Constraint(null, null, groupby, true)); + vr.aggressiveLoading = aggressiveLoading; + vr.aggressiveCaching = aggressiveCaching; + + return vr; } /** * Return a Relation that defines the properties of a group-by node. */ - Relation getGroupbyPropertyRelation () { - if (groupby == null) - throw new RuntimeException ("getGroupbyPropertyRelation called on non-group-by relation"); - Relation vr = new Relation (this); - vr.order = order; - vr.prototype = groupbyPrototype; - vr.filter = filter; - vr.constraints = constraints; - vr.addConstraint (new Constraint (null, null, groupby, true)); - return vr; - } + Relation getGroupbyPropertyRelation() { + if (groupby == null) { + throw new RuntimeException("getGroupbyPropertyRelation called on non-group-by relation"); + } + Relation vr = new Relation(this); + + vr.order = order; + vr.prototype = groupbyPrototype; + vr.filter = filter; + vr.constraints = constraints; + vr.addConstraint(new Constraint(null, null, groupby, true)); + + return vr; + } /** * Build the second half of an SQL select statement according to this relation * and a local object. */ - public String buildQuery (INode home, INode nonvirtual, String kstr, String pre, boolean useOrder) throws SQLException { - StringBuffer q = new StringBuffer (); - String prefix = pre; - if (kstr != null) { - q.append (prefix); - String accessColumn = accessName == null ? otherType.getIDField () : accessName; - q.append (accessColumn); - q.append (" = "); - // check if column is string type and value needs to be quoted - if (otherType.needsQuotes (accessColumn)) { - q.append ("'"); - q.append (escape (kstr)); - q.append ("'"); - } else - q.append (escape (kstr)); - prefix = " AND "; - } - for (int i=0; i<constraints.length; i++) { - q.append (prefix); - constraints[i].addToQuery (q, home, nonvirtual); - prefix = " AND "; - } + public String buildQuery(INode home, INode nonvirtual, String kstr, String pre, + boolean useOrder) throws SQLException { + StringBuffer q = new StringBuffer(); + String prefix = pre; - if (filter != null) { - q.append (prefix); - q.append (filter); - } - if (groupby != null) { - q.append (" GROUP BY "+groupby); - if (useOrder && groupbyOrder != null) - q.append (" ORDER BY "+groupbyOrder); - } else if (useOrder && order != null) - q.append (" ORDER BY "+order); - return q.toString (); + if (kstr != null) { + q.append(prefix); + + String accessColumn = (accessName == null) ? otherType.getIDField() : accessName; + + q.append(accessColumn); + q.append(" = "); + + // check if column is string type and value needs to be quoted + if (otherType.needsQuotes(accessColumn)) { + q.append("'"); + q.append(escape(kstr)); + q.append("'"); + } else { + q.append(escape(kstr)); + } + + prefix = " AND "; + } + + for (int i = 0; i < constraints.length; i++) { + q.append(prefix); + constraints[i].addToQuery(q, home, nonvirtual); + prefix = " AND "; + } + + if (filter != null) { + q.append(prefix); + q.append(filter); + } + + if (groupby != null) { + q.append(" GROUP BY " + groupby); + + if (useOrder && (groupbyOrder != null)) { + q.append(" ORDER BY " + groupbyOrder); + } + } else if (useOrder && (order != null)) { + q.append(" ORDER BY " + order); + } + + return q.toString(); } - public String renderConstraints (INode home, INode nonvirtual) throws SQLException { - StringBuffer q = new StringBuffer (); - String suffix = " AND "; - for (int i=0; i<constraints.length; i++) { - constraints[i].addToQuery (q, home, nonvirtual); - q.append (suffix); - } - if (filter != null) { - q.append (filter); - q.append (suffix); - } - return q.toString (); - } + /** + * + * + * @param home ... + * @param nonvirtual ... + * + * @return ... + * + * @throws SQLException ... + */ + public String renderConstraints(INode home, INode nonvirtual) + throws SQLException { + StringBuffer q = new StringBuffer(); + String suffix = " AND "; + for (int i = 0; i < constraints.length; i++) { + constraints[i].addToQuery(q, home, nonvirtual); + q.append(suffix); + } + + if (filter != null) { + q.append(filter); + q.append(suffix); + } + + return q.toString(); + } /** * Get the order section to use for this relation */ - public String getOrder () { - if (groupby != null) - return groupbyOrder; - else - return order; + public String getOrder() { + if (groupby != null) { + return groupbyOrder; + } else { + return order; + } } /** * Tell wether the property described by this relation is to be handled * as readonly/write protected. */ - public boolean isReadonly () { - return readonly; + public boolean isReadonly() { + return readonly; } - /** * Check if the child node fullfills the constraints defined by this relation. */ - public boolean checkConstraints (Node parent, Node child) { - // problem: if a filter property is defined for this relation, - // i.e. a piece of static SQL-where clause, we'd have to evaluate it - // in order to check the constraints. Because of this, if a filter - // is defined, we return false as soon as the modified-time is greater - // than the create-time of the child, i.e. if the child node has been - // modified since it was first fetched from the db. - if (filter != null && child.lastModified() > child.created()) - return false; - for (int i=0; i<constraints.length; i++) { - String propname = constraints[i].foreignProperty (); - if (propname != null) { - INode home = constraints[i].isGroupby ? parent : parent.getNonVirtualParent (); - String localName = constraints[i].localName; - String value = null; - if (localName == null || localName.equalsIgnoreCase (ownType.getIDField ())) - value = home.getID (); - else if (ownType.isRelational ()) - value = home.getString (ownType.columnNameToProperty (localName)); - else - value = home.getString (localName); - if (value != null && !value.equals (child.getString (propname))) { - return false; - } - } - } - return true; - } + public boolean checkConstraints(Node parent, Node child) { + // problem: if a filter property is defined for this relation, + // i.e. a piece of static SQL-where clause, we'd have to evaluate it + // in order to check the constraints. Because of this, if a filter + // is defined, we return false as soon as the modified-time is greater + // than the create-time of the child, i.e. if the child node has been + // modified since it was first fetched from the db. + if ((filter != null) && (child.lastModified() > child.created())) { + return false; + } + for (int i = 0; i < constraints.length; i++) { + String propname = constraints[i].foreignProperty(); + + if (propname != null) { + INode home = constraints[i].isGroupby ? parent + : parent.getNonVirtualParent(); + String localName = constraints[i].localName; + String value = null; + + if ((localName == null) || + localName.equalsIgnoreCase(ownType.getIDField())) { + value = home.getID(); + } else if (ownType.isRelational()) { + value = home.getString(ownType.columnNameToProperty(localName)); + } else { + value = home.getString(localName); + } + + if ((value != null) && !value.equals(child.getString(propname))) { + return false; + } + } + } + + return true; + } /** * Make sure that the child node fullfills the constraints defined by this relation by setting the * appropriate properties */ - public void setConstraints (Node parent, Node child) { - INode home = parent.getNonVirtualParent (); - for (int i=0; i<constraints.length; i++) { - // don't set groupby constraints since we don't know if the - // parent node is the base node or a group node - if (constraints[i].isGroupby) - continue; - Relation crel = otherType.columnNameToRelation (constraints[i].foreignName); - if (crel != null) { - // INode home = constraints[i].isGroupby ? parent : nonVirtual; - String localName = constraints[i].localName; - if (localName == null || localName.equalsIgnoreCase (ownType.getIDField ())) { - // only set node if property in child object is defined as reference. - if (crel.reftype == REFERENCE) { - INode currentValue = child.getNode (crel.propName); - // we set the backwards reference iff the reference is currently unset, if - // is set to a transient object, or if the new target is not transient. This - // prevents us from overwriting a persistent refererence with a transient one, - // which would most probably not be what we want. - if (currentValue == null || - (currentValue != home && - (currentValue.getState() == Node.TRANSIENT || - home.getState() != Node.TRANSIENT))) - child.setNode (crel.propName, home); - } else if (crel.reftype == PRIMITIVE) { - child.setString (crel.propName, home.getID ()); - } - } else if (crel.reftype == PRIMITIVE) { - String value = null; - if (ownType.isRelational ()) - value = home.getString (ownType.columnNameToProperty (localName)); - else - value = home.getString (localName); - if (value != null) { - child.setString (crel.propName, value); - } - } - } - } - } + public void setConstraints(Node parent, Node child) { + INode home = parent.getNonVirtualParent(); + for (int i = 0; i < constraints.length; i++) { + // don't set groupby constraints since we don't know if the + // parent node is the base node or a group node + if (constraints[i].isGroupby) { + continue; + } + + Relation crel = otherType.columnNameToRelation(constraints[i].foreignName); + + if (crel != null) { + // INode home = constraints[i].isGroupby ? parent : nonVirtual; + String localName = constraints[i].localName; + + if ((localName == null) || + localName.equalsIgnoreCase(ownType.getIDField())) { + // only set node if property in child object is defined as reference. + if (crel.reftype == REFERENCE) { + INode currentValue = child.getNode(crel.propName); + + // we set the backwards reference iff the reference is currently unset, if + // is set to a transient object, or if the new target is not transient. This + // prevents us from overwriting a persistent refererence with a transient one, + // which would most probably not be what we want. + if ((currentValue == null) || + ((currentValue != home) && + ((currentValue.getState() == Node.TRANSIENT) || + (home.getState() != Node.TRANSIENT)))) { + child.setNode(crel.propName, home); + } + } else if (crel.reftype == PRIMITIVE) { + child.setString(crel.propName, home.getID()); + } + } else if (crel.reftype == PRIMITIVE) { + String value = null; + + if (ownType.isRelational()) { + value = home.getString(ownType.columnNameToProperty(localName)); + } else { + value = home.getString(localName); + } + + if (value != null) { + child.setString(crel.propName, value); + } + } + } + } + } // a utility method to escape single quotes - String escape (String str) { - if (str == null) - return null; - if (str.indexOf ("'") < 0) - return str; - int l = str.length(); - StringBuffer sbuf = new StringBuffer (l + 10); - for (int i=0; i<l; i++) { - char c = str.charAt (i); - if (c == '\'') - sbuf.append ('\''); - sbuf.append (c); - } - return sbuf.toString (); + String escape(String str) { + if (str == null) { + return null; + } + + if (str.indexOf("'") < 0) { + return str; + } + + int l = str.length(); + StringBuffer sbuf = new StringBuffer(l + 10); + + for (int i = 0; i < l; i++) { + char c = str.charAt(i); + + if (c == '\'') { + sbuf.append('\''); + } + + sbuf.append(c); + } + + return sbuf.toString(); } - public String toString () { - String c = ""; - if (constraints != null) { - for (int i=0; i<constraints.length; i++) - c += constraints[i].toString (); - } - return "Relation["+ownType+"."+propName+">"+otherType+"]" + c; + /** + * + * + * @return ... + */ + public String toString() { + String c = ""; + + if (constraints != null) { + for (int i = 0; i < constraints.length; i++) + c += constraints[i].toString(); + } + + return "Relation[" + ownType + "." + propName + ">" + otherType + "]" + c; } /** @@ -620,55 +780,59 @@ public final class Relation { * establish a relation between database mapped objects. */ class Constraint { + String localName; + String tableName; + String foreignName; + boolean isGroupby; - String localName; - String tableName; - String foreignName; - boolean isGroupby; + Constraint(String local, String table, String foreign, boolean groupby) { + localName = local; + tableName = table; + foreignName = foreign; + isGroupby = groupby; + } - Constraint (String local, String table, String foreign, boolean groupby) { - localName = local; - tableName = table; - foreignName = foreign; - isGroupby = groupby; - } + public void addToQuery(StringBuffer q, INode home, INode nonvirtual) + throws SQLException { + String local = null; + INode ref = isGroupby ? home : nonvirtual; - public void addToQuery (StringBuffer q, INode home, INode nonvirtual) throws SQLException { - String local = null; - INode ref = isGroupby ? home : nonvirtual; - if (localName == null || localName.equalsIgnoreCase (ref.getDbMapping ().getIDField ())) - local = ref.getID (); - else { - String homeprop = ownType.columnNameToProperty (localName); - local = ref.getString (homeprop); - } - q.append (foreignName); - q.append (" = "); - if (otherType.needsQuotes (foreignName)) { - q.append ("'"); - q.append (escape (local)); - q.append ("'"); - } else - q.append (escape (local)); - } + if ((localName == null) || + localName.equalsIgnoreCase(ref.getDbMapping().getIDField())) { + local = ref.getID(); + } else { + String homeprop = ownType.columnNameToProperty(localName); - public boolean foreignKeyIsPrimary () { - return foreignName == null || foreignName.equalsIgnoreCase (otherType.getIDField ()); - } + local = ref.getString(homeprop); + } - public String foreignProperty () { - return otherType.columnNameToProperty (foreignName); - } + q.append(foreignName); + q.append(" = "); - public String localProperty () { - return ownType.columnNameToProperty (localName); - } + if (otherType.needsQuotes(foreignName)) { + q.append("'"); + q.append(escape(local)); + q.append("'"); + } else { + q.append(escape(local)); + } + } - public String toString () { - return ownType+"."+localName+"="+tableName+"."+foreignName; - } + public boolean foreignKeyIsPrimary() { + return (foreignName == null) || + foreignName.equalsIgnoreCase(otherType.getIDField()); + } + + public String foreignProperty() { + return otherType.columnNameToProperty(foreignName); + } + + public String localProperty() { + return ownType.columnNameToProperty(localName); + } + + public String toString() { + return ownType + "." + localName + "=" + tableName + "." + foreignName; + } } - } - - diff --git a/src/helma/objectmodel/db/Replicator.java b/src/helma/objectmodel/db/Replicator.java index d8d72cde..82669f3c 100644 --- a/src/helma/objectmodel/db/Replicator.java +++ b/src/helma/objectmodel/db/Replicator.java @@ -1,6 +1,19 @@ -// Replicator.java -// Copyright (c) Hannes Wallnöfer 2001 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel.db; import java.rmi.*; @@ -9,76 +22,113 @@ import java.util.*; /** * This class replicates the updates of transactions to other applications via RMI */ - public class Replicator implements Runnable { - Vector urls; - Vector add, delete, currentAdd, currentDelete; + Vector add; + Vector delete; + Vector currentAdd; + Vector currentDelete; Thread runner; NodeManager nmgr; - public Replicator (NodeManager nmgr) { - urls = new Vector (); - add = new Vector (); - delete = new Vector (); - this.nmgr = nmgr; - runner = new Thread (this); - runner.start (); + /** + * Creates a new Replicator object. + * + * @param nmgr ... + */ + public Replicator(NodeManager nmgr) { + urls = new Vector(); + add = new Vector(); + delete = new Vector(); + this.nmgr = nmgr; + runner = new Thread(this); + runner.start(); } - public void addUrl (String url) { - urls.addElement (url); - if (nmgr.logReplication) - nmgr.app.logEvent ("Adding replication listener: "+url); + /** + * + * + * @param url ... + */ + public void addUrl(String url) { + urls.addElement(url); + + if (nmgr.logReplication) { + nmgr.app.logEvent("Adding replication listener: " + url); + } } - public void run () { - while (Thread.currentThread () == runner) { - if (prepareReplication ()) { - for (int i=0; i<urls.size(); i++) { - try { - String url = (String) urls.elementAt (i); - IReplicationListener listener = (IReplicationListener) Naming.lookup (url); - listener.replicateCache (currentAdd, currentDelete); - if (nmgr.logReplication) - nmgr.app.logEvent ("Sent cache replication event: "+add.size()+" added, "+delete.size()+" deleted"); - } catch (Exception x) { - nmgr.app.logEvent ("Error sending cache replication event: "+x); - } - } - } + /** + * + */ + public void run() { + while (Thread.currentThread() == runner) { + if (prepareReplication()) { + for (int i = 0; i < urls.size(); i++) { + try { + String url = (String) urls.elementAt(i); + IReplicationListener listener = (IReplicationListener) Naming.lookup(url); - try { - if (runner != null) - runner.sleep (1000l); - } catch (InterruptedException ir) { - runner = null; - } - } + listener.replicateCache(currentAdd, currentDelete); + + if (nmgr.logReplication) { + nmgr.app.logEvent("Sent cache replication event: " + + add.size() + " added, " + delete.size() + + " deleted"); + } + } catch (Exception x) { + nmgr.app.logEvent("Error sending cache replication event: " + x); + } + } + } + + try { + if (runner != null) { + runner.sleep(1000L); + } + } catch (InterruptedException ir) { + runner = null; + } + } } - public synchronized void addNewNode (Node n) { - add.addElement (n); + /** + * + * + * @param n ... + */ + public synchronized void addNewNode(Node n) { + add.addElement(n); } - public synchronized void addModifiedNode (Node n) { - add.addElement (n); + /** + * + * + * @param n ... + */ + public synchronized void addModifiedNode(Node n) { + add.addElement(n); } - public synchronized void addDeletedNode (Node n) { - delete.addElement (n); + /** + * + * + * @param n ... + */ + public synchronized void addDeletedNode(Node n) { + delete.addElement(n); } - private synchronized boolean prepareReplication () { - if (add.size() == 0 && delete.size() == 0) - return false; - currentAdd = add; - currentDelete = delete; - add = new Vector (); - delete = new Vector (); - return true; - } + private synchronized boolean prepareReplication() { + if ((add.size() == 0) && (delete.size() == 0)) { + return false; + } + currentAdd = add; + currentDelete = delete; + add = new Vector(); + delete = new Vector(); + + return true; + } } - - diff --git a/src/helma/objectmodel/db/Server.java b/src/helma/objectmodel/db/Server.java index 66aca557..4b5111ae 100644 --- a/src/helma/objectmodel/db/Server.java +++ b/src/helma/objectmodel/db/Server.java @@ -1,6 +1,19 @@ -// Server.java -// Copyright (c) Hannes Wallnöfer 1998-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel.db; import java.io.IOException; @@ -9,16 +22,12 @@ import java.io.IOException; * Helma server main class. This moved to the helma.main package but a * simple redirector is kept here for backwards compatibility. */ - - public class Server { - +public class Server { /** * Just invoke the main method in the new Server class. */ - public static void main (String args[]) throws IOException { - System.err.println ("The Helma main class is now in helma.main.Server. Please update your start script accordingly."); - helma.main.Server.main (args); + public static void main(String[] args) throws IOException { + System.err.println("The Helma main class is now in helma.main.Server. Please update your start script accordingly."); + helma.main.Server.main(args); } - } - diff --git a/src/helma/objectmodel/db/SyntheticKey.java b/src/helma/objectmodel/db/SyntheticKey.java index 2735dcc8..a8c88c3f 100644 --- a/src/helma/objectmodel/db/SyntheticKey.java +++ b/src/helma/objectmodel/db/SyntheticKey.java @@ -1,6 +1,19 @@ -// SyntheticKey.java -// Copyright (c) Hannes Wallnöfer 1998-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel.db; import java.io.Serializable; @@ -9,59 +22,91 @@ import java.io.Serializable; * This is the internal key for an object that is not - or not directly - fetched from a db, * but derived from another object. This is useful for all kinds of object accessed via a * symbolic name from another object, like objects mounted via a property name column, - * virtual nodes and groupby nodes. + * virtual nodes and groupby nodes. */ public final class SyntheticKey implements Key, Serializable { - private final Key parentKey; private final String name; // lazily initialized hashcode private transient int hashcode = 0; - /** * make a key for a persistent Object, describing its datasource and id. */ - public SyntheticKey (Key key, String name) { - this.parentKey = key; - this.name = name; + public SyntheticKey(Key key, String name) { + this.parentKey = key; + this.name = name; } + /** + * + * + * @param what ... + * + * @return ... + */ + public boolean equals(Object what) { + if (what == this) { + return true; + } - public boolean equals (Object what) { - if (what == this) - return true; - if (!(what instanceof SyntheticKey)) - return false; - SyntheticKey k = (SyntheticKey) what; - return parentKey.equals (k.parentKey) && - (name == k.name || name.equals (k.name)); + if (!(what instanceof SyntheticKey)) { + return false; + } + + SyntheticKey k = (SyntheticKey) what; + + return parentKey.equals(k.parentKey) && + ((name == k.name) || name.equals(k.name)); } - public int hashCode () { - if (hashcode == 0) - hashcode = 17 + 37*name.hashCode () + 37*parentKey.hashCode (); - return hashcode; + /** + * + * + * @return ... + */ + public int hashCode() { + if (hashcode == 0) { + hashcode = 17 + (37 * name.hashCode()) + (37 * parentKey.hashCode()); + } + + return hashcode; } - - public Key getParentKey () { - return parentKey; + /** + * + * + * @return ... + */ + public Key getParentKey() { + return parentKey; } - public String getID () { - return name; + /** + * + * + * @return ... + */ + public String getID() { + return name; } - public String getStorageName () { - return null; + /** + * + * + * @return ... + */ + public String getStorageName() { + return null; } - public String toString () { - return parentKey+"/"+name; + /** + * + * + * @return ... + */ + public String toString() { + return parentKey + "/" + name; } - - } - diff --git a/src/helma/objectmodel/db/Transactor.java b/src/helma/objectmodel/db/Transactor.java index 3ff23205..8a9fa06a 100644 --- a/src/helma/objectmodel/db/Transactor.java +++ b/src/helma/objectmodel/db/Transactor.java @@ -1,251 +1,377 @@ -// Transactor.java -// Copyright (c) Hannes Wallnöfer 1998-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.objectmodel.db; -import java.io.*; -import java.util.*; -import java.sql.*; +import helma.framework.TimeoutException; import helma.objectmodel.*; import helma.util.Timer; -import helma.framework.TimeoutException; +import java.io.*; +import java.sql.*; +import java.util.*; /** - * A subclass of thread that keeps track of changed nodes and triggers + * A subclass of thread that keeps track of changed nodes and triggers * changes in the database when a transaction is commited. */ - public class Transactor extends Thread { - NodeManager nmgr; // List of nodes to be updated private HashMap nodes; private ArrayList nodesArray; + // List of visited clean nodes private HashMap cleannodes; + // Is a transaction in progress? private volatile boolean active; private volatile boolean killed; // Transaction for the embedded database protected ITransaction txn; + // Transactions for SQL data sources protected HashMap sqlCon; - public Timer timer; + // when did the current transaction start? private long tstart; + // a name to log the transaction. For HTTP transactions this is the rerquest path private String tname; - - public Transactor (Runnable runnable, ThreadGroup group, NodeManager nmgr) { - super (group, runnable, group.getName ()); - this.nmgr = nmgr; - nodes = new HashMap (); - nodesArray = new ArrayList (); - cleannodes = new HashMap (); - sqlCon = new HashMap (); - active = false; - killed = false; - timer = new Timer(); + /** + * Creates a new Transactor object. + * + * @param runnable ... + * @param group ... + * @param nmgr ... + */ + public Transactor(Runnable runnable, ThreadGroup group, NodeManager nmgr) { + super(group, runnable, group.getName()); + this.nmgr = nmgr; + nodes = new HashMap(); + nodesArray = new ArrayList(); + cleannodes = new HashMap(); + sqlCon = new HashMap(); + active = false; + killed = false; + timer = new Timer(); } - public void visitNode (Node node) { - if (node != null) { - Key key = node.getKey (); - if (!nodes.containsKey (key)) { - nodes.put (key, node); - nodesArray.add (node); - } - } + /** + * + * + * @param node ... + */ + public void visitNode(Node node) { + if (node != null) { + Key key = node.getKey(); + + if (!nodes.containsKey(key)) { + nodes.put(key, node); + nodesArray.add(node); + } + } } - public void dropNode (Node node) { - if (node != null) { - Key key = node.getKey (); - nodes.remove (key); - nodesArray.remove (node); - } + /** + * + * + * @param node ... + */ + public void dropNode(Node node) { + if (node != null) { + Key key = node.getKey(); + + nodes.remove(key); + nodesArray.remove(node); + } } - public void visitCleanNode (Node node) { - if (node != null) { - Key key = node.getKey (); - if (!cleannodes.containsKey (key)) { - cleannodes.put (key, node); - } - } + /** + * + * + * @param node ... + */ + public void visitCleanNode(Node node) { + if (node != null) { + Key key = node.getKey(); + + if (!cleannodes.containsKey(key)) { + cleannodes.put(key, node); + } + } } - public void visitCleanNode (Key key, Node node) { - if (node != null) { - if (!cleannodes.containsKey (key)) { - cleannodes.put (key, node); - } - } + /** + * + * + * @param key ... + * @param node ... + */ + public void visitCleanNode(Key key, Node node) { + if (node != null) { + if (!cleannodes.containsKey(key)) { + cleannodes.put(key, node); + } + } } - - public Node getVisitedNode (Object key) { - return key == null ? null : (Node) cleannodes.get (key); + /** + * + * + * @param key ... + * + * @return ... + */ + public Node getVisitedNode(Object key) { + return (key == null) ? null : (Node) cleannodes.get(key); } - public boolean isActive () { - return active; + /** + * + * + * @return ... + */ + public boolean isActive() { + return active; } - public void registerConnection (DbSource src, Connection con) { - sqlCon.put (src, con); + /** + * + * + * @param src ... + * @param con ... + */ + public void registerConnection(DbSource src, Connection con) { + sqlCon.put(src, con); } - public Connection getConnection (DbSource src) { - return (Connection) sqlCon.get (src); + /** + * + * + * @param src ... + * + * @return ... + */ + public Connection getConnection(DbSource src) { + return (Connection) sqlCon.get(src); } - public synchronized void begin (String tnm) throws Exception { + /** + * + * + * @param tnm ... + * + * @throws Exception ... + * @throws DatabaseException ... + */ + public synchronized void begin(String tnm) throws Exception { + if (killed) { + throw new DatabaseException("Transaction started on killed thread"); + } - if (killed) - throw new DatabaseException ("Transaction started on killed thread"); + if (active) { + abort(); + } - if (active) - abort (); - - nodes.clear (); - nodesArray.clear (); - cleannodes.clear (); - txn = nmgr.db.beginTransaction (); - active = true; - tstart = System.currentTimeMillis (); - tname = tnm; + nodes.clear(); + nodesArray.clear(); + cleannodes.clear(); + txn = nmgr.db.beginTransaction(); + active = true; + tstart = System.currentTimeMillis(); + tname = tnm; } - public synchronized void commit () throws Exception { + /** + * + * + * @throws Exception ... + */ + public synchronized void commit() throws Exception { + if (killed) { + abort(); - if (killed) { - abort (); - return; - } + return; + } - int ins = 0, upd = 0, dlt = 0; - int l = nodesArray.size (); + int ins = 0; + int upd = 0; + int dlt = 0; + int l = nodesArray.size(); - Replicator replicator = nmgr.getReplicator (); + Replicator replicator = nmgr.getReplicator(); - for (int i=0; i<l; i++) { - Node node = (Node) nodesArray.get (i); - // update nodes in db - int nstate = node.getState (); - if (nstate == Node.NEW) { - nmgr.registerNode (node); // register node with nodemanager cache - nmgr.insertNode (nmgr.db, txn, node); - node.setState (Node.CLEAN); - if (replicator != null) - replicator.addNewNode (node); - ins++; - nmgr.app.logEvent ("inserted: Node "+node.getPrototype ()+"/"+node.getID ()); - } else if (nstate == Node.MODIFIED) { - nmgr.updateNode (nmgr.db, txn, node); - node.setState (Node.CLEAN); - if (replicator != null) - replicator.addModifiedNode (node); - upd++; - nmgr.app.logEvent ("updated: Node "+node.getPrototype ()+"/"+node.getID ()); - } else if (nstate == Node.DELETED) { - // nmgr.app.logEvent ("deleted: "+node.getFullName ()+" ("+node.getName ()+")"); - nmgr.deleteNode (nmgr.db, txn, node); - nmgr.evictNode (node); - if (replicator != null) - replicator.addDeletedNode (node); - dlt++; - } else { - // nmgr.app.logEvent ("noop: "+node.getFullName ()); - } - node.clearWriteLock (); - } + for (int i = 0; i < l; i++) { + Node node = (Node) nodesArray.get(i); - nodes.clear (); - nodesArray.clear (); - cleannodes.clear (); + // update nodes in db + int nstate = node.getState(); - if (nmgr.idgen.dirty) { - nmgr.db.saveIDGenerator (txn, nmgr.idgen); - nmgr.idgen.dirty = false; - } + if (nstate == Node.NEW) { + nmgr.registerNode(node); // register node with nodemanager cache + nmgr.insertNode(nmgr.db, txn, node); + node.setState(Node.CLEAN); - if (active) { - active = false; - nmgr.db.commitTransaction (txn); - txn = null; - } + if (replicator != null) { + replicator.addNewNode(node); + } - nmgr.app.logAccess (tname+" "+l+" marked, "+ins+" inserted, "+upd+" updated, "+dlt+" deleted in "+(System.currentTimeMillis()-tstart)+" millis"); + ins++; + nmgr.app.logEvent("inserted: Node " + node.getPrototype() + "/" + + node.getID()); + } else if (nstate == Node.MODIFIED) { + nmgr.updateNode(nmgr.db, txn, node); + node.setState(Node.CLEAN); + + if (replicator != null) { + replicator.addModifiedNode(node); + } + + upd++; + nmgr.app.logEvent("updated: Node " + node.getPrototype() + "/" + + node.getID()); + } else if (nstate == Node.DELETED) { + // nmgr.app.logEvent ("deleted: "+node.getFullName ()+" ("+node.getName ()+")"); + nmgr.deleteNode(nmgr.db, txn, node); + nmgr.evictNode(node); + + if (replicator != null) { + replicator.addDeletedNode(node); + } + + dlt++; + } else { + // nmgr.app.logEvent ("noop: "+node.getFullName ()); + } + + node.clearWriteLock(); + } + + nodes.clear(); + nodesArray.clear(); + cleannodes.clear(); + + if (nmgr.idgen.dirty) { + nmgr.db.saveIDGenerator(txn, nmgr.idgen); + nmgr.idgen.dirty = false; + } + + if (active) { + active = false; + nmgr.db.commitTransaction(txn); + txn = null; + } + + nmgr.app.logAccess(tname + " " + l + " marked, " + ins + " inserted, " + upd + + " updated, " + dlt + " deleted in " + + (System.currentTimeMillis() - tstart) + " millis"); } - public synchronized void abort () throws Exception { + /** + * + * + * @throws Exception ... + */ + public synchronized void abort() throws Exception { + int l = nodesArray.size(); - int l = nodesArray.size (); - for (int i=0; i<l; i++ ) { - Node node = (Node) nodesArray.get (i); - // Declare node as invalid, so it won't be used by other threads that want to - // write on it and remove it from cache - nmgr.evictNode (node); - node.clearWriteLock (); - } - nodes.clear (); - nodesArray.clear (); - cleannodes.clear (); - // close any JDBC connections associated with this transactor thread - closeConnections (); + for (int i = 0; i < l; i++) { + Node node = (Node) nodesArray.get(i); - if (active) { - active = false; - if (txn != null) { - nmgr.db.abortTransaction (txn); - txn = null; - } - nmgr.app.logAccess (tname+" aborted after "+(System.currentTimeMillis()-tstart)+" millis"); - } + // Declare node as invalid, so it won't be used by other threads that want to + // write on it and remove it from cache + nmgr.evictNode(node); + node.clearWriteLock(); + } + + nodes.clear(); + nodesArray.clear(); + cleannodes.clear(); + + // close any JDBC connections associated with this transactor thread + closeConnections(); + + if (active) { + active = false; + + if (txn != null) { + nmgr.db.abortTransaction(txn); + txn = null; + } + + nmgr.app.logAccess(tname + " aborted after " + + (System.currentTimeMillis() - tstart) + " millis"); + } } - public synchronized void kill () { - killed = true; - // The thread is told to stop by setting the thread flag in the EcmaScript - // evaluator, so we can hope that it stops without doing anything else. - try { - join (500); - } catch (InterruptedException ir) {} + /** + * + */ + public synchronized void kill() { + killed = true; - // Interrupt the thread if it has not noticed the flag (e.g. because it is busy - // reading from a network socket). - if (isAlive()) { - interrupt (); - try { - join (1000); - } catch (InterruptedException ir) {} - } + // The thread is told to stop by setting the thread flag in the EcmaScript + // evaluator, so we can hope that it stops without doing anything else. + try { + join(500); + } catch (InterruptedException ir) { + } + + // Interrupt the thread if it has not noticed the flag (e.g. because it is busy + // reading from a network socket). + if (isAlive()) { + interrupt(); + + try { + join(1000); + } catch (InterruptedException ir) { + } + } } - public void closeConnections () { - // nmgr.app.logEvent("Cleaning up Transactor thread"); - if (sqlCon != null) { - for (Iterator i=sqlCon.values().iterator(); i.hasNext(); ) { - try { - Connection con = (Connection) i.next(); - con.close (); - nmgr.app.logEvent ("Closing DB connection: "+con); - } catch (Exception ignore) {} - } - sqlCon.clear (); - } + /** + * + */ + public void closeConnections() { + // nmgr.app.logEvent("Cleaning up Transactor thread"); + if (sqlCon != null) { + for (Iterator i = sqlCon.values().iterator(); i.hasNext();) { + try { + Connection con = (Connection) i.next(); + + con.close(); + nmgr.app.logEvent("Closing DB connection: " + con); + } catch (Exception ignore) { + } + } + + sqlCon.clear(); + } } - public String toString () { - return "Transactor["+tname+"]"; + /** + * + * + * @return ... + */ + public String toString() { + return "Transactor[" + tname + "]"; } - } - - - diff --git a/src/helma/objectmodel/db/WrappedNodeManager.java b/src/helma/objectmodel/db/WrappedNodeManager.java index 0499b821..4c57eb6a 100644 --- a/src/helma/objectmodel/db/WrappedNodeManager.java +++ b/src/helma/objectmodel/db/WrappedNodeManager.java @@ -1,156 +1,303 @@ -// WrappedNodeManager.java -// Copyright (c) Hannes Wallnöfer 1998-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel.db; import helma.objectmodel.*; import java.util.List; import java.util.Vector; - /** * A wrapper around NodeManager that catches most Exceptions, or rethrows them as RuntimeExceptions. * The idea behind this is that we don't care a lot about Exception classes, since Hop programming is done * in JavaScript which doesn't know about them (except for the exception message). */ - - public final class WrappedNodeManager { - +public final class WrappedNodeManager { NodeManager nmgr; - public WrappedNodeManager (NodeManager nmgr) { - this.nmgr = nmgr; + /** + * Creates a new WrappedNodeManager object. + * + * @param nmgr ... + */ + public WrappedNodeManager(NodeManager nmgr) { + this.nmgr = nmgr; } - public Node getNode (String id, DbMapping dbmap) { - return getNode (new DbKey (dbmap, id)); + /** + * + * + * @param id ... + * @param dbmap ... + * + * @return ... + */ + public Node getNode(String id, DbMapping dbmap) { + return getNode(new DbKey(dbmap, id)); } - public Node getNode (Key key) { - try { - return nmgr.getNode (key); - } catch (ObjectNotFoundException x) { - return null; - } catch (Exception x) { - nmgr.app.logEvent ("Error retrieving Node via DbMapping: "+x); - if (nmgr.app.debug ()) - x.printStackTrace(); - throw new RuntimeException ("Error retrieving Node: "+x); - } + /** + * + * + * @param key ... + * + * @return ... + */ + public Node getNode(Key key) { + try { + return nmgr.getNode(key); + } catch (ObjectNotFoundException x) { + return null; + } catch (Exception x) { + nmgr.app.logEvent("Error retrieving Node via DbMapping: " + x); + + if (nmgr.app.debug()) { + x.printStackTrace(); + } + + throw new RuntimeException("Error retrieving Node: " + x); + } } - public Node getNode (Node home, String id, Relation rel) { - try { - return nmgr.getNode (home, id, rel); - } catch (ObjectNotFoundException x) { - return null; - } catch (Exception x) { - nmgr.app.logEvent ("Error retrieving Node \""+id+"\" from "+home+": "+x); - if (nmgr.app.debug ()) - x.printStackTrace(); - throw new RuntimeException ("Error retrieving Node: "+x); - } + /** + * + * + * @param home ... + * @param id ... + * @param rel ... + * + * @return ... + */ + public Node getNode(Node home, String id, Relation rel) { + try { + return nmgr.getNode(home, id, rel); + } catch (ObjectNotFoundException x) { + return null; + } catch (Exception x) { + nmgr.app.logEvent("Error retrieving Node \"" + id + "\" from " + home + ": " + + x); + + if (nmgr.app.debug()) { + x.printStackTrace(); + } + + throw new RuntimeException("Error retrieving Node: " + x); + } } - public List getNodes (Node home, Relation rel) { - try { - return nmgr.getNodes (home, rel); - } catch (Exception x) { - if (nmgr.app.debug ()) - x.printStackTrace(); - throw new RuntimeException ("Error retrieving Nodes: "+x); - } + /** + * + * + * @param home ... + * @param rel ... + * + * @return ... + */ + public List getNodes(Node home, Relation rel) { + try { + return nmgr.getNodes(home, rel); + } catch (Exception x) { + if (nmgr.app.debug()) { + x.printStackTrace(); + } + + throw new RuntimeException("Error retrieving Nodes: " + x); + } } - public List getNodeIDs (Node home, Relation rel) { - try { - return nmgr.getNodeIDs (home, rel); - } catch (Exception x) { - if (nmgr.app.debug ()) - x.printStackTrace(); - throw new RuntimeException ("Error retrieving NodeIDs: "+x); - } + /** + * + * + * @param home ... + * @param rel ... + * + * @return ... + */ + public List getNodeIDs(Node home, Relation rel) { + try { + return nmgr.getNodeIDs(home, rel); + } catch (Exception x) { + if (nmgr.app.debug()) { + x.printStackTrace(); + } + + throw new RuntimeException("Error retrieving NodeIDs: " + x); + } } - public int countNodes (Node home, Relation rel) { - try { - return nmgr.countNodes (home, rel); - } catch (Exception x) { - if (nmgr.app.debug ()) - x.printStackTrace(); - throw new RuntimeException ("Error counting Node: "+x); - } + /** + * + * + * @param home ... + * @param rel ... + * + * @return ... + */ + public int countNodes(Node home, Relation rel) { + try { + return nmgr.countNodes(home, rel); + } catch (Exception x) { + if (nmgr.app.debug()) { + x.printStackTrace(); + } + + throw new RuntimeException("Error counting Node: " + x); + } } - public void deleteNode (Node node) { - try { - nmgr.deleteNode (node); - } catch (Exception x) { - if (nmgr.app.debug ()) - x.printStackTrace(); - throw new RuntimeException ("Error deleting Node: "+x); - } + /** + * + * + * @param node ... + */ + public void deleteNode(Node node) { + try { + nmgr.deleteNode(node); + } catch (Exception x) { + if (nmgr.app.debug()) { + x.printStackTrace(); + } + + throw new RuntimeException("Error deleting Node: " + x); + } } - public Vector getPropertyNames (Node home, Relation rel) { - try { - return nmgr.getPropertyNames (home, rel); - } catch (Exception x) { - if (nmgr.app.debug ()) - x.printStackTrace(); - throw new RuntimeException ("Error retrieving property names: "+x); - } + /** + * + * + * @param home ... + * @param rel ... + * + * @return ... + */ + public Vector getPropertyNames(Node home, Relation rel) { + try { + return nmgr.getPropertyNames(home, rel); + } catch (Exception x) { + if (nmgr.app.debug()) { + x.printStackTrace(); + } + + throw new RuntimeException("Error retrieving property names: " + x); + } } - public void registerNode (Node node) { - nmgr.registerNode (node); + /** + * + * + * @param node ... + */ + public void registerNode(Node node) { + nmgr.registerNode(node); } - public void evictNode (Node node) { - nmgr.evictNode (node); + /** + * + * + * @param node ... + */ + public void evictNode(Node node) { + nmgr.evictNode(node); } - public void evictNodeByKey (Key key) { - nmgr.evictNodeByKey (key); + /** + * + * + * @param key ... + */ + public void evictNodeByKey(Key key) { + nmgr.evictNodeByKey(key); } - public void evictKey (Key key) { - nmgr.evictKey (key); + /** + * + * + * @param key ... + */ + public void evictKey(Key key) { + nmgr.evictKey(key); } - - public String generateID () { - return nmgr.idgen.newID (); + /** + * + * + * @return ... + */ + public String generateID() { + return nmgr.idgen.newID(); } - public String generateID (DbMapping map) { - try { - // check if we use internal id generator - if (map == null || !map.isRelational () || "[hop]".equalsIgnoreCase (map.getIDgen())) - return nmgr.idgen.newID (); - // or if we query max key value - else if (map.getIDgen() == null || "[max]".equalsIgnoreCase (map.getIDgen())) - return nmgr.generateMaxID (map); - else - return nmgr.generateID (map); - // otherwise, we use an oracle sequence - } catch (Exception x) { - if (nmgr.app.debug ()) - x.printStackTrace(); - throw new RuntimeException (x.toString ()); - } + /** + * + * + * @param map ... + * + * @return ... + */ + public String generateID(DbMapping map) { + try { + // check if we use internal id generator + if ((map == null) || !map.isRelational() || + "[hop]".equalsIgnoreCase(map.getIDgen())) { + return nmgr.idgen.newID(); + } + // or if we query max key value + else if ((map.getIDgen() == null) || + "[max]".equalsIgnoreCase(map.getIDgen())) { + return nmgr.generateMaxID(map); + } else { + return nmgr.generateID(map); + } + + // otherwise, we use an oracle sequence + } catch (Exception x) { + if (nmgr.app.debug()) { + x.printStackTrace(); + } + + throw new RuntimeException(x.toString()); + } } - public Object[] getCacheEntries () { - return nmgr.getCacheEntries (); + /** + * + * + * @return ... + */ + public Object[] getCacheEntries() { + return nmgr.getCacheEntries(); } - public void logEvent (String msg) { - nmgr.app.logEvent (msg); + /** + * + * + * @param msg ... + */ + public void logEvent(String msg) { + nmgr.app.logEvent(msg); } - public DbMapping getDbMapping (String name) { - return nmgr.app.getDbMapping (name); + /** + * + * + * @param name ... + * + * @return ... + */ + public DbMapping getDbMapping(String name) { + return nmgr.app.getDbMapping(name); } - } diff --git a/src/helma/objectmodel/db/XmlDatabase.java b/src/helma/objectmodel/db/XmlDatabase.java index 20af7296..f72bf1b2 100644 --- a/src/helma/objectmodel/db/XmlDatabase.java +++ b/src/helma/objectmodel/db/XmlDatabase.java @@ -1,97 +1,240 @@ -package helma.objectmodel.db; +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ -import java.io.*; -import java.util.Date; -import org.w3c.dom.Element; -import org.w3c.dom.Document; +package helma.objectmodel.db; import helma.objectmodel.*; import helma.objectmodel.dom.*; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import java.io.*; +import java.util.Date; +import javax.xml.parsers.ParserConfigurationException; +import org.xml.sax.SAXException; /** * A simple XML-database */ - public final class XmlDatabase implements IDatabase { + private String dbHome; + private File dbBaseDir; + private NodeManager nmgr; + private IDGenerator idgen; - private String dbHome; - private File dbBaseDir; - private NodeManager nmgr; - private IDGenerator idgen; - // character encoding to use when writing files. - // use standard encoding by default. - private String encoding = null; - + // character encoding to use when writing files. + // use standard encoding by default. + private String encoding = null; - public XmlDatabase (String dbHome, String dbFilename, NodeManager nmgr) throws DatabaseException { - this.dbHome = dbHome; - this.nmgr = nmgr; - dbBaseDir = new File (dbHome); - if (!dbBaseDir.exists() && !dbBaseDir.mkdirs() ) - throw new RuntimeException("Couldn't create DB-directory"); - this.encoding = nmgr.app.getCharset (); - } + /** + * Creates a new XmlDatabase object. + * + * @param dbHome ... + * @param dbFilename ... + * @param nmgr ... + * + * @throws DatabaseException ... + * @throws RuntimeException ... + */ + public XmlDatabase(String dbHome, String dbFilename, NodeManager nmgr) + throws DatabaseException { + this.dbHome = dbHome; + this.nmgr = nmgr; + dbBaseDir = new File(dbHome); - public void shutdown () { } - public ITransaction beginTransaction () throws DatabaseException { return null; } - public void commitTransaction (ITransaction txn) throws DatabaseException { } - public void abortTransaction (ITransaction txn) throws DatabaseException { } + if (!dbBaseDir.exists() && !dbBaseDir.mkdirs()) { + throw new RuntimeException("Couldn't create DB-directory"); + } - public String nextID() throws ObjectNotFoundException { - if (idgen==null) { - getIDGenerator(null); - } - return idgen.newID(); - } + this.encoding = nmgr.app.getCharset(); + } - public IDGenerator getIDGenerator (ITransaction txn) throws ObjectNotFoundException { - File file = new File (dbBaseDir, "idgen.xml"); - this.idgen = IDGenParser.getIDGenerator(file); - return idgen; - } + /** + * + */ + public void shutdown() { + } - public void saveIDGenerator (ITransaction txn, IDGenerator idgen) throws Exception { - File file = new File (dbBaseDir, "idgen.xml"); - IDGenParser.saveIDGenerator(idgen,file); - this.idgen = idgen; - } + /** + * + * + * @return ... + * + * @throws DatabaseException ... + */ + public ITransaction beginTransaction() throws DatabaseException { + return null; + } - public INode getNode (ITransaction txn, String kstr) throws Exception { - File f = new File (dbBaseDir, kstr+".xml"); - if ( ! f.exists() ) - throw new ObjectNotFoundException ("Object not found for key "+kstr+"."); - try { - XmlDatabaseReader reader = new XmlDatabaseReader (nmgr); - Node node = reader.read (f); - return node; - } catch ( RuntimeException x ) { - nmgr.app.logEvent("error reading node from XmlDatbase: " + x.toString() ); - throw new ObjectNotFoundException(x.toString()); - } - } + /** + * + * + * @param txn ... + * + * @throws DatabaseException ... + */ + public void commitTransaction(ITransaction txn) throws DatabaseException { + } - public void saveNode (ITransaction txn, String kstr, INode node) throws Exception { - XmlWriter writer = null; - File file = new File (dbBaseDir,kstr+".xml"); - if (encoding != null) - writer = new XmlWriter (file, encoding); - else - writer = new XmlWriter (file); - writer.setMaxLevels(1); - boolean result = writer.write((Node)node); - writer.close(); - } + /** + * + * + * @param txn ... + * + * @throws DatabaseException ... + */ + public void abortTransaction(ITransaction txn) throws DatabaseException { + } - public void deleteNode (ITransaction txn, String kstr) throws Exception { - File f = new File (dbBaseDir, kstr+".xml"); - f.delete(); - } + /** + * + * + * @return ... + * + * @throws ObjectNotFoundException ... + */ + public String nextID() throws ObjectNotFoundException { + if (idgen == null) { + getIDGenerator(null); + } - public void setEncoding (String enc) { - this.encoding = encoding; - } + return idgen.newID(); + } - public String getEncoding () { - return encoding; - } + /** + * + * + * @param txn ... + * + * @return ... + * + * @throws ObjectNotFoundException ... + */ + public IDGenerator getIDGenerator(ITransaction txn) + throws ObjectNotFoundException { + File file = new File(dbBaseDir, "idgen.xml"); + + this.idgen = IDGenParser.getIDGenerator(file); + + return idgen; + } + + /** + * + * + * @param txn ... + * @param idgen ... + * + * @throws Exception ... + */ + public void saveIDGenerator(ITransaction txn, IDGenerator idgen) + throws IOException { + File file = new File(dbBaseDir, "idgen.xml"); + + IDGenParser.saveIDGenerator(idgen, file); + this.idgen = idgen; + } + + /** + * + * + * @param txn ... + * @param kstr ... + * + * @return ... + * + * @throws Exception ... + * @throws ObjectNotFoundException ... + */ + public INode getNode(ITransaction txn, String kstr) + throws IOException, ObjectNotFoundException, + ParserConfigurationException, SAXException { + File f = new File(dbBaseDir, kstr + ".xml"); + + if (!f.exists()) { + throw new ObjectNotFoundException("Object not found for key " + kstr + "."); + } + + try { + XmlDatabaseReader reader = new XmlDatabaseReader(nmgr); + Node node = reader.read(f); + + return node; + } catch (RuntimeException x) { + nmgr.app.logEvent("error reading node from XmlDatbase: " + x.toString()); + throw new ObjectNotFoundException(x.toString()); + } + } + + /** + * + * + * @param txn ... + * @param kstr ... + * @param node ... + * + * @throws Exception ... + */ + public void saveNode(ITransaction txn, String kstr, INode node) + throws IOException { + XmlWriter writer = null; + File file = new File(dbBaseDir, kstr + ".xml"); + + if (encoding != null) { + writer = new XmlWriter(file, encoding); + } else { + writer = new XmlWriter(file); + } + + writer.setMaxLevels(1); + + boolean result = writer.write((Node) node); + + writer.close(); + } + + /** + * + * + * @param txn ... + * @param kstr ... + * + * @throws Exception ... + */ + public void deleteNode(ITransaction txn, String kstr) + throws IOException { + File f = new File(dbBaseDir, kstr + ".xml"); + + f.delete(); + } + + /** + * + * + * @param enc ... + */ + public void setEncoding(String enc) { + this.encoding = encoding; + } + + /** + * + * + * @return ... + */ + public String getEncoding() { + return encoding; + } } diff --git a/src/helma/objectmodel/dom/IDGenParser.java b/src/helma/objectmodel/dom/IDGenParser.java index 2f16ee7d..f6cfd3f8 100644 --- a/src/helma/objectmodel/dom/IDGenParser.java +++ b/src/helma/objectmodel/dom/IDGenParser.java @@ -1,37 +1,80 @@ -package helma.objectmodel.dom; +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ -import java.io.*; -import java.util.Date; -import org.w3c.dom.*; +package helma.objectmodel.dom; import helma.objectmodel.ObjectNotFoundException; import helma.objectmodel.db.IDGenerator; +import org.w3c.dom.*; +import java.io.*; +import java.util.Date; -public class IDGenParser { +/** + * + */ +public class IDGenParser { + /** + * + * + * @param file ... + * + * @return ... + * + * @throws ObjectNotFoundException ... + */ + public static IDGenerator getIDGenerator(File file) + throws ObjectNotFoundException { + if (!file.exists()) { + throw new ObjectNotFoundException("IDGenerator not found in idgen.xml"); + } - public static IDGenerator getIDGenerator (File file) throws ObjectNotFoundException { - if ( ! file.exists() ) - throw new ObjectNotFoundException ("IDGenerator not found in idgen.xml"); - try { - Document document = XmlUtil.parse(new FileInputStream (file)); - org.w3c.dom.Element tmp = (Element)document.getDocumentElement().getElementsByTagName("counter").item(0); - return new IDGenerator( Long.parseLong (XmlUtil.getTextContent(tmp)) ); - } catch (Exception e) { - throw new ObjectNotFoundException(e.toString()); - } + try { + Document document = XmlUtil.parse(new FileInputStream(file)); + org.w3c.dom.Element tmp = (Element) document.getDocumentElement() + .getElementsByTagName("counter") + .item(0); + + return new IDGenerator(Long.parseLong(XmlUtil.getTextContent(tmp))); + } catch (Exception e) { + throw new ObjectNotFoundException(e.toString()); + } } - public static IDGenerator saveIDGenerator (IDGenerator idgen, File file) throws Exception { - OutputStreamWriter out = new OutputStreamWriter (new FileOutputStream (file)); - out.write ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); - out.write ("<!-- printed by helma object publisher -->\n"); - out.write ("<!-- created " + (new Date()).toString() + " -->\n" ); - out.write ("<xmlroot>\n"); - out.write (" <counter>" + idgen.getValue() + "</counter>\n"); - out.write ("</xmlroot>\n"); - out.close (); - return idgen; - } - -} + /** + * + * + * @param idgen ... + * @param file ... + * + * @return ... + * + * @throws Exception ... + */ + public static IDGenerator saveIDGenerator(IDGenerator idgen, File file) + throws IOException { + OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file)); + out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); + out.write("<!-- printed by helma object publisher -->\n"); + out.write("<!-- created " + (new Date()).toString() + " -->\n"); + out.write("<xmlroot>\n"); + out.write(" <counter>" + idgen.getValue() + "</counter>\n"); + out.write("</xmlroot>\n"); + out.close(); + + return idgen; + } +} diff --git a/src/helma/objectmodel/dom/XmlConstants.java b/src/helma/objectmodel/dom/XmlConstants.java index 2ab0709d..7c87064c 100644 --- a/src/helma/objectmodel/dom/XmlConstants.java +++ b/src/helma/objectmodel/dom/XmlConstants.java @@ -1,8 +1,25 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel.dom; -public interface XmlConstants { - - public final String NAMESPACE = "http://www.helma.org/docs/guide/features/database"; - public final String DATEFORMAT = "dd.MM.yyyy HH:mm:ss z"; - +/** + * + */ +public interface XmlConstants { + public final String NAMESPACE = "http://www.helma.org/docs/guide/features/database"; + public final String DATEFORMAT = "dd.MM.yyyy HH:mm:ss z"; } diff --git a/src/helma/objectmodel/dom/XmlConverter.java b/src/helma/objectmodel/dom/XmlConverter.java index 51c6472e..95e1bed6 100644 --- a/src/helma/objectmodel/dom/XmlConverter.java +++ b/src/helma/objectmodel/dom/XmlConverter.java @@ -1,345 +1,536 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel.dom; -import java.io.*; -import java.net.*; -import java.util.*; - -import javax.xml.parsers.*; -import org.w3c.dom.*; -import org.xml.sax.InputSource; - import helma.objectmodel.*; import helma.util.SystemProperties; +import org.w3c.dom.*; +import org.xml.sax.InputSource; +import java.io.*; +import java.net.*; +import java.util.*; +import javax.xml.parsers.*; +/** + * + */ public class XmlConverter implements XmlConstants { - private boolean DEBUG = false; - private boolean sparse = false; - private Properties props; - - private char defaultSeparator = '_'; - + private char defaultSeparator = '_'; private int offset = 0; + /** + * Creates a new XmlConverter object. + */ public XmlConverter() { - props = new SystemProperties(); + props = new SystemProperties(); } + /** + * Creates a new XmlConverter object. + * + * @param propFile ... + */ public XmlConverter(String propFile) { - props = new SystemProperties(propFile); - extractProperties(props); + props = new SystemProperties(propFile); + extractProperties(props); } + /** + * Creates a new XmlConverter object. + * + * @param propFile ... + */ public XmlConverter(File propFile) { - this ( propFile.getAbsolutePath() ); + this(propFile.getAbsolutePath()); } + /** + * Creates a new XmlConverter object. + * + * @param props ... + */ public XmlConverter(Properties props) { - this.props = props; - extractProperties(props); + this.props = props; + extractProperties(props); } - public INode convert( String desc ) { - return convert(desc, new TransientNode() ); + /** + * + * + * @param desc ... + * + * @return ... + */ + public INode convert(String desc) { + return convert(desc, new TransientNode()); } - public INode convert( String desc, INode helmaNode ) throws RuntimeException { - try { - return convert( new URL(desc), helmaNode ); - } catch ( MalformedURLException notanurl ) { - try { - return convert( new File(desc), helmaNode ); - } catch ( FileNotFoundException notfound ) { - throw new RuntimeException( "couldn't read xml: " + desc ); - } - } catch ( IOException ioerror ) { - throw new RuntimeException( "couldn't read xml: " + desc ); - } + /** + * + * + * @param desc ... + * @param helmaNode ... + * + * @return ... + * + * @throws RuntimeException ... + */ + public INode convert(String desc, INode helmaNode) + throws RuntimeException { + try { + return convert(new URL(desc), helmaNode); + } catch (MalformedURLException notanurl) { + try { + return convert(new File(desc), helmaNode); + } catch (FileNotFoundException notfound) { + throw new RuntimeException("couldn't read xml: " + desc); + } + } catch (IOException ioerror) { + throw new RuntimeException("couldn't read xml: " + desc); + } } - public INode convert( File file, INode helmaNode ) throws RuntimeException, FileNotFoundException { - return convert( new FileInputStream(file), helmaNode ); + /** + * + * + * @param file ... + * @param helmaNode ... + * + * @return ... + * + * @throws RuntimeException ... + * @throws FileNotFoundException ... + */ + public INode convert(File file, INode helmaNode) + throws RuntimeException, FileNotFoundException { + return convert(new FileInputStream(file), helmaNode); } - public INode convert( URL url, INode helmaNode ) throws RuntimeException, IOException, MalformedURLException { - return convert( url.openConnection().getInputStream(), helmaNode ); + /** + * + * + * @param url ... + * @param helmaNode ... + * + * @return ... + * + * @throws RuntimeException ... + * @throws IOException ... + * @throws MalformedURLException ... + */ + public INode convert(URL url, INode helmaNode) + throws RuntimeException, IOException, MalformedURLException { + return convert(url.openConnection().getInputStream(), helmaNode); } - public INode convert( InputStream in, INode helmaNode ) throws RuntimeException { - Document document = XmlUtil.parse (in); - if ( document!=null && document.getDocumentElement()!=null ) { - return convert( document.getDocumentElement(), helmaNode, new HashMap() ); - } else { - return helmaNode; - } + /** + * + * + * @param in ... + * @param helmaNode ... + * + * @return ... + * + * @throws RuntimeException ... + */ + public INode convert(InputStream in, INode helmaNode) + throws RuntimeException { + Document document = XmlUtil.parse(in); + + if ((document != null) && (document.getDocumentElement() != null)) { + return convert(document.getDocumentElement(), helmaNode, new HashMap()); + } else { + return helmaNode; + } } - public INode convertFromString( String xml, INode helmaNode ) throws RuntimeException { - Document document = XmlUtil.parse (new InputSource (new StringReader (xml))); - if ( document!=null && document.getDocumentElement()!=null ) { - return convert( document.getDocumentElement(), helmaNode, new HashMap() ); - } else { - return helmaNode; - } + /** + * + * + * @param xml ... + * @param helmaNode ... + * + * @return ... + * + * @throws RuntimeException ... + */ + public INode convertFromString(String xml, INode helmaNode) + throws RuntimeException { + Document document = XmlUtil.parse(new InputSource(new StringReader(xml))); + + if ((document != null) && (document.getDocumentElement() != null)) { + return convert(document.getDocumentElement(), helmaNode, new HashMap()); + } else { + return helmaNode; + } } - public INode convert( Element element, INode helmaNode, Map nodeCache ) { - offset++; - // previousNode is used to cache previous nodes with the same prototype - // so we can reset it in the nodeCache after we've run - Object previousNode = null; - if (DEBUG) - debug("reading " + element.getNodeName() ); - String prototype = props.getProperty(element.getNodeName()+"._prototype"); - if ( prototype == null && !sparse ) - prototype = "HopObject"; - // if we have a prototype (either explicit or implicit "hopobject"), - // set it on the Helma node and store it in the node cache. - if ( prototype != null ) { - helmaNode.setName( element.getNodeName() ); - helmaNode.setPrototype( prototype ); - previousNode = nodeCache.put (prototype, helmaNode); - } - // check attributes of the current element - attributes(element, helmaNode, nodeCache); - // check child nodes of the current element - if ( element.hasChildNodes() ) - children(element, helmaNode, nodeCache); + /** + * + * + * @param element ... + * @param helmaNode ... + * @param nodeCache ... + * + * @return ... + */ + public INode convert(Element element, INode helmaNode, Map nodeCache) { + offset++; - // if it exists, restore the previous node we've replaced in the node cache. - if (previousNode != null) - nodeCache.put (prototype, previousNode); + // previousNode is used to cache previous nodes with the same prototype + // so we can reset it in the nodeCache after we've run + Object previousNode = null; - offset--; - return helmaNode; + if (DEBUG) { + debug("reading " + element.getNodeName()); + } + + String prototype = props.getProperty(element.getNodeName() + "._prototype"); + + if ((prototype == null) && !sparse) { + prototype = "HopObject"; + } + + // if we have a prototype (either explicit or implicit "hopobject"), + // set it on the Helma node and store it in the node cache. + if (prototype != null) { + helmaNode.setName(element.getNodeName()); + helmaNode.setPrototype(prototype); + previousNode = nodeCache.put(prototype, helmaNode); + } + + // check attributes of the current element + attributes(element, helmaNode, nodeCache); + + // check child nodes of the current element + if (element.hasChildNodes()) { + children(element, helmaNode, nodeCache); + } + + // if it exists, restore the previous node we've replaced in the node cache. + if (previousNode != null) { + nodeCache.put(prototype, previousNode); + } + + offset--; + + return helmaNode; } /** * parse xml children and create hopobject-children */ - private INode children( Element element, helma.objectmodel.INode helmaNode, Map nodeCache ) { - NodeList list = element.getChildNodes(); - int len = list.getLength(); - boolean nodeIsInitialized = !nodeCache.isEmpty(); - StringBuffer textcontent = new StringBuffer(); - String domKey, helmaKey; - for ( int i=0; i<len; i++ ) { + private INode children(Element element, helma.objectmodel.INode helmaNode, + Map nodeCache) { + NodeList list = element.getChildNodes(); + int len = list.getLength(); + boolean nodeIsInitialized = !nodeCache.isEmpty(); + StringBuffer textcontent = new StringBuffer(); + String domKey; + String helmaKey; - // loop through the list of children - org.w3c.dom.Node childNode = list.item(i); + for (int i = 0; i < len; i++) { + // loop through the list of children + org.w3c.dom.Node childNode = list.item(i); - // if the current node hasn't been initialized yet, try if it can - // be initialized and converted from one of the child elements. - if (!nodeIsInitialized) { - if (childNode.getNodeType() == Node.ELEMENT_NODE) { - convert ((Element) childNode, helmaNode, nodeCache); - if (helmaNode.getPrototype() != null) - return helmaNode; - } - continue; - } + // if the current node hasn't been initialized yet, try if it can + // be initialized and converted from one of the child elements. + if (!nodeIsInitialized) { + if (childNode.getNodeType() == Node.ELEMENT_NODE) { + convert((Element) childNode, helmaNode, nodeCache); - // if it's text content of this element -> append to StringBuffer - if ( childNode.getNodeType() == Node.TEXT_NODE || - childNode.getNodeType() == Node.CDATA_SECTION_NODE ) { - textcontent.append( childNode.getNodeValue().trim() ); - continue; - } + if (helmaNode.getPrototype() != null) { + return helmaNode; + } + } - // it's some kind of element (property or child) - if ( childNode.getNodeType() == Node.ELEMENT_NODE ) { + continue; + } - Element childElement = (Element)childNode; + // if it's text content of this element -> append to StringBuffer + if ((childNode.getNodeType() == Node.TEXT_NODE) || + (childNode.getNodeType() == Node.CDATA_SECTION_NODE)) { + textcontent.append(childNode.getNodeValue().trim()); - // get the basic key we have to look for in the properties-table - domKey = element.getNodeName()+"."+childElement.getNodeName(); + continue; + } - // is there a childtext-2-property mapping? - if ( props!=null && props.containsKey(domKey+"._text") ) { - helmaKey = props.getProperty(domKey+"._text"); - if( helmaKey.equals("") ) - // if property is set but without value, read elementname for this mapping - helmaKey = childElement.getNodeName().replace(':',defaultSeparator); - if (DEBUG) - debug("childtext-2-property mapping, helmaKey " + helmaKey + " for domKey " + domKey ); - // check if helmaKey contains an explicit prototype name in which to - // set the property. - int dot = helmaKey.indexOf("."); - if (dot > -1) { - String prototype = helmaKey.substring (0, dot); - INode node = (INode) nodeCache.get (prototype); - helmaKey = helmaKey.substring (dot+1); - if (node != null && node.getString(helmaKey)==null) { - node.setString (helmaKey, XmlUtil.getTextContent (childNode)); - } - } else if ( helmaNode.getString(helmaKey)==null ) { - helmaNode.setString( helmaKey, XmlUtil.getTextContent(childNode) ); - if (DEBUG) - debug("childtext-2-property mapping, setting " + helmaKey + " as string" ); - } - continue; - } + // it's some kind of element (property or child) + if (childNode.getNodeType() == Node.ELEMENT_NODE) { + Element childElement = (Element) childNode; - // is there a simple child-2-property mapping? - // (lets the user define to use only one element and make this a property - // and simply ignore other elements of the same name) - if ( props!=null && props.containsKey(domKey+"._property") ) { - helmaKey = props.getProperty(domKey+"._property"); - // if property is set but without value, read elementname for this mapping: - if ( helmaKey.equals("") ) - helmaKey = childElement.getNodeName().replace(':',defaultSeparator); - if (DEBUG) - debug("child-2-property mapping, helmaKey " + helmaKey + " for domKey " + domKey); - // get the node on which to opererate, depending on the helmaKey - // value from the properties file. - INode node = helmaNode; - int dot = helmaKey.indexOf("."); - if (dot > -1) { - String prototype = helmaKey.substring (0, dot); - if (!prototype.equalsIgnoreCase (node.getPrototype())) - node = (INode) nodeCache.get (prototype); - helmaKey = helmaKey.substring (dot+1); - } - if (node == null) - continue; + // get the basic key we have to look for in the properties-table + domKey = element.getNodeName() + "." + childElement.getNodeName(); - if ( node.getNode(helmaKey)==null ) { - convert( childElement, node.createNode(helmaKey), nodeCache ); - if (DEBUG) - debug( "read " + childElement.toString() + node.getNode(helmaKey).toString() ); - } - continue; - } + // is there a childtext-2-property mapping? + if ((props != null) && props.containsKey(domKey + "._text")) { + helmaKey = props.getProperty(domKey + "._text"); + if (helmaKey.equals("")) { + // if property is set but without value, read elementname for this mapping + helmaKey = childElement.getNodeName().replace(':', + defaultSeparator); + } - // map it to one of the children-lists - helma.objectmodel.INode newHelmaNode = null; - String childrenMapping = props.getProperty(element.getNodeName()+"._children"); - // do we need a mapping directly among _children of helmaNode? - // can either be through property elname._children=_all or elname._children=childname - if( childrenMapping!=null && ( childrenMapping.equals("_all") || childrenMapping.equals(childElement.getNodeName()) ) ) { - newHelmaNode = convert(childElement, helmaNode.createNode(null), nodeCache ); - } - // in which virtual subnode collection should objects of this type be stored? - helmaKey = props.getProperty(domKey); - if ( helmaKey==null && !sparse ) { - helmaKey = childElement.getNodeName().replace(':',defaultSeparator); - } - if (helmaKey == null) { - // we don't map this child element itself since we do - // sparse parsing, but there may be something of interest - // in the child's attributes and child elements. - attributes (childElement, helmaNode, nodeCache); - children (childElement, helmaNode, nodeCache); - continue; - } + if (DEBUG) { + debug("childtext-2-property mapping, helmaKey " + helmaKey + + " for domKey " + domKey); + } - // get the node on which to opererate, depending on the helmaKey - // value from the properties file. - INode node = helmaNode; - int dot = helmaKey.indexOf("."); - if (dot > -1) { - String prototype = helmaKey.substring (0, dot); - if (!prototype.equalsIgnoreCase (node.getPrototype())) - node = (INode) nodeCache.get (prototype); - helmaKey = helmaKey.substring (dot+1); - } - if (node == null) - continue; + // check if helmaKey contains an explicit prototype name in which to + // set the property. + int dot = helmaKey.indexOf("."); - // try to get the virtual node - INode worknode = null; - if ("_children".equals (helmaKey)) { - worknode = node; - } else { - worknode = node.getNode( helmaKey ); - if ( worknode==null ) { - // if virtual node doesn't exist, create it - worknode = helmaNode.createNode( helmaKey ); - } - } - if (DEBUG) - debug( "mounting child "+ childElement.getNodeName() + " at worknode " + worknode.toString() ); - // now mount it, possibly re-using the helmaNode that's been created before - if ( newHelmaNode!=null ) { - worknode.addNode(newHelmaNode); - } else { - convert( childElement, worknode.createNode( null ), nodeCache ); - } - } - // forget about other types (comments etc) - continue; - } + if (dot > -1) { + String prototype = helmaKey.substring(0, dot); + INode node = (INode) nodeCache.get(prototype); - // if there's some text content for this element, map it: - if ( textcontent.length()>0 && !sparse ) { - helmaKey = props.getProperty(element.getNodeName()+"._text"); - if ( helmaKey==null ) - helmaKey = "text"; - if (DEBUG) - debug ("setting text "+textcontent+" to property "+helmaKey+" of object "+helmaNode); - helmaNode.setString(helmaKey, textcontent.toString().trim() ); - } + helmaKey = helmaKey.substring(dot + 1); - return helmaNode; + if ((node != null) && (node.getString(helmaKey) == null)) { + node.setString(helmaKey, XmlUtil.getTextContent(childNode)); + } + } else if (helmaNode.getString(helmaKey) == null) { + helmaNode.setString(helmaKey, XmlUtil.getTextContent(childNode)); + + if (DEBUG) { + debug("childtext-2-property mapping, setting " + helmaKey + + " as string"); + } + } + + continue; + } + + // is there a simple child-2-property mapping? + // (lets the user define to use only one element and make this a property + // and simply ignore other elements of the same name) + if ((props != null) && props.containsKey(domKey + "._property")) { + helmaKey = props.getProperty(domKey + "._property"); + + // if property is set but without value, read elementname for this mapping: + if (helmaKey.equals("")) { + helmaKey = childElement.getNodeName().replace(':', + defaultSeparator); + } + + if (DEBUG) { + debug("child-2-property mapping, helmaKey " + helmaKey + + " for domKey " + domKey); + } + + // get the node on which to opererate, depending on the helmaKey + // value from the properties file. + INode node = helmaNode; + int dot = helmaKey.indexOf("."); + + if (dot > -1) { + String prototype = helmaKey.substring(0, dot); + + if (!prototype.equalsIgnoreCase(node.getPrototype())) { + node = (INode) nodeCache.get(prototype); + } + + helmaKey = helmaKey.substring(dot + 1); + } + + if (node == null) { + continue; + } + + if (node.getNode(helmaKey) == null) { + convert(childElement, node.createNode(helmaKey), nodeCache); + + if (DEBUG) { + debug("read " + childElement.toString() + + node.getNode(helmaKey).toString()); + } + } + + continue; + } + + // map it to one of the children-lists + helma.objectmodel.INode newHelmaNode = null; + String childrenMapping = props.getProperty(element.getNodeName() + + "._children"); + + // do we need a mapping directly among _children of helmaNode? + // can either be through property elname._children=_all or elname._children=childname + if ((childrenMapping != null) && + (childrenMapping.equals("_all") || + childrenMapping.equals(childElement.getNodeName()))) { + newHelmaNode = convert(childElement, helmaNode.createNode(null), + nodeCache); + } + + // in which virtual subnode collection should objects of this type be stored? + helmaKey = props.getProperty(domKey); + + if ((helmaKey == null) && !sparse) { + helmaKey = childElement.getNodeName().replace(':', defaultSeparator); + } + + if (helmaKey == null) { + // we don't map this child element itself since we do + // sparse parsing, but there may be something of interest + // in the child's attributes and child elements. + attributes(childElement, helmaNode, nodeCache); + children(childElement, helmaNode, nodeCache); + + continue; + } + + // get the node on which to opererate, depending on the helmaKey + // value from the properties file. + INode node = helmaNode; + int dot = helmaKey.indexOf("."); + + if (dot > -1) { + String prototype = helmaKey.substring(0, dot); + + if (!prototype.equalsIgnoreCase(node.getPrototype())) { + node = (INode) nodeCache.get(prototype); + } + + helmaKey = helmaKey.substring(dot + 1); + } + + if (node == null) { + continue; + } + + // try to get the virtual node + INode worknode = null; + + if ("_children".equals(helmaKey)) { + worknode = node; + } else { + worknode = node.getNode(helmaKey); + + if (worknode == null) { + // if virtual node doesn't exist, create it + worknode = helmaNode.createNode(helmaKey); + } + } + + if (DEBUG) { + debug("mounting child " + childElement.getNodeName() + + " at worknode " + worknode.toString()); + } + + // now mount it, possibly re-using the helmaNode that's been created before + if (newHelmaNode != null) { + worknode.addNode(newHelmaNode); + } else { + convert(childElement, worknode.createNode(null), nodeCache); + } + } + + // forget about other types (comments etc) + continue; + } + + // if there's some text content for this element, map it: + if ((textcontent.length() > 0) && !sparse) { + helmaKey = props.getProperty(element.getNodeName() + "._text"); + + if (helmaKey == null) { + helmaKey = "text"; + } + + if (DEBUG) { + debug("setting text " + textcontent + " to property " + helmaKey + + " of object " + helmaNode); + } + + helmaNode.setString(helmaKey, textcontent.toString().trim()); + } + + return helmaNode; } /** * set element's attributes as properties of helmaNode */ - private INode attributes( Element element, INode helmaNode, Map nodeCache ) { - NamedNodeMap nnm = element.getAttributes(); - int len = nnm.getLength(); - for ( int i=0; i<len; i++ ) { - org.w3c.dom.Node attr = nnm.item(i); - String helmaKey = props.getProperty(element.getNodeName()+"._attribute."+attr.getNodeName()); - // unless we only map explicit attributes, use attribute name as property name - // in case no property name was defined. - if ( helmaKey==null && !sparse) - helmaKey = attr.getNodeName().replace(':',defaultSeparator); - if (helmaKey != null) { - // check if the mapping contains the prototype to which - // the property should be applied - int dot = helmaKey.indexOf ("."); - if (dot > -1) { - String prototype = helmaKey.substring (0, dot); - INode node = (INode) nodeCache.get (prototype); - if (node != null) { - node.setString (helmaKey.substring(dot+1), attr.getNodeValue()); - } - } else if (helmaNode.getPrototype() != null) { - helmaNode.setString( helmaKey, attr.getNodeValue() ); - } - } - } - return helmaNode; + private INode attributes(Element element, INode helmaNode, Map nodeCache) { + NamedNodeMap nnm = element.getAttributes(); + int len = nnm.getLength(); + + for (int i = 0; i < len; i++) { + org.w3c.dom.Node attr = nnm.item(i); + String helmaKey = props.getProperty(element.getNodeName() + "._attribute." + + attr.getNodeName()); + + // unless we only map explicit attributes, use attribute name as property name + // in case no property name was defined. + if ((helmaKey == null) && !sparse) { + helmaKey = attr.getNodeName().replace(':', defaultSeparator); + } + + if (helmaKey != null) { + // check if the mapping contains the prototype to which + // the property should be applied + int dot = helmaKey.indexOf("."); + + if (dot > -1) { + String prototype = helmaKey.substring(0, dot); + INode node = (INode) nodeCache.get(prototype); + + if (node != null) { + node.setString(helmaKey.substring(dot + 1), attr.getNodeValue()); + } + } else if (helmaNode.getPrototype() != null) { + helmaNode.setString(helmaKey, attr.getNodeValue()); + } + } + } + + return helmaNode; } /** * utility function */ - private void extractProperties( Properties props ) { - if ( props.containsKey("separator") ) { - defaultSeparator = props.getProperty("separator").charAt(0); - } - sparse = "sparse".equalsIgnoreCase (props.getProperty("_mode")); - } + private void extractProperties(Properties props) { + if (props.containsKey("separator")) { + defaultSeparator = props.getProperty("separator").charAt(0); + } + sparse = "sparse".equalsIgnoreCase(props.getProperty("_mode")); + } /** for testing */ void debug(Object msg) { - for ( int i=0; i<offset; i++ ) { - System.out.print(" "); - } - System.out.println(msg.toString()); + for (int i = 0; i < offset; i++) { + System.out.print(" "); + } + + System.out.println(msg.toString()); } - - public static void main ( String args[] ) { + /** + * + * + * @param args ... + */ + public static void main(String[] args) { } - - } - diff --git a/src/helma/objectmodel/dom/XmlDatabaseReader.java b/src/helma/objectmodel/dom/XmlDatabaseReader.java index 73db07c2..650b9a9f 100644 --- a/src/helma/objectmodel/dom/XmlDatabaseReader.java +++ b/src/helma/objectmodel/dom/XmlDatabaseReader.java @@ -1,189 +1,263 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel.dom; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; - -import java.text.SimpleDateFormat; -import java.text.ParseException; -import java.util.Date; -// import java.util.HashMap; -import java.util.Hashtable; -import java.util.List; - -import javax.xml.parsers.*; - -import org.xml.sax.*; -import org.xml.sax.helpers.DefaultHandler; - import helma.objectmodel.INode; import helma.objectmodel.db.DbKey; +import helma.objectmodel.db.DbMapping; import helma.objectmodel.db.ExternalizableVector; import helma.objectmodel.db.Node; import helma.objectmodel.db.NodeHandle; import helma.objectmodel.db.NodeManager; import helma.objectmodel.db.Property; -import helma.objectmodel.db.DbMapping; +import org.xml.sax.*; +import org.xml.sax.helpers.DefaultHandler; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +// import java.util.HashMap; +import java.util.Hashtable; +import java.util.List; +import javax.xml.parsers.*; + +/** + * + */ public final class XmlDatabaseReader extends DefaultHandler implements XmlConstants { - + static SAXParserFactory factory = SAXParserFactory.newInstance(); private NodeManager nmgr = null; private Node currentNode; - private String elementType = null; private String elementName = null; private StringBuffer charBuffer = null; - Hashtable propMap = null; List subnodes = null; - static SAXParserFactory factory = SAXParserFactory.newInstance (); - - - public XmlDatabaseReader (NodeManager nmgr) { - this.nmgr = nmgr; + /** + * Creates a new XmlDatabaseReader object. + * + * @param nmgr ... + */ + public XmlDatabaseReader(NodeManager nmgr) { + this.nmgr = nmgr; } - /** * read an InputSource with xml-content. */ - public Node read (File file) - throws ParserConfigurationException, SAXException, IOException { - if (nmgr==null) - throw new RuntimeException ("can't create a new Node without a NodeManager"); + public Node read(File file) + throws ParserConfigurationException, SAXException, IOException { + if (nmgr == null) { + throw new RuntimeException("can't create a new Node without a NodeManager"); + } - SAXParser parser = factory.newSAXParser (); + SAXParser parser = factory.newSAXParser(); - currentNode = null; + currentNode = null; - parser.parse (file, this); - return currentNode; + parser.parse(file, this); + + return currentNode; } + /** + * + * + * @param namespaceURI ... + * @param localName ... + * @param qName ... + * @param atts ... + */ + public void startElement(String namespaceURI, String localName, String qName, + Attributes atts) { + // System.err.println ("XML-READ: startElement "+namespaceURI+", "+localName+", "+qName+", "+atts.getValue("id")); + // discard the first element called xmlroot + if ("xmlroot".equals(qName) && (currentNode == null)) { + return; + } - public void startElement(String namespaceURI, String localName, String qName, Attributes atts) { - // System.err.println ("XML-READ: startElement "+namespaceURI+", "+localName+", "+qName+", "+atts.getValue("id")); - // discard the first element called xmlroot - if ("xmlroot".equals (qName) && currentNode == null) - return; - // if currentNode is null, this must be the hopobject node - if ("hopobject".equals (qName) && currentNode == null) { - String id = atts.getValue ("id"); - String name = atts.getValue ("name"); - String prototype = atts.getValue ("prototype"); - if ( "".equals(prototype) ) - prototype = "hopobject"; + // if currentNode is null, this must be the hopobject node + if ("hopobject".equals(qName) && (currentNode == null)) { + String id = atts.getValue("id"); + String name = atts.getValue("name"); + String prototype = atts.getValue("prototype"); - try { - long created = Long.parseLong (atts.getValue ("created")); - long lastmodified = Long.parseLong (atts.getValue ("lastModified")); - currentNode = new Node (name,id,prototype,nmgr.safe,created,lastmodified); - } catch ( NumberFormatException e ) { - currentNode = new Node (name,id,prototype,nmgr.safe); - } - return; - } - // find out what kind of element this is by looking at - // the number and names of attributes. - String idref = atts.getValue ("idref"); - if (idref != null) { - // a hopobject reference. - NodeHandle handle = makeNodeHandle (atts); - if ("hop:child".equals (qName)) { - if (subnodes == null) { - subnodes = new ExternalizableVector (); - currentNode.setSubnodes (subnodes); - } - subnodes.add (handle); - } else if ("hop:parent".equals (qName)) { - currentNode.setParentHandle (handle); - } else { - // property name may be encoded as "propertyname" attribute, - // otherwise it is the element name - String propName = atts.getValue ("propertyname"); - if (propName == null) - propName = qName; - Property prop = new Property (propName, currentNode); - prop.setNodeHandle (handle); - if (propMap == null) { - propMap = new Hashtable (); - currentNode.setPropMap (propMap); - } - propMap.put (propName.toLowerCase(), prop); - } - } else { - // a primitive property - elementType = atts.getValue ("type"); - if (elementType == null) - elementType = "string"; - // property name may be encoded as "propertyname" attribute, - // otherwise it is the element name - elementName = atts.getValue ("propertyname"); - if (elementName == null) - elementName = qName; - if (charBuffer == null) - charBuffer = new StringBuffer(); - else - charBuffer.setLength (0); - } + if ("".equals(prototype)) { + prototype = "hopobject"; + } + + try { + long created = Long.parseLong(atts.getValue("created")); + long lastmodified = Long.parseLong(atts.getValue("lastModified")); + + currentNode = new Node(name, id, prototype, nmgr.safe, created, + lastmodified); + } catch (NumberFormatException e) { + currentNode = new Node(name, id, prototype, nmgr.safe); + } + + return; + } + + // find out what kind of element this is by looking at + // the number and names of attributes. + String idref = atts.getValue("idref"); + + if (idref != null) { + // a hopobject reference. + NodeHandle handle = makeNodeHandle(atts); + + if ("hop:child".equals(qName)) { + if (subnodes == null) { + subnodes = new ExternalizableVector(); + currentNode.setSubnodes(subnodes); + } + + subnodes.add(handle); + } else if ("hop:parent".equals(qName)) { + currentNode.setParentHandle(handle); + } else { + // property name may be encoded as "propertyname" attribute, + // otherwise it is the element name + String propName = atts.getValue("propertyname"); + + if (propName == null) { + propName = qName; + } + + Property prop = new Property(propName, currentNode); + + prop.setNodeHandle(handle); + + if (propMap == null) { + propMap = new Hashtable(); + currentNode.setPropMap(propMap); + } + + propMap.put(propName.toLowerCase(), prop); + } + } else { + // a primitive property + elementType = atts.getValue("type"); + + if (elementType == null) { + elementType = "string"; + } + + // property name may be encoded as "propertyname" attribute, + // otherwise it is the element name + elementName = atts.getValue("propertyname"); + + if (elementName == null) { + elementName = qName; + } + + if (charBuffer == null) { + charBuffer = new StringBuffer(); + } else { + charBuffer.setLength(0); + } + } } - public void characters (char[] ch, int start, int length) - throws SAXException { - // append chars to char buffer - if (elementType != null) - charBuffer.append (ch, start, length); + /** + * + * + * @param ch ... + * @param start ... + * @param length ... + * + * @throws SAXException ... + */ + public void characters(char[] ch, int start, int length) + throws SAXException { + // append chars to char buffer + if (elementType != null) { + charBuffer.append(ch, start, length); + } } + /** + * + * + * @param namespaceURI ... + * @param localName ... + * @param qName ... + * + * @throws SAXException ... + */ public void endElement(String namespaceURI, String localName, String qName) - throws SAXException { - if (elementType != null) { - Property prop = new Property (elementName, currentNode); - String charValue = charBuffer.toString (); - charBuffer.setLength (0); - if ( "boolean".equals (elementType) ) { - if ( "true".equals(charValue) ) { - prop.setBooleanValue(true); - } else { - prop.setBooleanValue(false); - } - } else if ( "date".equals(elementType) ) { - SimpleDateFormat format = new SimpleDateFormat ( DATEFORMAT ); - try { - Date date = format.parse(charValue); - prop.setDateValue (date); - } catch ( ParseException e ) { - prop.setStringValue (charValue); - } - } else if ( "float".equals(elementType) ) { - prop.setFloatValue ((new Double(charValue)).doubleValue()); - } else if ( "integer".equals(elementType) ) { - prop.setIntegerValue ((new Long(charValue)).longValue()); - } else { - prop.setStringValue (charValue); - } - if (propMap == null) { - propMap = new Hashtable (); - currentNode.setPropMap (propMap); - } - propMap.put (elementName.toLowerCase(), prop); - elementName = null; - elementType = null; - charValue = null; - } - } + throws SAXException { + if (elementType != null) { + Property prop = new Property(elementName, currentNode); + String charValue = charBuffer.toString(); + charBuffer.setLength(0); + + if ("boolean".equals(elementType)) { + if ("true".equals(charValue)) { + prop.setBooleanValue(true); + } else { + prop.setBooleanValue(false); + } + } else if ("date".equals(elementType)) { + SimpleDateFormat format = new SimpleDateFormat(DATEFORMAT); + + try { + Date date = format.parse(charValue); + + prop.setDateValue(date); + } catch (ParseException e) { + prop.setStringValue(charValue); + } + } else if ("float".equals(elementType)) { + prop.setFloatValue((new Double(charValue)).doubleValue()); + } else if ("integer".equals(elementType)) { + prop.setIntegerValue((new Long(charValue)).longValue()); + } else { + prop.setStringValue(charValue); + } + + if (propMap == null) { + propMap = new Hashtable(); + currentNode.setPropMap(propMap); + } + + propMap.put(elementName.toLowerCase(), prop); + elementName = null; + elementType = null; + charValue = null; + } + } // create a node handle from a node reference DOM element - private NodeHandle makeNodeHandle (Attributes atts) { - String idref = atts.getValue ("idref"); - String protoref = atts.getValue ("prototyperef"); - DbMapping dbmap = null; - if (protoref != null) - dbmap = nmgr.getDbMapping(protoref); - return new NodeHandle (new DbKey (dbmap, idref)); + private NodeHandle makeNodeHandle(Attributes atts) { + String idref = atts.getValue("idref"); + String protoref = atts.getValue("prototyperef"); + DbMapping dbmap = null; + + if (protoref != null) { + dbmap = nmgr.getDbMapping(protoref); + } + + return new NodeHandle(new DbKey(dbmap, idref)); } - } - diff --git a/src/helma/objectmodel/dom/XmlReader.java b/src/helma/objectmodel/dom/XmlReader.java index dd52123e..10ffbb73 100644 --- a/src/helma/objectmodel/dom/XmlReader.java +++ b/src/helma/objectmodel/dom/XmlReader.java @@ -1,226 +1,305 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel.dom; +import helma.objectmodel.INode; +import org.xml.sax.*; +import org.xml.sax.helpers.DefaultHandler; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.Reader; - -import java.text.SimpleDateFormat; import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Stack; - import javax.xml.parsers.*; -import org.xml.sax.*; -import org.xml.sax.helpers.DefaultHandler; - -import helma.objectmodel.INode; - +/** + * + */ public final class XmlReader extends DefaultHandler implements XmlConstants { - - private INode rootNode, currentNode; + static SAXParserFactory factory = SAXParserFactory.newInstance(); + private INode rootNode; + private INode currentNode; private Stack nodeStack; private HashMap convertedNodes; - private String elementType = null; private String elementName = null; private StringBuffer charBuffer = null; - - static SAXParserFactory factory = SAXParserFactory.newInstance (); - boolean parsingHopObject; - public XmlReader () { + /** + * Creates a new XmlReader object. + */ + public XmlReader() { } - /** * main entry to read an xml-file. */ - public INode read (File file, INode helmaNode) - throws ParserConfigurationException, SAXException, IOException { - try { - return read (new FileInputStream(file), helmaNode); - } catch (FileNotFoundException notfound) { - System.err.println ("couldn't find xml-file: " + file.getAbsolutePath ()); - return helmaNode; - } + public INode read(File file, INode helmaNode) + throws ParserConfigurationException, SAXException, IOException { + try { + return read(new FileInputStream(file), helmaNode); + } catch (FileNotFoundException notfound) { + System.err.println("couldn't find xml-file: " + file.getAbsolutePath()); + + return helmaNode; + } } /** * read an InputStream with xml-content. */ - public INode read (InputStream in, INode helmaNode) - throws ParserConfigurationException, SAXException, IOException { - return read (new InputSource (in), helmaNode); + public INode read(InputStream in, INode helmaNode) + throws ParserConfigurationException, SAXException, IOException { + return read(new InputSource(in), helmaNode); } /** * read an character reader with xml-content. */ - public INode read (Reader in, INode helmaNode) - throws ParserConfigurationException, SAXException, IOException { - return read (new InputSource (in), helmaNode); + public INode read(Reader in, INode helmaNode) + throws ParserConfigurationException, SAXException, IOException { + return read(new InputSource(in), helmaNode); } /** * read an InputSource with xml-content. */ - public INode read (InputSource in, INode helmaNode) - throws ParserConfigurationException, SAXException, IOException { - if (helmaNode==null) - throw new RuntimeException ("Can't create a new Node without a root Node"); + public INode read(InputSource in, INode helmaNode) + throws ParserConfigurationException, SAXException, IOException { + if (helmaNode == null) { + throw new RuntimeException("Can't create a new Node without a root Node"); + } - SAXParser parser = factory.newSAXParser (); + SAXParser parser = factory.newSAXParser(); - rootNode = helmaNode; - currentNode = null; - convertedNodes = new HashMap (); - nodeStack = new Stack (); - parsingHopObject = true; + rootNode = helmaNode; + currentNode = null; + convertedNodes = new HashMap(); + nodeStack = new Stack(); + parsingHopObject = true; - parser.parse (in, this); - return rootNode; + parser.parse(in, this); + + return rootNode; } + /** + * + * + * @param namespaceURI ... + * @param localName ... + * @param qName ... + * @param atts ... + * + * @throws SAXException ... + */ + public void startElement(String namespaceURI, String localName, String qName, + Attributes atts) throws SAXException { + // System.err.println ("XML-READ: startElement "+namespaceURI+", "+localName+", "+qName+", "+atts.getValue("id")); + // discard the first element called xmlroot + if ("xmlroot".equals(qName) && (currentNode == null)) { + return; + } - public void startElement(String namespaceURI, String localName, String qName, Attributes atts) - throws SAXException { - // System.err.println ("XML-READ: startElement "+namespaceURI+", "+localName+", "+qName+", "+atts.getValue("id")); - // discard the first element called xmlroot - if ("xmlroot".equals (qName) && currentNode == null) - return; - // if currentNode is null, this must be the hopobject node - String id = atts.getValue ("id"); - if (id != null) { - // check if there is a current node. - if (currentNode == null) { - // If currentNode is null, this is the root node we're parsing. - currentNode = rootNode; - } else if ("hop:child".equals (qName)) { - // it's an anonymous child node - nodeStack.push (currentNode); - currentNode = currentNode.createNode (null); - } else { - // it's a named node property - nodeStack.push (currentNode); - // property name may be encoded as "propertyname" attribute, - // otherwise it is the element name - String propName = atts.getValue ("propertyname"); - if (propName == null) - propName = qName; - currentNode = currentNode.createNode (propName); - } - // set the prototype on the current node and - // add it to the map of parsed nodes. - String prototype = atts.getValue ("prototype"); - if ( !"".equals(prototype) && !"hopobject".equals(prototype) ) - currentNode.setPrototype (prototype); - String key = id + "-" + prototype; - convertedNodes.put( key, currentNode ); - return; - } + // if currentNode is null, this must be the hopobject node + String id = atts.getValue("id"); - // check if we have a currentNode to set properties on, - // otherwise throw exception. - if (currentNode == null) - throw new SAXException ("Invalid XML: No valid root HopObject found"); - // check if we are inside a HopObject - otherwise throw an exception - if (!parsingHopObject) - throw new SAXException ("Invalid XML: Found nested non-HobObject elements"); + if (id != null) { + // check if there is a current node. + if (currentNode == null) { + // If currentNode is null, this is the root node we're parsing. + currentNode = rootNode; + } else if ("hop:child".equals(qName)) { + // it's an anonymous child node + nodeStack.push(currentNode); + currentNode = currentNode.createNode(null); + } else { + // it's a named node property + nodeStack.push(currentNode); - // if we got so far, the element is not a hopobject. Set flag to prevent - // the hopobject stack to be popped when the element - // is closed. - parsingHopObject = false; + // property name may be encoded as "propertyname" attribute, + // otherwise it is the element name + String propName = atts.getValue("propertyname"); - // Is it a reference to an already parsed node? - String idref = atts.getValue ("idref"); - if (idref != null) { - // a reference to a node that should have been parsed - // and lying in our cache of parsed nodes. - String prototyperef = atts.getValue ("prototyperef"); - String key = idref + "-" + prototyperef; - INode n = (INode) convertedNodes.get (key); - if (n != null) { - if ("hop:child".equals (qName)) { - // add an already parsed node as child to current node - currentNode.addNode (n); - } else { - // set an already parsed node as node property to current node - // property name may be encoded as "propertyname" attribute, - // otherwise it is the element name - String propName = atts.getValue ("propertyname"); - if (propName == null) - propName = qName; - currentNode.setNode (propName, n); - } - } - } else { - // It's a primitive property. Remember the property name and type - // so we can properly parse/interpret the character data when we - // get it later on. - elementType = atts.getValue ("type"); - if (elementType == null) - elementType = "string"; - // property name may be encoded as "propertyname" attribute, - // otherwise it is the element name - elementName = atts.getValue ("propertyname"); - if (elementName == null) - elementName = qName; - if (charBuffer == null) - charBuffer = new StringBuffer(); - else - charBuffer.setLength (0); - } + if (propName == null) { + propName = qName; + } + + currentNode = currentNode.createNode(propName); + } + + // set the prototype on the current node and + // add it to the map of parsed nodes. + String prototype = atts.getValue("prototype"); + + if (!"".equals(prototype) && !"hopobject".equals(prototype)) { + currentNode.setPrototype(prototype); + } + + String key = id + "-" + prototype; + + convertedNodes.put(key, currentNode); + + return; + } + + // check if we have a currentNode to set properties on, + // otherwise throw exception. + if (currentNode == null) { + throw new SAXException("Invalid XML: No valid root HopObject found"); + } + + // check if we are inside a HopObject - otherwise throw an exception + if (!parsingHopObject) { + throw new SAXException("Invalid XML: Found nested non-HobObject elements"); + } + + // if we got so far, the element is not a hopobject. Set flag to prevent + // the hopobject stack to be popped when the element + // is closed. + parsingHopObject = false; + + // Is it a reference to an already parsed node? + String idref = atts.getValue("idref"); + + if (idref != null) { + // a reference to a node that should have been parsed + // and lying in our cache of parsed nodes. + String prototyperef = atts.getValue("prototyperef"); + String key = idref + "-" + prototyperef; + INode n = (INode) convertedNodes.get(key); + + if (n != null) { + if ("hop:child".equals(qName)) { + // add an already parsed node as child to current node + currentNode.addNode(n); + } else { + // set an already parsed node as node property to current node + // property name may be encoded as "propertyname" attribute, + // otherwise it is the element name + String propName = atts.getValue("propertyname"); + + if (propName == null) { + propName = qName; + } + + currentNode.setNode(propName, n); + } + } + } else { + // It's a primitive property. Remember the property name and type + // so we can properly parse/interpret the character data when we + // get it later on. + elementType = atts.getValue("type"); + + if (elementType == null) { + elementType = "string"; + } + + // property name may be encoded as "propertyname" attribute, + // otherwise it is the element name + elementName = atts.getValue("propertyname"); + + if (elementName == null) { + elementName = qName; + } + + if (charBuffer == null) { + charBuffer = new StringBuffer(); + } else { + charBuffer.setLength(0); + } + } } - public void characters (char[] ch, int start, int length) throws SAXException { - // System.err.println ("CHARACTERS: "+new String (ch, start, length)); - // append chars to char buffer - if (elementType != null) - charBuffer.append (ch, start, length); + /** + * + * + * @param ch ... + * @param start ... + * @param length ... + * + * @throws SAXException ... + */ + public void characters(char[] ch, int start, int length) + throws SAXException { + // System.err.println ("CHARACTERS: "+new String (ch, start, length)); + // append chars to char buffer + if (elementType != null) { + charBuffer.append(ch, start, length); + } } + /** + * + * + * @param namespaceURI ... + * @param localName ... + * @param qName ... + * + * @throws SAXException ... + */ public void endElement(String namespaceURI, String localName, String qName) - throws SAXException { - if (elementType != null) { - String charValue = charBuffer.toString (); - charBuffer.setLength (0); - if ( "boolean".equals (elementType) ) { - if ( "true".equals(charValue) ) { - currentNode.setBoolean(elementName, true); - } else { - currentNode.setBoolean(elementName, false); - } - } else if ( "date".equals(elementType) ) { - SimpleDateFormat format = new SimpleDateFormat ( DATEFORMAT ); - try { - Date date = format.parse(charValue); - currentNode.setDate (elementName, date); - } catch ( ParseException e ) { - currentNode.setString (elementName, charValue); - } - } else if ( "float".equals(elementType) ) { - currentNode.setFloat (elementName, (new Double(charValue)).doubleValue()); - } else if ( "integer".equals(elementType) ) { - currentNode.setInteger (elementName, (new Long(charValue)).longValue()); - } else { - currentNode.setString (elementName, charValue); - } - elementName = null; - elementType = null; - charValue = null; - } - if (parsingHopObject && !nodeStack.isEmpty ()) - currentNode = (INode) nodeStack.pop (); - else - parsingHopObject = true; // the next element end tag closes a hopobject again + throws SAXException { + if (elementType != null) { + String charValue = charBuffer.toString(); + + charBuffer.setLength(0); + + if ("boolean".equals(elementType)) { + if ("true".equals(charValue)) { + currentNode.setBoolean(elementName, true); + } else { + currentNode.setBoolean(elementName, false); + } + } else if ("date".equals(elementType)) { + SimpleDateFormat format = new SimpleDateFormat(DATEFORMAT); + + try { + Date date = format.parse(charValue); + + currentNode.setDate(elementName, date); + } catch (ParseException e) { + currentNode.setString(elementName, charValue); + } + } else if ("float".equals(elementType)) { + currentNode.setFloat(elementName, (new Double(charValue)).doubleValue()); + } else if ("integer".equals(elementType)) { + currentNode.setInteger(elementName, (new Long(charValue)).longValue()); + } else { + currentNode.setString(elementName, charValue); + } + + elementName = null; + elementType = null; + charValue = null; + } + + if (parsingHopObject && !nodeStack.isEmpty()) { + currentNode = (INode) nodeStack.pop(); + } else { + parsingHopObject = true; // the next element end tag closes a hopobject again + } } - } - diff --git a/src/helma/objectmodel/dom/XmlUtil.java b/src/helma/objectmodel/dom/XmlUtil.java index bd7bb63d..78c50b39 100644 --- a/src/helma/objectmodel/dom/XmlUtil.java +++ b/src/helma/objectmodel/dom/XmlUtil.java @@ -1,109 +1,161 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel.dom; -import java.io.InputStream; -import java.io.IOException; -import java.util.WeakHashMap; - -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.ParserConfigurationException; - +import helma.objectmodel.INode; +import helma.objectmodel.TransientNode; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import java.io.IOException; +import java.io.InputStream; +import java.util.WeakHashMap; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; -import helma.objectmodel.INode; -import helma.objectmodel.TransientNode; +/** + * + */ +public class XmlUtil { + private static final DocumentBuilderFactory domBuilderFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance(); + private static final WeakHashMap domBuilders = new WeakHashMap(); -public class XmlUtil { + private static synchronized DocumentBuilder getDocumentBuilder() { + DocumentBuilder domBuilder = (DocumentBuilder) domBuilders.get(Thread.currentThread()); - private static final DocumentBuilderFactory domBuilderFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance(); - private static final WeakHashMap domBuilders = new WeakHashMap(); + if (domBuilder != null) { + return domBuilder; + } else { + try { + domBuilder = domBuilderFactory.newDocumentBuilder(); + domBuilders.put(Thread.currentThread(), domBuilder); - private static synchronized DocumentBuilder getDocumentBuilder() { - DocumentBuilder domBuilder = (DocumentBuilder) domBuilders.get (Thread.currentThread()); - if (domBuilder != null) { - return domBuilder; - } else { - try { - domBuilder = domBuilderFactory.newDocumentBuilder(); - domBuilders.put (Thread.currentThread(), domBuilder); - return domBuilder; - } catch ( ParserConfigurationException e ) { - throw new RuntimeException ("Cannot build parser: "+e.toString()); - } - } - } + return domBuilder; + } catch (ParserConfigurationException e) { + throw new RuntimeException("Cannot build parser: " + e.toString()); + } + } + } - public static Document newDocument() { - DocumentBuilder d = getDocumentBuilder(); - return d.newDocument(); - } + /** + * + * + * @return ... + */ + public static Document newDocument() { + DocumentBuilder d = getDocumentBuilder(); - public static Document parse (InputStream in) throws RuntimeException { - DocumentBuilder d = getDocumentBuilder(); - try { - Document doc = d.parse (in); - doc.normalize(); - return doc; - } catch (SAXException e) { - throw new RuntimeException ("Bad xml-code: "+e.toString()); - } catch (IOException f) { - throw new RuntimeException ("Could not read Xml: "+f.toString()); - } - } + return d.newDocument(); + } - public static Document parse (InputSource in) throws RuntimeException { - DocumentBuilder d = getDocumentBuilder(); - try { - Document doc = d.parse (in); - doc.normalize(); - return doc; - } catch (SAXException e) { - throw new RuntimeException ("Bad xml-code: "+e.toString()); - } catch (IOException f) { - throw new RuntimeException ("Could not read Xml: "+f.toString()); - } - } + /** + * + * + * @param in ... + * + * @return ... + * + * @throws RuntimeException ... + */ + public static Document parse(InputStream in) throws RuntimeException { + DocumentBuilder d = getDocumentBuilder(); - /** - * get first "real" element (ie not the document-rootelement, but the next one - */ - public static Element getFirstElement (Document document) { - Element workelement = null; - if ( document.getDocumentElement()!=null ) { - org.w3c.dom.Node tmp = document.getDocumentElement().getFirstChild(); - while( tmp!=null ) { - tmp = tmp.getNextSibling(); - if ( tmp.getNodeType()==org.w3c.dom.Node.ELEMENT_NODE ) { - workelement = (Element) tmp; - break; - } - } - } - return workelement; - } + try { + Document doc = d.parse(in); - /** - * return the text content of an element - */ - public static String getTextContent( org.w3c.dom.Node element ) { - StringBuffer childtext = new StringBuffer(); - NodeList childlist = element.getChildNodes(); - int ct = childlist.getLength(); - for ( int j=0; j<ct; j++ ) { - org.w3c.dom.Node childNode = childlist.item(j); - if ( childNode.getNodeType() == Node.TEXT_NODE || - childNode.getNodeType() == Node.CDATA_SECTION_NODE) { - childtext.append(childNode.getNodeValue().trim() ); - } - } - return childtext.toString(); - } + doc.normalize(); + return doc; + } catch (SAXException e) { + throw new RuntimeException("Bad xml-code: " + e.toString()); + } catch (IOException f) { + throw new RuntimeException("Could not read Xml: " + f.toString()); + } + } + + /** + * + * + * @param in ... + * + * @return ... + * + * @throws RuntimeException ... + */ + public static Document parse(InputSource in) throws RuntimeException { + DocumentBuilder d = getDocumentBuilder(); + + try { + Document doc = d.parse(in); + + doc.normalize(); + + return doc; + } catch (SAXException e) { + throw new RuntimeException("Bad xml-code: " + e.toString()); + } catch (IOException f) { + throw new RuntimeException("Could not read Xml: " + f.toString()); + } + } + + /** + * get first "real" element (ie not the document-rootelement, but the next one + */ + public static Element getFirstElement(Document document) { + Element workelement = null; + + if (document.getDocumentElement() != null) { + org.w3c.dom.Node tmp = document.getDocumentElement().getFirstChild(); + + while (tmp != null) { + tmp = tmp.getNextSibling(); + + if (tmp.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) { + workelement = (Element) tmp; + + break; + } + } + } + + return workelement; + } + + /** + * return the text content of an element + */ + public static String getTextContent(org.w3c.dom.Node element) { + StringBuffer childtext = new StringBuffer(); + NodeList childlist = element.getChildNodes(); + int ct = childlist.getLength(); + + for (int j = 0; j < ct; j++) { + org.w3c.dom.Node childNode = childlist.item(j); + + if ((childNode.getNodeType() == Node.TEXT_NODE) || + (childNode.getNodeType() == Node.CDATA_SECTION_NODE)) { + childtext.append(childNode.getNodeValue().trim()); + } + } + + return childtext.toString(); + } } - diff --git a/src/helma/objectmodel/dom/XmlWriter.java b/src/helma/objectmodel/dom/XmlWriter.java index d31abeb6..52eba849 100644 --- a/src/helma/objectmodel/dom/XmlWriter.java +++ b/src/helma/objectmodel/dom/XmlWriter.java @@ -1,5 +1,30 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.objectmodel.dom; + +// import java.util.Set; +import helma.objectmodel.*; +import helma.objectmodel.INode; +import helma.objectmodel.IProperty; +import helma.objectmodel.TransientNode; +import helma.objectmodel.db.DbMapping; +import helma.objectmodel.db.Node; +import helma.util.HtmlEncoder; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; @@ -12,385 +37,498 @@ import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; -// import java.util.Set; - -import helma.objectmodel.*; -import helma.objectmodel.INode; -import helma.objectmodel.IProperty; -import helma.objectmodel.TransientNode; -import helma.objectmodel.db.Node; -import helma.objectmodel.db.DbMapping; -import helma.util.HtmlEncoder; +/** + * + */ public class XmlWriter extends OutputStreamWriter implements XmlConstants { + private final static String LINESEPARATOR = System.getProperty("line.separator"); + private static int fileid; + private Vector convertedNodes; + private int maxLevels = 3; + private String indent = " "; + private StringBuffer prefix = new StringBuffer(); + private SimpleDateFormat format = new SimpleDateFormat(DATEFORMAT); + private boolean dbmode = true; - private final static String LINESEPARATOR = System.getProperty("line.separator"); + // Only add encoding to XML declaration if it was explicitly set, not when we're using + // the platform's standard encoding. + private String explicitEncoding; - private Vector convertedNodes; - private int maxLevels = 3; + /** + * empty constructor, will use System.out as outputstream. + */ + public XmlWriter() { + super(System.out); + } - private String indent = " "; - private StringBuffer prefix = new StringBuffer(); + /** + * Creates a new XmlWriter object. + * + * @param out ... + */ + public XmlWriter(OutputStream out) { + super(out); + } - private static int fileid; - private SimpleDateFormat format = new SimpleDateFormat ( DATEFORMAT ); + /** + * Creates a new XmlWriter object. + * + * @param out ... + * @param enc ... + * + * @throws UnsupportedEncodingException ... + */ + public XmlWriter(OutputStream out, String enc) throws UnsupportedEncodingException { + super(out, enc); + explicitEncoding = enc; + } - private boolean dbmode = true; - - // Only add encoding to XML declaration if it was explicitly set, not when we're using - // the platform's standard encoding. - private String explicitEncoding; - - // Set of prototypes at which to stop writing. - // private Set stopTypes = null; + /** + * Creates a new XmlWriter object. + * + * @param desc ... + * + * @throws FileNotFoundException ... + */ + public XmlWriter(String desc) throws FileNotFoundException { + super(new FileOutputStream(desc)); + } - /** - * create ids that can be used for temporary files. - */ - public static int generateID() { - return fileid++; - } + /** + * Creates a new XmlWriter object. + * + * @param desc ... + * @param enc ... + * + * @throws FileNotFoundException ... + * @throws UnsupportedEncodingException ... + */ + public XmlWriter(String desc, String enc) + throws FileNotFoundException, UnsupportedEncodingException { + super(new FileOutputStream(desc), enc); + explicitEncoding = enc; + } - /** - * empty constructor, will use System.out as outputstream. - */ - public XmlWriter () { - super(System.out); - } + /** + * Creates a new XmlWriter object. + * + * @param file ... + * + * @throws FileNotFoundException ... + */ + public XmlWriter(File file) throws FileNotFoundException { + super(new FileOutputStream(file)); + } - public XmlWriter (OutputStream out) { - super(out); - } + /** + * Creates a new XmlWriter object. + * + * @param file ... + * @param enc ... + * + * @throws FileNotFoundException ... + * @throws UnsupportedEncodingException ... + */ + public XmlWriter(File file, String enc) + throws FileNotFoundException, UnsupportedEncodingException { + super(new FileOutputStream(file), enc); + explicitEncoding = enc; + } - public XmlWriter (OutputStream out, String enc) throws UnsupportedEncodingException { - super(out, enc); - explicitEncoding = enc; - } + // Set of prototypes at which to stop writing. + // private Set stopTypes = null; - public XmlWriter (String desc) throws FileNotFoundException { - super (new FileOutputStream (desc)); - } + /** + * create ids that can be used for temporary files. + */ + public static int generateID() { + return fileid++; + } - public XmlWriter (String desc, String enc) throws FileNotFoundException, UnsupportedEncodingException { - super (new FileOutputStream (desc), enc); - explicitEncoding = enc; - } + /** + * by default writing only descends 50 levels into the node tree to prevent + * infite loops. number can be changed here. + */ + public void setMaxLevels(int levels) { + maxLevels = levels; + } - public XmlWriter (File file) throws FileNotFoundException { - super (new FileOutputStream (file)); - } + /** + * + * + * @param dbmode ... + */ + public void setDatabaseMode(boolean dbmode) { + this.dbmode = dbmode; + } - public XmlWriter (File file, String enc) throws FileNotFoundException, UnsupportedEncodingException { - super (new FileOutputStream (file), enc); - explicitEncoding = enc; - } + /** + * Set a group of prototypes at which to stop XML serialization. + */ - /** - * by default writing only descends 50 levels into the node tree to prevent - * infite loops. number can be changed here. - */ - public void setMaxLevels (int levels) { - maxLevels = levels; - } + /* public void setStopTypes (Set set) { + this.stopTypes = set; + } */ - public void setDatabaseMode (boolean dbmode) { - this.dbmode = dbmode; - } + /** + * set the number of space chars + */ + public void setIndent(int ct) { + StringBuffer tmp = new StringBuffer(); - /** - * Set a group of prototypes at which to stop XML serialization. - */ - /* public void setStopTypes (Set set) { - this.stopTypes = set; - } */ + for (int i = 0; i < ct; i++) { + tmp.append(" "); + } - /** - * set the number of space chars - */ - public void setIndent (int ct) { - StringBuffer tmp = new StringBuffer (); - for ( int i=0; i<ct; i++ ) { - tmp.append(" "); - } - indent = tmp.toString(); - } + indent = tmp.toString(); + } - /** - * starting point for printing a node tree. - * creates document header too and initializes - * the cache of already converted nodes. - */ - public boolean write( INode node ) throws IOException { - convertedNodes = new Vector(); - if (explicitEncoding == null) - writeln ("<?xml version=\"1.0\"?>"); - else - writeln ("<?xml version=\"1.0\" encoding=\""+explicitEncoding+"\"?>"); - // writeln ("<!-- printed by helma object publisher -->"); - // writeln ("<!-- created " + (new Date()).toString() + " -->" ); - write ("<xmlroot xmlns:hop=\""); - write (NAMESPACE); - writeln ("\">"); - write (node, null, null, 0); - writeln ("</xmlroot>"); - convertedNodes = null; - return true; - } + /** + * starting point for printing a node tree. + * creates document header too and initializes + * the cache of already converted nodes. + */ + public boolean write(INode node) throws IOException { + convertedNodes = new Vector(); - /** - * write a hopobject and print all its properties and children. - * references are made here if a node already has been fully printed - * or if this is the last level that's going to be dumped - */ - public void write (INode node, String elementName, String propName, int level) throws IOException { - if (node==null) - return; - // if (stopTypes != null && stopTypes.contains (node.getPrototype())) - // return; - int previousLength = prefix.length(); - prefix.append(indent); - if ( ++level>maxLevels ) { - writeReferenceTag (node, elementName, propName); - prefix.setLength( previousLength ); - return; - } - if ( convertedNodes.contains(node) ) { - writeReferenceTag (node, elementName, propName); - } else { - convertedNodes.addElement (node); - writeTagOpen (node, elementName, propName); - INode parent = node.getParent (); - if ( parent!=null ) { - writeReferenceTag (parent, "hop:parent", null); - } - writeProperties (node, level); - writeChildren (node, level); - writeTagClose (elementName); - } - prefix.setLength( previousLength ); - } + if (explicitEncoding == null) { + writeln("<?xml version=\"1.0\"?>"); + } else { + writeln("<?xml version=\"1.0\" encoding=\"" + explicitEncoding + "\"?>"); + } + // writeln ("<!-- printed by helma object publisher -->"); + // writeln ("<!-- created " + (new Date()).toString() + " -->" ); + write("<xmlroot xmlns:hop=\""); + write(NAMESPACE); + writeln("\">"); + write(node, null, null, 0); + writeln("</xmlroot>"); + convertedNodes = null; + return true; + } - /** - * loop through properties and print them with their property-name - * as elementname - */ - private void writeProperties (INode node, int level) throws IOException { - Enumeration e = null; - if ( dbmode==true && node instanceof helma.objectmodel.db.Node ) { - // a newly constructed db.Node doesn't have a propMap, - // but returns an enumeration of all it's db-mapped properties - Hashtable props = ((Node)node).getPropMap(); - if (props==null) - return; - e = props.keys(); - } else { - e = node.properties(); - } - while ( e.hasMoreElements() ) { - String key = (String)e.nextElement(); - IProperty prop = node.get(key); - if ( prop!=null ) { - boolean validName = isValidElementName (key); - String elementName, propName; - if (validName) { - elementName = key; - propName = null; - } else { - elementName = "property"; - propName = key; - } - int type = prop.getType(); - if( type==IProperty.NODE ) { - write (prop.getNodeValue(), elementName, propName, level); - } else { - writeProperty (prop, elementName, propName); - } - } - } - } + /** + * write a hopobject and print all its properties and children. + * references are made here if a node already has been fully printed + * or if this is the last level that's going to be dumped + */ + public void write(INode node, String elementName, String propName, int level) + throws IOException { + if (node == null) { + return; + } - /* public void writeNullProperty (String key) throws IOException { - write (prefix.toString()); - write (indent); - write ("<"); - write (key); - write (" type=\"null\"/>"); - write (LINESEPARATOR); - } */ + // if (stopTypes != null && stopTypes.contains (node.getPrototype())) + // return; + int previousLength = prefix.length(); - /** - * write a single property, set attribute type according to type, - * apply xml-encoding. - */ - public void writeProperty (IProperty property, String elementName, String propName) throws IOException { - int propType = property.getType(); - // we can't encode java objects in XML - if (propType == IProperty.JAVAOBJECT) - return; - write (prefix.toString()); - write (indent); - write ("<"); - write (elementName); - if (propName != null) { - write (" propertyname=\""); - write (HtmlEncoder.encodeXml (propName)); - write ("\""); - } - switch (propType) { - case IProperty.BOOLEAN: - write (" type=\"boolean\">"); - write (property.getStringValue()); - break; - case IProperty.FLOAT: - write (" type=\"float\">"); - write (property.getStringValue()); - break; - case IProperty.INTEGER: - write (" type=\"integer\">"); - write (property.getStringValue()); - break; - case IProperty.DATE: - write (" type=\"date\">"); - write ( format.format (property.getDateValue()) ); - break; - case IProperty.STRING: - write (">"); - String str = HtmlEncoder.encodeXml (property.getStringValue()); - if (str != null) - write ( str ); - } - write ("</"); - write (elementName); - write (">"); - write (LINESEPARATOR); - } + prefix.append(indent); - /** - * loop through the children-array and print them as <hop:child> - */ - private void writeChildren (INode node, int level) throws IOException { - if ( dbmode==true && node instanceof helma.objectmodel.db.Node ) { - Node dbNode = (Node)node; - DbMapping smap = dbNode.getDbMapping() == null ? null : dbNode.getDbMapping().getSubnodeMapping (); - if (smap != null && smap.isRelational ()) - return; - } - Enumeration e = node.getSubnodes(); - while (e.hasMoreElements()) { - INode nextNode = (INode)e.nextElement(); - write (nextNode, "hop:child", null, level); - } - } + if (++level > maxLevels) { + writeReferenceTag(node, elementName, propName); + prefix.setLength(previousLength); - /** - * write an opening tag for a node. Include id and prototype, use a - * name if parameter is non-empty. - */ - public void writeTagOpen (INode node, String name, String propName) throws IOException { - write (prefix.toString()); - write ("<"); - write ( (name==null)?"hopobject" : name); - write (" id=\""); - write (getNodeIdentifier(node)); - if (propName != null) { - write ("\" propertyname=\""); - write (HtmlEncoder.encodeXml (propName)); - } - write ("\" name=\""); - write (node.getName()); - write ("\" prototype=\""); - write (getNodePrototype(node)); - write ("\" created=\""); - write (Long.toString(node.created())); - write ("\" lastModified=\""); - write (Long.toString(node.lastModified())); - //FIXME: do we need anonymous-property? - write ("\">"); - write (LINESEPARATOR); - } + return; + } - /** - * write a closing tag for a node - * e.g. </root> - */ - public void writeTagClose (String name) throws IOException { - write (prefix.toString()); - write ("</"); - write ( (name==null)?"hopobject" : name); - write (">"); - write (LINESEPARATOR); - } + if (convertedNodes.contains(node)) { + writeReferenceTag(node, elementName, propName); + } else { + convertedNodes.addElement(node); + writeTagOpen(node, elementName, propName); - /** - * write a tag holding a reference to an element that has - * been written out before. - * e.g. <parent idref="35" prototyperef="hopobject"/> - */ - public void writeReferenceTag (INode node, String name, String propName) throws IOException { - write (prefix.toString()); - write ("<"); - write ( (name==null)?"hopobject" : name); - write ( " idref=\""); - write (getNodeIdentifier(node)); - if (propName != null) { - write ("\" propertyname=\""); - write (HtmlEncoder.encodeXml (propName)); - } - write ("\" prototyperef=\""); - write (getNodePrototype(node)); - write ("\"/>"); - write (LINESEPARATOR); - } + INode parent = node.getParent(); - /** - * retrieve prototype-string of a node, defaults to "hopobject" - */ - private String getNodePrototype( INode node ) { - if ( node.getPrototype()==null || "".equals(node.getPrototype()) ) { - return "hopobject"; - } else { - return node.getPrototype(); - } - } + if (parent != null) { + writeReferenceTag(parent, "hop:parent", null); + } - /** - * TransientNode produces a different ID each time we call the getID()-method - * this is a workaround and uses hashCode if INode stands for a TransientNode. - */ - private String getNodeIdentifier( INode node ) { - try { - TransientNode tmp = (TransientNode)node; - return Integer.toString( tmp.hashCode() ); - } catch ( ClassCastException e ) { - return node.getID(); - } - } + writeProperties(node, level); + writeChildren(node, level); + writeTagClose(elementName); + } - public void writeln(String str) throws IOException { - write (str); - write (LINESEPARATOR); - } + prefix.setLength(previousLength); + } - - /** - * Check if a string is usable as XML element name. If not, the name - * will be appended as attribute to the XML element. We are - * conservative here, preferring to return false rather too often than - * not enough. - */ - private boolean isValidElementName (String str) { - char c = str.charAt (0); - if (!Character.isLetter(c)) - return false; - int l = str.length(); - for (int i=1; i<l; i++) { - c = str.charAt (i); - if (!Character.isLetterOrDigit(c) && c != '-' && c != '_') - return false; - } - return true; - } + /** + * loop through properties and print them with their property-name + * as elementname + */ + private void writeProperties(INode node, int level) + throws IOException { + Enumeration e = null; + + if ((dbmode == true) && node instanceof helma.objectmodel.db.Node) { + // a newly constructed db.Node doesn't have a propMap, + // but returns an enumeration of all it's db-mapped properties + Hashtable props = ((Node) node).getPropMap(); + + if (props == null) { + return; + } + + e = props.keys(); + } else { + e = node.properties(); + } + + while (e.hasMoreElements()) { + String key = (String) e.nextElement(); + IProperty prop = node.get(key); + + if (prop != null) { + boolean validName = isValidElementName(key); + String elementName; + String propName; + + if (validName) { + elementName = key; + propName = null; + } else { + elementName = "property"; + propName = key; + } + + int type = prop.getType(); + + if (type == IProperty.NODE) { + write(prop.getNodeValue(), elementName, propName, level); + } else { + writeProperty(prop, elementName, propName); + } + } + } + } + + /* public void writeNullProperty (String key) throws IOException { + write (prefix.toString()); + write (indent); + write ("<"); + write (key); + write (" type=\"null\"/>"); + write (LINESEPARATOR); + } */ + + /** + * write a single property, set attribute type according to type, + * apply xml-encoding. + */ + public void writeProperty(IProperty property, String elementName, String propName) + throws IOException { + int propType = property.getType(); + + // we can't encode java objects in XML + if (propType == IProperty.JAVAOBJECT) { + return; + } + + write(prefix.toString()); + write(indent); + write("<"); + write(elementName); + + if (propName != null) { + write(" propertyname=\""); + write(HtmlEncoder.encodeXml(propName)); + write("\""); + } + + switch (propType) { + case IProperty.BOOLEAN: + write(" type=\"boolean\">"); + write(property.getStringValue()); + + break; + + case IProperty.FLOAT: + write(" type=\"float\">"); + write(property.getStringValue()); + + break; + + case IProperty.INTEGER: + write(" type=\"integer\">"); + write(property.getStringValue()); + + break; + + case IProperty.DATE: + write(" type=\"date\">"); + write(format.format(property.getDateValue())); + + break; + + case IProperty.STRING: + write(">"); + + String str = HtmlEncoder.encodeXml(property.getStringValue()); + + if (str != null) { + write(str); + } + } + + write("</"); + write(elementName); + write(">"); + write(LINESEPARATOR); + } + + /** + * loop through the children-array and print them as <hop:child> + */ + private void writeChildren(INode node, int level) throws IOException { + if ((dbmode == true) && node instanceof helma.objectmodel.db.Node) { + Node dbNode = (Node) node; + DbMapping smap = (dbNode.getDbMapping() == null) ? null + : dbNode.getDbMapping() + .getSubnodeMapping(); + + if ((smap != null) && smap.isRelational()) { + return; + } + } + + Enumeration e = node.getSubnodes(); + + while (e.hasMoreElements()) { + INode nextNode = (INode) e.nextElement(); + + write(nextNode, "hop:child", null, level); + } + } + + /** + * write an opening tag for a node. Include id and prototype, use a + * name if parameter is non-empty. + */ + public void writeTagOpen(INode node, String name, String propName) + throws IOException { + write(prefix.toString()); + write("<"); + write((name == null) ? "hopobject" : name); + write(" id=\""); + write(getNodeIdentifier(node)); + + if (propName != null) { + write("\" propertyname=\""); + write(HtmlEncoder.encodeXml(propName)); + } + + write("\" name=\""); + write(node.getName()); + write("\" prototype=\""); + write(getNodePrototype(node)); + write("\" created=\""); + write(Long.toString(node.created())); + write("\" lastModified=\""); + write(Long.toString(node.lastModified())); + + //FIXME: do we need anonymous-property? + write("\">"); + write(LINESEPARATOR); + } + + /** + * write a closing tag for a node + * e.g. </root> + */ + public void writeTagClose(String name) throws IOException { + write(prefix.toString()); + write("</"); + write((name == null) ? "hopobject" : name); + write(">"); + write(LINESEPARATOR); + } + + /** + * write a tag holding a reference to an element that has + * been written out before. + * e.g. <parent idref="35" prototyperef="hopobject"/> + */ + public void writeReferenceTag(INode node, String name, String propName) + throws IOException { + write(prefix.toString()); + write("<"); + write((name == null) ? "hopobject" : name); + write(" idref=\""); + write(getNodeIdentifier(node)); + + if (propName != null) { + write("\" propertyname=\""); + write(HtmlEncoder.encodeXml(propName)); + } + + write("\" prototyperef=\""); + write(getNodePrototype(node)); + write("\"/>"); + write(LINESEPARATOR); + } + + /** + * retrieve prototype-string of a node, defaults to "hopobject" + */ + private String getNodePrototype(INode node) { + if ((node.getPrototype() == null) || "".equals(node.getPrototype())) { + return "hopobject"; + } else { + return node.getPrototype(); + } + } + + /** + * TransientNode produces a different ID each time we call the getID()-method + * this is a workaround and uses hashCode if INode stands for a TransientNode. + */ + private String getNodeIdentifier(INode node) { + try { + TransientNode tmp = (TransientNode) node; + + return Integer.toString(tmp.hashCode()); + } catch (ClassCastException e) { + return node.getID(); + } + } + + /** + * + * + * @param str ... + * + * @throws IOException ... + */ + public void writeln(String str) throws IOException { + write(str); + write(LINESEPARATOR); + } + + /** + * Check if a string is usable as XML element name. If not, the name + * will be appended as attribute to the XML element. We are + * conservative here, preferring to return false rather too often than + * not enough. + */ + private boolean isValidElementName(String str) { + char c = str.charAt(0); + + if (!Character.isLetter(c)) { + return false; + } + + int l = str.length(); + + for (int i = 1; i < l; i++) { + c = str.charAt(i); + + if (!Character.isLetterOrDigit(c) && (c != '-') && (c != '_')) { + return false; + } + } + + return true; + } } - diff --git a/src/helma/scripting/ActionFile.java b/src/helma/scripting/ActionFile.java index fa4e8c49..bb1e6957 100644 --- a/src/helma/scripting/ActionFile.java +++ b/src/helma/scripting/ActionFile.java @@ -1,15 +1,27 @@ -// ActionFile.java -// Copyright (c) Helma.org 1998-2002 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.scripting; -import java.util.Vector; -import java.util.Iterator; -import java.io.*; import helma.framework.*; import helma.framework.core.*; import helma.util.Updatable; - +import java.io.*; +import java.util.Iterator; +import java.util.Vector; /** * An ActionFile is a file containing function code that is exposed as a URI @@ -17,114 +29,178 @@ import helma.util.Updatable; * usually represented by a file with extension .hac (hop action file) * that contains the raw body of the function. */ - - public class ActionFile implements Updatable { - - String name, sourceName; + String name; + String sourceName; Prototype prototype; Application app; File file; String content; long lastmod; - - public ActionFile (File file, String name, Prototype proto) { - this.prototype = proto; - this.app = proto.getApplication (); - this.name = name; - this.sourceName = file.getParentFile().getName()+"/"+file.getName(); - this.file = file; - this.lastmod = file.lastModified (); - this.content = null; + /** + * Creates a new ActionFile object. + * + * @param file ... + * @param name ... + * @param proto ... + */ + public ActionFile(File file, String name, Prototype proto) { + this.prototype = proto; + this.app = proto.getApplication(); + this.name = name; + this.sourceName = file.getParentFile().getName() + "/" + file.getName(); + this.file = file; + this.lastmod = file.lastModified(); + this.content = null; } - public ActionFile (String content, String name, String sourceName, Prototype proto) { - this.prototype = proto; - this.app = proto.getApplication (); - this.name = name; - this.sourceName = sourceName; - this.file = null; - this.content = content; + /** + * Creates a new ActionFile object. + * + * @param content ... + * @param name ... + * @param sourceName ... + * @param proto ... + */ + public ActionFile(String content, String name, String sourceName, Prototype proto) { + this.prototype = proto; + this.app = proto.getApplication(); + this.name = name; + this.sourceName = sourceName; + this.file = null; + this.content = content; } - /** * Tell the type manager whether we need an update. this is the case when * the file has been modified or deleted. */ - public boolean needsUpdate () { - return lastmod != file.lastModified (); + public boolean needsUpdate() { + return lastmod != file.lastModified(); } - - public void update () { - if (!file.exists ()) { - // remove functions declared by this from all object prototypes - remove (); - } else { - lastmod = file.lastModified (); - } + /** + * + */ + public void update() { + if (!file.exists()) { + // remove functions declared by this from all object prototypes + remove(); + } else { + lastmod = file.lastModified(); + } } - public void remove () { - prototype.removeActionFile (this); + /** + * + */ + public void remove() { + prototype.removeActionFile(this); } - public File getFile () { - return file; + /** + * + * + * @return ... + */ + public File getFile() { + return file; } - public String getName () { - return name; + /** + * + * + * @return ... + */ + public String getName() { + return name; } - public String getSourceName () { - return sourceName; + /** + * + * + * @return ... + */ + public String getSourceName() { + return sourceName; } - public Reader getReader () throws FileNotFoundException { - if (content != null) - return new StringReader (content); - else if (file.length() == 0) - return new StringReader(";"); - else - return new FileReader (file); + /** + * + * + * @return ... + * + * @throws FileNotFoundException ... + */ + public Reader getReader() throws FileNotFoundException { + if (content != null) { + return new StringReader(content); + } else if (file.length() == 0) { + return new StringReader(";"); + } else { + return new FileReader(file); + } } - public String getContent () { - if (content != null) - return content; - else { - try { - FileReader reader = new FileReader (file); - char cbuf[] = new char[(int) file.length ()]; - reader.read (cbuf); - reader.close (); - return new String (cbuf); - } catch (Exception filex) { - app.logEvent ("Error reading "+this+": "+filex); - return null; - } - } + /** + * + * + * @return ... + */ + public String getContent() { + if (content != null) { + return content; + } else { + try { + FileReader reader = new FileReader(file); + char[] cbuf = new char[(int) file.length()]; + + reader.read(cbuf); + reader.close(); + + return new String(cbuf); + } catch (Exception filex) { + app.logEvent("Error reading " + this + ": " + filex); + + return null; + } + } } - public String getFunctionName () { - return name + "_action"; + /** + * + * + * @return ... + */ + public String getFunctionName() { + return name + "_action"; } - public Prototype getPrototype () { - return prototype; + /** + * + * + * @return ... + */ + public Prototype getPrototype() { + return prototype; } - public Application getApplication () { - return app; + /** + * + * + * @return ... + */ + public Application getApplication() { + return app; } - public String toString () { - return "ActionFile["+sourceName+"]"; + /** + * + * + * @return ... + */ + public String toString() { + return "ActionFile[" + sourceName + "]"; } - } - - diff --git a/src/helma/scripting/FunctionFile.java b/src/helma/scripting/FunctionFile.java index f89095d8..5c271414 100644 --- a/src/helma/scripting/FunctionFile.java +++ b/src/helma/scripting/FunctionFile.java @@ -1,25 +1,34 @@ -// FunctionFile.java -// Copyright (c) Hannes Wallnöfer 1998-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.scripting; -import java.util.HashMap; -import java.util.Iterator; -import java.util.HashSet; -import java.util.Enumeration; -import java.io.*; import helma.framework.*; import helma.framework.core.*; import helma.util.Updatable; - +import java.io.*; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; /** * This represents a File containing script functions for a given class/prototype. */ - - public class FunctionFile implements Updatable { - Prototype prototype; Application app; File file; @@ -27,13 +36,18 @@ public class FunctionFile implements Updatable { String content; long lastmod; - - public FunctionFile (File file, Prototype proto) { - this.prototype = proto; - this.app = proto.getApplication (); - this.sourceName = file.getParentFile().getName()+"/"+file.getName(); - this.file = file; - update (); + /** + * Creates a new FunctionFile object. + * + * @param file ... + * @param proto ... + */ + public FunctionFile(File file, Prototype proto) { + this.prototype = proto; + this.app = proto.getApplication(); + this.sourceName = file.getParentFile().getName() + "/" + file.getName(); + this.file = file; + update(); } /** @@ -41,55 +55,75 @@ public class FunctionFile implements Updatable { * files contained in zipped applications. The whole update mechanism is bypassed * by immediately parsing the code. */ - public FunctionFile (String body, String sourceName, Prototype proto) { - this.prototype = proto; - this.app = proto.getApplication (); - this.sourceName = sourceName; - this.file = null; - this.content = body; + public FunctionFile(String body, String sourceName, Prototype proto) { + this.prototype = proto; + this.app = proto.getApplication(); + this.sourceName = sourceName; + this.file = null; + this.content = body; } /** * Tell the type manager whether we need an update. this is the case when * the file has been modified or deleted. */ - public boolean needsUpdate () { - return file != null && lastmod != file.lastModified (); + public boolean needsUpdate() { + return (file != null) && (lastmod != file.lastModified()); } - - public void update () { - if (file != null) { - if (!file.exists ()) { - remove (); - } else { - lastmod = file.lastModified (); - } - } + /** + * + */ + public void update() { + if (file != null) { + if (!file.exists()) { + remove(); + } else { + lastmod = file.lastModified(); + } + } } - public File getFile () { - return file; + /** + * + * + * @return ... + */ + public File getFile() { + return file; } - public String getContent () { - return content; + /** + * + * + * @return ... + */ + public String getContent() { + return content; } - public String getSourceName () { - return sourceName; + /** + * + * + * @return ... + */ + public String getSourceName() { + return sourceName; } - public void remove () { - prototype.removeFunctionFile (this); + /** + * + */ + public void remove() { + prototype.removeFunctionFile(this); } - - public String toString () { - return sourceName; + /** + * + * + * @return ... + */ + public String toString() { + return sourceName; } - - } - - diff --git a/src/helma/scripting/ScriptingEngine.java b/src/helma/scripting/ScriptingEngine.java index ef7ace4d..d9320a57 100644 --- a/src/helma/scripting/ScriptingEngine.java +++ b/src/helma/scripting/ScriptingEngine.java @@ -1,5 +1,18 @@ -// ScriptingEngine.java -// Copyright (c) Hannes Wallnöfer 1998-2001 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.scripting; @@ -7,73 +20,69 @@ import helma.framework.IPathElement; import helma.framework.core.Application; import helma.framework.core.Prototype; import helma.framework.core.RequestEvaluator; -import java.util.*; import java.io.File; +import java.util.*; /** * This is the interface that must be implemented to make a scripting environment * usable by the Helma application server. * - * Implementations of this interface must have a public zero-argument constructor + * Implementations of this interface must have a public zero-argument constructor * to be usable by the Helma framework. */ public interface ScriptingEngine { - - /** + /** * Init the scripting engine with an application and a request evaluator */ - public void init (Application app, RequestEvaluator reval); + public void init(Application app, RequestEvaluator reval); /** * This method is called before an execution context for a request - * evaluation is entered to let the Engine know it should update + * evaluation is entered to let the Engine know it should update * its prototype information */ - public void updatePrototypes (); + public void updatePrototypes(); /** * This method is called when an execution context for a request * evaluation is entered. The globals parameter contains the global values * to be applied during this execution context. */ - public void enterContext (HashMap globals) throws ScriptingException; + public void enterContext(HashMap globals) throws ScriptingException; /** * This method is called to let the scripting engine know that the current * execution context has terminated. */ - public void exitContext (); - + public void exitContext(); /** - * Invoke a function on some object, using the given arguments and global vars. + * Invoke a function on some object, using the given arguments and global vars. * XML-RPC calls require special input and output parameter conversion. */ - public Object invoke (Object thisObject, String functionName, Object[] args, boolean xmlrpc) - throws ScriptingException; + public Object invoke(Object thisObject, String functionName, Object[] args, + boolean xmlrpc) throws ScriptingException; /** * Let the evaluator know that the current evaluation has been aborted. */ - public void abort (); + public void abort(); /** * Get a property on an object */ - public Object get (Object thisObject, String key); + public Object get(Object thisObject, String key); /** * Return true if a function by that name is defined for that object. */ - public boolean hasFunction (Object thisObject, String functionName); + public boolean hasFunction(Object thisObject, String functionName); /** * Get an IPathElement that offers introspection services into the application. * If this method returns null, no introspection is available for this kind of engine. - * In order to be compatible with the standard Helma management application, this + * In order to be compatible with the standard Helma management application, this * class should be compatible with helma.doc.DocApplication. */ - public IPathElement getIntrospector (); - + public IPathElement getIntrospector(); } - diff --git a/src/helma/scripting/ScriptingException.java b/src/helma/scripting/ScriptingException.java index 4cedd7ff..0e9f6f28 100644 --- a/src/helma/scripting/ScriptingException.java +++ b/src/helma/scripting/ScriptingException.java @@ -1,67 +1,105 @@ -// ScriptingException.java -// Copyright (c) Hannes Wallnöfer 1998-2001 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.scripting; - -import java.io.PrintWriter; import java.io.PrintStream; +import java.io.PrintWriter; /** * The base class for exceptions thrown by Helma scripting package */ public class ScriptingException extends Exception { - Exception wrapped; /** * Construct a ScriptingException given an error message */ - public ScriptingException (String msg) { - super (msg); - wrapped = null; + public ScriptingException(String msg) { + super(msg); + wrapped = null; } /** * Construct a ScriptingException given an error message */ - public ScriptingException (Exception w) { - wrapped = w; + public ScriptingException(Exception w) { + wrapped = w; } - public String toString () { - if (wrapped == null) - return super.toString (); - else - return wrapped.toString (); + /** + * + * + * @return ... + */ + public String toString() { + if (wrapped == null) { + return super.toString(); + } else { + return wrapped.toString(); + } } - public String getMessage () { - if (wrapped == null) - return super.getMessage (); - else - return wrapped.getMessage (); + /** + * + * + * @return ... + */ + public String getMessage() { + if (wrapped == null) { + return super.getMessage(); + } else { + return wrapped.getMessage(); + } } - public void printStackTrace () { - if (wrapped == null) - super.printStackTrace (); - else - wrapped.printStackTrace (); + /** + * + */ + public void printStackTrace() { + if (wrapped == null) { + super.printStackTrace(); + } else { + wrapped.printStackTrace(); + } } - public void printStackTrace (PrintStream stream) { - if (wrapped == null) - super.printStackTrace (stream); - else - wrapped.printStackTrace (stream); + /** + * + * + * @param stream ... + */ + public void printStackTrace(PrintStream stream) { + if (wrapped == null) { + super.printStackTrace(stream); + } else { + wrapped.printStackTrace(stream); + } } - public void printStackTrace (PrintWriter writer) { - if (wrapped == null) - super.printStackTrace (writer); - else - wrapped.printStackTrace (writer); + /** + * + * + * @param writer ... + */ + public void printStackTrace(PrintWriter writer) { + if (wrapped == null) { + super.printStackTrace(writer); + } else { + wrapped.printStackTrace(writer); + } } - } diff --git a/src/helma/scripting/Template.java b/src/helma/scripting/Template.java index 490112cc..72aa5044 100644 --- a/src/helma/scripting/Template.java +++ b/src/helma/scripting/Template.java @@ -1,187 +1,239 @@ -// Template.java -// Copyright (c) Hannes Wallnöfer 1998-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.scripting; -import java.io.*; -import java.util.Vector; -import java.util.Iterator; -import java.util.StringTokenizer; import helma.framework.*; import helma.framework.core.*; - +import java.io.*; +import java.util.Iterator; +import java.util.StringTokenizer; +import java.util.Vector; /** * This represents a Helma template, i.e. a file with the extension .hsp * (Helma server page) that contains both parts that are to be evaluated * as EcmaScript and parts that are to be delivered to the client as-is. - * Internally, templates are regular functions. + * Internally, templates are regular functions. * Helma templates are callable via URL, but this is just a leftover from the * days when there were no .hac (action) files. The recommended way * now is to have a .hac file with all the logic which in turn calls one or more * template files to do the formatting. */ - public class Template extends ActionFile { - - - public Template (File file, String name, Prototype proto) { - super (file, name, proto); + /** + * Creates a new Template object. + * + * @param file ... + * @param name ... + * @param proto ... + */ + public Template(File file, String name, Prototype proto) { + super(file, name, proto); } - public Template (String content, String name, String sourceName, Prototype proto) { - super (content, name, sourceName, proto); + /** + * Creates a new Template object. + * + * @param content ... + * @param name ... + * @param sourceName ... + * @param proto ... + */ + public Template(String content, String name, String sourceName, Prototype proto) { + super(content, name, sourceName, proto); } - public String getFunctionName () { - return name; + /** + * + * + * @return ... + */ + public String getFunctionName() { + return name; } - public Reader getReader () { - return new StringReader(getContent()); + /** + * + * + * @return ... + */ + public Reader getReader() { + return new StringReader(getContent()); } - public String getContent () { + /** + * + * + * @return ... + */ + public String getContent() { + Vector partBuffer = new Vector(); + String cstring = super.getContent(); + char[] cnt = cstring.toCharArray(); + int l = cnt.length; - Vector partBuffer = new Vector (); - String cstring = super.getContent(); - char[] cnt = cstring.toCharArray (); - int l = cnt.length; - if (l == 0) - return ""; + if (l == 0) { + return ""; + } - // if last charackter is whitespace, swallow it. this is necessary for some inner templates to look ok. - if (Character.isWhitespace (cnt[l-1])) - l -= 1; + // if last charackter is whitespace, swallow it. this is necessary for some inner templates to look ok. + if (Character.isWhitespace(cnt[l - 1])) { + l -= 1; + } - int lastIdx = 0; - for (int i = 0; i < l-1; i++) { - if (cnt[i] == '<' && cnt[i+1] == '%') { - int j = i+2; - while (j < l-1 && (cnt[j] != '%' || cnt[j+1] != '>')) { - j++; - } - if (j > i+2) { - if (i - lastIdx > 0) - partBuffer.addElement (new Part (this, new String (cnt, lastIdx, i - lastIdx), true)); - String script = new String (cnt, i+2, (j-i)-2); - partBuffer.addElement (new Part (this, script, false)); - lastIdx = j+2; - } - i = j+1; - } - } - if (lastIdx < l) - partBuffer.addElement (new Part (this, new String (cnt, lastIdx, l - lastIdx), true)); + int lastIdx = 0; - StringBuffer templateBody = new StringBuffer (); - int nparts = partBuffer.size(); + for (int i = 0; i < (l - 1); i++) { + if ((cnt[i] == '<') && (cnt[i + 1] == '%')) { + int j = i + 2; - for (int k = 0; k < nparts; k++) { - Part nextPart = (Part) partBuffer.elementAt (k); + while ((j < (l - 1)) && ((cnt[j] != '%') || (cnt[j + 1] != '>'))) { + j++; + } - if (nextPart.isStatic || nextPart.content.trim ().startsWith ("=")) { - // check for <%= ... %> statements - if (!nextPart.isStatic) { - nextPart.content = nextPart.content.trim ().substring (1).trim (); - // cut trailing ";" - while (nextPart.content.endsWith (";")) - nextPart.content = nextPart.content.substring (0, nextPart.content.length()-1); - } + if (j > (i + 2)) { + if ((i - lastIdx) > 0) { + partBuffer.addElement(new Part(this, + new String(cnt, lastIdx, + i - lastIdx), true)); + } - StringTokenizer st = new StringTokenizer (nextPart.content, "\r\n", true); - String nextLine = st.hasMoreTokens () ? st.nextToken () : null; + String script = new String(cnt, i + 2, (j - i) - 2); - // count newLines we "swallow", see explanation below - int newLineCount = 0; + partBuffer.addElement(new Part(this, script, false)); + lastIdx = j + 2; + } - templateBody.append ("res.write ("); - if (nextPart.isStatic) { - templateBody.append ("\""); - } + i = j + 1; + } + } - while (nextLine != null) { + if (lastIdx < l) { + partBuffer.addElement(new Part(this, new String(cnt, lastIdx, l - lastIdx), + true)); + } - if ("\n".equals (nextLine)) { - // append a CRLF - newLineCount++; - templateBody.append ("\\r\\n"); - } else if (!"\r".equals (nextLine)) try { - StringReader lineReader = new StringReader (nextLine); - int c = lineReader.read (); - while (c > -1) { - if (nextPart.isStatic && ((char)c == '"' || (char)c == '\\')) { - templateBody.append ('\\'); - } - templateBody.append ((char) c); - c = lineReader.read (); - } - } catch (IOException srx) {} + StringBuffer templateBody = new StringBuffer(); + int nparts = partBuffer.size(); - nextLine = st.hasMoreTokens () ? st.nextToken () : null; + for (int k = 0; k < nparts; k++) { + Part nextPart = (Part) partBuffer.elementAt(k); - } + if (nextPart.isStatic || nextPart.content.trim().startsWith("=")) { + // check for <%= ... %> statements + if (!nextPart.isStatic) { + nextPart.content = nextPart.content.trim().substring(1).trim(); - if (nextPart.isStatic) { - templateBody.append ("\""); - } + // cut trailing ";" + while (nextPart.content.endsWith(";")) + nextPart.content = nextPart.content.substring(0, + nextPart.content.length() - + 1); + } - templateBody.append ("); "); + StringTokenizer st = new StringTokenizer(nextPart.content, "\r\n", true); + String nextLine = st.hasMoreTokens() ? st.nextToken() : null; - // append the number of lines we have "swallowed" into - // one write statement, so error messages will *approximately* - // give correct line numbers. - for (int i=0; i<newLineCount; i++) { - templateBody.append ("\r\n"); - } + // count newLines we "swallow", see explanation below + int newLineCount = 0; - } else { - templateBody.append (nextPart.content); - if (!nextPart.content.trim ().endsWith (";")) { - templateBody.append (";"); - } - } - } - // templateBody.append ("\r\nreturn null;\r\n"); + templateBody.append("res.write ("); - return templateBody.toString (); + if (nextPart.isStatic) { + templateBody.append("\""); + } + + while (nextLine != null) { + if ("\n".equals(nextLine)) { + // append a CRLF + newLineCount++; + templateBody.append("\\r\\n"); + } else if (!"\r".equals(nextLine)) { + try { + StringReader lineReader = new StringReader(nextLine); + int c = lineReader.read(); + + while (c > -1) { + if (nextPart.isStatic && + (((char) c == '"') || ((char) c == '\\'))) { + templateBody.append('\\'); + } + + templateBody.append((char) c); + c = lineReader.read(); + } + } catch (IOException srx) { + } + } + + nextLine = st.hasMoreTokens() ? st.nextToken() : null; + } + + if (nextPart.isStatic) { + templateBody.append("\""); + } + + templateBody.append("); "); + + // append the number of lines we have "swallowed" into + // one write statement, so error messages will *approximately* + // give correct line numbers. + for (int i = 0; i < newLineCount; i++) { + templateBody.append("\r\n"); + } + } else { + templateBody.append(nextPart.content); + + if (!nextPart.content.trim().endsWith(";")) { + templateBody.append(";"); + } + } + } + + // templateBody.append ("\r\nreturn null;\r\n"); + return templateBody.toString(); } - public void remove () { - prototype.removeTemplate (this); + /** + * + */ + public void remove() { + prototype.removeTemplate(this); } - - class Part { + String content; + Template parent; + boolean isPart; + boolean isStatic; - String content; - Template parent; - boolean isPart; - boolean isStatic; + public Part(Template parent, String content, boolean isStatic) { + isPart = false; + this.parent = parent; + this.content = content; + this.isStatic = isStatic; + } + public String getName() { + return isStatic ? null : content; + } - public Part (Template parent, String content, boolean isStatic) { - isPart = false; - this.parent = parent; - this.content = content; - this.isStatic = isStatic; - } - - public String getName () { - return isStatic ? null : content; - } - - - public String toString () { - return "Template.Part ["+content+","+isStatic+"]"; - } - + public String toString() { + return "Template.Part [" + content + "," + isStatic + "]"; + } } - } - - - - - diff --git a/src/helma/scripting/fesi/ESBeanWrapper.java b/src/helma/scripting/fesi/ESBeanWrapper.java index 35055157..f97daee2 100644 --- a/src/helma/scripting/fesi/ESBeanWrapper.java +++ b/src/helma/scripting/fesi/ESBeanWrapper.java @@ -1,65 +1,98 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.scripting.fesi; -import java.util.Map; - -import helma.framework.core.ApplicationBean; -import helma.objectmodel.INode; -import helma.util.SystemProperties; - -import FESI.Interpreter.Evaluator; -import FESI.Exceptions.EcmaScriptException; import FESI.Data.ESNull; import FESI.Data.ESValue; import FESI.Data.ESWrapper; +import FESI.Exceptions.EcmaScriptException; +import FESI.Interpreter.Evaluator; +import helma.framework.core.ApplicationBean; +import helma.objectmodel.INode; +import helma.util.SystemProperties; +import java.util.Map; /** * Wrap a Java Bean for use in EcmaScript. */ - public class ESBeanWrapper extends ESWrapper { - FesiEngine engine; - public ESBeanWrapper (Object object, FesiEngine engine) { - super (object, engine.getEvaluator(),true); - this.engine = engine; + /** + * Creates a new ESBeanWrapper object. + * + * @param object ... + * @param engine ... + */ + public ESBeanWrapper(Object object, FesiEngine engine) { + super(object, engine.getEvaluator(), true); + this.engine = engine; } - /** - * Wrap getProperty, return ESNode if INode would be returned, - * ESMapWrapper if Map would be returned. - */ - public ESValue getProperty(String propertyName, int hash) throws EcmaScriptException { - try { - ESValue val = super.getProperty (propertyName, hash); - if (val instanceof ESWrapper) { - Object theObject = ((ESWrapper)val).getJavaObject (); - if (val instanceof ESWrapper && theObject instanceof INode) { - return engine.getNodeWrapper ((INode) theObject); - } else if (val instanceof ESWrapper && theObject instanceof Map) { - ESMapWrapper wrapper = new ESMapWrapper(engine, (Map) theObject); - if (theObject instanceof SystemProperties && super.getJavaObject () instanceof ApplicationBean) - wrapper.setReadonly(true); - return wrapper; + /** + * Wrap getProperty, return ESNode if INode would be returned, + * ESMapWrapper if Map would be returned. + */ + public ESValue getProperty(String propertyName, int hash) + throws EcmaScriptException { + try { + ESValue val = super.getProperty(propertyName, hash); + + if (val instanceof ESWrapper) { + Object theObject = ((ESWrapper) val).getJavaObject(); + + if (val instanceof ESWrapper && theObject instanceof INode) { + return engine.getNodeWrapper((INode) theObject); + } else if (val instanceof ESWrapper && theObject instanceof Map) { + ESMapWrapper wrapper = new ESMapWrapper(engine, (Map) theObject); + + if (theObject instanceof SystemProperties && + super.getJavaObject() instanceof ApplicationBean) { + wrapper.setReadonly(true); + } + + return wrapper; + } } - } - return val; - } catch (Exception rte) { - return ESNull.theNull; - } - } - public void putProperty(String propertyName, ESValue propertyValue, int hash) throws EcmaScriptException { - try { - super.putProperty (propertyName, propertyValue, hash); - } catch (Exception rte) { - // create a nice error message - throw new EcmaScriptException("can't set property " + propertyName + - " to this value on " + getJavaObject().toString() ); - } + return val; + } catch (Exception rte) { + return ESNull.theNull; + } } + /** + * + * + * @param propertyName ... + * @param propertyValue ... + * @param hash ... + * + * @throws EcmaScriptException ... + */ + public void putProperty(String propertyName, ESValue propertyValue, int hash) + throws EcmaScriptException { + try { + super.putProperty(propertyName, propertyValue, hash); + } catch (Exception rte) { + // create a nice error message + throw new EcmaScriptException("can't set property " + propertyName + + " to this value on " + + getJavaObject().toString()); + } + } } - - - diff --git a/src/helma/scripting/fesi/ESGenericObject.java b/src/helma/scripting/fesi/ESGenericObject.java index c396bf74..6af94430 100644 --- a/src/helma/scripting/fesi/ESGenericObject.java +++ b/src/helma/scripting/fesi/ESGenericObject.java @@ -1,109 +1,236 @@ -// ESGenericObject.java -// Copyright (c) Hannes Wallnöfer 1998-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.scripting.fesi; -import helma.framework.core.*; -import helma.framework.IPathElement; -import FESI.Interpreter.*; -import FESI.Exceptions.*; import FESI.Data.*; +import FESI.Exceptions.*; +import FESI.Interpreter.*; +import helma.framework.IPathElement; +import helma.framework.core.*; import java.util.*; - /** - * A wrapper for a Java object that may or may not implement the IPathElement interface. - */ - + * A wrapper for a Java object that may or may not implement the IPathElement interface. + */ public class ESGenericObject extends ObjectPrototype { - ESWrapper wrapper; Object wrappedObject; - public ESGenericObject (ESObject prototype, Evaluator evaluator, Object obj) { - super (prototype, evaluator); - wrappedObject = obj; - wrapper = new ESWrapper (obj, evaluator); - } - - - public String getESClassName () { - return "GenericObject"; - } - - public String toString () { - return wrappedObject.toString (); - } - - public String toDetailString () { - return wrapper.toDetailString (); - } - - - public void putProperty(String propertyName, ESValue propertyValue, int hash) throws EcmaScriptException { - wrapper.putProperty (propertyName, propertyValue, hash); - } - - public boolean hasProperty(String propertyName, int hash) throws EcmaScriptException { - return super.hasProperty (propertyName, hash) || wrapper.hasProperty (propertyName, hash); - } - - public boolean deleteProperty(String propertyName, int hash) throws EcmaScriptException { - return wrapper.deleteProperty (propertyName, hash); - } - - public ESValue getProperty (int i) throws EcmaScriptException { - return wrapper.getProperty (i); - } - - public void putProperty(int index, ESValue propertyValue) throws EcmaScriptException { - wrapper.putProperty (index, propertyValue); - } - - - public ESValue getProperty(String propertyName, int hash) throws EcmaScriptException { - ESValue val = super.getProperty (propertyName, hash); - if (val == null || val == ESUndefined.theUndefined) - val = wrapper.getProperty (propertyName, hash); - return val; - } - - public ESValue doIndirectCall(Evaluator evaluator, ESObject thisObject, String functionName, ESValue[] arguments) - throws EcmaScriptException, NoSuchMethodException { - if (super.hasProperty (functionName, functionName.hashCode())) - return super.doIndirectCall (evaluator, thisObject, functionName, arguments); - return wrapper.doIndirectCall (evaluator, thisObject, functionName, arguments); - } - - public Enumeration getAllProperties () { - return wrapper.getProperties (); - } - - public Enumeration getProperties () { - return wrapper.getProperties (); - } - - public Object toJavaObject () { - return wrappedObject; + /** + * Creates a new ESGenericObject object. + * + * @param prototype ... + * @param evaluator ... + * @param obj ... + */ + public ESGenericObject(ESObject prototype, Evaluator evaluator, Object obj) { + super(prototype, evaluator); + wrappedObject = obj; + wrapper = new ESWrapper(obj, evaluator); } /** - * An ESNode equals another object if it is an ESNode that wraps the same INode + * + * + * @return ... + */ + public String getESClassName() { + return "GenericObject"; + } + + /** + * + * + * @return ... + */ + public String toString() { + return wrappedObject.toString(); + } + + /** + * + * + * @return ... + */ + public String toDetailString() { + return wrapper.toDetailString(); + } + + /** + * + * + * @param propertyName ... + * @param propertyValue ... + * @param hash ... + * + * @throws EcmaScriptException ... + */ + public void putProperty(String propertyName, ESValue propertyValue, int hash) + throws EcmaScriptException { + wrapper.putProperty(propertyName, propertyValue, hash); + } + + /** + * + * + * @param propertyName ... + * @param hash ... + * + * @return ... + * + * @throws EcmaScriptException ... + */ + public boolean hasProperty(String propertyName, int hash) + throws EcmaScriptException { + return super.hasProperty(propertyName, hash) || + wrapper.hasProperty(propertyName, hash); + } + + /** + * + * + * @param propertyName ... + * @param hash ... + * + * @return ... + * + * @throws EcmaScriptException ... + */ + public boolean deleteProperty(String propertyName, int hash) + throws EcmaScriptException { + return wrapper.deleteProperty(propertyName, hash); + } + + /** + * + * + * @param i ... + * + * @return ... + * + * @throws EcmaScriptException ... + */ + public ESValue getProperty(int i) throws EcmaScriptException { + return wrapper.getProperty(i); + } + + /** + * + * + * @param index ... + * @param propertyValue ... + * + * @throws EcmaScriptException ... + */ + public void putProperty(int index, ESValue propertyValue) + throws EcmaScriptException { + wrapper.putProperty(index, propertyValue); + } + + /** + * + * + * @param propertyName ... + * @param hash ... + * + * @return ... + * + * @throws EcmaScriptException ... + */ + public ESValue getProperty(String propertyName, int hash) + throws EcmaScriptException { + ESValue val = super.getProperty(propertyName, hash); + + if ((val == null) || (val == ESUndefined.theUndefined)) { + val = wrapper.getProperty(propertyName, hash); + } + + return val; + } + + /** + * + * + * @param evaluator ... + * @param thisObject ... + * @param functionName ... + * @param arguments ... + * + * @return ... + * + * @throws EcmaScriptException ... + * @throws NoSuchMethodException ... + */ + public ESValue doIndirectCall(Evaluator evaluator, ESObject thisObject, + String functionName, ESValue[] arguments) + throws EcmaScriptException, NoSuchMethodException { + if (super.hasProperty(functionName, functionName.hashCode())) { + return super.doIndirectCall(evaluator, thisObject, functionName, arguments); + } + + return wrapper.doIndirectCall(evaluator, thisObject, functionName, arguments); + } + + /** + * + * + * @return ... + */ + public Enumeration getAllProperties() { + return wrapper.getProperties(); + } + + /** + * + * + * @return ... + */ + public Enumeration getProperties() { + return wrapper.getProperties(); + } + + /** + * + * + * @return ... + */ + public Object toJavaObject() { + return wrappedObject; + } + + /** + * An ESNode equals another object if it is an ESNode that wraps the same INode * or the wrapped INode itself. FIXME: doesen't check dbmapping/type! */ - public boolean equals (Object what) { - if (what == null) + public boolean equals(Object what) { + if (what == null) { return false; - if (what == this) + } + + if (what == this) { return true; + } + if (what instanceof ESGenericObject) { ESGenericObject other = (ESGenericObject) what; - return (wrappedObject.equals (other.wrappedObject)); + + return (wrappedObject.equals(other.wrappedObject)); } + return false; - } - + } } - - diff --git a/src/helma/scripting/fesi/ESMapWrapper.java b/src/helma/scripting/fesi/ESMapWrapper.java index e2f1b96d..ec7c6967 100644 --- a/src/helma/scripting/fesi/ESMapWrapper.java +++ b/src/helma/scripting/fesi/ESMapWrapper.java @@ -1,171 +1,189 @@ -// ESMapWrapper.java -// Copyright (c) Hannes Wallnöfer 1998-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.scripting.fesi; -import helma.framework.core.*; -import helma.objectmodel.INode; import FESI.Data.*; import FESI.Exceptions.*; import FESI.Interpreter.Evaluator; +import helma.framework.core.*; +import helma.objectmodel.INode; import java.util.*; - - /** - * An EcmaScript object that makes stuff in a hashtable accessible as its properties - */ - + * An EcmaScript object that makes stuff in a hashtable accessible as its properties + */ public class ESMapWrapper extends ESWrapper { - private Map data; private FesiEngine engine; private boolean readonly = false; - public ESMapWrapper (FesiEngine engine) { - super (new Object(), engine.getEvaluator ()); - this.engine = engine; + /** + * Creates a new ESMapWrapper object. + * + * @param engine ... + */ + public ESMapWrapper(FesiEngine engine) { + super(new Object(), engine.getEvaluator()); + this.engine = engine; } - public ESMapWrapper (FesiEngine engine, Map data) { - super (new Object(), engine.getEvaluator ()); - this.engine = engine; - this.data = data; + /** + * Creates a new ESMapWrapper object. + * + * @param engine ... + * @param data ... + */ + public ESMapWrapper(FesiEngine engine, Map data) { + super(new Object(), engine.getEvaluator()); + this.engine = engine; + this.data = data; } - public void setReadonly (boolean readonly) { - this.readonly = readonly; - } + /** + * + * + * @param readonly ... + */ + public void setReadonly(boolean readonly) { + this.readonly = readonly; + } - public void setData (Map data) { - this.data = data; + /** + * + * + * @param data ... + */ + public void setData(Map data) { + this.data = data; } /** * Overridden to make the object read-only */ - public void putProperty(String propertyName, ESValue propertyValue, int hash) throws EcmaScriptException { - if (data == null) - data = new HashMap (); - if (propertyValue == ESNull.theNull) - deleteProperty(propertyName, hash); - else if (readonly==false) - data.put (propertyName, propertyValue.toJavaObject ()); - else - throw new EcmaScriptException ("object is readonly"); - } - - public boolean deleteProperty(String propertyName, int hash) throws EcmaScriptException { - if (readonly==false) { - data.remove (propertyName); - return true; - } else - return false; - } - - public ESValue getProperty(String propertyName, int hash) throws EcmaScriptException { - if (data == null) - return ESNull.theNull; + public void putProperty(String propertyName, ESValue propertyValue, int hash) + throws EcmaScriptException { + if (data == null) { + data = new HashMap(); + } - Object val = data.get (propertyName); - - if (val == null) - return ESNull.theNull; - - if (val instanceof String) - return new ESString ((String) val); - else if (val instanceof INode) - return engine.getNodeWrapper ((INode) val); - else if (val instanceof Map) - return new ESMapWrapper (engine, (Map)val); - else if (val instanceof ESValue) - return (ESValue) val; - return ESLoader.normalizeValue(val, evaluator); + if (propertyValue == ESNull.theNull) { + deleteProperty(propertyName, hash); + } else if (readonly == false) { + data.put(propertyName, propertyValue.toJavaObject()); + } else { + throw new EcmaScriptException("object is readonly"); + } } + /** + * + * + * @param propertyName ... + * @param hash ... + * + * @return ... + * + * @throws EcmaScriptException ... + */ + public boolean deleteProperty(String propertyName, int hash) + throws EcmaScriptException { + if (readonly == false) { + data.remove(propertyName); - public Enumeration getAllProperties () { - return getProperties (); + return true; + } else { + return false; + } } - public Enumeration getProperties () { - Object[] keys = data == null ? null : data.keySet().toArray (); - return new Enum (keys); + /** + * + * + * @param propertyName ... + * @param hash ... + * + * @return ... + * + * @throws EcmaScriptException ... + */ + public ESValue getProperty(String propertyName, int hash) + throws EcmaScriptException { + if (data == null) { + return ESNull.theNull; + } + + Object val = data.get(propertyName); + + if (val == null) { + return ESNull.theNull; + } + + if (val instanceof String) { + return new ESString((String) val); + } else if (val instanceof INode) { + return engine.getNodeWrapper((INode) val); + } else if (val instanceof Map) { + return new ESMapWrapper(engine, (Map) val); + } else if (val instanceof ESValue) { + return (ESValue) val; + } + + return ESLoader.normalizeValue(val, evaluator); } + /** + * + * + * @return ... + */ + public Enumeration getAllProperties() { + return getProperties(); + } + + /** + * + * + * @return ... + */ + public Enumeration getProperties() { + Object[] keys = (data == null) ? null : data.keySet().toArray(); + + return new Enum(keys); + } class Enum implements Enumeration { - - Object[] elements; - int pos; - - Enum (Object[] elements) { - this.elements = elements; - pos = 0; - } - - public boolean hasMoreElements () { - return elements != null && pos < elements.length; - } - - public Object nextElement () { - if (elements == null || pos >= elements.length) - throw new NoSuchElementException (); - return elements[pos++]; - } + Object[] elements; + int pos; + + Enum(Object[] elements) { + this.elements = elements; + pos = 0; + } + + public boolean hasMoreElements() { + return (elements != null) && (pos < elements.length); + } + + public Object nextElement() { + if ((elements == null) || (pos >= elements.length)) { + throw new NoSuchElementException(); + } + + return elements[pos++]; + } } } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/helma/scripting/fesi/ESNode.java b/src/helma/scripting/fesi/ESNode.java index 71dcf062..130b1e4d 100644 --- a/src/helma/scripting/fesi/ESNode.java +++ b/src/helma/scripting/fesi/ESNode.java @@ -1,33 +1,43 @@ -// ESNode.java -// Copyright (c) Hannes Wallnöfer 1998-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.scripting.fesi; +import FESI.Data.*; +import FESI.Exceptions.*; +import FESI.Interpreter.*; +import helma.framework.core.*; import helma.objectmodel.*; import helma.objectmodel.db.*; -import helma.framework.core.*; import helma.util.*; -import FESI.Interpreter.*; -import FESI.Exceptions.*; -import FESI.Data.*; import java.io.*; import java.util.*; - /** - * An EcmaScript wrapper around a Node object. This is the basic - * HopObject that can be stored in the internal or external databases. - */ - + * An EcmaScript wrapper around a Node object. This is the basic + * HopObject that can be stored in the internal or external databases. + */ public class ESNode extends ObjectPrototype { - // the INode object wrapped by this ESObject INode node; // the cache node - persistent nodes have a transient property as a commodity to // store temporary stuff. INode cache; + // the ecmascript wrapper for the cache. ESNode cacheWrapper; @@ -40,308 +50,485 @@ public class ESNode extends ObjectPrototype { /** * Constructor used to create transient cache nodes */ - public ESNode (INode node, FesiEngine engine) { - super (engine.getPrototype("hopobject"), engine.getEvaluator()); - this.engine = engine; - this.node = node; - cache = null; - cacheWrapper = null; + public ESNode(INode node, FesiEngine engine) { + super(engine.getPrototype("hopobject"), engine.getEvaluator()); + this.engine = engine; + this.node = node; + cache = null; + cacheWrapper = null; - // this is a transient node, set node handle to null - handle = null; + // this is a transient node, set node handle to null + handle = null; } - public ESNode (ESObject prototype, Evaluator evaluator, Object obj, FesiEngine engine) { - super (prototype, evaluator); - // eval.app.logEvent ("in ESNode constructor: "+o.getClass ()); - this.engine = engine; - if (obj == null) - node = new TransientNode (null); - else if (obj instanceof ESWrapper) - node = (INode) ((ESWrapper) obj).getJavaObject (); - else if (obj instanceof INode) - node = (INode) obj; - else - node = new TransientNode (obj.toString ()); - // set node handle to wrapped node - if (node instanceof Node) - handle = ((Node) node).getHandle (); - else - handle = null; + /** + * Creates a new ESNode object. + * + * @param prototype ... + * @param evaluator ... + * @param obj ... + * @param engine ... + */ + public ESNode(ESObject prototype, Evaluator evaluator, Object obj, FesiEngine engine) { + super(prototype, evaluator); - // cache Node is initialized on demend when it is needed - cache = null; - cacheWrapper = null; + // eval.app.logEvent ("in ESNode constructor: "+o.getClass ()); + this.engine = engine; + + if (obj == null) { + node = new TransientNode(null); + } else if (obj instanceof ESWrapper) { + node = (INode) ((ESWrapper) obj).getJavaObject(); + } else if (obj instanceof INode) { + node = (INode) obj; + } else { + node = new TransientNode(obj.toString()); + } + + // set node handle to wrapped node + if (node instanceof Node) { + handle = ((Node) node).getHandle(); + } else { + handle = null; + } + + // cache Node is initialized on demend when it is needed + cache = null; + cacheWrapper = null; } /** * Check if the node has been invalidated. If so, it has to be re-fetched * from the db via the app's node manager. */ - protected void checkNode () { - if (node.getState () == INode.INVALID) try { - node = handle.getNode (engine.app.getWrappedNodeManager ()); - } catch (Exception nx) {} - } - - public INode getNode () { - checkNode (); - return node; - } - - public void setPrototype (String protoName) { - checkNode (); - node.setPrototype (protoName); - } - - public String getPrototypeName () { - return node.getPrototype (); - } - - public String getESClassName () { - return "HopObject"; - } - - public String toString () { - if (node == null) - return "<null>"; - return node.toString (); - } - - public String toDetailString () { - return "ES:[Object: builtin " + this.getClass().getName() + ":" + - ((node == null) ? "null" : node.toString()) + "]"; - } - - protected void setError (Throwable e) { - lastError = e; - } - - - public boolean add (ESValue what[]) { - checkNode (); - for (int i=0; i<what.length; i++) - if (what[i] instanceof ESNode) { - ESNode esn = (ESNode) what[i]; - INode added = node.addNode (esn.getNode ()); + protected void checkNode() { + if (node.getState() == INode.INVALID) { + try { + node = handle.getNode(engine.app.getWrappedNodeManager()); + } catch (Exception nx) { } + } + } + + /** + * + * + * @return ... + */ + public INode getNode() { + checkNode(); + + return node; + } + + /** + * + * + * @param protoName ... + */ + public void setPrototype(String protoName) { + checkNode(); + node.setPrototype(protoName); + } + + /** + * + * + * @return ... + */ + public String getPrototypeName() { + return node.getPrototype(); + } + + /** + * + * + * @return ... + */ + public String getESClassName() { + return "HopObject"; + } + + /** + * + * + * @return ... + */ + public String toString() { + if (node == null) { + return "<null>"; + } + + return node.toString(); + } + + /** + * + * + * @return ... + */ + public String toDetailString() { + return "ES:[Object: builtin " + this.getClass().getName() + ":" + + ((node == null) ? "null" : node.toString()) + "]"; + } + + protected void setError(Throwable e) { + lastError = e; + } + + /** + * + * + * @param what ... + * + * @return ... + */ + public boolean add(ESValue[] what) { + checkNode(); + + for (int i = 0; i < what.length; i++) + if (what[i] instanceof ESNode) { + ESNode esn = (ESNode) what[i]; + INode added = node.addNode(esn.getNode()); + } + return true; } - public ESValue list () { - checkNode (); - int l = node.numberOfNodes (); - Enumeration e = node.getSubnodes (); - ESObject ap = evaluator.getArrayPrototype(); - ArrayPrototype theArray = new ArrayPrototype(ap, evaluator); - if (e != null) { - theArray.setSize(l); - for (int i = 0; i<l; i++) { - theArray.setElementAt (engine.getNodeWrapper ((INode) e.nextElement ()), i); - } - } else { - theArray.setSize (0); - } - return theArray; + /** + * + * + * @return ... + */ + public ESValue list() { + checkNode(); + + int l = node.numberOfNodes(); + Enumeration e = node.getSubnodes(); + ESObject ap = evaluator.getArrayPrototype(); + ArrayPrototype theArray = new ArrayPrototype(ap, evaluator); + + if (e != null) { + theArray.setSize(l); + + for (int i = 0; i < l; i++) { + theArray.setElementAt(engine.getNodeWrapper((INode) e.nextElement()), i); + } + } else { + theArray.setSize(0); + } + + return theArray; } - public boolean addAt (ESValue what[]) throws EcmaScriptException { - checkNode (); - if (what.length < 2) - throw new EcmaScriptException ("Wrong number of arguments"); - if (! (what[1] instanceof ESNode)) - throw new EcmaScriptException ("Can ony add Node objects as subnodes"); + /** + * + * + * @param what ... + * + * @return ... + * + * @throws EcmaScriptException ... + */ + public boolean addAt(ESValue[] what) throws EcmaScriptException { + checkNode(); + + if (what.length < 2) { + throw new EcmaScriptException("Wrong number of arguments"); + } + + if (!(what[1] instanceof ESNode)) { + throw new EcmaScriptException("Can ony add Node objects as subnodes"); + } + ESNode esn = (ESNode) what[1]; - INode added = node.addNode (esn.getNode (), (int) what[0].toInt32 ()); + INode added = node.addNode(esn.getNode(), (int) what[0].toInt32()); + return true; } - - /** - * Remove node itself or one or more subnodes. - */ - public boolean remove (ESValue args[]) { - checkNode (); + /** + * Remove node itself or one or more subnodes. + */ + public boolean remove(ESValue[] args) { + checkNode(); + // semantics: if called without arguments, remove self. // otherwise, remove given subnodes. if (args.length == 0) { - return node.remove (); + return node.remove(); } else { - for (int i=0; i<args.length; i++) { + for (int i = 0; i < args.length; i++) { if (args[i] instanceof ESNode) { ESNode esn = (ESNode) args[i]; - node.removeNode (esn.getNode ()); + + node.removeNode(esn.getNode()); } } } + return true; } - /** - * Invalidate the node itself or a subnode - */ - public boolean invalidate (ESValue args[]) { + /** + * Invalidate the node itself or a subnode + */ + public boolean invalidate(ESValue[] args) { if (node instanceof helma.objectmodel.db.Node) { if (args.length == 0) { - ((helma.objectmodel.db.Node) node).invalidate (); + ((helma.objectmodel.db.Node) node).invalidate(); } else { - ((helma.objectmodel.db.Node) node).invalidateNode (args[0].toString ()); + ((helma.objectmodel.db.Node) node).invalidateNode(args[0].toString()); } } + return true; } + /** + * Check if node is contained in subnodes + */ + public int contains(ESValue[] args) { + checkNode(); - /** - * Check if node is contained in subnodes - */ - public int contains (ESValue args[]) { - checkNode (); - if (args.length == 1 && args[0] instanceof ESNode) { + if ((args.length == 1) && args[0] instanceof ESNode) { ESNode esn = (ESNode) args[0]; - return node.contains (esn.getNode ()); + + return node.contains(esn.getNode()); } + return -1; } - /** - * Prefetch child objects from (relational) database. - */ - public void prefetchChildren (ESValue args[]) throws Exception { - checkNode (); - if (!(node instanceof Node)) + /** + * Prefetch child objects from (relational) database. + */ + public void prefetchChildren(ESValue[] args) throws Exception { + checkNode(); + + if (!(node instanceof Node)) { return; - int start = 0, length = 0; + } + + int start = 0; + int length = 0; + try { if (args.length == 0) { start = 0; length = 1000; } else if (args.length == 2) { - if (args[0].isNumberValue ()) - start = args[0].toInt32 (); - else - throw new RuntimeException ("Illegal argument in prefetchChildren: "+args[0]); - if (args[1].isNumberValue ()) - length = args[1].toInt32 (); - else - throw new RuntimeException ("Illegal argument in prefetchChildren: "+args[1]); + if (args[0].isNumberValue()) { + start = args[0].toInt32(); + } else { + throw new RuntimeException("Illegal argument in prefetchChildren: " + + args[0]); + } + + if (args[1].isNumberValue()) { + length = args[1].toInt32(); + } else { + throw new RuntimeException("Illegal argument in prefetchChildren: " + + args[1]); + } } else { - throw new RuntimeException ("Wrong number of arguments in prefetchChildren"); + throw new RuntimeException("Wrong number of arguments in prefetchChildren"); } } catch (Exception x) { - throw new IllegalArgumentException (x.getMessage()); + throw new IllegalArgumentException(x.getMessage()); } - ((Node) node).prefetchChildren (start, length); + + ((Node) node).prefetchChildren(start, length); } - /** - * This used to be different from add(), it isn't anymore. It's left here for - * compatibility. - */ - public boolean link (ESValue args[]) { - checkNode (); - for (int i=0; i<args.length; i++) { + /** + * This used to be different from add(), it isn't anymore. It's left here for + * compatibility. + */ + public boolean link(ESValue[] args) { + checkNode(); + + for (int i = 0; i < args.length; i++) { if (args[i] instanceof ESNode) { ESNode esn = (ESNode) args[i]; - node.addNode (esn.getNode ()); + + node.addNode(esn.getNode()); } } + return true; } - - public boolean setParent (ESValue[] pval) { + /** + * + * + * @param pval ... + * + * @return ... + */ + public boolean setParent(ESValue[] pval) { // do a couple of checks: both nodes need to be persistent in order for setParent to make sense. - if (!(node instanceof helma.objectmodel.db.Node)) + if (!(node instanceof helma.objectmodel.db.Node)) { return false; - if (pval == null || pval.length < 1 || pval.length > 2) + } + + if ((pval == null) || (pval.length < 1) || (pval.length > 2)) { return false; - if (!(pval[0] instanceof ESNode)) + } + + if (!(pval[0] instanceof ESNode)) { return false; + } + ESNode esn = (ESNode) pval[0]; - INode pn = esn.getNode (); - if (!(pn instanceof helma.objectmodel.db.Node)) + INode pn = esn.getNode(); + + if (!(pn instanceof helma.objectmodel.db.Node)) { return false; + } + // check if there is an additional string element - if so, it's the property name by which the node is // accessed, otherwise it will be accessed as anonymous subnode via its id String propname = null; - if (pval.length == 2 && pval[1] != null && !(pval[1] instanceof ESNull)) - propname = pval[1].toString (); + + if ((pval.length == 2) && (pval[1] != null) && !(pval[1] instanceof ESNull)) { + propname = pval[1].toString(); + } + helma.objectmodel.db.Node n = (helma.objectmodel.db.Node) node; - n.setParent ((helma.objectmodel.db.Node) pn, propname); + + n.setParent((helma.objectmodel.db.Node) pn, propname); + return true; } + /** + * + * + * @param propertyName ... + * @param propertyValue ... + * @param hash ... + * + * @throws EcmaScriptException ... + */ + public void putProperty(String propertyName, ESValue propertyValue, int hash) + throws EcmaScriptException { + checkNode(); - public void putProperty(String propertyName, ESValue propertyValue, int hash) throws EcmaScriptException { - checkNode (); - // engine.app.logEvent ("put property called: "+propertyName+", "+propertyValue.getClass()); - if ("cache".equalsIgnoreCase (propertyName)) - throw new EcmaScriptException ("Can't modify read-only property \""+propertyName+"\"."); + // engine.app.logEvent ("put property called: "+propertyName+", "+propertyValue.getClass()); + if ("cache".equalsIgnoreCase(propertyName)) { + throw new EcmaScriptException("Can't modify read-only property \"" + + propertyName + "\"."); + } - if ("subnodeRelation".equalsIgnoreCase (propertyName)) { - node.setSubnodeRelation (propertyValue instanceof ESNull ? null : propertyValue.toString ()); - return; - } + if ("subnodeRelation".equalsIgnoreCase(propertyName)) { + node.setSubnodeRelation((propertyValue instanceof ESNull) ? null + : propertyValue.toString()); - // check if the property is write protected, i.e. the type.property file describes it as [readonly] - DbMapping dbm = node.getDbMapping (); - if (dbm != null) { - Relation rel = dbm.getPropertyRelation (propertyName); - if (rel != null && rel.isReadonly ()) - return; - } + return; + } - if (propertyValue instanceof ESNull || propertyValue instanceof ESUndefined) - node.unset (propertyName); - else if (propertyValue instanceof ESString) - node.setString (propertyName, propertyValue.toString ()); - else if (propertyValue instanceof ESBoolean) - node.setBoolean (propertyName, propertyValue.booleanValue ()); - else if (propertyValue instanceof ESNumber) - node.setFloat (propertyName, propertyValue.doubleValue ()); - else if (propertyValue instanceof DatePrototype) - node.setDate (propertyName, (Date) propertyValue.toJavaObject ()); - else if (propertyValue instanceof ESNode) { - // long now = System.currentTimeMillis (); - ESNode esn = (ESNode) propertyValue; - node.setNode (propertyName, esn.getNode ()); - // engine.app.logEvent ("*** spent "+(System.currentTimeMillis () - now)+" ms to set property "+propertyName); - } else { - // engine.app.logEvent ("got "+propertyValue.getClass ()); - // A persistent node can't store anything other than the types above, so throw an exception - // throw new EcmaScriptException ("Can't set a JavaScript Object or Array as property of "+node); - node.setJavaObject (propertyName, propertyValue.toJavaObject ()); - } - } - - public boolean deleteProperty(String propertyName, int hash) throws EcmaScriptException { - checkNode (); - // engine.app.logEvent ("delete property called: "+propertyName); - if (node.get (propertyName) != null) { - node.unset (propertyName); - return true; - } - return super.deleteProperty (propertyName, hash); - } - - public ESValue getProperty (int i) throws EcmaScriptException { - checkNode (); - INode n = node.getSubnodeAt (i); - if (n == null) - return ESNull.theNull; - return engine.getNodeWrapper (n); - } + // check if the property is write protected, i.e. the type.property file describes it as [readonly] + DbMapping dbm = node.getDbMapping(); - public void putProperty(int index, ESValue propertyValue) throws EcmaScriptException { - checkNode (); - if (propertyValue instanceof ESNode) { - ESNode n = (ESNode) propertyValue; - node.addNode (n.getNode (), index); - } else - throw new EcmaScriptException ("Can only add Nodes to Node arrays"); + if (dbm != null) { + Relation rel = dbm.getPropertyRelation(propertyName); + + if ((rel != null) && rel.isReadonly()) { + return; + } + } + + if (propertyValue instanceof ESNull || propertyValue instanceof ESUndefined) { + node.unset(propertyName); + } else if (propertyValue instanceof ESString) { + node.setString(propertyName, propertyValue.toString()); + } else if (propertyValue instanceof ESBoolean) { + node.setBoolean(propertyName, propertyValue.booleanValue()); + } else if (propertyValue instanceof ESNumber) { + node.setFloat(propertyName, propertyValue.doubleValue()); + } else if (propertyValue instanceof DatePrototype) { + node.setDate(propertyName, (Date) propertyValue.toJavaObject()); + } else if (propertyValue instanceof ESNode) { + // long now = System.currentTimeMillis (); + ESNode esn = (ESNode) propertyValue; + + node.setNode(propertyName, esn.getNode()); + + // engine.app.logEvent ("*** spent "+(System.currentTimeMillis () - now)+" ms to set property "+propertyName); + } else { + // engine.app.logEvent ("got "+propertyValue.getClass ()); + // A persistent node can't store anything other than the types above, so throw an exception + // throw new EcmaScriptException ("Can't set a JavaScript Object or Array as property of "+node); + node.setJavaObject(propertyName, propertyValue.toJavaObject()); + } } + /** + * + * + * @param propertyName ... + * @param hash ... + * + * @return ... + * + * @throws EcmaScriptException ... + */ + public boolean deleteProperty(String propertyName, int hash) + throws EcmaScriptException { + checkNode(); + + // engine.app.logEvent ("delete property called: "+propertyName); + if (node.get(propertyName) != null) { + node.unset(propertyName); + + return true; + } + + return super.deleteProperty(propertyName, hash); + } + + /** + * + * + * @param i ... + * + * @return ... + * + * @throws EcmaScriptException ... + */ + public ESValue getProperty(int i) throws EcmaScriptException { + checkNode(); + + INode n = node.getSubnodeAt(i); + + if (n == null) { + return ESNull.theNull; + } + + return engine.getNodeWrapper(n); + } + + /** + * + * + * @param index ... + * @param propertyValue ... + * + * @throws EcmaScriptException ... + */ + public void putProperty(int index, ESValue propertyValue) + throws EcmaScriptException { + checkNode(); + + if (propertyValue instanceof ESNode) { + ESNode n = (ESNode) propertyValue; + + node.addNode(n.getNode(), index); + } else { + throw new EcmaScriptException("Can only add Nodes to Node arrays"); + } + } /** * Retrieve a property from the node object or the underlying EcmaScript prototype. @@ -351,13 +538,18 @@ public class ESNode extends ObjectPrototype { * because generally things are divided cleanly between prototype and object - the * first holds the functions, the latter the mapped data properties. */ - public ESValue getProperty(String propertyName, int hash) throws EcmaScriptException { - checkNode (); - // engine.app.logEvent ("get property called: "+propertyName); - ESValue retval = super.getProperty (propertyName, hash); - if (! (retval instanceof ESUndefined)) - return retval; - return getNodeProperty (propertyName); + public ESValue getProperty(String propertyName, int hash) + throws EcmaScriptException { + checkNode(); + + // engine.app.logEvent ("get property called: "+propertyName); + ESValue retval = super.getProperty(propertyName, hash); + + if (!(retval instanceof ESUndefined)) { + return retval; + } + + return getNodeProperty(propertyName); } /** @@ -365,164 +557,256 @@ public class ESNode extends ObjectPrototype { * This is called directly when we call get(x) on a hopobject, since we don't want to return * the prototype functions in that case. */ - public ESValue getNodeProperty (String propertyName) throws EcmaScriptException { - // check for null - if (propertyName == null) - return ESNull.theNull; - // persistent or persistent capable nodes have a cache property that's a transient node. - // it it hasn't requested before, initialize it now - if ("cache".equalsIgnoreCase (propertyName) && node instanceof Node) { - cache = node.getCacheNode (); - if (cacheWrapper == null) - cacheWrapper = new ESNode (cache, engine); - else - cacheWrapper.node = cache; - return cacheWrapper; - } - if ("subnodeRelation".equalsIgnoreCase (propertyName)) { - String rel = node.getSubnodeRelation (); - return rel == null ? (ESValue) ESNull.theNull : new ESString (rel); - } + public ESValue getNodeProperty(String propertyName) + throws EcmaScriptException { + // check for null + if (propertyName == null) { + return ESNull.theNull; + } - // Everything starting with an underscore is interpreted as internal property - if (propertyName.startsWith ("_")) - return getInternalProperty (propertyName); + // persistent or persistent capable nodes have a cache property that's a transient node. + // it it hasn't requested before, initialize it now + if ("cache".equalsIgnoreCase(propertyName) && node instanceof Node) { + cache = node.getCacheNode(); - // this _may_ do a relational query if properties are mapped to a relational type. - IProperty p = node.get (propertyName); - if (p != null) { - if (p.getType () == IProperty.STRING) { - String str = p.getStringValue (); - if (str == null) - return ESNull.theNull; - else - return new ESString (str); - } - if (p.getType () == IProperty.BOOLEAN) - return ESBoolean.makeBoolean (p.getBooleanValue ()); - if (p.getType () == IProperty.DATE) - return new DatePrototype (evaluator, p.getDateValue ()); - if (p.getType () == IProperty.INTEGER) - return new ESNumber ((double) p.getIntegerValue ()); - if (p.getType () == IProperty.FLOAT) - return new ESNumber (p.getFloatValue ()); - if (p.getType () == IProperty.NODE) { - INode nd = p.getNodeValue (); - if (nd == null) - return ESNull.theNull; - else - return engine.getNodeWrapper (nd); - } - if (p.getType () == IProperty.JAVAOBJECT) - return ESLoader.normalizeObject (p.getJavaObjectValue (), evaluator); - } + if (cacheWrapper == null) { + cacheWrapper = new ESNode(cache, engine); + } else { + cacheWrapper.node = cache; + } - // as last resort, try to get property as anonymous subnode - INode anon = (INode) node.getChildElement (propertyName); - if (anon != null) - return engine.getNodeWrapper (anon); + return cacheWrapper; + } - return ESNull.theNull; + if ("subnodeRelation".equalsIgnoreCase(propertyName)) { + String rel = node.getSubnodeRelation(); + + return (rel == null) ? (ESValue) ESNull.theNull : new ESString(rel); + } + + // Everything starting with an underscore is interpreted as internal property + if (propertyName.startsWith("_")) { + return getInternalProperty(propertyName); + } + + // this _may_ do a relational query if properties are mapped to a relational type. + IProperty p = node.get(propertyName); + + if (p != null) { + if (p.getType() == IProperty.STRING) { + String str = p.getStringValue(); + + if (str == null) { + return ESNull.theNull; + } else { + return new ESString(str); + } + } + + if (p.getType() == IProperty.BOOLEAN) { + return ESBoolean.makeBoolean(p.getBooleanValue()); + } + + if (p.getType() == IProperty.DATE) { + return new DatePrototype(evaluator, p.getDateValue()); + } + + if (p.getType() == IProperty.INTEGER) { + return new ESNumber((double) p.getIntegerValue()); + } + + if (p.getType() == IProperty.FLOAT) { + return new ESNumber(p.getFloatValue()); + } + + if (p.getType() == IProperty.NODE) { + INode nd = p.getNodeValue(); + + if (nd == null) { + return ESNull.theNull; + } else { + return engine.getNodeWrapper(nd); + } + } + + if (p.getType() == IProperty.JAVAOBJECT) { + return ESLoader.normalizeObject(p.getJavaObjectValue(), evaluator); + } + } + + // as last resort, try to get property as anonymous subnode + INode anon = (INode) node.getChildElement(propertyName); + + if (anon != null) { + return engine.getNodeWrapper(anon); + } + + return ESNull.theNull; } /** * Some internal properties defined for every Node object. These are most commonly * used for debugging Helma applications. */ - private ESValue getInternalProperty (String propertyName) throws EcmaScriptException { - if ("__id__".equals (propertyName) || "_id".equals (propertyName)) { - return new ESString (node.getID ()); - } - if ("__prototype__".equals (propertyName) || "_prototype".equals (propertyName)) { - String p = node.getPrototype (); - if (p == null) - return ESNull.theNull; - else - return new ESString (node.getPrototype ()); - } - if ("__parent__".equals (propertyName) || "_parent".equals (propertyName)) { - INode n = node.getParent (); - if (n == null) - return ESNull.theNull; - else - return engine.getNodeWrapper (n); - } - // some more internal properties - if ("__name__".equals (propertyName)) - return new ESString (node.getName ()); - if ("__fullname__".equals (propertyName)) - return new ESString (node.getFullName ()); - if ("__hash__".equals (propertyName)) - return new ESString (""+node.hashCode ()); - if ("__node__".equals (propertyName)) - return new ESWrapper (node, evaluator); - if ("__created__".equalsIgnoreCase (propertyName)) - return new DatePrototype (evaluator, node.created ()); - if ("__lastmodified__".equalsIgnoreCase (propertyName)) - return new DatePrototype (evaluator, node.lastModified ()); + private ESValue getInternalProperty(String propertyName) + throws EcmaScriptException { + if ("__id__".equals(propertyName) || "_id".equals(propertyName)) { + return new ESString(node.getID()); + } - return ESNull.theNull; + if ("__prototype__".equals(propertyName) || "_prototype".equals(propertyName)) { + String p = node.getPrototype(); + + if (p == null) { + return ESNull.theNull; + } else { + return new ESString(node.getPrototype()); + } + } + + if ("__parent__".equals(propertyName) || "_parent".equals(propertyName)) { + INode n = node.getParent(); + + if (n == null) { + return ESNull.theNull; + } else { + return engine.getNodeWrapper(n); + } + } + + // some more internal properties + if ("__name__".equals(propertyName)) { + return new ESString(node.getName()); + } + + if ("__fullname__".equals(propertyName)) { + return new ESString(node.getFullName()); + } + + if ("__hash__".equals(propertyName)) { + return new ESString("" + node.hashCode()); + } + + if ("__node__".equals(propertyName)) { + return new ESWrapper(node, evaluator); + } + + if ("__created__".equalsIgnoreCase(propertyName)) { + return new DatePrototype(evaluator, node.created()); + } + + if ("__lastmodified__".equalsIgnoreCase(propertyName)) { + return new DatePrototype(evaluator, node.lastModified()); + } + + return ESNull.theNull; } - public boolean clearCache () { - checkNode (); - node.clearCacheNode (); - return true; + /** + * + * + * @return ... + */ + public boolean clearCache() { + checkNode(); + node.clearCacheNode(); + + return true; } - public Enumeration getAllProperties () { - return getProperties (); + /** + * + * + * @return ... + */ + public Enumeration getAllProperties() { + return getProperties(); } - public Enumeration getProperties () { - checkNode (); - return node.properties (); + /** + * + * + * @return ... + */ + public Enumeration getProperties() { + checkNode(); + + return node.properties(); } - + /** + * + * + * @return ... + */ public String error() { - if (lastError == null) { - return ""; - } else { - String exceptionName = lastError.getClass().getName(); - int l = exceptionName.lastIndexOf("."); - if (l>0) exceptionName = exceptionName.substring(l+1); - return exceptionName +": " + lastError.getMessage(); - } + if (lastError == null) { + return ""; + } else { + String exceptionName = lastError.getClass().getName(); + int l = exceptionName.lastIndexOf("."); + + if (l > 0) { + exceptionName = exceptionName.substring(l + 1); + } + + return exceptionName + ": " + lastError.getMessage(); + } } - + + /** + * + */ public void clearError() { lastError = null; } - public Object toJavaObject () { - return getNode (); + /** + * + * + * @return ... + */ + public Object toJavaObject() { + return getNode(); } /** * An ESNode equals another object if it is an ESNode that wraps the same INode * or the wrapped INode itself. FIXME: doesen't check dbmapping/type! */ - public boolean equals (Object what) { - if (what == null) + public boolean equals(Object what) { + if (what == null) { return false; - if (what == this) + } + + if (what == this) { return true; + } + if (what instanceof ESNode) { ESNode other = (ESNode) what; - if (handle != null) - return handle.equals (other.handle); - else + + if (handle != null) { + return handle.equals(other.handle); + } else { return (node == other.node); + } } + return false; } + /** + * + * + * @param hint ... + * + * @return ... + * + * @throws EcmaScriptException ... + */ public ESValue getDefaultValue(int hint) throws EcmaScriptException { - return new ESString (this.toString()); + return new ESString(this.toString()); } - -} // class ESNode - - - +} + // class ESNode diff --git a/src/helma/scripting/fesi/FesiActionAdapter.java b/src/helma/scripting/fesi/FesiActionAdapter.java index dca3a3e3..6051a4be 100644 --- a/src/helma/scripting/fesi/FesiActionAdapter.java +++ b/src/helma/scripting/fesi/FesiActionAdapter.java @@ -1,88 +1,121 @@ -// ActionFile.java -// Copyright (c) Hannes Wallnöfer 1998-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.scripting.fesi; -import helma.scripting.*; -import java.util.Vector; -import java.util.Iterator; -import java.io.*; -import helma.framework.*; -import helma.framework.core.*; -import helma.util.Updatable; -import FESI.Data.*; -import FESI.Parser.*; import FESI.AST.ASTFormalParameterList; import FESI.AST.ASTStatementList; import FESI.AST.EcmaScriptTreeConstants; -import FESI.Interpreter.*; +import FESI.Data.*; import FESI.Exceptions.*; - - +import FESI.Interpreter.*; +import FESI.Parser.*; +import helma.framework.*; +import helma.framework.core.*; +import helma.scripting.*; +import helma.util.Updatable; +import java.io.*; +import java.util.Iterator; +import java.util.Vector; /** * An class that updates fesi interpreters with actionfiles and templates. */ - - public class FesiActionAdapter { - Prototype prototype; Application app; String functionName; String sourceName; + // this is the parsed function which can be easily applied to FesiEngine objects - TypeUpdater pfunc, pfuncAsString; + TypeUpdater pfunc; - public FesiActionAdapter (ActionFile action) { - prototype = action.getPrototype (); - app = action.getApplication (); - Reader reader = null; - functionName = action.getFunctionName (); - sourceName = action.getSourceName (); - try { - reader = action.getReader (); - pfunc = parseFunction (functionName, - "arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10", - reader, - sourceName); - } catch (Throwable x) { - String message = x.getMessage (); - pfunc = new ErrorFeedback (functionName, message); - } finally { - try { - reader.close(); - } catch (Exception ignore) {} - } - // check if this is a template and we need to generate an "_as_string" variant - if (action instanceof Template) { - String content = "res.pushStringBuffer(); " + - action.getContent () + - "\r\nreturn res.popStringBuffer();\r\n"; - try { - pfuncAsString = parseFunction (functionName+"_as_string", - "arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10", - new StringReader(content), - sourceName); - } catch (Throwable x) { - String message = x.getMessage (); - pfunc = new ErrorFeedback (functionName+"_as_string", message); - } - } else { - pfuncAsString = null; - } + // this is the parsed function which can be easily applied to FesiEngine objects + TypeUpdater pfuncAsString; + + /** + * Creates a new FesiActionAdapter object. + * + * @param action ... + */ + public FesiActionAdapter(ActionFile action) { + prototype = action.getPrototype(); + app = action.getApplication(); + + Reader reader = null; + + functionName = action.getFunctionName(); + sourceName = action.getSourceName(); + + try { + reader = action.getReader(); + pfunc = parseFunction(functionName, + "arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10", + reader, sourceName); + } catch (Throwable x) { + String message = x.getMessage(); + + pfunc = new ErrorFeedback(functionName, message); + } finally { + try { + reader.close(); + } catch (Exception ignore) { + } + } + + // check if this is a template and we need to generate an "_as_string" variant + if (action instanceof Template) { + String content = "res.pushStringBuffer(); " + action.getContent() + + "\r\nreturn res.popStringBuffer();\r\n"; + + try { + pfuncAsString = parseFunction(functionName + "_as_string", + "arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10", + new StringReader(content), sourceName); + } catch (Throwable x) { + String message = x.getMessage(); + + pfunc = new ErrorFeedback(functionName + "_as_string", message); + } + } else { + pfuncAsString = null; + } } + /** + * + * + * @param engine ... + * + * @throws EcmaScriptException ... + */ + public synchronized void updateEvaluator(FesiEngine engine) + throws EcmaScriptException { + if (pfunc != null) { + pfunc.updateEvaluator(engine); + } - public synchronized void updateEvaluator (FesiEngine engine) throws EcmaScriptException { - if (pfunc != null) - pfunc.updateEvaluator (engine); - if (pfuncAsString != null) - pfuncAsString.updateEvaluator (engine); + if (pfuncAsString != null) { + pfuncAsString.updateEvaluator(engine); + } } - protected TypeUpdater parseFunction (String funcName, String params, Reader body, String sourceName) throws EcmaScriptException { - + protected TypeUpdater parseFunction(String funcName, String params, Reader body, + String sourceName) + throws EcmaScriptException { // ESObject fp = app.eval.evaluator.getFunctionPrototype(); // ConstructedFunctionObject function = null; ASTFormalParameterList fpl = null; @@ -90,116 +123,138 @@ public class FesiActionAdapter { FunctionEvaluationSource fes = null; /* if (body == null || "".equals (body.trim())) - body = ";\r\n"; - else - body = body + "\r\n"; */ - if (params == null) params = ""; - else params = params.trim (); + body = ";\r\n"; + else + body = body + "\r\n"; */ + if (params == null) { + params = ""; + } else { + params = params.trim(); + } EcmaScript parser; StringReader is; // Special case for empty parameters - if (params.length()==0) { + if (params.length() == 0) { fpl = new ASTFormalParameterList(EcmaScriptTreeConstants.JJTFORMALPARAMETERLIST); } else { is = new java.io.StringReader(params); parser = new EcmaScript(is); + try { fpl = (ASTFormalParameterList) parser.FormalParameterList(); is.close(); } catch (ParseException x) { - throw new EcmaScriptParseException (x, new FileEvaluationSource(sourceName, null)); + throw new EcmaScriptParseException(x, + new FileEvaluationSource(sourceName, + null)); } } + // this is very very very strange: without the toString, lots of obscure exceptions // deep inside the parser... // is = new java.io.StringReader(body.toString ()); try { - parser = new EcmaScript (body); + parser = new EcmaScript(body); sl = (ASTStatementList) parser.StatementList(); body.close(); } catch (ParseException x) { - app.logEvent ("Error parsing file "+app.getName()+":"+sourceName+": "+x); - throw new EcmaScriptParseException (x, new FileEvaluationSource(sourceName, null)); + app.logEvent("Error parsing file " + app.getName() + ":" + sourceName + ": " + + x); + throw new EcmaScriptParseException(x, + new FileEvaluationSource(sourceName, null)); } catch (Exception x) { - app.logEvent ("Error parsing file "+app.getName()+":"+sourceName+": "+x); - throw new RuntimeException (x.getMessage ()); + app.logEvent("Error parsing file " + app.getName() + ":" + sourceName + ": " + + x); + throw new RuntimeException(x.getMessage()); } - fes = new FunctionEvaluationSource (new FileEvaluationSource(sourceName, null), funcName); - return new ParsedFunction (fpl, sl, fes, null, funcName); + fes = new FunctionEvaluationSource(new FileEvaluationSource(sourceName, null), + funcName); + + return new ParsedFunction(fpl, sl, fes, null, funcName); + } + + interface TypeUpdater { + public void updateEvaluator(FesiEngine engine) + throws EcmaScriptException; } class ParsedFunction implements TypeUpdater { - ASTFormalParameterList fpl = null; ASTStatementList sl = null; FunctionEvaluationSource fes = null; String fullFunctionText = null; String functionName; - public ParsedFunction (ASTFormalParameterList fpl, ASTStatementList sl, FunctionEvaluationSource fes, - String fullFunctionText, String functionName) { - this.fpl = fpl; - this.sl = sl; - this.fes = fes; - this.fullFunctionText = fullFunctionText; - this.functionName = functionName; + public ParsedFunction(ASTFormalParameterList fpl, ASTStatementList sl, + FunctionEvaluationSource fes, String fullFunctionText, + String functionName) { + this.fpl = fpl; + this.sl = sl; + this.fes = fes; + this.fullFunctionText = fullFunctionText; + this.functionName = functionName; } - public void updateEvaluator (FesiEngine engine) throws EcmaScriptException { + public void updateEvaluator(FesiEngine engine) + throws EcmaScriptException { + ObjectPrototype op = engine.getPrototype(prototype.getName()); - ObjectPrototype op = engine.getPrototype (prototype.getName()); + EcmaScriptVariableVisitor vdvisitor = engine.evaluator.getVarDeclarationVisitor(); + Vector vnames = vdvisitor.processVariableDeclarations(sl, fes); - EcmaScriptVariableVisitor vdvisitor = engine.evaluator.getVarDeclarationVisitor(); - Vector vnames = vdvisitor.processVariableDeclarations(sl, fes); + FunctionPrototype fp = ConstructedFunctionObject.makeNewConstructedFunction(engine.evaluator, + functionName, + fes, + fullFunctionText, + fpl.getArguments(), + vnames, + sl); - FunctionPrototype fp = ConstructedFunctionObject.makeNewConstructedFunction ( - engine.evaluator, functionName, fes, - fullFunctionText, fpl.getArguments(), vnames, sl); - op.putHiddenProperty (functionName, fp); + op.putHiddenProperty(functionName, fp); } - } class ErrorFeedback implements TypeUpdater { + String functionName; + String errorMessage; - String functionName, errorMessage; - - public ErrorFeedback (String fname, String msg) { + public ErrorFeedback(String fname, String msg) { functionName = fname; errorMessage = msg; } - public void updateEvaluator (FesiEngine engine) throws EcmaScriptException { + public void updateEvaluator(FesiEngine engine) + throws EcmaScriptException { + ObjectPrototype op = engine.getPrototype(prototype.getName()); - ObjectPrototype op = engine.getPrototype (prototype.getName ()); - - FunctionPrototype fp = (FunctionPrototype) engine.evaluator.getFunctionPrototype (); - FunctionPrototype func = new ThrowException (functionName, engine.evaluator, fp, errorMessage); - op.putHiddenProperty (functionName, func); + FunctionPrototype fp = (FunctionPrototype) engine.evaluator.getFunctionPrototype(); + FunctionPrototype func = new ThrowException(functionName, engine.evaluator, + fp, errorMessage); + op.putHiddenProperty(functionName, func); } } class ThrowException extends BuiltinFunctionObject { String message; - ThrowException (String name, Evaluator evaluator, FunctionPrototype fp, String message) { - super (fp, evaluator, name, 1); - this.message = message == null ? "No error message available" : message; - } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - throw new EcmaScriptException (message); - } - public ESObject doConstruct (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - throw new EcmaScriptException (message); - } - } - interface TypeUpdater { - public void updateEvaluator (FesiEngine engine) throws EcmaScriptException; + ThrowException(String name, Evaluator evaluator, FunctionPrototype fp, + String message) { + super(fp, evaluator, name, 1); + this.message = (message == null) ? "No error message available" : message; + } + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + throw new EcmaScriptException(message); + } + + public ESObject doConstruct(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + throw new EcmaScriptException(message); + } } } - - diff --git a/src/helma/scripting/fesi/FesiEngine.java b/src/helma/scripting/fesi/FesiEngine.java index 0cf96e79..f1fd7524 100644 --- a/src/helma/scripting/fesi/FesiEngine.java +++ b/src/helma/scripting/fesi/FesiEngine.java @@ -1,31 +1,55 @@ -// FesiScriptingEnvironment.java -// Copyright (c) Hannes Wallnöfer 2002 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.scripting.fesi; -import helma.scripting.*; -import helma.scripting.fesi.extensions.*; -import helma.extensions.HelmaExtension; +import FESI.Data.*; +import FESI.Exceptions.*; +import FESI.Interpreter.*; +import helma.doc.DocApplication; import helma.extensions.ConfigurationException; +import helma.extensions.HelmaExtension; import helma.framework.*; import helma.framework.core.*; -import helma.doc.DocApplication; +import helma.main.Server; import helma.objectmodel.*; import helma.objectmodel.db.DbMapping; import helma.objectmodel.db.Relation; -import helma.main.Server; -import helma.util.Updatable; +import helma.scripting.*; +import helma.scripting.fesi.extensions.*; import helma.util.CacheMap; -import java.util.*; +import helma.util.Updatable; import java.io.*; -import FESI.Data.*; -import FESI.Interpreter.*; -import FESI.Exceptions.*; +import java.util.*; /** * This is the implementation of ScriptingEnvironment for the FESI EcmaScript interpreter. */ public class FesiEngine implements ScriptingEngine { + // extensions loaded by this evaluator + static final String[] extensions = new String[] { + "FESI.Extensions.BasicIO", + "FESI.Extensions.FileIO", + "helma.scripting.fesi.extensions.XmlRpcExtension", + "helma.scripting.fesi.extensions.ImageExtension", + "helma.scripting.fesi.extensions.FtpExtension", + "FESI.Extensions.JavaAccess", + "helma.scripting.fesi.extensions.DomExtension", + "FESI.Extensions.OptionalRegExp" + }; // the application we're running in Application app; @@ -45,258 +69,310 @@ public class FesiEngine implements ScriptingEngine { // the request evaluator instance owning this fesi evaluator RequestEvaluator reval; - // extensions loaded by this evaluator - static final String[] extensions = new String[] { - "FESI.Extensions.BasicIO", - "FESI.Extensions.FileIO", - "helma.scripting.fesi.extensions.XmlRpcExtension", - "helma.scripting.fesi.extensions.ImageExtension", - "helma.scripting.fesi.extensions.FtpExtension", - "FESI.Extensions.JavaAccess", - "helma.scripting.fesi.extensions.DomExtension", - "FESI.Extensions.OptionalRegExp"}; - // remember global variables from last invokation to be able to // do lazy cleanup Map lastGlobals = null; // the global vars set by extensions HashMap extensionGlobals; - + // the introspector that provides documentation for this application DocApplication doc = null; /** * Zero argument constructor. */ - public FesiEngine () {} + public FesiEngine() { + } /** * Initialize a FESI evaluator for the given application and request evaluator. */ - public void init (Application app, RequestEvaluator reval) { - this.app = app; - this.reval = reval; - wrappercache = new CacheMap (200, .75f); - prototypes = new Hashtable (); - try { - evaluator = new Evaluator(this); - global = evaluator.getGlobalObject(); - for (int i=0; i<extensions.length; i++) - evaluator.addExtension (extensions[i]); - HopExtension hopx = new HopExtension (app); - hopx.initializeExtension (this); - MailExtension mailx = (MailExtension) evaluator.addExtension ("helma.scripting.fesi.extensions.MailExtension"); - mailx.setProperties (app.getProperties ()); - Database dbx = (Database) evaluator.addExtension ("helma.scripting.fesi.extensions.Database"); - dbx.setApplication (app); - // load extensions defined in server.properties: - extensionGlobals = new HashMap (); - Vector extVec = Server.getServer ().getExtensions (); - for (int i=0; i<extVec.size(); i++ ) { - HelmaExtension ext = (HelmaExtension)extVec.get(i); - try { - HashMap tmpGlobals = ext.initScripting (app,this); - if (tmpGlobals!=null) - extensionGlobals.putAll(tmpGlobals); - } catch (ConfigurationException e) { - app.logEvent ("Couldn't initialize extension " + ext.getName () + ": " + e.getMessage ()); - } - } + public void init(Application app, RequestEvaluator reval) { + this.app = app; + this.reval = reval; + wrappercache = new CacheMap(200, .75f); + prototypes = new Hashtable(); - // fake a cache member like the one found in ESNodes - global.putHiddenProperty ("cache", new ESNode (new TransientNode ("cache"), this)); - global.putHiddenProperty ("undefined", ESUndefined.theUndefined); - ESBeanWrapper appnode = new ESBeanWrapper (new ApplicationBean (app), this); - global.putHiddenProperty ("app", appnode); - initialize(); - } catch (Exception e) { - System.err.println("Cannot initialize interpreter"); - System.err.println("Error: " + e); - e.printStackTrace (); - throw new RuntimeException (e.getMessage ()); - } + try { + evaluator = new Evaluator(this); + global = evaluator.getGlobalObject(); + + for (int i = 0; i < extensions.length; i++) + evaluator.addExtension(extensions[i]); + + HopExtension hopx = new HopExtension(app); + + hopx.initializeExtension(this); + + MailExtension mailx = (MailExtension) evaluator.addExtension("helma.scripting.fesi.extensions.MailExtension"); + + mailx.setProperties(app.getProperties()); + + Database dbx = (Database) evaluator.addExtension("helma.scripting.fesi.extensions.Database"); + + dbx.setApplication(app); + + // load extensions defined in server.properties: + extensionGlobals = new HashMap(); + + Vector extVec = Server.getServer().getExtensions(); + + for (int i = 0; i < extVec.size(); i++) { + HelmaExtension ext = (HelmaExtension) extVec.get(i); + + try { + HashMap tmpGlobals = ext.initScripting(app, this); + + if (tmpGlobals != null) { + extensionGlobals.putAll(tmpGlobals); + } + } catch (ConfigurationException e) { + app.logEvent("Couldn't initialize extension " + ext.getName() + ": " + + e.getMessage()); + } + } + + // fake a cache member like the one found in ESNodes + global.putHiddenProperty("cache", new ESNode(new TransientNode("cache"), this)); + global.putHiddenProperty("undefined", ESUndefined.theUndefined); + + ESBeanWrapper appnode = new ESBeanWrapper(new ApplicationBean(app), this); + + global.putHiddenProperty("app", appnode); + initialize(); + } catch (Exception e) { + System.err.println("Cannot initialize interpreter"); + System.err.println("Error: " + e); + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } } /** * Initialize the evaluator, making sure the minimum type information * necessary to bootstrap the rest is parsed. */ - private void initialize () { - // set the thread filed in the FESI evaluator - evaluator.thread = Thread.currentThread (); - Collection protos = app.getPrototypes(); - for (Iterator i=protos.iterator(); i.hasNext(); ) { - Prototype proto = (Prototype) i.next (); - initPrototype (proto); - } - // always fully initialize global prototype, because - // we always need it and there's no chance to trigger - // creation on demand. - getPrototype ("global"); - evaluator.thread = null; + private void initialize() { + // set the thread filed in the FESI evaluator + evaluator.thread = Thread.currentThread(); + + Collection protos = app.getPrototypes(); + + for (Iterator i = protos.iterator(); i.hasNext();) { + Prototype proto = (Prototype) i.next(); + + initPrototype(proto); + } + + // always fully initialize global prototype, because + // we always need it and there's no chance to trigger + // creation on demand. + getPrototype("global"); + evaluator.thread = null; } /** * Initialize a prototype without fully parsing its script files. */ - void initPrototype (Prototype prototype) { - // System.err.println ("FESI INIT PROTO "+prototype); - ObjectPrototype op = null; + void initPrototype(Prototype prototype) { + // System.err.println ("FESI INIT PROTO "+prototype); + ObjectPrototype op = null; - // get the prototype's prototype if possible and necessary - ObjectPrototype opp = null; - Prototype parent = prototype.getParentPrototype (); - if (parent != null) { - // see if parent prototype is already registered. if not, register it - opp = getRawPrototype (parent.getName ()); - if (opp == null) { - initPrototype (parent); - opp = getRawPrototype (parent.getName ()); - } - } - String name = prototype.getName (); - if (!"global".equalsIgnoreCase (name) && - !"hopobject".equalsIgnoreCase (name) && - opp == null) - { - if (app.isJavaPrototype (name)) - opp = getRawPrototype ("__javaobject__"); - else - opp = getRawPrototype ("hopobject"); - } + // get the prototype's prototype if possible and necessary + ObjectPrototype opp = null; + Prototype parent = prototype.getParentPrototype(); - // if prototype doesn't exist (i.e. is a standard prototype built by HopExtension), create it. - op = getRawPrototype (name); - if (op == null) { - op = new ObjectPrototype (opp, evaluator); - try { - op.putProperty ("prototypename", new ESString (name), "prototypename".hashCode ()); - } catch (EcmaScriptException ignore) {} - putPrototype (name, op); - } else { - // set parent prototype just in case it has been changed - op.setPrototype (opp); - } + if (parent != null) { + // see if parent prototype is already registered. if not, register it + opp = getRawPrototype(parent.getName()); - // Register a constructor for all types except global. - // This will first create a new prototyped hopobject and then calls - // the actual (scripted) constructor on it. - if (!"global".equalsIgnoreCase (name) && !"root".equalsIgnoreCase (name)) { - try { - FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype(); - global.putHiddenProperty (name, new NodeConstructor (name, fp, this)); - } catch (EcmaScriptException ignore) {} - } - // app.typemgr.updatePrototype (prototype.getName()); - // evaluatePrototype (prototype); + if (opp == null) { + initPrototype(parent); + opp = getRawPrototype(parent.getName()); + } + } + + String name = prototype.getName(); + + if (!"global".equalsIgnoreCase(name) && !"hopobject".equalsIgnoreCase(name) && + (opp == null)) { + if (app.isJavaPrototype(name)) { + opp = getRawPrototype("__javaobject__"); + } else { + opp = getRawPrototype("hopobject"); + } + } + + // if prototype doesn't exist (i.e. is a standard prototype built by HopExtension), create it. + op = getRawPrototype(name); + + if (op == null) { + op = new ObjectPrototype(opp, evaluator); + + try { + op.putProperty("prototypename", new ESString(name), + "prototypename".hashCode()); + } catch (EcmaScriptException ignore) { + } + + putPrototype(name, op); + } else { + // set parent prototype just in case it has been changed + op.setPrototype(opp); + } + + // Register a constructor for all types except global. + // This will first create a new prototyped hopobject and then calls + // the actual (scripted) constructor on it. + if (!"global".equalsIgnoreCase(name) && !"root".equalsIgnoreCase(name)) { + try { + FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype(); + + global.putHiddenProperty(name, new NodeConstructor(name, fp, this)); + } catch (EcmaScriptException ignore) { + } + } + + // app.typemgr.updatePrototype (prototype.getName()); + // evaluatePrototype (prototype); } /** * Set up a prototype, parsing and compiling all its script files. */ - void evaluatePrototype (Prototype prototype) { - // System.err.println ("FESI EVALUATE PROTO "+prototype+" FOR "+this); - ObjectPrototype op = null; + void evaluatePrototype(Prototype prototype) { + // System.err.println ("FESI EVALUATE PROTO "+prototype+" FOR "+this); + ObjectPrototype op = null; - // get the prototype's prototype if possible and necessary - ObjectPrototype opp = null; - Prototype parent = prototype.getParentPrototype (); - if (parent != null) { - // see if parent prototype is already registered. if not, register it - opp = getPrototype (parent.getName ()); - if (opp == null) { - evaluatePrototype (parent); - opp = getPrototype (parent.getName ()); - } - } - String name = prototype.getName (); - if (!"global".equalsIgnoreCase (name) && !"hopobject".equalsIgnoreCase (name) && opp == null) { - if (app.isJavaPrototype (name)) - opp = getPrototype ("__javaobject__"); - else - opp = getPrototype ("hopobject"); - } - // if prototype doesn't exist (i.e. is a standard prototype built by HopExtension), create it. - op = getPrototype (name); - if (op == null) { - op = new ObjectPrototype (opp, evaluator); - try { - op.putProperty ("prototypename", new ESString (name), "prototypename".hashCode ()); - } catch (EcmaScriptException ignore) {} - putPrototype (name, op); - } else { - // reset prototype to original state - resetPrototype (op); - // set parent prototype just in case it has been changed - op.setPrototype (opp); - } + // get the prototype's prototype if possible and necessary + ObjectPrototype opp = null; + Prototype parent = prototype.getParentPrototype(); - // Register a constructor for all types except global. - // This will first create a new prototyped hopobject and then calls - // the actual (scripted) constructor on it. - if (!"global".equalsIgnoreCase (name) && !"root".equalsIgnoreCase (name)) { - try { - FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype(); - global.putHiddenProperty (name, new NodeConstructor (name, fp, this)); - } catch (EcmaScriptException ignore) {} - } - for (Iterator it = prototype.getZippedCode().values().iterator(); it.hasNext(); ) { - Object code = it.next(); - evaluate (prototype, code); - } - for (Iterator it = prototype.getCode().values().iterator(); it.hasNext(); ) { - Object code = it.next(); - evaluate (prototype, code); - } + if (parent != null) { + // see if parent prototype is already registered. if not, register it + opp = getPrototype(parent.getName()); + + if (opp == null) { + evaluatePrototype(parent); + opp = getPrototype(parent.getName()); + } + } + + String name = prototype.getName(); + + if (!"global".equalsIgnoreCase(name) && !"hopobject".equalsIgnoreCase(name) && + (opp == null)) { + if (app.isJavaPrototype(name)) { + opp = getPrototype("__javaobject__"); + } else { + opp = getPrototype("hopobject"); + } + } + + // if prototype doesn't exist (i.e. is a standard prototype built by HopExtension), create it. + op = getPrototype(name); + + if (op == null) { + op = new ObjectPrototype(opp, evaluator); + + try { + op.putProperty("prototypename", new ESString(name), + "prototypename".hashCode()); + } catch (EcmaScriptException ignore) { + } + + putPrototype(name, op); + } else { + // reset prototype to original state + resetPrototype(op); + + // set parent prototype just in case it has been changed + op.setPrototype(opp); + } + + // Register a constructor for all types except global. + // This will first create a new prototyped hopobject and then calls + // the actual (scripted) constructor on it. + if (!"global".equalsIgnoreCase(name) && !"root".equalsIgnoreCase(name)) { + try { + FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype(); + + global.putHiddenProperty(name, new NodeConstructor(name, fp, this)); + } catch (EcmaScriptException ignore) { + } + } + + for (Iterator it = prototype.getZippedCode().values().iterator(); it.hasNext();) { + Object code = it.next(); + + evaluate(prototype, code); + } + + for (Iterator it = prototype.getCode().values().iterator(); it.hasNext();) { + Object code = it.next(); + + evaluate(prototype, code); + } } /** * Return an object prototype to its initial state, removing all application specific * functions. */ - void resetPrototype (ObjectPrototype op) { - for (Enumeration en = op.getAllProperties(); en.hasMoreElements(); ) { - String prop = en.nextElement ().toString (); - try { - ESValue esv = op.getProperty (prop, prop.hashCode ()); - if (esv instanceof ConstructedFunctionObject || esv instanceof FesiActionAdapter.ThrowException) - op.deleteProperty (prop, prop.hashCode()); - } catch (Exception x) {} - } + void resetPrototype(ObjectPrototype op) { + for (Enumeration en = op.getAllProperties(); en.hasMoreElements();) { + String prop = en.nextElement().toString(); + + try { + ESValue esv = op.getProperty(prop, prop.hashCode()); + + if (esv instanceof ConstructedFunctionObject || + esv instanceof FesiActionAdapter.ThrowException) { + op.deleteProperty(prop, prop.hashCode()); + } + } catch (Exception x) { + } + } } /** * This method is called before an execution context is entered to let the * engine know it should update its prototype information. */ - public void updatePrototypes () { - // set the thread filed in the FESI evaluator - evaluator.thread = Thread.currentThread (); - Collection protos = app.getPrototypes(); - for (Iterator i=protos.iterator(); i.hasNext(); ) { - Prototype proto = (Prototype) i.next (); - TypeInfo info = (TypeInfo) prototypes.get (proto.getName()); - if (info == null) { - // a prototype we don't know anything about yet. Init local update info. - initPrototype (proto); - info = (TypeInfo) prototypes.get (proto.getName()); - } - // only update prototype if it has already been initialized. - // otherwise, this will be done on demand - // System.err.println ("CHECKING PROTO: "+info); - if (info.lastUpdate > 0) { - Prototype p = app.typemgr.getPrototype (info.protoName); - if (p != null) { - // System.err.println ("UPDATING PROTO: "+p); - app.typemgr.updatePrototype(p); - if (p.getLastUpdate () > info.lastUpdate) { - evaluatePrototype(p); - info.lastUpdate = p.getLastUpdate (); - } - } - } - } + public void updatePrototypes() { + // set the thread filed in the FESI evaluator + evaluator.thread = Thread.currentThread(); + + Collection protos = app.getPrototypes(); + + for (Iterator i = protos.iterator(); i.hasNext();) { + Prototype proto = (Prototype) i.next(); + TypeInfo info = (TypeInfo) prototypes.get(proto.getName()); + + if (info == null) { + // a prototype we don't know anything about yet. Init local update info. + initPrototype(proto); + info = (TypeInfo) prototypes.get(proto.getName()); + } + + // only update prototype if it has already been initialized. + // otherwise, this will be done on demand + // System.err.println ("CHECKING PROTO: "+info); + if (info.lastUpdate > 0) { + Prototype p = app.typemgr.getPrototype(info.protoName); + + if (p != null) { + // System.err.println ("UPDATING PROTO: "+p); + app.typemgr.updatePrototype(p); + + if (p.getLastUpdate() > info.lastUpdate) { + evaluatePrototype(p); + info.lastUpdate = p.getLastUpdate(); + } + } + } + } } /** @@ -304,138 +380,170 @@ public class FesiEngine implements ScriptingEngine { * evaluation is entered. The globals parameter contains the global values * to be applied during this execution context. */ - public void enterContext (HashMap globals) throws ScriptingException { - // set the thread filed in the FESI evaluator - evaluator.thread = Thread.currentThread (); - // set globals on the global object - globals.putAll(extensionGlobals); - if (globals != null && globals != lastGlobals) { - // loop through global vars and set them - for (Iterator i=globals.keySet().iterator(); i.hasNext(); ) { - String k = (String) i.next(); - Object v = globals.get (k); - ESValue sv = null; - try { - // we do a lot of extra work to make access to global variables - // comfortable to EcmaScript coders, i.e. we use a lot of custom wrappers - // that expose properties and functions in a special way instead of just going - // with the standard java object wrappers. - if (v instanceof Map) { - sv = new ESMapWrapper (this, (Map) v); - } else if ("path".equals (k)) { - ArrayPrototype parr = new ArrayPrototype (evaluator.getArrayPrototype(), evaluator); - List path = (List) v; - // register path elements with their prototype - for (int j=0; j<path.size(); j++) { - Object pathElem = path.get (j); - ESValue wrappedElement = getElementWrapper (pathElem); - parr.putProperty (j, wrappedElement); - String protoname = app.getPrototypeName (pathElem); - if (protoname != null) - parr.putHiddenProperty (protoname, wrappedElement); - } - sv = parr; - } else if ("req".equals (k)) { - sv = new ESBeanWrapper (v, this); - } else if ("res".equals (k)) { - sv = new ESBeanWrapper (v, this); - } else if ("session".equals (k)) { - sv = new ESBeanWrapper (v, this); - } else if ("app".equals (k)) { - sv = new ESBeanWrapper (v, this); - } else if (v instanceof ESValue) { - sv = (ESValue)v; - } else { - sv = ESLoader.normalizeValue (v, evaluator); - } - global.putHiddenProperty (k, sv); - } catch (Exception x) { - app.logEvent ("Error setting global variable "+k+": "+x); - } - } - } - // remember the globals set on this evaluator - lastGlobals = globals; + public void enterContext(HashMap globals) throws ScriptingException { + // set the thread filed in the FESI evaluator + evaluator.thread = Thread.currentThread(); + + // set globals on the global object + globals.putAll(extensionGlobals); + + if ((globals != null) && (globals != lastGlobals)) { + // loop through global vars and set them + for (Iterator i = globals.keySet().iterator(); i.hasNext();) { + String k = (String) i.next(); + Object v = globals.get(k); + ESValue sv = null; + + try { + // we do a lot of extra work to make access to global variables + // comfortable to EcmaScript coders, i.e. we use a lot of custom wrappers + // that expose properties and functions in a special way instead of just going + // with the standard java object wrappers. + if (v instanceof Map) { + sv = new ESMapWrapper(this, (Map) v); + } else if ("path".equals(k)) { + ArrayPrototype parr = new ArrayPrototype(evaluator.getArrayPrototype(), + evaluator); + List path = (List) v; + + // register path elements with their prototype + for (int j = 0; j < path.size(); j++) { + Object pathElem = path.get(j); + ESValue wrappedElement = getElementWrapper(pathElem); + + parr.putProperty(j, wrappedElement); + + String protoname = app.getPrototypeName(pathElem); + + if (protoname != null) { + parr.putHiddenProperty(protoname, wrappedElement); + } + } + + sv = parr; + } else if ("req".equals(k)) { + sv = new ESBeanWrapper(v, this); + } else if ("res".equals(k)) { + sv = new ESBeanWrapper(v, this); + } else if ("session".equals(k)) { + sv = new ESBeanWrapper(v, this); + } else if ("app".equals(k)) { + sv = new ESBeanWrapper(v, this); + } else if (v instanceof ESValue) { + sv = (ESValue) v; + } else { + sv = ESLoader.normalizeValue(v, evaluator); + } + + global.putHiddenProperty(k, sv); + } catch (Exception x) { + app.logEvent("Error setting global variable " + k + ": " + x); + } + } + } + + // remember the globals set on this evaluator + lastGlobals = globals; } /** * This method is called to let the scripting engine know that the current * execution context has terminated. */ - public void exitContext () { - // unset the thread filed in the FESI evaluator - evaluator.thread = null; - // loop through previous globals and unset them, if necessary. - if (lastGlobals != null) { - for (Iterator i=lastGlobals.keySet().iterator(); i.hasNext(); ) { - String g = (String) i.next (); - try { - global.deleteProperty (g, g.hashCode()); - } catch (Exception x) { - System.err.println ("Error resetting global property: "+g); - } - } - lastGlobals = null; - } - } + public void exitContext() { + // unset the thread filed in the FESI evaluator + evaluator.thread = null; + // loop through previous globals and unset them, if necessary. + if (lastGlobals != null) { + for (Iterator i = lastGlobals.keySet().iterator(); i.hasNext();) { + String g = (String) i.next(); + + try { + global.deleteProperty(g, g.hashCode()); + } catch (Exception x) { + System.err.println("Error resetting global property: " + g); + } + } + + lastGlobals = null; + } + } /** * Invoke a function on some object, using the given arguments and global vars. */ - public Object invoke (Object thisObject, String functionName, Object[] args, boolean xmlrpc) throws ScriptingException { - ESObject eso = null; - if (thisObject == null) - eso = global; - else - eso = getElementWrapper (thisObject); - // Workaround to let the evaluator know about the current thread - // even if enterContext() has not been called yet. Otherwise, - // a TimeoutException would be thrown. - evaluator.thread = Thread.currentThread (); - try { - ESValue[] esv = args == null ? new ESValue[0] : new ESValue[args.length]; - for (int i=0; i<esv.length; i++) { - // XML-RPC requires special argument conversion - if (xmlrpc) - esv[i] = processXmlRpcArgument (args[i], evaluator); - // for java.util.Map objects, we use the special "tight" wrapper - // that makes the Map look like a native object - else if (args[i] instanceof Map) - esv[i] = new ESMapWrapper (this, (Map) args[i]); - else - esv[i] = ESLoader.normalizeValue (args[i], evaluator); - } - ESValue retval = eso.doIndirectCall (evaluator, eso, functionName, esv); - if (xmlrpc) - return processXmlRpcResponse (retval); - else if (retval == null) - return null; - else - return retval.toJavaObject (); - } catch (RedirectException redirect) { - throw redirect; - } catch (TimeoutException timeout) { - throw timeout; - } catch (ConcurrencyException concur) { - throw concur; - } catch (Exception x) { - // check if this is a redirect exception, which has been converted by fesi - // into an EcmaScript exception, which is why we can't explicitly catch it - if (reval.res.getRedirect() != null) - throw new RedirectException (reval.res.getRedirect ()); - // do the same for not-modified responses - if (reval.res.getNotModified()) - throw new RedirectException (null); - // has the request timed out? If so, throw TimeoutException - if (evaluator.thread != Thread.currentThread()) - throw new TimeoutException (); - if (app.debug ()) { - x.printStackTrace (); - } - // create and throw a ScriptingException wrapping the original exception - throw new ScriptingException (x); - } + public Object invoke(Object thisObject, String functionName, Object[] args, + boolean xmlrpc) throws ScriptingException { + ESObject eso = null; + + if (thisObject == null) { + eso = global; + } else { + eso = getElementWrapper(thisObject); + } + + // Workaround to let the evaluator know about the current thread + // even if enterContext() has not been called yet. Otherwise, + // a TimeoutException would be thrown. + evaluator.thread = Thread.currentThread(); + + try { + ESValue[] esv = (args == null) ? new ESValue[0] : new ESValue[args.length]; + + for (int i = 0; i < esv.length; i++) { + // XML-RPC requires special argument conversion + if (xmlrpc) { + esv[i] = processXmlRpcArgument(args[i], evaluator); + } + // for java.util.Map objects, we use the special "tight" wrapper + // that makes the Map look like a native object + else if (args[i] instanceof Map) { + esv[i] = new ESMapWrapper(this, (Map) args[i]); + } else { + esv[i] = ESLoader.normalizeValue(args[i], evaluator); + } + } + + ESValue retval = eso.doIndirectCall(evaluator, eso, functionName, esv); + + if (xmlrpc) { + return processXmlRpcResponse(retval); + } else if (retval == null) { + return null; + } else { + return retval.toJavaObject(); + } + } catch (RedirectException redirect) { + throw redirect; + } catch (TimeoutException timeout) { + throw timeout; + } catch (ConcurrencyException concur) { + throw concur; + } catch (Exception x) { + // check if this is a redirect exception, which has been converted by fesi + // into an EcmaScript exception, which is why we can't explicitly catch it + if (reval.res.getRedirect() != null) { + throw new RedirectException(reval.res.getRedirect()); + } + + // do the same for not-modified responses + if (reval.res.getNotModified()) { + throw new RedirectException(null); + } + + // has the request timed out? If so, throw TimeoutException + if (evaluator.thread != Thread.currentThread()) { + throw new TimeoutException(); + } + + if (app.debug()) { + x.printStackTrace(); + } + + // create and throw a ScriptingException wrapping the original exception + throw new ScriptingException(x); + } } /** @@ -443,248 +551,320 @@ public class FesiEngine implements ScriptingEngine { * aborted. This is done by setting the thread ref in the evaluator * object to null. */ - public void abort () { - // unset the thread filed in the FESI evaluator - evaluator.thread = null; + public void abort() { + // unset the thread filed in the FESI evaluator + evaluator.thread = null; } - /** * Check if an object has a function property (public method if it * is a java object) with that name. */ - public boolean hasFunction (Object obj, String fname) { - // System.err.println ("HAS_FUNC: "+fname); - String protoname = app.getPrototypeName (obj); - try { - ObjectPrototype op = getPrototype (protoname); - // if this is an untyped object return false - if (op == null) - return false; - ESValue func = op.getProperty (fname, fname.hashCode()); - if (func != null && func instanceof FunctionPrototype) - return true; - } catch (EcmaScriptException esx) { - // System.err.println ("Error in hasFunction: "+esx); - return false; - } - return false; - } + public boolean hasFunction(Object obj, String fname) { + // System.err.println ("HAS_FUNC: "+fname); + String protoname = app.getPrototypeName(obj); + try { + ObjectPrototype op = getPrototype(protoname); + + // if this is an untyped object return false + if (op == null) { + return false; + } + + ESValue func = op.getProperty(fname, fname.hashCode()); + + if ((func != null) && func instanceof FunctionPrototype) { + return true; + } + } catch (EcmaScriptException esx) { + // System.err.println ("Error in hasFunction: "+esx); + return false; + } + + return false; + } /** * Check if an object has a defined property (public field if it * is a java object) with that name. */ - public Object get (Object obj, String propname) { - if (obj == null || propname == null) - return null; + public Object get(Object obj, String propname) { + if ((obj == null) || (propname == null)) { + return null; + } - String prototypeName = app.getPrototypeName (obj); - if ("user".equalsIgnoreCase (prototypeName) && - "password".equalsIgnoreCase (propname)) - throw new RuntimeException ("access to password property not allowed"); + String prototypeName = app.getPrototypeName(obj); - // if this is a HopObject, check if the property is defined - // in the type.properties db-mapping. - if (obj instanceof INode) { - DbMapping dbm = app.getDbMapping (prototypeName); - if (dbm != null) { - Relation rel = dbm.propertyToRelation (propname); - if (rel == null || !rel.isPrimitive ()) - throw new RuntimeException ("\""+propname+"\" is not defined in "+prototypeName); - } - } + if ("user".equalsIgnoreCase(prototypeName) && + "password".equalsIgnoreCase(propname)) { + throw new RuntimeException("access to password property not allowed"); + } - ESObject eso = getElementWrapper (obj); - try { - ESValue prop = eso.getProperty (propname, propname.hashCode()); - if (prop != null && !(prop instanceof ESNull) && - !(prop instanceof ESUndefined)) - return prop.toJavaObject (); - } catch (EcmaScriptException esx) { - // System.err.println ("Error in getProperty: "+esx); - return null; - } - return null; + // if this is a HopObject, check if the property is defined + // in the type.properties db-mapping. + if (obj instanceof INode) { + DbMapping dbm = app.getDbMapping(prototypeName); + + if (dbm != null) { + Relation rel = dbm.propertyToRelation(propname); + + if ((rel == null) || !rel.isPrimitive()) { + throw new RuntimeException("\"" + propname + "\" is not defined in " + + prototypeName); + } + } + } + + ESObject eso = getElementWrapper(obj); + + try { + ESValue prop = eso.getProperty(propname, propname.hashCode()); + + if ((prop != null) && !(prop instanceof ESNull) && + !(prop instanceof ESUndefined)) { + return prop.toJavaObject(); + } + } catch (EcmaScriptException esx) { + // System.err.println ("Error in getProperty: "+esx); + return null; + } + + return null; } - /** + /** * Get a DocApplication object for a specific application. */ - public IPathElement getIntrospector () { - if (doc == null) { - doc = new DocApplication (app.getName(), app.getAppDir().toString()); - doc.readApplication (); - } - return doc; - } + public IPathElement getIntrospector() { + if (doc == null) { + doc = new DocApplication(app.getName(), app.getAppDir().toString()); + doc.readApplication(); + } + return doc; + } /** * Convert an input argument from Java to the scripting runtime * representation. */ - public static ESValue processXmlRpcArgument (Object what, Evaluator evaluator) throws Exception { - if (what == null) - return ESNull.theNull; - if (what instanceof Vector) { - Vector v = (Vector) what; - ArrayPrototype retval = new ArrayPrototype (evaluator.getArrayPrototype (), evaluator); - int l = v.size (); - for (int i=0; i<l; i++) - retval.putProperty (i, processXmlRpcArgument (v.elementAt (i), evaluator)); - return retval; - } - if (what instanceof Hashtable) { - Hashtable t = (Hashtable) what; - ESObject retval = new ObjectPrototype (evaluator.getObjectPrototype (), evaluator); - for (Enumeration e=t.keys(); e.hasMoreElements(); ) { - String next = (String) e.nextElement (); - retval.putProperty (next, processXmlRpcArgument (t.get (next), evaluator), next.hashCode ()); - } - return retval; - } - if (what instanceof String) - return new ESString (what.toString ()); - if (what instanceof Number) - return new ESNumber (new Double (what.toString ()).doubleValue ()); - if (what instanceof Boolean) - return ESBoolean.makeBoolean (((Boolean) what).booleanValue ()); - if (what instanceof Date) - return new DatePrototype (evaluator, (Date) what); - return ESLoader.normalizeValue (what, evaluator); - } + public static ESValue processXmlRpcArgument(Object what, Evaluator evaluator) + throws Exception { + if (what == null) { + return ESNull.theNull; + } + if (what instanceof Vector) { + Vector v = (Vector) what; + ArrayPrototype retval = new ArrayPrototype(evaluator.getArrayPrototype(), + evaluator); + int l = v.size(); + + for (int i = 0; i < l; i++) + retval.putProperty(i, processXmlRpcArgument(v.elementAt(i), evaluator)); + + return retval; + } + + if (what instanceof Hashtable) { + Hashtable t = (Hashtable) what; + ESObject retval = new ObjectPrototype(evaluator.getObjectPrototype(), + evaluator); + + for (Enumeration e = t.keys(); e.hasMoreElements();) { + String next = (String) e.nextElement(); + + retval.putProperty(next, processXmlRpcArgument(t.get(next), evaluator), + next.hashCode()); + } + + return retval; + } + + if (what instanceof String) { + return new ESString(what.toString()); + } + + if (what instanceof Number) { + return new ESNumber(new Double(what.toString()).doubleValue()); + } + + if (what instanceof Boolean) { + return ESBoolean.makeBoolean(((Boolean) what).booleanValue()); + } + + if (what instanceof Date) { + return new DatePrototype(evaluator, (Date) what); + } + + return ESLoader.normalizeValue(what, evaluator); + } /** * convert a JavaScript Object object to a generic Java object stucture. */ - public static Object processXmlRpcResponse (ESValue what) throws EcmaScriptException { - if (what == null || what instanceof ESNull) - return null; - if (what instanceof ArrayPrototype) { - ArrayPrototype a = (ArrayPrototype) what; - int l = a.size (); - Vector v = new Vector (); - for (int i=0; i<l; i++) { - Object nj = processXmlRpcResponse (a.getProperty (i)); - v.addElement (nj); - } - return v; - } - if (what instanceof ObjectPrototype) { - ObjectPrototype o = (ObjectPrototype) what; - Hashtable t = new Hashtable (); - for (Enumeration e=o.getProperties (); e.hasMoreElements (); ) { - String next = (String) e.nextElement (); - // We don't do deep serialization of HopObjects to avoid - // that the whole web site structure is sucked out with one - // object. Instead we return some kind of "proxy" objects - // that only contain the prototype and id of the HopObject property. - Object nj = null; - ESValue esv = o.getProperty (next, next.hashCode ()); - if (esv instanceof ESNode) { - INode node = ((ESNode) esv).getNode (); - if (node != null) { - Hashtable nt = new Hashtable (); - nt.put ("id", node.getID()); - if (node.getPrototype() != null) - nt.put ("prototype", node.getPrototype ()); - nj = nt; - } - } else - nj = processXmlRpcResponse (esv); - if (nj != null) // can't put null as value in hashtable - t.put (next, nj); - } - return t; - } - if (what instanceof ESUndefined || what instanceof ESNull) - return null; - Object jval = what.toJavaObject (); - if (jval instanceof Byte || jval instanceof Short) - jval = new Integer (jval.toString ()); - return jval; - } + public static Object processXmlRpcResponse(ESValue what) + throws EcmaScriptException { + if ((what == null) || what instanceof ESNull) { + return null; + } + if (what instanceof ArrayPrototype) { + ArrayPrototype a = (ArrayPrototype) what; + int l = a.size(); + Vector v = new Vector(); + + for (int i = 0; i < l; i++) { + Object nj = processXmlRpcResponse(a.getProperty(i)); + + v.addElement(nj); + } + + return v; + } + + if (what instanceof ObjectPrototype) { + ObjectPrototype o = (ObjectPrototype) what; + Hashtable t = new Hashtable(); + + for (Enumeration e = o.getProperties(); e.hasMoreElements();) { + String next = (String) e.nextElement(); + + // We don't do deep serialization of HopObjects to avoid + // that the whole web site structure is sucked out with one + // object. Instead we return some kind of "proxy" objects + // that only contain the prototype and id of the HopObject property. + Object nj = null; + ESValue esv = o.getProperty(next, next.hashCode()); + + if (esv instanceof ESNode) { + INode node = ((ESNode) esv).getNode(); + + if (node != null) { + Hashtable nt = new Hashtable(); + + nt.put("id", node.getID()); + + if (node.getPrototype() != null) { + nt.put("prototype", node.getPrototype()); + } + + nj = nt; + } + } else { + nj = processXmlRpcResponse(esv); + } + + if (nj != null) { // can't put null as value in hashtable + t.put(next, nj); + } + } + + return t; + } + + if (what instanceof ESUndefined || what instanceof ESNull) { + return null; + } + + Object jval = what.toJavaObject(); + + if (jval instanceof Byte || jval instanceof Short) { + jval = new Integer(jval.toString()); + } + + return jval; + } /** * Return the FESI Evaluator object wrapped by this object. */ - public Evaluator getEvaluator () { - return evaluator; + public Evaluator getEvaluator() { + return evaluator; } /** * Return the application we're running in */ - public Application getApplication () { - return app; + public Application getApplication() { + return app; } - /** * Get a raw prototype, i.e. in potentially unfinished state * without checking if it needs to be updated. - */ - private ObjectPrototype getRawPrototype (String protoName) { - if (protoName == null) + */ + private ObjectPrototype getRawPrototype(String protoName) { + if (protoName == null) { return null; - TypeInfo info = (TypeInfo) prototypes.get (protoName); - return info == null? null : info.objectPrototype; + } + + TypeInfo info = (TypeInfo) prototypes.get(protoName); + + return (info == null) ? null : info.objectPrototype; } /** * Get the object prototype for a prototype name and initialize/update it * if necessary. */ - public ObjectPrototype getPrototype (String protoName) { - if (protoName == null) + public ObjectPrototype getPrototype(String protoName) { + if (protoName == null) { return null; - TypeInfo info = (TypeInfo) prototypes.get (protoName); - if (info != null && info.lastUpdate == 0) { - Prototype p = app.typemgr.getPrototype (protoName); + } + + TypeInfo info = (TypeInfo) prototypes.get(protoName); + + if ((info != null) && (info.lastUpdate == 0)) { + Prototype p = app.typemgr.getPrototype(protoName); + if (p != null) { app.typemgr.updatePrototype(p); - if (p.getLastUpdate () > info.lastUpdate) { - info.lastUpdate = p.getLastUpdate (); + + if (p.getLastUpdate() > info.lastUpdate) { + info.lastUpdate = p.getLastUpdate(); evaluatePrototype(p); } - // set info.lastUpdate to 1 if it is 0 so we know we - // have initialized this prototype already, even if - // it is empty (i.e. doesn't contain any scripts/skins/actoins - if (info.lastUpdate == 0) - info.lastUpdate = 1; + + // set info.lastUpdate to 1 if it is 0 so we know we + // have initialized this prototype already, even if + // it is empty (i.e. doesn't contain any scripts/skins/actoins + if (info.lastUpdate == 0) { + info.lastUpdate = 1; + } } } - return info == null? null : info.objectPrototype; + + return (info == null) ? null : info.objectPrototype; } /** * Register an object prototype for a certain prototype name. */ - public void putPrototype (String protoName, ObjectPrototype op) { - if (protoName != null && op != null) - prototypes.put (protoName, new TypeInfo (op, protoName)); + public void putPrototype(String protoName, ObjectPrototype op) { + if ((protoName != null) && (op != null)) { + prototypes.put(protoName, new TypeInfo(op, protoName)); + } } - /** * Get a Script wrapper for an object. In contrast to getElementWrapper, this is called for * any Java object, not just the ones in the request path which we know are scripted. * So what we do is check if the object belongs to a scripted class. If so, we call getElementWrapper() * with the object, otherwise we return a generic unscripted object wrapper. */ - public ESValue getObjectWrapper (Object e) { - if (app.getPrototypeName (e) != null) - return getElementWrapper (e); - /* else if (e instanceof Map) - return new ESMapWrapper (this, (Map) e); */ - /* else if (e instanceof INode) - return new ESNode ((INode) e, this); */ - else - return new ESWrapper (e, evaluator); + public ESValue getObjectWrapper(Object e) { + if (app.getPrototypeName(e) != null) { + return getElementWrapper(e); + } + /* else if (e instanceof Map) + return new ESMapWrapper (this, (Map) e); */ + /* else if (e instanceof INode) + return new ESNode ((INode) e, this); */ + else { + return new ESWrapper(e, evaluator); + } } /** @@ -692,36 +872,37 @@ public class FesiEngine implements ScriptingEngine { * interface, the getPrototype method will be used to retrieve the name of the prototype * to use. Otherwise, a Java-Class-to-Script-Prototype mapping is consulted. */ - public ESObject getElementWrapper (Object e) { + public ESObject getElementWrapper(Object e) { + // check if e is an instance of a helma objectmodel node. + if (e instanceof INode) { + return getNodeWrapper((INode) e); + } - // check if e is an instance of a helma objectmodel node. - if (e instanceof INode) - return getNodeWrapper ((INode) e); + // Gotta find out the prototype name to use for this object... + String prototypeName = app.getPrototypeName(e); - // Gotta find out the prototype name to use for this object... - String prototypeName = app.getPrototypeName (e); - - ObjectPrototype op = getPrototype (prototypeName); + ObjectPrototype op = getPrototype(prototypeName); - if (op == null) - op = getPrototype ("hopobject"); + if (op == null) { + op = getPrototype("hopobject"); + } - return new ESGenericObject (op, evaluator, e); + return new ESGenericObject(op, evaluator, e); } - - /** * Get a script wrapper for an instance of helma.objectmodel.INode */ - public ESNode getNodeWrapper (INode n) { + public ESNode getNodeWrapper(INode n) { // FIXME: should this return ESNull.theNull? - if (n == null) + if (n == null) { return null; + } - ESNode esn = (ESNode) wrappercache.get (n); - if (esn == null || esn.getNode() != n) { - String protoname = n.getPrototype (); + ESNode esn = (ESNode) wrappercache.get(n); + + if ((esn == null) || (esn.getNode() != n)) { + String protoname = n.getPrototype(); ObjectPrototype op = null; @@ -729,123 +910,129 @@ public class FesiEngine implements ScriptingEngine { // this *should* be done on the objectmodel level, but isn't currently // for embedded nodes since there's not enough type info at the objectmodel level // for those nodes. - if (protoname != null && protoname.length() > 0 && n.getDbMapping () == null) { - n.setDbMapping (app.getDbMapping (protoname)); + if ((protoname != null) && (protoname.length() > 0) && + (n.getDbMapping() == null)) { + n.setDbMapping(app.getDbMapping(protoname)); } - op = getPrototype (protoname); + op = getPrototype(protoname); // no prototype found for this node? - if (op == null) + if (op == null) { op = getPrototype("hopobject"); + } - esn = new ESNode (op, evaluator, n, this); + esn = new ESNode(op, evaluator, n, this); + + wrappercache.put(n, esn); - wrappercache.put (n, esn); // app.logEvent ("Wrapper for "+n+" created"); } return esn; } - /** * Register a new Node wrapper with the wrapper cache. This is used by the * Node constructor. */ - public void putNodeWrapper (INode n, ESNode esn) { - wrappercache.put (n, esn); + public void putNodeWrapper(INode n, ESNode esn) { + wrappercache.put(n, esn); } /** * Return the application's classloader */ - public ClassLoader getClassLoader () { - return app.getClassLoader (); + public ClassLoader getClassLoader() { + return app.getClassLoader(); } /** * Return the RequestEvaluator owning and driving this FESI evaluator. */ - public RequestEvaluator getRequestEvaluator () { - return reval; + public RequestEvaluator getRequestEvaluator() { + return reval; } /** * Return the Response object of the current evaluation context. Proxy method to RequestEvaluator. */ - public ResponseTrans getResponse () { - return reval.res; + public ResponseTrans getResponse() { + return reval.res; } /** * Return the Request object of the current evaluation context. Proxy method to RequestEvaluator. */ - public RequestTrans getRequest () { - return reval.req; + public RequestTrans getRequest() { + return reval.req; } - private synchronized void evaluate (Prototype prototype, Object code) { - if (code instanceof FunctionFile) { - FunctionFile funcfile = (FunctionFile) code; - File file = funcfile.getFile (); - if (file != null) { - try { - FileReader fr = new FileReader (file); - EvaluationSource es = new FileEvaluationSource (funcfile.getSourceName(), null); - updateEvaluator (prototype, fr, es); - } catch (IOException iox) { - app.logEvent ("Error updating function file: "+iox); - } - } else { - StringReader reader = new StringReader (funcfile.getContent()); - EvaluationSource es = new FileEvaluationSource (funcfile.getSourceName(), null); - updateEvaluator (prototype, reader, es); - } - } else if (code instanceof ActionFile) { - ActionFile action = (ActionFile) code; - FesiActionAdapter fa = new FesiActionAdapter (action); - try { - fa.updateEvaluator (this); - } catch (EcmaScriptException esx) { - app.logEvent ("Error parsing "+action+": "+esx); - } - } - } + private synchronized void evaluate(Prototype prototype, Object code) { + if (code instanceof FunctionFile) { + FunctionFile funcfile = (FunctionFile) code; + File file = funcfile.getFile(); - - private synchronized void updateEvaluator (Prototype prototype, Reader reader, EvaluationSource source) { - try { - ObjectPrototype op = getPrototype (prototype.getName()); - // do the update, evaluating the file - evaluator.evaluate(reader, op, source, false); - } catch (Throwable e) { - app.logEvent ("Error parsing function file "+source+": "+e); - } finally { - if (reader != null) { + if (file != null) { try { - reader.close(); - } catch (IOException ignore) {} + FileReader fr = new FileReader(file); + EvaluationSource es = new FileEvaluationSource(funcfile.getSourceName(), + null); + + updateEvaluator(prototype, fr, es); + } catch (IOException iox) { + app.logEvent("Error updating function file: " + iox); + } + } else { + StringReader reader = new StringReader(funcfile.getContent()); + EvaluationSource es = new FileEvaluationSource(funcfile.getSourceName(), + null); + + updateEvaluator(prototype, reader, es); + } + } else if (code instanceof ActionFile) { + ActionFile action = (ActionFile) code; + FesiActionAdapter fa = new FesiActionAdapter(action); + + try { + fa.updateEvaluator(this); + } catch (EcmaScriptException esx) { + app.logEvent("Error parsing " + action + ": " + esx); } } } + private synchronized void updateEvaluator(Prototype prototype, Reader reader, + EvaluationSource source) { + try { + ObjectPrototype op = getPrototype(prototype.getName()); + + // do the update, evaluating the file + evaluator.evaluate(reader, op, source, false); + } catch (Throwable e) { + app.logEvent("Error parsing function file " + source + ": " + e); + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException ignore) { + } + } + } + } class TypeInfo { - ObjectPrototype objectPrototype; long lastUpdate = 0; String protoName; - public TypeInfo (ObjectPrototype op, String name) { + public TypeInfo(ObjectPrototype op, String name) { objectPrototype = op; protoName = name; } - public String toString () { - return ("TypeInfo["+protoName+","+new Date(lastUpdate)+"]"); + public String toString() { + return ("TypeInfo[" + protoName + "," + new Date(lastUpdate) + "]"); } - } - } diff --git a/src/helma/scripting/fesi/HopExtension.java b/src/helma/scripting/fesi/HopExtension.java index 5e241596..9b0ed567 100644 --- a/src/helma/scripting/fesi/HopExtension.java +++ b/src/helma/scripting/fesi/HopExtension.java @@ -1,370 +1,576 @@ -// HopExtension.java -// Copyright (c) Hannes Wallnöfer 1998-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.scripting.fesi; -import helma.framework.*; -import helma.framework.core.*; -import helma.objectmodel.*; -import helma.util.*; -import helma.framework.IPathElement; -import helma.scripting.ScriptingException; -import FESI.Interpreter.*; +import FESI.Data.*; import FESI.Exceptions.*; import FESI.Extensions.*; -import FESI.Data.*; +import FESI.Interpreter.*; +import helma.framework.*; +import helma.framework.IPathElement; +import helma.framework.core.*; +import helma.objectmodel.*; +import helma.scripting.ScriptingException; +import helma.util.*; +import org.xml.sax.InputSource; import java.io.*; -import java.util.*; -import java.text.*; +import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; -import java.net.HttpURLConnection; +import java.text.*; import java.text.SimpleDateFormat; -import org.xml.sax.InputSource; +import java.util.*; /** * This is the basic Extension for FESI interpreters used in Helma. It sets up * varios constructors, global functions and properties on the HopObject prototype * (Node objects), the global prototype, the session object etc. */ - public final class HopExtension { - protected Application app; protected FesiEngine engine; - public HopExtension (Application app) { + // previously in FESI.Data.NumberObject + private Hashtable formatTable = new Hashtable(); + + /** + * Creates a new HopExtension object. + * + * @param app ... + */ + public HopExtension(Application app) { this.app = app; } - /** * Called by the evaluator after the extension is loaded. */ - public void initializeExtension (FesiEngine engine) throws EcmaScriptException { + public void initializeExtension(FesiEngine engine) + throws EcmaScriptException { this.engine = engine; - Evaluator evaluator = engine.getEvaluator (); + + Evaluator evaluator = engine.getEvaluator(); GlobalObject go = evaluator.getGlobalObject(); FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype(); ESObject op = evaluator.getObjectPrototype(); // The editor functions for String, Boolean and Number are deprecated! - ESObject sp = evaluator.getStringPrototype (); - sp.putHiddenProperty ("editor", new StringEditor ("editor", evaluator, fp)); - ESObject np = evaluator.getNumberPrototype (); - np.putHiddenProperty ("editor", new NumberEditor ("editor", evaluator, fp)); - np.putHiddenProperty ("format", new NumberPrototypeFormat ("format", evaluator, fp)); - ESObject bp = evaluator.getBooleanPrototype (); - bp.putHiddenProperty ("editor", new BooleanEditor ("editor", evaluator, fp)); - ESObject dp = evaluator.getDatePrototype (); - dp.putHiddenProperty ("format", new DatePrototypeFormat ("format", evaluator, fp)); + ESObject sp = evaluator.getStringPrototype(); - sp.putHiddenProperty ("trim", new StringTrim ("trim", evaluator, fp)); + sp.putHiddenProperty("editor", new StringEditor("editor", evaluator, fp)); + + ESObject np = evaluator.getNumberPrototype(); + + np.putHiddenProperty("editor", new NumberEditor("editor", evaluator, fp)); + np.putHiddenProperty("format", new NumberPrototypeFormat("format", evaluator, fp)); + + ESObject bp = evaluator.getBooleanPrototype(); + + bp.putHiddenProperty("editor", new BooleanEditor("editor", evaluator, fp)); + + ESObject dp = evaluator.getDatePrototype(); + + dp.putHiddenProperty("format", new DatePrototypeFormat("format", evaluator, fp)); + + sp.putHiddenProperty("trim", new StringTrim("trim", evaluator, fp)); // generic (Java wrapper) object prototype - ObjectPrototype esObjectPrototype = new ObjectPrototype (op, evaluator); + ObjectPrototype esObjectPrototype = new ObjectPrototype(op, evaluator); + // the Node prototype ObjectPrototype esNodePrototype = new ObjectPrototype(op, evaluator); + // the Session prototype - ObjectPrototype esSessionPrototype = new ObjectPrototype (esNodePrototype, evaluator); + ObjectPrototype esSessionPrototype = new ObjectPrototype(esNodePrototype, + evaluator); + // the Node constructor - ESObject node = new NodeConstructor ("Node", fp, engine); + ESObject node = new NodeConstructor("Node", fp, engine); // register the default methods of Node objects in the Node prototype - esNodePrototype.putHiddenProperty ("add", new NodeAdd ("add", evaluator, fp)); - esNodePrototype.putHiddenProperty ("addAt", new NodeAddAt ("addAt", evaluator, fp)); - esNodePrototype.putHiddenProperty ("remove", new NodeRemove ("remove", evaluator, fp)); - esNodePrototype.putHiddenProperty ("link", new NodeLink ("link", evaluator, fp)); - esNodePrototype.putHiddenProperty ("list", new NodeList ("list", evaluator, fp)); - esNodePrototype.putHiddenProperty ("set", new NodeSet ("set", evaluator, fp)); - esNodePrototype.putHiddenProperty ("get", new NodeGet ("get", evaluator, fp)); - esNodePrototype.putHiddenProperty ("count", new NodeCount ("count", evaluator, fp)); - esNodePrototype.putHiddenProperty ("contains", new NodeContains ("contains", evaluator, fp)); - esNodePrototype.putHiddenProperty ("size", new NodeCount ("size", evaluator, fp)); - esNodePrototype.putHiddenProperty ("editor", new NodeEditor ("editor", evaluator, fp)); - esNodePrototype.putHiddenProperty ("path", new NodeHref ("path", evaluator, fp)); - esNodePrototype.putHiddenProperty ("href", new NodeHref ("href", evaluator, fp)); - esNodePrototype.putHiddenProperty ("setParent", new NodeSetParent ("setParent", evaluator, fp)); - esNodePrototype.putHiddenProperty ("invalidate", new NodeInvalidate ("invalidate", evaluator, fp)); - esNodePrototype.putHiddenProperty ("prefetchChildren", new NodePrefetch ("prefetchChildren", evaluator, fp)); - esNodePrototype.putHiddenProperty ("renderSkin", new RenderSkin ("renderSkin", evaluator, fp, false, false)); - esNodePrototype.putHiddenProperty ("renderSkinAsString", new RenderSkin ("renderSkinAsString", evaluator, fp, false, true)); - esNodePrototype.putHiddenProperty ("clearCache", new NodeClearCache ("clearCache", evaluator, fp)); + esNodePrototype.putHiddenProperty("add", new NodeAdd("add", evaluator, fp)); + esNodePrototype.putHiddenProperty("addAt", new NodeAddAt("addAt", evaluator, fp)); + esNodePrototype.putHiddenProperty("remove", + new NodeRemove("remove", evaluator, fp)); + esNodePrototype.putHiddenProperty("link", new NodeLink("link", evaluator, fp)); + esNodePrototype.putHiddenProperty("list", new NodeList("list", evaluator, fp)); + esNodePrototype.putHiddenProperty("set", new NodeSet("set", evaluator, fp)); + esNodePrototype.putHiddenProperty("get", new NodeGet("get", evaluator, fp)); + esNodePrototype.putHiddenProperty("count", new NodeCount("count", evaluator, fp)); + esNodePrototype.putHiddenProperty("contains", + new NodeContains("contains", evaluator, fp)); + esNodePrototype.putHiddenProperty("size", new NodeCount("size", evaluator, fp)); + esNodePrototype.putHiddenProperty("editor", + new NodeEditor("editor", evaluator, fp)); + esNodePrototype.putHiddenProperty("path", new NodeHref("path", evaluator, fp)); + esNodePrototype.putHiddenProperty("href", new NodeHref("href", evaluator, fp)); + esNodePrototype.putHiddenProperty("setParent", + new NodeSetParent("setParent", evaluator, fp)); + esNodePrototype.putHiddenProperty("invalidate", + new NodeInvalidate("invalidate", evaluator, fp)); + esNodePrototype.putHiddenProperty("prefetchChildren", + new NodePrefetch("prefetchChildren", evaluator, + fp)); + esNodePrototype.putHiddenProperty("renderSkin", + new RenderSkin("renderSkin", evaluator, fp, + false, false)); + esNodePrototype.putHiddenProperty("renderSkinAsString", + new RenderSkin("renderSkinAsString", evaluator, + fp, false, true)); + esNodePrototype.putHiddenProperty("clearCache", + new NodeClearCache("clearCache", evaluator, fp)); // default methods for generic Java wrapper object prototype. // This is a small subset of the methods in esNodePrototype. - esObjectPrototype.putHiddenProperty ("href", new NodeHref ("href", evaluator, fp)); - esObjectPrototype.putHiddenProperty("renderSkin", new RenderSkin ("renderSkin", evaluator, fp, false, false)); - esObjectPrototype.putHiddenProperty("renderSkinAsString", new RenderSkin ("renderSkinAsString", evaluator, fp, false, true)); + esObjectPrototype.putHiddenProperty("href", new NodeHref("href", evaluator, fp)); + esObjectPrototype.putHiddenProperty("renderSkin", + new RenderSkin("renderSkin", evaluator, fp, + false, false)); + esObjectPrototype.putHiddenProperty("renderSkinAsString", + new RenderSkin("renderSkinAsString", + evaluator, fp, false, true)); // methods that give access to properties and global user lists go.putHiddenProperty("Node", node); // register the constructor for a plain Node object. go.putHiddenProperty("HopObject", node); // HopObject is the new name for node. - go.putHiddenProperty("getProperty", new GlobalGetProperty ("getProperty", evaluator, fp)); - go.putHiddenProperty("token", new GlobalGetProperty ("token", evaluator, fp)); - go.putHiddenProperty("getAge", new GlobalGetAge ("getAge", evaluator, fp)); - go.putHiddenProperty("getURL", new GlobalGetURL ("getURL", evaluator, fp)); - go.putHiddenProperty("encode", new GlobalEncode ("encode", evaluator, fp)); - go.putHiddenProperty("encodeXml", new GlobalEncodeXml ("encodeXml", evaluator, fp)); - go.putHiddenProperty("encodeForm", new GlobalEncodeForm ("encodeForm", evaluator, fp)); - go.putHiddenProperty("format", new GlobalFormat ("format", evaluator, fp)); - go.putHiddenProperty("stripTags", new GlobalStripTags ("stripTags", evaluator, fp)); - go.putHiddenProperty("getXmlDocument", new GlobalGetXmlDocument ("getXmlDocument", evaluator, fp)); - go.putHiddenProperty("getHtmlDocument", new GlobalGetHtmlDocument ("getHtmlDocument", evaluator, fp)); - go.putHiddenProperty("jdomize", new GlobalJDOM ("jdomize", evaluator, fp)); - go.putHiddenProperty("getSkin", new GlobalCreateSkin ("getSkin", evaluator, fp)); - go.putHiddenProperty("createSkin", new GlobalCreateSkin ("createSkin", evaluator, fp)); - go.putHiddenProperty("renderSkin", new RenderSkin ("renderSkin", evaluator, fp, true, false)); - go.putHiddenProperty("renderSkinAsString", new RenderSkin ("renderSkinAsString", evaluator, fp, true, true)); - go.putHiddenProperty("authenticate", new GlobalAuthenticate ("authenticate", evaluator, fp)); + go.putHiddenProperty("getProperty", + new GlobalGetProperty("getProperty", evaluator, fp)); + go.putHiddenProperty("token", new GlobalGetProperty("token", evaluator, fp)); + go.putHiddenProperty("getAge", new GlobalGetAge("getAge", evaluator, fp)); + go.putHiddenProperty("getURL", new GlobalGetURL("getURL", evaluator, fp)); + go.putHiddenProperty("encode", new GlobalEncode("encode", evaluator, fp)); + go.putHiddenProperty("encodeXml", new GlobalEncodeXml("encodeXml", evaluator, fp)); + go.putHiddenProperty("encodeForm", + new GlobalEncodeForm("encodeForm", evaluator, fp)); + go.putHiddenProperty("format", new GlobalFormat("format", evaluator, fp)); + go.putHiddenProperty("stripTags", new GlobalStripTags("stripTags", evaluator, fp)); + go.putHiddenProperty("getXmlDocument", + new GlobalGetXmlDocument("getXmlDocument", evaluator, fp)); + go.putHiddenProperty("getHtmlDocument", + new GlobalGetHtmlDocument("getHtmlDocument", evaluator, fp)); + go.putHiddenProperty("jdomize", new GlobalJDOM("jdomize", evaluator, fp)); + go.putHiddenProperty("getSkin", new GlobalCreateSkin("getSkin", evaluator, fp)); + go.putHiddenProperty("createSkin", + new GlobalCreateSkin("createSkin", evaluator, fp)); + go.putHiddenProperty("renderSkin", + new RenderSkin("renderSkin", evaluator, fp, true, false)); + go.putHiddenProperty("renderSkinAsString", + new RenderSkin("renderSkinAsString", evaluator, fp, true, + true)); + go.putHiddenProperty("authenticate", + new GlobalAuthenticate("authenticate", evaluator, fp)); go.deleteProperty("exit", "exit".hashCode()); // register object prototypes with FesiEngine - engine.putPrototype ("global", go); - engine.putPrototype ("hopobject", esNodePrototype); - engine.putPrototype ("__javaobject__", esObjectPrototype); -// engine.putPrototype ("session", esSessionPrototype); + engine.putPrototype("global", go); + engine.putPrototype("hopobject", esNodePrototype); + engine.putPrototype("__javaobject__", esObjectPrototype); + + // engine.putPrototype ("session", esSessionPrototype); + } + + private String getNumberChoice(String name, double from, double to, double step, + double value) { + double l = 0.000001; + StringBuffer b = new StringBuffer("<select name=\""); + + // DecimalFormat fmt = new DecimalFormat (); + b.append(name); + b.append("\">"); + + // check step for finity + if (step == 0.0) { + step = 1.0; + } + + if ((step * (to - from)) < 0) { + step *= -1; + } + + double d = (from <= to) ? 1.0 : (-1.0); + + for (double i = from; (i * d) <= (to * d); i += step) { + if (Math.abs(i % 1) < l) { + int j = (int) i; + + b.append("<option value=\"" + j); + + if (i == value) { + b.append("\" selected=\"true"); + } + + b.append("\">" + j); + } else { + b.append("<option value=\"" + i); + + if (i == value) { + b.append("\" selected=\"true"); + } + + b.append("\">" + i); + } + } + + b.append("</select>"); + + return b.toString(); } class NodeAdd extends BuiltinFunctionObject { - NodeAdd (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + NodeAdd(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - ESNode node = (ESNode) thisObject; - return ESBoolean.makeBoolean (node.add (arguments)); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESNode node = (ESNode) thisObject; + + return ESBoolean.makeBoolean(node.add(arguments)); } } class NodeAddAt extends BuiltinFunctionObject { - NodeAddAt (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + NodeAddAt(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - ESNode node = (ESNode) thisObject; - return ESBoolean.makeBoolean (node.addAt (arguments)); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESNode node = (ESNode) thisObject; + + return ESBoolean.makeBoolean(node.addAt(arguments)); } } class NodeRemove extends BuiltinFunctionObject { - NodeRemove (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + NodeRemove(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - ESNode node = (ESNode) thisObject; - return ESBoolean.makeBoolean (node.remove (arguments)); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESNode node = (ESNode) thisObject; + + return ESBoolean.makeBoolean(node.remove(arguments)); } } - class NodeLink extends BuiltinFunctionObject { - NodeLink (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + NodeLink(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - ESNode node = (ESNode) thisObject; - return ESBoolean.makeBoolean (node.link (arguments)); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESNode node = (ESNode) thisObject; + + return ESBoolean.makeBoolean(node.link(arguments)); } } - + class NodeList extends BuiltinFunctionObject { - NodeList (String name, Evaluator evaluator, FunctionPrototype fp) { + NodeList(String name, Evaluator evaluator, FunctionPrototype fp) { super(fp, evaluator, name, 0); } - public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - ESNode node = (ESNode) thisObject; - return node.list (); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESNode node = (ESNode) thisObject; + + return node.list(); } } class NodeGet extends BuiltinFunctionObject { - NodeGet (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + NodeGet(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - ESValue esv = null; - if (arguments[0].isNumberValue ()) { - int i = arguments[0].toInt32 (); - esv = thisObject.getProperty (i); - } else { - String name = arguments[0].toString (); - // call esNodeProperty() method special to ESNode because we want to avoid - // retrieving prototype functions when calling hopobject.get(). - ESNode esn = (ESNode) thisObject; - esv = esn.getNodeProperty (name); - } - return (esv); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESValue esv = null; + + if (arguments[0].isNumberValue()) { + int i = arguments[0].toInt32(); + + esv = thisObject.getProperty(i); + } else { + String name = arguments[0].toString(); + + // call esNodeProperty() method special to ESNode because we want to avoid + // retrieving prototype functions when calling hopobject.get(). + ESNode esn = (ESNode) thisObject; + + esv = esn.getNodeProperty(name); + } + + return (esv); } } class NodeSet extends BuiltinFunctionObject { - NodeSet (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + NodeSet(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - ESNode esn = (ESNode) thisObject; - if (arguments[0].isNumberValue ()) { - return ESBoolean.makeBoolean (esn.addAt (arguments)); - } else { - String propname = arguments[0].toString (); - esn.putProperty (propname, arguments[1], propname.hashCode ()); - } - return ESBoolean.makeBoolean (true); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESNode esn = (ESNode) thisObject; + + if (arguments[0].isNumberValue()) { + return ESBoolean.makeBoolean(esn.addAt(arguments)); + } else { + String propname = arguments[0].toString(); + + esn.putProperty(propname, arguments[1], propname.hashCode()); + } + + return ESBoolean.makeBoolean(true); } } class NodeCount extends BuiltinFunctionObject { - NodeCount (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + NodeCount(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - INode node = ((ESNode) thisObject).getNode (); - return new ESNumber ((double) node.numberOfNodes ()); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + INode node = ((ESNode) thisObject).getNode(); + + return new ESNumber((double) node.numberOfNodes()); } } class NodeContains extends BuiltinFunctionObject { - NodeContains (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + NodeContains(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - ESNode node = (ESNode) thisObject; - return new ESNumber (node.contains (arguments)); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESNode node = (ESNode) thisObject; + + return new ESNumber(node.contains(arguments)); } } - class NodeInvalidate extends BuiltinFunctionObject { - NodeInvalidate (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 0); + NodeInvalidate(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 0); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { ESNode esn = (ESNode) thisObject; - return ESBoolean.makeBoolean (esn.invalidate (arguments)); + + return ESBoolean.makeBoolean(esn.invalidate(arguments)); } } - class NodePrefetch extends BuiltinFunctionObject { - NodePrefetch (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 0); + NodePrefetch(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 0); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { try { ESNode esn = (ESNode) thisObject; - esn.prefetchChildren (arguments); + + esn.prefetchChildren(arguments); } catch (IllegalArgumentException illarg) { throw illarg; } catch (Exception x) { // swallow exceptions in prefetchChildren } + return ESNull.theNull; } } - class NodeEditor extends BuiltinFunctionObject { - - NodeEditor (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + NodeEditor(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - if (arguments.length < 1) - throw new EcmaScriptException ("Missing argument for Node.editor(): Name of property to be edited."); - String propName = arguments[0].toString (); - ESValue propValue = thisObject.getProperty (propName, propName.hashCode ()); - if (propValue.isBooleanValue ()) - return (booleanEditor (thisObject, propName, propValue, arguments)); - if (propValue.isNumberValue ()) - return (numberEditor (thisObject, propName, propValue, arguments)); - if (propValue instanceof DatePrototype) - return (dateEditor (thisObject, propName, propValue, arguments)); - return (stringEditor (thisObject, propName, propValue, arguments)); - } - - public ESValue stringEditor (ESObject thisObject, String propName, ESValue propValue, ESValue[] arguments) - throws EcmaScriptException { - String value = null; - if (propValue == null || ESNull.theNull == propValue || ESUndefined.theUndefined == propValue) - value = ""; - else - value = HtmlEncoder.encodeFormValue (propValue.toString ()); - if (arguments.length == 2 && arguments[1].isNumberValue ()) - return new ESString ("<input type=\"text\" name=\""+propName+"\" size=\""+arguments[1].toInt32 ()+"\" value=\""+ value +"\">"); - else if (arguments.length == 3 && arguments[1].isNumberValue () && arguments[2].isNumberValue ()) - return new ESString ("<textarea name=\""+propName+"\" cols=\""+arguments[1].toInt32 ()+"\" rows=\""+arguments[2].toInt32 ()+"\" wrap=\"virtual\">"+value+"</textarea>"); - return new ESString ("<input type=\"text\" name=\""+propName+"\" value=\""+ value +"\">"); - } - - public ESValue dateEditor (ESObject thisObject, String propName, ESValue propValue, ESValue[] arguments) - throws EcmaScriptException { - Date date = (Date) propValue.toJavaObject (); - DateFormat fmt = arguments.length > 1 ? new SimpleDateFormat (arguments[1].toString ()) : new SimpleDateFormat (); - return new ESString ("<input type=\"text\" name=\""+propName+"\" value=\""+ fmt.format (date) +"\">"); - } - - public ESValue numberEditor (ESObject thisObject, String propName, ESValue propValue, ESValue[] arguments) - throws EcmaScriptException { - ESNumber esn = (ESNumber) propValue.toESNumber (); - double value = esn.doubleValue (); - if (arguments.length == 3 && arguments[1].isNumberValue () && arguments[2].isNumberValue ()) - return new ESString (getNumberChoice (propName, arguments[1].toInt32 (), arguments[2].toInt32 (), 1, value)); - else if (arguments.length == 4 && arguments[1].isNumberValue () && arguments[2].isNumberValue () && arguments[3].isNumberValue ()) - return new ESString (getNumberChoice (propName, arguments[1].doubleValue (), arguments[2].doubleValue (), arguments[3].doubleValue (), value)); - DecimalFormat fmt = new DecimalFormat (); - if (arguments.length == 2 && arguments[1].isNumberValue ()) - return new ESString ("<input type=\"text\" name=\""+propName+"\" size=\""+arguments[1].toInt32 ()+"\" value=\""+ fmt.format (value) +"\">"); - else - return new ESString ("<input type=\"text\" name=\""+propName+"\" size=\"8\" value=\""+ fmt.format (value) +"\">"); - } - - public ESValue booleanEditor (ESObject thisObject, String propName, ESValue propValue, ESValue[] arguments) - throws EcmaScriptException { - ESBoolean esb = (ESBoolean) propValue.toESBoolean (); - String value = esb.toString (); - if (arguments.length < 2) { - String retval = "<input type=\"checkbox\" name=\""+propName+"\" value=\"on\""; - if (esb.booleanValue ()) retval += " checked"; - retval +=">"; - return new ESString (retval); + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + if (arguments.length < 1) { + throw new EcmaScriptException("Missing argument for Node.editor(): Name of property to be edited."); } - boolean forValue = arguments[1].booleanValue (); - StringBuffer retval = new StringBuffer ("<input type=\"radio\" name=\""+propName+"\" value=\""); - if (forValue) retval.append ("on"); - retval.append ("\""); - if (forValue == esb.booleanValue()) retval.append (" checked"); - retval.append (">"); - return new ESString (retval.toString ()); + + String propName = arguments[0].toString(); + ESValue propValue = thisObject.getProperty(propName, propName.hashCode()); + + if (propValue.isBooleanValue()) { + return (booleanEditor(thisObject, propName, propValue, arguments)); + } + + if (propValue.isNumberValue()) { + return (numberEditor(thisObject, propName, propValue, arguments)); + } + + if (propValue instanceof DatePrototype) { + return (dateEditor(thisObject, propName, propValue, arguments)); + } + + return (stringEditor(thisObject, propName, propValue, arguments)); + } + + public ESValue stringEditor(ESObject thisObject, String propName, + ESValue propValue, ESValue[] arguments) + throws EcmaScriptException { + String value = null; + + if ((propValue == null) || (ESNull.theNull == propValue) || + (ESUndefined.theUndefined == propValue)) { + value = ""; + } else { + value = HtmlEncoder.encodeFormValue(propValue.toString()); + } + + if ((arguments.length == 2) && arguments[1].isNumberValue()) { + return new ESString("<input type=\"text\" name=\"" + propName + + "\" size=\"" + arguments[1].toInt32() + + "\" value=\"" + value + "\">"); + } else if ((arguments.length == 3) && arguments[1].isNumberValue() && + arguments[2].isNumberValue()) { + return new ESString("<textarea name=\"" + propName + "\" cols=\"" + + arguments[1].toInt32() + "\" rows=\"" + + arguments[2].toInt32() + "\" wrap=\"virtual\">" + + value + "</textarea>"); + } + + return new ESString("<input type=\"text\" name=\"" + propName + + "\" value=\"" + value + "\">"); + } + + public ESValue dateEditor(ESObject thisObject, String propName, + ESValue propValue, ESValue[] arguments) + throws EcmaScriptException { + Date date = (Date) propValue.toJavaObject(); + DateFormat fmt = (arguments.length > 1) + ? new SimpleDateFormat(arguments[1].toString()) + : new SimpleDateFormat(); + + return new ESString("<input type=\"text\" name=\"" + propName + + "\" value=\"" + fmt.format(date) + "\">"); + } + + public ESValue numberEditor(ESObject thisObject, String propName, + ESValue propValue, ESValue[] arguments) + throws EcmaScriptException { + ESNumber esn = (ESNumber) propValue.toESNumber(); + double value = esn.doubleValue(); + + if ((arguments.length == 3) && arguments[1].isNumberValue() && + arguments[2].isNumberValue()) { + return new ESString(getNumberChoice(propName, arguments[1].toInt32(), + arguments[2].toInt32(), 1, value)); + } else if ((arguments.length == 4) && arguments[1].isNumberValue() && + arguments[2].isNumberValue() && arguments[3].isNumberValue()) { + return new ESString(getNumberChoice(propName, arguments[1].doubleValue(), + arguments[2].doubleValue(), + arguments[3].doubleValue(), value)); + } + + DecimalFormat fmt = new DecimalFormat(); + + if ((arguments.length == 2) && arguments[1].isNumberValue()) { + return new ESString("<input type=\"text\" name=\"" + propName + + "\" size=\"" + arguments[1].toInt32() + + "\" value=\"" + fmt.format(value) + "\">"); + } else { + return new ESString("<input type=\"text\" name=\"" + propName + + "\" size=\"8\" value=\"" + fmt.format(value) + "\">"); + } + } + + public ESValue booleanEditor(ESObject thisObject, String propName, + ESValue propValue, ESValue[] arguments) + throws EcmaScriptException { + ESBoolean esb = (ESBoolean) propValue.toESBoolean(); + String value = esb.toString(); + + if (arguments.length < 2) { + String retval = "<input type=\"checkbox\" name=\"" + propName + + "\" value=\"on\""; + + if (esb.booleanValue()) { + retval += " checked"; + } + + retval += ">"; + + return new ESString(retval); + } + + boolean forValue = arguments[1].booleanValue(); + StringBuffer retval = new StringBuffer("<input type=\"radio\" name=\"" + + propName + "\" value=\""); + + if (forValue) { + retval.append("on"); + } + + retval.append("\""); + + if (forValue == esb.booleanValue()) { + retval.append(" checked"); + } + + retval.append(">"); + + return new ESString(retval.toString()); } } - class StringEditor extends BuiltinFunctionObject { - StringEditor (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + StringEditor(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - throw (new EcmaScriptException ("String.editor() wird nicht mehr unterstuetzt. Statt node.strvar.editor(...) kann node.editor(\"strvar\", ...) verwendet werden.")); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + throw (new EcmaScriptException("String.editor() wird nicht mehr unterstuetzt. Statt node.strvar.editor(...) kann node.editor(\"strvar\", ...) verwendet werden.")); } } - + class NumberEditor extends BuiltinFunctionObject { - NumberEditor (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + NumberEditor(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - throw (new EcmaScriptException ("Number.editor() wird nicht mehr unterstuetzt. Statt node.nvar.editor(...) kann node.editor(\"nvar\", ...) verwendet werden.")); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + throw (new EcmaScriptException("Number.editor() wird nicht mehr unterstuetzt. Statt node.nvar.editor(...) kann node.editor(\"nvar\", ...) verwendet werden.")); } } - - class BooleanEditor extends BuiltinFunctionObject { - BooleanEditor (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + + class BooleanEditor extends BuiltinFunctionObject { + BooleanEditor(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - throw (new EcmaScriptException ("Boolean.editor() wird nicht mehr unterstuetzt. Statt node.boolvar.editor(...) kann node.editor(\"boolvar\", ...) verwendet werden.")); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + throw (new EcmaScriptException("Boolean.editor() wird nicht mehr unterstuetzt. Statt node.boolvar.editor(...) kann node.editor(\"boolvar\", ...) verwendet werden.")); } } @@ -373,74 +579,88 @@ public final class HopExtension { DatePrototypeFormat(String name, Evaluator evaluator, FunctionPrototype fp) { super(fp, evaluator, name, 0); } - public ESValue callFunction(ESObject thisObject, - ESValue[] arguments) - throws EcmaScriptException { - DatePrototype aDate = (DatePrototype) thisObject; - DateFormat df = arguments.length > 0 ? - new SimpleDateFormat (arguments[0].toString ()) : - new SimpleDateFormat (); - df.setTimeZone(TimeZone.getDefault()); - return (aDate.toJavaObject() == null) ? - new ESString(""): - new ESString(df.format((Date) aDate.toJavaObject())); + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + DatePrototype aDate = (DatePrototype) thisObject; + + DateFormat df = (arguments.length > 0) + ? new SimpleDateFormat(arguments[0].toString()) + : new SimpleDateFormat(); + + df.setTimeZone(TimeZone.getDefault()); + + return (aDate.toJavaObject() == null) ? new ESString("") + : new ESString(df.format((Date) aDate.toJavaObject())); } } - // previously in FESI.Data.NumberObject - private Hashtable formatTable = new Hashtable (); class NumberPrototypeFormat extends BuiltinFunctionObject { NumberPrototypeFormat(String name, Evaluator evaluator, FunctionPrototype fp) { super(fp, evaluator, name, 0); - } - public ESValue callFunction(ESObject thisObject, - ESValue[] arguments) - throws EcmaScriptException { - ESObject aNumber = (ESObject) thisObject; - String fstr = "#,##0.00"; - if (arguments.length >= 1) - fstr = arguments[0].toString (); - DecimalFormat df = (DecimalFormat) formatTable.get (fstr); - if (df == null) { - df = new DecimalFormat (fstr); - formatTable.put (fstr, df); - } - return new ESString(df.format(aNumber.doubleValue ())); + } + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESObject aNumber = (ESObject) thisObject; + String fstr = "#,##0.00"; + + if (arguments.length >= 1) { + fstr = arguments[0].toString(); + } + + DecimalFormat df = (DecimalFormat) formatTable.get(fstr); + + if (df == null) { + df = new DecimalFormat(fstr); + formatTable.put(fstr, df); + } + + return new ESString(df.format(aNumber.doubleValue())); } } - class StringTrim extends BuiltinFunctionObject { - StringTrim (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); - } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - return new ESString ( thisObject.toString().trim() ); - } - } + class StringTrim extends BuiltinFunctionObject { + StringTrim(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); + } + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + return new ESString(thisObject.toString().trim()); + } + } class GlobalGetProperty extends BuiltinFunctionObject { - GlobalGetProperty (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + GlobalGetProperty(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - if (arguments.length == 0) - return new ESString (""); - String defval = (arguments.length > 1) ? arguments[1].toString () : ""; - return new ESString (app.getProperty (arguments[0].toString (), defval)); - + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + if (arguments.length == 0) { + return new ESString(""); + } + + String defval = (arguments.length > 1) ? arguments[1].toString() : ""; + + return new ESString(app.getProperty(arguments[0].toString(), defval)); } } class GlobalAuthenticate extends BuiltinFunctionObject { - GlobalAuthenticate (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + GlobalAuthenticate(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - if (arguments.length != 2) - return ESBoolean.makeBoolean (false); - return ESBoolean.makeBoolean (app.authenticate (arguments[0].toString (), arguments[1].toString ())); + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + if (arguments.length != 2) { + return ESBoolean.makeBoolean(false); + } + + return ESBoolean.makeBoolean(app.authenticate(arguments[0].toString(), + arguments[1].toString())); } } @@ -448,15 +668,20 @@ public final class HopExtension { * Get a parsed Skin from an app-managed skin text */ class GlobalCreateSkin extends BuiltinFunctionObject { - GlobalCreateSkin (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + GlobalCreateSkin(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - if (arguments.length != 1 || ESNull.theNull.equals (arguments[0])) - throw new EcmaScriptException ("createSkin must be called with one String argument"); - String str = arguments[0].toString (); - Skin skin = new Skin (str, app); - return new ESWrapper (skin, evaluator); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + if ((arguments.length != 1) || ESNull.theNull.equals(arguments[0])) { + throw new EcmaScriptException("createSkin must be called with one String argument"); + } + + String str = arguments[0].toString(); + Skin skin = new Skin(str, app); + + return new ESWrapper(skin, evaluator); } } @@ -466,382 +691,498 @@ public final class HopExtension { class RenderSkin extends BuiltinFunctionObject { boolean global; boolean asString; - RenderSkin (String name, Evaluator evaluator, FunctionPrototype fp, boolean global, boolean asString) { - super (fp, evaluator, name, 1); + + RenderSkin(String name, Evaluator evaluator, FunctionPrototype fp, + boolean global, boolean asString) { + super(fp, evaluator, name, 1); this.global = global; this.asString = asString; } - public ESValue callFunction (ESObject thisObj, ESValue[] arguments) throws EcmaScriptException { - if (arguments.length < 1 || arguments.length > 2 || arguments[0] ==null || arguments[0] == ESNull.theNull) - throw new EcmaScriptException ("renderSkin requires one argument containing the skin name and an optional parameter object argument"); + + public ESValue callFunction(ESObject thisObj, ESValue[] arguments) + throws EcmaScriptException { + if ((arguments.length < 1) || (arguments.length > 2) || + (arguments[0] == null) || (arguments[0] == ESNull.theNull)) { + throw new EcmaScriptException("renderSkin requires one argument containing the skin name and an optional parameter object argument"); + } + try { Skin skin = null; ESObject thisObject = global ? null : thisObj; HashMap params = null; - if (arguments.length > 1 && arguments[1] instanceof ESObject) { - // create an parameter object to pass to the skin + + if ((arguments.length > 1) && arguments[1] instanceof ESObject) { + // create an parameter object to pass to the skin ESObject paramObject = (ESObject) arguments[1]; - params = new HashMap (); - for (Enumeration en=paramObject.getProperties(); en.hasMoreElements(); ) { + + params = new HashMap(); + + for (Enumeration en = paramObject.getProperties(); + en.hasMoreElements();) { String propname = (String) en.nextElement(); - params.put (propname, paramObject.getProperty (propname, propname.hashCode()).toJavaObject()); + + params.put(propname, + paramObject.getProperty(propname, propname.hashCode()) + .toJavaObject()); } } // first, see if the first argument already is a skin object. If not, it's the name of the skin to be called if (arguments[0] instanceof ESWrapper) { - Object obj = ((ESWrapper) arguments[0]).toJavaObject (); - if (obj instanceof Skin) + Object obj = ((ESWrapper) arguments[0]).toJavaObject(); + + if (obj instanceof Skin) { skin = (Skin) obj; + } } // retrieve res.skinpath, an array of objects that tell us where to look for skins // (strings for directory names and INodes for internal, db-stored skinsets) ResponseTrans res = engine.getResponse(); - Object[] skinpath = res.getSkinpath (); + Object[] skinpath = res.getSkinpath(); // ready... retrieve the skin and render it. - Object javaObject = thisObject == null ? null : thisObject.toJavaObject (); + Object javaObject = (thisObject == null) ? null : thisObject.toJavaObject(); + if (skin == null) { - String skinid = app.getPrototypeName(javaObject)+"/"+arguments[0].toString (); - skin = res.getCachedSkin (skinid); + String skinid = app.getPrototypeName(javaObject) + "/" + + arguments[0].toString(); + + skin = res.getCachedSkin(skinid); + if (skin == null) { - skin = app.getSkin (javaObject, arguments[0].toString (), skinpath); - res.cacheSkin (skinid, skin); + skin = app.getSkin(javaObject, arguments[0].toString(), skinpath); + res.cacheSkin(skinid, skin); } } - if (asString) - res.pushStringBuffer (); - if (skin != null) - skin.render (engine.getRequestEvaluator(), javaObject, params); - else - res.write ("[Skin not found: "+arguments[0]+"]"); - if (asString) - return new ESString (res.popStringBuffer ()); + + if (asString) { + res.pushStringBuffer(); + } + + if (skin != null) { + skin.render(engine.getRequestEvaluator(), javaObject, params); + } else { + res.write("[Skin not found: " + arguments[0] + "]"); + } + + if (asString) { + return new ESString(res.popStringBuffer()); + } } catch (RedirectException redir) { // let redirect pass through throw redir; } catch (Exception x) { - x.printStackTrace (); - throw new EcmaScriptException ("renderSkin: "+x); + x.printStackTrace(); + throw new EcmaScriptException("renderSkin: " + x); } + return ESNull.theNull; } } - class GlobalGetAge extends BuiltinFunctionObject { - GlobalGetAge (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + GlobalGetAge(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - if (arguments.length != 1 || !(arguments[0] instanceof DatePrototype)) - throw new EcmaScriptException ("Invalid arguments for function getAge(Date)"); - - Date d = (Date) arguments[0].toJavaObject (); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + if ((arguments.length != 1) || !(arguments[0] instanceof DatePrototype)) { + throw new EcmaScriptException("Invalid arguments for function getAge(Date)"); + } + + Date d = (Date) arguments[0].toJavaObject(); + try { - long then = d.getTime () / 60000l; - long now = System.currentTimeMillis () / 60000l; - StringBuffer age = new StringBuffer (); + long then = d.getTime() / 60000L; + long now = System.currentTimeMillis() / 60000L; + StringBuffer age = new StringBuffer(); String divider = "vor "; long diff = now - then; long days = diff / 1440; + if (days > 0) { - age.append (days > 1 ? divider+days+ " Tagen" : divider+"1 Tag"); + age.append((days > 1) ? (divider + days + " Tagen") : (divider + + "1 Tag")); divider = ", "; } + long hours = (diff % 1440) / 60; + if (hours > 0) { - age.append (hours > 1 ? divider+hours+ " Stunden" : divider+"1 Stunde"); + age.append((hours > 1) ? (divider + hours + " Stunden") + : (divider + "1 Stunde")); divider = ", "; } + long minutes = diff % 60; - if (minutes > 0) - age.append (minutes > 1 ? divider+minutes+ " Minuten" : divider+"1 Minute"); - return new ESString (age.toString ()); - + + if (minutes > 0) { + age.append((minutes > 1) ? (divider + minutes + " Minuten") + : (divider + "1 Minute")); + } + + return new ESString(age.toString()); } catch (Exception e) { - app.logEvent ("Error formatting date: "+e); - e.printStackTrace (); - return new ESString (""); + app.logEvent("Error formatting date: " + e); + e.printStackTrace(); + + return new ESString(""); } } } class GlobalGetURL extends BuiltinFunctionObject { - GlobalGetURL (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + GlobalGetURL(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - if (arguments.length < 1) - return ESNull.theNull; + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + if (arguments.length < 1) { + return ESNull.theNull; + } + try { - URL url = new URL (arguments[0].toString ()); - URLConnection con = url.openConnection (); + URL url = new URL(arguments[0].toString()); + URLConnection con = url.openConnection(); + // do we have if-modified-since or etag headers to set? if (arguments.length > 1) { if (arguments[1] instanceof DatePrototype) { Date date = (Date) arguments[1].toJavaObject(); + con.setIfModifiedSince(date.getTime()); - SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.UK); + + SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", + Locale.UK); + format.setTimeZone(TimeZone.getTimeZone("GMT")); con.setRequestProperty("If-Modified-Since", format.format(date)); } else if (arguments[1] != null) { - con.setRequestProperty ("If-None-Match", arguments[1].toString()); + con.setRequestProperty("If-None-Match", arguments[1].toString()); } } + + String httpUserAgent = app.getProperty("httpUserAgent"); + + if (httpUserAgent != null) { + con.setRequestProperty("User-Agent", httpUserAgent); + } + con.setAllowUserInteraction(false); - String filename = url.getFile (); - String contentType = con.getContentType (); - long lastmod = con.getLastModified (); - String etag = con.getHeaderField ("ETag"); + + String filename = url.getFile(); + String contentType = con.getContentType(); + long lastmod = con.getLastModified(); + String etag = con.getHeaderField("ETag"); int length = con.getContentLength(); int resCode = 0; - if (con instanceof HttpURLConnection) + + if (con instanceof HttpURLConnection) { resCode = ((HttpURLConnection) con).getResponseCode(); - ByteArrayOutputStream body = new ByteArrayOutputStream (); - if (length != 0 && resCode != 304) { - InputStream in = new BufferedInputStream(con.getInputStream ()); + } + + ByteArrayOutputStream body = new ByteArrayOutputStream(); + + if ((length != 0) && (resCode != 304)) { + InputStream in = new BufferedInputStream(con.getInputStream()); byte[] b = new byte[1024]; int read; - while ((read = in.read (b)) > -1) - body.write (b, 0, read); - in.close (); + + while ((read = in.read(b)) > -1) + body.write(b, 0, read); + + in.close(); } - MimePart mime = new MimePart (filename, body.toByteArray(), contentType); - if (lastmod > 0) + + MimePart mime = new MimePart(filename, body.toByteArray(), contentType); + + if (lastmod > 0) { mime.lastModified = new Date(lastmod); + } + mime.eTag = etag; - return ESLoader.normalizeObject (mime, evaluator); - } catch (Exception ignore) {} - return ESNull.theNull; + + return ESLoader.normalizeObject(mime, evaluator); + } catch (Exception ignore) { + } + + return ESNull.theNull; } } class GlobalEncode extends BuiltinFunctionObject { - GlobalEncode (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + GlobalEncode(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - if (arguments.length < 1) - return ESNull.theNull; - return new ESString (HtmlEncoder.encodeAll (arguments[0].toString ())); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + if (arguments.length < 1) { + return ESNull.theNull; + } + + return new ESString(HtmlEncoder.encodeAll(arguments[0].toString())); } } class GlobalEncodeXml extends BuiltinFunctionObject { - GlobalEncodeXml (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + GlobalEncodeXml(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - if (arguments.length < 1) - return ESNull.theNull; - return new ESString (HtmlEncoder.encodeXml (arguments[0].toString ())); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + if (arguments.length < 1) { + return ESNull.theNull; + } + + return new ESString(HtmlEncoder.encodeXml(arguments[0].toString())); } } class GlobalEncodeForm extends BuiltinFunctionObject { - GlobalEncodeForm (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + GlobalEncodeForm(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - if (arguments.length < 1) - return ESNull.theNull; - return new ESString (HtmlEncoder.encodeFormValue (arguments[0].toString ())); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + if (arguments.length < 1) { + return ESNull.theNull; + } + + return new ESString(HtmlEncoder.encodeFormValue(arguments[0].toString())); } } // strip tags from XML/HTML text class GlobalStripTags extends BuiltinFunctionObject { - GlobalStripTags (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + GlobalStripTags(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - if (arguments.length < 1) - return ESNull.theNull; - StringBuffer b = new StringBuffer (); - char[] c = arguments[0].toString ().toCharArray (); - boolean inTag = false; - for (int i=0; i<c.length; i++) { - if (c[i] == '<') inTag = true; - if (!inTag) b.append (c[i]); - if (c[i] == '>') inTag = false; + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + if (arguments.length < 1) { + return ESNull.theNull; } - return new ESString (b.toString ()); + + StringBuffer b = new StringBuffer(); + char[] c = arguments[0].toString().toCharArray(); + boolean inTag = false; + + for (int i = 0; i < c.length; i++) { + if (c[i] == '<') { + inTag = true; + } + + if (!inTag) { + b.append(c[i]); + } + + if (c[i] == '>') { + inTag = false; + } + } + + return new ESString(b.toString()); } } class GlobalFormat extends BuiltinFunctionObject { - GlobalFormat (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + GlobalFormat(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - if (arguments.length < 1) - return ESNull.theNull; - return new ESString (HtmlEncoder.encode (arguments[0].toString ())); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + if (arguments.length < 1) { + return ESNull.theNull; + } + + return new ESString(HtmlEncoder.encode(arguments[0].toString())); } } class GlobalGetXmlDocument extends BuiltinFunctionObject { - GlobalGetXmlDocument (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + GlobalGetXmlDocument(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { try { - Object p = arguments[0].toJavaObject (); - Object doc = helma.util.XmlUtils.parseXml (p); - return ESLoader.normalizeObject (doc, evaluator); + Object p = arguments[0].toJavaObject(); + Object doc = helma.util.XmlUtils.parseXml(p); + + return ESLoader.normalizeObject(doc, evaluator); } catch (Exception noluck) { - app.logEvent ("Error creating XML document: "+noluck); + app.logEvent("Error creating XML document: " + noluck); } + return ESNull.theNull; } } class GlobalGetHtmlDocument extends BuiltinFunctionObject { - GlobalGetHtmlDocument (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + GlobalGetHtmlDocument(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { try { - Object p = arguments[0].toJavaObject (); - Object doc = helma.util.XmlUtils.parseHtml (p); - return ESLoader.normalizeObject (doc, evaluator); + Object p = arguments[0].toJavaObject(); + Object doc = helma.util.XmlUtils.parseHtml(p); + + return ESLoader.normalizeObject(doc, evaluator); } catch (Exception noluck) { - app.logEvent ("Error creating HTML document: "+noluck); + app.logEvent("Error creating HTML document: " + noluck); } + return ESNull.theNull; } } class GlobalJDOM extends BuiltinFunctionObject { - GlobalJDOM (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + GlobalJDOM(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { try { - Class.forName ("org.w3c.dom.Document"); - org.w3c.dom.Document doc = (org.w3c.dom.Document) arguments[0].toJavaObject (); - Class.forName ("org.jdom.input.DOMBuilder"); - org.jdom.input.DOMBuilder builder = new org.jdom.input.DOMBuilder (); - return ESLoader.normalizeObject (builder.build (doc), evaluator); + Class.forName("org.w3c.dom.Document"); + + org.w3c.dom.Document doc = (org.w3c.dom.Document) arguments[0].toJavaObject(); + + Class.forName("org.jdom.input.DOMBuilder"); + + org.jdom.input.DOMBuilder builder = new org.jdom.input.DOMBuilder(); + + return ESLoader.normalizeObject(builder.build(doc), evaluator); } catch (Exception noluck) { - app.logEvent ("Error building JDOM document: "+noluck); + app.logEvent("Error building JDOM document: " + noluck); } + return ESNull.theNull; } } class NodeSetParent extends BuiltinFunctionObject { - NodeSetParent (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 2); + NodeSetParent(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 2); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - ESNode node = (ESNode) thisObject; - return ESBoolean.makeBoolean (node.setParent (arguments)); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESNode node = (ESNode) thisObject; + + return ESBoolean.makeBoolean(node.setParent(arguments)); } } class NodeClearCache extends BuiltinFunctionObject { - NodeClearCache (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 2); + NodeClearCache(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 2); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - ESNode node = (ESNode) thisObject; - return ESBoolean.makeBoolean (node.clearCache ()); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESNode node = (ESNode) thisObject; + + return ESBoolean.makeBoolean(node.clearCache()); } } class NodeHref extends BuiltinFunctionObject { - NodeHref (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + NodeHref(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - Object elem = thisObject.toJavaObject (); - String tmpname = arguments.length == 0 ? "" : arguments[0].toString (); - String basicHref =app.getNodeHref (elem, tmpname); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + Object elem = thisObject.toJavaObject(); + String tmpname = (arguments.length == 0) ? "" : arguments[0].toString(); + String basicHref = app.getNodeHref(elem, tmpname); + // check if the app.properties specify a href-function to post-process the // basic href. - String hrefFunction = app.getProperty ("hrefFunction", null); + String hrefFunction = app.getProperty("hrefFunction", null); + if (hrefFunction != null) { Object funcElem = elem; + while (funcElem != null) { - if (engine.hasFunction (funcElem, hrefFunction)) { - Object obj; - try { - obj = engine.invoke (funcElem, hrefFunction, new Object[] {basicHref}, false); - } catch (ScriptingException x) { - throw new RuntimeException ("Error in hrefFunction: "+x); - } - if (obj == null) - throw new RuntimeException ("hrefFunction "+hrefFunction+" returned null"); - basicHref = obj.toString (); + if (engine.hasFunction(funcElem, hrefFunction)) { + Object obj; + + try { + obj = engine.invoke(funcElem, hrefFunction, + new Object[] { basicHref }, false); + } catch (ScriptingException x) { + throw new RuntimeException("Error in hrefFunction: " + x); + } + + if (obj == null) { + throw new RuntimeException("hrefFunction " + hrefFunction + + " returned null"); + } + + basicHref = obj.toString(); + + break; } - funcElem = app.getParentElement (funcElem); + + funcElem = app.getParentElement(funcElem); } } + // check if the app.properties specify a href-skin to post-process the // basic href. - String hrefSkin = app.getProperty ("hrefSkin", null); + String hrefSkin = app.getProperty("hrefSkin", null); + if (hrefSkin != null) { // we need to post-process the href with a skin for this application // first, look in the object href was called on. Object skinElem = elem; Skin skin = null; + // ResponseTrans res = engine.getResponse(); // Object[] skinpath = res.getSkinpath (); - while (skin == null && skinElem != null) { - Prototype proto = app.getPrototype (skinElem); + while ((skin == null) && (skinElem != null)) { + Prototype proto = app.getPrototype(skinElem); + if (proto != null) { - skin = proto.getSkin (hrefSkin); + skin = proto.getSkin(hrefSkin); + } + + if (skin == null) { + skinElem = app.getParentElement(skinElem); } - if (skin == null) - skinElem = app.getParentElement (skinElem); } if (skin != null) { - basicHref = renderSkin (skin, basicHref, skinElem); + basicHref = renderSkin(skin, basicHref, skinElem); } } - return new ESString (basicHref); + return new ESString(basicHref); } - private String renderSkin (Skin skin, String path, Object skinElem) throws EcmaScriptException { - engine.getResponse().pushStringBuffer (); - HashMap param = new HashMap (); - param.put ("path", path); - skin.render (engine.getRequestEvaluator(), skinElem, param); - return engine.getResponse().popStringBuffer ().trim (); + + private String renderSkin(Skin skin, String path, Object skinElem) + throws EcmaScriptException { + engine.getResponse().pushStringBuffer(); + + HashMap param = new HashMap(); + + param.put("path", path); + skin.render(engine.getRequestEvaluator(), skinElem, param); + + return engine.getResponse().popStringBuffer().trim(); } } - - - private String getNumberChoice (String name, double from, double to, double step, double value) { - double l = 0.000001; - StringBuffer b = new StringBuffer ("<select name=\""); - // DecimalFormat fmt = new DecimalFormat (); - b.append (name); - b.append ("\">"); - // check step for finity - if (step == 0.0) step = 1.0; - if (step * (to - from) < 0) step *= -1; - double d = from <= to ? 1.0 : -1.0; - for (double i=from; i*d<=to*d; i+=step) { - if (Math.abs (i%1) < l) { - int j = (int) i; - b.append ("<option value=\""+j); - if (i == value) b.append ("\" selected=\"true"); - b.append ("\">"+j); - } else { - b.append ("<option value=\""+i); - if (i == value) b.append ("\" selected=\"true"); - b.append ("\">"+i); - } - } - b.append ("</select>"); - return b.toString (); - } - - - } - +} diff --git a/src/helma/scripting/fesi/NodeConstructor.java b/src/helma/scripting/fesi/NodeConstructor.java index 6c9d278b..c4172e05 100644 --- a/src/helma/scripting/fesi/NodeConstructor.java +++ b/src/helma/scripting/fesi/NodeConstructor.java @@ -1,90 +1,164 @@ -// NodeConstructor.java -// Copyright (c) Hannes Wallnöfer 2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.scripting.fesi; -import helma.objectmodel.db.Node; -import helma.framework.core.*; import FESI.Data.*; import FESI.Exceptions.*; import FESI.Interpreter.*; +import helma.framework.core.*; +import helma.objectmodel.db.Node; /** * A constructor for user defined data types. This first constructs a node, sets its prototype * and invokes the scripted constructor function on it. */ - public class NodeConstructor extends BuiltinFunctionObject { + FesiEngine engine; + String typename; - FesiEngine engine; - String typename; + /** + * Creates a new NodeConstructor object. + * + * @param name ... + * @param fp ... + * @param engine ... + */ + public NodeConstructor(String name, FunctionPrototype fp, FesiEngine engine) { + super(fp, engine.getEvaluator(), name, 1); + typename = name; + this.engine = engine; + } - public NodeConstructor (String name, FunctionPrototype fp, FesiEngine engine) { - super(fp, engine.getEvaluator (), name, 1); - typename = name; - this.engine = engine; + /** + * + * + * @param thisObject ... + * @param arguments ... + * + * @return ... + * + * @throws EcmaScriptException ... + */ + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + return doConstruct(thisObject, arguments); + } + + /** + * + * + * @param thisObject ... + * @param arguments ... + * + * @return ... + * + * @throws EcmaScriptException ... + */ + public ESObject doConstruct(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESNode node = null; + Application app = engine.getApplication(); + + if ("Node".equals(typename) || "hopobject".equalsIgnoreCase(typename)) { + String nodeName = null; + + if ((arguments.length > 0) && (arguments[0] != null)) { + nodeName = arguments[0].toString(); + } + + Node n = new Node(nodeName, (String) null, app.getWrappedNodeManager()); + + node = new ESNode(engine.getPrototype("hopobject"), this.evaluator, n, engine); + engine.putNodeWrapper(node.getNode(), node); + } else { + // Typed nodes are instantiated as helma.objectmodel.db.Node from the beginning + // even if we don't know yet if they are going to be stored in a database. The reason + // is that we want to be able to use the specail features like subnode relations even for + // transient nodes. + ObjectPrototype op = engine.getPrototype(typename); + Node n = new Node(typename, typename, app.getWrappedNodeManager()); + + node = new ESNode(op, engine.getEvaluator(), n, engine); + node.setPrototype(typename); + node.getNode().setDbMapping(app.getDbMapping(typename)); + + try { + // first try calling "constructor", if that doesn't work, try calling a function + // with the name of the type. + // HACK: There is an incompatibility problem here, because the property + // constructor is defined as the constructor of the object by EcmaScript. + if (op.getProperty("constructor", "constructor".hashCode()) instanceof ConstructedFunctionObject) { + node.doIndirectCall(engine.getEvaluator(), node, "constructor", + arguments); + } else if (op.getProperty(typename, typename.hashCode()) instanceof ConstructedFunctionObject) { + node.doIndirectCall(engine.getEvaluator(), node, typename, arguments); + } + } catch (Exception x) { + throw new EcmaScriptException(x.toString()); + } } - public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - return doConstruct(thisObject, arguments); + return node; + } + + /** + * + * + * @param propertyName ... + * @param previousScope ... + * @param hash ... + * + * @return ... + * + * @throws EcmaScriptException ... + */ + public ESValue getPropertyInScope(String propertyName, ScopeChain previousScope, + int hash) throws EcmaScriptException { + return super.getPropertyInScope(propertyName, previousScope, hash); + } + + /** + * + * + * @param propertyName ... + * @param hash ... + * + * @return ... + * + * @throws EcmaScriptException ... + */ + public ESValue getProperty(String propertyName, int hash) + throws EcmaScriptException { + if ("prototype".equals(propertyName)) { + return engine.getPrototype(typename); } - public ESObject doConstruct(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - ESNode node = null; - Application app = engine.getApplication (); - if ("Node".equals (typename) || "hopobject".equalsIgnoreCase (typename)) { - String nodeName = null; - if (arguments.length > 0 && arguments[0] != null) - nodeName = arguments[0].toString(); - Node n = new Node (nodeName, (String) null, app.getWrappedNodeManager ()); - node = new ESNode (engine.getPrototype ("hopobject"), this.evaluator, n, engine); - engine.putNodeWrapper (node.getNode (), node); - } else { - // Typed nodes are instantiated as helma.objectmodel.db.Node from the beginning - // even if we don't know yet if they are going to be stored in a database. The reason - // is that we want to be able to use the specail features like subnode relations even for - // transient nodes. - ObjectPrototype op = engine.getPrototype (typename); - Node n = new Node (typename, typename, app.getWrappedNodeManager ()); - node = new ESNode (op, engine.getEvaluator (), n, engine); - node.setPrototype (typename); - node.getNode ().setDbMapping (app.getDbMapping (typename)); - try { - // first try calling "constructor", if that doesn't work, try calling a function - // with the name of the type. - // HACK: There is an incompatibility problem here, because the property - // constructor is defined as the constructor of the object by EcmaScript. - if (op.getProperty ("constructor", - "constructor".hashCode()) - instanceof ConstructedFunctionObject) - node.doIndirectCall (engine.getEvaluator(), node, "constructor", arguments); - else if (op.getProperty (typename, - typename.hashCode()) - instanceof ConstructedFunctionObject) - node.doIndirectCall (engine.getEvaluator(), node, typename, arguments); - } catch (Exception x) { - throw new EcmaScriptException (x.toString()); - } - } - return node; - } - - public ESValue getPropertyInScope(String propertyName, ScopeChain previousScope, int hash) throws EcmaScriptException { - return super.getPropertyInScope (propertyName, previousScope, hash); - } - - public ESValue getProperty(String propertyName, int hash) throws EcmaScriptException { - if ("prototype".equals (propertyName)) - return engine.getPrototype (typename); - return super.getProperty(propertyName, hash); - } - - public String[] getSpecialPropertyNames() { - String ns[] = {}; - return ns; - } - - } // class NodeConstructor - + return super.getProperty(propertyName, hash); + } + /** + * + * + * @return ... + */ + public String[] getSpecialPropertyNames() { + String[] ns = { }; + return ns; + } +} + // class NodeConstructor diff --git a/src/helma/scripting/fesi/PhantomEngine.java b/src/helma/scripting/fesi/PhantomEngine.java index f453e4d1..3a0100b9 100644 --- a/src/helma/scripting/fesi/PhantomEngine.java +++ b/src/helma/scripting/fesi/PhantomEngine.java @@ -1,17 +1,32 @@ -// PhantomEngine.java -// Copyright (c) Hannes Wallnöfer 2002 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.scripting.fesi; import helma.scripting.ScriptingException; +/** + * + */ public final class PhantomEngine extends FesiEngine { - /** * */ - public Object invoke (Object thisObject, String functionName, Object[] args, boolean xmlrpc) throws ScriptingException { - return super.invoke (thisObject, functionName, args, xmlrpc); + public Object invoke(Object thisObject, String functionName, Object[] args, + boolean xmlrpc) throws ScriptingException { + return super.invoke(thisObject, functionName, args, xmlrpc); } - -} \ No newline at end of file +} diff --git a/src/helma/scripting/fesi/extensions/DomExtension.java b/src/helma/scripting/fesi/extensions/DomExtension.java index 61af344f..d3cb491e 100644 --- a/src/helma/scripting/fesi/extensions/DomExtension.java +++ b/src/helma/scripting/fesi/extensions/DomExtension.java @@ -1,153 +1,239 @@ -package helma.scripting.fesi.extensions; +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ -import java.io.ByteArrayOutputStream; -import java.io.StringReader; -import java.io.File; -import java.io.IOException; -import java.io.FileNotFoundException; +package helma.scripting.fesi.extensions; import FESI.Data.*; import FESI.Exceptions.*; import FESI.Extensions.*; import FESI.Interpreter.*; - import helma.framework.core.Application; import helma.framework.core.RequestEvaluator; import helma.objectmodel.INode; import helma.objectmodel.db.Node; import helma.objectmodel.dom.*; import helma.scripting.fesi.ESNode; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.StringReader; -public class DomExtension extends Extension { - +/** + * + */ +public class DomExtension extends Extension { private transient Evaluator evaluator = null; + /** + * Creates a new DomExtension object. + */ public DomExtension() { super(); } - public void initializeExtension(Evaluator evaluator) throws EcmaScriptException { + /** + * + * + * @param evaluator ... + * + * @throws EcmaScriptException ... + */ + public void initializeExtension(Evaluator evaluator) + throws EcmaScriptException { this.evaluator = evaluator; + GlobalObject go = evaluator.getGlobalObject(); ObjectPrototype op = (ObjectPrototype) evaluator.getObjectPrototype(); FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype(); ESObject globalXml = new GlobalObjectXml("Xml", evaluator, fp); - globalXml.putHiddenProperty ("length",new ESNumber(1)); - globalXml.putHiddenProperty ("read", new XmlRead ("read", evaluator, fp, false)); - globalXml.putHiddenProperty ("readFromString", new XmlRead ("readFromString", evaluator, fp, true)); - globalXml.putHiddenProperty ("write", new XmlWrite ("write", evaluator, fp)); - globalXml.putHiddenProperty ("writeToString", new XmlWriteToString ("writeToString", evaluator, fp)); - globalXml.putHiddenProperty ("get", new XmlGet ("get", evaluator, fp)); - globalXml.putHiddenProperty ("getFromString", new XmlGetFromString ("getFromString", evaluator, fp)); - go.putHiddenProperty ("Xml", globalXml); - } - class GlobalObjectXml extends BuiltinFunctionObject { - GlobalObjectXml(String name, Evaluator evaluator, FunctionPrototype fp) { - super(fp, evaluator, name, 1); - } - public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - return doConstruct(thisObject, arguments); - } - public ESObject doConstruct(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - throw new EcmaScriptException("Xml can't be instanced"); - } - } + globalXml.putHiddenProperty("length", new ESNumber(1)); + globalXml.putHiddenProperty("read", new XmlRead("read", evaluator, fp, false)); + globalXml.putHiddenProperty("readFromString", + new XmlRead("readFromString", evaluator, fp, true)); + globalXml.putHiddenProperty("write", new XmlWrite("write", evaluator, fp)); + globalXml.putHiddenProperty("writeToString", + new XmlWriteToString("writeToString", evaluator, fp)); + globalXml.putHiddenProperty("get", new XmlGet("get", evaluator, fp)); + globalXml.putHiddenProperty("getFromString", + new XmlGetFromString("getFromString", evaluator, fp)); + go.putHiddenProperty("Xml", globalXml); + } - class XmlWrite extends BuiltinFunctionObject { - XmlWrite(String name, Evaluator evaluator, FunctionPrototype fp) { - super(fp, evaluator, name, 1); - } - public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - if ( arguments==null || arguments.length != 2 ) - throw new EcmaScriptException("Wrong number of arguments in Xml.write()"); - INode node = null; - try { - node = ((ESNode)arguments[0]).getNode(); - } catch ( Exception e ) { - // we definitly need a node - throw new EcmaScriptException("First argument in Xml.write() is not an hopobject"); - } - try { - File tmpFile = new File(arguments[1].toString()+".tmp."+XmlWriter.generateID()); - XmlWriter writer = new XmlWriter (tmpFile, "UTF-8"); - writer.setDatabaseMode(false); - boolean result = writer.write(node); - writer.close(); - File finalFile = new File(arguments[1].toString()); - tmpFile.renameTo (finalFile); - this.evaluator.engine.getApplication().logEvent("wrote xml to " + finalFile.getAbsolutePath() ); - } catch (IOException io) { - throw new EcmaScriptException (io.toString()); - } - return ESBoolean.makeBoolean(true); + class GlobalObjectXml extends BuiltinFunctionObject { + GlobalObjectXml(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); + } + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + return doConstruct(thisObject, arguments); + } + + public ESObject doConstruct(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + throw new EcmaScriptException("Xml can't be instanced"); + } + + public String toString() { + try { + String parser = javax.xml.parsers.DocumentBuilderFactory.newInstance() + .getClass() + .getPackage() + .getName(); + + return "[Xml " + parser + "]"; + } catch (NullPointerException zeero) { + return "[Xml - no parser available]"; + } } } - /** - * Xml.create() is used to get a string containing the xml-content. - * Useful if Xml-content should be made public through the web. - */ + class XmlWrite extends BuiltinFunctionObject { + XmlWrite(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); + } + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + if ((arguments == null) || (arguments.length != 2)) { + throw new EcmaScriptException("Wrong number of arguments in Xml.write()"); + } + + INode node = null; + + try { + node = ((ESNode) arguments[0]).getNode(); + } catch (Exception e) { + // we definitly need a node + throw new EcmaScriptException("First argument in Xml.write() is not an hopobject"); + } + + try { + File tmpFile = new File(arguments[1].toString() + ".tmp." + + XmlWriter.generateID()); + XmlWriter writer = new XmlWriter(tmpFile, "UTF-8"); + + writer.setDatabaseMode(false); + + boolean result = writer.write(node); + + writer.close(); + + File finalFile = new File(arguments[1].toString()); + + tmpFile.renameTo(finalFile); + this.evaluator.engine.getApplication().logEvent("wrote xml to " + + finalFile.getAbsolutePath()); + } catch (IOException io) { + throw new EcmaScriptException(io.toString()); + } + + return ESBoolean.makeBoolean(true); + } + } + + /** + * Xml.create() is used to get a string containing the xml-content. + * Useful if Xml-content should be made public through the web. + */ class XmlWriteToString extends BuiltinFunctionObject { - XmlWriteToString(String name, Evaluator evaluator, FunctionPrototype fp) { - super(fp, evaluator, name, 1); - } - public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - if ( arguments==null || arguments.length==0 ) - throw new EcmaScriptException("Not enough arguments in Xml.writeToString()"); - INode node = null; - try { - node = ((ESNode)arguments[0]).getNode(); - } catch ( Exception e ) { - // we definitly need a node - throw new EcmaScriptException("argument is not an hopobject"); - } - try { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - XmlWriter writer = new XmlWriter (out, "UTF-8"); - // in case we ever want to limit serialization depth... - // if (arguments.length > 1 && arguments[1] instanceof ESNumber) - // writer.setMaxLevels(arguments[1].toInt32()); - writer.setDatabaseMode(false); - boolean result = writer.write(node); - writer.flush(); - return new ESString (out.toString("UTF-8")); - } catch (IOException io) { - throw new EcmaScriptException (io.toString()); - } + XmlWriteToString(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); + } + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + if ((arguments == null) || (arguments.length == 0)) { + throw new EcmaScriptException("Not enough arguments in Xml.writeToString()"); + } + + INode node = null; + + try { + node = ((ESNode) arguments[0]).getNode(); + } catch (Exception e) { + // we definitly need a node + throw new EcmaScriptException("argument is not an hopobject"); + } + + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + XmlWriter writer = new XmlWriter(out, "UTF-8"); + + // in case we ever want to limit serialization depth... + // if (arguments.length > 1 && arguments[1] instanceof ESNumber) + // writer.setMaxLevels(arguments[1].toInt32()); + writer.setDatabaseMode(false); + + boolean result = writer.write(node); + + writer.flush(); + + return new ESString(out.toString("UTF-8")); + } catch (IOException io) { + throw new EcmaScriptException(io.toString()); + } } } class XmlRead extends BuiltinFunctionObject { boolean fromstring; + XmlRead(String name, Evaluator evaluator, FunctionPrototype fp, boolean fromstring) { super(fp, evaluator, name, 1); - this.fromstring = fromstring; + this.fromstring = fromstring; } - public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - if ( arguments==null || arguments.length==0 ) - throw new EcmaScriptException("Missing arguments in Xml.read()"); - INode node = null; - try { - node = ((ESNode)arguments[1]).getNode(); - } catch ( Exception e ) { //classcast, arrayindex etc - // make sure we have a node, even if 2nd arg doesn't exist or is not a node - node = new Node ( (String)null, (String)null, this.evaluator.engine.getApplication().getWrappedNodeManager() ); - } - try { - XmlReader reader = new XmlReader (); - INode result = null; - if (fromstring) - result = reader.read (new StringReader (arguments[0].toString()),node); - else - result = reader.read (new File(arguments[0].toString()),node); - return this.evaluator.engine.getNodeWrapper (result); - } catch ( NoClassDefFoundError e ) { - throw new EcmaScriptException ("Can't load XML parser:"+e); - } catch ( Exception f ) { - throw new EcmaScriptException (f.toString()); - } + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + if ((arguments == null) || (arguments.length == 0)) { + throw new EcmaScriptException("Missing arguments in Xml.read()"); + } + + INode node = null; + + try { + node = ((ESNode) arguments[1]).getNode(); + } catch (Exception e) { //classcast, arrayindex etc + + // make sure we have a node, even if 2nd arg doesn't exist or is not a node + node = new Node((String) null, (String) null, + this.evaluator.engine.getApplication() + .getWrappedNodeManager()); + } + + try { + XmlReader reader = new XmlReader(); + INode result = null; + + if (fromstring) { + result = reader.read(new StringReader(arguments[0].toString()), node); + } else { + result = reader.read(new File(arguments[0].toString()), node); + } + + return this.evaluator.engine.getNodeWrapper(result); + } catch (NoClassDefFoundError e) { + throw new EcmaScriptException("Can't load XML parser:" + e); + } catch (Exception f) { + throw new EcmaScriptException(f.toString()); + } } } @@ -155,24 +241,33 @@ public class DomExtension extends Extension { XmlGet(String name, Evaluator evaluator, FunctionPrototype fp) { super(fp, evaluator, name, 1); } - public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - if ( arguments==null || arguments.length==0 ) - throw new EcmaScriptException("Xml.get() needs a location as an argument"); - try { - XmlConverter converter; - if ( arguments.length>1 ) { - converter = new XmlConverter (arguments[1].toString()); - } else { - converter = new XmlConverter (); - } - INode node = new helma.objectmodel.db.Node ( (String)null, (String)null, this.evaluator.engine.getApplication().getWrappedNodeManager() ); - INode result = converter.convert (arguments[0].toString(),node); - return this.evaluator.engine.getNodeWrapper(result); - } catch ( NoClassDefFoundError e ) { - throw new EcmaScriptException("Can't load dom-capable xml parser."); - } catch ( RuntimeException f ) { - throw new EcmaScriptException(f.toString()); - } + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + if ((arguments == null) || (arguments.length == 0)) { + throw new EcmaScriptException("Xml.get() needs a location as an argument"); + } + + try { + XmlConverter converter; + + if (arguments.length > 1) { + converter = new XmlConverter(arguments[1].toString()); + } else { + converter = new XmlConverter(); + } + + INode node = new helma.objectmodel.db.Node((String) null, (String) null, + this.evaluator.engine.getApplication() + .getWrappedNodeManager()); + INode result = converter.convert(arguments[0].toString(), node); + + return this.evaluator.engine.getNodeWrapper(result); + } catch (NoClassDefFoundError e) { + throw new EcmaScriptException("Can't load dom-capable xml parser."); + } catch (RuntimeException f) { + throw new EcmaScriptException(f.toString()); + } } } @@ -180,27 +275,33 @@ public class DomExtension extends Extension { XmlGetFromString(String name, Evaluator evaluator, FunctionPrototype fp) { super(fp, evaluator, name, 1); } - public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - if ( arguments==null || arguments.length==0 ) - throw new EcmaScriptException("Xml.getFromString() needs an XML string as parameter"); - try { - XmlConverter converter; - if ( arguments.length>1 ) { - converter = new XmlConverter (arguments[1].toString()); - } else { - converter = new XmlConverter (); - } - INode node = new helma.objectmodel.db.Node ( (String)null, (String)null, this.evaluator.engine.getApplication().getWrappedNodeManager() ); - INode result = converter.convertFromString (arguments[0].toString(),node); - return this.evaluator.engine.getNodeWrapper(result); - } catch ( NoClassDefFoundError e ) { - throw new EcmaScriptException("Can't load dom-capable xml parser."); - } catch ( RuntimeException f ) { - throw new EcmaScriptException(f.toString()); - } + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + if ((arguments == null) || (arguments.length == 0)) { + throw new EcmaScriptException("Xml.getFromString() needs an XML string as parameter"); + } + + try { + XmlConverter converter; + + if (arguments.length > 1) { + converter = new XmlConverter(arguments[1].toString()); + } else { + converter = new XmlConverter(); + } + + INode node = new helma.objectmodel.db.Node((String) null, (String) null, + this.evaluator.engine.getApplication() + .getWrappedNodeManager()); + INode result = converter.convertFromString(arguments[0].toString(), node); + + return this.evaluator.engine.getNodeWrapper(result); + } catch (NoClassDefFoundError e) { + throw new EcmaScriptException("Can't load dom-capable xml parser."); + } catch (RuntimeException f) { + throw new EcmaScriptException(f.toString()); + } } } - } - - diff --git a/src/helma/scripting/fesi/extensions/ESMail.java b/src/helma/scripting/fesi/extensions/ESMail.java index c8d1c3ea..13aedd08 100644 --- a/src/helma/scripting/fesi/extensions/ESMail.java +++ b/src/helma/scripting/fesi/extensions/ESMail.java @@ -1,207 +1,353 @@ -// ESMail.java -// Copyright (c) Hannes Wallnöfer 1998-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.scripting.fesi.extensions; -import javax.mail.Session; -import javax.mail.Multipart; -import javax.mail.Address; -import javax.mail.Transport; -import javax.mail.Message; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeUtility; -import javax.mail.internet.MimeMultipart; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.AddressException; -import javax.activation.*; +import FESI.Data.*; +import FESI.Exceptions.*; +import FESI.Interpreter.*; +import helma.util.*; import java.io.*; import java.util.*; -import helma.util.*; -import FESI.Data.*; -import FESI.Interpreter.*; -import FESI.Exceptions.*; +import javax.activation.*; +import javax.mail.Address; +import javax.mail.Message; +import javax.mail.Multipart; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.AddressException; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; +import javax.mail.internet.MimeUtility; /** - * A JavaScript wrapper around a JavaMail message class to send + * A JavaScript wrapper around a JavaMail message class to send * mail via SMTP from Helma */ - public class ESMail extends ESObject implements Serializable { - + public static final int OK = 0; + public static final int SUBJECT = 10; + public static final int TEXT = 11; + public static final int MIMEPART = 12; + public static final int TO = 20; + public static final int CC = 21; + public static final int BCC = 22; + public static final int FROM = 23; + public static final int REPLYTO = 24; + public static final int SEND = 30; MailExtension mailx; Properties mprops; MimeMessage message; Multipart multipart; StringBuffer buffer; - int status; - public static final int OK=0; - public static final int SUBJECT=10; - public static final int TEXT=11; - public static final int MIMEPART=12; - public static final int TO=20; - public static final int CC=21; - public static final int BCC=22; - public static final int FROM=23; - public static final int REPLYTO=24; - public static final int SEND=30; + /** + * Creates a new ESMail object. + * + * @param mailx ... + */ + public ESMail(MailExtension mailx) { + super(mailx.esMailPrototype, mailx.eval); + this.status = OK; + this.mailx = mailx; + this.mprops = mailx.mprops; - public ESMail (MailExtension mailx) { - super (mailx.esMailPrototype, mailx.eval); - this.status = OK; - this.mailx = mailx; - this.mprops = mailx.mprops; + // create some properties and get the default Session + try { + Properties props = new Properties(); - // create some properties and get the default Session - try { - Properties props = new Properties(); - props.put ("mail.smtp.host", mprops.getProperty ("smtp", "mail")); + props.put("mail.smtp.host", mprops.getProperty("smtp", "mail")); - Session session = Session.getDefaultInstance(props, null); - message = new MimeMessage (session); - } catch (Throwable t) { - this.evaluator.engine.getApplication().logEvent ("Error in mail constructor: "+t); - } + Session session = Session.getDefaultInstance(props, null); + + message = new MimeMessage(session); + } catch (Throwable t) { + this.evaluator.engine.getApplication().logEvent("Error in mail constructor: " + + t); + } } - public void setStatus (int status) { - // Only register the first error that occurrs - if (this.status == 0) - this.status = status; + /** + * + * + * @param status ... + */ + public void setStatus(int status) { + // Only register the first error that occurrs + if (this.status == 0) { + this.status = status; + } } - public int getStatus () { - return status; + /** + * + * + * @return ... + */ + public int getStatus() { + return status; } - public ESValue getProperty(String propertyName, int hash) throws EcmaScriptException { - if ("status".equalsIgnoreCase (propertyName)) - return new ESNumber (status); - return super.getProperty (propertyName, hash); + /** + * + * + * @param propertyName ... + * @param hash ... + * + * @return ... + * + * @throws EcmaScriptException ... + */ + public ESValue getProperty(String propertyName, int hash) + throws EcmaScriptException { + if ("status".equalsIgnoreCase(propertyName)) { + return new ESNumber(status); + } + + return super.getProperty(propertyName, hash); } /** * */ + public void setText(ESValue val) throws Exception { + if (buffer == null) { + buffer = new StringBuffer(); + } - public void setText (ESValue val) throws Exception { - if (buffer == null) - buffer = new StringBuffer (); - if (val != null) - buffer.append (val.toString ()); + if (val != null) { + buffer.append(val.toString()); + } } - public void addPart (ESValue val[]) throws Exception { - if (val == null || val.length == 0 || val.length > 2) - throw new IOException ("mail.addPart called with wrong number of arguments."); - if (multipart == null) { - multipart = new MimeMultipart (); - } - MimeBodyPart part = new MimeBodyPart (); - Object obj = val[0].toJavaObject (); - if (obj instanceof String) { - part.setContent (obj.toString (), "text/plain"); - } else if (obj instanceof File) { - FileDataSource source = new FileDataSource ((File) obj); - part.setDataHandler (new DataHandler (source)); - } else if (obj instanceof MimePart) { - MimePartDataSource source = new MimePartDataSource ((MimePart) obj); - part.setDataHandler (new DataHandler (source)); - } - // check if an explicit file name was given for this part - if (val.length == 2) try { - part.setFileName (val[1].toString()); - } catch (Exception x) { - // FIXME: error setting file name ... should we ignore this or throw an exception? - } - multipart.addBodyPart (part); + /** + * + * + * @param val ... + * + * @throws Exception ... + * @throws IOException ... + */ + public void addPart(ESValue[] val) throws Exception { + if ((val == null) || (val.length == 0) || (val.length > 2)) { + throw new IOException("mail.addPart called with wrong number of arguments."); + } + + if (multipart == null) { + multipart = new MimeMultipart(); + } + + MimeBodyPart part = new MimeBodyPart(); + Object obj = val[0].toJavaObject(); + + if (obj instanceof String) { + part.setContent(obj.toString(), "text/plain"); + } else if (obj instanceof File) { + FileDataSource source = new FileDataSource((File) obj); + + part.setDataHandler(new DataHandler(source)); + } else if (obj instanceof MimePart) { + MimePartDataSource source = new MimePartDataSource((MimePart) obj); + + part.setDataHandler(new DataHandler(source)); + } + + // check if an explicit file name was given for this part + if (val.length == 2) { + try { + part.setFileName(val[1].toString()); + } catch (Exception x) { + // FIXME: error setting file name ... should we ignore this or throw an exception? + } + } + + multipart.addBodyPart(part); } - public void setSubject (ESValue val) throws Exception { - if (val == null) - return; - message.setSubject (MimeUtility.encodeWord (val.toString ())); + /** + * + * + * @param val ... + * + * @throws Exception ... + */ + public void setSubject(ESValue val) throws Exception { + if (val == null) { + return; + } + + message.setSubject(MimeUtility.encodeWord(val.toString())); } - public void setReplyTo (ESValue add) throws Exception { - String addstring = add.toString (); - if (addstring.indexOf ("@") < 0) - throw new AddressException (); - Address replyTo[] = new Address[1]; - replyTo[0] = new InternetAddress (addstring); - message.setReplyTo (replyTo); + /** + * + * + * @param add ... + * + * @throws Exception ... + * @throws AddressException ... + */ + public void setReplyTo(ESValue add) throws Exception { + String addstring = add.toString(); + + if (addstring.indexOf("@") < 0) { + throw new AddressException(); + } + + Address[] replyTo = new Address[1]; + + replyTo[0] = new InternetAddress(addstring); + message.setReplyTo(replyTo); } - public void setFrom (ESValue add[]) throws Exception { - String addstring = add[0].toString (); - if (addstring.indexOf ("@") < 0) - throw new AddressException (); - Address address = null; - if (add.length > 1) - address = new InternetAddress (addstring, MimeUtility.encodeWord (add[1].toString ())); - else - address = new InternetAddress (addstring); - message.setFrom (address); + /** + * + * + * @param add ... + * + * @throws Exception ... + * @throws AddressException ... + */ + public void setFrom(ESValue[] add) throws Exception { + String addstring = add[0].toString(); + + if (addstring.indexOf("@") < 0) { + throw new AddressException(); + } + + Address address = null; + + if (add.length > 1) { + address = new InternetAddress(addstring, + MimeUtility.encodeWord(add[1].toString())); + } else { + address = new InternetAddress(addstring); + } + + message.setFrom(address); } - public void addTo (ESValue add[]) throws Exception { - String addstring = add[0].toString (); - if (addstring.indexOf ("@") < 0) - throw new AddressException (); - Address address = null; - if (add.length > 1) - address = new InternetAddress (addstring, MimeUtility.encodeWord (add[1].toString ())); - else - address = new InternetAddress (addstring); - message.addRecipient (Message.RecipientType.TO, address); + /** + * + * + * @param add ... + * + * @throws Exception ... + * @throws AddressException ... + */ + public void addTo(ESValue[] add) throws Exception { + String addstring = add[0].toString(); + + if (addstring.indexOf("@") < 0) { + throw new AddressException(); + } + + Address address = null; + + if (add.length > 1) { + address = new InternetAddress(addstring, + MimeUtility.encodeWord(add[1].toString())); + } else { + address = new InternetAddress(addstring); + } + + message.addRecipient(Message.RecipientType.TO, address); } - public void addCC (ESValue add[]) throws Exception { - String addstring = add[0].toString (); - if (addstring.indexOf ("@") < 0) - throw new AddressException (); - Address address = null; - if (add.length > 1) - address = new InternetAddress (addstring, MimeUtility.encodeWord (add[1].toString ())); - else - address = new InternetAddress (addstring); - message.addRecipient (Message.RecipientType.CC, address); + /** + * + * + * @param add ... + * + * @throws Exception ... + * @throws AddressException ... + */ + public void addCC(ESValue[] add) throws Exception { + String addstring = add[0].toString(); + + if (addstring.indexOf("@") < 0) { + throw new AddressException(); + } + + Address address = null; + + if (add.length > 1) { + address = new InternetAddress(addstring, + MimeUtility.encodeWord(add[1].toString())); + } else { + address = new InternetAddress(addstring); + } + + message.addRecipient(Message.RecipientType.CC, address); } - public void addBCC (ESValue add[]) throws Exception { - String addstring = add[0].toString (); - if (addstring.indexOf ("@") < 0) - throw new AddressException (); - Address address = null; - if (add.length > 1) - address = new InternetAddress (addstring, MimeUtility.encodeWord (add[1].toString ())); - else - address = new InternetAddress (addstring); - message.addRecipient (Message.RecipientType.BCC, address); + /** + * + * + * @param add ... + * + * @throws Exception ... + * @throws AddressException ... + */ + public void addBCC(ESValue[] add) throws Exception { + String addstring = add[0].toString(); + + if (addstring.indexOf("@") < 0) { + throw new AddressException(); + } + + Address address = null; + + if (add.length > 1) { + address = new InternetAddress(addstring, + MimeUtility.encodeWord(add[1].toString())); + } else { + address = new InternetAddress(addstring); + } + + message.addRecipient(Message.RecipientType.BCC, address); } - public void send () throws Exception { - if (buffer != null) { - // if we also have a multipart body, add - // plain string as first part to it. - if (multipart != null) { - MimeBodyPart part = new MimeBodyPart (); - part.setContent (buffer.toString (), "text/plain"); - multipart.addBodyPart (part, 0); - message.setContent (multipart); - } else { - message.setText (buffer.toString ()); - } - } else if (multipart != null) - message.setContent (multipart); - else - message.setText (""); - Transport.send (message); + /** + * + * + * @throws Exception ... + */ + public void send() throws Exception { + if (buffer != null) { + // if we also have a multipart body, add + // plain string as first part to it. + if (multipart != null) { + MimeBodyPart part = new MimeBodyPart(); + + part.setContent(buffer.toString(), "text/plain"); + multipart.addBodyPart(part, 0); + message.setContent(multipart); + } else { + message.setText(buffer.toString()); + } + } else if (multipart != null) { + message.setContent(multipart); + } else { + message.setText(""); + } + + Transport.send(message); } - - } - diff --git a/src/helma/scripting/fesi/extensions/FtpExtension.java b/src/helma/scripting/fesi/extensions/FtpExtension.java index 007f5a64..0c772170 100644 --- a/src/helma/scripting/fesi/extensions/FtpExtension.java +++ b/src/helma/scripting/fesi/extensions/FtpExtension.java @@ -1,35 +1,43 @@ -// FtpExtension.java -// Copyright (c) Hannes Wallnöfer 1998-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.scripting.fesi.extensions; -import helma.objectmodel.*; -import FESI.Parser.*; import FESI.AST.*; -import FESI.Interpreter.*; +import FESI.Data.*; import FESI.Exceptions.*; import FESI.Extensions.*; -import FESI.Data.*; +import FESI.Interpreter.*; +import FESI.Parser.*; +import com.oroinc.net.ftp.*; +import helma.objectmodel.*; import java.io.*; -import com.oroinc.net.ftp.*; - - /** - * A FTP-client object that allows to do some FTP from HOP applications. - * FTP support is far from complete but can easily be extended if more - * functionality is needed. - * This uses the NetComponent classes from savarese.org (ex oroinc.com). - */ - + * A FTP-client object that allows to do some FTP from HOP applications. + * FTP support is far from complete but can easily be extended if more + * functionality is needed. + * This uses the NetComponent classes from savarese.org (ex oroinc.com). + */ class ESFtpClient extends ESObject { - private FTPClient ftpclient; private String server; private Exception lastError = null; private File localDir = null; - /** * Create a new FTP Client * @@ -38,35 +46,48 @@ class ESFtpClient extends ESObject { */ ESFtpClient(ESObject prototype, Evaluator evaluator, ESValue srvstr) { super(prototype, evaluator); - this.server = srvstr.toString (); + this.server = srvstr.toString(); } ESFtpClient(ESObject prototype, Evaluator evaluator) { super(prototype, evaluator); } - + /** + * + * + * @return ... + */ public String getESClassName() { return "FtpClient"; } - + + /** + * + * + * @return ... + */ public String toString() { - return "[FtpClient]"; + return "[FtpClient]"; } - + + /** + * + * + * @return ... + */ public String toDetailString() { - return "ES:[Object: builtin " + this.getClass().getName() + ":" + - this.toString() + "]"; + return "ES:[Object: builtin " + this.getClass().getName() + ":" + + this.toString() + "]"; } - - ESValue getLastError() throws EcmaScriptException { + + ESValue getLastError() throws EcmaScriptException { if (lastError == null) { return ESNull.theNull; } else { return ESLoader.normalizeValue(lastError, evaluator); } } - /** * Login to the FTP server @@ -74,108 +95,154 @@ class ESFtpClient extends ESObject { * @param arguments The argument list * @return true if successful, false otherwise */ - ESValue login(ESValue arguments[]) throws EcmaScriptException { - if (server == null) + ESValue login(ESValue[] arguments) throws EcmaScriptException { + if (server == null) { return ESBoolean.makeBoolean(false); + } + try { - ftpclient = new FTPClient (); - ftpclient.connect (server); - boolean b = ftpclient.login (arguments[0].toString(), arguments[1].toString()); - return ESBoolean.makeBoolean (b); + ftpclient = new FTPClient(); + ftpclient.connect(server); + + boolean b = ftpclient.login(arguments[0].toString(), arguments[1].toString()); + + return ESBoolean.makeBoolean(b); } catch (Exception x) { - return ESBoolean.makeBoolean (false); + return ESBoolean.makeBoolean(false); } catch (NoClassDefFoundError x) { - return ESBoolean.makeBoolean (false); + return ESBoolean.makeBoolean(false); } } - ESValue cd (ESValue arguments[]) throws EcmaScriptException { - if (ftpclient == null) - return ESBoolean.makeBoolean(false); + ESValue cd(ESValue[] arguments) throws EcmaScriptException { + if (ftpclient == null) { + return ESBoolean.makeBoolean(false); + } + try { - ftpclient.changeWorkingDirectory (arguments[0].toString ()); - return ESBoolean.makeBoolean(true); - } catch (Exception wrong) {} + ftpclient.changeWorkingDirectory(arguments[0].toString()); + + return ESBoolean.makeBoolean(true); + } catch (Exception wrong) { + } + return ESBoolean.makeBoolean(false); } + ESValue mkdir(ESValue[] arguments) throws EcmaScriptException { + if (ftpclient == null) { + return ESBoolean.makeBoolean(false); + } - ESValue mkdir (ESValue arguments[]) throws EcmaScriptException { - if (ftpclient == null) - return ESBoolean.makeBoolean(false); try { - return ESBoolean.makeBoolean(ftpclient.makeDirectory (arguments[0].toString ())); - } catch (Exception wrong) {} + return ESBoolean.makeBoolean(ftpclient.makeDirectory(arguments[0].toString())); + } catch (Exception wrong) { + } + return ESBoolean.makeBoolean(false); } - ESValue lcd (ESValue arguments[]) throws EcmaScriptException { + ESValue lcd(ESValue[] arguments) throws EcmaScriptException { try { - localDir = new File (arguments[0].toString()); - if (!localDir.exists()) - localDir.mkdirs(); - return ESBoolean.makeBoolean(true); - } catch (Exception wrong) {} + localDir = new File(arguments[0].toString()); + + if (!localDir.exists()) { + localDir.mkdirs(); + } + + return ESBoolean.makeBoolean(true); + } catch (Exception wrong) { + } + return ESBoolean.makeBoolean(false); } - ESValue putFile(ESValue arguments[]) throws EcmaScriptException { - if (ftpclient == null) - return ESBoolean.makeBoolean(false); + ESValue putFile(ESValue[] arguments) throws EcmaScriptException { + if (ftpclient == null) { + return ESBoolean.makeBoolean(false); + } + try { - String fn = arguments[0].toString(); - File f = localDir == null ? new File (fn) : new File (localDir, fn); - InputStream fin = new BufferedInputStream (new FileInputStream (f)); - ftpclient.storeFile (arguments[1].toString (), fin); - fin.close (); - return ESBoolean.makeBoolean(true); - } catch (Exception wrong) {} + String fn = arguments[0].toString(); + File f = (localDir == null) ? new File(fn) : new File(localDir, fn); + InputStream fin = new BufferedInputStream(new FileInputStream(f)); + + ftpclient.storeFile(arguments[1].toString(), fin); + fin.close(); + + return ESBoolean.makeBoolean(true); + } catch (Exception wrong) { + } + return ESBoolean.makeBoolean(false); } - ESValue putString(ESValue arguments[]) throws EcmaScriptException { - if (ftpclient == null) - return ESBoolean.makeBoolean(false); + ESValue putString(ESValue[] arguments) throws EcmaScriptException { + if (ftpclient == null) { + return ESBoolean.makeBoolean(false); + } + try { - byte[] bytes = null; - // check if this already is a byte array - if (arguments[0] instanceof ESArrayWrapper) { - Object o = ((ESArrayWrapper) arguments[0]).toJavaObject (); - if (o instanceof byte[]) - bytes = (byte[]) o; - } - if (bytes == null) - bytes = arguments[0].toString().getBytes(); - ByteArrayInputStream bin = new ByteArrayInputStream (bytes); - ftpclient.storeFile (arguments[1].toString (), bin); - return ESBoolean.makeBoolean(true); - } catch (Exception wrong) {} + byte[] bytes = null; + + // check if this already is a byte array + if (arguments[0] instanceof ESArrayWrapper) { + Object o = ((ESArrayWrapper) arguments[0]).toJavaObject(); + + if (o instanceof byte[]) { + bytes = (byte[]) o; + } + } + + if (bytes == null) { + bytes = arguments[0].toString().getBytes(); + } + + ByteArrayInputStream bin = new ByteArrayInputStream(bytes); + + ftpclient.storeFile(arguments[1].toString(), bin); + + return ESBoolean.makeBoolean(true); + } catch (Exception wrong) { + } + return ESBoolean.makeBoolean(false); } + ESValue getFile(ESValue[] arguments) throws EcmaScriptException { + if (ftpclient == null) { + return ESBoolean.makeBoolean(false); + } - ESValue getFile(ESValue arguments[]) throws EcmaScriptException { - if (ftpclient == null ) - return ESBoolean.makeBoolean(false); try { - String fn = arguments[0].toString(); - File f = localDir == null ? new File (fn) : new File (localDir, fn); - OutputStream out = new BufferedOutputStream (new FileOutputStream(f)); - ftpclient.retrieveFile (arguments[0].toString (), out); - out.close (); - return ESBoolean.makeBoolean(true); - } catch (Exception wrong) {} + String fn = arguments[0].toString(); + File f = (localDir == null) ? new File(fn) : new File(localDir, fn); + OutputStream out = new BufferedOutputStream(new FileOutputStream(f)); + + ftpclient.retrieveFile(arguments[0].toString(), out); + out.close(); + + return ESBoolean.makeBoolean(true); + } catch (Exception wrong) { + } + return ESBoolean.makeBoolean(false); } - ESValue getString(ESValue arguments[]) throws EcmaScriptException { - if (ftpclient == null ) + ESValue getString(ESValue[] arguments) throws EcmaScriptException { + if (ftpclient == null) { return ESNull.theNull; + } + try { - ByteArrayOutputStream bout = new ByteArrayOutputStream (); - ftpclient.retrieveFile (arguments[0].toString (), bout); - return new ESString (bout.toString ()); - } catch (Exception wrong) {} + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + + ftpclient.retrieveFile(arguments[0].toString(), bout); + + return new ESString(bout.toString()); + } catch (Exception wrong) { + } + return ESNull.theNull; } @@ -185,84 +252,144 @@ class ESFtpClient extends ESObject { * @param arguments The argument list * @return true if successful, false otherwise */ - ESValue logout (ESValue arguments[]) throws EcmaScriptException { + ESValue logout(ESValue[] arguments) throws EcmaScriptException { if (ftpclient != null) { - try { - ftpclient.logout (); - } catch (IOException ignore) {} - try { - ftpclient.disconnect (); - } catch (IOException ignore) {} + try { + ftpclient.logout(); + } catch (IOException ignore) { + } + + try { + ftpclient.disconnect(); + } catch (IOException ignore) { + } } - return ESBoolean.makeBoolean (true); + + return ESBoolean.makeBoolean(true); } - ESValue binary (ESValue arguments[]) throws EcmaScriptException { + ESValue binary(ESValue[] arguments) throws EcmaScriptException { if (ftpclient != null) { - try { - ftpclient.setFileType (FTP.BINARY_FILE_TYPE); - return ESBoolean.makeBoolean (true); - } catch (IOException ignore) {} + try { + ftpclient.setFileType(FTP.BINARY_FILE_TYPE); + + return ESBoolean.makeBoolean(true); + } catch (IOException ignore) { + } } - return ESBoolean.makeBoolean (false); + + return ESBoolean.makeBoolean(false); } - ESValue ascii (ESValue arguments[]) throws EcmaScriptException { + ESValue ascii(ESValue[] arguments) throws EcmaScriptException { if (ftpclient != null) { - try { - ftpclient.setFileType (FTP.ASCII_FILE_TYPE); - return ESBoolean.makeBoolean (true); - } catch (IOException ignore) {} + try { + ftpclient.setFileType(FTP.ASCII_FILE_TYPE); + + return ESBoolean.makeBoolean(true); + } catch (IOException ignore) { + } } - return ESBoolean.makeBoolean (false); + + return ESBoolean.makeBoolean(false); } - - } +/** + * + */ public class FtpExtension extends Extension { - private transient Evaluator evaluator = null; private ESObject esFtpPrototype = null; - public FtpExtension () { + /** + * Creates a new FtpExtension object. + */ + public FtpExtension() { super(); } + /** + * + * + * @param evaluator ... + * + * @throws EcmaScriptException ... + */ + public void initializeExtension(Evaluator evaluator) + throws EcmaScriptException { + this.evaluator = evaluator; + + GlobalObject go = evaluator.getGlobalObject(); + ObjectPrototype op = (ObjectPrototype) evaluator.getObjectPrototype(); + FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype(); + + esFtpPrototype = new ESFtpClient(op, evaluator); + + ESObject globalFtpObject = new GlobalObjectFtpClient("FtpClient", evaluator, fp); + + globalFtpObject.putHiddenProperty("prototype", esFtpPrototype); + globalFtpObject.putHiddenProperty("length", new ESNumber(1)); + + esFtpPrototype.putHiddenProperty("login", + new FtpClientLogin("login", evaluator, fp)); + esFtpPrototype.putHiddenProperty("cd", new FtpClientCD("cd", evaluator, fp)); + esFtpPrototype.putHiddenProperty("mkdir", + new FtpClientMKDIR("mkdir", evaluator, fp)); + esFtpPrototype.putHiddenProperty("lcd", new FtpClientLCD("lcd", evaluator, fp)); + esFtpPrototype.putHiddenProperty("putFile", + new FtpClientPutFile("putFile", evaluator, fp)); + esFtpPrototype.putHiddenProperty("putString", + new FtpClientPutString("putString", evaluator, fp)); + esFtpPrototype.putHiddenProperty("getFile", + new FtpClientGetFile("getFile", evaluator, fp)); + esFtpPrototype.putHiddenProperty("getString", + new FtpClientGetString("getString", evaluator, fp)); + esFtpPrototype.putHiddenProperty("logout", + new FtpClientLogout("logout", evaluator, fp)); + esFtpPrototype.putHiddenProperty("binary", + new FtpClientBinary("binary", evaluator, fp)); + esFtpPrototype.putHiddenProperty("ascii", + new FtpClientAscii("ascii", evaluator, fp)); + + go.putHiddenProperty("FtpClient", globalFtpObject); + } + class GlobalObjectFtpClient extends BuiltinFunctionObject { GlobalObjectFtpClient(String name, Evaluator evaluator, FunctionPrototype fp) { super(fp, evaluator, name, 1); } public ESValue callFunction(ESObject thisObject, ESValue[] arguments) - throws EcmaScriptException { - return doConstruct(thisObject, arguments); + throws EcmaScriptException { + return doConstruct(thisObject, arguments); } public ESObject doConstruct(ESObject thisObject, ESValue[] arguments) - throws EcmaScriptException { - ESFtpClient ftp = null; - if (arguments.length != 1) - throw new EcmaScriptException("FtpClient requires 1 argument"); - ftp = new ESFtpClient (esFtpPrototype, - this.evaluator, - arguments[0]); - return ftp; + throws EcmaScriptException { + ESFtpClient ftp = null; + + if (arguments.length != 1) { + throw new EcmaScriptException("FtpClient requires 1 argument"); + } + + ftp = new ESFtpClient(esFtpPrototype, this.evaluator, arguments[0]); + + return ftp; } - } - class FtpClientLogin extends BuiltinFunctionObject { FtpClientLogin(String name, Evaluator evaluator, FunctionPrototype fp) { super(fp, evaluator, name, 1); } - public ESValue callFunction(ESObject thisObject, - ESValue[] arguments) - throws EcmaScriptException { - ESFtpClient ftp = (ESFtpClient) thisObject; - return ftp.login (arguments); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESFtpClient ftp = (ESFtpClient) thisObject; + + return ftp.login(arguments); } } @@ -270,11 +397,12 @@ public class FtpExtension extends Extension { FtpClientCD(String name, Evaluator evaluator, FunctionPrototype fp) { super(fp, evaluator, name, 1); } - public ESValue callFunction(ESObject thisObject, - ESValue[] arguments) - throws EcmaScriptException { - ESFtpClient ftp = (ESFtpClient) thisObject; - return ftp.cd (arguments); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESFtpClient ftp = (ESFtpClient) thisObject; + + return ftp.cd(arguments); } } @@ -282,11 +410,12 @@ public class FtpExtension extends Extension { FtpClientMKDIR(String name, Evaluator evaluator, FunctionPrototype fp) { super(fp, evaluator, name, 1); } - public ESValue callFunction(ESObject thisObject, - ESValue[] arguments) - throws EcmaScriptException { - ESFtpClient ftp = (ESFtpClient) thisObject; - return ftp.mkdir (arguments); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESFtpClient ftp = (ESFtpClient) thisObject; + + return ftp.mkdir(arguments); } } @@ -294,59 +423,64 @@ public class FtpExtension extends Extension { FtpClientLCD(String name, Evaluator evaluator, FunctionPrototype fp) { super(fp, evaluator, name, 1); } - public ESValue callFunction(ESObject thisObject, - ESValue[] arguments) - throws EcmaScriptException { - ESFtpClient ftp = (ESFtpClient) thisObject; - return ftp.lcd (arguments); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESFtpClient ftp = (ESFtpClient) thisObject; + + return ftp.lcd(arguments); } } class FtpClientPutFile extends BuiltinFunctionObject { - FtpClientPutFile (String name, Evaluator evaluator, FunctionPrototype fp) { + FtpClientPutFile(String name, Evaluator evaluator, FunctionPrototype fp) { super(fp, evaluator, name, 1); } - public ESValue callFunction(ESObject thisObject, - ESValue[] arguments) - throws EcmaScriptException { - ESFtpClient ftp = (ESFtpClient) thisObject; - return ftp.putFile (arguments); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESFtpClient ftp = (ESFtpClient) thisObject; + + return ftp.putFile(arguments); } } class FtpClientPutString extends BuiltinFunctionObject { - FtpClientPutString (String name, Evaluator evaluator, FunctionPrototype fp) { + FtpClientPutString(String name, Evaluator evaluator, FunctionPrototype fp) { super(fp, evaluator, name, 1); } - public ESValue callFunction(ESObject thisObject, - ESValue[] arguments) - throws EcmaScriptException { - ESFtpClient ftp = (ESFtpClient) thisObject; - return ftp.putString (arguments); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESFtpClient ftp = (ESFtpClient) thisObject; + + return ftp.putString(arguments); } } class FtpClientGetFile extends BuiltinFunctionObject { - FtpClientGetFile (String name, Evaluator evaluator, FunctionPrototype fp) { + FtpClientGetFile(String name, Evaluator evaluator, FunctionPrototype fp) { super(fp, evaluator, name, 1); } - public ESValue callFunction(ESObject thisObject, - ESValue[] arguments) - throws EcmaScriptException { - ESFtpClient ftp = (ESFtpClient) thisObject; - return ftp.getFile (arguments); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESFtpClient ftp = (ESFtpClient) thisObject; + + return ftp.getFile(arguments); } } class FtpClientGetString extends BuiltinFunctionObject { - FtpClientGetString (String name, Evaluator evaluator, FunctionPrototype fp) { + FtpClientGetString(String name, Evaluator evaluator, FunctionPrototype fp) { super(fp, evaluator, name, 1); } - public ESValue callFunction(ESObject thisObject, - ESValue[] arguments) - throws EcmaScriptException { - ESFtpClient ftp = (ESFtpClient) thisObject; - return ftp.getString (arguments); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESFtpClient ftp = (ESFtpClient) thisObject; + + return ftp.getString(arguments); } } @@ -354,11 +488,12 @@ public class FtpExtension extends Extension { FtpClientLogout(String name, Evaluator evaluator, FunctionPrototype fp) { super(fp, evaluator, name, 1); } - public ESValue callFunction(ESObject thisObject, - ESValue[] arguments) - throws EcmaScriptException { - ESFtpClient ftp = (ESFtpClient) thisObject; - return ftp.logout (arguments); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESFtpClient ftp = (ESFtpClient) thisObject; + + return ftp.logout(arguments); } } @@ -366,11 +501,12 @@ public class FtpExtension extends Extension { FtpClientBinary(String name, Evaluator evaluator, FunctionPrototype fp) { super(fp, evaluator, name, 1); } - public ESValue callFunction(ESObject thisObject, - ESValue[] arguments) - throws EcmaScriptException { - ESFtpClient ftp = (ESFtpClient) thisObject; - return ftp.binary (arguments); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESFtpClient ftp = (ESFtpClient) thisObject; + + return ftp.binary(arguments); } } @@ -378,42 +514,12 @@ public class FtpExtension extends Extension { FtpClientAscii(String name, Evaluator evaluator, FunctionPrototype fp) { super(fp, evaluator, name, 1); } - public ESValue callFunction(ESObject thisObject, - ESValue[] arguments) - throws EcmaScriptException { - ESFtpClient ftp = (ESFtpClient) thisObject; - return ftp.ascii (arguments); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESFtpClient ftp = (ESFtpClient) thisObject; + + return ftp.ascii(arguments); } } - - - public void initializeExtension(Evaluator evaluator) throws EcmaScriptException { - - this.evaluator = evaluator; - GlobalObject go = evaluator.getGlobalObject(); - ObjectPrototype op = (ObjectPrototype) evaluator.getObjectPrototype(); - FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype(); - - esFtpPrototype = new ESFtpClient (op, evaluator); - - ESObject globalFtpObject = new GlobalObjectFtpClient("FtpClient", evaluator, fp); - globalFtpObject.putHiddenProperty("prototype",esFtpPrototype); - globalFtpObject.putHiddenProperty("length",new ESNumber(1)); - - - esFtpPrototype.putHiddenProperty("login", new FtpClientLogin("login", evaluator, fp)); - esFtpPrototype.putHiddenProperty("cd", new FtpClientCD("cd", evaluator, fp)); - esFtpPrototype.putHiddenProperty("mkdir", new FtpClientMKDIR("mkdir", evaluator, fp)); - esFtpPrototype.putHiddenProperty("lcd", new FtpClientLCD("lcd", evaluator, fp)); - esFtpPrototype.putHiddenProperty("putFile", new FtpClientPutFile("putFile", evaluator, fp)); - esFtpPrototype.putHiddenProperty("putString", new FtpClientPutString("putString", evaluator, fp)); - esFtpPrototype.putHiddenProperty("getFile", new FtpClientGetFile("getFile", evaluator, fp)); - esFtpPrototype.putHiddenProperty("getString", new FtpClientGetString("getString", evaluator, fp)); - esFtpPrototype.putHiddenProperty("logout", new FtpClientLogout("logout", evaluator, fp)); - esFtpPrototype.putHiddenProperty("binary", new FtpClientBinary("binary", evaluator, fp)); - esFtpPrototype.putHiddenProperty("ascii", new FtpClientAscii("ascii", evaluator, fp)); - - go.putHiddenProperty("FtpClient", globalFtpObject); - - } - } +} diff --git a/src/helma/scripting/fesi/extensions/ImageExtension.java b/src/helma/scripting/fesi/extensions/ImageExtension.java index 2add810d..822e38a4 100644 --- a/src/helma/scripting/fesi/extensions/ImageExtension.java +++ b/src/helma/scripting/fesi/extensions/ImageExtension.java @@ -1,106 +1,124 @@ -// ImageExtension.java -// Copyright (c) Hannes Wallnöfer 1998-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.scripting.fesi.extensions; -import helma.objectmodel.*; -import helma.util.*; -import helma.image.*; - -import FESI.Interpreter.*; +import FESI.Data.*; import FESI.Exceptions.*; import FESI.Extensions.*; -import FESI.Data.*; - -import java.io.*; +import FESI.Interpreter.*; +import helma.image.*; +import helma.objectmodel.*; +import helma.util.*; import java.awt.image.*; -import java.util.*; +import java.io.*; import java.rmi.Naming; - +import java.util.*; /** * Extension to do Image manipulation from HOP. */ - public class ImageExtension extends Extension { - + static ImageGenerator imggen; protected Evaluator evaluator = null; - static ImageGenerator imggen; - - - public ImageExtension () { + /** + * Creates a new ImageExtension object. + */ + public ImageExtension() { super(); } + /** + * Called by the evaluator after the extension is loaded. + */ + public void initializeExtension(Evaluator evaluator) + throws EcmaScriptException { + this.evaluator = evaluator; + + GlobalObject go = evaluator.getGlobalObject(); + FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype(); + ESObject image = new GlobalObjectImage("Image", evaluator, fp, this); // the Image constructor + + go.putHiddenProperty("Image", image); // register the constructor for a Image object. + } class GlobalObjectImage extends BuiltinFunctionObject { - ImageExtension imagex; - GlobalObjectImage (String name, Evaluator evaluator, FunctionPrototype fp, ImageExtension imagex) { + GlobalObjectImage(String name, Evaluator evaluator, FunctionPrototype fp, + ImageExtension imagex) { super(fp, evaluator, name, 1); this.imagex = imagex; } - public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - return doConstruct(thisObject, arguments); + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + return doConstruct(thisObject, arguments); } - public ESObject doConstruct(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { + public ESObject doConstruct(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { Object img = null; try { if (imggen == null) { try { - imggen = new ImageGenerator (); + imggen = new ImageGenerator(); } catch (UnsatisfiedLinkError noawt) { - System.err.println ("Error creating Image: "+noawt); + System.err.println("Error creating Image: " + noawt); } } if (arguments.length == 1) { if (arguments[0] instanceof ESArrayWrapper) { - Object obj = ((ESArrayWrapper) arguments[0]).toJavaObject (); + Object obj = ((ESArrayWrapper) arguments[0]).toJavaObject(); + if (obj instanceof byte[]) { - img = imggen.createImage ((byte[]) obj); + img = imggen.createImage((byte[]) obj); } } else if (arguments[0] instanceof ESString) { - String imgurl = arguments[0].toString (); - img = imggen.createPaintableImage (imgurl); + String imgurl = arguments[0].toString(); + + img = imggen.createPaintableImage(imgurl); } } else if (arguments.length == 2) { - if (arguments[0] instanceof ESWrapper && arguments[1] instanceof ESWrapper) { + if (arguments[0] instanceof ESWrapper && + arguments[1] instanceof ESWrapper) { // create a new image from an existing one and an image filter - Object image = arguments[0].toJavaObject (); - Object filter = arguments[1].toJavaObject (); - img = imggen.createPaintableImage ((ImageWrapper) image, (ImageFilter) filter); - } else if (arguments[0].isNumberValue () && arguments[1].isNumberValue ()) { - img = imggen.createPaintableImage (arguments[0].toInt32(), arguments[1].toInt32()); + Object image = arguments[0].toJavaObject(); + Object filter = arguments[1].toJavaObject(); + + img = imggen.createPaintableImage((ImageWrapper) image, + (ImageFilter) filter); + } else if (arguments[0].isNumberValue() && + arguments[1].isNumberValue()) { + img = imggen.createPaintableImage(arguments[0].toInt32(), + arguments[1].toInt32()); } } } catch (Exception error) { - System.err.println ("Error creating Image: "+error); + System.err.println("Error creating Image: " + error); } - if (img == null) - throw new EcmaScriptException ("Error creating image: Bad parameters or setup problem."); + if (img == null) { + throw new EcmaScriptException("Error creating image: Bad parameters or setup problem."); + } - return new ESWrapper (img, this.evaluator); + return new ESWrapper(img, this.evaluator); } } - - - /** - * Called by the evaluator after the extension is loaded. - */ - public void initializeExtension(Evaluator evaluator) throws EcmaScriptException { - this.evaluator = evaluator; - GlobalObject go = evaluator.getGlobalObject(); - FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype(); - ESObject image = new GlobalObjectImage ("Image", evaluator, fp, this); // the Image constructor - go.putHiddenProperty("Image", image); // register the constructor for a Image object. - } - } - diff --git a/src/helma/scripting/fesi/extensions/MailExtension.java b/src/helma/scripting/fesi/extensions/MailExtension.java index 103e0d4b..8b69f841 100644 --- a/src/helma/scripting/fesi/extensions/MailExtension.java +++ b/src/helma/scripting/fesi/extensions/MailExtension.java @@ -1,254 +1,324 @@ -// MailExtension.java -// Copyright (c) Hannes Wallnöfer 1998-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.scripting.fesi.extensions; -import helma.util.*; - -import FESI.Interpreter.*; +import FESI.Data.*; import FESI.Exceptions.*; import FESI.Extensions.*; -import FESI.Data.*; - +import FESI.Interpreter.*; +import helma.util.*; import java.io.*; import java.util.*; - -/** +/** * Extension to create and send mail messages via SMTP from HOP applications */ - public class MailExtension extends Extension { - - protected Evaluator eval = null; protected ObjectPrototype esMailPrototype = null; protected Properties mprops; - - public MailExtension () { + /** + * Creates a new MailExtension object. + */ + public MailExtension() { super(); } - public void setProperties (Properties props) { + /** + * + * + * @param props ... + */ + public void setProperties(Properties props) { this.mprops = props; } /** * Called by the evaluator after the extension is loaded. */ - public void initializeExtension(Evaluator evaluator) throws EcmaScriptException { - + public void initializeExtension(Evaluator evaluator) + throws EcmaScriptException { this.eval = evaluator; + GlobalObject go = evaluator.getGlobalObject(); FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype(); ESObject op = evaluator.getObjectPrototype(); - esMailPrototype = new ObjectPrototype(op, evaluator); // the Node prototype - ESObject mail = new GlobalObjectMail ("Mail", evaluator, fp, this); // the Mail constructor + esMailPrototype = new ObjectPrototype(op, evaluator); // the Node prototype + + ESObject mail = new GlobalObjectMail("Mail", evaluator, fp, this); // the Mail constructor go.putHiddenProperty("Mail", mail); // register the constructor for a Mail object. - // methods for sending mail from JS... - ESObject p = new MailSetText ("setText", evaluator, fp); + ESObject p = new MailSetText("setText", evaluator, fp); + esMailPrototype.putHiddenProperty("setText", p); esMailPrototype.putHiddenProperty("addText", p); - esMailPrototype.putHiddenProperty("addPart", new MailAddPart ("addPart", evaluator, fp)); - esMailPrototype.putHiddenProperty("setSubject", new MailSetSubject ("setSubject", evaluator, fp)); - esMailPrototype.putHiddenProperty("setReplyTo", new MailSetReplyTo ("setReplyTo", evaluator, fp)); - esMailPrototype.putHiddenProperty("setFrom", new MailSetFrom ("setFrom", evaluator, fp)); + esMailPrototype.putHiddenProperty("addPart", + new MailAddPart("addPart", evaluator, fp)); + esMailPrototype.putHiddenProperty("setSubject", + new MailSetSubject("setSubject", evaluator, fp)); + esMailPrototype.putHiddenProperty("setReplyTo", + new MailSetReplyTo("setReplyTo", evaluator, fp)); + esMailPrototype.putHiddenProperty("setFrom", + new MailSetFrom("setFrom", evaluator, fp)); - p = new MailAddTo ("addTo", evaluator, fp); + p = new MailAddTo("addTo", evaluator, fp); esMailPrototype.putHiddenProperty("addTo", p); esMailPrototype.putHiddenProperty("setTo", p); - p = new MailAddCC ("addCC", evaluator, fp); + p = new MailAddCC("addCC", evaluator, fp); esMailPrototype.putHiddenProperty("addCC", p); esMailPrototype.putHiddenProperty("setCC", p); - p = new MailAddBCC ("addBCC", evaluator, fp); + p = new MailAddBCC("addBCC", evaluator, fp); esMailPrototype.putHiddenProperty("addBCC", p); esMailPrototype.putHiddenProperty("setBCC", p); - esMailPrototype.putHiddenProperty("send", new MailSend ("send", evaluator, fp)); - + esMailPrototype.putHiddenProperty("send", new MailSend("send", evaluator, fp)); } - class GlobalObjectMail extends BuiltinFunctionObject { - MailExtension mailx; - GlobalObjectMail (String name, Evaluator evaluator, FunctionPrototype fp, MailExtension mailx) { + GlobalObjectMail(String name, Evaluator evaluator, FunctionPrototype fp, + MailExtension mailx) { super(fp, evaluator, name, 1); this.mailx = mailx; } - - public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - return doConstruct(thisObject, arguments); - } - - public ESObject doConstruct(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - ESMail mail = null; - if (arguments.length == 0) { - mail = new ESMail (mailx); - } else { - mail = new ESMail (mailx); - // should/could do something with extra arguments... - } - return mail; + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + return doConstruct(thisObject, arguments); + } + + public ESObject doConstruct(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESMail mail = null; + + if (arguments.length == 0) { + mail = new ESMail(mailx); + } else { + mail = new ESMail(mailx); + + // should/could do something with extra arguments... + } + + return mail; } } - - + class MailSetText extends BuiltinFunctionObject { - MailSetText (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + MailSetText(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { ESMail mail = (ESMail) thisObject; - if (arguments.length == 1) try { - mail.setText (arguments[0]); - } catch (Exception x) { - mail.setStatus (ESMail.TEXT); - return ESBoolean.makeBoolean(false); + + if (arguments.length == 1) { + try { + mail.setText(arguments[0]); + } catch (Exception x) { + mail.setStatus(ESMail.TEXT); + + return ESBoolean.makeBoolean(false); + } } + return ESBoolean.makeBoolean(true); } } class MailAddPart extends BuiltinFunctionObject { - MailAddPart (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + MailAddPart(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { ESMail mail = (ESMail) thisObject; + try { - mail.addPart (arguments); + mail.addPart(arguments); } catch (Exception x) { - mail.setStatus (ESMail.MIMEPART); - return ESBoolean.makeBoolean(false); - } - return ESBoolean.makeBoolean(true); - } - } - - class MailSetSubject extends BuiltinFunctionObject { - MailSetSubject (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); - } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - ESMail mail = (ESMail) thisObject; - if (arguments.length == 1) try { - mail.setSubject (arguments[0]); - } catch (Exception x) { - mail.setStatus (ESMail.SUBJECT); + mail.setStatus(ESMail.MIMEPART); + return ESBoolean.makeBoolean(false); } + return ESBoolean.makeBoolean(true); } } - - class MailSetReplyTo extends BuiltinFunctionObject { - MailSetReplyTo (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + + class MailSetSubject extends BuiltinFunctionObject { + MailSetSubject(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { ESMail mail = (ESMail) thisObject; - if (arguments.length == 1) try { - mail.setReplyTo (arguments[0]); - } catch (Exception x) { - mail.setStatus (ESMail.REPLYTO); - return ESBoolean.makeBoolean(false); + + if (arguments.length == 1) { + try { + mail.setSubject(arguments[0]); + } catch (Exception x) { + mail.setStatus(ESMail.SUBJECT); + + return ESBoolean.makeBoolean(false); + } } + + return ESBoolean.makeBoolean(true); + } + } + + class MailSetReplyTo extends BuiltinFunctionObject { + MailSetReplyTo(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); + } + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESMail mail = (ESMail) thisObject; + + if (arguments.length == 1) { + try { + mail.setReplyTo(arguments[0]); + } catch (Exception x) { + mail.setStatus(ESMail.REPLYTO); + + return ESBoolean.makeBoolean(false); + } + } + return ESBoolean.makeBoolean(true); } } class MailSetFrom extends BuiltinFunctionObject { - MailSetFrom (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); + MailSetFrom(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - ESMail mail = (ESMail) thisObject; - try { - mail.setFrom (arguments); - } catch (Exception x) { - mail.setStatus (ESMail.FROM); - return ESBoolean.makeBoolean(false); - } - return ESBoolean.makeBoolean(true); - } - } - class MailAddTo extends BuiltinFunctionObject { - MailAddTo (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); - } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { ESMail mail = (ESMail) thisObject; - try { - mail.addTo (arguments); - } catch (Exception x) { - mail.setStatus (ESMail.TO); - return ESBoolean.makeBoolean(false); - } - return ESBoolean.makeBoolean(true); - } - } - class MailAddCC extends BuiltinFunctionObject { - MailAddCC (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); - } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - ESMail mail = (ESMail) thisObject; try { - mail.addCC (arguments); + mail.setFrom(arguments); } catch (Exception x) { - mail.setStatus (ESMail.CC); - return ESBoolean.makeBoolean(false); - } - return ESBoolean.makeBoolean(true); - } - } - - class MailAddBCC extends BuiltinFunctionObject { - MailAddBCC (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); - } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - ESMail mail = (ESMail) thisObject; - try { - mail.addBCC (arguments); - } catch (Exception x) { - mail.setStatus (ESMail.BCC); - return ESBoolean.makeBoolean(false); - } - return ESBoolean.makeBoolean(true); - } - } + mail.setStatus(ESMail.FROM); - class MailSend extends BuiltinFunctionObject { - MailSend (String name, Evaluator evaluator, FunctionPrototype fp) { - super (fp, evaluator, name, 1); - } - public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - ESMail mail = (ESMail) thisObject; - try { - mail.send (); - } catch (Exception x) { - evaluator.engine.getApplication().logEvent ("Error sending mail: "+x); - mail.setStatus (ESMail.SEND); return ESBoolean.makeBoolean(false); } + return ESBoolean.makeBoolean(true); } } -} + class MailAddTo extends BuiltinFunctionObject { + MailAddTo(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); + } + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESMail mail = (ESMail) thisObject; + + try { + mail.addTo(arguments); + } catch (Exception x) { + mail.setStatus(ESMail.TO); + + return ESBoolean.makeBoolean(false); + } + + return ESBoolean.makeBoolean(true); + } + } + + class MailAddCC extends BuiltinFunctionObject { + MailAddCC(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); + } + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESMail mail = (ESMail) thisObject; + + try { + mail.addCC(arguments); + } catch (Exception x) { + mail.setStatus(ESMail.CC); + + return ESBoolean.makeBoolean(false); + } + + return ESBoolean.makeBoolean(true); + } + } + + class MailAddBCC extends BuiltinFunctionObject { + MailAddBCC(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); + } + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESMail mail = (ESMail) thisObject; + + try { + mail.addBCC(arguments); + } catch (Exception x) { + mail.setStatus(ESMail.BCC); + + return ESBoolean.makeBoolean(false); + } + + return ESBoolean.makeBoolean(true); + } + } + + class MailSend extends BuiltinFunctionObject { + MailSend(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); + } + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESMail mail = (ESMail) thisObject; + + try { + mail.send(); + } catch (Exception x) { + evaluator.engine.getApplication().logEvent("Error sending mail: " + x); + mail.setStatus(ESMail.SEND); + + return ESBoolean.makeBoolean(false); + } + + return ESBoolean.makeBoolean(true); + } + } +} diff --git a/src/helma/scripting/fesi/extensions/XmlRpcExtension.java b/src/helma/scripting/fesi/extensions/XmlRpcExtension.java index 40cd0887..dbc9bfe5 100644 --- a/src/helma/scripting/fesi/extensions/XmlRpcExtension.java +++ b/src/helma/scripting/fesi/extensions/XmlRpcExtension.java @@ -1,140 +1,182 @@ -// XmlRpcExtension.java -// Copyright (c) Hannes Wallnöfer, 1999 - All rights reserved +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.scripting.fesi.extensions; -import org.apache.xmlrpc.*; - -import helma.scripting.fesi.FesiEngine; - -import FESI.Interpreter.*; +import FESI.Data.*; import FESI.Exceptions.*; import FESI.Extensions.*; -import FESI.Data.*; - +import FESI.Interpreter.*; +import helma.scripting.fesi.FesiEngine; +import org.apache.xmlrpc.*; import java.io.*; -import java.util.*; import java.net.*; +import java.util.*; - -/** - * An extension to transparently call and serve XML-RPC from the - * <a href=http://home.worldcom.ch/jmlugrin/fesi/>FESI EcmaScript</a> interpreter. - * The extension adds constructors for XML-RPC clients and servers to the Global Object. - * For more information on how to use this please look at the files <tt>server.es</tt> and +/** + * An extension to transparently call and serve XML-RPC from the + * <a href=http://home.worldcom.ch/jmlugrin/fesi/>FESI EcmaScript</a> interpreter. + * The extension adds constructors for XML-RPC clients and servers to the Global Object. + * For more information on how to use this please look at the files <tt>server.es</tt> and * <tt>client.es</tt> in the src/fesi directory of the distribution. - * - * All argument conversion is done automatically. Currently the following argument and return + * + * All argument conversion is done automatically. Currently the following argument and return * types are supported: * <ul> * <li> plain objects (with all properties returned by ESObject.getProperties ()) - * <li> arrays + * <li> arrays * <li> strings * <li> date objects * <li> booleans * <li> integer and float numbers (long values are not supported!) * </ul> - * + * */ public class XmlRpcExtension extends Extension { - Evaluator evaluator; ESObject op; - public void initializeExtension (Evaluator evaluator) throws EcmaScriptException { + /** + * + * + * @param evaluator ... + * + * @throws EcmaScriptException ... + */ + public void initializeExtension(Evaluator evaluator) + throws EcmaScriptException { // XmlRpc.setDebug (true); this.evaluator = evaluator; + GlobalObject go = evaluator.getGlobalObject(); FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype(); op = evaluator.getObjectPrototype(); - go.putHiddenProperty ("Remote", new GlobalObjectRemote ("Remote", evaluator, fp)); // the Remote constructor + go.putHiddenProperty("Remote", new GlobalObjectRemote("Remote", evaluator, fp)); // the Remote constructor } - class GlobalObjectRemote extends BuiltinFunctionObject { - - GlobalObjectRemote (String name, Evaluator evaluator, FunctionPrototype fp) { + GlobalObjectRemote(String name, Evaluator evaluator, FunctionPrototype fp) { super(fp, evaluator, name, 1); } - - public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - return doConstruct(thisObject, arguments); + + public ESValue callFunction(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + return doConstruct(thisObject, arguments); } - - public ESObject doConstruct(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { - ESObject remote = null; - String url = null; - String robj = null; - if (arguments.length >= 1) - url = arguments[0].toString (); - if (arguments.length >= 2) - robj = arguments[1].toString (); - try { - remote = new ESRemote (op, this.evaluator, url, robj); - } catch (MalformedURLException x) { - throw new EcmaScriptException (x.toString ()); - } - return remote; + + public ESObject doConstruct(ESObject thisObject, ESValue[] arguments) + throws EcmaScriptException { + ESObject remote = null; + String url = null; + String robj = null; + + if (arguments.length >= 1) { + url = arguments[0].toString(); + } + + if (arguments.length >= 2) { + robj = arguments[1].toString(); + } + + try { + remote = new ESRemote(op, this.evaluator, url, robj); + } catch (MalformedURLException x) { + throw new EcmaScriptException(x.toString()); + } + + return remote; } } - class ESRemote extends ObjectPrototype { - URL url; String remoteObject; - - public ESRemote (ESObject prototype, Evaluator evaluator, String urlstring, String robj) throws MalformedURLException { - super (prototype, evaluator); - this.url = new URL (urlstring); + + public ESRemote(ESObject prototype, Evaluator evaluator, String urlstring, + String robj) throws MalformedURLException { + super(prototype, evaluator); + this.url = new URL(urlstring); remoteObject = robj; } - public ESRemote (ESObject prototype, Evaluator evaluator, URL url, String robj) { - super (prototype, evaluator); + public ESRemote(ESObject prototype, Evaluator evaluator, URL url, String robj) { + super(prototype, evaluator); this.url = url; remoteObject = robj; } - - public ESValue doIndirectCall(Evaluator evaluator, ESObject target, String functionName, ESValue arguments[]) - throws EcmaScriptException, NoSuchMethodException { + + public ESValue doIndirectCall(Evaluator evaluator, ESObject target, + String functionName, ESValue[] arguments) + throws EcmaScriptException, NoSuchMethodException { // System.out.println ("doIndirectCall called with "+remoteObject+"."+functionName); - XmlRpcClient client = new XmlRpcClient (url); + XmlRpcClient client = new XmlRpcClient(url); + // long now = System.currentTimeMillis (); Object retval = null; int l = arguments.length; - Vector v = new Vector (); - for (int i=0; i<l; i++) { - Object arg = FesiEngine.processXmlRpcResponse (arguments[i]); + Vector v = new Vector(); + + for (int i = 0; i < l; i++) { + Object arg = FesiEngine.processXmlRpcResponse(arguments[i]); + // System.out.println ("converted to J: "+arg.getClass ()); - v.addElement (arg); + v.addElement(arg); } + // System.out.println ("spent "+(System.currentTimeMillis ()-now)+" millis in argument conversion"); - ESObject esretval = ObjectObject.createObject (evaluator); + ESObject esretval = ObjectObject.createObject(evaluator); + try { - String method = remoteObject == null ? functionName : remoteObject+"."+functionName; - retval = client.execute (method, v); - esretval.putProperty ("error", ESNull.theNull, "error".hashCode()); - esretval.putProperty ("result", FesiEngine.processXmlRpcArgument (retval, evaluator), "result".hashCode()); + String method = (remoteObject == null) ? functionName + : (remoteObject + "." + + functionName); + + retval = client.execute(method, v); + esretval.putProperty("error", ESNull.theNull, "error".hashCode()); + esretval.putProperty("result", + FesiEngine.processXmlRpcArgument(retval, evaluator), + "result".hashCode()); } catch (Exception x) { String msg = x.getMessage(); - if (msg == null || msg.length() == 0) - msg = x.toString (); - esretval.putProperty ("error", new ESString(msg), "error".hashCode()); - esretval.putProperty ("result", ESNull.theNull, "result".hashCode()); + + if ((msg == null) || (msg.length() == 0)) { + msg = x.toString(); + } + + esretval.putProperty("error", new ESString(msg), "error".hashCode()); + esretval.putProperty("result", ESNull.theNull, "result".hashCode()); } + return esretval; } - - public ESValue getProperty (String name, int hash) throws EcmaScriptException { - ESValue sprop = super.getProperty (name, hash); - if (sprop != ESUndefined.theUndefined && sprop != ESNull.theNull) - return sprop; - String newRemoteObject = remoteObject == null ? name : remoteObject+"."+name; - return new ESRemote (op, this.evaluator, url, newRemoteObject); + + public ESValue getProperty(String name, int hash) + throws EcmaScriptException { + ESValue sprop = super.getProperty(name, hash); + + if ((sprop != ESUndefined.theUndefined) && (sprop != ESNull.theNull)) { + return sprop; + } + + String newRemoteObject = (remoteObject == null) ? name + : (remoteObject + "." + name); + + return new ESRemote(op, this.evaluator, url, newRemoteObject); } } - } diff --git a/src/helma/servlet/AbstractServletClient.java b/src/helma/servlet/AbstractServletClient.java index 8d14aeb6..cc6cc2bf 100644 --- a/src/helma/servlet/AbstractServletClient.java +++ b/src/helma/servlet/AbstractServletClient.java @@ -1,349 +1,451 @@ -// ServletClient.java -// Copyright (c) Hannes Wallnöfer, Raphael Spannocchi 1998-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ /* Portierung von helma.asp.AspClient auf Servlets */ /* Author: Raphael Spannocchi Datum: 27.11.1998 */ - package helma.servlet; -import javax.servlet.*; -import javax.servlet.http.*; -import java.io.*; -import java.util.*; -import java.net.URLDecoder; import helma.framework.*; import helma.util.*; +import java.io.*; +import java.net.URLDecoder; +import java.util.*; +import javax.servlet.*; +import javax.servlet.http.*; /** * This is an abstract Hop servlet adapter. This class communicates with hop applications * via RMI. Subclasses are either one servlet per app, or one servlet that handles multiple apps */ - public abstract class AbstractServletClient extends HttpServlet { + static final byte HTTP_GET = 0; + static final byte HTTP_POST = 1; // host on which Helma app is running String host = null; + // port of Helma RMI server int port = 0; + // RMI url of Helma app String hopUrl; // limit to HTTP uploads in kB int uploadLimit = 1024; + // cookie domain to use String cookieDomain; + // default encoding for requests - String defaultEncoding; + String defaultEncoding; + // allow caching of responses boolean caching; + // enable debug output boolean debug; - static final byte HTTP_GET = 0; - static final byte HTTP_POST = 1; + /** + * + * + * @param init ... + * + * @throws ServletException ... + */ + public void init(ServletConfig init) throws ServletException { + super.init(init); - public void init (ServletConfig init) throws ServletException { - super.init (init); - // get max size for file uploads - String upstr = init.getInitParameter ("uploadLimit"); - uploadLimit = upstr == null ? 1024 : Integer.parseInt (upstr); - // get cookie domain - cookieDomain = init.getInitParameter ("cookieDomain"); - if (cookieDomain != null) - cookieDomain = cookieDomain.toLowerCase(); - // get default encoding - defaultEncoding = init.getInitParameter ("charset"); - debug = ("true".equalsIgnoreCase (init.getInitParameter ("debug"))); - caching = ! ("false".equalsIgnoreCase (init.getInitParameter ("caching"))); + // get max size for file uploads + String upstr = init.getInitParameter("uploadLimit"); + + uploadLimit = (upstr == null) ? 1024 : Integer.parseInt(upstr); + + // get cookie domain + cookieDomain = init.getInitParameter("cookieDomain"); + + if (cookieDomain != null) { + cookieDomain = cookieDomain.toLowerCase(); + } + + // get default encoding + defaultEncoding = init.getInitParameter("charset"); + debug = ("true".equalsIgnoreCase(init.getInitParameter("debug"))); + caching = !("false".equalsIgnoreCase(init.getInitParameter("caching"))); } + abstract ResponseTrans execute(RequestTrans req) throws Exception; - abstract ResponseTrans execute (RequestTrans req) throws Exception; - - - public void doGet (HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - execute (request, response, HTTP_GET); - } - - public void doPost (HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - execute (request, response, HTTP_POST); + /** + * + * + * @param request ... + * @param response ... + * + * @throws ServletException ... + * @throws IOException ... + */ + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + execute(request, response, HTTP_GET); } - - protected void execute (HttpServletRequest request, - HttpServletResponse response, - byte method) { - - RequestTrans reqtrans = new RequestTrans (method); - // get app and path from original request path - // String pathInfo = request.getPathInfo (); - // String appID = getAppID (pathInfo); - // reqtrans.path = getRequestPath (pathInfo); - - try { - - // read and set http parameters - Map parameters = parseParameters (request); - for (Iterator i=parameters.entrySet().iterator(); i.hasNext(); ) { - Map.Entry entry = (Map.Entry) i.next (); - String key = (String) entry.getKey (); - String[] values = (String[]) entry.getValue (); - if (values != null && values.length > 0) { - reqtrans.set (key, values[0]); // set to single string value - if (values.length > 1) - reqtrans.set (key+"_array", values); // set string array - } - } - - // check for MIME file uploads - String contentType = request.getContentType(); - if (contentType != null && contentType.indexOf("multipart/form-data")==0) { - // File Upload - try { - FileUpload upload = getUpload (request); - if (upload != null) { - Hashtable parts = upload.getParts (); - for (Enumeration e = parts.keys(); e.hasMoreElements(); ) { - String nextKey = (String) e.nextElement (); - Object nextPart = parts.get (nextKey); - reqtrans.set (nextKey, nextPart); - } - } - } catch (Exception upx) { - sendError ( - response, - response.SC_REQUEST_ENTITY_TOO_LARGE, - "Sorry, upload size exceeds limit of "+uploadLimit+"kB."); - return; - } - } - - // read cookies - Cookie[] reqCookies = request.getCookies(); - if (reqCookies != null) { - for (int i=0; i < reqCookies.length;i++) try { - // get Cookies - String nextKey = reqCookies[i].getName (); - String nextPart = reqCookies[i].getValue (); - if ("HopSession".equals (nextKey)) - reqtrans.session = nextPart; - else - reqtrans.set (nextKey, nextPart); - } catch (Exception badCookie) {} - } - - // do standard HTTP variables - String host = request.getHeader ("Host"); - if (host != null) { - host = host.toLowerCase(); - reqtrans.set ("http_host", host); - } - - String referer = request.getHeader ("Referer"); - if (referer != null) - reqtrans.set ("http_referer", referer); - - try { - long ifModifiedSince = request.getDateHeader ("If-Modified-Since"); - if (ifModifiedSince > -1) - reqtrans.setIfModifiedSince (ifModifiedSince); - } catch (IllegalArgumentException ignore) {} - - String ifNoneMatch = request.getHeader ("If-None-Match"); - if (ifNoneMatch != null) - reqtrans.setETags (ifNoneMatch); - - String remotehost = request.getRemoteAddr (); - if (remotehost != null) - reqtrans.set ("http_remotehost", remotehost); - - // get the cookie domain to use for this response, if any. - String resCookieDomain = cookieDomain; - if (resCookieDomain != null) { - // check if cookieDomain is valid for this response. - // (note: cookieDomain is guaranteed to be lower case) - if (host != null && host.toLowerCase().indexOf (cookieDomain) == -1) - resCookieDomain = null; - } - // check if we need to create a session id. also handle the - // case that the session id doesn't match the remote host address - if (reqtrans.session == null || !reqtrans.session.startsWith (remotehost)) { - reqtrans.session = remotehost+"."+Long.toString ( - Math.round (Math.random ()* Long.MAX_VALUE) - - System.currentTimeMillis (), 36); - Cookie c = new Cookie("HopSession", reqtrans.session); - c.setPath ("/"); - if (resCookieDomain != null) - c.setDomain (resCookieDomain); - response.addCookie(c); - } - - String browser = request.getHeader ("User-Agent"); - if (browser != null) - reqtrans.set ("http_browser", browser); - - String authorization = request.getHeader("authorization"); - if ( authorization != null ) - reqtrans.set ("authorization", authorization ); - - // response.setHeader ("Server", "Helma/"+helma.main.Server.version); - - reqtrans.path = getPathInfo (request); - ResponseTrans restrans = execute (reqtrans); - - // set cookies - int ncookies = restrans.countCookies(); - if (restrans.countCookies() > 0) { - CookieTrans[] resCookies = restrans.getCookies (); - for (int i = 0; i < resCookies.length; i++) try { - Cookie c = resCookies[i].getCookie ("/", resCookieDomain); - response.addCookie(c); - } catch (Exception ignore) {} - } - // write response - writeResponse (request, response, restrans); - - } catch (Exception x) { - try { - if (debug) - sendError ( - response, - response.SC_INTERNAL_SERVER_ERROR, - "Error in request handler:" +x); - else - sendError ( - response, - response.SC_INTERNAL_SERVER_ERROR, - "The server encountered an error while processing your request. "+ - "Please check back later."); - log ("Exception in execute: "+x); - } catch (IOException io_e) { - log ("Exception in sendError: "+io_e); - } - } + /** + * + * + * @param request ... + * @param response ... + * + * @throws ServletException ... + * @throws IOException ... + */ + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + execute(request, response, HTTP_POST); } + protected void execute(HttpServletRequest request, HttpServletResponse response, + byte method) { + RequestTrans reqtrans = new RequestTrans(method); - void writeResponse (HttpServletRequest req, - HttpServletResponse res, - ResponseTrans hopres) { + // get app and path from original request path + // String pathInfo = request.getPathInfo (); + // String appID = getAppID (pathInfo); + // reqtrans.path = getRequestPath (pathInfo); + try { + // read and set http parameters + Map parameters = parseParameters(request); - if (hopres.getETag() != null) { - res.setHeader ("ETag", hopres.getETag()); - } - if (hopres.getRedirect () != null) { - sendRedirect(req, res, hopres.getRedirect ()); - } else if (hopres.getNotModified ()) { - res.setStatus (HttpServletResponse.SC_NOT_MODIFIED); - } else { + for (Iterator i = parameters.entrySet().iterator(); i.hasNext();) { + Map.Entry entry = (Map.Entry) i.next(); + String key = (String) entry.getKey(); + String[] values = (String[]) entry.getValue(); - if (!hopres.cache || ! caching) { - // Disable caching of response. - // for HTTP 1.0 - res.setDateHeader ("Expires", System.currentTimeMillis ()-10000); - res.setHeader ("Pragma", "no-cache"); - // for HTTP 1.1 - res.setHeader ("Cache-Control", "no-cache, no-store, must-revalidate, max-age=0"); - } - if ( hopres.realm!=null ) - res.setHeader( "WWW-Authenticate", "Basic realm=\"" + hopres.realm + "\"" ); - if (hopres.status > 0) - res.setStatus (hopres.status); - // set last-modified header to now - long modified = hopres.getLastModified (); - if (modified > -1) - res.setDateHeader ("Last-Modified", System.currentTimeMillis ()); - // if we don't know which charset to use for parsing HTTP params, - // take the one from the response. This usually works because - // browsers send parrameters in the same encoding as the page - // containing the form has. Problem is we can do this only per servlet, - // not per session or even per page, which would produce too much overhead - if (defaultEncoding == null) - defaultEncoding = hopres.charset; - res.setContentLength (hopres.getContentLength ()); - res.setContentType (hopres.getContentType ()); - try { - OutputStream out = res.getOutputStream (); - out.write (hopres.getContent ()); - out.flush (); - } catch(Exception io_e) { - log ("Exception in writeResponse: "+io_e); - } - } + if ((values != null) && (values.length > 0)) { + reqtrans.set(key, values[0]); // set to single string value + + if (values.length > 1) { + reqtrans.set(key + "_array", values); // set string array + } + } + } + + // check for MIME file uploads + String contentType = request.getContentType(); + + if ((contentType != null) && + (contentType.indexOf("multipart/form-data") == 0)) { + // File Upload + try { + FileUpload upload = getUpload(request); + + if (upload != null) { + Hashtable parts = upload.getParts(); + + for (Enumeration e = parts.keys(); e.hasMoreElements();) { + String nextKey = (String) e.nextElement(); + Object nextPart = parts.get(nextKey); + + reqtrans.set(nextKey, nextPart); + } + } + } catch (Exception upx) { + sendError(response, response.SC_REQUEST_ENTITY_TOO_LARGE, + "Sorry, upload size exceeds limit of " + uploadLimit + + "kB."); + + return; + } + } + + // read cookies + Cookie[] reqCookies = request.getCookies(); + + if (reqCookies != null) { + for (int i = 0; i < reqCookies.length; i++) + try { + // get Cookies + String nextKey = reqCookies[i].getName(); + String nextPart = reqCookies[i].getValue(); + + if ("HopSession".equals(nextKey)) { + reqtrans.session = nextPart; + } else { + reqtrans.set(nextKey, nextPart); + } + } catch (Exception badCookie) { + } + } + + // do standard HTTP variables + String host = request.getHeader("Host"); + + if (host != null) { + host = host.toLowerCase(); + reqtrans.set("http_host", host); + } + + String referer = request.getHeader("Referer"); + + if (referer != null) { + reqtrans.set("http_referer", referer); + } + + try { + long ifModifiedSince = request.getDateHeader("If-Modified-Since"); + + if (ifModifiedSince > -1) { + reqtrans.setIfModifiedSince(ifModifiedSince); + } + } catch (IllegalArgumentException ignore) { + } + + String ifNoneMatch = request.getHeader("If-None-Match"); + + if (ifNoneMatch != null) { + reqtrans.setETags(ifNoneMatch); + } + + String remotehost = request.getRemoteAddr(); + + if (remotehost != null) { + reqtrans.set("http_remotehost", remotehost); + } + + // get the cookie domain to use for this response, if any. + String resCookieDomain = cookieDomain; + + if (resCookieDomain != null) { + // check if cookieDomain is valid for this response. + // (note: cookieDomain is guaranteed to be lower case) + if ((host != null) && (host.toLowerCase().indexOf(cookieDomain) == -1)) { + resCookieDomain = null; + } + } + + // check if we need to create a session id. also handle the + // case that the session id doesn't match the remote host address + if ((reqtrans.session == null) || !reqtrans.session.startsWith(remotehost)) { + reqtrans.session = remotehost + "." + + Long.toString(Math.round(Math.random() * Long.MAX_VALUE) - + System.currentTimeMillis(), 36); + + Cookie c = new Cookie("HopSession", reqtrans.session); + + c.setPath("/"); + + if (resCookieDomain != null) { + c.setDomain(resCookieDomain); + } + + response.addCookie(c); + } + + String browser = request.getHeader("User-Agent"); + + if (browser != null) { + reqtrans.set("http_browser", browser); + } + + String authorization = request.getHeader("authorization"); + + if (authorization != null) { + reqtrans.set("authorization", authorization); + } + + // response.setHeader ("Server", "Helma/"+helma.main.Server.version); + reqtrans.path = getPathInfo(request); + + ResponseTrans restrans = execute(reqtrans); + + // set cookies + int ncookies = restrans.countCookies(); + + if (restrans.countCookies() > 0) { + CookieTrans[] resCookies = restrans.getCookies(); + + for (int i = 0; i < resCookies.length; i++) + try { + Cookie c = resCookies[i].getCookie("/", resCookieDomain); + + response.addCookie(c); + } catch (Exception ignore) { + } + } + + // write response + writeResponse(request, response, restrans); + } catch (Exception x) { + try { + if (debug) { + sendError(response, response.SC_INTERNAL_SERVER_ERROR, + "Error in request handler:" + x); + } else { + sendError(response, response.SC_INTERNAL_SERVER_ERROR, + "The server encountered an error while processing your request. " + + "Please check back later."); + } + + log("Exception in execute: " + x); + } catch (IOException io_e) { + log("Exception in sendError: " + io_e); + } + } } + void writeResponse(HttpServletRequest req, HttpServletResponse res, + ResponseTrans hopres) { + if (hopres.getETag() != null) { + res.setHeader("ETag", hopres.getETag()); + } - void sendError (HttpServletResponse response, int code, String message) - throws IOException { - response.reset (); - response.setStatus (code); - response.setContentType ("text/html"); - Writer writer = response.getWriter (); - writer.write (message); - writer.flush (); + if (hopres.getRedirect() != null) { + sendRedirect(req, res, hopres.getRedirect()); + } else if (hopres.getNotModified()) { + res.setStatus(HttpServletResponse.SC_NOT_MODIFIED); + } else { + if (!hopres.cache || !caching) { + // Disable caching of response. + // for HTTP 1.0 + res.setDateHeader("Expires", System.currentTimeMillis() - 10000); + res.setHeader("Pragma", "no-cache"); + + // for HTTP 1.1 + res.setHeader("Cache-Control", + "no-cache, no-store, must-revalidate, max-age=0"); + } + + if (hopres.realm != null) { + res.setHeader("WWW-Authenticate", "Basic realm=\"" + hopres.realm + "\""); + } + + if (hopres.status > 0) { + res.setStatus(hopres.status); + } + + // set last-modified header to now + long modified = hopres.getLastModified(); + + if (modified > -1) { + res.setDateHeader("Last-Modified", System.currentTimeMillis()); + } + + // if we don't know which charset to use for parsing HTTP params, + // take the one from the response. This usually works because + // browsers send parrameters in the same encoding as the page + // containing the form has. Problem is we can do this only per servlet, + // not per session or even per page, which would produce too much overhead + if (defaultEncoding == null) { + defaultEncoding = hopres.charset; + } + + res.setContentLength(hopres.getContentLength()); + res.setContentType(hopres.getContentType()); + + try { + OutputStream out = res.getOutputStream(); + + out.write(hopres.getContent()); + out.flush(); + } catch (Exception io_e) { + log("Exception in writeResponse: " + io_e); + } + } } - void sendRedirect (HttpServletRequest req, HttpServletResponse res, String url) { - String location = url; - if (url.indexOf ("://") == -1) - { - // need to transform a relative URL into an absolute one - String scheme = req.getScheme (); - StringBuffer loc = new StringBuffer(scheme); - loc.append ("://"); - loc.append (req.getServerName ()); - int p = req.getServerPort (); - // check if we need to include server port - if (p > 0 && - (("http".equals(scheme) && p != 80) || - ("https".equals(scheme) && p != 443))) - { - loc.append (":"); - loc.append (p); - } - if (!url.startsWith ("/")) - { - String requri = req.getRequestURI (); - int lastSlash = requri.lastIndexOf ("/"); - if (lastSlash == requri.length()-1) - loc.append (requri); - else if (lastSlash > -1) - loc.append (requri.substring (0, lastSlash+1)); - else - loc.append ("/"); - } - loc.append (url); - location = loc.toString (); - } - // send status code 303 for HTTP 1.1, 302 otherwise - if (isOneDotOne (req.getProtocol ())) - res.setStatus (res.SC_SEE_OTHER); - else - res.setStatus (res.SC_MOVED_TEMPORARILY); - res.setContentType ("text/html"); - res.setHeader ("Location", location); + void sendError(HttpServletResponse response, int code, String message) + throws IOException { + response.reset(); + response.setStatus(code); + response.setContentType("text/html"); + + Writer writer = response.getWriter(); + + writer.write(message); + writer.flush(); } - FileUpload getUpload (HttpServletRequest request) throws Exception { - int contentLength = request.getContentLength (); - BufferedInputStream in = new BufferedInputStream (request.getInputStream ()); - if (contentLength > uploadLimit*1024) { - throw new RuntimeException ("Upload exceeds limit of "+uploadLimit+" kb."); - } - String contentType = request.getContentType (); - FileUpload upload = new FileUpload(uploadLimit); - upload.load (in, contentType, contentLength); - return upload; + void sendRedirect(HttpServletRequest req, HttpServletResponse res, String url) { + String location = url; + + if (url.indexOf("://") == -1) { + // need to transform a relative URL into an absolute one + String scheme = req.getScheme(); + StringBuffer loc = new StringBuffer(scheme); + + loc.append("://"); + loc.append(req.getServerName()); + + int p = req.getServerPort(); + + // check if we need to include server port + if ((p > 0) && + (("http".equals(scheme) && (p != 80)) || + ("https".equals(scheme) && (p != 443)))) { + loc.append(":"); + loc.append(p); + } + + if (!url.startsWith("/")) { + String requri = req.getRequestURI(); + int lastSlash = requri.lastIndexOf("/"); + + if (lastSlash == (requri.length() - 1)) { + loc.append(requri); + } else if (lastSlash > -1) { + loc.append(requri.substring(0, lastSlash + 1)); + } else { + loc.append("/"); + } + } + + loc.append(url); + location = loc.toString(); + } + + // send status code 303 for HTTP 1.1, 302 otherwise + if (isOneDotOne(req.getProtocol())) { + res.setStatus(res.SC_SEE_OTHER); + } else { + res.setStatus(res.SC_MOVED_TEMPORARILY); + } + + res.setContentType("text/html"); + res.setHeader("Location", location); } + FileUpload getUpload(HttpServletRequest request) throws Exception { + int contentLength = request.getContentLength(); + BufferedInputStream in = new BufferedInputStream(request.getInputStream()); + + if (contentLength > (uploadLimit * 1024)) { + throw new RuntimeException("Upload exceeds limit of " + uploadLimit + " kb."); + } + + String contentType = request.getContentType(); + FileUpload upload = new FileUpload(uploadLimit); + + upload.load(in, contentType, contentLength); + + return upload; + } Object getUploadPart(FileUpload upload, String name) { - return upload.getParts().get(name); + return upload.getParts().get(name); } - /** * Put name value pair in map. * @@ -352,9 +454,10 @@ public abstract class AbstractServletClient extends HttpServlet { * Put name and value pair in map. When name already exist, add value * to array of values. */ - private static void putMapEntry( Map map, String name, String value) { + private static void putMapEntry(Map map, String name, String value) { String[] newValues = null; String[] oldValues = (String[]) map.get(name); + if (oldValues == null) { newValues = new String[1]; newValues[0] = value; @@ -363,42 +466,49 @@ public abstract class AbstractServletClient extends HttpServlet { System.arraycopy(oldValues, 0, newValues, 0, oldValues.length); newValues[oldValues.length] = value; } + map.put(name, newValues); } + protected Map parseParameters(HttpServletRequest request) { + String encoding = request.getCharacterEncoding(); - - protected Map parseParameters (HttpServletRequest request) { - - String encoding = request.getCharacterEncoding (); - if (encoding == null) + if (encoding == null) { // no encoding from request, use standard one encoding = defaultEncoding; - if (encoding == null) - encoding = "ISO-8859-1"; + } + + if (encoding == null) { + encoding = "ISO-8859-1"; + } + + HashMap parameters = new HashMap(); - HashMap parameters = new HashMap (); // Parse any query string parameters from the request try { - parseParameters (parameters, request.getQueryString().getBytes(), encoding); + parseParameters(parameters, request.getQueryString().getBytes(), encoding); } catch (Exception e) { } // Parse any posted parameters in the input stream if ("POST".equals(request.getMethod()) && - "application/x-www-form-urlencoded".equals(request.getContentType())) { + "application/x-www-form-urlencoded".equals(request.getContentType())) { try { int max = request.getContentLength(); int len = 0; - byte buf[] = new byte[max]; + byte[] buf = new byte[max]; ServletInputStream is = request.getInputStream(); + while (len < max) { int next = is.read(buf, len, max - len); - if (next < 0 ) { + + if (next < 0) { break; } + len += next; } + // is.close(); parseParameters(parameters, buf, encoding); } catch (IllegalArgumentException e) { @@ -406,7 +516,7 @@ public abstract class AbstractServletClient extends HttpServlet { } } - return parameters; + return parameters; } /** @@ -428,41 +538,53 @@ public abstract class AbstractServletClient extends HttpServlet { * * @exception UnsupportedEncodingException if the data is malformed */ - public static void parseParameters (Map map, byte[] data, String encoding) - throws UnsupportedEncodingException { - - if (data != null && data.length > 0) { - int pos = 0; - int ix = 0; - int ox = 0; + public static void parseParameters(Map map, byte[] data, String encoding) + throws UnsupportedEncodingException { + if ((data != null) && (data.length > 0)) { + int pos = 0; + int ix = 0; + int ox = 0; String key = null; String value = null; + while (ix < data.length) { byte c = data[ix++]; + switch ((char) c) { - case '&': - value = new String(data, 0, ox, encoding); - if (key != null) { - putMapEntry(map, key, value); - key = null; - } - ox = 0; - break; - case '=': - key = new String(data, 0, ox, encoding); - ox = 0; - break; - case '+': - data[ox++] = (byte)' '; - break; - case '%': - data[ox++] = (byte)((convertHexDigit(data[ix++]) << 4) - + convertHexDigit(data[ix++])); - break; - default: - data[ox++] = c; + case '&': + value = new String(data, 0, ox, encoding); + + if (key != null) { + putMapEntry(map, key, value); + key = null; + } + + ox = 0; + + break; + + case '=': + key = new String(data, 0, ox, encoding); + ox = 0; + + break; + + case '+': + data[ox++] = (byte) ' '; + + break; + + case '%': + data[ox++] = (byte) ((convertHexDigit(data[ix++]) << 4) + + convertHexDigit(data[ix++])); + + break; + + default: + data[ox++] = c; } } + //The last value does not end in '&'. So save it now. if (key != null) { value = new String(data, 0, ox, encoding); @@ -476,48 +598,73 @@ public abstract class AbstractServletClient extends HttpServlet { * * @param b the character value byte */ - private static byte convertHexDigit( byte b ) { - if ((b >= '0') && (b <= '9')) return (byte)(b - '0'); - if ((b >= 'a') && (b <= 'f')) return (byte)(b - 'a' + 10); - if ((b >= 'A') && (b <= 'F')) return (byte)(b - 'A' + 10); + private static byte convertHexDigit(byte b) { + if ((b >= '0') && (b <= '9')) { + return (byte) (b - '0'); + } + + if ((b >= 'a') && (b <= 'f')) { + return (byte) (b - 'a' + 10); + } + + if ((b >= 'A') && (b <= 'F')) { + return (byte) (b - 'A' + 10); + } + return 0; } - boolean isOneDotOne (String protocol) { - if (protocol == null) - return false; - if (protocol.endsWith ("1.1")) - return true; - return false; + boolean isOneDotOne(String protocol) { + if (protocol == null) { + return false; + } + + if (protocol.endsWith("1.1")) { + return true; + } + + return false; } - String getPathInfo (HttpServletRequest req) { - StringTokenizer t = new StringTokenizer (req.getContextPath(), "/"); - int prefixTokens = t.countTokens(); - t = new StringTokenizer (req.getServletPath(), "/"); - prefixTokens += t.countTokens(); - - t = new StringTokenizer (req.getRequestURI(), "/"); - int uriTokens = t.countTokens(); - StringBuffer pathbuffer = new StringBuffer (); - for (int i=0; i<uriTokens; i++) { - String token = t.nextToken (); - if (i < prefixTokens) - continue; - if (i > prefixTokens) - pathbuffer.append ("/"); - if (token.indexOf ("+") == -1 && token.indexOf ("%") == -1) - pathbuffer.append (token); - else - pathbuffer.append (URLDecoder.decode (token)); - } - return pathbuffer.toString (); + String getPathInfo(HttpServletRequest req) { + StringTokenizer t = new StringTokenizer(req.getContextPath(), "/"); + int prefixTokens = t.countTokens(); + + t = new StringTokenizer(req.getServletPath(), "/"); + prefixTokens += t.countTokens(); + + t = new StringTokenizer(req.getRequestURI(), "/"); + + int uriTokens = t.countTokens(); + StringBuffer pathbuffer = new StringBuffer(); + + for (int i = 0; i < uriTokens; i++) { + String token = t.nextToken(); + + if (i < prefixTokens) { + continue; + } + + if (i > prefixTokens) { + pathbuffer.append("/"); + } + + if ((token.indexOf("+") == -1) && (token.indexOf("%") == -1)) { + pathbuffer.append(token); + } else { + pathbuffer.append(URLDecoder.decode(token)); + } + } + + return pathbuffer.toString(); } - public String getServletInfo(){ - return new String("Helma Servlet Client"); + /** + * + * + * @return ... + */ + public String getServletInfo() { + return new String("Helma Servlet Client"); } - - } - diff --git a/src/helma/servlet/EmbeddedServletClient.java b/src/helma/servlet/EmbeddedServletClient.java index 6724278c..e2b621b1 100644 --- a/src/helma/servlet/EmbeddedServletClient.java +++ b/src/helma/servlet/EmbeddedServletClient.java @@ -1,51 +1,74 @@ -// EmbeddedServletClient.java -// Copyright (c) Hannes Wallnöfer, 2002 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.servlet; -import javax.servlet.*; -import java.io.*; -import java.util.*; import helma.framework.*; import helma.framework.core.Application; import helma.main.*; import helma.util.*; +import java.io.*; +import java.util.*; +import javax.servlet.*; /** * Servlet client that runs a Helma application for the embedded * web server */ - public final class EmbeddedServletClient extends AbstractServletClient { - private Application app = null; private String appName; // The path where this servlet is mounted String mountpoint; - public EmbeddedServletClient () { - super (); + /** + * Creates a new EmbeddedServletClient object. + */ + public EmbeddedServletClient() { + super(); } + /** + * + * + * @param init ... + * + * @throws ServletException ... + */ + public void init(ServletConfig init) throws ServletException { + super.init(init); + appName = init.getInitParameter("application"); - public void init (ServletConfig init) throws ServletException { - super.init (init); - appName = init.getInitParameter ("application"); - if (appName == null) - throw new ServletException ("Application name not set in init parameters"); - mountpoint = init.getInitParameter ("mountpoint"); - if (mountpoint == null) - mountpoint = "/"+appName; + if (appName == null) { + throw new ServletException("Application name not set in init parameters"); + } + + mountpoint = init.getInitParameter("mountpoint"); + + if (mountpoint == null) { + mountpoint = "/" + appName; + } } - ResponseTrans execute (RequestTrans req) throws Exception { - if (app == null) - app = Server.getServer().getApplication (appName); - return app.execute (req); - } + ResponseTrans execute(RequestTrans req) throws Exception { + if (app == null) { + app = Server.getServer().getApplication(appName); + } + return app.execute(req); + } } - - - diff --git a/src/helma/servlet/MultiServletClient.java b/src/helma/servlet/MultiServletClient.java index 4100f48c..29a98f0a 100644 --- a/src/helma/servlet/MultiServletClient.java +++ b/src/helma/servlet/MultiServletClient.java @@ -1,82 +1,111 @@ -// MultiServletClient.java -// Copyright (c) Hannes Wallnöfer 2001 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.servlet; -import javax.servlet.*; -import javax.servlet.http.*; +import helma.framework.*; import java.io.*; import java.rmi.Naming; import java.rmi.RemoteException; import java.util.Hashtable; -import helma.framework.*; +import javax.servlet.*; +import javax.servlet.http.*; /** * This is the HOP servlet adapter. This class communicates with any * Hop application on a given Hop server, extracting the application name * from the request path. */ - public class MultiServletClient extends AbstractServletClient { - private Hashtable apps; - public void init (ServletConfig init) throws ServletException { - super.init (init); - apps = new Hashtable (); - host = init.getInitParameter ("host"); - if (host == null) - host = "localhost"; - String portstr = init.getInitParameter ("port"); - port = portstr == null ? 5055 : Integer.parseInt (portstr); - hopUrl = "//" + host + ":" + port + "/"; + /** + * + * + * @param init ... + * + * @throws ServletException ... + */ + public void init(ServletConfig init) throws ServletException { + super.init(init); + apps = new Hashtable(); + host = init.getInitParameter("host"); + + if (host == null) { + host = "localhost"; + } + + String portstr = init.getInitParameter("port"); + + port = (portstr == null) ? 5055 : Integer.parseInt(portstr); + hopUrl = "//" + host + ":" + port + "/"; } - public void destroy () { - if (apps != null) { - apps.clear (); - apps = null; - } + /** + * + */ + public void destroy() { + if (apps != null) { + apps.clear(); + apps = null; + } } - ResponseTrans execute (RequestTrans req) throws Exception { - // the app-id is the first element in the request path - // so we have to first get than and than rewrite req.path. - int slash = req.path.indexOf ("/"); - String appId = null; - if (slash == -1) { - // no slash found, path equals app-id - appId = req.path; - req.path = ""; - } else { - // cut path into app id and rewritten path - appId = req.path.substring (0, slash); - req.path = req.path.substring (slash+1); - } - IRemoteApp app = getApp (appId); - try { - return app.execute (req); - } catch (Exception x) { - invalidateApp (appId); - app = getApp (appId); - return app.execute (req); - } + ResponseTrans execute(RequestTrans req) throws Exception { + // the app-id is the first element in the request path + // so we have to first get than and than rewrite req.path. + int slash = req.path.indexOf("/"); + String appId = null; + + if (slash == -1) { + // no slash found, path equals app-id + appId = req.path; + req.path = ""; + } else { + // cut path into app id and rewritten path + appId = req.path.substring(0, slash); + req.path = req.path.substring(slash + 1); + } + + IRemoteApp app = getApp(appId); + + try { + return app.execute(req); + } catch (Exception x) { + invalidateApp(appId); + app = getApp(appId); + + return app.execute(req); + } } - IRemoteApp getApp (String appId) throws Exception { - IRemoteApp app = (IRemoteApp) apps.get (appId); - if (app != null) - return app; - app = (IRemoteApp) Naming.lookup (hopUrl + appId); - apps.put (appId, app); - return app; + IRemoteApp getApp(String appId) throws Exception { + IRemoteApp app = (IRemoteApp) apps.get(appId); + + if (app != null) { + return app; + } + + app = (IRemoteApp) Naming.lookup(hopUrl + appId); + apps.put(appId, app); + + return app; } - void invalidateApp (String appId) { - apps.remove (appId); + void invalidateApp(String appId) { + apps.remove(appId); } - - } - diff --git a/src/helma/servlet/ServletClient.java b/src/helma/servlet/ServletClient.java index e8751f72..45bab3fd 100644 --- a/src/helma/servlet/ServletClient.java +++ b/src/helma/servlet/ServletClient.java @@ -1,62 +1,86 @@ -// ServletClient.java -// Copyright (c) Hannes Wallnöfer, Raphael Spannocchi 1998-2002 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.servlet; -import javax.servlet.*; +import helma.framework.*; import java.io.*; import java.rmi.Naming; import java.rmi.RemoteException; import java.util.*; -import helma.framework.*; +import javax.servlet.*; /** * This is the standard Helma servlet adapter. This class represents a servlet * that is dedicated to one Helma application over RMI. */ - public class ServletClient extends AbstractServletClient { - private IRemoteApp app = null; private String appName = null; - public void init (ServletConfig init) throws ServletException { - super.init (init); - appName = init.getInitParameter ("application"); - host = init.getInitParameter ("host"); - if (host == null) - host = "localhost"; - String portstr = init.getInitParameter ("port"); - port = portstr == null ? 5055 : Integer.parseInt (portstr); - hopUrl = "//" + host + ":" + port + "/"; - if (appName == null) - throw new ServletException ("Application name not specified for helma.servlet.ServletClient"); + /** + * + * + * @param init ... + * + * @throws ServletException ... + */ + public void init(ServletConfig init) throws ServletException { + super.init(init); + appName = init.getInitParameter("application"); + host = init.getInitParameter("host"); + + if (host == null) { + host = "localhost"; + } + + String portstr = init.getInitParameter("port"); + + port = (portstr == null) ? 5055 : Integer.parseInt(portstr); + hopUrl = "//" + host + ":" + port + "/"; + + if (appName == null) { + throw new ServletException("Application name not specified for helma.servlet.ServletClient"); + } } - public void destroy () { - if (app != null) { - app = null; - } + /** + * + */ + public void destroy() { + if (app != null) { + app = null; + } } + ResponseTrans execute(RequestTrans req) throws Exception { + if (app == null) { + initApp(); + } - ResponseTrans execute (RequestTrans req) throws Exception { - if (app == null) - initApp (); - try { - return app.execute (req); - } catch (Exception x) { - initApp (); - return app.execute (req); - } + try { + return app.execute(req); + } catch (Exception x) { + initApp(); + + return app.execute(req); + } } - synchronized void initApp () throws Exception { - app = (IRemoteApp) Naming.lookup (hopUrl + appName); + synchronized void initApp() throws Exception { + app = (IRemoteApp) Naming.lookup(hopUrl + appName); } - - } - - diff --git a/src/helma/servlet/StandaloneServletClient.java b/src/helma/servlet/StandaloneServletClient.java index 4ae5a8ca..53b1c869 100644 --- a/src/helma/servlet/StandaloneServletClient.java +++ b/src/helma/servlet/StandaloneServletClient.java @@ -1,14 +1,27 @@ -// StandaloneServletClient.java -// Copyright (c) Hannes Wallnöfer, 2001 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.servlet; -import javax.servlet.*; -import java.io.*; -import java.util.*; import helma.framework.*; import helma.framework.core.Application; import helma.util.*; +import java.io.*; +import java.util.*; +import javax.servlet.*; /** * Standalone servlet client that runs a Helma application all by itself @@ -22,75 +35,85 @@ import helma.util.*; * <li> dbdir - the path of the embedded XML data store </li> * </ul> */ - public final class StandaloneServletClient extends AbstractServletClient { - private Application app = null; private String appName; private String appDir; private String dbDir; + /** + * + * + * @param init ... + * + * @throws ServletException ... + */ + public void init(ServletConfig init) throws ServletException { + super.init(init); - public void init (ServletConfig init) throws ServletException { - super.init (init); - - appName = init.getInitParameter ("application"); - if (appName == null || appName.trim().length() == 0) - throw new ServletException ("application parameter not specified"); + appName = init.getInitParameter("application"); - appDir = init.getInitParameter ("appdir"); - if (appDir == null || appDir.trim().length() == 0) - throw new ServletException ("appdir parameter not specified"); + if ((appName == null) || (appName.trim().length() == 0)) { + throw new ServletException("application parameter not specified"); + } - dbDir = init.getInitParameter ("dbdir"); - if (dbDir == null || dbDir.trim().length() == 0) - throw new ServletException ("dbdir parameter not specified"); -} + appDir = init.getInitParameter("appdir"); - ResponseTrans execute (RequestTrans req) throws Exception { - if (app == null) - createApp (); - return app.execute (req); + if ((appDir == null) || (appDir.trim().length() == 0)) { + throw new ServletException("appdir parameter not specified"); + } + + dbDir = init.getInitParameter("dbdir"); + + if ((dbDir == null) || (dbDir.trim().length() == 0)) { + throw new ServletException("dbdir parameter not specified"); + } } + ResponseTrans execute(RequestTrans req) throws Exception { + if (app == null) { + createApp(); + } + + return app.execute(req); + } /** * Create the application. Since we are synchronized only here, we * do another check if the app already exists and immediately return if it does. */ - synchronized void createApp () { - if (app != null) - return; - try { - File appHome = new File (appDir); - File dbHome = new File (dbDir); - app = new Application (appName, appHome, dbHome); - app.init (); - app.start (); - } catch (Exception x) { - log ("Error starting Application "+appName+": "+x); - x.printStackTrace (); - } - } + synchronized void createApp() { + if (app != null) { + return; + } + try { + File appHome = new File(appDir); + File dbHome = new File(dbDir); + + app = new Application(appName, appHome, dbHome); + app.init(); + app.start(); + } catch (Exception x) { + log("Error starting Application " + appName + ": " + x); + x.printStackTrace(); + } + } /** * The servlet is being destroyed. Close and release the application if * it does exist. */ - public void destroy () { - if (app != null) { - try { - app.stop (); - } catch (Exception x) { - log ("Error shutting down app "+app.getName()+": "); - x.printStackTrace (); - } - } - app = null; + public void destroy() { + if (app != null) { + try { + app.stop(); + } catch (Exception x) { + log("Error shutting down app " + app.getName() + ": "); + x.printStackTrace(); + } + } + + app = null; } - } - - - diff --git a/src/helma/util/CronJob.java b/src/helma/util/CronJob.java index 05ce44ac..159fe2af 100644 --- a/src/helma/util/CronJob.java +++ b/src/helma/util/CronJob.java @@ -86,7 +86,7 @@ public class CronJob { private String name = null; private String function = null; - private long timeout = 30000; + private long timeout = 20000; /** A method for parsing properties. It looks through the properties * file for entries that look like this: @@ -161,7 +161,26 @@ public class CronJob { */ - public static Collection parse(Properties props) { + public static CronJob newJob (String functionName, String year, String month, String day, String weekday, String hour, String minute) { + CronJob job = new CronJob (functionName); + job.setFunction (functionName); + if (year != null) + parseYear (job, year); + if (month != null) + parseMonth (job, month); + if (day != null) + parseDay (job, day); + if (weekday != null) + parseWeekDay (job, weekday); + if (hour != null) + parseHour (job, hour); + if (minute != null) + parseMinute (job, minute); + return job; + } + + + public static Vector parse(Properties props) { Hashtable jobs = new Hashtable (); Enumeration e = props.keys (); while (e.hasMoreElements ()) { @@ -195,13 +214,40 @@ public class CronJob { parseHour (job, value); } else if (jobSpec.equalsIgnoreCase("minute")) { parseMinute (job, value); + } else if (jobSpec.equalsIgnoreCase("timeout")) { + parseTimeout (job, value); } } catch (NoSuchElementException nsee) { } } - return jobs.values (); + Vector jobVec = new Vector (jobs.values ()); + return (Vector) sort (jobVec); } + public static List sort (List list) { + Collections.sort (list, new Comparator() { + public int compare (Object o1, Object o2) { + CronJob cron1 = (CronJob) o1; + CronJob cron2 = (CronJob) o2; + if (cron1.getTimeout () > cron2.getTimeout ()) + return 1; + else if (cron1.getTimeout () < cron2.getTimeout ()) + return -1; + else + return 0; + } + public boolean equals (Object o1, Object o2) { + if (o1!=null) { + return o1.equals (o2); + } else { + return false; + } + } + + }); + return list; + } + public static void parseYear (CronJob job, String value) { if (value.equals("*")) { @@ -351,6 +397,22 @@ public class CronJob { } + public static void parseTimeout (CronJob job, String timeout) { + long timeoutValue = 1000 * Long.valueOf(timeout).longValue (); + job.setTimeout (timeoutValue); + } + + public static long nextFullMinute () { + long now = System.currentTimeMillis(); + long millisAfterMinute = (now % 60000); + return (now + 60000 - millisAfterMinute); + } + + public static long millisToNextFullMinute () { + long now = System.currentTimeMillis(); + long millisAfterMinute = (now % 60000); + return (60000 - millisAfterMinute); + } /** * Create an empty CronJob. @@ -657,13 +719,6 @@ public class CronJob { this.timeout = timeout; } - /** - * Set this entry's timeout - */ - public void setTimeout(String timeout) - { - this.timeout = Long.valueOf(timeout).longValue (); - } /** * Get this entry's timeout @@ -672,4 +727,9 @@ public class CronJob { { return this.timeout; } + + public String toString () { + return "[CronJob " + name + "]"; + } + } diff --git a/src/helma/util/CryptFile.java b/src/helma/util/CryptFile.java index e33228c0..bc44c679 100644 --- a/src/helma/util/CryptFile.java +++ b/src/helma/util/CryptFile.java @@ -1,78 +1,128 @@ -// CryptFile.java -// Copyright (c) Hannes Wallnöfer 2001 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.util; -import java.util.*; import java.io.*; +import java.util.*; /** * This file authenticates against a passwd file */ - public class CryptFile { - private Properties users; private CryptFile parentFile; private File file; private long lastRead = 0; - public CryptFile (File file, CryptFile parentFile) { - this.file = file; - this.parentFile = parentFile; - users = new Properties (); + /** + * Creates a new CryptFile object. + * + * @param file ... + * @param parentFile ... + */ + public CryptFile(File file, CryptFile parentFile) { + this.file = file; + this.parentFile = parentFile; + users = new Properties(); } + /** + * + * + * @param username ... + * @param pw ... + * + * @return ... + */ + public boolean authenticate(String username, String pw) { + if (file.exists() && (file.lastModified() > lastRead)) { + readFile(); + } else if (!file.exists() && (users.size() > 0)) { + users.clear(); + } - public boolean authenticate (String username, String pw) { - if (file.exists () && file.lastModified () > lastRead) - readFile (); - else if (!file.exists () && users.size () > 0) - users.clear (); - String realpw = users.getProperty (username); - if (realpw != null) { - try { - // check if password matches - // first we try with unix crypt algorithm - String cryptpw = Crypt.crypt (realpw, pw); - if (realpw.equals (cryptpw)) - return true; - // then try MD5 - if (realpw.equals (MD5Encoder.encode (pw))) - return true; - } catch (Exception x) { - return false; - } - } else { - if (parentFile != null) - return parentFile.authenticate (username, pw); - } - return false; + String realpw = users.getProperty(username); + + if (realpw != null) { + try { + // check if password matches + // first we try with unix crypt algorithm + String cryptpw = Crypt.crypt(realpw, pw); + + if (realpw.equals(cryptpw)) { + return true; + } + + // then try MD5 + if (realpw.equals(MD5Encoder.encode(pw))) { + return true; + } + } catch (Exception x) { + return false; + } + } else { + if (parentFile != null) { + return parentFile.authenticate(username, pw); + } + } + + return false; } - private synchronized void readFile () { - BufferedReader reader = null; - users = new Properties (); - try { - reader = new BufferedReader (new FileReader (file)); - String line = reader.readLine (); - while (line != null) { - StringTokenizer st = new StringTokenizer (line, ":"); - if (st.countTokens () > 1) - users.put (st.nextToken (), st.nextToken ()); - line = reader.readLine (); - } - } catch (Exception ignore) { - } finally { - if (reader != null) - try { reader.close (); } catch (Exception x) {} - lastRead = System.currentTimeMillis (); - } + private synchronized void readFile() { + BufferedReader reader = null; + + users = new Properties(); + + try { + reader = new BufferedReader(new FileReader(file)); + + String line = reader.readLine(); + + while (line != null) { + StringTokenizer st = new StringTokenizer(line, ":"); + + if (st.countTokens() > 1) { + users.put(st.nextToken(), st.nextToken()); + } + + line = reader.readLine(); + } + } catch (Exception ignore) { + } finally { + if (reader != null) { + try { + reader.close(); + } catch (Exception x) { + } + } + + lastRead = System.currentTimeMillis(); + } } - public static void main (String args[]) { - CryptFile cf = new CryptFile (new File ("passwd"), null); - System.err.println (cf.authenticate ("hns", "asdf")); - } + /** + * + * + * @param args ... + */ + public static void main(String[] args) { + CryptFile cf = new CryptFile(new File("passwd"), null); + System.err.println(cf.authenticate("hns", "asdf")); + } } diff --git a/src/helma/util/EmptyEnumeration.java b/src/helma/util/EmptyEnumeration.java index a5157fea..36765c1e 100644 --- a/src/helma/util/EmptyEnumeration.java +++ b/src/helma/util/EmptyEnumeration.java @@ -1,5 +1,18 @@ -// EmptyEnumeration.java -// Copyright (c) Hannes Wallnöfer 2001 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.util; @@ -8,16 +21,22 @@ import java.util.Enumeration; /** * Utility class for empty enum */ - public class EmptyEnumeration implements Enumeration { - - - public boolean hasMoreElements () { - return false; + /** + * + * + * @return ... + */ + public boolean hasMoreElements() { + return false; } - public Object nextElement () { - return null; + /** + * + * + * @return ... + */ + public Object nextElement() { + return null; } - } diff --git a/src/helma/util/FileUpload.java b/src/helma/util/FileUpload.java index d22e5aad..1b8b80a3 100644 --- a/src/helma/util/FileUpload.java +++ b/src/helma/util/FileUpload.java @@ -1,5 +1,18 @@ -// FileUpload.java -// Copyright (c) Hannes Wallnöfer 1996-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.util; @@ -10,99 +23,138 @@ import java.util.*; /** * Utility class for MIME file uploads via HTTP POST. */ - public class FileUpload { - public Hashtable parts; int maxKbytes; - public FileUpload () { - maxKbytes = 1024; + /** + * Creates a new FileUpload object. + */ + public FileUpload() { + maxKbytes = 1024; } - public FileUpload (int max) { - maxKbytes = max; + /** + * Creates a new FileUpload object. + * + * @param max ... + */ + public FileUpload(int max) { + maxKbytes = max; } - public Hashtable getParts () { - return parts; + /** + * + * + * @return ... + */ + public Hashtable getParts() { + return parts; } + /** + * + * + * @param is ... + * @param contentType ... + * @param contentLength ... + * + * @throws Exception ... + * @throws MimeParserException ... + * @throws IOException ... + */ + public void load(InputStream is, String contentType, int contentLength) + throws Exception { + parts = new Hashtable(); - public void load (InputStream is, String contentType, int contentLength) throws Exception { + String boundary = getSubHeader(contentType, "boundary"); - parts = new Hashtable (); + if (boundary == null) { + throw new MimeParserException("Error parsing MIME input stream."); + } - String boundary = getSubHeader (contentType, "boundary"); - if (boundary == null) - throw new MimeParserException ("Error parsing MIME input stream."); - if (maxKbytes > -1 && contentLength > maxKbytes*1024) - throw new IOException ("Size of upload exceeds limit of " + maxKbytes + " kB."); + if ((maxKbytes > -1) && (contentLength > (maxKbytes * 1024))) { + throw new IOException("Size of upload exceeds limit of " + maxKbytes + + " kB."); + } - byte b[] = new byte[contentLength]; - MultipartInputStream in = new MultipartInputStream (new BufferedInputStream (is), boundary.getBytes ()); + byte[] b = new byte[contentLength]; + MultipartInputStream in = new MultipartInputStream(new BufferedInputStream(is), + boundary.getBytes()); - while (in.nextInputStream ()) { + while (in.nextInputStream()) { + MimeParser parser = new MimeParser(in, new MimeHeadersFactory()); + MimeHeaders headers = (MimeHeaders) parser.parse(); - MimeParser parser = new MimeParser (in, new MimeHeadersFactory ()); - MimeHeaders headers = (MimeHeaders) parser.parse (); + InputStream bodystream = parser.getInputStream(); + int read; + int count = 0; - InputStream bodystream = parser.getInputStream (); - int read, count = 0; - - while ((read = bodystream.read (b, count, 4096)) > -1) { - count += read; - if (count == b.length) { - byte newb[] = new byte[count+4096]; - System.arraycopy (b, 0, newb, 0, count); - b = newb; - } - } + while ((read = bodystream.read(b, count, 4096)) > -1) { + count += read; - byte newb[] = new byte[count]; - System.arraycopy (b, 0, newb, 0, count); + if (count == b.length) { + byte[] newb = new byte[count + 4096]; - String type = headers.getValue("Content-Type"); - String disposition = headers.getValue ("Content-Disposition"); - String name = getSubHeader (disposition, "name"); - String filename = getSubHeader (disposition, "filename"); - if (filename != null) { - int sep = filename.lastIndexOf ("\\"); - if (sep > -1) - filename = filename.substring (sep+1); - sep = filename.lastIndexOf ("/"); - if (sep > -1) - filename = filename.substring (sep+1); - } - if (filename != null) { - MimePart part = new MimePart (filename, newb, type); - parts.put (name, part); - } else { - parts.put (name, new String (newb)); - } + System.arraycopy(b, 0, newb, 0, count); + b = newb; + } + } - } + byte[] newb = new byte[count]; + System.arraycopy(b, 0, newb, 0, count); + + String type = headers.getValue("Content-Type"); + String disposition = headers.getValue("Content-Disposition"); + String name = getSubHeader(disposition, "name"); + String filename = getSubHeader(disposition, "filename"); + + if (filename != null) { + int sep = filename.lastIndexOf("\\"); + + if (sep > -1) { + filename = filename.substring(sep + 1); + } + + sep = filename.lastIndexOf("/"); + + if (sep > -1) { + filename = filename.substring(sep + 1); + } + } + + if (filename != null) { + MimePart part = new MimePart(filename, newb, type); + + parts.put(name, part); + } else { + parts.put(name, new String(newb)); + } + } } + private String getSubHeader(String header, String subHeaderName) { + if (header == null) { + return null; + } + String retval = null; + StringTokenizer headerTokenizer = new StringTokenizer(header, ";"); - private String getSubHeader (String header, String subHeaderName) { - if (header == null) - return null; - String retval = null; - StringTokenizer headerTokenizer = new StringTokenizer(header, ";"); - while (headerTokenizer.hasMoreTokens()) { - String token = headerTokenizer.nextToken().trim (); - int i = token.indexOf ("="); - if (i > 0) { - String hname = token.substring (0, i).trim (); - if (hname.equalsIgnoreCase (subHeaderName)) - retval = token.substring (i+1).replace ('"', ' ').trim (); - } - } - return retval; + while (headerTokenizer.hasMoreTokens()) { + String token = headerTokenizer.nextToken().trim(); + int i = token.indexOf("="); + + if (i > 0) { + String hname = token.substring(0, i).trim(); + + if (hname.equalsIgnoreCase(subHeaderName)) { + retval = token.substring(i + 1).replace('"', ' ').trim(); + } + } + } + + return retval; } - - } diff --git a/src/helma/util/HtmlEncoder.java b/src/helma/util/HtmlEncoder.java index 29c587ad..6bfbdf8b 100644 --- a/src/helma/util/HtmlEncoder.java +++ b/src/helma/util/HtmlEncoder.java @@ -1,23 +1,34 @@ -// HtmlEncoder.java -// Copyright (c) Hannes Wallnöfer 1997-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.util; -import java.io.*; -import java.util.*; import java.awt.*; import java.awt.image.*; +import java.io.*; import java.text.*; - +import java.util.*; /** - * This is a utility class to encode special characters and do formatting + * This is a utility class to encode special characters and do formatting * for HTML output. */ - public final class HtmlEncoder { - // transformation table for characters 128 to 255. These actually fall into two + // transformation table for characters 128 to 255. These actually fall into two // groups, put together for efficiency: "Windows" chacacters 128-159 such as // "smart quotes", which are encoded to valid Unicode entities, and // valid ISO-8859 caracters 160-255, which are encoded to the symbolic HTML @@ -157,140 +168,158 @@ public final class HtmlEncoder { "&yuml;" // 255 }; + static final HashSet allTags = new HashSet(); - static final HashSet allTags = new HashSet (); static { - allTags.add ("a"); - allTags.add ("abbr"); - allTags.add ("address"); - allTags.add ("applet"); - allTags.add ("area"); - allTags.add ("b"); - allTags.add ("base"); - allTags.add ("basefont"); - allTags.add ("bgsound"); - allTags.add ("big"); - allTags.add ("blink"); - allTags.add ("blockquote"); - allTags.add ("bq"); - allTags.add ("body"); - allTags.add ("br"); - allTags.add ("button"); - allTags.add ("caption"); - allTags.add ("center"); - allTags.add ("cite"); - allTags.add ("code"); - allTags.add ("col"); - allTags.add ("colgroup"); - allTags.add ("del"); - allTags.add ("dir"); - allTags.add ("div"); - allTags.add ("dl"); - allTags.add ("dt"); - allTags.add ("dd"); - allTags.add ("em"); - allTags.add ("embed"); - allTags.add ("fieldset"); - allTags.add ("font"); - allTags.add ("form"); - allTags.add ("frame"); - allTags.add ("frameset"); - allTags.add ("h1"); - allTags.add ("h2"); - allTags.add ("h3"); - allTags.add ("h4"); - allTags.add ("h5"); - allTags.add ("h6"); - allTags.add ("head"); - allTags.add ("html"); - allTags.add ("hr"); - allTags.add ("i"); - allTags.add ("iframe"); - allTags.add ("img"); - allTags.add ("input"); - allTags.add ("ins"); - allTags.add ("isindex"); - allTags.add ("kbd"); - allTags.add ("li"); - allTags.add ("link"); - allTags.add ("listing"); - allTags.add ("map"); - allTags.add ("marquee"); - allTags.add ("menu"); - allTags.add ("meta"); - allTags.add ("nobr"); - allTags.add ("noframes"); - allTags.add ("object"); - allTags.add ("ol"); - allTags.add ("option"); - allTags.add ("optgroup"); - allTags.add ("p"); - allTags.add ("param"); - allTags.add ("plaintext"); - allTags.add ("pre"); - allTags.add ("q"); - allTags.add ("s"); - allTags.add ("samp"); - allTags.add ("script"); - allTags.add ("select"); - allTags.add ("small"); - allTags.add ("span"); - allTags.add ("strike"); - allTags.add ("strong"); - allTags.add ("style"); - allTags.add ("sub"); - allTags.add ("sup"); - allTags.add ("table"); - allTags.add ("tbody"); - allTags.add ("td"); - allTags.add ("textarea"); - allTags.add ("tfoot"); - allTags.add ("th"); - allTags.add ("thead"); - allTags.add ("title"); - allTags.add ("tr"); - allTags.add ("tt"); - allTags.add ("u"); - allTags.add ("ul"); - allTags.add ("var"); - allTags.add ("wbr"); - allTags.add ("xmp"); + allTags.add("a"); + allTags.add("abbr"); + allTags.add("acronym"); + allTags.add("address"); + allTags.add("applet"); + allTags.add("area"); + allTags.add("b"); + allTags.add("base"); + allTags.add("basefont"); + allTags.add("bdo"); + allTags.add("bgsound"); + allTags.add("big"); + allTags.add("blink"); + allTags.add("blockquote"); + allTags.add("bq"); + allTags.add("body"); + allTags.add("br"); + allTags.add("button"); + allTags.add("caption"); + allTags.add("center"); + allTags.add("cite"); + allTags.add("code"); + allTags.add("col"); + allTags.add("colgroup"); + allTags.add("del"); + allTags.add("dfn"); + allTags.add("dir"); + allTags.add("div"); + allTags.add("dl"); + allTags.add("dt"); + allTags.add("dd"); + allTags.add("em"); + allTags.add("embed"); + allTags.add("fieldset"); + allTags.add("font"); + allTags.add("form"); + allTags.add("frame"); + allTags.add("frameset"); + allTags.add("h1"); + allTags.add("h2"); + allTags.add("h3"); + allTags.add("h4"); + allTags.add("h5"); + allTags.add("h6"); + allTags.add("head"); + allTags.add("html"); + allTags.add("hr"); + allTags.add("i"); + allTags.add("iframe"); + allTags.add("img"); + allTags.add("input"); + allTags.add("ins"); + allTags.add("isindex"); + allTags.add("kbd"); + allTags.add("label"); + allTags.add("legend"); + allTags.add("li"); + allTags.add("link"); + allTags.add("listing"); + allTags.add("map"); + allTags.add("marquee"); + allTags.add("menu"); + allTags.add("meta"); + allTags.add("nobr"); + allTags.add("noframes"); + allTags.add("noscript"); + allTags.add("object"); + allTags.add("ol"); + allTags.add("option"); + allTags.add("optgroup"); + allTags.add("p"); + allTags.add("param"); + allTags.add("plaintext"); + allTags.add("pre"); + allTags.add("q"); + allTags.add("s"); + allTags.add("samp"); + allTags.add("script"); + allTags.add("select"); + allTags.add("small"); + allTags.add("span"); + allTags.add("strike"); + allTags.add("strong"); + allTags.add("style"); + allTags.add("sub"); + allTags.add("sup"); + allTags.add("table"); + allTags.add("tbody"); + allTags.add("td"); + allTags.add("textarea"); + allTags.add("tfoot"); + allTags.add("th"); + allTags.add("thead"); + allTags.add("title"); + allTags.add("tr"); + allTags.add("tt"); + allTags.add("u"); + allTags.add("ul"); + allTags.add("var"); + allTags.add("wbr"); + allTags.add("xmp"); } - // tags which signal us to start suppressing \n -> <br> encoding - // these are "structrural" tags, for example, we don't want to add <br>s - // between a <table> and a <tr>. - static final HashSet suppressLinebreakTags = new HashSet (); - static { - suppressLinebreakTags.add ("table"); - suppressLinebreakTags.add ("ul"); - suppressLinebreakTags.add ("ol"); - suppressLinebreakTags.add ("pre"); - } + // HTML block tags need to suppress automatic newline to <br> + // conversion around them to look good. However, they differ + // in how many newlines around them should ignored. These sets + // help to treat each tag right in newline conversion. + static final HashSet swallowAll = new HashSet(); + static final HashSet swallowTwo = new HashSet(); + static final HashSet swallowOne = new HashSet(); - // tags which signal us to stop suppressing \n -> <br> encoding - // these usually signal transition from structural tags to normal - // HTML text, e.g. <td> - static final HashSet encodeLinebreakTags = new HashSet (); static { - encodeLinebreakTags.add ("td"); - encodeLinebreakTags.add ("th"); - encodeLinebreakTags.add ("li"); - } + // actual block level elements + swallowOne.add("address"); + swallowTwo.add("blockquote"); + swallowTwo.add("center"); + swallowOne.add("dir"); + swallowOne.add("div"); + swallowTwo.add("dl"); + swallowTwo.add("fieldset"); + swallowTwo.add("form"); + swallowTwo.add("h1"); + swallowTwo.add("h2"); + swallowTwo.add("h3"); + swallowTwo.add("h4"); + swallowTwo.add("h5"); + swallowTwo.add("h6"); + swallowTwo.add("hr"); + swallowTwo.add("isindex"); + swallowAll.add("menu"); + swallowAll.add("noframes"); + swallowAll.add("noscript"); + swallowTwo.add("ol"); + swallowTwo.add("p"); + swallowTwo.add("pre"); + swallowOne.add("table"); + swallowTwo.add("ul"); - /** - * - */ - public final static String encode (String str) { - if (str == null) - return null; - int l = str.length(); - if (l == 0) - return ""; - // try to make stringbuffer large enough from the start - StringBuffer ret = new StringBuffer (Math.round (l*1.4f)); - encode (str, ret); - return ret.toString(); + /// to be treated as block level elements + swallowTwo.add("dd"); + swallowTwo.add("dt"); + swallowTwo.add("frameset"); + swallowTwo.add("li"); + swallowAll.add("tbody"); + swallowTwo.add("td"); + swallowAll.add("tfoot"); + swallowOne.add("th"); + swallowAll.add("thead"); + swallowAll.add("tr"); } /** @@ -298,354 +327,580 @@ public final class HtmlEncoder { * Helma macros and HTML comments are passed through unescaped, while * other occurrences of '<', '>' and '&' are encoded to HTML entities. */ - public final static void encode (String str, StringBuffer ret) { - if (str == null) - return; + public final static String encode(String str) { + if (str == null) { + return null; + } - int l = str.length(); + int l = str.length(); - // are we currently within a < and a > that consitute some kind of tag? - // we use tag balancing to know whether we are inside a tag (and should - // pass things through unchanged) or outside (and should encode stuff). - boolean insideTag = false; - // are we inside an HTML tag? - boolean insideHtmlTag = false; - // if we are inside a <code> tag, we encode everything to make - // documentation work easier - boolean insideCodeTag = false; - // are we within a Helma <% macro %> tag? We treat macro tags and - // comments specially, since we can't rely on tag balancing - // to know when we leave a macro tag or comment. - boolean insideMacroTag = false; - // are we inside an HTML comment? - boolean insideComment = false; - // the quotation mark we are in within an HTML or Macro tag, if any - char htmlQuoteChar = '\u0000'; - char macroQuoteChar = '\u0000'; - // the difference between swallowOneNewline and ignoreNewline is that - // swallowOneNewline is just effective once (for the next newline) - boolean ignoreNewline = false; - boolean swallowOneNewline = false; - // did we meet a backslash escape? - boolean escape = false; + if (l == 0) { + return ""; + } - for (int i=0; i<l; i++) { - char c = str.charAt(i); + // try to make stringbuffer large enough from the start + StringBuffer ret = new StringBuffer(Math.round(l * 1.4f)); - switch (c) { - case '&': - // check if this is an HTML entity already, - // in which case we pass it though unchanged - if (i < l-3 && !insideCodeTag) { - // is this a numeric entity? - if (str.charAt(i+1) == '#' ) { - int j = i+2; - while (j<l && Character.isDigit (str.charAt(j))) - j++; - if (j<l && str.charAt(j) == ';') { - ret.append ("&"); - break; - } - } else { - int j = i+1; - while (j<l && Character.isLetterOrDigit (str.charAt(j))) - j++; - if (j<l && str.charAt(j) == ';') { - ret.append ("&"); - break; - } - } - } - // we didn't reach a break, so encode the ampersand as HTML entity - ret.append ("&amp;"); - break; - case '<': - if (i < l-2) { - if (!insideMacroTag && '%' == str.charAt(i+1)) { - // this is the beginning of a Helma macro tag - if (!insideCodeTag) { - insideMacroTag = insideTag = true; - macroQuoteChar = '\u0000'; - } - } else if ('!' == str.charAt(i+1) && '-' == str.charAt(i+2)) { - // the beginning of an HTML comment? - if (!insideCodeTag) - insideComment = insideTag = (i<l-3 && '-' == str.charAt(i+3)); - } else if (!insideTag) { - // check if this is a HTML tag. - boolean insideCloseTag = ('/' == str.charAt(i+1)); - int tagStart = insideCloseTag ? i+2 : i+1; - int j = tagStart; - while (j<l && Character.isLetterOrDigit (str.charAt(j))) - j++; - if (j > tagStart && j < l) { - String tagName = str.substring (tagStart, j).toLowerCase(); - if ("code".equals (tagName) && insideCloseTag && insideCodeTag) - insideCodeTag = false; - if (allTags.contains (tagName) && !insideCodeTag) { - insideHtmlTag = insideTag = true; - htmlQuoteChar = '\u0000'; - // set ignoreNewline on some tags, depending on wheather they're - // being opened or closed. - // what's going on here? we switch newline encoding on inside some tags, for - // others we switch it on when they're closed - if (encodeLinebreakTags.contains (tagName)) { - ignoreNewline = insideCloseTag; - swallowOneNewline = true; - } else if (suppressLinebreakTags.contains (tagName)) { - ignoreNewline = !insideCloseTag; - swallowOneNewline = true; - } else if ("p".equals (tagName) || "blockquote".equals (tagName) || "bq".equals (tagName)) { - swallowOneNewline = true; - } - if ("code".equals (tagName) && !insideCloseTag) - insideCodeTag = true; - } - } - } - } // if (i < l-2) - if (insideTag) - ret.append ('<'); - else - ret.append ("&lt;"); - break; - case '\\': - ret.append (c); - if (insideTag && !insideComment) - escape = !escape; - break; - case '"': - case '\'': - ret.append (c); - if (!insideComment) { - // check if the quote is escaped - if (insideMacroTag) { - if (escape) - escape = false; - else if (macroQuoteChar == c) - macroQuoteChar = '\u0000'; - else if (macroQuoteChar == '\u0000') - macroQuoteChar = c; - } else if (insideHtmlTag) { - if (escape) - escape = false; - else if (htmlQuoteChar == c) - htmlQuoteChar = '\u0000'; - else if (htmlQuoteChar == '\u0000') - htmlQuoteChar = c; - } - } - break; - case '\n': - ret.append ('\n'); - if (!insideTag) { - if (!ignoreNewline && !swallowOneNewline) - ret.append ("<br />"); - swallowOneNewline = false; - } - break; - case '>': - // For Helma macro tags and comments, we overrule tag balancing, - // i.e. we don't require that '<' and '>' be balanced within - // macros and comments. Rather, we check for the matching closing tag. - if (insideComment) { - ret.append ('>'); - insideComment = !(str.charAt(i-2) == '-' && str.charAt(i-1) == '-'); - } else if (insideMacroTag) { - ret.append ('>'); - insideMacroTag = !(str.charAt(i-1) == '%' && macroQuoteChar == '\u0000'); - } else if (insideHtmlTag) { - ret.append ('>'); - // only leave HTML tag if quotation marks are balanced - // within that tag. - insideHtmlTag = htmlQuoteChar != '\u0000'; - } else { - ret.append ("&gt;"); - } - // check if we still are inside any kind of tag - insideTag = insideComment || insideMacroTag || insideHtmlTag; - break; - default: - // ret.append (c); - if (c < 128) - ret.append (c); - else if (c >= 128 && c < 256) - ret.append (transform[c-128]); - else { - ret.append ("&#"); - ret.append ((int) c); - ret.append (";"); - } - if (swallowOneNewline && !insideTag && !Character.isWhitespace (c)) - swallowOneNewline = false; - escape = false; - } - } - } + encode(str, ret, null); + return ret.toString(); + } /** - * + * Do "smart" encodging on a string. This means that valid HTML entities and tags, + * Helma macros and HTML comments are passed through unescaped, while + * other occurrences of '<', '>' and '&' are encoded to HTML entities. */ - public final static String encodeFormValue (String str) { - if (str == null) - return null; - int l = str.length(); - if (l == 0) - return ""; - StringBuffer ret = new StringBuffer (Math.round (l*1.2f)); - encodeAll (str, ret, false); - return ret.toString(); + public final static void encode(String str, StringBuffer ret) { + encode(str, ret, null); + } + + /** + * Do "smart" encodging on a string. This means that valid HTML entities and tags, + * Helma macros and HTML comments are passed through unescaped, while + * other occurrences of '<', '>' and '&' are encoded to HTML entities. + */ + public final static void encode(String str, StringBuffer ret, Set allowedTags) { + if (str == null) { + return; + } + + int l = str.length(); + + Stack openTags = new Stack(); + + // are we currently within a < and a > that consitute some kind of tag? + // we use tag balancing to know whether we are inside a tag (and should + // pass things through unchanged) or outside (and should encode stuff). + boolean insideTag = false; + + // are we inside an HTML tag? + boolean insideHtmlTag = false; + + // if we are inside a <code> tag, we encode everything to make + // documentation work easier + boolean insideCodeTag = false; + boolean insidePreTag = false; + + // are we within a Helma <% macro %> tag? We treat macro tags and + // comments specially, since we can't rely on tag balancing + // to know when we leave a macro tag or comment. + boolean insideMacroTag = false; + + // are we inside an HTML comment? + boolean insideComment = false; + + // the quotation mark we are in within an HTML or Macro tag, if any + char htmlQuoteChar = '\u0000'; + char macroQuoteChar = '\u0000'; + + // number of newlines to ignore in \n -> <br> conversion + int swallowLinebreaks = 0; + + // number of newlines met since the last non-whitespace character + int linebreaks = 0; + + // did we meet a backslash escape? + boolean escape = false; + + for (int i = 0; i < l; i++) { + char c = str.charAt(i); + + // step one: check if this is the beginning of an HTML tag, comment or + // Helma macro. + if (c == '<') { + if (i < (l - 2)) { + if (!insideMacroTag && ('%' == str.charAt(i + 1))) { + // this is the beginning of a Helma macro tag + if (!insideCodeTag) { + insideMacroTag = insideTag = true; + macroQuoteChar = '\u0000'; + } + } else if (('!' == str.charAt(i + 1)) && ('-' == str.charAt(i + 2))) { + // the beginning of an HTML comment? + if (!insideCodeTag) { + insideComment = insideTag = ((i < (l - 3)) && + ('-' == str.charAt(i + 3))); + } + } else if (!insideTag) { + // check if this is a HTML tag. + boolean insideCloseTag = ('/' == str.charAt(i + 1)); + int tagStart = insideCloseTag ? (i + 2) : (i + 1); + int j = tagStart; + + while ((j < l) && Character.isLetterOrDigit(str.charAt(j))) + j++; + + if ((j > tagStart) && (j < l)) { + String tagName = str.substring(tagStart, j).toLowerCase(); + + if ("code".equals(tagName) && insideCloseTag && + insideCodeTag) { + insideCodeTag = false; + } + + if (((allowedTags == null) || allowedTags.contains(tagName)) && + allTags.contains(tagName) && !insideCodeTag) { + insideHtmlTag = insideTag = true; + htmlQuoteChar = '\u0000'; + + // set ignoreNewline on some tags, depending on wheather they're + // being opened or closed. + // what's going on here? we switch newline encoding on inside some tags, for + // others we switch it on when they're closed + linebreaks = Math.max(linebreaks - swallowLinebreaks, 0); + + if (swallowAll.contains(tagName)) { + swallowLinebreaks = 1000; + } else if (swallowTwo.contains(tagName)) { + swallowLinebreaks = 2; + } else if (swallowOne.contains(tagName)) { + swallowLinebreaks = 1; + } else { + swallowLinebreaks = 0; + } + + if (insideCloseTag) { + int t = openTags.search(tagName); + + if (t == -1) { + i = j; + insideHtmlTag = insideTag = false; + + continue; + } else if (t > 1) { + for (int k = 1; k < t; k++) { + ret.append("</"); + ret.append(openTags.pop()); + ret.append(">"); + } + } + + openTags.pop(); + } else { + openTags.push(tagName); + swallowLinebreaks = Math.max(swallowLinebreaks - 1, 0); + } + + if ("code".equals(tagName) && !insideCloseTag) { + insideCodeTag = true; + } + + if ("pre".equals(tagName)) { + insidePreTag = !insideCloseTag; + } + } + } + } + } + // if (i < l-2) + } + + if ((linebreaks > 0) && !Character.isWhitespace(c)) { + if (!insidePreTag && (linebreaks > swallowLinebreaks)) { + linebreaks -= swallowLinebreaks; + + for (int k = 0; k < linebreaks; k++) + ret.append("<br />\n"); + } + + if (!insideTag) { + swallowLinebreaks = 0; + } + + linebreaks = 0; + } + + switch (c) { + case '<': + + if (insideTag) { + ret.append('<'); + } else { + ret.append("&lt;"); + } + + break; + + case '&': + + // check if this is an HTML entity already, + // in which case we pass it though unchanged + if ((i < (l - 3)) && !insideCodeTag) { + // is this a numeric entity? + if (str.charAt(i + 1) == '#') { + int j = i + 2; + + while ((j < l) && Character.isDigit(str.charAt(j))) + j++; + + if ((j < l) && (str.charAt(j) == ';')) { + ret.append("&"); + + break; + } + } else { + int j = i + 1; + + while ((j < l) && Character.isLetterOrDigit(str.charAt(j))) + j++; + + if ((j < l) && (str.charAt(j) == ';')) { + ret.append("&"); + + break; + } + } + } + + // we didn't reach a break, so encode the ampersand as HTML entity + ret.append("&amp;"); + + break; + + case '\\': + ret.append(c); + + if (insideTag && !insideComment) { + escape = !escape; + } + + break; + + case '"': + case '\'': + ret.append(c); + + if (!insideComment) { + // check if the quote is escaped + if (insideMacroTag) { + if (escape) { + escape = false; + } else if (macroQuoteChar == c) { + macroQuoteChar = '\u0000'; + } else if (macroQuoteChar == '\u0000') { + macroQuoteChar = c; + } + } else if (insideHtmlTag) { + if (escape) { + escape = false; + } else if (htmlQuoteChar == c) { + htmlQuoteChar = '\u0000'; + } else if (htmlQuoteChar == '\u0000') { + htmlQuoteChar = c; + } + } + } + + break; + + case '\n': + ret.append('\n'); + + if (!insideTag) { + linebreaks++; + } + + break; + + case '>': + + // For Helma macro tags and comments, we overrule tag balancing, + // i.e. we don't require that '<' and '>' be balanced within + // macros and comments. Rather, we check for the matching closing tag. + if (insideComment) { + ret.append('>'); + insideComment = !((str.charAt(i - 2) == '-') && + (str.charAt(i - 1) == '-')); + } else if (insideMacroTag) { + ret.append('>'); + insideMacroTag = !((str.charAt(i - 1) == '%') && + (macroQuoteChar == '\u0000')); + } else if (insideHtmlTag) { + ret.append('>'); + + // only leave HTML tag if quotation marks are balanced + // within that tag. + insideHtmlTag = htmlQuoteChar != '\u0000'; + + // Check if this is an empty tag so we don't generate an + // additional </close> tag. + if (str.charAt(i - 1) == '/') { + openTags.pop(); + } + } else { + ret.append("&gt;"); + } + + // check if we still are inside any kind of tag + insideTag = insideComment || insideMacroTag || insideHtmlTag; + + break; + + default: + + // ret.append (c); + if (c < 128) { + ret.append(c); + } else if ((c >= 128) && (c < 256)) { + ret.append(transform[c - 128]); + } else { + ret.append("&#"); + ret.append((int) c); + ret.append(";"); + } + + escape = false; + } + } + + // if tags were opened but not closed, close them. + int o = openTags.size(); + + if (o > 0) { + for (int k = 0; k < o; k++) { + ret.append("</"); + ret.append(openTags.pop()); + ret.append(">"); + } + } + + // add remaining newlines we may have collected + if ((linebreaks > 0) && (linebreaks > swallowLinebreaks)) { + linebreaks -= swallowLinebreaks; + + for (int i = 0; i < linebreaks; i++) + ret.append("<br />\n"); + } } /** * */ - public final static void encodeFormValue (String str, StringBuffer ret) { - encodeAll (str, ret, false); - } + public final static String encodeFormValue(String str) { + if (str == null) { + return null; + } + int l = str.length(); - /** - * - */ - public final static String encodeAll (String str) { - if (str == null) - return null; - int l = str.length(); - if (l == 0) - return ""; - StringBuffer ret = new StringBuffer (Math.round (l*1.2f)); - encodeAll (str, ret, true); - return ret.toString(); + if (l == 0) { + return ""; + } + + StringBuffer ret = new StringBuffer(Math.round(l * 1.2f)); + + encodeAll(str, ret, false); + + return ret.toString(); } /** * */ - public final static void encodeAll (String str, StringBuffer ret) { - encodeAll (str, ret, true); + public final static void encodeFormValue(String str, StringBuffer ret) { + encodeAll(str, ret, false); } - /** * */ - public final static void encodeAll (String str, StringBuffer ret, boolean encodeNewline) { - if (str == null) - return; + public final static String encodeAll(String str) { + if (str == null) { + return null; + } - int l = str.length(); - for (int i=0; i<l; i++) { - char c = str.charAt (i); - switch (c) { - case '<' : - ret.append ("&lt;"); - break; - case '>': - ret.append ("&gt;"); - break; - case '&': - ret.append ("&amp;"); - break; - case '"': - ret.append ("&quot;"); - break; - case '\n': - ret.append ('\n'); - if (encodeNewline) { - ret.append ("<br />"); - } - break; - default: - // ret.append (c); - if (c < 128) - ret.append (c); - else if (c >= 128 && c < 256) - ret.append (transform[c-128]); - else { - ret.append ("&#"); - ret.append ((int) c); - ret.append (";"); - } - } - } - } + int l = str.length(); + if (l == 0) { + return ""; + } - public final static String encodeXml (String str) { - if (str == null) - return null; - int l = str.length(); - if (l == 0) - return ""; - StringBuffer ret = new StringBuffer (Math.round (l*1.2f)); - encodeXml (str, ret); - return ret.toString(); + StringBuffer ret = new StringBuffer(Math.round(l * 1.2f)); + + encodeAll(str, ret, true); + + return ret.toString(); } - public final static void encodeXml (String str, StringBuffer ret) { - if (str == null) - return; + /** + * + */ + public final static void encodeAll(String str, StringBuffer ret) { + encodeAll(str, ret, true); + } - int l = str.length(); - for (int i=0; i<l; i++) { - char c = str.charAt (i); - switch (c) { - case '<' : - ret.append ("&lt;"); - break; - case '>': - ret.append ("&gt;"); - break; - case '&': - ret.append ("&amp;"); - break; - case '"': - ret.append ("&quot;"); - break; - case '\'': - ret.append ("&apos;"); - break; - default: - if (c < 0x20) { - // sort out invalid XML characters below 0x20 - all but 0x9, 0xA and 0xD. - // The trick is an adaption of java.lang.Character.isSpace(). - if (((((1L << 0x9) | (1L << 0xA) | (1L << 0xD)) >> c) & 1L) != 0) - ret.append (c); - } else { - ret.append (c); - } - } - } - } + /** + * + */ + public final static void encodeAll(String str, StringBuffer ret, boolean encodeNewline) { + if (str == null) { + return; + } + + int l = str.length(); + + for (int i = 0; i < l; i++) { + char c = str.charAt(i); + + switch (c) { + case '<': + ret.append("&lt;"); + + break; + + case '>': + ret.append("&gt;"); + + break; + + case '&': + ret.append("&amp;"); + + break; + + case '"': + ret.append("&quot;"); + + break; + + case '\n': + ret.append('\n'); + + if (encodeNewline) { + ret.append("<br />"); + } + + break; + + default: + + // ret.append (c); + if (c < 128) { + ret.append(c); + } else if ((c >= 128) && (c < 256)) { + ret.append(transform[c - 128]); + } else { + ret.append("&#"); + ret.append((int) c); + ret.append(";"); + } + } + } + } + + /** + * + * + * @param str ... + * + * @return ... + */ + public final static String encodeXml(String str) { + if (str == null) { + return null; + } + + int l = str.length(); + + if (l == 0) { + return ""; + } + + StringBuffer ret = new StringBuffer(Math.round(l * 1.2f)); + + encodeXml(str, ret); + + return ret.toString(); + } + + /** + * + * + * @param str ... + * @param ret ... + */ + public final static void encodeXml(String str, StringBuffer ret) { + if (str == null) { + return; + } + + int l = str.length(); + + for (int i = 0; i < l; i++) { + char c = str.charAt(i); + + switch (c) { + case '<': + ret.append("&lt;"); + + break; + + case '>': + ret.append("&gt;"); + + break; + + case '&': + ret.append("&amp;"); + + break; + + case '"': + ret.append("&quot;"); + + break; + + case '\'': + ret.append("&apos;"); + + break; + + default: + + if (c < 0x20) { + // sort out invalid XML characters below 0x20 - all but 0x9, 0xA and 0xD. + // The trick is an adaption of java.lang.Character.isSpace(). + if (((((1L << 0x9) | (1L << 0xA) | (1L << 0xD)) >> c) & 1L) != 0) { + ret.append(c); + } + } else { + ret.append(c); + } + } + } + } // test method - public static String printCharRange (int from, int to) { - StringBuffer response = new StringBuffer(); - for (int i=from;i<to;i++) { - response.append (i); - response.append (" "); - response.append ((char) i); - response.append (" "); - if (i < 128) - response.append ((char) i); - else if (i >= 128 && i < 256) - response.append (transform[i-128]); - else { - response.append ("&#"); - response.append (i); - response.append (";"); - } - response.append ("\r\n"); - } - return response.toString(); + public static String printCharRange(int from, int to) { + StringBuffer response = new StringBuffer(); + + for (int i = from; i < to; i++) { + response.append(i); + response.append(" "); + response.append((char) i); + response.append(" "); + + if (i < 128) { + response.append((char) i); + } else if ((i >= 128) && (i < 256)) { + response.append(transform[i - 128]); + } else { + response.append("&#"); + response.append(i); + response.append(";"); + } + + response.append("\r\n"); + } + + return response.toString(); } // for testing... - public static void main (String[] args) { - for (int i=0; i<args.length; i++) - System.err.println (encode (args[i])); + public static void main(String[] args) { + for (int i = 0; i < args.length; i++) + System.err.println(encode(args[i])); } - -} // end of class +} + // end of class diff --git a/src/helma/util/HtmlParser.java b/src/helma/util/HtmlParser.java index c3c177c3..eeb58e13 100644 --- a/src/helma/util/HtmlParser.java +++ b/src/helma/util/HtmlParser.java @@ -1,258 +1,307 @@ -// HtmlParser.java -// Copyright (c) Hannes Wallnöfer 2002 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.util; -import java.util.HashMap; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Stack; -import java.util.EmptyStackException; -import java.io.IOException; -import javax.swing.text.html.parser.*; -import javax.swing.text.SimpleAttributeSet; -import org.xml.sax.SAXException; import org.apache.html.dom.*; import org.w3c.dom.html.HTMLDocument; +import org.xml.sax.SAXException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.EmptyStackException; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Stack; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.html.parser.*; +/** + * + */ public class HtmlParser extends Parser { + static final HashSet stopNone = new HashSet(); + static final HashSet stopTable = new HashSet(); + static final HashSet stopList = new HashSet(); + static final HashSet stopDeflist = new HashSet(); - HTMLBuilder builder; - Attributes attributes = new Attributes (); - - Stack stack = new Stack (); - - static final HashSet stopNone = new HashSet (); - static final HashSet stopTable = new HashSet (); - static final HashSet stopList = new HashSet (); - static final HashSet stopDeflist = new HashSet (); static { - stopTable.add ("TABLE"); - stopList.add ("TABLE"); - stopList.add ("UL"); - stopList.add ("OL"); - stopDeflist.add ("TABLE"); - stopDeflist.add ("DL"); + stopTable.add("TABLE"); + stopList.add("TABLE"); + stopList.add("UL"); + stopList.add("OL"); + stopDeflist.add("TABLE"); + stopDeflist.add("DL"); } + HTMLBuilder builder; + Attributes attributes = new Attributes(); + Stack stack = new Stack(); - public HtmlParser () throws IOException { - super (DTD.getDTD ("html32")); - // define elements to be treated as container tags, and undefine those - // to be treated as empty tags. - dtd.getElement ("table"); - dtd.getElement ("tr"); - dtd.getElement ("td"); - dtd.getElement ("span"); - dtd.getElement ("div"); - dtd.getElement ("font"); - dtd.getElement ("b"); - dtd.getElement ("i"); - dtd.getElement ("a"); - dtd.getElement ("blockquote"); - dtd.getElement ("em"); - dtd.getElement ("ul"); - dtd.getElement ("ol"); - dtd.getElement ("li"); - dtd.getElement ("dl"); - dtd.getElement ("dt"); - dtd.getElement ("dd"); - dtd.getElement ("h1"); - dtd.getElement ("h2"); - dtd.getElement ("h3"); - dtd.getElement ("h4"); - dtd.getElement ("h5"); - dtd.getElement ("h6"); - dtd.getElement ("form"); - dtd.getElement ("option"); - dtd.elementHash.remove ("meta"); - dtd.elementHash.remove ("link"); - dtd.elementHash.remove ("base"); - builder = new HTMLBuilder (); - try { - builder.startDocument (); - } catch (SAXException x) { - System.err.println ("Error in constructor"); - } + /** + * Creates a new HtmlParser object. + * + * @throws IOException ... + */ + public HtmlParser() throws IOException { + super(DTD.getDTD("html32")); + + // define elements to be treated as container tags, and undefine those + // to be treated as empty tags. + dtd.getElement("table"); + dtd.getElement("tr"); + dtd.getElement("td"); + dtd.getElement("span"); + dtd.getElement("div"); + dtd.getElement("font"); + dtd.getElement("b"); + dtd.getElement("i"); + dtd.getElement("a"); + dtd.getElement("blockquote"); + dtd.getElement("em"); + dtd.getElement("ul"); + dtd.getElement("ol"); + dtd.getElement("li"); + dtd.getElement("dl"); + dtd.getElement("dt"); + dtd.getElement("dd"); + dtd.getElement("h1"); + dtd.getElement("h2"); + dtd.getElement("h3"); + dtd.getElement("h4"); + dtd.getElement("h5"); + dtd.getElement("h6"); + dtd.getElement("form"); + dtd.getElement("option"); + dtd.elementHash.remove("meta"); + dtd.elementHash.remove("link"); + dtd.elementHash.remove("base"); + builder = new HTMLBuilder(); + + try { + builder.startDocument(); + } catch (SAXException x) { + System.err.println("Error in constructor"); + } } /** * Handle Start Tag. */ protected void handleStartTag(TagElement tag) { - // System.err.println ("handleStartTag ("+tag.getHTMLTag()+")"); - attributes.convert (getAttributes()); - flushAttributes(); - String tagname = tag.getHTMLTag().toString().toUpperCase(); - // immediately empty A anchor tag - if ("A".equals (tagname) && attributes.getValue ("href") == null) try { - builder.startElement (tagname, attributes); - builder.endElement (tagname); - return; - } catch (SAXException x) {} - if ("TD".equals (tagname)) { - closeOpenTags ("TD", stopTable, 10); - } else if ("TR".equals (tagname)) { - closeOpenTags ("TR", stopTable, 10); - } else if ("LI".equals (tagname)) { - closeOpenTags ("LI", stopList, 6); - } else if ("DT".equals (tagname) || "DD".equals (tagname)) { - closeOpenTags ("DT", stopDeflist, 6); - closeOpenTags ("DL", stopDeflist, 6); - } else if ("OPTION".equals (tagname)) { - closeOpenTags ("OPTION", stopNone, 1); - } else if ("P".equals (tagname)) { - closeOpenTags ("P", stopNone, 1); - } - stack.push (tagname); - try { - builder.startElement (tagname, attributes); - } catch (SAXException x) { - System.err.println ("Error in handleStartTag"); - } + // System.err.println ("handleStartTag ("+tag.getHTMLTag()+")"); + attributes.convert(getAttributes()); + flushAttributes(); + + String tagname = tag.getHTMLTag().toString().toUpperCase(); + + // immediately empty A anchor tag + if ("A".equals(tagname) && (attributes.getValue("href") == null)) { + try { + builder.startElement(tagname, attributes); + builder.endElement(tagname); + + return; + } catch (SAXException x) { + } + } + + if ("TD".equals(tagname)) { + closeOpenTags("TD", stopTable, 10); + } else if ("TR".equals(tagname)) { + closeOpenTags("TR", stopTable, 10); + } else if ("LI".equals(tagname)) { + closeOpenTags("LI", stopList, 6); + } else if ("DT".equals(tagname) || "DD".equals(tagname)) { + closeOpenTags("DT", stopDeflist, 6); + closeOpenTags("DL", stopDeflist, 6); + } else if ("OPTION".equals(tagname)) { + closeOpenTags("OPTION", stopNone, 1); + } else if ("P".equals(tagname)) { + closeOpenTags("P", stopNone, 1); + } + + stack.push(tagname); + + try { + builder.startElement(tagname, attributes); + } catch (SAXException x) { + System.err.println("Error in handleStartTag"); + } } /** * Handle End Tag. */ protected void handleEndTag(TagElement tag) { - // System.err.println ("handleEndTag ("+tag.getHTMLTag()+")"); - String tagname = tag.getHTMLTag().toString().toUpperCase(); - try { - if (tagname.equals (stack.peek ())) - stack.pop (); - } catch (EmptyStackException es) {} - try { - builder.endElement (tagname); - } catch (SAXException x) { - System.err.println ("Error in handleEndTag: "+x); - } - } + // System.err.println ("handleEndTag ("+tag.getHTMLTag()+")"); + String tagname = tag.getHTMLTag().toString().toUpperCase(); + try { + if (tagname.equals(stack.peek())) { + stack.pop(); + } + } catch (EmptyStackException es) { + } + + try { + builder.endElement(tagname); + } catch (SAXException x) { + System.err.println("Error in handleEndTag: " + x); + } + } /** * Handle Empty Tag. */ protected void handleEmptyTag(TagElement tag) { - // System.err.println ("handleEmptyTag ("+tag.getHTMLTag()+")"); - attributes.convert (getAttributes()); - flushAttributes(); - String tagname = tag.getHTMLTag().toString().toUpperCase(); - try { - builder.startElement (tagname, attributes); - builder.endElement (tagname); - } catch (SAXException x) { - System.err.println ("Error in handleEmptyTag: "+x); - } - } + // System.err.println ("handleEmptyTag ("+tag.getHTMLTag()+")"); + attributes.convert(getAttributes()); + flushAttributes(); + String tagname = tag.getHTMLTag().toString().toUpperCase(); + + try { + builder.startElement(tagname, attributes); + builder.endElement(tagname); + } catch (SAXException x) { + System.err.println("Error in handleEmptyTag: " + x); + } + } /** * Handle Text. */ - protected void handleText(char data[]) { - // System.err.println ("handleText ("+new String (data)+")"); - try { - builder.characters (data, 0, data.length); - } catch (SAXException x) { - System.err.println ("Error in handleText"); - } + protected void handleText(char[] data) { + // System.err.println ("handleText ("+new String (data)+")"); + try { + builder.characters(data, 0, data.length); + } catch (SAXException x) { + System.err.println("Error in handleText"); + } } /* * Error handling. */ protected void handleError(int ln, String errorMsg) { - // System.err.println ("handleError ("+ln+": "+errorMsg+")"); + // System.err.println ("handleError ("+ln+": "+errorMsg+")"); } /** * Handle comment. */ - protected void handleComment(char data[]) { - // System.err.println ("handleComment ("+new String (data)+")"); - /* try { - builder.characters (data, 0, data.length); - } catch (SAXException x) { - System.err.println ("Error in handleComment"); - }*/ + protected void handleComment(char[] data) { + // System.err.println ("handleComment ("+new String (data)+")"); + + /* try { + builder.characters (data, 0, data.length); + } catch (SAXException x) { + System.err.println ("Error in handleComment"); + }*/ } - public HTMLDocument getDocument () { - try { - builder.endDocument (); - } catch (SAXException x) {} - return builder.getHTMLDocument (); + /** + * + * + * @return ... + */ + public HTMLDocument getDocument() { + try { + builder.endDocument(); + } catch (SAXException x) { + } + + return builder.getHTMLDocument(); } - - private void closeOpenTags (String until, HashSet stoppers, int maxdepth) { - int l = stack.size(); - int stop = Math.max (0, l-maxdepth); - int found = -1; - for (int i=l-1; i>=stop; i--) { - Object o = stack.elementAt (i); - if (stoppers.contains (o)) - return; - if (until.equals (o)) { - found = i; - break; - } - } - if (found > -1) { - for (int i=l-1; i>=found; i--) { - try { - String t = (String) stack.pop (); - builder.endElement (t); - } catch (Exception x) {} - } - } + private void closeOpenTags(String until, HashSet stoppers, int maxdepth) { + int l = stack.size(); + int stop = Math.max(0, l - maxdepth); + int found = -1; + + for (int i = l - 1; i >= stop; i--) { + Object o = stack.elementAt(i); + + if (stoppers.contains(o)) { + return; + } + + if (until.equals(o)) { + found = i; + + break; + } + } + + if (found > -1) { + for (int i = l - 1; i >= found; i--) { + try { + String t = (String) stack.pop(); + + builder.endElement(t); + } catch (Exception x) { + } + } + } } class Attributes implements org.xml.sax.AttributeList { - HashMap map = new HashMap(); - ArrayList names = new ArrayList(); - ArrayList values = new ArrayList (); + HashMap map = new HashMap(); + ArrayList names = new ArrayList(); + ArrayList values = new ArrayList(); - public int getLength() { - return names.size(); - } + public int getLength() { + return names.size(); + } - public String getName (int i) { - return (String) names.get (i); - } + public String getName(int i) { + return (String) names.get(i); + } - public String getType (int i) { - return "CDATA"; - } + public String getType(int i) { + return "CDATA"; + } - public String getType (String name) { - return "CDATA"; - } + public String getType(String name) { + return "CDATA"; + } - public String getValue (int i) { - return (String) values.get (i); - } + public String getValue(int i) { + return (String) values.get(i); + } - public String getValue (String name) { - return (String) map.get (name); - } + public String getValue(String name) { + return (String) map.get(name); + } - public void convert (SimpleAttributeSet attset) { - map.clear (); - names.clear (); - values.clear (); - for (Enumeration e = attset.getAttributeNames(); e.hasMoreElements(); ) { - Object name = e.nextElement (); - Object value = attset.getAttribute (name).toString(); - name = name.toString().toLowerCase (); - map.put (name, value); - names.add (name); - values.add (value); - } - } + public void convert(SimpleAttributeSet attset) { + map.clear(); + names.clear(); + values.clear(); + for (Enumeration e = attset.getAttributeNames(); e.hasMoreElements();) { + Object name = e.nextElement(); + Object value = attset.getAttribute(name).toString(); + + name = name.toString().toLowerCase(); + map.put(name, value); + names.add(name); + values.add(value); + } + } } } - diff --git a/src/helma/util/InetAddressFilter.java b/src/helma/util/InetAddressFilter.java index 0ceaeccd..1bbc2138 100644 --- a/src/helma/util/InetAddressFilter.java +++ b/src/helma/util/InetAddressFilter.java @@ -1,5 +1,18 @@ -// InetAddressFilter.java -// Copyright (c) Hannes Wallnöfer 1998-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.util; @@ -10,47 +23,109 @@ import java.util.*; /** * A class for paranoid servers to filter IP addresses. */ - public class InetAddressFilter { + private Vector patterns; - Vector patterns; + /** + * Creates a new InetAddressFilter object. + */ + public InetAddressFilter() { + patterns = new Vector(); + } - public InetAddressFilter () { - patterns = new Vector (); + /** + * Addes an address template to the address filter. + * + * @param address The string representation of the IP address, either version 4 or 6. + * + * @throws IOException if the parameter does not represent a valid IP address + */ + public void addAddress(String address) throws IOException { + boolean v6 = false; + String separator = "."; + int length = 4; + int loop = 4; + + // check if this is a v4 or v6 IP address + if (address.indexOf(":") > -1) { + v6 = true; + separator = ":."; + length = 16; + loop = 8; + } + + int[] pattern = new int[length]; + + StringTokenizer st = new StringTokenizer(address, separator); + + if (st.countTokens() != loop) { + throw new IOException("\"" + address + + "\" does not represent a valid IP address"); + } + + for (int i = 0; i < loop; i++) { + String next = st.nextToken(); + + if (v6) { + if ("*".equals(next)) { + pattern[i*2] = pattern[i*2+1] = 256; + } else if (next.length() == 0) { + pattern[i*2] = pattern[i*2+1] = 0; + } else { + int n = Integer.parseInt(next, 16); + pattern[i*2] = (byte) ((n & 0xff00) >> 8); + pattern[i*2+1] = (byte) (n & 0xff); + } + } else { + if ("*".equals(next)) { + pattern[i] = 256; + } else { + pattern[i] = (byte) Integer.parseInt(next); + } + } + } + patterns.addElement(pattern); } - - public void addAddress (String address) throws IOException { - int pattern[] = new int[4]; - StringTokenizer st = new StringTokenizer (address, "."); - if (st.countTokens () != 4) - throw new IOException ("\""+address+"\" does not represent a valid IP address"); - for (int i=0; i<4; i++) { - String next = st.nextToken (); - if ("*".equals (next)) - pattern[i] = 256; - else - pattern[i] = (byte) Integer.parseInt (next); - } - patterns.addElement (pattern); - } - - public boolean matches (InetAddress address) { - if (address == null) - return false; - byte add[] = address.getAddress (); - if (add == null) - return false; - int l = patterns.size(); - for (int k=0; k<l; k++) { - int pattern[] = (int[]) patterns.elementAt (k); - for (int i=0; i<4; i++) { - if (pattern[i] < 255 && pattern[i] != add[i]) // not wildcard and doesn't match - break; - if (i == 3) - return true; - } - } - return false; + + /** + * Check if the given address matches any of our patterns + * + * @param address the ip address to match + * + * @return true if we find a match + */ + public boolean matches(InetAddress address) { + if (address == null) { + return false; + } + + byte[] add = address.getAddress(); + + if (add == null) { + return false; + } + + int l = patterns.size(); + + for (int k = 0; k < l; k++) { + int[] pattern = (int[]) patterns.elementAt(k); + + // is the address different version than pattern? + if (pattern.length != add.length) + continue; + + for (int i = 0; i < add.length; i++) { + if ((pattern[i] < 255) && (pattern[i] != add[i])) { + // not wildcard and doesn't match + break; + } + + if (i == add.length-1) { + return true; + } + } + } + + return false; } } - diff --git a/src/helma/util/Logger.java b/src/helma/util/Logger.java index 99a8cf70..de756d7f 100644 --- a/src/helma/util/Logger.java +++ b/src/helma/util/Logger.java @@ -1,25 +1,44 @@ -// Logger.java -// Copyright (c) Hannes Wallnöfer 1999-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.util; + import java.io.*; -import java.util.*; import java.text.*; +import java.util.*; import java.util.zip.GZIPOutputStream; /** * Utility class for asynchronous logging. */ - public final class Logger { - // we use one static thread for all Loggers static Runner runner; + // the list of active loggers static ArrayList loggers; + // hash map of loggers static HashMap loggerMap; + // fields for date rendering and caching + static DateFormat dformat = new SimpleDateFormat("[yyyy/MM/dd HH:mm] "); + static long dateLastRendered; + static String dateCache; + // buffer for log items private List entries; @@ -28,6 +47,7 @@ public final class Logger { private File logdir; private File logfile; private PrintWriter writer; + // the canonical name for this logger String canonicalName; @@ -37,380 +57,441 @@ public final class Logger { // flag to tell runner thread if this log should be closed/discarded boolean closed = false; - // fields for date rendering and caching - static DateFormat dformat = new SimpleDateFormat ("[yyyy/MM/dd HH:mm] "); - static long dateLastRendered; - static String dateCache; // number format for log file rotation - DecimalFormat nformat = new DecimalFormat ("000"); - DateFormat aformat = new SimpleDateFormat ("yyyy-MM-dd"); - - + DecimalFormat nformat = new DecimalFormat("000"); + DateFormat aformat = new SimpleDateFormat("yyyy-MM-dd"); /** * Create a logger for a PrintStream, such as System.out. */ - public Logger (PrintStream out) { - this.out = out; - canonicalName = out.toString (); + public Logger(PrintStream out) { + this.out = out; + canonicalName = out.toString(); - // create a synchronized list for log entries since different threads may - // attempt to modify the list at the same time - entries = Collections.synchronizedList (new LinkedList ()); + // create a synchronized list for log entries since different threads may + // attempt to modify the list at the same time + entries = Collections.synchronizedList(new LinkedList()); - // register this instance with static logger list - start (this); + // register this instance with static logger list + start(this); } /** * Create a file logger. The actual file names do have numbers appended and are * rotated every x bytes. */ - private Logger (String dirname, String filename) { - this.filename = filename; - logdir = new File (dirname); - logfile = new File (logdir, filename+".log"); + private Logger(String dirname, String filename) { + this.filename = filename; + logdir = new File(dirname); + logfile = new File(logdir, filename + ".log"); - try { - canonicalName = logfile.getCanonicalPath (); - } catch (IOException iox) { - canonicalName = logfile.getAbsolutePath (); - } + try { + canonicalName = logfile.getCanonicalPath(); + } catch (IOException iox) { + canonicalName = logfile.getAbsolutePath(); + } - if (!logdir.exists()) - logdir.mkdirs (); + if (!logdir.exists()) { + logdir.mkdirs(); + } - try { - if (logfile.exists () && logfile.lastModified () < lastMidnight ()) { - // rotate if a log file exists and is NOT from today - rotateLogFile (); - } else { - // create a new log file, append to an existing file - writer = new PrintWriter (new FileWriter (logfile.getAbsolutePath(), true), false); - } - } catch (IOException iox) { - System.err.println ("Error creating log "+canonicalName+": "+iox); - } + try { + if (logfile.exists() && (logfile.lastModified() < lastMidnight())) { + // rotate if a log file exists and is NOT from today + rotateLogFile(); + } else { + // create a new log file, append to an existing file + writer = new PrintWriter(new FileWriter(logfile.getAbsolutePath(), true), + false); + } + } catch (IOException iox) { + System.err.println("Error creating log " + canonicalName + ": " + iox); + } - // create a synchronized list for log entries since different threads may - // attempt to modify the list at the same time - entries = Collections.synchronizedList (new LinkedList ()); + // create a synchronized list for log entries since different threads may + // attempt to modify the list at the same time + entries = Collections.synchronizedList(new LinkedList()); - // register this instance with static logger list - start (this); + // register this instance with static logger list + start(this); } - /** * Get a logger with a symbolic file name within a directory. */ - public static synchronized Logger getLogger (String dirname, String filename) { - if (filename == null || dirname == null) - throw new RuntimeException ("Logger can't use null as file or directory name"); - File file = new File (dirname, filename+".log"); - Logger log = null; - if (loggerMap != null) try { - log = (Logger) loggerMap.get (file.getCanonicalPath()); - } catch (IOException iox) { - log = (Logger) loggerMap.get (file.getAbsolutePath()); - } - if (log == null || log.isClosed ()) - log = new Logger (dirname, filename); - return log; - } + public static synchronized Logger getLogger(String dirname, String filename) { + if ((filename == null) || (dirname == null)) { + throw new RuntimeException("Logger can't use null as file or directory name"); + } + File file = new File(dirname, filename + ".log"); + Logger log = null; + + if (loggerMap != null) { + try { + log = (Logger) loggerMap.get(file.getCanonicalPath()); + } catch (IOException iox) { + log = (Logger) loggerMap.get(file.getAbsolutePath()); + } + } + + if ((log == null) || log.isClosed()) { + log = new Logger(dirname, filename); + } + + return log; + } /** * Append a message to the log. */ - public void log (String msg) { - // if we are closed, drop message without further notice - if (closed) - return; - // it's enough to render the date every 5 seconds - if (System.currentTimeMillis () - 5000 > dateLastRendered) - renderDate (); - entries.add (dateCache + msg); + public void log(String msg) { + // if we are closed, drop message without further notice + if (closed) { + return; + } + + // it's enough to render the date every 5 seconds + if ((System.currentTimeMillis() - 5000) > dateLastRendered) { + renderDate(); + } + + entries.add(dateCache + msg); } - private static synchronized void renderDate () { - dateLastRendered = System.currentTimeMillis (); - dateCache = dformat.format (new Date()); + private static synchronized void renderDate() { + dateLastRendered = System.currentTimeMillis(); + dateCache = dformat.format(new Date()); } - /** * Return an object which identifies this logger. */ - public String getCanonicalName () { - return canonicalName; + public String getCanonicalName() { + return canonicalName; } - /** * Get the list of unwritten entries */ - public List getEntries () { - return entries; + public List getEntries() { + return entries; } /** * This is called by the runner thread to perform actual output. */ - public void write () { - if (entries.isEmpty ()) - return; - try { + public void write() { + if (entries.isEmpty()) { + return; + } - int l = entries.size(); + try { + int l = entries.size(); - // check if writing to printstream or file - if (out != null) { - for (int i=0; i<l; i++) { - String entry = (String) entries.get (0); - entries.remove (0); - out.println (entry); - } - } else { - if (writer == null || !logfile.exists() || !logfile.canWrite()) { - // rotate the log file if we can't write to it - rotateLogFile (); - } - for (int i=0; i<l; i++) { - String entry = (String) entries.get (0); - entries.remove (0); - writer.println (entry); - } - writer.flush (); - } + // check if writing to printstream or file + if (out != null) { + for (int i = 0; i < l; i++) { + String entry = (String) entries.get(0); - } catch (Exception x) { - int e = entries.size(); - if (e > 1000) { - // more than 1000 entries queued plus exception - something - // is definitely wrong with this logger. Write a message to std err and - // discard queued log entries. - System.err.println ("Error writing log file "+this+": "+x); - System.err.println ("Discarding "+e+" log entries."); - entries.clear (); - } - } + entries.remove(0); + out.println(entry); + } + } else { + if ((writer == null) || !logfile.exists() || !logfile.canWrite()) { + // rotate the log file if we can't write to it + rotateLogFile(); + } + + for (int i = 0; i < l; i++) { + String entry = (String) entries.get(0); + + entries.remove(0); + writer.println(entry); + } + + writer.flush(); + } + } catch (Exception x) { + int e = entries.size(); + + if (e > 1000) { + // more than 1000 entries queued plus exception - something + // is definitely wrong with this logger. Write a message to std err and + // discard queued log entries. + System.err.println("Error writing log file " + this + ": " + x); + System.err.println("Discarding " + e + " log entries."); + entries.clear(); + } + } } /** * Rotate log files, closing, renaming and gzipping the old file and * start a new one. */ - private void rotateLogFile () throws IOException { - // if the logger is not file based do nothing. - if (logfile == null) - return; - if (writer != null) try { - writer.close(); - } catch (Exception ignore) {} - // only backup/rotate if the log file is not empty, - if (logfile.exists() && logfile.length() > 0) { - String today = aformat.format(new Date()); - int ct=0; - File archive = null; - // first append just the date - String archname = filename+"-"+today+".log.gz"; - while (archive==null || archive.exists()) { - archive = new File (logdir, archname); - // for the next try we append a counter - String archidx = ct>999 ? Integer.toString(ct) : nformat.format (++ct); - archname = filename+"-"+today+"-"+ archidx +".log.gz"; - } - if (logfile.renameTo (archive)) - (new GZipper(archive)).start(); - else - System.err.println ("Error rotating log file "+canonicalName+". Old file will possibly be overwritten!"); - } - writer = new PrintWriter (new FileWriter (logfile), false); + private void rotateLogFile() throws IOException { + // if the logger is not file based do nothing. + if (logfile == null) { + return; + } + + if (writer != null) { + try { + writer.close(); + } catch (Exception ignore) { + } + } + + // only backup/rotate if the log file is not empty, + if (logfile.exists() && (logfile.length() > 0)) { + String today = aformat.format(new Date()); + int ct = 0; + File archive = null; + + // first append just the date + String archname = filename + "-" + today + ".log.gz"; + + while ((archive == null) || archive.exists()) { + archive = new File(logdir, archname); + + // for the next try we append a counter + String archidx = (ct > 999) ? Integer.toString(ct) : nformat.format(++ct); + + archname = filename + "-" + today + "-" + archidx + ".log.gz"; + } + + if (logfile.renameTo(archive)) { + (new GZipper(archive)).start(); + } else { + System.err.println("Error rotating log file " + canonicalName + + ". Old file will possibly be overwritten!"); + } + } + + writer = new PrintWriter(new FileWriter(logfile), false); } /** * Tell whether this log is closed. */ - public boolean isClosed () { - return closed; + public boolean isClosed() { + return closed; } /** * Tells a log to close down. Only the flag is set, the actual closing is * done by the runner thread next time it comes around. */ - public void close () { - this.closed = true; + public void close() { + this.closed = true; } /** * Actually closes the file writer of a log. */ - void closeFiles () { - if (writer != null) try { - writer.close (); - } catch (Exception ignore) {} + void closeFiles() { + if (writer != null) { + try { + writer.close(); + } catch (Exception ignore) { + } + } } /** * Return a string representation of this Logger */ - public String toString () { - return "Logger["+canonicalName+"]"; + public String toString() { + return "Logger[" + canonicalName + "]"; } - /** * Add a log to the list of logs and * create and start the runner thread if necessary. */ - static synchronized void start (Logger log) { - if (loggers == null) - loggers = new ArrayList (); - if (loggerMap == null) - loggerMap = new HashMap (); + static synchronized void start(Logger log) { + if (loggers == null) { + loggers = new ArrayList(); + } - loggers.add (log); - loggerMap.put (log.canonicalName, log); + if (loggerMap == null) { + loggerMap = new HashMap(); + } - if (runner == null || !runner.isAlive ()) { - runner = new Runner (); - runner.start (); - } + loggers.add(log); + loggerMap.put(log.canonicalName, log); + + if ((runner == null) || !runner.isAlive()) { + runner = new Runner(); + runner.start(); + } } /** * Return a list of all active Loggers */ - public static List getLoggers () { - if (loggers == null) - return null; - return (List) loggers.clone (); + public static List getLoggers() { + if (loggers == null) { + return null; + } + + return (List) loggers.clone(); } - /** + /** * Notify the runner thread that it should wake up and run. */ - public static void wakeup () { - if (runner != null) - runner.wakeup (); + public static void wakeup() { + if (runner != null) { + runner.wakeup(); + } } - private static void rotateAllLogs () { - int nloggers = loggers.size(); - for (int i=nloggers-1; i>=0; i--) { - Logger log = (Logger) loggers.get (i); - try { - log.rotateLogFile (); - } catch (IOException io) { - System.err.println ("Error rotating log " + log.getCanonicalName() + ": " + io.toString ()); - } - } + private static void rotateAllLogs() { + int nloggers = loggers.size(); + + for (int i = nloggers - 1; i >= 0; i--) { + Logger log = (Logger) loggers.get(i); + + try { + log.rotateLogFile(); + } catch (IOException io) { + System.err.println("Error rotating log " + log.getCanonicalName() + ": " + + io.toString()); + } + } + } + + /** + * + * + * @return ... + */ + public static long nextMidnight() { + Calendar cal = Calendar.getInstance(); + + cal.set(Calendar.DATE, 1 + cal.get(Calendar.DATE)); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 1); + + // for testing, rotate the logs every minute: + // cal.set (Calendar.MINUTE, 1 + cal.get(Calendar.MINUTE)); + return cal.getTime().getTime(); + } + + /** + * + * + * @return ... + */ + public static long lastMidnight() { + return nextMidnight() - 86400000; + } + + /** + * test main method + */ + public static void main(String[] args) throws IOException { + Logger log = new Logger(".", "testlog"); + long start = System.currentTimeMillis(); + + for (int i = 0; i < 1000; i++) { + log.log("test log entry " + i); + + try { + Thread.sleep(100); + } catch (InterruptedException ie) { + } + } + + log.log("done: " + (System.currentTimeMillis() - start)); + System.err.println(System.currentTimeMillis() - start); + log.close(); + + // System.exit (0); } /** * The static runner class that loops through all loggers. */ static class Runner extends Thread { + public synchronized void run() { + long nextMidnight = nextMidnight(); - public synchronized void run () { - long nextMidnight = nextMidnight (); - while (runner == this && !isInterrupted ()) { - if (nextMidnight < System.currentTimeMillis ()) { - rotateAllLogs (); - nextMidnight = nextMidnight (); - } - int nloggers = loggers.size(); - for (int i=nloggers-1; i>=0; i--) { - try { - Logger log = (Logger) loggers.get (i); - log.write (); - if (log.closed && log.entries.isEmpty()) { - loggers.remove (log); - log.closeFiles (); - } - } catch (Exception x) { - System.err.println ("Error in Logger main loop: "+x); - } - } - // if there are no active logs, exit logger thread - if (loggers.size() == 0) - return; - try { - wait (250); - } catch (InterruptedException ix) {} - } - } - - public synchronized void wakeup () { - notifyAll (); - } + while ((runner == this) && !isInterrupted()) { + if (nextMidnight < System.currentTimeMillis()) { + rotateAllLogs(); + nextMidnight = nextMidnight(); + } + int nloggers = loggers.size(); + + for (int i = nloggers - 1; i >= 0; i--) { + try { + Logger log = (Logger) loggers.get(i); + + log.write(); + + if (log.closed && log.entries.isEmpty()) { + loggers.remove(log); + log.closeFiles(); + } + } catch (Exception x) { + System.err.println("Error in Logger main loop: " + x); + } + } + + // if there are no active logs, exit logger thread + if (loggers.size() == 0) { + return; + } + + try { + wait(250); + } catch (InterruptedException ix) { + } + } + } + + public synchronized void wakeup() { + notifyAll(); + } } /** * a Thread class that zips up a file, filename will stay the same. */ - class GZipper extends Thread { - File file, temp; - public GZipper (File file) { - this.file = file; - this.temp = new File (file.getAbsolutePath()+".tmp"); - } + class GZipper extends Thread { + File file; + File temp; - public void run() { - long start = System.currentTimeMillis(); - try { - GZIPOutputStream zip = new GZIPOutputStream( new FileOutputStream(temp)); - BufferedInputStream in = new BufferedInputStream(new FileInputStream(file)); - byte[] b = new byte[1024]; - int len = 0; - while( (len=in.read(b,0,1024))!=-1 ) { - zip.write(b,0,len); - } - zip.close(); - in.close(); - file.delete(); - temp.renameTo(file); - } catch ( Exception e ) { - System.err.println (e.toString()); - } - } + public GZipper(File file) { + this.file = file; + this.temp = new File(file.getAbsolutePath() + ".tmp"); + } + + public void run() { + long start = System.currentTimeMillis(); + + try { + GZIPOutputStream zip = new GZIPOutputStream(new FileOutputStream(temp)); + BufferedInputStream in = new BufferedInputStream(new FileInputStream(file)); + byte[] b = new byte[1024]; + int len = 0; + + while ((len = in.read(b, 0, 1024)) != -1) { + zip.write(b, 0, len); + } + + zip.close(); + in.close(); + file.delete(); + temp.renameTo(file); + } catch (Exception e) { + System.err.println(e.toString()); + } + } } - - - public static long nextMidnight () { - Calendar cal = Calendar.getInstance (); - cal.set (Calendar.DATE, 1 + cal.get(Calendar.DATE)); - cal.set (Calendar.HOUR_OF_DAY, 0); - cal.set (Calendar.MINUTE, 0); - cal.set (Calendar.SECOND, 1); - // for testing, rotate the logs every minute: - // cal.set (Calendar.MINUTE, 1 + cal.get(Calendar.MINUTE)); - return cal.getTime().getTime (); - } - - public static long lastMidnight () { - return nextMidnight () - 86400000; - } - - /** - * test main method - */ - public static void main (String[] args) throws IOException { - Logger log = new Logger (".", "testlog"); - long start = System.currentTimeMillis (); - for (int i=0; i<1000; i++) { - log.log ("test log entry "+i); - try { - Thread.sleep(100); - } catch (InterruptedException ie) { } - } - log.log ("done: "+(System.currentTimeMillis () - start)); - System.err.println (System.currentTimeMillis () - start); - log.close (); - // System.exit (0); - } - } diff --git a/src/helma/util/Logo.java b/src/helma/util/Logo.java index 6464b8ea..bbddbab8 100644 --- a/src/helma/util/Logo.java +++ b/src/helma/util/Logo.java @@ -1,3 +1,19 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.util; import java.io.FileInputStream; @@ -5,87 +21,151 @@ import java.io.FileInputStream; /** * class with byte data of helma logo */ +public class Logo { + public static final byte[] hop = { + 71, 73, 70, 56, 57, 97, -82, 0, 35, 0, -60, 0, 0, + -1, -1, -1, -17, -17, -17, -33, -33, -33, -52, + -52, -52, -67, -67, -67, -84, -84, -84, -103, + -103, -103, -119, -119, -119, 120, 120, 120, 102, + 102, 102, 84, 84, 84, 67, 67, 67, 51, 51, 51, 33, + 33, 33, 18, 18, 18, 0, 0, 0, -2, 1, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 33, -7, 4, 4, 20, 0, -1, 0, + 44, 0, 0, 0, 0, -82, 0, 35, 0, 0, 5, -1, 32, 32, + -114, 100, 105, -98, 104, -86, -82, 108, -21, -66, + 112, 44, -49, 116, 109, -33, 120, -82, -45, -61, + -79, 52, -114, 96, 67, 113, 24, -20, -114, -56, + -92, -78, 21, 32, 32, 22, -63, -121, 116, 74, 109, + 44, -118, -127, -91, 118, -53, 125, 5, 122, 63, 7, + 117, 76, -106, 58, -84, -40, -82, 122, -83, 28, + 24, -62, -27, -72, -4, 113, 78, 20, -78, -20, -68, + -34, 21, 40, 36, 24, 98, 115, -126, -126, 14, 12, + 8, 4, 120, 123, -118, 122, 2, 5, 10, -127, -125, + -111, -111, 117, -120, -117, -106, 92, 5, -128, + -110, -101, -100, -123, 4, -105, -96, 72, 4, 64, + -100, -91, -110, 103, 70, -95, -86, 55, 9, -112, + 83, 12, 11, 12, -111, 86, 11, -90, 100, 14, 9, 47, + 4, 4, 2, 57, 77, -107, 55, -69, -67, 36, -65, + -119, 42, 2, -69, 54, -78, 100, -97, 4, -111, 8, + 34, -74, 100, 12, 47, 82, -48, 36, -50, 15, -97, + -70, 82, -37, 54, -42, 37, -39, -37, -75, 11, 40, + 8, 82, 54, -82, 83, 34, -25, -125, -51, -46, 99, + 14, 46, -30, 37, -19, -58, 44, -19, 56, -12, 36, + -7, -47, 15, -41, 38, -56, -91, -101, 38, 34, -63, + -126, 90, 85, -96, 76, -55, 114, 96, -116, -107, + 6, 15, -84, -72, 114, 112, 80, -99, -68, 19, -55, + 70, 52, 124, 48, -128, -41, 8, 100, -34, 0, 16, + 72, -11, 17, 24, 0, 5, 15, -88, -1, -91, 64, 118, + -49, -60, -58, -114, -61, 78, -90, 28, 33, -116, + -90, 55, 49, 9, 58, -34, 27, 105, -94, 35, 9, 117, + 15, 114, 1, -64, 51, -64, 76, 1, 17, 1, 106, 53, + 40, 40, -91, -41, -80, 0, 6, -112, 66, 124, 112, + -128, 4, -54, 41, 23, 73, 24, 8, -60, 0, 79, 2, + 51, 82, -114, 2, -112, -91, 64, 68, -127, 64, 101, + -121, 34, 116, 96, 100, -86, 20, -110, 34, 32, 78, + 117, -48, -53, 64, 83, 1, 82, -86, 126, -91, 19, + 54, 110, 80, 17, 118, 57, 2, 24, 48, 87, 0, 94, + -66, 116, -122, -99, -107, -110, 86, -82, -108, + 68, 64, -85, 2, 64, -112, 10, -30, 81, 3, -48, + -20, -90, -107, 117, -111, 64, 84, 0, 5, -60, -18, + 69, -96, 96, 65, -81, 108, 102, -62, -47, 41, 0, + 81, -78, -84, 6, 8, -60, -108, 3, 0, -82, -88, 3, + -42, 15, 122, -43, -6, -13, 15, -76, -75, -112, + 67, -91, 44, 24, 61, -103, -114, 111, 109, 99, 35, + -58, 126, 80, 46, 64, 94, 118, -24, 0, -120, 65, + 32, -117, 64, 1, 41, 9, -82, 70, -75, -115, 91, + -128, -13, -120, 7, 127, 50, 19, -39, -101, -10, + 108, -118, -28, -81, 9, 23, 17, 30, 64, 123, -124, + -122, 14, -111, -57, 90, -94, 22, 52, -5, -2, -96, + -111, -99, -1, 9, 127, -83, 93, -113, 61, 17, -43, + 62, -40, 116, -13, 93, 85, 2, -11, 3, -50, -1, + 126, -5, 8, -108, -51, 23, -120, -28, 67, -113, + 127, -38, 16, 56, 2, 80, 34, 52, -12, 73, 81, 81, + 5, 32, -33, 57, 27, -126, 35, -35, 53, 14, -112, + 72, 85, 9, 27, -91, -10, 81, 95, -32, 100, 115, + 20, 56, 27, 5, 112, -104, 2, -7, 124, -91, -46, 8, + -3, -44, -13, 24, 61, -32, -44, 66, -115, -117, + -76, -11, 102, 79, 126, -13, 1, -28, 99, 113, 15, + -56, -56, 88, 62, 67, -106, -96, -114, 74, 95, + 101, 97, 87, 76, 76, -43, -43, 23, 94, 71, 97, 9, + 0, 94, 42, 61, -63, 20, 125, 35, 4, -10, 69, 95, + 27, 9, 80, -44, 3, 71, 125, -75, 84, 96, 83, 44, + 5, -111, 80, 35, -96, 116, -93, 85, 17, 1, 16, + -29, -103, 71, -31, 100, 103, 83, 120, 2, -96, + -90, 8, 103, 118, 24, -56, 103, 122, -94, -76, + -90, 67, 50, 45, 101, -126, 58, 66, 49, -96, 104, + 108, -48, -127, -39, 78, 47, -41, 81, -102, -101, + 111, 85, 57, -41, 40, 21, 89, 21, 39, 79, 96, -67, + -4, 9, 106, 114, 101, -99, -45, -23, -127, 37, + -68, 121, 2, 68, 101, -119, 122, -41, 115, -82, + 94, -70, 31, 0, -127, -91, 18, 24, 93, -121, 85, + -59, -86, -89, -87, 62, -112, -106, -109, 99, 72, + -26, 43, 123, -77, 33, -76, -98, 123, -58, 77, + 118, 17, -92, -59, -67, -93, 30, -89, 36, 36, 88, + 39, -87, -59, 41, -38, 35, -1, 115, 5, 34, 55, 2, + -86, 37, 124, -89, -33, 95, -90, 30, -9, -55, 126, + -25, 88, 91, 94, -114, 72, 90, 103, -32, -75, -77, + 33, 37, 34, -80, 84, 56, 27, -51, 121, -80, -31, + 23, 100, -79, -8, -78, 119, 41, -120, -13, -127, + -87, 47, 52, 16, 61, -5, 109, 46, 19, -10, -122, + -39, 124, 125, 32, 112, 90, 55, 38, -120, -13, 93, + 84, -46, 62, 64, -92, 44, 4, 51, -116, 108, 57, 2, + 32, 16, 85, 55, 18, 50, -116, -33, -63, 22, 94, + 56, 70, -122, -56, -99, 41, 101, 91, 104, -118, + 32, 11, -119, 44, -117, 32, -58, 81, 61, 48, 20, + 15, 9, 13, 13, -111, 82, 22, -39, 40, -16, 21, 93, + 123, 38, -71, 39, 108, 127, 121, 123, -122, 8, + -39, 32, 112, 79, 59, 6, -51, -124, 44, 115, 98, + -4, -56, -40, -50, -67, 108, 36, 108, 111, -50, + -40, 76, -51, -111, 67, -42, 124, 78, 46, 77, -62, + 43, 5, -108, 62, 7, -106, 64, 22, 3, 92, -107, + -106, 93, 89, -90, -84, -27, 97, 12, -100, -106, + -59, 94, 109, 18, -77, -13, -40, 36, 59, -102, 82, + 42, 127, -86, 69, 7, -35, -76, -54, -106, 74, 82, + 77, -107, -128, 18, 90, -61, 108, -107, -46, 110, + 123, -38, -51, 64, 42, 2, -120, -79, 84, -96, 34, + -104, -99, 69, -95, -45, 2, -114, 75, 22, -122, + -94, -32, 22, 60, -100, -113, 49, 103, 12, -86, + -22, -80, -21, 125, 42, 48, 40, -44, -7, -23, 123, + -53, 32, 0, 3, -100, -63, 101, 3, -73, -92, -69, + 112, -64, -26, -88, -37, -30, -119, 12, 3, 28, + -108, -45, 14, -71, 47, -32, 122, -20, 43, 32, 64, + 74, -19, -90, 20, 34, 22, -16, -56, -65, -48, + -120, -23, -60, 15, 66, -111, 1, 45, 37, 47, -3, + 10, -115, 40, 48, 124, -13, 85, 40, 80, 0, -107, + -45, 119, -17, -123, 19, -102, -44, 94, -56, 33, + -47, 123, 111, -2, -9, -44, 69, 81, -54, -8, -37, + -97, -17, -66, 14, 77, 60, -95, 126, 28, 20, -111, + -1, -2, -3, 109, 28, -96, 0, 32, 66, 16, 49, 64, + -7, -8, 11, -96, 0, 7, -56, -122, 16, 0, 0, 59 + }; -public class Logo { + /** + * utitilty function to create byte array from file + */ + public static void main(String[] args) throws Exception { + FileInputStream fis = new FileInputStream(args[0]); + byte[] b = new byte[256]; + int linect = 0; + int ct = 0; - public static final byte hop[] = { - 71, 73,70,56,57,97,-82,0,35,0,-60,0,0,-1,-1,-1,-17,-17,-17,-33,-33,-33,-52,-52,-52,-67, - -67,-67,-84,-84,-84,-103,-103,-103,-119,-119,-119,120,120,120,102,102,102,84,84,84,67, - 67,67,51,51,51,33,33,33,18,18,18,0,0,0,-2,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,33,-7,4,4,20,0,-1,0,44,0,0,0,0,-82,0, - 35,0,0,5,-1,32,32,-114,100,105,-98,104,-86,-82,108,-21,-66,112,44,-49,116,109,-33,120, - -82,-45,-61,-79,52,-114,96,67,113,24,-20,-114,-56,-92,-78,21,32,32,22,-63,-121,116,74, - 109,44,-118,-127,-91,118,-53,125,5,122,63,7,117,76,-106,58,-84,-40,-82,122,-83,28,24, - -62,-27,-72,-4,113,78,20,-78,-20,-68,-34,21,40,36,24,98,115,-126,-126,14,12,8,4,120,123, - -118,122,2,5,10,-127,-125,-111,-111,117,-120,-117,-106,92,5,-128,-110,-101,-100,-123,4, - -105,-96,72,4,64,-100,-91,-110,103,70,-95,-86,55,9,-112,83,12,11,12,-111,86,11,-90,100, - 14,9,47,4,4,2,57,77,-107,55,-69,-67,36,-65,-119,42,2,-69,54,-78,100,-97,4,-111,8,34,-74, - 100,12,47,82,-48,36,-50,15,-97,-70,82,-37,54,-42,37,-39,-37,-75,11,40,8,82,54,-82,83,34, - -25,-125,-51,-46,99,14,46,-30,37,-19,-58,44,-19,56,-12,36,-7,-47,15,-41,38,-56,-91,-101, - 38,34,-63,-126,90,85,-96,76,-55,114,96,-116,-107,6,15,-84,-72,114,112,80,-99,-68,19,-55, - 70,52,124,48,-128,-41,8,100,-34,0,16,72,-11,17,24,0,5,15,-88,-1,-91,64,118,-49,-60,-58, - -114,-61,78,-90,28,33,-116,-90,55,49,9,58,-34,27,105,-94,35,9,117,15,114,1,-64,51,-64, - 76,1,17,1,106,53,40,40,-91,-41,-80,0,6,-112,66,124,112,-128,4,-54,41,23,73,24,8,-60,0, - 79,2,51,82,-114,2,-112,-91,64,68,-127,64,101,-121,34,116,96,100,-86,20,-110,34,32,78, - 117,-48,-53,64,83,1,82,-86,126,-91,19,54,110,80,17,118,57,2,24,48,87,0,94,-66,116,-122, - -99,-107,-110,86,-82,-108,68,64,-85,2,64,-112,10,-30,81,3,-48,-20,-90,-107,117,-111,64, - 84,0,5,-60,-18,69,-96,96,65,-81,108,102,-62,-47,41,0,81,-78,-84,6,8,-60,-108,3,0,-82, - -88,3,-42,15,122,-43,-6,-13,15,-76,-75,-112,67,-91,44,24,61,-103,-114,111,109,99,35, - -58,126,80,46,64,94,118,-24,0,-120,65,32,-117,64,1,41,9,-82,70,-75,-115,91,-128,-13, - -120,7,127,50,19,-39,-101,-10,108,-118,-28,-81,9,23,17,30,64,123,-124,-122,14,-111, - -57,90,-94,22,52,-5,-2,-96,-111,-99,-1,9,127,-83,93,-113,61,17,-43,62,-40,116,-13,93, - 85,2,-11,3,-50,-1,126,-5,8,-108,-51,23,-120,-28,67,-113,127,-38,16,56,2,80,34,52,-12, - 73,81,81,5,32,-33,57,27,-126,35,-35,53,14,-112,72,85,9,27,-91,-10,81,95,-32,100,115, - 20,56,27,5,112,-104,2,-7,124,-91,-46,8,-3,-44,-13,24,61,-32,-44,66,-115,-117,-76,-11, - 102,79,126,-13,1,-28,99,113,15,-56,-56,88,62,67,-106,-96,-114,74,95,101,97,87,76,76, - -43,-43,23,94,71,97,9,0,94,42,61,-63,20,125,35,4,-10,69,95,27,9,80,-44,3,71,125,-75, - 84,96,83,44,5,-111,80,35,-96,116,-93,85,17,1,16,-29,-103,71,-31,100,103,83,120,2,-96, - -90,8,103,118,24,-56,103,122,-94,-76,-90,67,50,45,101,-126,58,66,49,-96,104,108,-48, - -127,-39,78,47,-41,81,-102,-101,111,85,57,-41,40,21,89,21,39,79,96,-67,-4,9,106,114, - 101,-99,-45,-23,-127,37,-68,121,2,68,101,-119,122,-41,115,-82,94,-70,31,0,-127,-91, - 18,24,93,-121,85,-59,-86,-89,-87,62,-112,-106,-109,99,72,-26,43,123,-77,33,-76,-98, - 123,-58,77,118,17,-92,-59,-67,-93,30,-89,36,36,88,39,-87,-59,41,-38,35,-1,115,5,34, - 55,2,-86,37,124,-89,-33,95,-90,30,-9,-55,126,-25,88,91,94,-114,72,90,103,-32,-75,-77, - 33,37,34,-80,84,56,27,-51,121,-80,-31,23,100,-79,-8,-78,119,41,-120,-13,-127,-87,47, - 52,16,61,-5,109,46,19,-10,-122,-39,124,125,32,112,90,55,38,-120,-13,93,84,-46,62,64, - -92,44,4,51,-116,108,57,2,32,16,85,55,18,50,-116,-33,-63,22,94,56,70,-122,-56,-99,41, - 101,91,104,-118,32,11,-119,44,-117,32,-58,81,61,48,20,15,9,13,13,-111,82,22,-39,40, - -16,21,93,123,38,-71,39,108,127,121,123,-122,8,-39,32,112,79,59,6,-51,-124,44,115, - 98,-4,-56,-40,-50,-67,108,36,108,111,-50,-40,76,-51,-111,67,-42,124,78,46,77,-62,43, - 5,-108,62,7,-106,64,22,3,92,-107,-106,93,89,-90,-84,-27,97,12,-100,-106,-59,94,109, - 18,-77,-13,-40,36,59,-102,82,42,127,-86,69,7,-35,-76,-54,-106,74,82,77,-107,-128,18, - 90,-61,108,-107,-46,110,123,-38,-51,64,42,2,-120,-79,84,-96,34,-104,-99,69,-95,-45,2, - -114,75,22,-122,-94,-32,22,60,-100,-113,49,103,12,-86,-22,-80,-21,125,42,48,40,-44, - -7,-23,123,-53,32,0,3,-100,-63,101,3,-73,-92,-69,112,-64,-26,-88, -37,-30,-119,12,3, - 28,-108,-45,14,-71,47,-32,122,-20,43,32,64,74,-19,-90,20,34,22,-16,-56,-65,-48,-120, - -23,-60,15,66,-111,1,45,37,47,-3,10,-115,40,48,124,-13,85,40,80,0,-107,-45,119,-17, - -123,19,-102,-44,94,-56,33,-47,123,111,-2,-9,-44,69,81,-54,-8,-37,-97,-17,-66,14,77, - 60,-95,126,28,20,-111,-1,-2,-3,109,28,-96,0,32,66,16,49,64,-7,-8,11,-96,0,7,-56,-122, - 16,0,0,59 - }; + System.out.print("\n\n\n static byte[] image = {\n "); - /** - * utitilty function to create byte array from file - */ - public static void main ( String args[] ) throws Exception { - FileInputStream fis = new FileInputStream ( args[0] ); - byte[] b = new byte[256]; - int linect=0, ct=0; - System.out.print( "\n\n\n static byte[] image = {\n "); - while ( ct>-1 ) { - ct = fis.read(b); - for ( int i=0; i<ct; i++ ) { - System.out.print( b[i] + "," ); - linect++; - if ( linect>30 ) { - linect=0; - System.out.print("\n "); - } - } - } - System.out.print( " };\n\n\n"); + while (ct > -1) { + ct = fis.read(b); - } + for (int i = 0; i < ct; i++) { + System.out.print(b[i] + ","); + linect++; + if (linect > 30) { + linect = 0; + System.out.print("\n "); + } + } + } + System.out.print(" };\n\n\n"); + } } diff --git a/src/helma/util/MD5Encoder.java b/src/helma/util/MD5Encoder.java index df82f7a2..ee4e5a96 100644 --- a/src/helma/util/MD5Encoder.java +++ b/src/helma/util/MD5Encoder.java @@ -1,47 +1,91 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.util; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; - +/** + * + */ public class MD5Encoder { - private static MessageDigest md; - /** used by commandline script to create admin username & password */ - public static void main ( String args[] ) throws Exception { - if ( args.length < 2 ) { - System.out.println( "\n\nUsage: helma.util.MD5Encoder <username> <password>"); - System.out.println( "Output:"); - System.out.println( "adminUsername=<encoded username>"); - System.out.println( "adminPassword=<encoded password>\n"); + /** used by commandline script to create admin username & password */ + public static void main(String[] args) throws Exception { + if (args.length < 2) { + System.out.println("\n\nUsage: helma.util.MD5Encoder <username> <password>"); + System.out.println("Output:"); + System.out.println("adminUsername=<encoded username>"); + System.out.println("adminPassword=<encoded password>\n"); System.exit(0); } - System.out.println( "adminUsername=" + encode(args[0]) ); - System.out.println( "adminPassword=" + encode(args[1]) ); + + System.out.println("adminUsername=" + encode(args[0])); + System.out.println("adminPassword=" + encode(args[1])); } + /** + * + * + * @param str ... + * + * @return ... + * + * @throws NoSuchAlgorithmException ... + */ public static String encode(String str) throws NoSuchAlgorithmException { - return encode (str.getBytes()); + return encode(str.getBytes()); } + /** + * + * + * @param message ... + * + * @return ... + * + * @throws NoSuchAlgorithmException ... + */ public static String encode(byte[] message) throws NoSuchAlgorithmException { md = MessageDigest.getInstance("MD5"); + byte[] b = md.digest(message); - StringBuffer buf = new StringBuffer(b.length*2); - for ( int i=0; i<b.length; i++ ) { - int j = (b[i]<0) ? 256+b[i] : b[i]; - if ( j<16 ) buf.append("0"); + StringBuffer buf = new StringBuffer(b.length * 2); + + for (int i = 0; i < b.length; i++) { + int j = (b[i] < 0) ? (256 + b[i]) : b[i]; + + if (j < 16) { + buf.append("0"); + } + buf.append(Integer.toHexString(j)); } + return buf.toString(); } /** * Convert a long to a byte array. */ - public static byte[] toBytes (long n) { + public static byte[] toBytes(long n) { byte[] b = new byte[8]; + b[0] = (byte) (n); n >>>= 8; b[1] = (byte) (n); @@ -57,8 +101,7 @@ public class MD5Encoder { b[6] = (byte) (n); n >>>= 8; b[7] = (byte) (n); + return b; } - } - diff --git a/src/helma/util/MimePart.java b/src/helma/util/MimePart.java index 974c2ea4..fa18937e 100644 --- a/src/helma/util/MimePart.java +++ b/src/helma/util/MimePart.java @@ -1,5 +1,18 @@ -// MimePart.java -// Copyright (c) Hannes Wallnöfer 2001 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.util; @@ -9,83 +22,132 @@ import java.util.Date; /** * This represents a MIME part of a HTTP file upload */ - public class MimePart implements Serializable { - public final String name; public int contentLength; public String contentType; private byte[] content; - public Date lastModified; public String eTag; - - public MimePart (String name, byte[] content, String contentType) { - this.name = name; - this.content = content == null ? new byte[0] : content; - this.contentType = contentType; - contentLength = content == null ? 0 : content.length; + /** + * Creates a new MimePart object. + * + * @param name ... + * @param content ... + * @param contentType ... + */ + public MimePart(String name, byte[] content, String contentType) { + this.name = name; + this.content = (content == null) ? new byte[0] : content; + this.contentType = contentType; + contentLength = (content == null) ? 0 : content.length; } - public String getContentType () { - return contentType; + /** + * + * + * @return ... + */ + public String getContentType() { + return contentType; } - public int getContentLength () { - return contentLength; + /** + * + * + * @return ... + */ + public int getContentLength() { + return contentLength; } - public String getName () { - return name; + /** + * + * + * @return ... + */ + public String getName() { + return name; } - public byte[] getContent () { - return content; + /** + * + * + * @return ... + */ + public byte[] getContent() { + return content; } - public String getText () { - if (contentType == null || contentType.startsWith ("text/")) { - // FIXME: check for encoding - return new String (content); - } else { - return null; - } + /** + * + * + * @return ... + */ + public String getText() { + if ((contentType == null) || contentType.startsWith("text/")) { + // FIXME: check for encoding + return new String(content); + } else { + return null; + } } - - public String writeToFile (String dir) { - return writeToFile (dir, null); + /** + * + * + * @param dir ... + * + * @return ... + */ + public String writeToFile(String dir) { + return writeToFile(dir, null); } - public String writeToFile (String dir, String fname) { - try { - File base = new File (dir); - // make directories if they don't exist - if (!base.exists ()) - base.mkdirs (); + /** + * + * + * @param dir ... + * @param fname ... + * + * @return ... + */ + public String writeToFile(String dir, String fname) { + try { + File base = new File(dir); - String filename = name; - if (fname != null) { - if (fname.indexOf (".") < 0) { - // check if we can use extension from name - int ndot = name == null ? -1 : name.lastIndexOf ("."); - if (ndot > -1) - filename = fname + name.substring (ndot); - else - filename = fname; - } else { - filename = fname; - } - } - File file = new File (base, filename); - FileOutputStream fout = new FileOutputStream (file); - fout.write (getContent ()); - fout.close (); - return filename; - } catch (Exception x) { - return null; - } + // make directories if they don't exist + if (!base.exists()) { + base.mkdirs(); + } + + String filename = name; + + if (fname != null) { + if (fname.indexOf(".") < 0) { + // check if we can use extension from name + int ndot = (name == null) ? (-1) : name.lastIndexOf("."); + + if (ndot > -1) { + filename = fname + name.substring(ndot); + } else { + filename = fname; + } + } else { + filename = fname; + } + } + + File file = new File(base, filename); + FileOutputStream fout = new FileOutputStream(file); + + fout.write(getContent()); + fout.close(); + + return filename; + } catch (Exception x) { + return null; + } } - } diff --git a/src/helma/util/MimePartDataSource.java b/src/helma/util/MimePartDataSource.java index a120afe0..7cd7fac7 100644 --- a/src/helma/util/MimePartDataSource.java +++ b/src/helma/util/MimePartDataSource.java @@ -1,45 +1,89 @@ -// MimePartDataSource.java -// Copyright (c) Hannes Wallnöfer 1999-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.util; -import javax.activation.*; import java.io.*; +import javax.activation.*; /** * Makes MimeParts usable as Datasources in the Java Activation Framework (JAF) */ - public class MimePartDataSource implements DataSource { - private MimePart part; private String name; - public MimePartDataSource (MimePart part) { + /** + * Creates a new MimePartDataSource object. + * + * @param part ... + */ + public MimePartDataSource(MimePart part) { this.part = part; - this.name = part.getName (); + this.name = part.getName(); } - public MimePartDataSource (MimePart part, String name) { + /** + * Creates a new MimePartDataSource object. + * + * @param part ... + * @param name ... + */ + public MimePartDataSource(MimePart part, String name) { this.part = part; this.name = name; } - + /** + * + * + * @return ... + * + * @throws IOException ... + */ public InputStream getInputStream() throws IOException { - return new ByteArrayInputStream(part.getContent ()); + return new ByteArrayInputStream(part.getContent()); } - public OutputStream getOutputStream () throws IOException { - throw new IOException ("Can't write to MimePart object."); + /** + * + * + * @return ... + * + * @throws IOException ... + */ + public OutputStream getOutputStream() throws IOException { + throw new IOException("Can't write to MimePart object."); } + /** + * + * + * @return ... + */ public String getContentType() { return part.contentType; } - public String getName () { + /** + * + * + * @return ... + */ + public String getName() { return name; } - } diff --git a/src/helma/util/ParanoidServerSocket.java b/src/helma/util/ParanoidServerSocket.java index b3955bf5..30044d86 100644 --- a/src/helma/util/ParanoidServerSocket.java +++ b/src/helma/util/ParanoidServerSocket.java @@ -1,50 +1,98 @@ -// ParanoidServerSocket.java -// Copyright (c) Hannes Wallnöfer 1999-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.util; -import java.net.*; import java.io.IOException; +import java.net.*; /** * A server socket that can allow connections to only a few selected hosts. */ - public class ParanoidServerSocket extends ServerSocket { - private InetAddressFilter filter; - - public ParanoidServerSocket (int port) throws IOException { - super (port); + /** + * Creates a new ParanoidServerSocket object. + * + * @param port ... + * + * @throws IOException ... + */ + public ParanoidServerSocket(int port) throws IOException { + super(port); } - public ParanoidServerSocket (int port, InetAddressFilter filter) throws IOException { - super (port); - this.filter = filter; + /** + * Creates a new ParanoidServerSocket object. + * + * @param port ... + * @param filter ... + * + * @throws IOException ... + */ + public ParanoidServerSocket(int port, InetAddressFilter filter) + throws IOException { + super(port); + this.filter = filter; } - public Socket accept () throws IOException { - Socket s = null; - while (s == null) { - s = super.accept (); - if (filter != null && !filter.matches (s.getInetAddress ())) { - System.err.println ("Refusing connection from "+s.getInetAddress ()); - try { - s.close(); - } catch (IOException ignore) {} - s = null; - } - } - return s; + /** + * + * + * @return ... + * + * @throws IOException ... + */ + public Socket accept() throws IOException { + Socket s = null; + + while (s == null) { + s = super.accept(); + + if ((filter != null) && !filter.matches(s.getInetAddress())) { + System.err.println("Refusing connection from " + s.getInetAddress()); + + try { + s.close(); + } catch (IOException ignore) { + } + + s = null; + } + } + + return s; } - public void setFilter (InetAddressFilter filter) { - this.filter = filter; + /** + * + * + * @param filter ... + */ + public void setFilter(InetAddressFilter filter) { + this.filter = filter; } - public InetAddressFilter getFilter () { - return this.filter; + /** + * + * + * @return ... + */ + public InetAddressFilter getFilter() { + return this.filter; } - } diff --git a/src/helma/util/SystemProperties.java b/src/helma/util/SystemProperties.java index 259fa67f..408ab729 100644 --- a/src/helma/util/SystemProperties.java +++ b/src/helma/util/SystemProperties.java @@ -1,25 +1,35 @@ -// Property.java -// Copyright (c) Hannes Wallnöfer 1997-2000 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.util; -import java.util.*; import java.io.*; +import java.util.*; /** * A property dictionary that is updated from a property file each time the * file is modified. It is also case insensitive. */ - public final class SystemProperties extends Properties { - - private SystemProperties defaultProps; // the default/fallback properties. - private File file; // the underlying properties file from which we read. - private long lastread, lastcheck, lastadd; // time we last read/checked the underlying properties file - - // the timespan for which we omit checking for changed files after we - // did a check, in milliseconds. - final static long cacheTime = 1500l; + final static long cacheTime = 1500L; + private SystemProperties defaultProps; // the default/fallback properties. + private File file; // the underlying properties file from which we read. + private long lastread; // time we last read/checked the underlying properties file + private long lastcheck; // time we last read/checked the underlying properties file + private long lastadd; // time we last read/checked the underlying properties file // map of additional properties private HashMap additionalProps = null; @@ -27,253 +37,296 @@ public final class SystemProperties extends Properties { /** * Construct an empty properties object. */ - public SystemProperties () { - this (null, null); + public SystemProperties() { + this(null, null); } /** * Construct a properties object and read it from an input stream. */ - public SystemProperties (InputStream in) { - this (null, null); - try { - load (in); - } catch (Exception x) { - System.err.println ("Error reading properties from file "+file+": "+x); - } finally { - try { - in.close (); - } catch (Exception ignore) {} - } - lastread = System.currentTimeMillis (); + public SystemProperties(InputStream in) { + this(null, null); + + try { + load(in); + } catch (Exception x) { + System.err.println("Error reading properties from file " + file + ": " + x); + } finally { + try { + in.close(); + } catch (Exception ignore) { + } + } + + lastread = System.currentTimeMillis(); } /** * Construct a properties object from a properties file. */ - public SystemProperties (String filename) { - this (filename, null); + public SystemProperties(String filename) { + this(filename, null); } /** * Contstruct a properties object with the given default properties. */ - public SystemProperties (SystemProperties defaultProps) { - this (null, defaultProps); + public SystemProperties(SystemProperties defaultProps) { + this(null, defaultProps); } - /** * Construct a properties object from a file name with the given default properties */ - public SystemProperties (String filename, SystemProperties defaultProps) { - // System.err.println ("building sysprops with file "+filename+" and node "+node); - super (defaultProps); - this.defaultProps = defaultProps; - file = filename == null ? null : new File (filename); - lastcheck = lastread = lastadd = 0; + public SystemProperties(String filename, SystemProperties defaultProps) { + // System.err.println ("building sysprops with file "+filename+" and node "+node); + super(defaultProps); + this.defaultProps = defaultProps; + file = (filename == null) ? null : new File(filename); + lastcheck = lastread = lastadd = 0; } - /** - * Return the modify-time of the underlying properties file. - */ - public long lastModified () { - if (file == null || !file.exists ()) - return lastadd; - return Math.max (file.lastModified (), lastadd); + /** + * Return the modify-time of the underlying properties file. + */ + public long lastModified() { + if ((file == null) || !file.exists()) { + return lastadd; + } + + return Math.max(file.lastModified(), lastadd); } /** * Return a checksum that changes when something in the properties changes. */ - public long getChecksum () { - if (defaultProps == null) - return lastModified (); - return lastModified () + defaultProps.lastModified (); + public long getChecksum() { + if (defaultProps == null) { + return lastModified(); + } + + return lastModified() + defaultProps.lastModified(); } /** * Private method to read file if it has been changed since the last time we did */ - private void checkFile () { - if (file != null && file.exists() && file.lastModified () > lastread) - readFile (); - lastcheck = System.currentTimeMillis (); + private void checkFile() { + if ((file != null) && file.exists() && (file.lastModified() > lastread)) { + readFile(); + } + + lastcheck = System.currentTimeMillis(); } /** * Private method to read the underlying properties file. Assumes that the * file exists and is readable. */ - private synchronized void readFile () { - // IServer.getLogger().log ("Reading properties from file "+file); - FileInputStream bpin = null; - try { - bpin = new FileInputStream (file); - load (bpin); - } catch (Exception x) { - System.err.println ("Error reading properties from file "+file+": "+x); - } finally { - try { - bpin.close (); - } catch (Exception ignore) {} - } + private synchronized void readFile() { + // IServer.getLogger().log ("Reading properties from file "+file); + FileInputStream bpin = null; + + try { + bpin = new FileInputStream(file); + load(bpin); + } catch (Exception x) { + System.err.println("Error reading properties from file " + file + ": " + x); + } finally { + try { + bpin.close(); + } catch (Exception ignore) { + } + } } + /** + * + * + * @param in ... + * + * @throws IOException ... + */ + public synchronized void load(InputStream in) throws IOException { + clear(); + super.load(in); - public synchronized void load (InputStream in) throws IOException { - clear (); - super.load (in); - if (additionalProps != null) { - for (Iterator i=additionalProps.values().iterator(); i.hasNext(); ) - putAll ((Properties) i.next()); - } - lastread = System.currentTimeMillis (); + if (additionalProps != null) { + for (Iterator i = additionalProps.values().iterator(); i.hasNext();) + putAll((Properties) i.next()); + } + + lastread = System.currentTimeMillis(); } - /** * Similar to load(), but adds to the existing properties instead * of discarding them. */ - public synchronized void addProps (String key, InputStream in) throws IOException { - Properties p = new SystemProperties(); - p.load (in); - if (additionalProps == null) - additionalProps = new HashMap (); - additionalProps.put (key, p); - putAll (p); - lastadd = System.currentTimeMillis (); + public synchronized void addProps(String key, InputStream in) + throws IOException { + Properties p = new SystemProperties(); + + p.load(in); + + if (additionalProps == null) { + additionalProps = new HashMap(); + } + + additionalProps.put(key, p); + putAll(p); + lastadd = System.currentTimeMillis(); } - /** + /** * Remove an additional properties dictionary. */ - public synchronized void removeProps (String key) { - if (additionalProps != null) { - // remove added properties for this key. If we had - // properties associated with the key, mark props as updated. - Object p = additionalProps.remove (key); - if (p != null) - lastadd = System.currentTimeMillis (); - } - } + public synchronized void removeProps(String key) { + if (additionalProps != null) { + // remove added properties for this key. If we had + // properties associated with the key, mark props as updated. + Object p = additionalProps.remove(key); + if (p != null) { + lastadd = System.currentTimeMillis(); + } + } + } /* * This should not be used directly if properties are read from file, * otherwise changes will be lost whe the file is next modified. */ - public Object put (Object key, Object value) { - // cut off trailing whitespace - if (value != null) - value = value.toString().trim(); - return super.put (key.toString().toLowerCase(), value); + public Object put(Object key, Object value) { + // cut off trailing whitespace + if (value != null) { + value = value.toString().trim(); + } + + return super.put(key.toString().toLowerCase(), value); } /** * Overrides method to act on the wrapped properties object. */ - public Object get (Object key) { - if (System.currentTimeMillis () - lastcheck > cacheTime) - checkFile (); - return super.get (key.toString().toLowerCase()); + public Object get(Object key) { + if ((System.currentTimeMillis() - lastcheck) > cacheTime) { + checkFile(); + } + + return super.get(key.toString().toLowerCase()); } /** * Overrides method to act on the wrapped properties object. */ - public Object remove (Object key) { - return super.remove (key.toString().toLowerCase()); + public Object remove(Object key) { + return super.remove(key.toString().toLowerCase()); } /** * Overrides method to act on the wrapped properties object. */ - public boolean contains (Object obj) { - if (System.currentTimeMillis () - lastcheck > cacheTime) - checkFile (); - return super.contains (obj); + public boolean contains(Object obj) { + if ((System.currentTimeMillis() - lastcheck) > cacheTime) { + checkFile(); + } + + return super.contains(obj); } /** * Overrides method to act on the wrapped properties object. */ - public boolean containsKey (Object key) { - if (System.currentTimeMillis () - lastcheck > cacheTime) - checkFile (); - return super.containsKey (key.toString().toLowerCase()); + public boolean containsKey(Object key) { + if ((System.currentTimeMillis() - lastcheck) > cacheTime) { + checkFile(); + } + + return super.containsKey(key.toString().toLowerCase()); } /** * Overrides method to act on the wrapped properties object. */ - public boolean isEmpty () { - if (System.currentTimeMillis () - lastcheck > cacheTime) - checkFile (); - return super.isEmpty (); + public boolean isEmpty() { + if ((System.currentTimeMillis() - lastcheck) > cacheTime) { + checkFile(); + } + + return super.isEmpty(); } /** * Overrides method to act on the wrapped properties object. */ - public String getProperty (String name) { - if (System.currentTimeMillis () - lastcheck > cacheTime) - checkFile (); - return super.getProperty (name.toLowerCase()); + public String getProperty(String name) { + if ((System.currentTimeMillis() - lastcheck) > cacheTime) { + checkFile(); + } + + return super.getProperty(name.toLowerCase()); } /** * Overrides method to act on the wrapped properties object. */ - public String getProperty (String name, String defaultValue) { - if (System.currentTimeMillis () - lastcheck > cacheTime) - checkFile (); - return super.getProperty (name.toLowerCase(), defaultValue); + public String getProperty(String name, String defaultValue) { + if ((System.currentTimeMillis() - lastcheck) > cacheTime) { + checkFile(); + } + + return super.getProperty(name.toLowerCase(), defaultValue); } /** * Overrides method to act on the wrapped properties object. */ - public Enumeration keys () { - if (System.currentTimeMillis () - lastcheck > cacheTime) - checkFile (); - return super.keys(); + public Enumeration keys() { + if ((System.currentTimeMillis() - lastcheck) > cacheTime) { + checkFile(); + } + + return super.keys(); } /** * Overrides method to act on the wrapped properties object. */ - public Set keySet () { - if (System.currentTimeMillis () - lastcheck > cacheTime) - checkFile (); - return super.keySet(); + public Set keySet() { + if ((System.currentTimeMillis() - lastcheck) > cacheTime) { + checkFile(); + } + + return super.keySet(); } /** * Overrides method to act on the wrapped properties object. */ - public Enumeration elements () { - if (System.currentTimeMillis () - lastcheck > cacheTime) - checkFile (); - return super.elements(); + public Enumeration elements() { + if ((System.currentTimeMillis() - lastcheck) > cacheTime) { + checkFile(); + } + + return super.elements(); } /** * Overrides method to act on the wrapped properties object. */ public int size() { - if (System.currentTimeMillis () - lastcheck > cacheTime) - checkFile (); - return super.size(); + if ((System.currentTimeMillis() - lastcheck) > cacheTime) { + checkFile(); + } + + return super.size(); } /** * Overrides method to act on the wrapped properties object. */ - public String toString () { - return super.toString (); + public String toString() { + return super.toString(); } - } - diff --git a/src/helma/util/Timer.java b/src/helma/util/Timer.java index 3d59ecb7..c59a5ee5 100644 --- a/src/helma/util/Timer.java +++ b/src/helma/util/Timer.java @@ -1,70 +1,106 @@ -// Timer.java -// Copyright (c) Hannes Wallnöfer 1999-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.util; -import java.util.*; import java.io.PrintStream; +import java.util.*; /** * Utility class for timing a series of events */ - public class Timer { - private Vector timeline; private Hashtable events; - public Timer () { - timeline = new Vector (); - events = new Hashtable (); + /** + * Creates a new Timer object. + */ + public Timer() { + timeline = new Vector(); + events = new Hashtable(); } - public void reset () { - timeline.setSize (0); - events.clear (); + /** + * + */ + public void reset() { + timeline.setSize(0); + events.clear(); } - public void beginEvent (String name) { - timeline.addElement (name); - events.put (name, new Event (name)); + /** + * + * + * @param name ... + */ + public void beginEvent(String name) { + timeline.addElement(name); + events.put(name, new Event(name)); } - public void endEvent (String name) { - Event event = (Event) events.get (name); - if (event != null) - event.terminate (); + /** + * + * + * @param name ... + */ + public void endEvent(String name) { + Event event = (Event) events.get(name); + + if (event != null) { + event.terminate(); + } } - public void dump (PrintStream out) { - for (int i=0; i<timeline.size(); i++) { - String name = (String) timeline.elementAt (i); - Event event = (Event) events.get (name); - out.println (event); - } + /** + * + * + * @param out ... + */ + public void dump(PrintStream out) { + for (int i = 0; i < timeline.size(); i++) { + String name = (String) timeline.elementAt(i); + Event event = (Event) events.get(name); + + out.println(event); + } } class Event { + String name; + long start; + long end; - String name; - long start, end; + Event(String name) { + this.name = name; + start = System.currentTimeMillis(); + } - Event (String name) { - this.name = name; - start = System.currentTimeMillis (); - } + void terminate() { + end = System.currentTimeMillis(); + } - void terminate () { - end = System.currentTimeMillis (); - } + public String toString() { + long now = System.currentTimeMillis(); - public String toString () { - long now = System.currentTimeMillis (); - if (end == 0l) - return (" + "+(now-start)+" "+name); - else - return (" "+(end-start)+" "+name); - } + if (end == 0L) { + return (" + " + (now - start) + " " + name); + } else { + return (" " + (end - start) + " " + name); + } + } } - } diff --git a/src/helma/util/Updatable.java b/src/helma/util/Updatable.java index cea3a911..5a81f5d5 100644 --- a/src/helma/util/Updatable.java +++ b/src/helma/util/Updatable.java @@ -1,52 +1,40 @@ -// Updatable.java -// Copyright (c) Hannes Wallnöfer 2001 - +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.util; /** * An interface of classes that can update themselves and know when to do so. */ - - public interface Updatable { + /** + * + * + * @return ... + */ + public boolean needsUpdate(); - public boolean needsUpdate (); - - public void update (); - - public void remove (); + /** + * + */ + public void update(); + /** + * + */ + public void remove(); } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/helma/util/UrlEncoded.java b/src/helma/util/UrlEncoded.java index fda0d10f..bc1db426 100644 --- a/src/helma/util/UrlEncoded.java +++ b/src/helma/util/UrlEncoded.java @@ -1,37 +1,57 @@ -// UrlEncoded.java -// (c) 2002 Hannes Wallnoefer +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.util; import java.net.URLEncoder; - /** - * A proxy to java.net.URLEncoder which only encodes when - * there is actual work to do. This is necessary because - * URLEncoder is quite inefficient (e.g. it preallocates - * buffers and stuff), and we call it often with + * A proxy to java.net.URLEncoder which only encodes when + * there is actual work to do. This is necessary because + * URLEncoder is quite inefficient (e.g. it preallocates + * buffers and stuff), and we call it often with * short string that don't need encoding. */ public final class UrlEncoded { - - - public static String encode (String str) { + /** + * + * + * @param str ... + * + * @return ... + */ + public static String encode(String str) { int l = str.length(); boolean needsSpaceEncoding = false; - for (int i=0; i<l; i++) { + + for (int i = 0; i < l; i++) { char c = str.charAt(i); + if (c == ' ') { needsSpaceEncoding = true; - } else if (!(c>='a' && c<='z' || - c>='A' && c<='Z' || - c>='0' && c<='9')) { - return URLEncoder.encode (str); + } else if (!(((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || + ((c >= '0') && (c <= '9')))) { + return URLEncoder.encode(str); } } - if (needsSpaceEncoding) - return str.replace (' ', '+'); + + if (needsSpaceEncoding) { + return str.replace(' ', '+'); + } + return str; } - -} \ No newline at end of file +} diff --git a/src/helma/util/WebBroadcaster.java b/src/helma/util/WebBroadcaster.java index 48eb09ef..8fe891d4 100644 --- a/src/helma/util/WebBroadcaster.java +++ b/src/helma/util/WebBroadcaster.java @@ -1,5 +1,18 @@ -// WebBroadcaster.java -// Copyright (c) Hannes Wallnöfer 1999-2000 +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ package helma.util; @@ -10,341 +23,399 @@ import java.util.*; /** * A utility hack to do "html web broadcasts". */ - public class WebBroadcaster implements Runnable { + static String lastResult = ""; + static String reloadJS = "<html>\r\n<head><SCRIPT language=JavaScript>\r\n<!--\r\nfunction reload (url) {\r\n window.location.href=url;\r\n}\r\n//-->\r\n</SCRIPT>\r\n"; + static String scrollJS = "<SCRIPT language=JavaScript>\r\n<!--\r\nfunction scroller () {\r\n window.scroll(1, 500000);\r\n window.setTimeout(\"scroller()\", 100);\r\n}\r\nscroller();\r\n//-->\r\n</SCRIPT>\r\n</head>\r\n<body>\r\n"; + private Vector connections; + private ServerSocket serverSocket; + private Thread listener; + private boolean paranoid; + private Vector accept; + private Vector deny; + long time; + int last; - private Vector connections; - private ServerSocket serverSocket; - private Thread listener; - private boolean paranoid; - static String lastResult = ""; - private Vector accept, deny; - static String reloadJS = "<html>\r\n<head><SCRIPT language=JavaScript>\r\n<!--\r\nfunction reload (url) {\r\n window.location.href=url;\r\n}\r\n//-->\r\n</SCRIPT>\r\n"; - static String scrollJS = "<SCRIPT language=JavaScript>\r\n<!--\r\nfunction scroller () {\r\n window.scroll(1, 500000);\r\n window.setTimeout(\"scroller()\", 100);\r\n}\r\nscroller();\r\n//-->\r\n</SCRIPT>\r\n</head>\r\n<body>\r\n"; - long time; - int last; + /** + * Creates a Web server at the specified port number. + */ + public WebBroadcaster(int port) throws IOException { + super(); + connections = new Vector(); + accept = new Vector(); + deny = new Vector(); - /** - * - */ - public static void main (String args[]) { - System.out.println ("Usage: java helma.util.WebBroadcaster [port]"); - int p = 8080; - if (args.length > 0) try { - p = Integer.parseInt (args[0]); - } catch (NumberFormatException nfx) { - System.out.println ("Error parsing port number: "+args[0]); - } - - try { - WebBroadcaster server = new WebBroadcaster (p); - // webserver.setParanoid (false); - // webserver.acceptClient ("192.168.*.*"); - System.out.println ("started web broadcast server on port "+p); - } catch (IOException x) { - System.out.println ("Error creating web broadcast server: "+x); + // make a new server socket with extra large queue size + this.serverSocket = new ServerSocket(port, 2000); + listener = new Thread(this); + listener.start(); } - } + /** + * + */ + public static void main(String[] args) { + System.out.println("Usage: java helma.util.WebBroadcaster [port]"); + int p = 8080; - /** - * Creates a Web server at the specified port number. - */ - public WebBroadcaster (int port) throws IOException { - super(); - connections = new Vector (); - accept = new Vector (); - deny = new Vector (); - // make a new server socket with extra large queue size - this.serverSocket = new ServerSocket (port, 2000); - listener = new Thread (this); - listener.start (); - } + if (args.length > 0) { + try { + p = Integer.parseInt(args[0]); + } catch (NumberFormatException nfx) { + System.out.println("Error parsing port number: " + args[0]); + } + } + try { + WebBroadcaster server = new WebBroadcaster(p); - public void broadcast (String message) { - long start = System.currentTimeMillis (); - int l = connections.size (); - synchronized (this) { - if (l != last) { - System.out.println ("broadcasting to "+l+" clients in "+time+" millis."); - last = l; - } + // webserver.setParanoid (false); + // webserver.acceptClient ("192.168.*.*"); + System.out.println("started web broadcast server on port " + p); + } catch (IOException x) { + System.out.println("Error creating web broadcast server: " + x); + } } - for (int i=l-1; i>=0; i--) { - try { - Connection c = (Connection) connections.elementAt (i); - c.send (message); - } catch (Exception ignore) {} + + /** + * + * + * @param message ... + */ + public void broadcast(String message) { + long start = System.currentTimeMillis(); + int l = connections.size(); + + synchronized (this) { + if (l != last) { + System.out.println("broadcasting to " + l + " clients in " + time + + " millis."); + last = l; + } + } + + for (int i = l - 1; i >= 0; i--) { + try { + Connection c = (Connection) connections.elementAt(i); + + c.send(message); + } catch (Exception ignore) { + } + } + + time = System.currentTimeMillis() - start; } - time = System.currentTimeMillis () - start; - } - - /** - * Switch client filtering on/off. - * @see acceptClient(java.lang.String) - * @see denyClient(java.lang.String) - */ - public void setParanoid (boolean p) { - paranoid = p; - } - - - /** - * Add an IP address to the list of accepted clients. The parameter can contain '*' as wildcard - * character, e.g. "192.168.*.*". You must call setParanoid(true) in order for this to have any - * effect. - * - * @see denyClient(java.lang.String) - * @see setParanoid(boolean) - */ - public void acceptClient (String address) throws IllegalArgumentException { - try { - AddressMatcher m = new AddressMatcher (address); - accept.addElement (m); - } catch (Exception x) { - throw new IllegalArgumentException ("\""+address+"\" does not represent a valid IP address"); + /** + * Switch client filtering on/off. + * @see acceptClient(java.lang.String) + * @see denyClient(java.lang.String) + */ + public void setParanoid(boolean p) { + paranoid = p; } - } - /** - * Add an IP address to the list of denied clients. The parameter can contain '*' as wildcard - * character, e.g. "192.168.*.*". You must call setParanoid(true) in order for this to have any - * effect. - * - * @see acceptClient(java.lang.String) - * @see setParanoid(boolean) - */ - public void denyClient (String address) throws IllegalArgumentException { - try { - AddressMatcher m = new AddressMatcher (address); - deny.addElement (m); - } catch (Exception x) { - throw new IllegalArgumentException ("\""+address+"\" does not represent a valid IP address"); + /** + * Add an IP address to the list of accepted clients. The parameter can contain '*' as wildcard + * character, e.g. "192.168.*.*". You must call setParanoid(true) in order for this to have any + * effect. + * + * @see denyClient(java.lang.String) + * @see setParanoid(boolean) + */ + public void acceptClient(String address) throws IllegalArgumentException { + try { + AddressMatcher m = new AddressMatcher(address); + + accept.addElement(m); + } catch (Exception x) { + throw new IllegalArgumentException("\"" + address + + "\" does not represent a valid IP address"); + } } - } - - private boolean checkSocket (Socket s) { - int l = deny.size (); - byte address[] = s.getInetAddress ().getAddress (); - for (int i=0; i<l; i++) { - AddressMatcher match = (AddressMatcher) deny.elementAt (i); - if (match.matches (address)) + + /** + * Add an IP address to the list of denied clients. The parameter can contain '*' as wildcard + * character, e.g. "192.168.*.*". You must call setParanoid(true) in order for this to have any + * effect. + * + * @see acceptClient(java.lang.String) + * @see setParanoid(boolean) + */ + public void denyClient(String address) throws IllegalArgumentException { + try { + AddressMatcher m = new AddressMatcher(address); + + deny.addElement(m); + } catch (Exception x) { + throw new IllegalArgumentException("\"" + address + + "\" does not represent a valid IP address"); + } + } + + private boolean checkSocket(Socket s) { + int l = deny.size(); + byte[] address = s.getInetAddress().getAddress(); + + for (int i = 0; i < l; i++) { + AddressMatcher match = (AddressMatcher) deny.elementAt(i); + + if (match.matches(address)) { + return false; + } + } + + l = accept.size(); + + for (int i = 0; i < l; i++) { + AddressMatcher match = (AddressMatcher) accept.elementAt(i); + + if (match.matches(address)) { + return true; + } + } + return false; } - l = accept.size (); - for (int i=0; i<l; i++) { - AddressMatcher match = (AddressMatcher) accept.elementAt (i); - if (match.matches (address)) - return true; - } - return false; - } - /** - * Listens for client requests until stopped. - */ - public void run() { - Thread current = Thread.currentThread (); - try { - while (listener == current) { - Socket socket = serverSocket.accept(); + /** + * Listens for client requests until stopped. + */ + public void run() { + Thread current = Thread.currentThread(); + try { - // if (!paranoid || checkSocket (socket)) - new Connection (socket); - // else - // socket.close (); - } catch (Exception x) { - System.out.println ("Error in listener: "+x); + while (listener == current) { + Socket socket = serverSocket.accept(); + + try { + // if (!paranoid || checkSocket (socket)) + new Connection(socket); + + // else + // socket.close (); + } catch (Exception x) { + System.out.println("Error in listener: " + x); + } + } + } catch (Exception exception) { + System.err.println("Error accepting Web connections (" + exception + ")."); + } finally { + try { + serverSocket.close(); + serverSocket = null; + } catch (IOException ignore) { + } } - } } - catch (Exception exception) { - System.err.println("Error accepting Web connections (" + exception + ")."); - } - finally { - try { - serverSocket.close(); - serverSocket = null; - } - catch (IOException ignore) {} - } - } -class Connection implements Runnable { + class Connection implements Runnable { + private Socket socket; + private InputStream input; + private BufferedWriter output; + private Thread responder; - private Socket socket; - private InputStream input; - private BufferedWriter output; - private Thread responder; - - public Connection (Socket socket) throws IOException { - super(); - this.socket = socket; - socket.setSoTimeout (30000); - input = new BufferedInputStream (socket.getInputStream()); - output = new BufferedWriter (new OutputStreamWriter(socket.getOutputStream())); - responder = new Thread (this); - responder.start(); - } - - /* public void run () { - Thread current = Thread.currentThread (); - if (current == cleaner) { - cleanup (); - } else if (current == responder) { - respond (); - } - } */ - - public void run () { - - boolean newConnection = false; - - try { - - DataInputStream reader = new DataInputStream (input); - boolean keepalive = false; - int cycle = 0; - // implement keep-alive connections - do { - // if (cycle > 0) System.out.println ("Reusing connection: "+cycle); - String line = reader.readLine(); - if (line == null) throw new IOException ("connection reset"); - int contentLength = 0; - StringTokenizer tokens = new StringTokenizer(line); - String method = tokens.nextToken(); - String uri = tokens.nextToken (); - String httpversion = tokens.nextToken (); - keepalive = "HTTP/1.1".equals (httpversion); - - do { - // System.out.println (line); - line = reader.readLine(); - if (line != null) { - line = line.toLowerCase (); - if (line.startsWith ("content-length:")) - contentLength = Integer.parseInt (line.substring (15).trim ()); - if (line.startsWith ("connection:")) - keepalive = line.indexOf ("keep-alive") > -1; - } - } while (line != null && ! line.equals("")); - // System.out.println (""); - - if ("GET".equals (method)) { - - output.write (httpversion+" 200 OK\r\n"); - output.write ("Server: helma.WebBroadcast\r\n"); - output.write ("Content-Type: text/html\r\n"); - newConnection = uri.startsWith ("/NEW"); - if (!newConnection) { - output.write ("Content-Length: 5\r\n"); - if (keepalive) - output.write ("Connection: keep-alive\r\n"); - output.write ("\r\n"); - output.write ("done."); - output.flush (); - cycle += 1; - if (uri.startsWith ("/MSG")) - broadcast (uri+"<br>\r\n"); - continue; - } - - output.write ("Connection: close\r\n"); - output.write ("\r\n"); - output.write (reloadJS); - output.write (scrollJS); - output.flush (); - - connections.addElement (this); - - } else { - output.write ("HTTP/1.0 400 Bad Request\r\n"); - output.write ("Server: helma.WebBroadcast\r\n\r\n"); - output.write ("Bad Request."); - // output.write (lastResult); - output.flush (); - keepalive = false; + public Connection(Socket socket) throws IOException { + super(); + this.socket = socket; + socket.setSoTimeout(30000); + input = new BufferedInputStream(socket.getInputStream()); + output = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); + responder = new Thread(this); + responder.start(); + } + + /* public void run () { + Thread current = Thread.currentThread (); + if (current == cleaner) { + cleanup (); + } else if (current == responder) { + respond (); + } + } */ + public void run() { + boolean newConnection = false; + + try { + DataInputStream reader = new DataInputStream(input); + boolean keepalive = false; + int cycle = 0; + + // implement keep-alive connections + do { + // if (cycle > 0) System.out.println ("Reusing connection: "+cycle); + String line = reader.readLine(); + + if (line == null) { + throw new IOException("connection reset"); + } + + int contentLength = 0; + StringTokenizer tokens = new StringTokenizer(line); + String method = tokens.nextToken(); + String uri = tokens.nextToken(); + String httpversion = tokens.nextToken(); + + keepalive = "HTTP/1.1".equals(httpversion); + + do { + // System.out.println (line); + line = reader.readLine(); + + if (line != null) { + line = line.toLowerCase(); + + if (line.startsWith("content-length:")) { + contentLength = Integer.parseInt(line.substring(15).trim()); + } + + if (line.startsWith("connection:")) { + keepalive = line.indexOf("keep-alive") > -1; + } + } + } while ((line != null) && !line.equals("")); + + // System.out.println (""); + if ("GET".equals(method)) { + output.write(httpversion + " 200 OK\r\n"); + output.write("Server: helma.WebBroadcast\r\n"); + output.write("Content-Type: text/html\r\n"); + newConnection = uri.startsWith("/NEW"); + + if (!newConnection) { + output.write("Content-Length: 5\r\n"); + + if (keepalive) { + output.write("Connection: keep-alive\r\n"); + } + + output.write("\r\n"); + output.write("done."); + output.flush(); + cycle += 1; + + if (uri.startsWith("/MSG")) { + broadcast(uri + "<br>\r\n"); + } + + continue; + } + + output.write("Connection: close\r\n"); + output.write("\r\n"); + output.write(reloadJS); + output.write(scrollJS); + output.flush(); + + connections.addElement(this); + } else { + output.write("HTTP/1.0 400 Bad Request\r\n"); + output.write("Server: helma.WebBroadcast\r\n\r\n"); + output.write("Bad Request."); + + // output.write (lastResult); + output.flush(); + keepalive = false; + } + } while (keepalive && !newConnection); + } catch (Exception x) { + System.out.print("."); + } finally { + if (newConnection) { // leave connection open + + return; + } + + try { + output.close(); + } catch (IOException ignore) { + } + + try { + input.close(); + } catch (IOException ignore) { + } + + try { + socket.close(); + } catch (IOException ignore) { + } + } + } + + public void cleanup() { + } + + public synchronized void send(String message) { + try { + output.write(message); + output.flush(); + } catch (Exception exception) { + try { + connections.removeElement(this); + } catch (Exception ignore) { + } + + try { + output.close(); + } catch (IOException ignore) { + } + + try { + input.close(); + } catch (IOException ignore) { + } + + try { + socket.close(); + } catch (IOException ignore) { + } + } + } + + public String toString() { + return socket.getInetAddress().getHostName(); } - } while (keepalive && !newConnection); - } catch (Exception x) { - System.out.print ("."); - } finally { - if (newConnection) // leave connection open - return; - try { - output.close(); - } catch (IOException ignore) {} - try { - input.close(); - } catch (IOException ignore) {} - try { - socket.close(); - } catch (IOException ignore) {} } - } - - public void cleanup () { - - } - - public synchronized void send (String message) { - try { - output.write (message); - output.flush (); - } catch (Exception exception) { - try { - connections.removeElement (this); - } catch (Exception ignore) {} - try { - output.close(); - } catch (IOException ignore) {} - try { - input.close(); - } catch (IOException ignore) {} - try { - socket.close(); - } catch (IOException ignore) {} - } - } + class AddressMatcher { + int[] pattern; - public String toString () { - return socket.getInetAddress ().getHostName (); - } + public AddressMatcher(String address) throws Exception { + pattern = new int[4]; -} + StringTokenizer st = new StringTokenizer(address, "."); + if (st.countTokens() != 4) { + throw new Exception("\"" + address + + "\" does not represent a valid IP address"); + } -class AddressMatcher { + for (int i = 0; i < 4; i++) { + String next = st.nextToken(); - int pattern[]; - - public AddressMatcher (String address) throws Exception { - pattern = new int[4]; - StringTokenizer st = new StringTokenizer (address, "."); - if (st.countTokens () != 4) - throw new Exception ("\""+address+"\" does not represent a valid IP address"); - for (int i=0; i<4; i++) { - String next = st.nextToken (); - if ("*".equals (next)) - pattern[i] = 256; - else - pattern[i] = (byte) Integer.parseInt (next); - } - } - - public boolean matches (byte address[]) { - for (int i=0; i<4; i++) { - if (pattern[i] > 255) // wildcard - continue; - if (pattern[i] != address[i]) - return false; - } - return true; + if ("*".equals(next)) { + pattern[i] = 256; + } else { + pattern[i] = (byte) Integer.parseInt(next); + } + } + } + + public boolean matches(byte[] address) { + for (int i = 0; i < 4; i++) { + if (pattern[i] > 255) { // wildcard + + continue; + } + + if (pattern[i] != address[i]) { + return false; + } + } + + return true; + } } } - -} \ No newline at end of file diff --git a/src/helma/util/XmlUtils.java b/src/helma/util/XmlUtils.java index 918ebcb1..e98e96a3 100644 --- a/src/helma/util/XmlUtils.java +++ b/src/helma/util/XmlUtils.java @@ -1,78 +1,129 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + package helma.util; -import java.io.InputStream; +import org.w3c.dom.Document; +import org.xml.sax.InputSource; +import org.xml.sax.Parser; +import org.xml.sax.SAXException; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; -import java.io.InputStreamReader; -import java.net.URL; import java.net.MalformedURLException; - -import javax.xml.parsers.DocumentBuilderFactory; +import java.net.URL; import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.SAXParserFactory; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.ParserConfigurationException; - -import org.w3c.dom.Document; -import org.xml.sax.Parser; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; - +import javax.xml.parsers.SAXParserFactory; +/** + * + */ public class XmlUtils { - private static DocumentBuilderFactory domBuilderFactory = null; private static SAXParserFactory saxParserFactory = null; - public static Document parseXml (Object obj) - throws SAXException, IOException, ParserConfigurationException { - if (domBuilderFactory == null) - domBuilderFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance(); - DocumentBuilder parser = domBuilderFactory.newDocumentBuilder(); - Document doc = null; - if (obj instanceof String) try { - // first try to interpret string as URL - URL url = new URL (obj.toString ()); - doc = parser.parse (obj.toString()); - } catch (MalformedURLException nourl) { - // if not a URL, maybe it is the XML itself - doc = parser.parse (new InputSource (new StringReader (obj.toString()))); - } else if (obj instanceof InputStream) { - doc = parser.parse (new InputSource ((InputStream) obj)); - } else if (obj instanceof Reader) { - doc = parser.parse (new InputSource ((Reader) obj)); - } - doc.normalize(); - return doc; + /** + * + * + * @param obj ... + * + * @return ... + * + * @throws SAXException ... + * @throws IOException ... + * @throws ParserConfigurationException ... + */ + public static Document parseXml(Object obj) + throws SAXException, IOException, + ParserConfigurationException { + if (domBuilderFactory == null) { + domBuilderFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance(); + } + + DocumentBuilder parser = domBuilderFactory.newDocumentBuilder(); + Document doc = null; + + if (obj instanceof String) { + try { + // first try to interpret string as URL + URL url = new URL(obj.toString()); + + doc = parser.parse(obj.toString()); + } catch (MalformedURLException nourl) { + // if not a URL, maybe it is the XML itself + doc = parser.parse(new InputSource(new StringReader(obj.toString()))); + } + } else if (obj instanceof InputStream) { + doc = parser.parse(new InputSource((InputStream) obj)); + } else if (obj instanceof Reader) { + doc = parser.parse(new InputSource((Reader) obj)); + } + + doc.normalize(); + + return doc; } + /** + * + * + * @param obj ... + * + * @return ... + * + * @throws SAXException ... + * @throws IOException ... + * @throws ParserConfigurationException ... + */ + public static Document parseHtml(Object obj) + throws SAXException, IOException, + ParserConfigurationException { + try { + Class.forName("org.apache.html.dom.HTMLBuilder"); + } catch (Throwable notfound) { + throw new IOException("Couldn't load nekohtml/Xerces HTML parser: " + + notfound); + } - public static Document parseHtml (Object obj) - throws SAXException, IOException, ParserConfigurationException { - try { - Class.forName ("org.apache.html.dom.HTMLBuilder"); - } catch (Throwable notfound) { - throw new IOException ("Couldn't load nekohtml/Xerces HTML parser: "+notfound); - } - Document doc = null; - HtmlParser parser = new HtmlParser (); - if (obj instanceof String) try { - // first try to interpret string as URL - URL url = new URL (obj.toString ()); - parser.parse (new InputStreamReader (url.openStream())); - } catch (MalformedURLException nourl) { - // if not a URL, maybe it is the XML itself - parser.parse (new StringReader (obj.toString())); - } else if (obj instanceof InputStream) { - parser.parse (new InputStreamReader ((InputStream) obj)); - } else if (obj instanceof Reader) { - parser.parse ((Reader) obj); - } - doc = parser.getDocument (); - return doc; + Document doc = null; + HtmlParser parser = new HtmlParser(); + + if (obj instanceof String) { + try { + // first try to interpret string as URL + URL url = new URL(obj.toString()); + + parser.parse(new InputStreamReader(url.openStream())); + } catch (MalformedURLException nourl) { + // if not a URL, maybe it is the XML itself + parser.parse(new StringReader(obj.toString())); + } + } else if (obj instanceof InputStream) { + parser.parse(new InputStreamReader((InputStream) obj)); + } else if (obj instanceof Reader) { + parser.parse((Reader) obj); + } + + doc = parser.getDocument(); + + return doc; } - - }