From b1744ffa9ae897ef73a19474883a99ed1a7b0842 Mon Sep 17 00:00:00 2001 From: Gabe Wong Date: Tue, 5 Jun 2012 16:22:02 -0700 Subject: [PATCH] V.2-06/04/2012 --- LICENSE | 2098 ++-- NOTICE | 72 +- README | 222 +- RELEASE-NOTES | 456 +- RUNNING.txt | 578 +- bin/bootstrap.jar | Bin bin/catalina-tasks.xml | 122 +- bin/catalina.bat | 646 +- bin/catalina.sh | 0 bin/catalina2.sh | 0 bin/commons-daemon-native.tar.gz | Bin bin/commons-daemon.jar | Bin bin/configtest.bat | 118 +- bin/configtest.sh | 0 bin/cpappend.bat | 70 +- bin/demon.sh | 0 bin/derby.log | 10 +- bin/digest.bat | 118 +- bin/digest.sh | 0 bin/setclasspath.bat | 176 +- bin/setclasspath.sh | 0 bin/setenv.bat | 0 bin/setenv.sh | 1 + bin/shutdown.bat | 118 +- bin/shutdown.sh | 0 bin/startup.bat | 0 bin/startup.sh | 0 bin/tomcat-juli.jar | Bin bin/tomcat-native.tar.gz | Bin bin/tool-wrapper.bat | 194 +- bin/tool-wrapper.sh | 0 bin/version.bat | 118 +- bin/version.sh | 0 conf/Catalina/localhost/ROOT.xml.sample | 0 conf/catalina.policy | 492 +- conf/catalina.properties | 238 +- conf/context.xml | 68 +- conf/logging.properties | 128 +- conf/server.xml | 284 +- conf/tomcat-users.xml | 72 +- conf/web.xml | 8566 ++++++++--------- jdk/bin/ControlPanel | 0 jdk/bin/HtmlConverter | 0 jdk/bin/appletviewer | Bin jdk/bin/apt | Bin jdk/bin/extcheck | Bin jdk/bin/idlj | Bin jdk/bin/jar | Bin jdk/bin/jarsigner | Bin jdk/bin/java | Bin jdk/bin/java-rmi.cgi | 0 jdk/bin/javac | Bin jdk/bin/javadoc | Bin jdk/bin/javah | Bin jdk/bin/javap | Bin jdk/bin/javaws | Bin jdk/bin/jconsole | Bin jdk/bin/jcontrol | 0 jdk/bin/jdb | Bin jdk/bin/jhat | Bin jdk/bin/jinfo | Bin jdk/bin/jmap | Bin jdk/bin/jps | Bin jdk/bin/jrunscript | Bin jdk/bin/jsadebugd | Bin jdk/bin/jstack | Bin jdk/bin/jstat | Bin jdk/bin/jstatd | Bin jdk/bin/jvisualvm | 0 jdk/bin/keytool | Bin jdk/bin/native2ascii | Bin jdk/bin/orbd | Bin jdk/bin/pack200 | Bin jdk/bin/policytool | Bin jdk/bin/rmic | Bin jdk/bin/rmid | Bin jdk/bin/rmiregistry | Bin jdk/bin/schemagen | Bin jdk/bin/serialver | Bin jdk/bin/servertool | Bin jdk/bin/tnameserv | Bin jdk/bin/unpack200 | Bin jdk/bin/wsgen | Bin jdk/bin/wsimport | Bin jdk/bin/xjc | Bin jdk/jre/bin/ControlPanel | 0 jdk/jre/bin/java | Bin jdk/jre/bin/java_vm | Bin jdk/jre/bin/javaws | Bin jdk/jre/bin/jcontrol | 0 jdk/jre/bin/keytool | Bin jdk/jre/bin/orbd | Bin jdk/jre/bin/pack200 | Bin jdk/jre/bin/policytool | Bin jdk/jre/bin/rmid | Bin jdk/jre/bin/rmiregistry | Bin jdk/jre/bin/servertool | Bin jdk/jre/bin/tnameserv | Bin jdk/jre/bin/unpack200 | Bin jdk/jre/javaws/javaws | Bin jdk/jre/lib/deploy/messages_zh_HK.properties | 0 jdk/jre/lib/i386/client/libjsig.so | Bin jdk/jre/lib/i386/client/libjvm.so | Bin jdk/jre/lib/i386/headless/libmawt.so | Bin jdk/jre/lib/i386/jli/libjli.so | Bin jdk/jre/lib/i386/libJdbcOdbc.so | Bin jdk/jre/lib/i386/libattach.so | Bin jdk/jre/lib/i386/libawt.so | Bin jdk/jre/lib/i386/libcmm.so | Bin jdk/jre/lib/i386/libdcpr.so | Bin jdk/jre/lib/i386/libdeploy.so | Bin jdk/jre/lib/i386/libdt_socket.so | Bin jdk/jre/lib/i386/libfontmanager.so | Bin jdk/jre/lib/i386/libhprof.so | Bin jdk/jre/lib/i386/libinstrument.so | Bin jdk/jre/lib/i386/libioser12.so | Bin jdk/jre/lib/i386/libj2gss.so | Bin jdk/jre/lib/i386/libj2pcsc.so | Bin jdk/jre/lib/i386/libj2pkcs11.so | Bin jdk/jre/lib/i386/libjaas_unix.so | Bin jdk/jre/lib/i386/libjava.so | Bin jdk/jre/lib/i386/libjava_crw_demo.so | Bin jdk/jre/lib/i386/libjavaplugin_jni.so | Bin jdk/jre/lib/i386/libjavaplugin_nscp.so | Bin jdk/jre/lib/i386/libjavaplugin_nscp_gcc29.so | Bin jdk/jre/lib/i386/libjawt.so | Bin jdk/jre/lib/i386/libjdwp.so | Bin jdk/jre/lib/i386/libjpeg.so | Bin jdk/jre/lib/i386/libjsig.so | Bin jdk/jre/lib/i386/libjsound.so | Bin jdk/jre/lib/i386/libjsoundalsa.so | Bin jdk/jre/lib/i386/libmanagement.so | Bin jdk/jre/lib/i386/libmlib_image.so | Bin jdk/jre/lib/i386/libnet.so | Bin jdk/jre/lib/i386/libnio.so | Bin jdk/jre/lib/i386/libnpjp2.so | Bin jdk/jre/lib/i386/libnpt.so | Bin jdk/jre/lib/i386/librmi.so | Bin jdk/jre/lib/i386/libsaproc.so | Bin jdk/jre/lib/i386/libsplashscreen.so | Bin jdk/jre/lib/i386/libunpack.so | Bin jdk/jre/lib/i386/libverify.so | Bin jdk/jre/lib/i386/libzip.so | Bin jdk/jre/lib/i386/motif21/libmawt.so | Bin jdk/jre/lib/i386/native_threads/libhpi.so | Bin jdk/jre/lib/i386/server/libjsig.so | Bin jdk/jre/lib/i386/server/libjvm.so | Bin jdk/jre/lib/i386/xawt/libmawt.so | Bin jdk/jre/lib/jexec | Bin .../i386/ns7-gcc29/libjavaplugin_oji.so | Bin jdk/jre/plugin/i386/ns7/libjavaplugin_oji.so | Bin jdk/lib/jexec | Bin lib/activation.jar | Bin lib/annotations-api.jar | Bin lib/catalina-ant.jar | Bin lib/catalina-ha.jar | Bin lib/catalina-tribes.jar | Bin lib/catalina.jar | Bin lib/derby.jar | Bin lib/ecj-3.7.2.jar | Bin lib/el-api.jar | Bin lib/jasper-el.jar | Bin lib/jasper.jar | Bin lib/jcr-2.0.jar | Bin lib/jsp-api.jar | Bin lib/mail.jar | Bin lib/mysql-connector-java-5.0.4-bin.jar | Bin lib/postgresql.jar | Bin lib/servlet-api.jar | Bin lib/tomcat-api.jar | Bin lib/tomcat-coyote.jar | Bin lib/tomcat-dbcp.jar | Bin lib/tomcat-i18n-es.jar | Bin lib/tomcat-i18n-fr.jar | Bin lib/tomcat-i18n-ja.jar | Bin lib/tomcat-jdbc.jar | Bin lib/tomcat-util.jar | Bin source/ngasi/caimito/CaimitoConfig.java | 1 + .../ngasi/caimito/CaimitoDefaultServlet.java | 4492 ++++----- source/ngasi/caimito/CaimitoException.java | 2 +- source/ngasi/caimito/CaimitoUtil.java | 0 .../ngasi/caimito/CaimitoWebdavServlet.java | 6915 +++++++------ source/ngasi/caimito/resource/CacheMgr.java | 208 +- .../caimito/resource/CloudResourceObj.java | 240 +- .../caimito/resource/FileResourceObj.java | 394 +- .../resource/OpenStackResourceObj.java | 1503 +-- .../ngasi/caimito/resource/ResourceObj.java | 372 +- .../ngasi/caimito/resource/ResourceStore.java | 1466 +-- .../ngasi/caimito/resource/ShaftAppMgr.java | 104 +- .../caimito/resource/ShaftResourceObj.java | 114 +- webapps/RELEASE-NOTES.txt | 456 +- .../WEB-INF/caimito/config.properties.sample | 73 +- .../classes/ngasi/caimito/CaimitoConfig.class | Bin 2676 -> 2819 bytes .../caimito/CaimitoDefaultServlet$Range.class | Bin 555 -> 661 bytes .../ngasi/caimito/CaimitoDefaultServlet.class | Bin 25454 -> 30949 bytes .../ngasi/caimito/CaimitoException.class | Bin 943 -> 1241 bytes .../classes/ngasi/caimito/CaimitoUtil.class | Bin 820 -> 972 bytes .../CaimitoWebdavServlet$LockInfo.class | Bin 2998 -> 3444 bytes .../CaimitoWebdavServlet$WebdavResolver.class | Bin 868 -> 1080 bytes .../ngasi/caimito/CaimitoWebdavServlet.class | Bin 31487 -> 39667 bytes .../ngasi/caimito/WebdavServletStatus.class | Bin 2895 -> 3138 bytes .../ngasi/caimito/resource/CacheMgr.class | Bin 1519 -> 1796 bytes .../resource/CaimitoBooleanHolder.class | Bin 269 -> 367 bytes .../caimito/resource/CloudResourceObj.class | Bin 2261 -> 2668 bytes .../caimito/resource/FileResourceObj.class | Bin 4102 -> 4935 bytes .../ngasi/caimito/resource/OSRAttribute.class | Bin 1531 -> 1711 bytes .../resource/OpenStackResourceObj$1.class | Bin 607 -> 709 bytes .../resource/OpenStackResourceObj.class | Bin 7974 -> 11529 bytes .../ngasi/caimito/resource/ResourceObj.class | Bin 4040 -> 4637 bytes .../caimito/resource/ResourceStore.class | Bin 12979 -> 15321 bytes .../ngasi/caimito/resource/ShaftAppMgr.class | Bin 219 -> 304 bytes .../caimito/resource/ShaftResourceObj.class | Bin 404 -> 512 bytes webapps/WEB-INF/lib/ac.jar | Bin webapps/WEB-INF/lib/asm-3.1.jar | Bin webapps/WEB-INF/lib/gson.jar | Bin .../WEB-INF/lib/jackson-core-asl-1.8.3.jar | Bin webapps/WEB-INF/lib/jackson-jaxrs-1.8.3.jar | Bin .../WEB-INF/lib/jackson-mapper-asl-1.8.3.jar | Bin webapps/WEB-INF/lib/jackson-xc-1.8.3.jar | Bin webapps/WEB-INF/lib/jersey-client-1.10.jar | Bin webapps/WEB-INF/lib/jersey-core-1.10.jar | Bin webapps/WEB-INF/lib/jersey-json-1.10.jar | Bin webapps/WEB-INF/lib/jersey-server-1.10.jar | Bin webapps/WEB-INF/lib/jersey-servlet-1.10.jar | Bin webapps/WEB-INF/lib/jettison-1.1.jar | Bin webapps/WEB-INF/lib/jsr311-api-1.1.1.jar | Bin webapps/WEB-INF/lib/tools.jar | Bin 246626 -> 292278 bytes webapps/WEB-INF/shaft/app.properties | 0 webapps/WEB-INF/shaft/load_db.sql | 0 webapps/WEB-INF/shaft/server.properties | 0 webapps/WEB-INF/web.xml | 176 +- webapps/build.xml | 186 +- webapps/ca/public/.gitattributes | 0 webapps/ca/public/.gitignore | 0 webapps/ca/public/.htaccess | 0 webapps/ca/public/401.html | 0 webapps/ca/public/404.html | 0 webapps/ca/public/500.html | 0 .../apple-touch-icon-114x114-precomposed.png | Bin .../apple-touch-icon-57x57-precomposed.png | Bin .../apple-touch-icon-72x72-precomposed.png | Bin .../public/apple-touch-icon-precomposed.png | Bin webapps/ca/public/apple-touch-icon.png | Bin webapps/ca/public/crossdomain.xml | 0 webapps/ca/public/css/style.css | 0 webapps/ca/public/favicon.ico | Bin webapps/ca/public/humans.txt | 0 webapps/ca/public/img/.gitignore | 0 webapps/ca/public/index.html | 0 webapps/ca/public/js/libs/jquery-1.7.1.js | 0 webapps/ca/public/js/libs/jquery-1.7.1.min.js | 0 .../ca/public/js/libs/modernizr-2.5.3.min.js | 0 webapps/ca/public/js/plugins.js | 0 webapps/ca/public/js/script.js | 0 webapps/ca/public/logo.png | Bin webapps/ca/public/readme.md | 0 webapps/ca/public/robots.txt | 0 webapps/ca/public/symbol.png | Bin webapps/ca/server/pathprivileges.db | 0 webapps/ca/server/publicpaths.db | 0 webapps/favicon.ico | Bin webapps/index.jsp | 444 +- webapps/tomcat.css | 700 +- 263 files changed, 16443 insertions(+), 16368 deletions(-) mode change 100644 => 100755 LICENSE mode change 100644 => 100755 NOTICE mode change 100644 => 100755 README mode change 100644 => 100755 RELEASE-NOTES mode change 100644 => 100755 RUNNING.txt mode change 100644 => 100755 bin/bootstrap.jar mode change 100644 => 100755 bin/catalina-tasks.xml mode change 100644 => 100755 bin/catalina.bat mode change 100644 => 100755 bin/catalina.sh mode change 100644 => 100755 bin/catalina2.sh mode change 100644 => 100755 bin/commons-daemon-native.tar.gz mode change 100644 => 100755 bin/commons-daemon.jar mode change 100644 => 100755 bin/configtest.bat mode change 100644 => 100755 bin/configtest.sh mode change 100644 => 100755 bin/cpappend.bat mode change 100644 => 100755 bin/demon.sh mode change 100644 => 100755 bin/digest.bat mode change 100644 => 100755 bin/digest.sh mode change 100644 => 100755 bin/setclasspath.bat mode change 100644 => 100755 bin/setclasspath.sh mode change 100644 => 100755 bin/setenv.bat mode change 100644 => 100755 bin/setenv.sh mode change 100644 => 100755 bin/shutdown.bat mode change 100644 => 100755 bin/shutdown.sh mode change 100644 => 100755 bin/startup.bat mode change 100644 => 100755 bin/startup.sh mode change 100644 => 100755 bin/tomcat-juli.jar mode change 100644 => 100755 bin/tomcat-native.tar.gz mode change 100644 => 100755 bin/tool-wrapper.bat mode change 100644 => 100755 bin/tool-wrapper.sh mode change 100644 => 100755 bin/version.bat mode change 100644 => 100755 bin/version.sh mode change 100644 => 100755 conf/Catalina/localhost/ROOT.xml.sample mode change 100644 => 100755 conf/catalina.policy mode change 100644 => 100755 conf/catalina.properties mode change 100644 => 100755 conf/context.xml mode change 100644 => 100755 conf/logging.properties mode change 100644 => 100755 conf/server.xml mode change 100644 => 100755 conf/tomcat-users.xml mode change 100644 => 100755 conf/web.xml mode change 100644 => 100755 jdk/bin/ControlPanel mode change 100644 => 100755 jdk/bin/HtmlConverter mode change 100644 => 100755 jdk/bin/appletviewer mode change 100644 => 100755 jdk/bin/apt mode change 100644 => 100755 jdk/bin/extcheck mode change 100644 => 100755 jdk/bin/idlj mode change 100644 => 100755 jdk/bin/jar mode change 100644 => 100755 jdk/bin/jarsigner mode change 100644 => 100755 jdk/bin/java mode change 100644 => 100755 jdk/bin/java-rmi.cgi mode change 100644 => 100755 jdk/bin/javac mode change 100644 => 100755 jdk/bin/javadoc mode change 100644 => 100755 jdk/bin/javah mode change 100644 => 100755 jdk/bin/javap mode change 100644 => 100755 jdk/bin/javaws mode change 100644 => 100755 jdk/bin/jconsole mode change 100644 => 100755 jdk/bin/jcontrol mode change 100644 => 100755 jdk/bin/jdb mode change 100644 => 100755 jdk/bin/jhat mode change 100644 => 100755 jdk/bin/jinfo mode change 100644 => 100755 jdk/bin/jmap mode change 100644 => 100755 jdk/bin/jps mode change 100644 => 100755 jdk/bin/jrunscript mode change 100644 => 100755 jdk/bin/jsadebugd mode change 100644 => 100755 jdk/bin/jstack mode change 100644 => 100755 jdk/bin/jstat mode change 100644 => 100755 jdk/bin/jstatd mode change 100644 => 100755 jdk/bin/jvisualvm mode change 100644 => 100755 jdk/bin/keytool mode change 100644 => 100755 jdk/bin/native2ascii mode change 100644 => 100755 jdk/bin/orbd mode change 100644 => 100755 jdk/bin/pack200 mode change 100644 => 100755 jdk/bin/policytool mode change 100644 => 100755 jdk/bin/rmic mode change 100644 => 100755 jdk/bin/rmid mode change 100644 => 100755 jdk/bin/rmiregistry mode change 100644 => 100755 jdk/bin/schemagen mode change 100644 => 100755 jdk/bin/serialver mode change 100644 => 100755 jdk/bin/servertool mode change 100644 => 100755 jdk/bin/tnameserv mode change 100644 => 100755 jdk/bin/unpack200 mode change 100644 => 100755 jdk/bin/wsgen mode change 100644 => 100755 jdk/bin/wsimport mode change 100644 => 100755 jdk/bin/xjc mode change 100644 => 100755 jdk/jre/bin/ControlPanel mode change 100644 => 100755 jdk/jre/bin/java mode change 100644 => 100755 jdk/jre/bin/java_vm mode change 100644 => 100755 jdk/jre/bin/javaws mode change 100644 => 100755 jdk/jre/bin/jcontrol mode change 100644 => 100755 jdk/jre/bin/keytool mode change 100644 => 100755 jdk/jre/bin/orbd mode change 100644 => 100755 jdk/jre/bin/pack200 mode change 100644 => 100755 jdk/jre/bin/policytool mode change 100644 => 100755 jdk/jre/bin/rmid mode change 100644 => 100755 jdk/jre/bin/rmiregistry mode change 100644 => 100755 jdk/jre/bin/servertool mode change 100644 => 100755 jdk/jre/bin/tnameserv mode change 100644 => 100755 jdk/jre/bin/unpack200 mode change 100644 => 100755 jdk/jre/javaws/javaws mode change 100644 => 100755 jdk/jre/lib/deploy/messages_zh_HK.properties mode change 100644 => 100755 jdk/jre/lib/i386/client/libjsig.so mode change 100644 => 100755 jdk/jre/lib/i386/client/libjvm.so mode change 100644 => 100755 jdk/jre/lib/i386/headless/libmawt.so mode change 100644 => 100755 jdk/jre/lib/i386/jli/libjli.so mode change 100644 => 100755 jdk/jre/lib/i386/libJdbcOdbc.so mode change 100644 => 100755 jdk/jre/lib/i386/libattach.so mode change 100644 => 100755 jdk/jre/lib/i386/libawt.so mode change 100644 => 100755 jdk/jre/lib/i386/libcmm.so mode change 100644 => 100755 jdk/jre/lib/i386/libdcpr.so mode change 100644 => 100755 jdk/jre/lib/i386/libdeploy.so mode change 100644 => 100755 jdk/jre/lib/i386/libdt_socket.so mode change 100644 => 100755 jdk/jre/lib/i386/libfontmanager.so mode change 100644 => 100755 jdk/jre/lib/i386/libhprof.so mode change 100644 => 100755 jdk/jre/lib/i386/libinstrument.so mode change 100644 => 100755 jdk/jre/lib/i386/libioser12.so mode change 100644 => 100755 jdk/jre/lib/i386/libj2gss.so mode change 100644 => 100755 jdk/jre/lib/i386/libj2pcsc.so mode change 100644 => 100755 jdk/jre/lib/i386/libj2pkcs11.so mode change 100644 => 100755 jdk/jre/lib/i386/libjaas_unix.so mode change 100644 => 100755 jdk/jre/lib/i386/libjava.so mode change 100644 => 100755 jdk/jre/lib/i386/libjava_crw_demo.so mode change 100644 => 100755 jdk/jre/lib/i386/libjavaplugin_jni.so mode change 100644 => 100755 jdk/jre/lib/i386/libjavaplugin_nscp.so mode change 100644 => 100755 jdk/jre/lib/i386/libjavaplugin_nscp_gcc29.so mode change 100644 => 100755 jdk/jre/lib/i386/libjawt.so mode change 100644 => 100755 jdk/jre/lib/i386/libjdwp.so mode change 100644 => 100755 jdk/jre/lib/i386/libjpeg.so mode change 100644 => 100755 jdk/jre/lib/i386/libjsig.so mode change 100644 => 100755 jdk/jre/lib/i386/libjsound.so mode change 100644 => 100755 jdk/jre/lib/i386/libjsoundalsa.so mode change 100644 => 100755 jdk/jre/lib/i386/libmanagement.so mode change 100644 => 100755 jdk/jre/lib/i386/libmlib_image.so mode change 100644 => 100755 jdk/jre/lib/i386/libnet.so mode change 100644 => 100755 jdk/jre/lib/i386/libnio.so mode change 100644 => 100755 jdk/jre/lib/i386/libnpjp2.so mode change 100644 => 100755 jdk/jre/lib/i386/libnpt.so mode change 100644 => 100755 jdk/jre/lib/i386/librmi.so mode change 100644 => 100755 jdk/jre/lib/i386/libsaproc.so mode change 100644 => 100755 jdk/jre/lib/i386/libsplashscreen.so mode change 100644 => 100755 jdk/jre/lib/i386/libunpack.so mode change 100644 => 100755 jdk/jre/lib/i386/libverify.so mode change 100644 => 100755 jdk/jre/lib/i386/libzip.so mode change 100644 => 100755 jdk/jre/lib/i386/motif21/libmawt.so mode change 100644 => 100755 jdk/jre/lib/i386/native_threads/libhpi.so mode change 100644 => 100755 jdk/jre/lib/i386/server/libjsig.so mode change 100644 => 100755 jdk/jre/lib/i386/server/libjvm.so mode change 100644 => 100755 jdk/jre/lib/i386/xawt/libmawt.so mode change 100644 => 100755 jdk/jre/lib/jexec mode change 100644 => 100755 jdk/jre/plugin/i386/ns7-gcc29/libjavaplugin_oji.so mode change 100644 => 100755 jdk/jre/plugin/i386/ns7/libjavaplugin_oji.so mode change 100644 => 100755 jdk/lib/jexec mode change 100644 => 100755 lib/activation.jar mode change 100644 => 100755 lib/annotations-api.jar mode change 100644 => 100755 lib/catalina-ant.jar mode change 100644 => 100755 lib/catalina-ha.jar mode change 100644 => 100755 lib/catalina-tribes.jar mode change 100644 => 100755 lib/catalina.jar mode change 100644 => 100755 lib/derby.jar mode change 100644 => 100755 lib/ecj-3.7.2.jar mode change 100644 => 100755 lib/el-api.jar mode change 100644 => 100755 lib/jasper-el.jar mode change 100644 => 100755 lib/jasper.jar mode change 100644 => 100755 lib/jcr-2.0.jar mode change 100644 => 100755 lib/jsp-api.jar mode change 100644 => 100755 lib/mail.jar mode change 100644 => 100755 lib/mysql-connector-java-5.0.4-bin.jar mode change 100644 => 100755 lib/postgresql.jar mode change 100644 => 100755 lib/servlet-api.jar mode change 100644 => 100755 lib/tomcat-api.jar mode change 100644 => 100755 lib/tomcat-coyote.jar mode change 100644 => 100755 lib/tomcat-dbcp.jar mode change 100644 => 100755 lib/tomcat-i18n-es.jar mode change 100644 => 100755 lib/tomcat-i18n-fr.jar mode change 100644 => 100755 lib/tomcat-i18n-ja.jar mode change 100644 => 100755 lib/tomcat-jdbc.jar mode change 100644 => 100755 lib/tomcat-util.jar mode change 100644 => 100755 source/ngasi/caimito/CaimitoConfig.java mode change 100644 => 100755 source/ngasi/caimito/CaimitoDefaultServlet.java mode change 100644 => 100755 source/ngasi/caimito/CaimitoException.java mode change 100644 => 100755 source/ngasi/caimito/CaimitoUtil.java mode change 100644 => 100755 source/ngasi/caimito/CaimitoWebdavServlet.java mode change 100644 => 100755 source/ngasi/caimito/resource/CacheMgr.java mode change 100644 => 100755 source/ngasi/caimito/resource/CloudResourceObj.java mode change 100644 => 100755 source/ngasi/caimito/resource/FileResourceObj.java mode change 100644 => 100755 source/ngasi/caimito/resource/OpenStackResourceObj.java mode change 100644 => 100755 source/ngasi/caimito/resource/ResourceObj.java mode change 100644 => 100755 source/ngasi/caimito/resource/ResourceStore.java mode change 100644 => 100755 source/ngasi/caimito/resource/ShaftAppMgr.java mode change 100644 => 100755 source/ngasi/caimito/resource/ShaftResourceObj.java mode change 100644 => 100755 webapps/RELEASE-NOTES.txt mode change 100644 => 100755 webapps/WEB-INF/caimito/config.properties.sample mode change 100644 => 100755 webapps/WEB-INF/lib/ac.jar mode change 100644 => 100755 webapps/WEB-INF/lib/asm-3.1.jar mode change 100644 => 100755 webapps/WEB-INF/lib/gson.jar mode change 100644 => 100755 webapps/WEB-INF/lib/jackson-core-asl-1.8.3.jar mode change 100644 => 100755 webapps/WEB-INF/lib/jackson-jaxrs-1.8.3.jar mode change 100644 => 100755 webapps/WEB-INF/lib/jackson-mapper-asl-1.8.3.jar mode change 100644 => 100755 webapps/WEB-INF/lib/jackson-xc-1.8.3.jar mode change 100644 => 100755 webapps/WEB-INF/lib/jersey-client-1.10.jar mode change 100644 => 100755 webapps/WEB-INF/lib/jersey-core-1.10.jar mode change 100644 => 100755 webapps/WEB-INF/lib/jersey-json-1.10.jar mode change 100644 => 100755 webapps/WEB-INF/lib/jersey-server-1.10.jar mode change 100644 => 100755 webapps/WEB-INF/lib/jersey-servlet-1.10.jar mode change 100644 => 100755 webapps/WEB-INF/lib/jettison-1.1.jar mode change 100644 => 100755 webapps/WEB-INF/lib/jsr311-api-1.1.1.jar mode change 100644 => 100755 webapps/WEB-INF/shaft/app.properties mode change 100644 => 100755 webapps/WEB-INF/shaft/load_db.sql mode change 100644 => 100755 webapps/WEB-INF/shaft/server.properties mode change 100644 => 100755 webapps/WEB-INF/web.xml mode change 100644 => 100755 webapps/build.xml mode change 100644 => 100755 webapps/ca/public/.gitattributes mode change 100644 => 100755 webapps/ca/public/.gitignore mode change 100644 => 100755 webapps/ca/public/.htaccess mode change 100644 => 100755 webapps/ca/public/401.html mode change 100644 => 100755 webapps/ca/public/404.html mode change 100644 => 100755 webapps/ca/public/500.html mode change 100644 => 100755 webapps/ca/public/apple-touch-icon-114x114-precomposed.png mode change 100644 => 100755 webapps/ca/public/apple-touch-icon-57x57-precomposed.png mode change 100644 => 100755 webapps/ca/public/apple-touch-icon-72x72-precomposed.png mode change 100644 => 100755 webapps/ca/public/apple-touch-icon-precomposed.png mode change 100644 => 100755 webapps/ca/public/apple-touch-icon.png mode change 100644 => 100755 webapps/ca/public/crossdomain.xml mode change 100644 => 100755 webapps/ca/public/css/style.css mode change 100644 => 100755 webapps/ca/public/favicon.ico mode change 100644 => 100755 webapps/ca/public/humans.txt mode change 100644 => 100755 webapps/ca/public/img/.gitignore mode change 100644 => 100755 webapps/ca/public/index.html mode change 100644 => 100755 webapps/ca/public/js/libs/jquery-1.7.1.js mode change 100644 => 100755 webapps/ca/public/js/libs/jquery-1.7.1.min.js mode change 100644 => 100755 webapps/ca/public/js/libs/modernizr-2.5.3.min.js mode change 100644 => 100755 webapps/ca/public/js/plugins.js mode change 100644 => 100755 webapps/ca/public/js/script.js mode change 100644 => 100755 webapps/ca/public/logo.png mode change 100644 => 100755 webapps/ca/public/readme.md mode change 100644 => 100755 webapps/ca/public/robots.txt mode change 100644 => 100755 webapps/ca/public/symbol.png mode change 100644 => 100755 webapps/ca/server/pathprivileges.db mode change 100644 => 100755 webapps/ca/server/publicpaths.db mode change 100644 => 100755 webapps/favicon.ico mode change 100644 => 100755 webapps/index.jsp mode change 100644 => 100755 webapps/tomcat.css diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 index cbded9c..48da7e4 --- a/LICENSE +++ b/LICENSE @@ -1,1049 +1,1049 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - -APACHE TOMCAT SUBCOMPONENTS: - -Apache Tomcat includes a number of subcomponents with separate copyright notices -and license terms. Your use of these subcomponents is subject to the terms and -conditions of the following licenses. - - -For the ecj-x.x.x.jar component: - -Eclipse Public License - v 1.0 - -THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC -LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM -CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. - -1. DEFINITIONS - -"Contribution" means: - -a) in the case of the initial Contributor, the initial code and documentation -distributed under this Agreement, and - -b) in the case of each subsequent Contributor: - -i) changes to the Program, and - -ii) additions to the Program; - -where such changes and/or additions to the Program originate from and are -distributed by that particular Contributor. A Contribution 'originates' from a -Contributor if it was added to the Program by such Contributor itself or anyone -acting on such Contributor's behalf. Contributions do not include additions to -the Program which: (i) are separate modules of software distributed in -conjunction with the Program under their own license agreement, and (ii) are not -derivative works of the Program. - -"Contributor" means any person or entity that distributes the Program. - -"Licensed Patents" mean patent claims licensable by a Contributor which are -necessarily infringed by the use or sale of its Contribution alone or when -combined with the Program. - -"Program" means the Contributions distributed in accordance with this Agreement. - -"Recipient" means anyone who receives the Program under this Agreement, -including all Contributors. - -2. GRANT OF RIGHTS - -a) Subject to the terms of this Agreement, each Contributor hereby grants -Recipient a non-exclusive, worldwide, royalty-free copyright license to -reproduce, prepare derivative works of, publicly display, publicly perform, -distribute and sublicense the Contribution of such Contributor, if any, and such -derivative works, in source code and object code form. - -b) Subject to the terms of this Agreement, each Contributor hereby grants -Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed -Patents to make, use, sell, offer to sell, import and otherwise transfer the -Contribution of such Contributor, if any, in source code and object code form. -This patent license shall apply to the combination of the Contribution and the -Program if, at the time the Contribution is added by the Contributor, such -addition of the Contribution causes such combination to be covered by the -Licensed Patents. The patent license shall not apply to any other combinations -which include the Contribution. No hardware per se is licensed hereunder. - -c) Recipient understands that although each Contributor grants the licenses to -its Contributions set forth herein, no assurances are provided by any -Contributor that the Program does not infringe the patent or other intellectual -property rights of any other entity. Each Contributor disclaims any liability to -Recipient for claims brought by any other entity based on infringement of -intellectual property rights or otherwise. As a condition to exercising the -rights and licenses granted hereunder, each Recipient hereby assumes sole -responsibility to secure any other intellectual property rights needed, if any. -For example, if a third party patent license is required to allow Recipient to -distribute the Program, it is Recipient's responsibility to acquire that license -before distributing the Program. - -d) Each Contributor represents that to its knowledge it has sufficient copyright -rights in its Contribution, if any, to grant the copyright license set forth in -this Agreement. - -3. REQUIREMENTS - -A Contributor may choose to distribute the Program in object code form under its -own license agreement, provided that: - -a) it complies with the terms and conditions of this Agreement; and - -b) its license agreement: - -i) effectively disclaims on behalf of all Contributors all warranties and -conditions, express and implied, including warranties or conditions of title and -non-infringement, and implied warranties or conditions of merchantability and -fitness for a particular purpose; - -ii) effectively excludes on behalf of all Contributors all liability for -damages, including direct, indirect, special, incidental and consequential -damages, such as lost profits; - -iii) states that any provisions which differ from this Agreement are offered by -that Contributor alone and not by any other party; and - -iv) states that source code for the Program is available from such Contributor, -and informs licensees how to obtain it in a reasonable manner on or through a -medium customarily used for software exchange. - -When the Program is made available in source code form: - -a) it must be made available under this Agreement; and - -b) a copy of this Agreement must be included with each copy of the Program. - -Contributors may not remove or alter any copyright notices contained within the -Program. - -Each Contributor must identify itself as the originator of its Contribution, if -any, in a manner that reasonably allows subsequent Recipients to identify the -originator of the Contribution. - -4. COMMERCIAL DISTRIBUTION - -Commercial distributors of software may accept certain responsibilities with -respect to end users, business partners and the like. While this license is -intended to facilitate the commercial use of the Program, the Contributor who -includes the Program in a commercial product offering should do so in a manner -which does not create potential liability for other Contributors. Therefore, if -a Contributor includes the Program in a commercial product offering, such -Contributor ("Commercial Contributor") hereby agrees to defend and indemnify -every other Contributor ("Indemnified Contributor") against any losses, damages -and costs (collectively "Losses") arising from claims, lawsuits and other legal -actions brought by a third party against the Indemnified Contributor to the -extent caused by the acts or omissions of such Commercial Contributor in -connection with its distribution of the Program in a commercial product -offering. The obligations in this section do not apply to any claims or Losses -relating to any actual or alleged intellectual property infringement. In order -to qualify, an Indemnified Contributor must: a) promptly notify the Commercial -Contributor in writing of such claim, and b) allow the Commercial Contributor -to control, and cooperate with the Commercial Contributor in, the defense and -any related settlement negotiations. The Indemnified Contributor may -participate in any such claim at its own expense. - -For example, a Contributor might include the Program in a commercial product -offering, Product X. That Contributor is then a Commercial Contributor. If that -Commercial Contributor then makes performance claims, or offers warranties -related to Product X, those performance claims and warranties are such -Commercial Contributor's responsibility alone. Under this section, the -Commercial Contributor would have to defend claims against the other -Contributors related to those performance claims and warranties, and if a court -requires any other Contributor to pay any damages as a result, the Commercial -Contributor must pay those damages. - -5. NO WARRANTY - -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR -IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, -NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each -Recipient is solely responsible for determining the appropriateness of using and -distributing the Program and assumes all risks associated with its exercise of -rights under this Agreement , including but not limited to the risks and costs -of program errors, compliance with applicable laws, damage to or loss of data, -programs or equipment, and unavailability or interruption of operations. - -6. DISCLAIMER OF LIABILITY - -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY -CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST -PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS -GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -7. GENERAL - -If any provision of this Agreement is invalid or unenforceable under applicable -law, it shall not affect the validity or enforceability of the remainder of the -terms of this Agreement, and without further action by the parties hereto, such -provision shall be reformed to the minimum extent necessary to make such -provision valid and enforceable. - -If Recipient institutes patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Program itself -(excluding combinations of the Program with other software or hardware) -infringes such Recipient's patent(s), then such Recipient's rights granted under -Section 2(b) shall terminate as of the date such litigation is filed. - -All Recipient's rights under this Agreement shall terminate if it fails to -comply with any of the material terms or conditions of this Agreement and does -not cure such failure in a reasonable period of time after becoming aware of -such noncompliance. If all Recipient's rights under this Agreement terminate, -Recipient agrees to cease use and distribution of the Program as soon as -reasonably practicable. However, Recipient's obligations under this Agreement -and any licenses granted by Recipient relating to the Program shall continue and -survive. - -Everyone is permitted to copy and distribute copies of this Agreement, but in -order to avoid inconsistency the Agreement is copyrighted and may only be -modified in the following manner. The Agreement Steward reserves the right to -publish new versions (including revisions) of this Agreement from time to time. -No one other than the Agreement Steward has the right to modify this Agreement. -The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation -may assign the responsibility to serve as the Agreement Steward to a suitable -separate entity. Each new version of the Agreement will be given a -distinguishing version number. The Program (including Contributions) may always -be distributed subject to the version of the Agreement under which it was -received. In addition, after a new version of the Agreement is published, -Contributor may elect to distribute the Program (including its Contributions) -under the new version. Except as expressly stated in Sections 2(a) and 2(b) -above, Recipient receives no rights or licenses to the intellectual property of -any Contributor under this Agreement, whether expressly, by implication, -estoppel or otherwise. All rights in the Program not expressly granted under -this Agreement are reserved. - -This Agreement is governed by the laws of the State of New York and the -intellectual property laws of the United States of America. No party to this -Agreement will bring a legal action under this Agreement more than one year -after the cause of action arose. Each party waives its rights to a jury trial in -any resulting litigation. - - -For the Windows Installer component: - - * All NSIS source code, plug-ins, documentation, examples, header files and - graphics, with the exception of the compression modules and where - otherwise noted, are licensed under the zlib/libpng license. - * The zlib compression module for NSIS is licensed under the zlib/libpng - license. - * The bzip2 compression module for NSIS is licensed under the bzip2 license. - * The lzma compression module for NSIS is licensed under the Common Public - License version 1.0. - -zlib/libpng license - -This software is provided 'as-is', without any express or implied warranty. In -no event will the authors be held liable for any damages arising from the use of -this software. - -Permission is granted to anyone to use this software for any purpose, including -commercial applications, and to alter it and redistribute it freely, subject to -the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not claim - that you wrote the original software. If you use this software in a - product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - -bzip2 license - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. The origin of this software must not be misrepresented; you must not claim - that you wrote the original software. If you use this software in a - product, an acknowledgment in the product documentation would be - appreciated but is not required. - 3. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 4. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -OF SUCH DAMAGE. - -Julian Seward, Cambridge, UK. - -jseward@acm.org -Common Public License version 1.0 - -THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC -LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM -CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. - -1. DEFINITIONS - -"Contribution" means: - -a) in the case of the initial Contributor, the initial code and documentation -distributed under this Agreement, and b) in the case of each subsequent -Contributor: - -i) changes to the Program, and - -ii) additions to the Program; - -where such changes and/or additions to the Program originate from and are -distributed by that particular Contributor. A Contribution 'originates' from a -Contributor if it was added to the Program by such Contributor itself or anyone -acting on such Contributor's behalf. Contributions do not include additions to -the Program which: (i) are separate modules of software distributed in -conjunction with the Program under their own license agreement, and (ii) are not -derivative works of the Program. - -"Contributor" means any person or entity that distributes the Program. - -"Licensed Patents " mean patent claims licensable by a Contributor which are -necessarily infringed by the use or sale of its Contribution alone or when -combined with the Program. - -"Program" means the Contributions distributed in accordance with this Agreement. - -"Recipient" means anyone who receives the Program under this Agreement, -including all Contributors. - -2. GRANT OF RIGHTS - -a) Subject to the terms of this Agreement, each Contributor hereby grants -Recipient a non-exclusive, worldwide, royalty-free copyright license to -reproduce, prepare derivative works of, publicly display, publicly perform, -distribute and sublicense the Contribution of such Contributor, if any, and such -derivative works, in source code and object code form. - -b) Subject to the terms of this Agreement, each Contributor hereby grants -Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed -Patents to make, use, sell, offer to sell, import and otherwise transfer the -Contribution of such Contributor, if any, in source code and object code form. -This patent license shall apply to the combination of the Contribution and the -Program if, at the time the Contribution is added by the Contributor, such -addition of the Contribution causes such combination to be covered by the -Licensed Patents. The patent license shall not apply to any other combinations -which include the Contribution. No hardware per se is licensed hereunder. - -c) Recipient understands that although each Contributor grants the licenses to -its Contributions set forth herein, no assurances are provided by any -Contributor that the Program does not infringe the patent or other intellectual -property rights of any other entity. Each Contributor disclaims any liability to -Recipient for claims brought by any other entity based on infringement of -intellectual property rights or otherwise. As a condition to exercising the -rights and licenses granted hereunder, each Recipient hereby assumes sole -responsibility to secure any other intellectual property rights needed, if any. -For example, if a third party patent license is required to allow Recipient to -distribute the Program, it is Recipient's responsibility to acquire that license -before distributing the Program. - -d) Each Contributor represents that to its knowledge it has sufficient copyright -rights in its Contribution, if any, to grant the copyright license set forth in -this Agreement. - -3. REQUIREMENTS - -A Contributor may choose to distribute the Program in object code form under its -own license agreement, provided that: - -a) it complies with the terms and conditions of this Agreement; and - -b) its license agreement: - -i) effectively disclaims on behalf of all Contributors all warranties and -conditions, express and implied, including warranties or conditions of title and -non-infringement, and implied warranties or conditions of merchantability and -fitness for a particular purpose; - -ii) effectively excludes on behalf of all Contributors all liability for -damages, including direct, indirect, special, incidental and consequential -damages, such as lost profits; - -iii) states that any provisions which differ from this Agreement are offered by -that Contributor alone and not by any other party; and - -iv) states that source code for the Program is available from such Contributor, -and informs licensees how to obtain it in a reasonable manner on or through a -medium customarily used for software exchange. - -When the Program is made available in source code form: - -a) it must be made available under this Agreement; and - -b) a copy of this Agreement must be included with each copy of the Program. - -Contributors may not remove or alter any copyright notices contained within the -Program. - -Each Contributor must identify itself as the originator of its Contribution, if -any, in a manner that reasonably allows subsequent Recipients to identify the -originator of the Contribution. - -4. COMMERCIAL DISTRIBUTION - -Commercial distributors of software may accept certain responsibilities with -respect to end users, business partners and the like. While this license is -intended to facilitate the commercial use of the Program, the Contributor who -includes the Program in a commercial product offering should do so in a manner -which does not create potential liability for other Contributors. Therefore, if -a Contributor includes the Program in a commercial product offering, such -Contributor ("Commercial Contributor") hereby agrees to defend and indemnify -every other Contributor ("Indemnified Contributor") against any losses, damages -and costs (collectively "Losses") arising from claims, lawsuits and other legal -actions brought by a third party against the Indemnified Contributor to the -extent caused by the acts or omissions of such Commercial Contributor in -connection with its distribution of the Program in a commercial product -offering. The obligations in this section do not apply to any claims or Losses -relating to any actual or alleged intellectual property infringement. In order -to qualify, an Indemnified Contributor must: a) promptly notify the Commercial -Contributor in writing of such claim, and b) allow the Commercial Contributor to -control, and cooperate with the Commercial Contributor in, the defense and any -related settlement negotiations. The Indemnified Contributor may participate in -any such claim at its own expense. - -For example, a Contributor might include the Program in a commercial product -offering, Product X. That Contributor is then a Commercial Contributor. If that -Commercial Contributor then makes performance claims, or offers warranties -related to Product X, those performance claims and warranties are such -Commercial Contributor's responsibility alone. Under this section, the -Commercial Contributor would have to defend claims against the other -Contributors related to those performance claims and warranties, and if a court -requires any other Contributor to pay any damages as a result, the Commercial -Contributor must pay those damages. - -5. NO WARRANTY - -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR -IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, -NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each -Recipient is solely responsible for determining the appropriateness of using and -distributing the Program and assumes all risks associated with its exercise of -rights under this Agreement, including but not limited to the risks and costs of -program errors, compliance with applicable laws, damage to or loss of data, -programs or equipment, and unavailability or interruption of operations. - -6. DISCLAIMER OF LIABILITY - -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY -CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST -PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS -GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -7. GENERAL - -If any provision of this Agreement is invalid or unenforceable under applicable -law, it shall not affect the validity or enforceability of the remainder of the -terms of this Agreement, and without further action by the parties hereto, such -provision shall be reformed to the minimum extent necessary to make such -provision valid and enforceable. - -If Recipient institutes patent litigation against a Contributor with respect to -a patent applicable to software (including a cross-claim or counterclaim in a -lawsuit), then any patent licenses granted by that Contributor to such Recipient -under this Agreement shall terminate as of the date such litigation is filed. In -addition, if Recipient institutes patent litigation against any entity -(including a cross-claim or counterclaim in a lawsuit) alleging that the Program -itself (excluding combinations of the Program with other software or hardware) -infringes such Recipient's patent(s), then such Recipient's rights granted under -Section 2(b) shall terminate as of the date such litigation is filed. - -All Recipient's rights under this Agreement shall terminate if it fails to -comply with any of the material terms or conditions of this Agreement and does -not cure such failure in a reasonable period of time after becoming aware of -such noncompliance. If all Recipient's rights under this Agreement terminate, -Recipient agrees to cease use and distribution of the Program as soon as -reasonably practicable. However, Recipient's obligations under this Agreement -and any licenses granted by Recipient relating to the Program shall continue and -survive. - -Everyone is permitted to copy and distribute copies of this Agreement, but in -order to avoid inconsistency the Agreement is copyrighted and may only be -modified in the following manner. The Agreement Steward reserves the right to -publish new versions (including revisions) of this Agreement from time to time. -No one other than the Agreement Steward has the right to modify this Agreement. -IBM is the initial Agreement Steward. IBM may assign the responsibility to serve -as the Agreement Steward to a suitable separate entity. Each new version of the -Agreement will be given a distinguishing version number. The Program (including -Contributions) may always be distributed subject to the version of the Agreement -under which it was received. In addition, after a new version of the Agreement -is published, Contributor may elect to distribute the Program (including its -Contributions) under the new version. Except as expressly stated in Sections -2(a) and 2(b) above, Recipient receives no rights or licenses to the -intellectual property of any Contributor under this Agreement, whether -expressly, by implication, estoppel or otherwise. All rights in the Program not -expressly granted under this Agreement are reserved. - -This Agreement is governed by the laws of the State of New York and the -intellectual property laws of the United States of America. No party to this -Agreement will bring a legal action under this Agreement more than one year -after the cause of action arose. Each party waives its rights to a jury trial in -any resulting litigation. - -Special exception for LZMA compression module - -Igor Pavlov and Amir Szekely, the authors of the LZMA compression module for -NSIS, expressly permit you to statically or dynamically link your code (or bind -by name) to the files from the LZMA compression module for NSIS without -subjecting your linked code to the terms of the Common Public license version -1.0. Any modifications or additions to files from the LZMA compression module -for NSIS, however, are subject to the terms of the Common Public License version -1.0. - - -For the following XML Schemas for Java EE Deployment Descriptors: - - javaee_5.xsd - - javaee_web_services_1_2.xsd - - javaee_web_services_client_1_2.xsd - - javaee_6.xsd - - javaee_web_services_1_3.xsd - - javaee_web_services_client_1_3.xsd - - web-app_3_0.xsd - - web-common_3_0.xsd - - web-fragment_3_0.xsd - -COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 - -1. Definitions. - - 1.1. Contributor. means each individual or entity that creates or contributes - to the creation of Modifications. - - 1.2. Contributor Version. means the combination of the Original Software, - prior Modifications used by a Contributor (if any), and the - Modifications made by that particular Contributor. - - 1.3. Covered Software. means (a) the Original Software, or (b) Modifications, - or (c) the combination of files containing Original Software with files - containing Modifications, in each case including portions thereof. - - 1.4. Executable. means the Covered Software in any form other than Source - Code. - - 1.5. Initial Developer. means the individual or entity that first makes - Original Software available under this License. - - 1.6. Larger Work. means a work which combines Covered Software or portions - thereof with code not governed by the terms of this License. - - 1.7. License. means this document. - - 1.8. Licensable. means having the right to grant, to the maximum extent - possible, whether at the time of the initial grant or subsequently - acquired, any and all of the rights conveyed herein. - - 1.9. Modifications. means the Source Code and Executable form of any of the - following: - - A. Any file that results from an addition to, deletion from or - modification of the contents of a file containing Original Software - or previous Modifications; - - B. Any new file that contains any part of the Original Software or - previous Modification; or - - C. Any new file that is contributed or otherwise made available under - the terms of this License. - - 1.10. Original Software. means the Source Code and Executable form of - computer software code that is originally released under this License. - - 1.11. Patent Claims. means any patent claim(s), now owned or hereafter - acquired, including without limitation, method, process, and apparatus - claims, in any patent Licensable by grantor. - - 1.12. Source Code. means (a) the common form of computer software code in - which modifications are made and (b) associated documentation included - in or with such code. - - 1.13. You. (or .Your.) means an individual or a legal entity exercising - rights under, and complying with all of the terms of, this License. For - legal entities, .You. includes any entity which controls, is controlled - by, or is under common control with You. For purposes of this - definition, .control. means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. - -2. License Grants. - - 2.1. The Initial Developer Grant. - - Conditioned upon Your compliance with Section 3.1 below and subject to - third party intellectual property claims, the Initial Developer hereby - grants You a world-wide, royalty-free, non-exclusive license: - - (a) under intellectual property rights (other than patent or trademark) - Licensable by Initial Developer, to use, reproduce, modify, display, - perform, sublicense and distribute the Original Software (or - portions thereof), with or without Modifications, and/or as part of - a Larger Work; and - - (b) under Patent Claims infringed by the making, using or selling of - Original Software, to make, have made, use, practice, sell, and - offer for sale, and/or otherwise dispose of the Original Software - (or portions thereof). - - (c) The licenses granted in Sections 2.1(a) and (b) are effective on the - date Initial Developer first distributes or otherwise makes the - Original Software available to a third party under the terms of this - License. - - (d) Notwithstanding Section 2.1(b) above, no patent license is granted: - (1) for code that You delete from the Original Software, or (2) for - infringements caused by: (i) the modification of the Original - Software, or (ii) the combination of the Original Software with - other software or devices. - - 2.2. Contributor Grant. - - Conditioned upon Your compliance with Section 3.1 below and subject to third - party intellectual property claims, each Contributor hereby grants You a - world-wide, royalty-free, non-exclusive license: - - (a) under intellectual property rights (other than patent or trademark) - Licensable by Contributor to use, reproduce, modify, display, - perform, sublicense and distribute the Modifications created by such - Contributor (or portions thereof), either on an unmodified basis, - with other Modifications, as Covered Software and/or as part of a - Larger Work; and - - (b) under Patent Claims infringed by the making, using, or selling of - Modifications made by that Contributor either alone and/or in - combination with its Contributor Version (or portions of such - combination), to make, use, sell, offer for sale, have made, and/or - otherwise dispose of: (1) Modifications made by that Contributor (or - portions thereof); and (2) the combination of Modifications made by - that Contributor with its Contributor Version (or portions of such - combination). - - (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on - the date Contributor first distributes or otherwise makes the - Modifications available to a third party. - - (d) Notwithstanding Section 2.2(b) above, no patent license is granted: - (1) for any code that Contributor has deleted from the Contributor - Version; (2) for infringements caused by: (i) third party - modifications of Contributor Version, or (ii) the combination of - Modifications made by that Contributor with other software (except - as part of the Contributor Version) or other devices; or (3) under - Patent Claims infringed by Covered Software in the absence of - Modifications made by that Contributor. - -3. Distribution Obligations. - - 3.1. Availability of Source Code. - Any Covered Software that You distribute or otherwise make available in - Executable form must also be made available in Source Code form and that - Source Code form must be distributed only under the terms of this License. - You must include a copy of this License with every copy of the Source Code - form of the Covered Software You distribute or otherwise make available. - You must inform recipients of any such Covered Software in Executable form - as to how they can obtain such Covered Software in Source Code form in a - reasonable manner on or through a medium customarily used for software - exchange. - - 3.2. Modifications. - The Modifications that You create or to which You contribute are governed - by the terms of this License. You represent that You believe Your - Modifications are Your original creation(s) and/or You have sufficient - rights to grant the rights conveyed by this License. - - 3.3. Required Notices. - You must include a notice in each of Your Modifications that identifies - You as the Contributor of the Modification. You may not remove or alter - any copyright, patent or trademark notices contained within the Covered - Software, or any notices of licensing or any descriptive text giving - attribution to any Contributor or the Initial Developer. - - 3.4. Application of Additional Terms. - You may not offer or impose any terms on any Covered Software in Source - Code form that alters or restricts the applicable version of this License - or the recipients. rights hereunder. You may choose to offer, and to - charge a fee for, warranty, support, indemnity or liability obligations to - one or more recipients of Covered Software. However, you may do so only on - Your own behalf, and not on behalf of the Initial Developer or any - Contributor. You must make it absolutely clear that any such warranty, - support, indemnity or liability obligation is offered by You alone, and - You hereby agree to indemnify the Initial Developer and every Contributor - for any liability incurred by the Initial Developer or such Contributor as - a result of warranty, support, indemnity or liability terms You offer. - - 3.5. Distribution of Executable Versions. - You may distribute the Executable form of the Covered Software under the - terms of this License or under the terms of a license of Your choice, - which may contain terms different from this License, provided that You are - in compliance with the terms of this License and that the license for the - Executable form does not attempt to limit or alter the recipient.s rights - in the Source Code form from the rights set forth in this License. If You - distribute the Covered Software in Executable form under a different - license, You must make it absolutely clear that any terms which differ - from this License are offered by You alone, not by the Initial Developer - or Contributor. You hereby agree to indemnify the Initial Developer and - every Contributor for any liability incurred by the Initial Developer or - such Contributor as a result of any such terms You offer. - - 3.6. Larger Works. - You may create a Larger Work by combining Covered Software with other code - not governed by the terms of this License and distribute the Larger Work - as a single product. In such a case, You must make sure the requirements - of this License are fulfilled for the Covered Software. - -4. Versions of the License. - - 4.1. New Versions. - Sun Microsystems, Inc. is the initial license steward and may publish - revised and/or new versions of this License from time to time. Each - version will be given a distinguishing version number. Except as provided - in Section 4.3, no one other than the license steward has the right to - modify this License. - - 4.2. Effect of New Versions. - You may always continue to use, distribute or otherwise make the Covered - Software available under the terms of the version of the License under - which You originally received the Covered Software. If the Initial - Developer includes a notice in the Original Software prohibiting it from - being distributed or otherwise made available under any subsequent version - of the License, You must distribute and make the Covered Software - available under the terms of the version of the License under which You - originally received the Covered Software. Otherwise, You may also choose - to use, distribute or otherwise make the Covered Software available under - the terms of any subsequent version of the License published by the - license steward. - - 4.3. Modified Versions. - When You are an Initial Developer and You want to create a new license for - Your Original Software, You may create and use a modified version of this - License if You: (a) rename the license and remove any references to the - name of the license steward (except to note that the license differs from - this License); and (b) otherwise make it clear that the license contains - terms which differ from this License. - -5. DISCLAIMER OF WARRANTY. - - COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN .AS IS. BASIS, WITHOUT - WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT - LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, - MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK - AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD - ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL - DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY - SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN - ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED - HEREUNDER EXCEPT UNDER THIS DISCLAIMER. - -6. TERMINATION. - - 6.1. This License and the rights granted hereunder will terminate - automatically if You fail to comply with terms herein and fail to - cure such breach within 30 days of becoming aware of the breach. - Provisions which, by their nature, must remain in effect beyond the - termination of this License shall survive. - - 6.2. If You assert a patent infringement claim (excluding declaratory - judgment actions) against Initial Developer or a Contributor (the - Initial Developer or Contributor against whom You assert such claim - is referred to as .Participant.) alleging that the Participant - Software (meaning the Contributor Version where the Participant is a - Contributor or the Original Software where the Participant is the - Initial Developer) directly or indirectly infringes any patent, then - any and all rights granted directly or indirectly to You by such - Participant, the Initial Developer (if the Initial Developer is not - the Participant) and all Contributors under Sections 2.1 and/or 2.2 - of this License shall, upon 60 days notice from Participant terminate - prospectively and automatically at the expiration of such 60 day - notice period, unless if within such 60 day period You withdraw Your - claim with respect to the Participant Software against such - Participant either unilaterally or pursuant to a written agreement - with Participant. - - 6.3. In the event of termination under Sections 6.1 or 6.2 above, all end - user licenses that have been validly granted by You or any - distributor hereunder prior to termination (excluding licenses - granted to You by any distributor) shall survive termination. - -7. LIMITATION OF LIABILITY. - - UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING - NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY - OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF - ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, - INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT - LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK STOPPAGE, - COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR - LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF - SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR - DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY.S NEGLIGENCE TO THE EXTENT - APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE - EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS - EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. - -8. U.S. GOVERNMENT END USERS. - - The Covered Software is a .commercial item,. as that term is defined in 48 - C.F.R. 2.101 (Oct. 1995), consisting of .commercial computer software. (as - that term is defined at 48 C.F.R. ? 252.227-7014(a)(1)) and commercial - computer software documentation. as such terms are used in 48 C.F.R. 12.212 - (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 - through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered - Software with only those rights set forth herein. This U.S. Government Rights - clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or - provision that addresses Government rights in computer software under this - License. - -9. MISCELLANEOUS. - - This License represents the complete agreement concerning subject matter - hereof. If any provision of this License is held to be unenforceable, such - provision shall be reformed only to the extent necessary to make it - enforceable. This License shall be governed by the law of the jurisdiction - specified in a notice contained within the Original Software (except to the - extent applicable law, if any, provides otherwise), excluding such - jurisdiction's conflict-of-law provisions. Any litigation relating to this - License shall be subject to the jurisdiction of the courts located in the - jurisdiction and venue specified in a notice contained within the Original - Software, with the losing party responsible for costs, including, without - limitation, court costs and reasonable attorneys. fees and expenses. The - application of the United Nations Convention on Contracts for the - International Sale of Goods is expressly excluded. Any law or regulation - which provides that the language of a contract shall be construed against - the drafter shall not apply to this License. You agree that You alone are - responsible for compliance with the United States export administration - regulations (and the export control laws and regulation of any other - countries) when You use, distribute or otherwise make available any Covered - Software. - -10. RESPONSIBILITY FOR CLAIMS. - - As between Initial Developer and the Contributors, each party is responsible - for claims and damages arising, directly or indirectly, out of its - utilization of rights under this License and You agree to work with Initial - Developer and Contributors to distribute such responsibility on an equitable - basis. Nothing herein is intended or shall be deemed to constitute any - admission of liability. - - NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION - LICENSE (CDDL) - - The code released under the CDDL shall be governed by the laws of the State - of California (excluding conflict-of-law provisions). Any litigation relating - to this License shall be subject to the jurisdiction of the Federal Courts of - the Northern District of California and the state courts of the State of - California, with venue lying in Santa Clara County, California. - + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + +APACHE TOMCAT SUBCOMPONENTS: + +Apache Tomcat includes a number of subcomponents with separate copyright notices +and license terms. Your use of these subcomponents is subject to the terms and +conditions of the following licenses. + + +For the ecj-x.x.x.jar component: + +Eclipse Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC +LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM +CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and documentation +distributed under this Agreement, and + +b) in the case of each subsequent Contributor: + +i) changes to the Program, and + +ii) additions to the Program; + +where such changes and/or additions to the Program originate from and are +distributed by that particular Contributor. A Contribution 'originates' from a +Contributor if it was added to the Program by such Contributor itself or anyone +acting on such Contributor's behalf. Contributions do not include additions to +the Program which: (i) are separate modules of software distributed in +conjunction with the Program under their own license agreement, and (ii) are not +derivative works of the Program. + +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which are +necessarily infringed by the use or sale of its Contribution alone or when +combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, +including all Contributors. + +2. GRANT OF RIGHTS + +a) Subject to the terms of this Agreement, each Contributor hereby grants +Recipient a non-exclusive, worldwide, royalty-free copyright license to +reproduce, prepare derivative works of, publicly display, publicly perform, +distribute and sublicense the Contribution of such Contributor, if any, and such +derivative works, in source code and object code form. + +b) Subject to the terms of this Agreement, each Contributor hereby grants +Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed +Patents to make, use, sell, offer to sell, import and otherwise transfer the +Contribution of such Contributor, if any, in source code and object code form. +This patent license shall apply to the combination of the Contribution and the +Program if, at the time the Contribution is added by the Contributor, such +addition of the Contribution causes such combination to be covered by the +Licensed Patents. The patent license shall not apply to any other combinations +which include the Contribution. No hardware per se is licensed hereunder. + +c) Recipient understands that although each Contributor grants the licenses to +its Contributions set forth herein, no assurances are provided by any +Contributor that the Program does not infringe the patent or other intellectual +property rights of any other entity. Each Contributor disclaims any liability to +Recipient for claims brought by any other entity based on infringement of +intellectual property rights or otherwise. As a condition to exercising the +rights and licenses granted hereunder, each Recipient hereby assumes sole +responsibility to secure any other intellectual property rights needed, if any. +For example, if a third party patent license is required to allow Recipient to +distribute the Program, it is Recipient's responsibility to acquire that license +before distributing the Program. + +d) Each Contributor represents that to its knowledge it has sufficient copyright +rights in its Contribution, if any, to grant the copyright license set forth in +this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under its +own license agreement, provided that: + +a) it complies with the terms and conditions of this Agreement; and + +b) its license agreement: + +i) effectively disclaims on behalf of all Contributors all warranties and +conditions, express and implied, including warranties or conditions of title and +non-infringement, and implied warranties or conditions of merchantability and +fitness for a particular purpose; + +ii) effectively excludes on behalf of all Contributors all liability for +damages, including direct, indirect, special, incidental and consequential +damages, such as lost profits; + +iii) states that any provisions which differ from this Agreement are offered by +that Contributor alone and not by any other party; and + +iv) states that source code for the Program is available from such Contributor, +and informs licensees how to obtain it in a reasonable manner on or through a +medium customarily used for software exchange. + +When the Program is made available in source code form: + +a) it must be made available under this Agreement; and + +b) a copy of this Agreement must be included with each copy of the Program. + +Contributors may not remove or alter any copyright notices contained within the +Program. + +Each Contributor must identify itself as the originator of its Contribution, if +any, in a manner that reasonably allows subsequent Recipients to identify the +originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with +respect to end users, business partners and the like. While this license is +intended to facilitate the commercial use of the Program, the Contributor who +includes the Program in a commercial product offering should do so in a manner +which does not create potential liability for other Contributors. Therefore, if +a Contributor includes the Program in a commercial product offering, such +Contributor ("Commercial Contributor") hereby agrees to defend and indemnify +every other Contributor ("Indemnified Contributor") against any losses, damages +and costs (collectively "Losses") arising from claims, lawsuits and other legal +actions brought by a third party against the Indemnified Contributor to the +extent caused by the acts or omissions of such Commercial Contributor in +connection with its distribution of the Program in a commercial product +offering. The obligations in this section do not apply to any claims or Losses +relating to any actual or alleged intellectual property infringement. In order +to qualify, an Indemnified Contributor must: a) promptly notify the Commercial +Contributor in writing of such claim, and b) allow the Commercial Contributor +to control, and cooperate with the Commercial Contributor in, the defense and +any related settlement negotiations. The Indemnified Contributor may +participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product +offering, Product X. That Contributor is then a Commercial Contributor. If that +Commercial Contributor then makes performance claims, or offers warranties +related to Product X, those performance claims and warranties are such +Commercial Contributor's responsibility alone. Under this section, the +Commercial Contributor would have to defend claims against the other +Contributors related to those performance claims and warranties, and if a court +requires any other Contributor to pay any damages as a result, the Commercial +Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR +IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, +NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each +Recipient is solely responsible for determining the appropriateness of using and +distributing the Program and assumes all risks associated with its exercise of +rights under this Agreement , including but not limited to the risks and costs +of program errors, compliance with applicable laws, damage to or loss of data, +programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY +CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST +PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS +GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable +law, it shall not affect the validity or enforceability of the remainder of the +terms of this Agreement, and without further action by the parties hereto, such +provision shall be reformed to the minimum extent necessary to make such +provision valid and enforceable. + +If Recipient institutes patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Program itself +(excluding combinations of the Program with other software or hardware) +infringes such Recipient's patent(s), then such Recipient's rights granted under +Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to +comply with any of the material terms or conditions of this Agreement and does +not cure such failure in a reasonable period of time after becoming aware of +such noncompliance. If all Recipient's rights under this Agreement terminate, +Recipient agrees to cease use and distribution of the Program as soon as +reasonably practicable. However, Recipient's obligations under this Agreement +and any licenses granted by Recipient relating to the Program shall continue and +survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in +order to avoid inconsistency the Agreement is copyrighted and may only be +modified in the following manner. The Agreement Steward reserves the right to +publish new versions (including revisions) of this Agreement from time to time. +No one other than the Agreement Steward has the right to modify this Agreement. +The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation +may assign the responsibility to serve as the Agreement Steward to a suitable +separate entity. Each new version of the Agreement will be given a +distinguishing version number. The Program (including Contributions) may always +be distributed subject to the version of the Agreement under which it was +received. In addition, after a new version of the Agreement is published, +Contributor may elect to distribute the Program (including its Contributions) +under the new version. Except as expressly stated in Sections 2(a) and 2(b) +above, Recipient receives no rights or licenses to the intellectual property of +any Contributor under this Agreement, whether expressly, by implication, +estoppel or otherwise. All rights in the Program not expressly granted under +this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the +intellectual property laws of the United States of America. No party to this +Agreement will bring a legal action under this Agreement more than one year +after the cause of action arose. Each party waives its rights to a jury trial in +any resulting litigation. + + +For the Windows Installer component: + + * All NSIS source code, plug-ins, documentation, examples, header files and + graphics, with the exception of the compression modules and where + otherwise noted, are licensed under the zlib/libpng license. + * The zlib compression module for NSIS is licensed under the zlib/libpng + license. + * The bzip2 compression module for NSIS is licensed under the bzip2 license. + * The lzma compression module for NSIS is licensed under the Common Public + License version 1.0. + +zlib/libpng license + +This software is provided 'as-is', without any express or implied warranty. In +no event will the authors be held liable for any damages arising from the use of +this software. + +Permission is granted to anyone to use this software for any purpose, including +commercial applications, and to alter it and redistribute it freely, subject to +the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not claim + that you wrote the original software. If you use this software in a + product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +bzip2 license + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. The origin of this software must not be misrepresented; you must not claim + that you wrote the original software. If you use this software in a + product, an acknowledgment in the product documentation would be + appreciated but is not required. + 3. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 4. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +Julian Seward, Cambridge, UK. + +jseward@acm.org +Common Public License version 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC +LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM +CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and documentation +distributed under this Agreement, and b) in the case of each subsequent +Contributor: + +i) changes to the Program, and + +ii) additions to the Program; + +where such changes and/or additions to the Program originate from and are +distributed by that particular Contributor. A Contribution 'originates' from a +Contributor if it was added to the Program by such Contributor itself or anyone +acting on such Contributor's behalf. Contributions do not include additions to +the Program which: (i) are separate modules of software distributed in +conjunction with the Program under their own license agreement, and (ii) are not +derivative works of the Program. + +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents " mean patent claims licensable by a Contributor which are +necessarily infringed by the use or sale of its Contribution alone or when +combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, +including all Contributors. + +2. GRANT OF RIGHTS + +a) Subject to the terms of this Agreement, each Contributor hereby grants +Recipient a non-exclusive, worldwide, royalty-free copyright license to +reproduce, prepare derivative works of, publicly display, publicly perform, +distribute and sublicense the Contribution of such Contributor, if any, and such +derivative works, in source code and object code form. + +b) Subject to the terms of this Agreement, each Contributor hereby grants +Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed +Patents to make, use, sell, offer to sell, import and otherwise transfer the +Contribution of such Contributor, if any, in source code and object code form. +This patent license shall apply to the combination of the Contribution and the +Program if, at the time the Contribution is added by the Contributor, such +addition of the Contribution causes such combination to be covered by the +Licensed Patents. The patent license shall not apply to any other combinations +which include the Contribution. No hardware per se is licensed hereunder. + +c) Recipient understands that although each Contributor grants the licenses to +its Contributions set forth herein, no assurances are provided by any +Contributor that the Program does not infringe the patent or other intellectual +property rights of any other entity. Each Contributor disclaims any liability to +Recipient for claims brought by any other entity based on infringement of +intellectual property rights or otherwise. As a condition to exercising the +rights and licenses granted hereunder, each Recipient hereby assumes sole +responsibility to secure any other intellectual property rights needed, if any. +For example, if a third party patent license is required to allow Recipient to +distribute the Program, it is Recipient's responsibility to acquire that license +before distributing the Program. + +d) Each Contributor represents that to its knowledge it has sufficient copyright +rights in its Contribution, if any, to grant the copyright license set forth in +this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under its +own license agreement, provided that: + +a) it complies with the terms and conditions of this Agreement; and + +b) its license agreement: + +i) effectively disclaims on behalf of all Contributors all warranties and +conditions, express and implied, including warranties or conditions of title and +non-infringement, and implied warranties or conditions of merchantability and +fitness for a particular purpose; + +ii) effectively excludes on behalf of all Contributors all liability for +damages, including direct, indirect, special, incidental and consequential +damages, such as lost profits; + +iii) states that any provisions which differ from this Agreement are offered by +that Contributor alone and not by any other party; and + +iv) states that source code for the Program is available from such Contributor, +and informs licensees how to obtain it in a reasonable manner on or through a +medium customarily used for software exchange. + +When the Program is made available in source code form: + +a) it must be made available under this Agreement; and + +b) a copy of this Agreement must be included with each copy of the Program. + +Contributors may not remove or alter any copyright notices contained within the +Program. + +Each Contributor must identify itself as the originator of its Contribution, if +any, in a manner that reasonably allows subsequent Recipients to identify the +originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with +respect to end users, business partners and the like. While this license is +intended to facilitate the commercial use of the Program, the Contributor who +includes the Program in a commercial product offering should do so in a manner +which does not create potential liability for other Contributors. Therefore, if +a Contributor includes the Program in a commercial product offering, such +Contributor ("Commercial Contributor") hereby agrees to defend and indemnify +every other Contributor ("Indemnified Contributor") against any losses, damages +and costs (collectively "Losses") arising from claims, lawsuits and other legal +actions brought by a third party against the Indemnified Contributor to the +extent caused by the acts or omissions of such Commercial Contributor in +connection with its distribution of the Program in a commercial product +offering. The obligations in this section do not apply to any claims or Losses +relating to any actual or alleged intellectual property infringement. In order +to qualify, an Indemnified Contributor must: a) promptly notify the Commercial +Contributor in writing of such claim, and b) allow the Commercial Contributor to +control, and cooperate with the Commercial Contributor in, the defense and any +related settlement negotiations. The Indemnified Contributor may participate in +any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product +offering, Product X. That Contributor is then a Commercial Contributor. If that +Commercial Contributor then makes performance claims, or offers warranties +related to Product X, those performance claims and warranties are such +Commercial Contributor's responsibility alone. Under this section, the +Commercial Contributor would have to defend claims against the other +Contributors related to those performance claims and warranties, and if a court +requires any other Contributor to pay any damages as a result, the Commercial +Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR +IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, +NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each +Recipient is solely responsible for determining the appropriateness of using and +distributing the Program and assumes all risks associated with its exercise of +rights under this Agreement, including but not limited to the risks and costs of +program errors, compliance with applicable laws, damage to or loss of data, +programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY +CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST +PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS +GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable +law, it shall not affect the validity or enforceability of the remainder of the +terms of this Agreement, and without further action by the parties hereto, such +provision shall be reformed to the minimum extent necessary to make such +provision valid and enforceable. + +If Recipient institutes patent litigation against a Contributor with respect to +a patent applicable to software (including a cross-claim or counterclaim in a +lawsuit), then any patent licenses granted by that Contributor to such Recipient +under this Agreement shall terminate as of the date such litigation is filed. In +addition, if Recipient institutes patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging that the Program +itself (excluding combinations of the Program with other software or hardware) +infringes such Recipient's patent(s), then such Recipient's rights granted under +Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to +comply with any of the material terms or conditions of this Agreement and does +not cure such failure in a reasonable period of time after becoming aware of +such noncompliance. If all Recipient's rights under this Agreement terminate, +Recipient agrees to cease use and distribution of the Program as soon as +reasonably practicable. However, Recipient's obligations under this Agreement +and any licenses granted by Recipient relating to the Program shall continue and +survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in +order to avoid inconsistency the Agreement is copyrighted and may only be +modified in the following manner. The Agreement Steward reserves the right to +publish new versions (including revisions) of this Agreement from time to time. +No one other than the Agreement Steward has the right to modify this Agreement. +IBM is the initial Agreement Steward. IBM may assign the responsibility to serve +as the Agreement Steward to a suitable separate entity. Each new version of the +Agreement will be given a distinguishing version number. The Program (including +Contributions) may always be distributed subject to the version of the Agreement +under which it was received. In addition, after a new version of the Agreement +is published, Contributor may elect to distribute the Program (including its +Contributions) under the new version. Except as expressly stated in Sections +2(a) and 2(b) above, Recipient receives no rights or licenses to the +intellectual property of any Contributor under this Agreement, whether +expressly, by implication, estoppel or otherwise. All rights in the Program not +expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the +intellectual property laws of the United States of America. No party to this +Agreement will bring a legal action under this Agreement more than one year +after the cause of action arose. Each party waives its rights to a jury trial in +any resulting litigation. + +Special exception for LZMA compression module + +Igor Pavlov and Amir Szekely, the authors of the LZMA compression module for +NSIS, expressly permit you to statically or dynamically link your code (or bind +by name) to the files from the LZMA compression module for NSIS without +subjecting your linked code to the terms of the Common Public license version +1.0. Any modifications or additions to files from the LZMA compression module +for NSIS, however, are subject to the terms of the Common Public License version +1.0. + + +For the following XML Schemas for Java EE Deployment Descriptors: + - javaee_5.xsd + - javaee_web_services_1_2.xsd + - javaee_web_services_client_1_2.xsd + - javaee_6.xsd + - javaee_web_services_1_3.xsd + - javaee_web_services_client_1_3.xsd + - web-app_3_0.xsd + - web-common_3_0.xsd + - web-fragment_3_0.xsd + +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + +1. Definitions. + + 1.1. Contributor. means each individual or entity that creates or contributes + to the creation of Modifications. + + 1.2. Contributor Version. means the combination of the Original Software, + prior Modifications used by a Contributor (if any), and the + Modifications made by that particular Contributor. + + 1.3. Covered Software. means (a) the Original Software, or (b) Modifications, + or (c) the combination of files containing Original Software with files + containing Modifications, in each case including portions thereof. + + 1.4. Executable. means the Covered Software in any form other than Source + Code. + + 1.5. Initial Developer. means the individual or entity that first makes + Original Software available under this License. + + 1.6. Larger Work. means a work which combines Covered Software or portions + thereof with code not governed by the terms of this License. + + 1.7. License. means this document. + + 1.8. Licensable. means having the right to grant, to the maximum extent + possible, whether at the time of the initial grant or subsequently + acquired, any and all of the rights conveyed herein. + + 1.9. Modifications. means the Source Code and Executable form of any of the + following: + + A. Any file that results from an addition to, deletion from or + modification of the contents of a file containing Original Software + or previous Modifications; + + B. Any new file that contains any part of the Original Software or + previous Modification; or + + C. Any new file that is contributed or otherwise made available under + the terms of this License. + + 1.10. Original Software. means the Source Code and Executable form of + computer software code that is originally released under this License. + + 1.11. Patent Claims. means any patent claim(s), now owned or hereafter + acquired, including without limitation, method, process, and apparatus + claims, in any patent Licensable by grantor. + + 1.12. Source Code. means (a) the common form of computer software code in + which modifications are made and (b) associated documentation included + in or with such code. + + 1.13. You. (or .Your.) means an individual or a legal entity exercising + rights under, and complying with all of the terms of, this License. For + legal entities, .You. includes any entity which controls, is controlled + by, or is under common control with You. For purposes of this + definition, .control. means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + +2. License Grants. + + 2.1. The Initial Developer Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject to + third party intellectual property claims, the Initial Developer hereby + grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or trademark) + Licensable by Initial Developer, to use, reproduce, modify, display, + perform, sublicense and distribute the Original Software (or + portions thereof), with or without Modifications, and/or as part of + a Larger Work; and + + (b) under Patent Claims infringed by the making, using or selling of + Original Software, to make, have made, use, practice, sell, and + offer for sale, and/or otherwise dispose of the Original Software + (or portions thereof). + + (c) The licenses granted in Sections 2.1(a) and (b) are effective on the + date Initial Developer first distributes or otherwise makes the + Original Software available to a third party under the terms of this + License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is granted: + (1) for code that You delete from the Original Software, or (2) for + infringements caused by: (i) the modification of the Original + Software, or (ii) the combination of the Original Software with + other software or devices. + + 2.2. Contributor Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject to third + party intellectual property claims, each Contributor hereby grants You a + world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or trademark) + Licensable by Contributor to use, reproduce, modify, display, + perform, sublicense and distribute the Modifications created by such + Contributor (or portions thereof), either on an unmodified basis, + with other Modifications, as Covered Software and/or as part of a + Larger Work; and + + (b) under Patent Claims infringed by the making, using, or selling of + Modifications made by that Contributor either alone and/or in + combination with its Contributor Version (or portions of such + combination), to make, use, sell, offer for sale, have made, and/or + otherwise dispose of: (1) Modifications made by that Contributor (or + portions thereof); and (2) the combination of Modifications made by + that Contributor with its Contributor Version (or portions of such + combination). + + (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on + the date Contributor first distributes or otherwise makes the + Modifications available to a third party. + + (d) Notwithstanding Section 2.2(b) above, no patent license is granted: + (1) for any code that Contributor has deleted from the Contributor + Version; (2) for infringements caused by: (i) third party + modifications of Contributor Version, or (ii) the combination of + Modifications made by that Contributor with other software (except + as part of the Contributor Version) or other devices; or (3) under + Patent Claims infringed by Covered Software in the absence of + Modifications made by that Contributor. + +3. Distribution Obligations. + + 3.1. Availability of Source Code. + Any Covered Software that You distribute or otherwise make available in + Executable form must also be made available in Source Code form and that + Source Code form must be distributed only under the terms of this License. + You must include a copy of this License with every copy of the Source Code + form of the Covered Software You distribute or otherwise make available. + You must inform recipients of any such Covered Software in Executable form + as to how they can obtain such Covered Software in Source Code form in a + reasonable manner on or through a medium customarily used for software + exchange. + + 3.2. Modifications. + The Modifications that You create or to which You contribute are governed + by the terms of this License. You represent that You believe Your + Modifications are Your original creation(s) and/or You have sufficient + rights to grant the rights conveyed by this License. + + 3.3. Required Notices. + You must include a notice in each of Your Modifications that identifies + You as the Contributor of the Modification. You may not remove or alter + any copyright, patent or trademark notices contained within the Covered + Software, or any notices of licensing or any descriptive text giving + attribution to any Contributor or the Initial Developer. + + 3.4. Application of Additional Terms. + You may not offer or impose any terms on any Covered Software in Source + Code form that alters or restricts the applicable version of this License + or the recipients. rights hereunder. You may choose to offer, and to + charge a fee for, warranty, support, indemnity or liability obligations to + one or more recipients of Covered Software. However, you may do so only on + Your own behalf, and not on behalf of the Initial Developer or any + Contributor. You must make it absolutely clear that any such warranty, + support, indemnity or liability obligation is offered by You alone, and + You hereby agree to indemnify the Initial Developer and every Contributor + for any liability incurred by the Initial Developer or such Contributor as + a result of warranty, support, indemnity or liability terms You offer. + + 3.5. Distribution of Executable Versions. + You may distribute the Executable form of the Covered Software under the + terms of this License or under the terms of a license of Your choice, + which may contain terms different from this License, provided that You are + in compliance with the terms of this License and that the license for the + Executable form does not attempt to limit or alter the recipient.s rights + in the Source Code form from the rights set forth in this License. If You + distribute the Covered Software in Executable form under a different + license, You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial Developer + or Contributor. You hereby agree to indemnify the Initial Developer and + every Contributor for any liability incurred by the Initial Developer or + such Contributor as a result of any such terms You offer. + + 3.6. Larger Works. + You may create a Larger Work by combining Covered Software with other code + not governed by the terms of this License and distribute the Larger Work + as a single product. In such a case, You must make sure the requirements + of this License are fulfilled for the Covered Software. + +4. Versions of the License. + + 4.1. New Versions. + Sun Microsystems, Inc. is the initial license steward and may publish + revised and/or new versions of this License from time to time. Each + version will be given a distinguishing version number. Except as provided + in Section 4.3, no one other than the license steward has the right to + modify this License. + + 4.2. Effect of New Versions. + You may always continue to use, distribute or otherwise make the Covered + Software available under the terms of the version of the License under + which You originally received the Covered Software. If the Initial + Developer includes a notice in the Original Software prohibiting it from + being distributed or otherwise made available under any subsequent version + of the License, You must distribute and make the Covered Software + available under the terms of the version of the License under which You + originally received the Covered Software. Otherwise, You may also choose + to use, distribute or otherwise make the Covered Software available under + the terms of any subsequent version of the License published by the + license steward. + + 4.3. Modified Versions. + When You are an Initial Developer and You want to create a new license for + Your Original Software, You may create and use a modified version of this + License if You: (a) rename the license and remove any references to the + name of the license steward (except to note that the license differs from + this License); and (b) otherwise make it clear that the license contains + terms which differ from this License. + +5. DISCLAIMER OF WARRANTY. + + COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN .AS IS. BASIS, WITHOUT + WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT + LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, + MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK + AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD + ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL + DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY + SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN + ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED + HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +6. TERMINATION. + + 6.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to + cure such breach within 30 days of becoming aware of the breach. + Provisions which, by their nature, must remain in effect beyond the + termination of this License shall survive. + + 6.2. If You assert a patent infringement claim (excluding declaratory + judgment actions) against Initial Developer or a Contributor (the + Initial Developer or Contributor against whom You assert such claim + is referred to as .Participant.) alleging that the Participant + Software (meaning the Contributor Version where the Participant is a + Contributor or the Original Software where the Participant is the + Initial Developer) directly or indirectly infringes any patent, then + any and all rights granted directly or indirectly to You by such + Participant, the Initial Developer (if the Initial Developer is not + the Participant) and all Contributors under Sections 2.1 and/or 2.2 + of this License shall, upon 60 days notice from Participant terminate + prospectively and automatically at the expiration of such 60 day + notice period, unless if within such 60 day period You withdraw Your + claim with respect to the Participant Software against such + Participant either unilaterally or pursuant to a written agreement + with Participant. + + 6.3. In the event of termination under Sections 6.1 or 6.2 above, all end + user licenses that have been validly granted by You or any + distributor hereunder prior to termination (excluding licenses + granted to You by any distributor) shall survive termination. + +7. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING + NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY + OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF + ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, + INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT + LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK STOPPAGE, + COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR + LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF + SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR + DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY.S NEGLIGENCE TO THE EXTENT + APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS + EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +8. U.S. GOVERNMENT END USERS. + + The Covered Software is a .commercial item,. as that term is defined in 48 + C.F.R. 2.101 (Oct. 1995), consisting of .commercial computer software. (as + that term is defined at 48 C.F.R. ? 252.227-7014(a)(1)) and commercial + computer software documentation. as such terms are used in 48 C.F.R. 12.212 + (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 + through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered + Software with only those rights set forth herein. This U.S. Government Rights + clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or + provision that addresses Government rights in computer software under this + License. + +9. MISCELLANEOUS. + + This License represents the complete agreement concerning subject matter + hereof. If any provision of this License is held to be unenforceable, such + provision shall be reformed only to the extent necessary to make it + enforceable. This License shall be governed by the law of the jurisdiction + specified in a notice contained within the Original Software (except to the + extent applicable law, if any, provides otherwise), excluding such + jurisdiction's conflict-of-law provisions. Any litigation relating to this + License shall be subject to the jurisdiction of the courts located in the + jurisdiction and venue specified in a notice contained within the Original + Software, with the losing party responsible for costs, including, without + limitation, court costs and reasonable attorneys. fees and expenses. The + application of the United Nations Convention on Contracts for the + International Sale of Goods is expressly excluded. Any law or regulation + which provides that the language of a contract shall be construed against + the drafter shall not apply to this License. You agree that You alone are + responsible for compliance with the United States export administration + regulations (and the export control laws and regulation of any other + countries) when You use, distribute or otherwise make available any Covered + Software. + +10. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is responsible + for claims and damages arising, directly or indirectly, out of its + utilization of rights under this License and You agree to work with Initial + Developer and Contributors to distribute such responsibility on an equitable + basis. Nothing herein is intended or shall be deemed to constitute any + admission of liability. + + NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION + LICENSE (CDDL) + + The code released under the CDDL shall be governed by the laws of the State + of California (excluding conflict-of-law provisions). Any litigation relating + to this License shall be subject to the jurisdiction of the Federal Courts of + the Northern District of California and the state courts of the State of + California, with venue lying in Santa Clara County, California. + diff --git a/NOTICE b/NOTICE old mode 100644 new mode 100755 index 30d31d5..91916d3 --- a/NOTICE +++ b/NOTICE @@ -1,36 +1,36 @@ -Apache Tomcat -Copyright 1999-2012 The Apache Software Foundation - -This product includes software developed by -The Apache Software Foundation (http://www.apache.org/). - -The Windows Installer is built with the Nullsoft -Scriptable Install System (NSIS), which is -open source software. The original software and -related information is available at -http://nsis.sourceforge.net. - -Java compilation software for JSP pages is provided by Eclipse, -which is open source software. The original software and -related information is available at -http://www.eclipse.org. - -For the bayeux implementation -The org.apache.cometd.bayeux API is derivative work originating at the Dojo Foundation -* Copyright 2007-2008 Guy Molinari -* Copyright 2007-2008 Filip Hanik -* Copyright 2007 Dojo Foundation -* Copyright 2007 Mort Bay Consulting Pty. Ltd. - -The original XML Schemas for Java EE Deployment Descriptors: - - javaee_5.xsd - - javaee_web_services_1_2.xsd - - javaee_web_services_client_1_2.xsd - - javaee_6.xsd - - javaee_web_services_1_3.xsd - - javaee_web_services_client_1_3.xsd - - web-app_3_0.xsd - - web-common_3_0.xsd - - web-fragment_3_0.xsd - - jsp_2_2.xsd -may be obtained from http://java.sun.com/xml/ns/javaee/ +Apache Tomcat +Copyright 1999-2012 The Apache Software Foundation + +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). + +The Windows Installer is built with the Nullsoft +Scriptable Install System (NSIS), which is +open source software. The original software and +related information is available at +http://nsis.sourceforge.net. + +Java compilation software for JSP pages is provided by Eclipse, +which is open source software. The original software and +related information is available at +http://www.eclipse.org. + +For the bayeux implementation +The org.apache.cometd.bayeux API is derivative work originating at the Dojo Foundation +* Copyright 2007-2008 Guy Molinari +* Copyright 2007-2008 Filip Hanik +* Copyright 2007 Dojo Foundation +* Copyright 2007 Mort Bay Consulting Pty. Ltd. + +The original XML Schemas for Java EE Deployment Descriptors: + - javaee_5.xsd + - javaee_web_services_1_2.xsd + - javaee_web_services_client_1_2.xsd + - javaee_6.xsd + - javaee_web_services_1_3.xsd + - javaee_web_services_client_1_3.xsd + - web-app_3_0.xsd + - web-common_3_0.xsd + - web-fragment_3_0.xsd + - jsp_2_2.xsd +may be obtained from http://java.sun.com/xml/ns/javaee/ diff --git a/README b/README old mode 100644 new mode 100755 index 94949a5..ce0fe3a --- a/README +++ b/README @@ -1,111 +1,111 @@ -Caimito is an open source (Apache Software License 2.0) WebDAV,caching, and content-delivery server frontend for cloud storage. Caimito supports Softlayer Object Storage, Open Stack Storage, and Amazon S3. Caimito also features a REST interface for configuring user access. Caimito is ideal for Hosting and Reseller environments. - -Requirements -Requires any Linux distro. - -Download -http://cloud-drive.ngasi.com/s1/f1/caimito/public/caimito.zip - -Install -cd to /usr directory -unzip caimito contents to directory then copy 2 configuration files. -cd /usr unzip -q -o -a caimito.zip cp /usr/caimito/conf/Catalina/localhost/ROOT.xml.sample /usr/caimito/conf/Catalina/localhost/ROOT.xml cp /usr/caimito/webapps/WEB-INF/caimito/config.properties.sample /usr/caimito/webapps/WEB-INF/caimito/config.properties - -Configure -Database -Caimito is installed with a default Derby Database. -To change the database, edit the following file: -/usr/caimito/conf/Catalina/localhost/ROOT.xml -Resource Storage -The resource storage type and access info is set in the following file: -/usr/caimito/webapps/WEB-INF/caimito/config.properties -The default storage type is "file". To change to a Cloud storage, edit the value for "resource". The value for Open Stack and Softlayer Object Storage would be "openstack" (Amazon S3 support coming soon). The values for "cloud.username", "cloud.api.key_password", "cloud.url", and "cloud.store" should be populated with the appropriate information. "cloud.store" is populated with the name of an already created "container" or "bucket". - -Run -cd /usr/caimito/bin -./startup.sh - -To run as a Deamon: -./demon.sh - -To Stop: -./shutdown.sh - -Access: -Point any HTTP enabled client to: -http://hostname:8619/ -NOTE: Make sure access to port 8619 is enabled through any firewall. - -By default access is restricted so you would be prompted to login. Login with the following information: -User: caimitoadmin Password: caimito -The above is the default Super Admin user. Follow the instructions below to change the password. - -Configuring Users: -There are 4 default levels of Users. They are listed below in hierarchical order: -Super Admin -is the single user that has overriding control over all other users. The Super Admin has the privilege to create one or more Directory Admin and assign access to the Directory Admin to a sub directory. -Directory Admin -A Directory Admin has the privilege to create one or more Client and assign access to the client to a directory owned by the Directory Admin. -Client -A Client has the privilege to create one or more End User and assign access to the End User to a directory owned by the Client. -End User -Although the End User may have directory access, the End User has no administrative privilege. -Configuring User access is a 2 step process. First the User is created, then the specific directory access is granted. -Below is the steps to do so with the REST API. (The REST API is based on Shaftwork framework.) -Create User -http://hostname:8619/ca/shaftrest/shaftusermgr/add?shaftuser.new=user1&shaftpassword.new=tiger&shaftuser=caimitoadmin&shaftpassword=caimito -Here a Directory Admin, user1, was created with the password tiger. -Set Directory Privilege -http://hostname:8619/ca/shaftrest/pathprivileges/add?shaftuser=caimitoadmin&shaftpassword=caimito&resourceuser=user1&path=dirpath1&privilege=2&maxspace=20 -Here user1, was assigned access to dirpath1 with a max space of 20GB. The directory path is an absolute path relative to the root directory path of the User (the root path for the Super Admin is /). So the newly protected path would look like: -http://hostname:8619/dirpath1 -In the above example, the privilege was set with a value of 2. A privilege of 2 signifies READ/WRITE access. A privilege of 1 signifies READ only access. -Privileges: -1 -READ only -2 -READ/WRITE -Public Paths -Authentication may not be required for all directory paths. In these situations, you set public path access - which means world read access to the directory. -http://hostname:8619/ca/shaftrest/publicpaths/add?shaftuser=user1&shaftpassword=tiger&path=dirpath1/public&listing=false -In the above example, the path, dirpath1/public, was set to world readable access. So the public path would look like: -http://hostname:8619/dirpath1/public -Also in this example, the optional "listing" attribute was set to false. If "listing" is set the true, users would be able to see a list of the contents contained in the directory. -Change Password -http://hostname:8619/ca/shaftrest/shaftusermgr/update?shaftpassword.new=lion&shaftuser=user1&shaftpassword=tiger -The above example changes the password for user1 to lion. -Delete User -http://hostname:8619/ca/shaftrest/shaftusermgr/delete?shaftuser.eq=user1&shaftuser=caimitoadmin&shaftpassword=caimito -The above example removes user1. -Delete Directory Privilege -http://hostname:8619/ca/shaftrest/pathprivileges/delete?shaftuser=caimitoadmin&shaftpassword=caimito&resourceuser.eq=user1&path.eq=dirpath1 -Here user1's privilege to dirpath1 was removed. -Delete Public Paths -http://hostname:8619/ca/shaftrest/publicpaths/delete?shaftuser=user1&shaftpassword=tiger&path.eq=dirpath1/public -In the above example, world readable access to dirpath1/public, was removed. - -Mounting Caimito as a File System -Windows -Right Click "Computer" -Click "Add a network location" -Enter the appropriate Caimito URL and login credentials. -Linux -Download and install one of the packages at the following link: -http://pkgs.repoforge.org/davfs2/ -Add Caimito access info like so -echo "http://hostname:8619 caimitoadmin caimito" >> /etc/davfs2/secrets -Create a directory to map the mounted file system -mkdir /clouddrive -Mount Caimito like so: -mount -t davfs http://hostname:8619 /clouddrive -Virtuozzo and OpenVZ -Install fuse on the Host system like so: -yum -y install fuse -Then set the following for the VPS like so: -vzctl set 227 --devnodes fuse:rw --save - -Web Interface -COMING SOON! - -Community -Contact: support(AT)ngasi.com +Caimito is an open source (Apache Software License 2.0) WebDAV,caching, and content-delivery server frontend for cloud storage. Caimito supports Softlayer Object Storage, Open Stack Storage, and Amazon S3. Caimito also features a REST interface for configuring user access. Caimito is ideal for Hosting and Reseller environments. + +Requirements +Requires any Linux distro. + +Download +http://cloud-drive.ngasi.com/s1/f1/caimito/public/caimito.zip + +Install +cd to /usr directory +unzip caimito contents to directory then copy 2 configuration files. +cd /usr unzip -q -o -a caimito.zip cp /usr/caimito/conf/Catalina/localhost/ROOT.xml.sample /usr/caimito/conf/Catalina/localhost/ROOT.xml cp /usr/caimito/webapps/WEB-INF/caimito/config.properties.sample /usr/caimito/webapps/WEB-INF/caimito/config.properties + +Configure +Database +Caimito is installed with a default Derby Database. +To change the database, edit the following file: +/usr/caimito/conf/Catalina/localhost/ROOT.xml +Resource Storage +The resource storage type and access info is set in the following file: +/usr/caimito/webapps/WEB-INF/caimito/config.properties +The default storage type is "file". To change to a Cloud storage, edit the value for "resource". The value for Open Stack and Softlayer Object Storage would be "openstack" (Amazon S3 support coming soon). The values for "cloud.username", "cloud.api.key_password", "cloud.url", and "cloud.store" should be populated with the appropriate information. "cloud.store" is populated with the name of an already created "container" or "bucket". + +Run +cd /usr/caimito/bin +./startup.sh + +To run as a Deamon: +./demon.sh + +To Stop: +./shutdown.sh + +Access: +Point any HTTP enabled client to: +http://hostname:8619/ +NOTE: Make sure access to port 8619 is enabled through any firewall. + +By default access is restricted so you would be prompted to login. Login with the following information: +User: caimitoadmin Password: caimito +The above is the default Super Admin user. Follow the instructions below to change the password. + +Configuring Users: +There are 4 default levels of Users. They are listed below in hierarchical order: +Super Admin +is the single user that has overriding control over all other users. The Super Admin has the privilege to create one or more Directory Admin and assign access to the Directory Admin to a sub directory. +Directory Admin +A Directory Admin has the privilege to create one or more Client and assign access to the client to a directory owned by the Directory Admin. +Client +A Client has the privilege to create one or more End User and assign access to the End User to a directory owned by the Client. +End User +Although the End User may have directory access, the End User has no administrative privilege. +Configuring User access is a 2 step process. First the User is created, then the specific directory access is granted. +Below is the steps to do so with the REST API. (The REST API is based on Shaftwork framework.) +Create User +http://hostname:8619/ca/shaftrest/shaftusermgr/add?shaftuser.new=user1&shaftpassword.new=tiger&shaftuser=caimitoadmin&shaftpassword=caimito +Here a Directory Admin, user1, was created with the password tiger. +Set Directory Privilege +http://hostname:8619/ca/shaftrest/pathprivileges/add?shaftuser=caimitoadmin&shaftpassword=caimito&resourceuser=user1&path=dirpath1&privilege=2&maxspace=20 +Here user1, was assigned access to dirpath1 with a max space of 20GB. The directory path is an absolute path relative to the root directory path of the User (the root path for the Super Admin is /). So the newly protected path would look like: +http://hostname:8619/dirpath1 +In the above example, the privilege was set with a value of 2. A privilege of 2 signifies READ/WRITE access. A privilege of 1 signifies READ only access. +Privileges: +1 +READ only +2 +READ/WRITE +Public Paths +Authentication may not be required for all directory paths. In these situations, you set public path access - which means world read access to the directory. +http://hostname:8619/ca/shaftrest/publicpaths/add?shaftuser=user1&shaftpassword=tiger&path=dirpath1/public&listing=false +In the above example, the path, dirpath1/public, was set to world readable access. So the public path would look like: +http://hostname:8619/dirpath1/public +Also in this example, the optional "listing" attribute was set to false. If "listing" is set the true, users would be able to see a list of the contents contained in the directory. +Change Password +http://hostname:8619/ca/shaftrest/shaftusermgr/update?shaftpassword.new=lion&shaftuser=user1&shaftpassword=tiger +The above example changes the password for user1 to lion. +Delete User +http://hostname:8619/ca/shaftrest/shaftusermgr/delete?shaftuser.eq=user1&shaftuser=caimitoadmin&shaftpassword=caimito +The above example removes user1. +Delete Directory Privilege +http://hostname:8619/ca/shaftrest/pathprivileges/delete?shaftuser=caimitoadmin&shaftpassword=caimito&resourceuser.eq=user1&path.eq=dirpath1 +Here user1's privilege to dirpath1 was removed. +Delete Public Paths +http://hostname:8619/ca/shaftrest/publicpaths/delete?shaftuser=user1&shaftpassword=tiger&path.eq=dirpath1/public +In the above example, world readable access to dirpath1/public, was removed. + +Mounting Caimito as a File System +Windows +Right Click "Computer" +Click "Add a network location" +Enter the appropriate Caimito URL and login credentials. +Linux +Download and install one of the packages at the following link: +http://pkgs.repoforge.org/davfs2/ +Add Caimito access info like so +echo "http://hostname:8619 caimitoadmin caimito" >> /etc/davfs2/secrets +Create a directory to map the mounted file system +mkdir /clouddrive +Mount Caimito like so: +mount -t davfs http://hostname:8619 /clouddrive +Virtuozzo and OpenVZ +Install fuse on the Host system like so: +yum -y install fuse +Then set the following for the VPS like so: +vzctl set 227 --devnodes fuse:rw --save + +Web Interface +COMING SOON! + +Community +Contact: support(AT)ngasi.com diff --git a/RELEASE-NOTES b/RELEASE-NOTES old mode 100644 new mode 100755 index f6f9391..a811a2b --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,228 +1,228 @@ -================================================================================ - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -================================================================================ - -$Id: RELEASE-NOTES 1189163 2011-10-26 12:19:26Z kkolinko $ - - - Apache Tomcat Version 7.0.27 - Release Notes - - -========= -CONTENTS: -========= - -* Dependency Changes -* API Stability -* JNI Based Applications -* Bundled APIs -* Web application reloading and static fields in shared libraries -* Tomcat on Linux -* Enabling SSI and CGI Support -* Security manager URLs -* Symlinking static resources -* Viewing the Tomcat Change Log -* Cryptographic software notice -* When all else fails - - -=================== -Dependency Changes: -=================== -Tomcat 7.0 is designed to run on Java SE 6 and later. - -In addition, Tomcat 7.0 uses the Eclipse JDT Java compiler for -compiling JSP pages. This means you no longer need to have the complete -Java Development Kit (JDK) to run Tomcat, but a Java Runtime Environment -(JRE) is sufficient. The Eclipse JDT Java compiler is bundled with the -binary Tomcat distributions. Tomcat can also be configured to use the -compiler from the JDK to compile JSPs, or any other Java compiler supported -by Apache Ant. - - -============== -API Stability: -============== -The public interfaces for the following classes are fixed and will not be -changed at all during the remaining lifetime of the 7.x series: -- javax/**/* - -The public interfaces for the following classes may be added to in order to -resolve bugs and/or add new features. No existing interface will be removed or -changed although it may be deprecated. -- org/apache/catalina/* -- org/apache/catalina/comet/* - -Note: As Tomcat 7 matures, the above list will be added to. The list is not - considered complete at this time. - -The remaining classes are considered part of the Tomcat internals and may change -without notice between point releases. - - -======================= -JNI Based Applications: -======================= -Applications that require native libraries must ensure that the libraries have -been loaded prior to use. Typically, this is done with a call like: - - static { - System.loadLibrary("path-to-library-file"); - } - -in some class. However, the application must also ensure that the library is -not loaded more than once. If the above code were placed in a class inside -the web application (i.e. under /WEB-INF/classes or /WEB-INF/lib), and the -application were reloaded, the loadLibrary() call would be attempted a second -time. - -To avoid this problem, place classes that load native libraries outside of the -web application, and ensure that the loadLibrary() call is executed only once -during the lifetime of a particular JVM. - - -============= -Bundled APIs: -============= -A standard installation of Tomcat 7.0 makes all of the following APIs available -for use by web applications (by placing them in "lib"): -* annotations-api.jar (Annotations package) -* catalina.jar (Tomcat Catalina implementation) -* catalina-ant.jar (Tomcat Catalina Ant tasks) -* catalina-ha.jar (High availability package) -* catalina-tribes.jar (Group communication) -* ecj-3.7.2.jar (Eclipse JDT Java compiler) -* el-api.jar (EL 2.2 API) -* jasper.jar (Jasper 2 Compiler and Runtime) -* jasper-el.jar (Jasper 2 EL implementation) -* jsp-api.jar (JSP 2.2 API) -* servlet-api.jar (Servlet 3.0 API) -* tomcat-api.jar (Interfaces shared by Catalina and Jasper) -* tomcat-coyote.jar (Tomcat connectors and utility classes) -* tomcat-dbcp.jar (package renamed database connection pool based on Commons DBCP) - -You can make additional APIs available to all of your web applications by -putting unpacked classes into a "classes" directory (not created by default), -or by placing them in JAR files in the "lib" directory. - -To override the XML parser implementation or interfaces, use the endorsed -mechanism of the JVM. The default configuration defines JARs located in -"endorsed" as endorsed. - - -================================================================ -Web application reloading and static fields in shared libraries: -================================================================ -Some shared libraries (many are part of the JDK) keep references to objects -instantiated by the web application. To avoid class loading related problems -(ClassCastExceptions, messages indicating that the classloader -is stopped, etc.), the shared libraries state should be reinitialized. - -Something which might help is to avoid putting classes which would be -referenced by a shared static field in the web application classloader, -and putting them in the shared classloader instead (JARs should be put in the -"lib" folder, and classes should be put in the "classes" folder). - - -================ -Tomcat on Linux: -================ -GLIBC 2.2 / Linux 2.4 users should define an environment variable: -export LD_ASSUME_KERNEL=2.2.5 - -Redhat Linux 9.0 users should use the following setting to avoid -stability problems: -export LD_ASSUME_KERNEL=2.4.1 - -There are some Linux bugs reported against the NIO sendfile behavior, make sure you -have a JDK that is up to date, or disable sendfile behavior in the Connector.
-6427312: (fc) FileChannel.transferTo() throws IOException "system call interrupted"
-5103988: (fc) FileChannel.transferTo should return -1 for EAGAIN instead throws IOException
-6253145: (fc) FileChannel.transferTo on Linux fails when going beyond 2GB boundary
-6470086: (fc) FileChannel.transferTo(2147483647, 1, channel) cause "Value too large" exception
- - -============================= -Enabling SSI and CGI Support: -============================= -Because of the security risks associated with CGI and SSI available -to web applications, these features are disabled by default. - -To enable and configure CGI support, please see the cgi-howto.html page. - -To enable and configue SSI support, please see the ssi-howto.html page. - - -====================== -Security manager URLs: -====================== -In order to grant security permissions to JARs located inside the -web application repository, use URLs of of the following format -in your policy file: - -file:${catalina.base}/webapps/examples/WEB-INF/lib/driver.jar - - -============================ -Symlinking static resources: -============================ -By default, Unix symlinks will not work when used in a web application to link -resources located outside the web application root directory. - -This behavior is optional, and the "allowLinking" flag may be used to disable -the check. - - -============================== -Viewing the Tomcat Change Log: -============================== -See changelog.html in this directory. - - -============================= -Cryptographic software notice -============================= -This distribution includes cryptographic software. The country in -which you currently reside may have restrictions on the import, -possession, use, and/or re-export to another country, of -encryption software. BEFORE using any encryption software, please -check your country's laws, regulations and policies concerning the -import, possession, or use, and re-export of encryption software, to -see if this is permitted. See for more -information. - -The U.S. Government Department of Commerce, Bureau of Industry and -Security (BIS), has classified this software as Export Commodity -Control Number (ECCN) 5D002.C.1, which includes information security -software using or performing cryptographic functions with asymmetric -algorithms. The form and manner of this Apache Software Foundation -distribution makes it eligible for export under the License Exception -ENC Technology Software Unrestricted (TSU) exception (see the BIS -Export Administration Regulations, Section 740.13) for both object -code and source code. - -The following provides more details on the included cryptographic -software: - - Tomcat includes code designed to work with JSSE - - Tomcat includes code designed to work with OpenSSL - - -==================== -When all else fails: -==================== -See the FAQ -http://tomcat.apache.org/faq/ +================================================================================ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +================================================================================ + +$Id: RELEASE-NOTES 1189163 2011-10-26 12:19:26Z kkolinko $ + + + Apache Tomcat Version 7.0.27 + Release Notes + + +========= +CONTENTS: +========= + +* Dependency Changes +* API Stability +* JNI Based Applications +* Bundled APIs +* Web application reloading and static fields in shared libraries +* Tomcat on Linux +* Enabling SSI and CGI Support +* Security manager URLs +* Symlinking static resources +* Viewing the Tomcat Change Log +* Cryptographic software notice +* When all else fails + + +=================== +Dependency Changes: +=================== +Tomcat 7.0 is designed to run on Java SE 6 and later. + +In addition, Tomcat 7.0 uses the Eclipse JDT Java compiler for +compiling JSP pages. This means you no longer need to have the complete +Java Development Kit (JDK) to run Tomcat, but a Java Runtime Environment +(JRE) is sufficient. The Eclipse JDT Java compiler is bundled with the +binary Tomcat distributions. Tomcat can also be configured to use the +compiler from the JDK to compile JSPs, or any other Java compiler supported +by Apache Ant. + + +============== +API Stability: +============== +The public interfaces for the following classes are fixed and will not be +changed at all during the remaining lifetime of the 7.x series: +- javax/**/* + +The public interfaces for the following classes may be added to in order to +resolve bugs and/or add new features. No existing interface will be removed or +changed although it may be deprecated. +- org/apache/catalina/* +- org/apache/catalina/comet/* + +Note: As Tomcat 7 matures, the above list will be added to. The list is not + considered complete at this time. + +The remaining classes are considered part of the Tomcat internals and may change +without notice between point releases. + + +======================= +JNI Based Applications: +======================= +Applications that require native libraries must ensure that the libraries have +been loaded prior to use. Typically, this is done with a call like: + + static { + System.loadLibrary("path-to-library-file"); + } + +in some class. However, the application must also ensure that the library is +not loaded more than once. If the above code were placed in a class inside +the web application (i.e. under /WEB-INF/classes or /WEB-INF/lib), and the +application were reloaded, the loadLibrary() call would be attempted a second +time. + +To avoid this problem, place classes that load native libraries outside of the +web application, and ensure that the loadLibrary() call is executed only once +during the lifetime of a particular JVM. + + +============= +Bundled APIs: +============= +A standard installation of Tomcat 7.0 makes all of the following APIs available +for use by web applications (by placing them in "lib"): +* annotations-api.jar (Annotations package) +* catalina.jar (Tomcat Catalina implementation) +* catalina-ant.jar (Tomcat Catalina Ant tasks) +* catalina-ha.jar (High availability package) +* catalina-tribes.jar (Group communication) +* ecj-3.7.2.jar (Eclipse JDT Java compiler) +* el-api.jar (EL 2.2 API) +* jasper.jar (Jasper 2 Compiler and Runtime) +* jasper-el.jar (Jasper 2 EL implementation) +* jsp-api.jar (JSP 2.2 API) +* servlet-api.jar (Servlet 3.0 API) +* tomcat-api.jar (Interfaces shared by Catalina and Jasper) +* tomcat-coyote.jar (Tomcat connectors and utility classes) +* tomcat-dbcp.jar (package renamed database connection pool based on Commons DBCP) + +You can make additional APIs available to all of your web applications by +putting unpacked classes into a "classes" directory (not created by default), +or by placing them in JAR files in the "lib" directory. + +To override the XML parser implementation or interfaces, use the endorsed +mechanism of the JVM. The default configuration defines JARs located in +"endorsed" as endorsed. + + +================================================================ +Web application reloading and static fields in shared libraries: +================================================================ +Some shared libraries (many are part of the JDK) keep references to objects +instantiated by the web application. To avoid class loading related problems +(ClassCastExceptions, messages indicating that the classloader +is stopped, etc.), the shared libraries state should be reinitialized. + +Something which might help is to avoid putting classes which would be +referenced by a shared static field in the web application classloader, +and putting them in the shared classloader instead (JARs should be put in the +"lib" folder, and classes should be put in the "classes" folder). + + +================ +Tomcat on Linux: +================ +GLIBC 2.2 / Linux 2.4 users should define an environment variable: +export LD_ASSUME_KERNEL=2.2.5 + +Redhat Linux 9.0 users should use the following setting to avoid +stability problems: +export LD_ASSUME_KERNEL=2.4.1 + +There are some Linux bugs reported against the NIO sendfile behavior, make sure you +have a JDK that is up to date, or disable sendfile behavior in the Connector.
+6427312: (fc) FileChannel.transferTo() throws IOException "system call interrupted"
+5103988: (fc) FileChannel.transferTo should return -1 for EAGAIN instead throws IOException
+6253145: (fc) FileChannel.transferTo on Linux fails when going beyond 2GB boundary
+6470086: (fc) FileChannel.transferTo(2147483647, 1, channel) cause "Value too large" exception
+ + +============================= +Enabling SSI and CGI Support: +============================= +Because of the security risks associated with CGI and SSI available +to web applications, these features are disabled by default. + +To enable and configure CGI support, please see the cgi-howto.html page. + +To enable and configue SSI support, please see the ssi-howto.html page. + + +====================== +Security manager URLs: +====================== +In order to grant security permissions to JARs located inside the +web application repository, use URLs of of the following format +in your policy file: + +file:${catalina.base}/webapps/examples/WEB-INF/lib/driver.jar + + +============================ +Symlinking static resources: +============================ +By default, Unix symlinks will not work when used in a web application to link +resources located outside the web application root directory. + +This behavior is optional, and the "allowLinking" flag may be used to disable +the check. + + +============================== +Viewing the Tomcat Change Log: +============================== +See changelog.html in this directory. + + +============================= +Cryptographic software notice +============================= +This distribution includes cryptographic software. The country in +which you currently reside may have restrictions on the import, +possession, use, and/or re-export to another country, of +encryption software. BEFORE using any encryption software, please +check your country's laws, regulations and policies concerning the +import, possession, or use, and re-export of encryption software, to +see if this is permitted. See for more +information. + +The U.S. Government Department of Commerce, Bureau of Industry and +Security (BIS), has classified this software as Export Commodity +Control Number (ECCN) 5D002.C.1, which includes information security +software using or performing cryptographic functions with asymmetric +algorithms. The form and manner of this Apache Software Foundation +distribution makes it eligible for export under the License Exception +ENC Technology Software Unrestricted (TSU) exception (see the BIS +Export Administration Regulations, Section 740.13) for both object +code and source code. + +The following provides more details on the included cryptographic +software: + - Tomcat includes code designed to work with JSSE + - Tomcat includes code designed to work with OpenSSL + + +==================== +When all else fails: +==================== +See the FAQ +http://tomcat.apache.org/faq/ diff --git a/RUNNING.txt b/RUNNING.txt old mode 100644 new mode 100755 index bf37d60..8ccc91d --- a/RUNNING.txt +++ b/RUNNING.txt @@ -1,289 +1,289 @@ -================================================================================ - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -================================================================================ - -$Id: RUNNING.txt 1196746 2011-11-02 18:31:50Z kkolinko $ - - =================================================== - Running The Apache Tomcat 7.0 Servlet/JSP Container - =================================================== - -Apache Tomcat 7.0 requires the Java Standard Edition Runtime -Environment (JRE) version 6.0 or later. - -============================= -Running With JRE 6.0 Or Later -============================= - -(1) Download and Install the Java SE Runtime Environment (JRE) - -(1.1) Download the Java SE Runtime Environment (JRE), - release version 6.0 or later, from - http://www.oracle.com/technetwork/java/javase/downloads/index.html - -(1.2) Install the JRE according to the instructions included with the - release. - - You may also use the full JDK rather than just the JRE. In this - case set you have to configure your environment variables - differently - see below. - - -(2) Download and Install the Tomcat Binary Distribution - -(2.1) Download a binary distribution of Tomcat from: - - http://tomcat.apache.org/ - -(2.2) Unpack the binary distribution into a convenient location so that the - distribution resides in its own directory (conventionally named - "apache-tomcat-[version]"). - - For the purposes of the remainder of this document, the name - "CATALINA_HOME" is used to refer to the full pathname of the release - directory. - -NOTE: As an alternative to downloading a binary distribution, you can -create your own from the Tomcat source code, as described in -"BUILDING.txt". You can either - - a) Do the full "release" build and find the created distributive in the - "output/release" directory and then proceed with unpacking as above, or - - b) Do a simple build and use the "output/build" directory as - "CATALINA_HOME". Be warned that there are some differences between - contents of "output/build" and the official "release" distributive. - - -(3) Configure Environment Variables - -Tomcat itself is a Java application and does not use environment variables, -but the startup scripts use them to prepare the command that starts Tomcat. -The full list of supported environment variables is provided as a comment -at the top of catalina.bat (Windows) and catalina.sh (Unix) files. - -(3.1) CATALINA_HOME and CATALINA_BASE - -The CATALINA_HOME and CATALINA_BASE environment variables are used to -specify location of Tomcat itself and of its active configuration -respectively. - -The CATALINA_HOME environment variable should be set as defined in (2.2) -above. The startup scripts have some logic to set this variable -automatically if it is absent (based on the location of the script in -Unixes and on the current directory in Windows), but it might be not -perfect. - -The CATALINA_BASE environment variable is optional and is further described -in "Multiple Tomcat Instances" section below. If it is not set it defaults -to be equal to CATALINA_HOME. - -(3.2) JRE_HOME and other variables - -The third and the last environment variable that is needed to start Tomcat -specifies location of JRE or JDK that should be used to start Tomcat. - -There are two different names of this variable, depending on whether JRE or -JDK is used. Use the JRE_HOME variable to specify location of a JRE and -JAVA_HOME variable to specify location of a JDK. - -All variables except CATALINA_HOME and CATALINA_BASE can be configured in a -setenv.bat (Windows) or setenv.sh (Unix) file. The setenv file can be either -in CATALINA_BASE/bin or in CATALINA_HOME/bin. If both are present, only the -one in CATALINA_BASE is used. - -So, either set JRE_HOME variable by yourselves or create the file. For -example, - -On Windows, %CATALINA_BASE%\bin\setenv.bat: - - set "JRE_HOME=%ProgramFiles%\Java\jre6" - exit /b 0 - -On Unix, $CATALINA_BASE/bin/setenv.sh: - - JRE_HOME=/usr/java/latest - - -(4) Start Up Tomcat - -(4.1) Tomcat can be started by executing one of the following commands: - - %CATALINA_HOME%\bin\startup.bat (Windows) - - $CATALINA_HOME/bin/startup.sh (Unix) - - or - - %CATALINA_HOME%\bin\catalina.bat start (Windows) - - $CATALINA_HOME/bin/catalina.sh start (Unix) - -(4.2) After startup, the default web applications included with Tomcat will be - available by visiting: - - http://localhost:8080/ - -(4.3) Further information about configuring and running Tomcat can be found in - the documentation included here, as well as on the Tomcat web site: - - http://tomcat.apache.org/ - - -(5) Shut Down Tomcat - -(5.1) Tomcat can be shut down by executing one of the following commands: - - %CATALINA_HOME%\bin\shutdown.bat (Windows) - - $CATALINA_HOME/bin/shutdown.sh (Unix) - - or - - %CATALINA_HOME%\bin\catalina.bat stop (Windows) - - $CATALINA_HOME/bin/catalina.sh stop (Unix) - -================================================== -Advanced Configuration - Multiple Tomcat Instances -================================================== - -In many circumstances, it is desirable to have a single copy of a Tomcat -binary distribution shared among multiple users on the same server. To make -this possible, you can set the CATALINA_BASE environment variable to the -directory that contains the files for your 'personal' Tomcat instance. - -When running with separate CATALINA_HOME and CATALINA_BASE, the files -and directories are split as following: - -In CATALINA_BASE: - - * bin - Only the following files: - - * setenv.sh (*nix) or setenv.bat (Windows), - * tomcat-juli.jar - - The setenv scripts were described above. The tomcat-juli library - is documented in the Logging chapter in the User Guide. - - * conf - Server configuration files (including server.xml) - - * lib - Libraries and classes - - * logs - Log and output files - - * webapps - Automatically loaded web applications - - * work - Temporary working directories for web applications - - * temp - Directory used by the JVM for temporary files (java.io.tmpdir) - - -In CATALINA_HOME: - - * bin - Startup and shutdown scripts - - The following files will be used only if they are absent in - CATALINA_BASE/bin: - - setenv.sh (*nix), setenv.bat (Windows), tomcat-juli.jar - - * lib - Libraries and classes, as explained below - - * endorsed - Libraries that override standard "Endorsed Standards" - libraries provided by JRE. See Classloading documentation - in the User Guide for details. - - By default this "endorsed" directory is absent. - -In the default configuration the JAR libraries and classes both in -CATALINA_BASE/lib and in CATALINA_HOME/lib will be added to the common -classpath, but the ones in CATALINA_BASE will be added first and thus will -be searched first. - -The idea is that you may leave the standard Tomcat libraries in -CATALINA_HOME/lib and add other ones such as database drivers into -CATALINA_BASE/lib. - -In general it is advised to never share libraries between web applications, -but put them into WEB-INF/lib directories inside the applications. See -Classloading documentation in the User Guide for details. - - -It might be useful to note that the values of CATALINA_HOME and -CATALINA_BASE can be referenced in the XML configuration files processed -by Tomcat as ${catalina.home} and ${catalina.base} respectively. - -For example, the standard manager web application can be kept in -CATALINA_HOME/webapps/manager and loaded into CATALINA_BASE by using -the following trick: - - * Copy the CATALINA_HOME/webapps/manager/META-INF/context.xml - file as CATALINA_BASE/conf/Catalina/localhost/manager.xml - - * Add docBase attribute as shown below. - -The file will look like the following: - - - - - -See Deployer chapter in User Guide and Context and Host chapters in the -Configuration Reference for more information on contexts and web -application deployment. - - -================ -Troubleshooting -================ - -There are only really 3 things likely to go wrong during the stand-alone -Tomcat install: - -(1) The most common hiccup is when another web server (or any process for that - matter) has laid claim to port 8080. This is the default HTTP port that - Tomcat attempts to bind to at startup. To change this, open the file: - - $CATALINA_HOME/conf/server.xml - - and search for '8080'. Change it to a port that isn't in use, and is - greater than 1024, as ports less than or equal to 1024 require superuser - access to bind under UNIX. - - Restart Tomcat and you're in business. Be sure that you replace the "8080" - in the URL you're using to access Tomcat. For example, if you change the - port to 1977, you would request the URL http://localhost:1977/ in your browser. - -(2) An "out of environment space" error when running the batch files in - Windows 95, 98, or ME operating systems. - - Right-click on the STARTUP.BAT and SHUTDOWN.BAT files. Click on - "Properties", then on the "Memory" tab. For the "Initial environment" field, - enter in something like 4096. - - After you click apply, Windows will create shortcuts which you can use - to start and stop the container. - -(3) The 'localhost' machine isn't found. This could happen if you're behind a - proxy. If that's the case, make sure the proxy configuration for your - browser knows that you shouldn't be going through the proxy to access the - "localhost". - - In Firefox, this is under Tools/Preferences -> Advanced/Network -> - Connection -> Settings..., and in Internet Explorer it is Tools -> - Internet Options -> Connections -> LAN Settings. +================================================================================ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +================================================================================ + +$Id: RUNNING.txt 1196746 2011-11-02 18:31:50Z kkolinko $ + + =================================================== + Running The Apache Tomcat 7.0 Servlet/JSP Container + =================================================== + +Apache Tomcat 7.0 requires the Java Standard Edition Runtime +Environment (JRE) version 6.0 or later. + +============================= +Running With JRE 6.0 Or Later +============================= + +(1) Download and Install the Java SE Runtime Environment (JRE) + +(1.1) Download the Java SE Runtime Environment (JRE), + release version 6.0 or later, from + http://www.oracle.com/technetwork/java/javase/downloads/index.html + +(1.2) Install the JRE according to the instructions included with the + release. + + You may also use the full JDK rather than just the JRE. In this + case set you have to configure your environment variables + differently - see below. + + +(2) Download and Install the Tomcat Binary Distribution + +(2.1) Download a binary distribution of Tomcat from: + + http://tomcat.apache.org/ + +(2.2) Unpack the binary distribution into a convenient location so that the + distribution resides in its own directory (conventionally named + "apache-tomcat-[version]"). + + For the purposes of the remainder of this document, the name + "CATALINA_HOME" is used to refer to the full pathname of the release + directory. + +NOTE: As an alternative to downloading a binary distribution, you can +create your own from the Tomcat source code, as described in +"BUILDING.txt". You can either + + a) Do the full "release" build and find the created distributive in the + "output/release" directory and then proceed with unpacking as above, or + + b) Do a simple build and use the "output/build" directory as + "CATALINA_HOME". Be warned that there are some differences between + contents of "output/build" and the official "release" distributive. + + +(3) Configure Environment Variables + +Tomcat itself is a Java application and does not use environment variables, +but the startup scripts use them to prepare the command that starts Tomcat. +The full list of supported environment variables is provided as a comment +at the top of catalina.bat (Windows) and catalina.sh (Unix) files. + +(3.1) CATALINA_HOME and CATALINA_BASE + +The CATALINA_HOME and CATALINA_BASE environment variables are used to +specify location of Tomcat itself and of its active configuration +respectively. + +The CATALINA_HOME environment variable should be set as defined in (2.2) +above. The startup scripts have some logic to set this variable +automatically if it is absent (based on the location of the script in +Unixes and on the current directory in Windows), but it might be not +perfect. + +The CATALINA_BASE environment variable is optional and is further described +in "Multiple Tomcat Instances" section below. If it is not set it defaults +to be equal to CATALINA_HOME. + +(3.2) JRE_HOME and other variables + +The third and the last environment variable that is needed to start Tomcat +specifies location of JRE or JDK that should be used to start Tomcat. + +There are two different names of this variable, depending on whether JRE or +JDK is used. Use the JRE_HOME variable to specify location of a JRE and +JAVA_HOME variable to specify location of a JDK. + +All variables except CATALINA_HOME and CATALINA_BASE can be configured in a +setenv.bat (Windows) or setenv.sh (Unix) file. The setenv file can be either +in CATALINA_BASE/bin or in CATALINA_HOME/bin. If both are present, only the +one in CATALINA_BASE is used. + +So, either set JRE_HOME variable by yourselves or create the file. For +example, + +On Windows, %CATALINA_BASE%\bin\setenv.bat: + + set "JRE_HOME=%ProgramFiles%\Java\jre6" + exit /b 0 + +On Unix, $CATALINA_BASE/bin/setenv.sh: + + JRE_HOME=/usr/java/latest + + +(4) Start Up Tomcat + +(4.1) Tomcat can be started by executing one of the following commands: + + %CATALINA_HOME%\bin\startup.bat (Windows) + + $CATALINA_HOME/bin/startup.sh (Unix) + + or + + %CATALINA_HOME%\bin\catalina.bat start (Windows) + + $CATALINA_HOME/bin/catalina.sh start (Unix) + +(4.2) After startup, the default web applications included with Tomcat will be + available by visiting: + + http://localhost:8080/ + +(4.3) Further information about configuring and running Tomcat can be found in + the documentation included here, as well as on the Tomcat web site: + + http://tomcat.apache.org/ + + +(5) Shut Down Tomcat + +(5.1) Tomcat can be shut down by executing one of the following commands: + + %CATALINA_HOME%\bin\shutdown.bat (Windows) + + $CATALINA_HOME/bin/shutdown.sh (Unix) + + or + + %CATALINA_HOME%\bin\catalina.bat stop (Windows) + + $CATALINA_HOME/bin/catalina.sh stop (Unix) + +================================================== +Advanced Configuration - Multiple Tomcat Instances +================================================== + +In many circumstances, it is desirable to have a single copy of a Tomcat +binary distribution shared among multiple users on the same server. To make +this possible, you can set the CATALINA_BASE environment variable to the +directory that contains the files for your 'personal' Tomcat instance. + +When running with separate CATALINA_HOME and CATALINA_BASE, the files +and directories are split as following: + +In CATALINA_BASE: + + * bin - Only the following files: + + * setenv.sh (*nix) or setenv.bat (Windows), + * tomcat-juli.jar + + The setenv scripts were described above. The tomcat-juli library + is documented in the Logging chapter in the User Guide. + + * conf - Server configuration files (including server.xml) + + * lib - Libraries and classes + + * logs - Log and output files + + * webapps - Automatically loaded web applications + + * work - Temporary working directories for web applications + + * temp - Directory used by the JVM for temporary files (java.io.tmpdir) + + +In CATALINA_HOME: + + * bin - Startup and shutdown scripts + + The following files will be used only if they are absent in + CATALINA_BASE/bin: + + setenv.sh (*nix), setenv.bat (Windows), tomcat-juli.jar + + * lib - Libraries and classes, as explained below + + * endorsed - Libraries that override standard "Endorsed Standards" + libraries provided by JRE. See Classloading documentation + in the User Guide for details. + + By default this "endorsed" directory is absent. + +In the default configuration the JAR libraries and classes both in +CATALINA_BASE/lib and in CATALINA_HOME/lib will be added to the common +classpath, but the ones in CATALINA_BASE will be added first and thus will +be searched first. + +The idea is that you may leave the standard Tomcat libraries in +CATALINA_HOME/lib and add other ones such as database drivers into +CATALINA_BASE/lib. + +In general it is advised to never share libraries between web applications, +but put them into WEB-INF/lib directories inside the applications. See +Classloading documentation in the User Guide for details. + + +It might be useful to note that the values of CATALINA_HOME and +CATALINA_BASE can be referenced in the XML configuration files processed +by Tomcat as ${catalina.home} and ${catalina.base} respectively. + +For example, the standard manager web application can be kept in +CATALINA_HOME/webapps/manager and loaded into CATALINA_BASE by using +the following trick: + + * Copy the CATALINA_HOME/webapps/manager/META-INF/context.xml + file as CATALINA_BASE/conf/Catalina/localhost/manager.xml + + * Add docBase attribute as shown below. + +The file will look like the following: + + + + + +See Deployer chapter in User Guide and Context and Host chapters in the +Configuration Reference for more information on contexts and web +application deployment. + + +================ +Troubleshooting +================ + +There are only really 3 things likely to go wrong during the stand-alone +Tomcat install: + +(1) The most common hiccup is when another web server (or any process for that + matter) has laid claim to port 8080. This is the default HTTP port that + Tomcat attempts to bind to at startup. To change this, open the file: + + $CATALINA_HOME/conf/server.xml + + and search for '8080'. Change it to a port that isn't in use, and is + greater than 1024, as ports less than or equal to 1024 require superuser + access to bind under UNIX. + + Restart Tomcat and you're in business. Be sure that you replace the "8080" + in the URL you're using to access Tomcat. For example, if you change the + port to 1977, you would request the URL http://localhost:1977/ in your browser. + +(2) An "out of environment space" error when running the batch files in + Windows 95, 98, or ME operating systems. + + Right-click on the STARTUP.BAT and SHUTDOWN.BAT files. Click on + "Properties", then on the "Memory" tab. For the "Initial environment" field, + enter in something like 4096. + + After you click apply, Windows will create shortcuts which you can use + to start and stop the container. + +(3) The 'localhost' machine isn't found. This could happen if you're behind a + proxy. If that's the case, make sure the proxy configuration for your + browser knows that you shouldn't be going through the proxy to access the + "localhost". + + In Firefox, this is under Tools/Preferences -> Advanced/Network -> + Connection -> Settings..., and in Internet Explorer it is Tools -> + Internet Options -> Connections -> LAN Settings. diff --git a/bin/bootstrap.jar b/bin/bootstrap.jar old mode 100644 new mode 100755 diff --git a/bin/catalina-tasks.xml b/bin/catalina-tasks.xml old mode 100644 new mode 100755 index a40314a..ae5a20d --- a/bin/catalina-tasks.xml +++ b/bin/catalina-tasks.xml @@ -1,61 +1,61 @@ - - - - - - Catalina Ant Manager, JMX and JSPC Tasks - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + Catalina Ant Manager, JMX and JSPC Tasks + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bin/catalina.bat b/bin/catalina.bat old mode 100644 new mode 100755 index 611b4cb..fa96fde --- a/bin/catalina.bat +++ b/bin/catalina.bat @@ -1,323 +1,323 @@ -@echo off -rem Licensed to the Apache Software Foundation (ASF) under one or more -rem contributor license agreements. See the NOTICE file distributed with -rem this work for additional information regarding copyright ownership. -rem The ASF licenses this file to You under the Apache License, Version 2.0 -rem (the "License"); you may not use this file except in compliance with -rem the License. You may obtain a copy of the License at -rem -rem http://www.apache.org/licenses/LICENSE-2.0 -rem -rem Unless required by applicable law or agreed to in writing, software -rem distributed under the License is distributed on an "AS IS" BASIS, -rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -rem See the License for the specific language governing permissions and -rem limitations under the License. - -if "%OS%" == "Windows_NT" setlocal -rem --------------------------------------------------------------------------- -rem Start/Stop Script for the CATALINA Server -rem -rem Environment Variable Prerequisites -rem -rem Do not set the variables in this script. Instead put them into a script -rem setenv.bat in CATALINA_BASE/bin to keep your customizations separate. -rem -rem CATALINA_HOME May point at your Catalina "build" directory. -rem -rem CATALINA_BASE (Optional) Base directory for resolving dynamic portions -rem of a Catalina installation. If not present, resolves to -rem the same directory that CATALINA_HOME points to. -rem -rem CATALINA_OPTS (Optional) Java runtime options used when the "start", -rem "run" or "debug" command is executed. -rem Include here and not in JAVA_OPTS all options, that should -rem only be used by Tomcat itself, not by the stop process, -rem the version command etc. -rem Examples are heap size, GC logging, JMX ports etc. -rem -rem CATALINA_TMPDIR (Optional) Directory path location of temporary directory -rem the JVM should use (java.io.tmpdir). Defaults to -rem %CATALINA_BASE%\temp. -rem -rem JAVA_HOME Must point at your Java Development Kit installation. -rem Required to run the with the "debug" argument. -rem -rem JRE_HOME Must point at your Java Runtime installation. -rem Defaults to JAVA_HOME if empty. If JRE_HOME and JAVA_HOME -rem are both set, JRE_HOME is used. -rem -rem JAVA_OPTS (Optional) Java runtime options used when any command -rem is executed. -rem Include here and not in CATALINA_OPTS all options, that -rem should be used by Tomcat and also by the stop process, -rem the version command etc. -rem Most options should go into CATALINA_OPTS. -rem -rem JAVA_ENDORSED_DIRS (Optional) Lists of of semi-colon separated directories -rem containing some jars in order to allow replacement of APIs -rem created outside of the JCP (i.e. DOM and SAX from W3C). -rem It can also be used to update the XML parser implementation. -rem Defaults to $CATALINA_HOME/endorsed. -rem -rem JPDA_TRANSPORT (Optional) JPDA transport used when the "jpda start" -rem command is executed. The default is "dt_socket". -rem -rem JPDA_ADDRESS (Optional) Java runtime options used when the "jpda start" -rem command is executed. The default is 8000. -rem -rem JPDA_SUSPEND (Optional) Java runtime options used when the "jpda start" -rem command is executed. Specifies whether JVM should suspend -rem execution immediately after startup. Default is "n". -rem -rem JPDA_OPTS (Optional) Java runtime options used when the "jpda start" -rem command is executed. If used, JPDA_TRANSPORT, JPDA_ADDRESS, -rem and JPDA_SUSPEND are ignored. Thus, all required jpda -rem options MUST be specified. The default is: -rem -rem -agentlib:jdwp=transport=%JPDA_TRANSPORT%, -rem address=%JPDA_ADDRESS%,server=y,suspend=%JPDA_SUSPEND% -rem -rem LOGGING_CONFIG (Optional) Override Tomcat's logging config file -rem Example (all one line) -rem set LOGGING_CONFIG="-Djava.util.logging.config.file=%CATALINA_BASE%\conf\logging.properties" -rem -rem LOGGING_MANAGER (Optional) Override Tomcat's logging manager -rem Example (all one line) -rem set LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager" -rem -rem TITLE (Optional) Specify the title of Tomcat window. The default -rem TITLE is Tomcat if it's not specified. -rem Example (all one line) -rem set TITLE=Tomcat.Cluster#1.Server#1 [%DATE% %TIME%] -rem -rem -rem -rem $Id: catalina.bat 1202062 2011-11-15 06:50:02Z mturk $ -rem --------------------------------------------------------------------------- - -rem Suppress Terminate batch job on CTRL+C -if not ""%1"" == ""run"" goto mainEntry -if ""%TEMP%"" == """" goto mainEntry -if exist "%TEMP%\%~nx0.run" goto mainEntry -echo Y>"%TEMP%\%~nx0.run" -if not exist "%TEMP%\%~nx0.run" goto mainEntry -echo Y>"%TEMP%\%~nx0.Y" -call "%~f0" %* <"%TEMP%\%~nx0.Y" -rem Use provided errorlevel -set RETVAL=%ERRORLEVEL% -del /Q "%TEMP%\%~nx0.Y" >NUL 2>&1 -exit /B %RETVAL% -:mainEntry -del /Q "%TEMP%\%~nx0.run" >NUL 2>&1 - -rem Guess CATALINA_HOME if not defined -set "CURRENT_DIR=%cd%" -if not "%CATALINA_HOME%" == "" goto gotHome -set "CATALINA_HOME=%CURRENT_DIR%" -if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome -cd .. -set "CATALINA_HOME=%cd%" -cd "%CURRENT_DIR%" -:gotHome - -if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome -echo The CATALINA_HOME environment variable is not defined correctly -echo This environment variable is needed to run this program -goto end -:okHome - -rem Copy CATALINA_BASE from CATALINA_HOME if not defined -if not "%CATALINA_BASE%" == "" goto gotBase -set "CATALINA_BASE=%CATALINA_HOME%" -:gotBase - -rem Ensure that any user defined CLASSPATH variables are not used on startup, -rem but allow them to be specified in setenv.bat, in rare case when it is needed. -set CLASSPATH= - -rem Get standard environment variables -if not exist "%CATALINA_BASE%\bin\setenv.bat" goto checkSetenvHome -call "%CATALINA_BASE%\bin\setenv.bat" -goto setenvDone -:checkSetenvHome -if exist "%CATALINA_HOME%\bin\setenv.bat" call "%CATALINA_HOME%\bin\setenv.bat" -:setenvDone - -rem Get standard Java environment variables -if exist "%CATALINA_HOME%\bin\setclasspath.bat" goto okSetclasspath -echo Cannot find "%CATALINA_HOME%\bin\setclasspath.bat" -echo This file is needed to run this program -goto end -:okSetclasspath -call "%CATALINA_HOME%\bin\setclasspath.bat" %1 -if errorlevel 1 goto end - -rem Add on extra jar file to CLASSPATH -rem Note that there are no quotes as we do not want to introduce random -rem quotes into the CLASSPATH -if "%CLASSPATH%" == "" goto emptyClasspath -set "CLASSPATH=%CLASSPATH%;" -:emptyClasspath -set "CLASSPATH=%CLASSPATH%%CATALINA_HOME%\bin\bootstrap.jar" - -if not "%CATALINA_TMPDIR%" == "" goto gotTmpdir -set "CATALINA_TMPDIR=%CATALINA_BASE%\temp" -:gotTmpdir - -rem Add tomcat-juli.jar to classpath -rem tomcat-juli.jar can be over-ridden per instance -if not exist "%CATALINA_BASE%\bin\tomcat-juli.jar" goto juliClasspathHome -set "CLASSPATH=%CLASSPATH%;%CATALINA_BASE%\bin\tomcat-juli.jar" -goto juliClasspathDone -:juliClasspathHome -set "CLASSPATH=%CLASSPATH%;%CATALINA_HOME%\bin\tomcat-juli.jar" -:juliClasspathDone - -if not "%LOGGING_CONFIG%" == "" goto noJuliConfig -set LOGGING_CONFIG=-Dnop -if not exist "%CATALINA_BASE%\conf\logging.properties" goto noJuliConfig -set LOGGING_CONFIG=-Djava.util.logging.config.file="%CATALINA_BASE%\conf\logging.properties" -:noJuliConfig -set JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG% - -if not "%LOGGING_MANAGER%" == "" goto noJuliManager -set LOGGING_MANAGER=-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -:noJuliManager -set JAVA_OPTS=%JAVA_OPTS% %LOGGING_MANAGER% - -rem ----- Execute The Requested Command --------------------------------------- - -echo Using CATALINA_BASE: "%CATALINA_BASE%" -echo Using CATALINA_HOME: "%CATALINA_HOME%" -echo Using CATALINA_TMPDIR: "%CATALINA_TMPDIR%" -if ""%1"" == ""debug"" goto use_jdk -echo Using JRE_HOME: "%JRE_HOME%" -goto java_dir_displayed -:use_jdk -echo Using JAVA_HOME: "%JAVA_HOME%" -:java_dir_displayed -echo Using CLASSPATH: "%CLASSPATH%" - -set _EXECJAVA=%_RUNJAVA% -set MAINCLASS=org.apache.catalina.startup.Bootstrap -set ACTION=start -set SECURITY_POLICY_FILE= -set DEBUG_OPTS= -set JPDA= - -if not ""%1"" == ""jpda"" goto noJpda -set JPDA=jpda -if not "%JPDA_TRANSPORT%" == "" goto gotJpdaTransport -set JPDA_TRANSPORT=dt_socket -:gotJpdaTransport -if not "%JPDA_ADDRESS%" == "" goto gotJpdaAddress -set JPDA_ADDRESS=8000 -:gotJpdaAddress -if not "%JPDA_SUSPEND%" == "" goto gotJpdaSuspend -set JPDA_SUSPEND=n -:gotJpdaSuspend -if not "%JPDA_OPTS%" == "" goto gotJpdaOpts -set JPDA_OPTS=-agentlib:jdwp=transport=%JPDA_TRANSPORT%,address=%JPDA_ADDRESS%,server=y,suspend=%JPDA_SUSPEND% -:gotJpdaOpts -shift -:noJpda - -if ""%1"" == ""debug"" goto doDebug -if ""%1"" == ""run"" goto doRun -if ""%1"" == ""start"" goto doStart -if ""%1"" == ""stop"" goto doStop -if ""%1"" == ""configtest"" goto doConfigTest -if ""%1"" == ""version"" goto doVersion - -echo Usage: catalina ( commands ... ) -echo commands: -echo debug Start Catalina in a debugger -echo debug -security Debug Catalina with a security manager -echo jpda start Start Catalina under JPDA debugger -echo run Start Catalina in the current window -echo run -security Start in the current window with security manager -echo start Start Catalina in a separate window -echo start -security Start in a separate window with security manager -echo stop Stop Catalina -echo configtest Run a basic syntax check on server.xml -echo version What version of tomcat are you running? -goto end - -:doDebug -shift -set _EXECJAVA=%_RUNJDB% -set DEBUG_OPTS=-sourcepath "%CATALINA_HOME%\..\..\java" -if not ""%1"" == ""-security"" goto execCmd -shift -echo Using Security Manager -set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy" -goto execCmd - -:doRun -shift -if not ""%1"" == ""-security"" goto execCmd -shift -echo Using Security Manager -set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy" -goto execCmd - -:doStart -shift -if not "%OS%" == "Windows_NT" goto noTitle -if "%TITLE%" == "" set TITLE=Tomcat -set _EXECJAVA=start "%TITLE%" %_RUNJAVA% -goto gotTitle -:noTitle -set _EXECJAVA=start %_RUNJAVA% -:gotTitle -if not ""%1"" == ""-security"" goto execCmd -shift -echo Using Security Manager -set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy" -goto execCmd - -:doStop -shift -set ACTION=stop -set CATALINA_OPTS= -goto execCmd - -:doConfigTest -shift -set ACTION=configtest -set CATALINA_OPTS= -goto execCmd - -:doVersion -%_EXECJAVA% -classpath "%CATALINA_HOME%\lib\catalina.jar" org.apache.catalina.util.ServerInfo -goto end - - -:execCmd -rem Get remaining unshifted command line arguments and save them in the -set CMD_LINE_ARGS= -:setArgs -if ""%1""=="""" goto doneSetArgs -set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1 -shift -goto setArgs -:doneSetArgs - -rem Execute Java with the applicable properties -if not "%JPDA%" == "" goto doJpda -if not "%SECURITY_POLICY_FILE%" == "" goto doSecurity -%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION% -goto end -:doSecurity -%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Djava.security.manager -Djava.security.policy=="%SECURITY_POLICY_FILE%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION% -goto end -:doJpda -if not "%SECURITY_POLICY_FILE%" == "" goto doSecurityJpda -%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %JPDA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION% -goto end -:doSecurityJpda -%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %JPDA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Djava.security.manager -Djava.security.policy=="%SECURITY_POLICY_FILE%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION% -goto end - -:end +@echo off +rem Licensed to the Apache Software Foundation (ASF) under one or more +rem contributor license agreements. See the NOTICE file distributed with +rem this work for additional information regarding copyright ownership. +rem The ASF licenses this file to You under the Apache License, Version 2.0 +rem (the "License"); you may not use this file except in compliance with +rem the License. You may obtain a copy of the License at +rem +rem http://www.apache.org/licenses/LICENSE-2.0 +rem +rem Unless required by applicable law or agreed to in writing, software +rem distributed under the License is distributed on an "AS IS" BASIS, +rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +rem See the License for the specific language governing permissions and +rem limitations under the License. + +if "%OS%" == "Windows_NT" setlocal +rem --------------------------------------------------------------------------- +rem Start/Stop Script for the CATALINA Server +rem +rem Environment Variable Prerequisites +rem +rem Do not set the variables in this script. Instead put them into a script +rem setenv.bat in CATALINA_BASE/bin to keep your customizations separate. +rem +rem CATALINA_HOME May point at your Catalina "build" directory. +rem +rem CATALINA_BASE (Optional) Base directory for resolving dynamic portions +rem of a Catalina installation. If not present, resolves to +rem the same directory that CATALINA_HOME points to. +rem +rem CATALINA_OPTS (Optional) Java runtime options used when the "start", +rem "run" or "debug" command is executed. +rem Include here and not in JAVA_OPTS all options, that should +rem only be used by Tomcat itself, not by the stop process, +rem the version command etc. +rem Examples are heap size, GC logging, JMX ports etc. +rem +rem CATALINA_TMPDIR (Optional) Directory path location of temporary directory +rem the JVM should use (java.io.tmpdir). Defaults to +rem %CATALINA_BASE%\temp. +rem +rem JAVA_HOME Must point at your Java Development Kit installation. +rem Required to run the with the "debug" argument. +rem +rem JRE_HOME Must point at your Java Runtime installation. +rem Defaults to JAVA_HOME if empty. If JRE_HOME and JAVA_HOME +rem are both set, JRE_HOME is used. +rem +rem JAVA_OPTS (Optional) Java runtime options used when any command +rem is executed. +rem Include here and not in CATALINA_OPTS all options, that +rem should be used by Tomcat and also by the stop process, +rem the version command etc. +rem Most options should go into CATALINA_OPTS. +rem +rem JAVA_ENDORSED_DIRS (Optional) Lists of of semi-colon separated directories +rem containing some jars in order to allow replacement of APIs +rem created outside of the JCP (i.e. DOM and SAX from W3C). +rem It can also be used to update the XML parser implementation. +rem Defaults to $CATALINA_HOME/endorsed. +rem +rem JPDA_TRANSPORT (Optional) JPDA transport used when the "jpda start" +rem command is executed. The default is "dt_socket". +rem +rem JPDA_ADDRESS (Optional) Java runtime options used when the "jpda start" +rem command is executed. The default is 8000. +rem +rem JPDA_SUSPEND (Optional) Java runtime options used when the "jpda start" +rem command is executed. Specifies whether JVM should suspend +rem execution immediately after startup. Default is "n". +rem +rem JPDA_OPTS (Optional) Java runtime options used when the "jpda start" +rem command is executed. If used, JPDA_TRANSPORT, JPDA_ADDRESS, +rem and JPDA_SUSPEND are ignored. Thus, all required jpda +rem options MUST be specified. The default is: +rem +rem -agentlib:jdwp=transport=%JPDA_TRANSPORT%, +rem address=%JPDA_ADDRESS%,server=y,suspend=%JPDA_SUSPEND% +rem +rem LOGGING_CONFIG (Optional) Override Tomcat's logging config file +rem Example (all one line) +rem set LOGGING_CONFIG="-Djava.util.logging.config.file=%CATALINA_BASE%\conf\logging.properties" +rem +rem LOGGING_MANAGER (Optional) Override Tomcat's logging manager +rem Example (all one line) +rem set LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager" +rem +rem TITLE (Optional) Specify the title of Tomcat window. The default +rem TITLE is Tomcat if it's not specified. +rem Example (all one line) +rem set TITLE=Tomcat.Cluster#1.Server#1 [%DATE% %TIME%] +rem +rem +rem +rem $Id: catalina.bat 1202062 2011-11-15 06:50:02Z mturk $ +rem --------------------------------------------------------------------------- + +rem Suppress Terminate batch job on CTRL+C +if not ""%1"" == ""run"" goto mainEntry +if ""%TEMP%"" == """" goto mainEntry +if exist "%TEMP%\%~nx0.run" goto mainEntry +echo Y>"%TEMP%\%~nx0.run" +if not exist "%TEMP%\%~nx0.run" goto mainEntry +echo Y>"%TEMP%\%~nx0.Y" +call "%~f0" %* <"%TEMP%\%~nx0.Y" +rem Use provided errorlevel +set RETVAL=%ERRORLEVEL% +del /Q "%TEMP%\%~nx0.Y" >NUL 2>&1 +exit /B %RETVAL% +:mainEntry +del /Q "%TEMP%\%~nx0.run" >NUL 2>&1 + +rem Guess CATALINA_HOME if not defined +set "CURRENT_DIR=%cd%" +if not "%CATALINA_HOME%" == "" goto gotHome +set "CATALINA_HOME=%CURRENT_DIR%" +if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome +cd .. +set "CATALINA_HOME=%cd%" +cd "%CURRENT_DIR%" +:gotHome + +if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome +echo The CATALINA_HOME environment variable is not defined correctly +echo This environment variable is needed to run this program +goto end +:okHome + +rem Copy CATALINA_BASE from CATALINA_HOME if not defined +if not "%CATALINA_BASE%" == "" goto gotBase +set "CATALINA_BASE=%CATALINA_HOME%" +:gotBase + +rem Ensure that any user defined CLASSPATH variables are not used on startup, +rem but allow them to be specified in setenv.bat, in rare case when it is needed. +set CLASSPATH= + +rem Get standard environment variables +if not exist "%CATALINA_BASE%\bin\setenv.bat" goto checkSetenvHome +call "%CATALINA_BASE%\bin\setenv.bat" +goto setenvDone +:checkSetenvHome +if exist "%CATALINA_HOME%\bin\setenv.bat" call "%CATALINA_HOME%\bin\setenv.bat" +:setenvDone + +rem Get standard Java environment variables +if exist "%CATALINA_HOME%\bin\setclasspath.bat" goto okSetclasspath +echo Cannot find "%CATALINA_HOME%\bin\setclasspath.bat" +echo This file is needed to run this program +goto end +:okSetclasspath +call "%CATALINA_HOME%\bin\setclasspath.bat" %1 +if errorlevel 1 goto end + +rem Add on extra jar file to CLASSPATH +rem Note that there are no quotes as we do not want to introduce random +rem quotes into the CLASSPATH +if "%CLASSPATH%" == "" goto emptyClasspath +set "CLASSPATH=%CLASSPATH%;" +:emptyClasspath +set "CLASSPATH=%CLASSPATH%%CATALINA_HOME%\bin\bootstrap.jar" + +if not "%CATALINA_TMPDIR%" == "" goto gotTmpdir +set "CATALINA_TMPDIR=%CATALINA_BASE%\temp" +:gotTmpdir + +rem Add tomcat-juli.jar to classpath +rem tomcat-juli.jar can be over-ridden per instance +if not exist "%CATALINA_BASE%\bin\tomcat-juli.jar" goto juliClasspathHome +set "CLASSPATH=%CLASSPATH%;%CATALINA_BASE%\bin\tomcat-juli.jar" +goto juliClasspathDone +:juliClasspathHome +set "CLASSPATH=%CLASSPATH%;%CATALINA_HOME%\bin\tomcat-juli.jar" +:juliClasspathDone + +if not "%LOGGING_CONFIG%" == "" goto noJuliConfig +set LOGGING_CONFIG=-Dnop +if not exist "%CATALINA_BASE%\conf\logging.properties" goto noJuliConfig +set LOGGING_CONFIG=-Djava.util.logging.config.file="%CATALINA_BASE%\conf\logging.properties" +:noJuliConfig +set JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG% + +if not "%LOGGING_MANAGER%" == "" goto noJuliManager +set LOGGING_MANAGER=-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager +:noJuliManager +set JAVA_OPTS=%JAVA_OPTS% %LOGGING_MANAGER% + +rem ----- Execute The Requested Command --------------------------------------- + +echo Using CATALINA_BASE: "%CATALINA_BASE%" +echo Using CATALINA_HOME: "%CATALINA_HOME%" +echo Using CATALINA_TMPDIR: "%CATALINA_TMPDIR%" +if ""%1"" == ""debug"" goto use_jdk +echo Using JRE_HOME: "%JRE_HOME%" +goto java_dir_displayed +:use_jdk +echo Using JAVA_HOME: "%JAVA_HOME%" +:java_dir_displayed +echo Using CLASSPATH: "%CLASSPATH%" + +set _EXECJAVA=%_RUNJAVA% +set MAINCLASS=org.apache.catalina.startup.Bootstrap +set ACTION=start +set SECURITY_POLICY_FILE= +set DEBUG_OPTS= +set JPDA= + +if not ""%1"" == ""jpda"" goto noJpda +set JPDA=jpda +if not "%JPDA_TRANSPORT%" == "" goto gotJpdaTransport +set JPDA_TRANSPORT=dt_socket +:gotJpdaTransport +if not "%JPDA_ADDRESS%" == "" goto gotJpdaAddress +set JPDA_ADDRESS=8000 +:gotJpdaAddress +if not "%JPDA_SUSPEND%" == "" goto gotJpdaSuspend +set JPDA_SUSPEND=n +:gotJpdaSuspend +if not "%JPDA_OPTS%" == "" goto gotJpdaOpts +set JPDA_OPTS=-agentlib:jdwp=transport=%JPDA_TRANSPORT%,address=%JPDA_ADDRESS%,server=y,suspend=%JPDA_SUSPEND% +:gotJpdaOpts +shift +:noJpda + +if ""%1"" == ""debug"" goto doDebug +if ""%1"" == ""run"" goto doRun +if ""%1"" == ""start"" goto doStart +if ""%1"" == ""stop"" goto doStop +if ""%1"" == ""configtest"" goto doConfigTest +if ""%1"" == ""version"" goto doVersion + +echo Usage: catalina ( commands ... ) +echo commands: +echo debug Start Catalina in a debugger +echo debug -security Debug Catalina with a security manager +echo jpda start Start Catalina under JPDA debugger +echo run Start Catalina in the current window +echo run -security Start in the current window with security manager +echo start Start Catalina in a separate window +echo start -security Start in a separate window with security manager +echo stop Stop Catalina +echo configtest Run a basic syntax check on server.xml +echo version What version of tomcat are you running? +goto end + +:doDebug +shift +set _EXECJAVA=%_RUNJDB% +set DEBUG_OPTS=-sourcepath "%CATALINA_HOME%\..\..\java" +if not ""%1"" == ""-security"" goto execCmd +shift +echo Using Security Manager +set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy" +goto execCmd + +:doRun +shift +if not ""%1"" == ""-security"" goto execCmd +shift +echo Using Security Manager +set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy" +goto execCmd + +:doStart +shift +if not "%OS%" == "Windows_NT" goto noTitle +if "%TITLE%" == "" set TITLE=Tomcat +set _EXECJAVA=start "%TITLE%" %_RUNJAVA% +goto gotTitle +:noTitle +set _EXECJAVA=start %_RUNJAVA% +:gotTitle +if not ""%1"" == ""-security"" goto execCmd +shift +echo Using Security Manager +set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy" +goto execCmd + +:doStop +shift +set ACTION=stop +set CATALINA_OPTS= +goto execCmd + +:doConfigTest +shift +set ACTION=configtest +set CATALINA_OPTS= +goto execCmd + +:doVersion +%_EXECJAVA% -classpath "%CATALINA_HOME%\lib\catalina.jar" org.apache.catalina.util.ServerInfo +goto end + + +:execCmd +rem Get remaining unshifted command line arguments and save them in the +set CMD_LINE_ARGS= +:setArgs +if ""%1""=="""" goto doneSetArgs +set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1 +shift +goto setArgs +:doneSetArgs + +rem Execute Java with the applicable properties +if not "%JPDA%" == "" goto doJpda +if not "%SECURITY_POLICY_FILE%" == "" goto doSecurity +%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION% +goto end +:doSecurity +%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Djava.security.manager -Djava.security.policy=="%SECURITY_POLICY_FILE%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION% +goto end +:doJpda +if not "%SECURITY_POLICY_FILE%" == "" goto doSecurityJpda +%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %JPDA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION% +goto end +:doSecurityJpda +%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %JPDA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Djava.security.manager -Djava.security.policy=="%SECURITY_POLICY_FILE%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION% +goto end + +:end diff --git a/bin/catalina.sh b/bin/catalina.sh old mode 100644 new mode 100755 diff --git a/bin/catalina2.sh b/bin/catalina2.sh old mode 100644 new mode 100755 diff --git a/bin/commons-daemon-native.tar.gz b/bin/commons-daemon-native.tar.gz old mode 100644 new mode 100755 diff --git a/bin/commons-daemon.jar b/bin/commons-daemon.jar old mode 100644 new mode 100755 diff --git a/bin/configtest.bat b/bin/configtest.bat old mode 100644 new mode 100755 index a3afc6a..c3bfd89 --- a/bin/configtest.bat +++ b/bin/configtest.bat @@ -1,59 +1,59 @@ -@echo off -rem Licensed to the Apache Software Foundation (ASF) under one or more -rem contributor license agreements. See the NOTICE file distributed with -rem this work for additional information regarding copyright ownership. -rem The ASF licenses this file to You under the Apache License, Version 2.0 -rem (the "License"); you may not use this file except in compliance with -rem the License. You may obtain a copy of the License at -rem -rem http://www.apache.org/licenses/LICENSE-2.0 -rem -rem Unless required by applicable law or agreed to in writing, software -rem distributed under the License is distributed on an "AS IS" BASIS, -rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -rem See the License for the specific language governing permissions and -rem limitations under the License. - -if "%OS%" == "Windows_NT" setlocal -rem --------------------------------------------------------------------------- -rem Configuration test script for the CATALINA Server -rem -rem $Id: configtest.bat 1137560 2011-06-20 09:27:44Z rjung $ -rem --------------------------------------------------------------------------- - -rem Guess CATALINA_HOME if not defined -set "CURRENT_DIR=%cd%" -if not "%CATALINA_HOME%" == "" goto gotHome -set "CATALINA_HOME=%CURRENT_DIR%" -if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome -cd .. -set "CATALINA_HOME=%cd%" -cd "%CURRENT_DIR%" -:gotHome -if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome -echo The CATALINA_HOME environment variable is not defined correctly -echo This environment variable is needed to run this program -goto end -:okHome - -set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat" - -rem Check that target executable exists -if exist "%EXECUTABLE%" goto okExec -echo Cannot find "%EXECUTABLE%" -echo This file is needed to run this program -goto end -:okExec - -rem Get remaining unshifted command line arguments and save them in the -set CMD_LINE_ARGS= -:setArgs -if ""%1""=="""" goto doneSetArgs -set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1 -shift -goto setArgs -:doneSetArgs - -call "%EXECUTABLE%" configtest %CMD_LINE_ARGS% - -:end +@echo off +rem Licensed to the Apache Software Foundation (ASF) under one or more +rem contributor license agreements. See the NOTICE file distributed with +rem this work for additional information regarding copyright ownership. +rem The ASF licenses this file to You under the Apache License, Version 2.0 +rem (the "License"); you may not use this file except in compliance with +rem the License. You may obtain a copy of the License at +rem +rem http://www.apache.org/licenses/LICENSE-2.0 +rem +rem Unless required by applicable law or agreed to in writing, software +rem distributed under the License is distributed on an "AS IS" BASIS, +rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +rem See the License for the specific language governing permissions and +rem limitations under the License. + +if "%OS%" == "Windows_NT" setlocal +rem --------------------------------------------------------------------------- +rem Configuration test script for the CATALINA Server +rem +rem $Id: configtest.bat 1137560 2011-06-20 09:27:44Z rjung $ +rem --------------------------------------------------------------------------- + +rem Guess CATALINA_HOME if not defined +set "CURRENT_DIR=%cd%" +if not "%CATALINA_HOME%" == "" goto gotHome +set "CATALINA_HOME=%CURRENT_DIR%" +if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome +cd .. +set "CATALINA_HOME=%cd%" +cd "%CURRENT_DIR%" +:gotHome +if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome +echo The CATALINA_HOME environment variable is not defined correctly +echo This environment variable is needed to run this program +goto end +:okHome + +set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat" + +rem Check that target executable exists +if exist "%EXECUTABLE%" goto okExec +echo Cannot find "%EXECUTABLE%" +echo This file is needed to run this program +goto end +:okExec + +rem Get remaining unshifted command line arguments and save them in the +set CMD_LINE_ARGS= +:setArgs +if ""%1""=="""" goto doneSetArgs +set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1 +shift +goto setArgs +:doneSetArgs + +call "%EXECUTABLE%" configtest %CMD_LINE_ARGS% + +:end diff --git a/bin/configtest.sh b/bin/configtest.sh old mode 100644 new mode 100755 diff --git a/bin/cpappend.bat b/bin/cpappend.bat old mode 100644 new mode 100755 index ca4b5fa..b9b90c1 --- a/bin/cpappend.bat +++ b/bin/cpappend.bat @@ -1,35 +1,35 @@ -@echo off -rem Licensed to the Apache Software Foundation (ASF) under one or more -rem contributor license agreements. See the NOTICE file distributed with -rem this work for additional information regarding copyright ownership. -rem The ASF licenses this file to You under the Apache License, Version 2.0 -rem (the "License"); you may not use this file except in compliance with -rem the License. You may obtain a copy of the License at -rem -rem http://www.apache.org/licenses/LICENSE-2.0 -rem -rem Unless required by applicable law or agreed to in writing, software -rem distributed under the License is distributed on an "AS IS" BASIS, -rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -rem See the License for the specific language governing permissions and -rem limitations under the License. - -rem --------------------------------------------------------------------------- -rem Append to CLASSPATH -rem -rem $Id: cpappend.bat 562770 2007-08-04 22:13:58Z markt $ -rem --------------------------------------------------------------------------- - -rem Process the first argument -if ""%1"" == """" goto end -set CLASSPATH=%CLASSPATH%;%1 -shift - -rem Process the remaining arguments -:setArgs -if ""%1"" == """" goto doneSetArgs -set CLASSPATH=%CLASSPATH% %1 -shift -goto setArgs -:doneSetArgs -:end +@echo off +rem Licensed to the Apache Software Foundation (ASF) under one or more +rem contributor license agreements. See the NOTICE file distributed with +rem this work for additional information regarding copyright ownership. +rem The ASF licenses this file to You under the Apache License, Version 2.0 +rem (the "License"); you may not use this file except in compliance with +rem the License. You may obtain a copy of the License at +rem +rem http://www.apache.org/licenses/LICENSE-2.0 +rem +rem Unless required by applicable law or agreed to in writing, software +rem distributed under the License is distributed on an "AS IS" BASIS, +rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +rem See the License for the specific language governing permissions and +rem limitations under the License. + +rem --------------------------------------------------------------------------- +rem Append to CLASSPATH +rem +rem $Id: cpappend.bat 562770 2007-08-04 22:13:58Z markt $ +rem --------------------------------------------------------------------------- + +rem Process the first argument +if ""%1"" == """" goto end +set CLASSPATH=%CLASSPATH%;%1 +shift + +rem Process the remaining arguments +:setArgs +if ""%1"" == """" goto doneSetArgs +set CLASSPATH=%CLASSPATH% %1 +shift +goto setArgs +:doneSetArgs +:end diff --git a/bin/demon.sh b/bin/demon.sh old mode 100644 new mode 100755 diff --git a/bin/derby.log b/bin/derby.log index 2ab67de..81e8cae 100644 --- a/bin/derby.log +++ b/bin/derby.log @@ -1,10 +1,10 @@ ---------------------------------------------------------------- -Wed May 23 07:49:33 PDT 2012: -Booting Derby version The Apache Software Foundation - Apache Derby - 10.8.2.2 - (1181258): instance a816c00e-0137-7a2c-9e93-000002f597d0 -on database directory /idrive/usr/caimito/bin/caimito_db with class loader org.apache.catalina.loader.StandardClassLoader@1df5a8f -Loaded from file:/idrive/usr/caimito/lib/derby.jar +Tue Jun 05 14:00:21 PDT 2012: +Booting Derby version The Apache Software Foundation - Apache Derby - 10.8.2.2 - (1181258): instance a816c00e-0137-be72-c544-000002f61848 +on database directory /home/idrive/caimito/bin/caimito_db with class loader org.apache.catalina.loader.StandardClassLoader@1df5a8f +Loaded from file:/home/idrive/caimito/lib/derby.jar java.vendor=Sun Microsystems Inc. java.runtime.version=1.6.0_24-b07 -user.dir=/idrive/usr/caimito/bin +user.dir=/home/idrive/caimito/bin derby.system.home=null Database Class Loader started - derby.database.classpath='' diff --git a/bin/digest.bat b/bin/digest.bat old mode 100644 new mode 100755 index dcc21a3..41491dc --- a/bin/digest.bat +++ b/bin/digest.bat @@ -1,59 +1,59 @@ -@echo off -rem Licensed to the Apache Software Foundation (ASF) under one or more -rem contributor license agreements. See the NOTICE file distributed with -rem this work for additional information regarding copyright ownership. -rem The ASF licenses this file to You under the Apache License, Version 2.0 -rem (the "License"); you may not use this file except in compliance with -rem the License. You may obtain a copy of the License at -rem -rem http://www.apache.org/licenses/LICENSE-2.0 -rem -rem Unless required by applicable law or agreed to in writing, software -rem distributed under the License is distributed on an "AS IS" BASIS, -rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -rem See the License for the specific language governing permissions and -rem limitations under the License. - -if "%OS%" == "Windows_NT" setlocal -rem --------------------------------------------------------------------------- -rem Script to digest password using the algorithm specified -rem -rem $Id: digest.bat 1137559 2011-06-20 09:27:30Z rjung $ -rem --------------------------------------------------------------------------- - -rem Guess CATALINA_HOME if not defined -set "CURRENT_DIR=%cd%" -if not "%CATALINA_HOME%" == "" goto gotHome -set "CATALINA_HOME=%CURRENT_DIR%" -if exist "%CATALINA_HOME%\bin\tool-wrapper.bat" goto okHome -cd .. -set "CATALINA_HOME=%cd%" -cd "%CURRENT_DIR%" -:gotHome -if exist "%CATALINA_HOME%\bin\tool-wrapper.bat" goto okHome -echo The CATALINA_HOME environment variable is not defined correctly -echo This environment variable is needed to run this program -goto end -:okHome - -set "EXECUTABLE=%CATALINA_HOME%\bin\tool-wrapper.bat" - -rem Check that target executable exists -if exist "%EXECUTABLE%" goto okExec -echo Cannot find "%EXECUTABLE%" -echo This file is needed to run this program -goto end -:okExec - -rem Get remaining unshifted command line arguments and save them in the -set CMD_LINE_ARGS= -:setArgs -if ""%1""=="""" goto doneSetArgs -set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1 -shift -goto setArgs -:doneSetArgs - -call "%EXECUTABLE%" -server org.apache.catalina.realm.RealmBase %CMD_LINE_ARGS% - -:end +@echo off +rem Licensed to the Apache Software Foundation (ASF) under one or more +rem contributor license agreements. See the NOTICE file distributed with +rem this work for additional information regarding copyright ownership. +rem The ASF licenses this file to You under the Apache License, Version 2.0 +rem (the "License"); you may not use this file except in compliance with +rem the License. You may obtain a copy of the License at +rem +rem http://www.apache.org/licenses/LICENSE-2.0 +rem +rem Unless required by applicable law or agreed to in writing, software +rem distributed under the License is distributed on an "AS IS" BASIS, +rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +rem See the License for the specific language governing permissions and +rem limitations under the License. + +if "%OS%" == "Windows_NT" setlocal +rem --------------------------------------------------------------------------- +rem Script to digest password using the algorithm specified +rem +rem $Id: digest.bat 1137559 2011-06-20 09:27:30Z rjung $ +rem --------------------------------------------------------------------------- + +rem Guess CATALINA_HOME if not defined +set "CURRENT_DIR=%cd%" +if not "%CATALINA_HOME%" == "" goto gotHome +set "CATALINA_HOME=%CURRENT_DIR%" +if exist "%CATALINA_HOME%\bin\tool-wrapper.bat" goto okHome +cd .. +set "CATALINA_HOME=%cd%" +cd "%CURRENT_DIR%" +:gotHome +if exist "%CATALINA_HOME%\bin\tool-wrapper.bat" goto okHome +echo The CATALINA_HOME environment variable is not defined correctly +echo This environment variable is needed to run this program +goto end +:okHome + +set "EXECUTABLE=%CATALINA_HOME%\bin\tool-wrapper.bat" + +rem Check that target executable exists +if exist "%EXECUTABLE%" goto okExec +echo Cannot find "%EXECUTABLE%" +echo This file is needed to run this program +goto end +:okExec + +rem Get remaining unshifted command line arguments and save them in the +set CMD_LINE_ARGS= +:setArgs +if ""%1""=="""" goto doneSetArgs +set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1 +shift +goto setArgs +:doneSetArgs + +call "%EXECUTABLE%" -server org.apache.catalina.realm.RealmBase %CMD_LINE_ARGS% + +:end diff --git a/bin/digest.sh b/bin/digest.sh old mode 100644 new mode 100755 diff --git a/bin/setclasspath.bat b/bin/setclasspath.bat old mode 100644 new mode 100755 index 366912b..e29b41a --- a/bin/setclasspath.bat +++ b/bin/setclasspath.bat @@ -1,88 +1,88 @@ -@echo off -rem Licensed to the Apache Software Foundation (ASF) under one or more -rem contributor license agreements. See the NOTICE file distributed with -rem this work for additional information regarding copyright ownership. -rem The ASF licenses this file to You under the Apache License, Version 2.0 -rem (the "License"); you may not use this file except in compliance with -rem the License. You may obtain a copy of the License at -rem -rem http://www.apache.org/licenses/LICENSE-2.0 -rem -rem Unless required by applicable law or agreed to in writing, software -rem distributed under the License is distributed on an "AS IS" BASIS, -rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -rem See the License for the specific language governing permissions and -rem limitations under the License. - -rem --------------------------------------------------------------------------- -rem Set JAVA_HOME or JRE_HOME if not already set, ensure any provided settings -rem are valid and consistent with the selected start-up options and set up the -rem endorsed directory. -rem -rem $Id: setclasspath.bat 1202062 2011-11-15 06:50:02Z mturk $ -rem --------------------------------------------------------------------------- - -rem Make sure prerequisite environment variables are set - -rem In debug mode we need a real JDK (JAVA_HOME) -if ""%1"" == ""debug"" goto needJavaHome - -rem Otherwise either JRE or JDK are fine -if not "%JRE_HOME%" == "" goto gotJreHome -if not "%JAVA_HOME%" == "" goto gotJavaHome -echo Neither the JAVA_HOME nor the JRE_HOME environment variable is defined -echo At least one of these environment variable is needed to run this program -goto exit - -:needJavaHome -rem Check if we have a usable JDK -if "%JAVA_HOME%" == "" goto noJavaHome -if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome -if not exist "%JAVA_HOME%\bin\javaw.exe" goto noJavaHome -if not exist "%JAVA_HOME%\bin\jdb.exe" goto noJavaHome -if not exist "%JAVA_HOME%\bin\javac.exe" goto noJavaHome -set "JRE_HOME=%JAVA_HOME%" -goto okJava - -:noJavaHome -echo The JAVA_HOME environment variable is not defined correctly. -echo It is needed to run this program in debug mode. -echo NB: JAVA_HOME should point to a JDK not a JRE. -goto exit - -:gotJavaHome -rem No JRE given, use JAVA_HOME as JRE_HOME -set "JRE_HOME=%JAVA_HOME%" - -:gotJreHome -rem Check if we have a usable JRE -if not exist "%JRE_HOME%\bin\java.exe" goto noJreHome -if not exist "%JRE_HOME%\bin\javaw.exe" goto noJreHome -goto okJava - -:noJreHome -rem Needed at least a JRE -echo The JRE_HOME environment variable is not defined correctly -echo This environment variable is needed to run this program -goto exit - -:okJava -rem Don't override the endorsed dir if the user has set it previously -if not "%JAVA_ENDORSED_DIRS%" == "" goto gotEndorseddir -rem Set the default -Djava.endorsed.dirs argument -set "JAVA_ENDORSED_DIRS=%CATALINA_HOME%\endorsed" -:gotEndorseddir - -rem Set standard command for invoking Java. -rem Note that NT requires a window name argument when using start. -rem Also note the quoting as JAVA_HOME may contain spaces. -set _RUNJAVA="%JRE_HOME%\bin\java" -set _RUNJDB="%JAVA_HOME%\bin\jdb" - -goto end - -:exit -exit /b 1 - -:end -exit /b 0 +@echo off +rem Licensed to the Apache Software Foundation (ASF) under one or more +rem contributor license agreements. See the NOTICE file distributed with +rem this work for additional information regarding copyright ownership. +rem The ASF licenses this file to You under the Apache License, Version 2.0 +rem (the "License"); you may not use this file except in compliance with +rem the License. You may obtain a copy of the License at +rem +rem http://www.apache.org/licenses/LICENSE-2.0 +rem +rem Unless required by applicable law or agreed to in writing, software +rem distributed under the License is distributed on an "AS IS" BASIS, +rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +rem See the License for the specific language governing permissions and +rem limitations under the License. + +rem --------------------------------------------------------------------------- +rem Set JAVA_HOME or JRE_HOME if not already set, ensure any provided settings +rem are valid and consistent with the selected start-up options and set up the +rem endorsed directory. +rem +rem $Id: setclasspath.bat 1202062 2011-11-15 06:50:02Z mturk $ +rem --------------------------------------------------------------------------- + +rem Make sure prerequisite environment variables are set + +rem In debug mode we need a real JDK (JAVA_HOME) +if ""%1"" == ""debug"" goto needJavaHome + +rem Otherwise either JRE or JDK are fine +if not "%JRE_HOME%" == "" goto gotJreHome +if not "%JAVA_HOME%" == "" goto gotJavaHome +echo Neither the JAVA_HOME nor the JRE_HOME environment variable is defined +echo At least one of these environment variable is needed to run this program +goto exit + +:needJavaHome +rem Check if we have a usable JDK +if "%JAVA_HOME%" == "" goto noJavaHome +if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome +if not exist "%JAVA_HOME%\bin\javaw.exe" goto noJavaHome +if not exist "%JAVA_HOME%\bin\jdb.exe" goto noJavaHome +if not exist "%JAVA_HOME%\bin\javac.exe" goto noJavaHome +set "JRE_HOME=%JAVA_HOME%" +goto okJava + +:noJavaHome +echo The JAVA_HOME environment variable is not defined correctly. +echo It is needed to run this program in debug mode. +echo NB: JAVA_HOME should point to a JDK not a JRE. +goto exit + +:gotJavaHome +rem No JRE given, use JAVA_HOME as JRE_HOME +set "JRE_HOME=%JAVA_HOME%" + +:gotJreHome +rem Check if we have a usable JRE +if not exist "%JRE_HOME%\bin\java.exe" goto noJreHome +if not exist "%JRE_HOME%\bin\javaw.exe" goto noJreHome +goto okJava + +:noJreHome +rem Needed at least a JRE +echo The JRE_HOME environment variable is not defined correctly +echo This environment variable is needed to run this program +goto exit + +:okJava +rem Don't override the endorsed dir if the user has set it previously +if not "%JAVA_ENDORSED_DIRS%" == "" goto gotEndorseddir +rem Set the default -Djava.endorsed.dirs argument +set "JAVA_ENDORSED_DIRS=%CATALINA_HOME%\endorsed" +:gotEndorseddir + +rem Set standard command for invoking Java. +rem Note that NT requires a window name argument when using start. +rem Also note the quoting as JAVA_HOME may contain spaces. +set _RUNJAVA="%JRE_HOME%\bin\java" +set _RUNJDB="%JAVA_HOME%\bin\jdb" + +goto end + +:exit +exit /b 1 + +:end +exit /b 0 diff --git a/bin/setclasspath.sh b/bin/setclasspath.sh old mode 100644 new mode 100755 diff --git a/bin/setenv.bat b/bin/setenv.bat old mode 100644 new mode 100755 diff --git a/bin/setenv.sh b/bin/setenv.sh old mode 100644 new mode 100755 index 425abf4..7845878 --- a/bin/setenv.sh +++ b/bin/setenv.sh @@ -1,4 +1,5 @@ #!/bin/sh export JAVA_HOME=/usr/caimito/jdk +#export JAVA_HOME=/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0 export JRE_HOME=$JAVA_HOME export PATH=$JAVA_HOME/bin:$PATH diff --git a/bin/shutdown.bat b/bin/shutdown.bat old mode 100644 new mode 100755 index 9c652a5..0f30951 --- a/bin/shutdown.bat +++ b/bin/shutdown.bat @@ -1,59 +1,59 @@ -@echo off -rem Licensed to the Apache Software Foundation (ASF) under one or more -rem contributor license agreements. See the NOTICE file distributed with -rem this work for additional information regarding copyright ownership. -rem The ASF licenses this file to You under the Apache License, Version 2.0 -rem (the "License"); you may not use this file except in compliance with -rem the License. You may obtain a copy of the License at -rem -rem http://www.apache.org/licenses/LICENSE-2.0 -rem -rem Unless required by applicable law or agreed to in writing, software -rem distributed under the License is distributed on an "AS IS" BASIS, -rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -rem See the License for the specific language governing permissions and -rem limitations under the License. - -if "%OS%" == "Windows_NT" setlocal -rem --------------------------------------------------------------------------- -rem Stop script for the CATALINA Server -rem -rem $Id: shutdown.bat 895392 2010-01-03 14:02:31Z kkolinko $ -rem --------------------------------------------------------------------------- - -rem Guess CATALINA_HOME if not defined -set "CURRENT_DIR=%cd%" -if not "%CATALINA_HOME%" == "" goto gotHome -set "CATALINA_HOME=%CURRENT_DIR%" -if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome -cd .. -set "CATALINA_HOME=%cd%" -cd "%CURRENT_DIR%" -:gotHome -if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome -echo The CATALINA_HOME environment variable is not defined correctly -echo This environment variable is needed to run this program -goto end -:okHome - -set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat" - -rem Check that target executable exists -if exist "%EXECUTABLE%" goto okExec -echo Cannot find "%EXECUTABLE%" -echo This file is needed to run this program -goto end -:okExec - -rem Get remaining unshifted command line arguments and save them in the -set CMD_LINE_ARGS= -:setArgs -if ""%1""=="""" goto doneSetArgs -set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1 -shift -goto setArgs -:doneSetArgs - -call "%EXECUTABLE%" stop %CMD_LINE_ARGS% - -:end +@echo off +rem Licensed to the Apache Software Foundation (ASF) under one or more +rem contributor license agreements. See the NOTICE file distributed with +rem this work for additional information regarding copyright ownership. +rem The ASF licenses this file to You under the Apache License, Version 2.0 +rem (the "License"); you may not use this file except in compliance with +rem the License. You may obtain a copy of the License at +rem +rem http://www.apache.org/licenses/LICENSE-2.0 +rem +rem Unless required by applicable law or agreed to in writing, software +rem distributed under the License is distributed on an "AS IS" BASIS, +rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +rem See the License for the specific language governing permissions and +rem limitations under the License. + +if "%OS%" == "Windows_NT" setlocal +rem --------------------------------------------------------------------------- +rem Stop script for the CATALINA Server +rem +rem $Id: shutdown.bat 895392 2010-01-03 14:02:31Z kkolinko $ +rem --------------------------------------------------------------------------- + +rem Guess CATALINA_HOME if not defined +set "CURRENT_DIR=%cd%" +if not "%CATALINA_HOME%" == "" goto gotHome +set "CATALINA_HOME=%CURRENT_DIR%" +if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome +cd .. +set "CATALINA_HOME=%cd%" +cd "%CURRENT_DIR%" +:gotHome +if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome +echo The CATALINA_HOME environment variable is not defined correctly +echo This environment variable is needed to run this program +goto end +:okHome + +set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat" + +rem Check that target executable exists +if exist "%EXECUTABLE%" goto okExec +echo Cannot find "%EXECUTABLE%" +echo This file is needed to run this program +goto end +:okExec + +rem Get remaining unshifted command line arguments and save them in the +set CMD_LINE_ARGS= +:setArgs +if ""%1""=="""" goto doneSetArgs +set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1 +shift +goto setArgs +:doneSetArgs + +call "%EXECUTABLE%" stop %CMD_LINE_ARGS% + +:end diff --git a/bin/shutdown.sh b/bin/shutdown.sh old mode 100644 new mode 100755 diff --git a/bin/startup.bat b/bin/startup.bat old mode 100644 new mode 100755 diff --git a/bin/startup.sh b/bin/startup.sh old mode 100644 new mode 100755 diff --git a/bin/tomcat-juli.jar b/bin/tomcat-juli.jar old mode 100644 new mode 100755 diff --git a/bin/tomcat-native.tar.gz b/bin/tomcat-native.tar.gz old mode 100644 new mode 100755 diff --git a/bin/tool-wrapper.bat b/bin/tool-wrapper.bat old mode 100644 new mode 100755 index 9eb3612..0d4dae6 --- a/bin/tool-wrapper.bat +++ b/bin/tool-wrapper.bat @@ -1,97 +1,97 @@ -@echo off -rem Licensed to the Apache Software Foundation (ASF) under one or more -rem contributor license agreements. See the NOTICE file distributed with -rem this work for additional information regarding copyright ownership. -rem The ASF licenses this file to You under the Apache License, Version 2.0 -rem (the "License"); you may not use this file except in compliance with -rem the License. You may obtain a copy of the License at -rem -rem http://www.apache.org/licenses/LICENSE-2.0 -rem -rem Unless required by applicable law or agreed to in writing, software -rem distributed under the License is distributed on an "AS IS" BASIS, -rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -rem See the License for the specific language governing permissions and -rem limitations under the License. - -if "%OS%" == "Windows_NT" setlocal -rem --------------------------------------------------------------------------- -rem Wrapper script for command line tools -rem -rem Environment Variable Prerequisites -rem -rem CATALINA_HOME May point at your Catalina "build" directory. -rem -rem TOOL_OPTS (Optional) Java runtime options. -rem -rem JAVA_HOME Must point at your Java Development Kit installation. -rem Using JRE_HOME instead works as well. -rem -rem JRE_HOME Must point at your Java Runtime installation. -rem Defaults to JAVA_HOME if empty. If JRE_HOME and JAVA_HOME -rem are both set, JRE_HOME is used. -rem -rem JAVA_OPTS (Optional) Java runtime options. -rem -rem JAVA_ENDORSED_DIRS (Optional) Lists of of semi-colon separated directories -rem containing some jars in order to allow replacement of APIs -rem created outside of the JCP (i.e. DOM and SAX from W3C). -rem It can also be used to update the XML parser implementation. -rem Defaults to $CATALINA_HOME/endorsed. -rem -rem $Id: tool-wrapper.bat 1138835 2011-06-23 11:27:57Z rjung $ -rem --------------------------------------------------------------------------- - -rem Guess CATALINA_HOME if not defined -set "CURRENT_DIR=%cd%" -if not "%CATALINA_HOME%" == "" goto gotHome -set "CATALINA_HOME=%CURRENT_DIR%" -if exist "%CATALINA_HOME%\bin\tool-wrapper.bat" goto okHome -cd .. -set "CATALINA_HOME=%cd%" -cd "%CURRENT_DIR%" -:gotHome -if exist "%CATALINA_HOME%\bin\tool-wrapper.bat" goto okHome -echo The CATALINA_HOME environment variable is not defined correctly -echo This environment variable is needed to run this program -goto end -:okHome - -rem Ensure that any user defined CLASSPATH variables are not used on startup, -rem but allow them to be specified in setenv.bat, in rare case when it is needed. -set CLASSPATH= - -rem Get standard environment variables -if exist "%CATALINA_HOME%\bin\setenv.bat" call "%CATALINA_HOME%\bin\setenv.bat" - -rem Get standard Java environment variables -if exist "%CATALINA_HOME%\bin\setclasspath.bat" goto okSetclasspath -echo Cannot find "%CATALINA_HOME%\bin\setclasspath.bat" -echo This file is needed to run this program -goto end -:okSetclasspath -call "%CATALINA_HOME%\bin\setclasspath.bat" %1 -if errorlevel 1 goto end - -rem Add on extra jar files to CLASSPATH -rem Note that there are no quotes as we do not want to introduce random -rem quotes into the CLASSPATH -if "%CLASSPATH%" == "" goto emptyClasspath -set "CLASSPATH=%CLASSPATH%;" -:emptyClasspath -set "CLASSPATH=%CLASSPATH%%CATALINA_HOME%\bin\bootstrap.jar;%CATALINA_HOME%\bin\tomcat-juli.jar;%CATALINA_HOME%\lib\servlet-api.jar" - -set JAVA_OPTS=%JAVA_OPTS% -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager - -rem Get remaining unshifted command line arguments and save them in the -set CMD_LINE_ARGS= -:setArgs -if ""%1""=="""" goto doneSetArgs -set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1 -shift -goto setArgs -:doneSetArgs - -%_RUNJAVA% %JAVA_OPTS% %TOOL_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.home="%CATALINA_HOME%" org.apache.catalina.startup.Tool %CMD_LINE_ARGS% - -:end +@echo off +rem Licensed to the Apache Software Foundation (ASF) under one or more +rem contributor license agreements. See the NOTICE file distributed with +rem this work for additional information regarding copyright ownership. +rem The ASF licenses this file to You under the Apache License, Version 2.0 +rem (the "License"); you may not use this file except in compliance with +rem the License. You may obtain a copy of the License at +rem +rem http://www.apache.org/licenses/LICENSE-2.0 +rem +rem Unless required by applicable law or agreed to in writing, software +rem distributed under the License is distributed on an "AS IS" BASIS, +rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +rem See the License for the specific language governing permissions and +rem limitations under the License. + +if "%OS%" == "Windows_NT" setlocal +rem --------------------------------------------------------------------------- +rem Wrapper script for command line tools +rem +rem Environment Variable Prerequisites +rem +rem CATALINA_HOME May point at your Catalina "build" directory. +rem +rem TOOL_OPTS (Optional) Java runtime options. +rem +rem JAVA_HOME Must point at your Java Development Kit installation. +rem Using JRE_HOME instead works as well. +rem +rem JRE_HOME Must point at your Java Runtime installation. +rem Defaults to JAVA_HOME if empty. If JRE_HOME and JAVA_HOME +rem are both set, JRE_HOME is used. +rem +rem JAVA_OPTS (Optional) Java runtime options. +rem +rem JAVA_ENDORSED_DIRS (Optional) Lists of of semi-colon separated directories +rem containing some jars in order to allow replacement of APIs +rem created outside of the JCP (i.e. DOM and SAX from W3C). +rem It can also be used to update the XML parser implementation. +rem Defaults to $CATALINA_HOME/endorsed. +rem +rem $Id: tool-wrapper.bat 1138835 2011-06-23 11:27:57Z rjung $ +rem --------------------------------------------------------------------------- + +rem Guess CATALINA_HOME if not defined +set "CURRENT_DIR=%cd%" +if not "%CATALINA_HOME%" == "" goto gotHome +set "CATALINA_HOME=%CURRENT_DIR%" +if exist "%CATALINA_HOME%\bin\tool-wrapper.bat" goto okHome +cd .. +set "CATALINA_HOME=%cd%" +cd "%CURRENT_DIR%" +:gotHome +if exist "%CATALINA_HOME%\bin\tool-wrapper.bat" goto okHome +echo The CATALINA_HOME environment variable is not defined correctly +echo This environment variable is needed to run this program +goto end +:okHome + +rem Ensure that any user defined CLASSPATH variables are not used on startup, +rem but allow them to be specified in setenv.bat, in rare case when it is needed. +set CLASSPATH= + +rem Get standard environment variables +if exist "%CATALINA_HOME%\bin\setenv.bat" call "%CATALINA_HOME%\bin\setenv.bat" + +rem Get standard Java environment variables +if exist "%CATALINA_HOME%\bin\setclasspath.bat" goto okSetclasspath +echo Cannot find "%CATALINA_HOME%\bin\setclasspath.bat" +echo This file is needed to run this program +goto end +:okSetclasspath +call "%CATALINA_HOME%\bin\setclasspath.bat" %1 +if errorlevel 1 goto end + +rem Add on extra jar files to CLASSPATH +rem Note that there are no quotes as we do not want to introduce random +rem quotes into the CLASSPATH +if "%CLASSPATH%" == "" goto emptyClasspath +set "CLASSPATH=%CLASSPATH%;" +:emptyClasspath +set "CLASSPATH=%CLASSPATH%%CATALINA_HOME%\bin\bootstrap.jar;%CATALINA_HOME%\bin\tomcat-juli.jar;%CATALINA_HOME%\lib\servlet-api.jar" + +set JAVA_OPTS=%JAVA_OPTS% -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager + +rem Get remaining unshifted command line arguments and save them in the +set CMD_LINE_ARGS= +:setArgs +if ""%1""=="""" goto doneSetArgs +set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1 +shift +goto setArgs +:doneSetArgs + +%_RUNJAVA% %JAVA_OPTS% %TOOL_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.home="%CATALINA_HOME%" org.apache.catalina.startup.Tool %CMD_LINE_ARGS% + +:end diff --git a/bin/tool-wrapper.sh b/bin/tool-wrapper.sh old mode 100644 new mode 100755 diff --git a/bin/version.bat b/bin/version.bat old mode 100644 new mode 100755 index efe2a2b..3a67165 --- a/bin/version.bat +++ b/bin/version.bat @@ -1,59 +1,59 @@ -@echo off -rem Licensed to the Apache Software Foundation (ASF) under one or more -rem contributor license agreements. See the NOTICE file distributed with -rem this work for additional information regarding copyright ownership. -rem The ASF licenses this file to You under the Apache License, Version 2.0 -rem (the "License"); you may not use this file except in compliance with -rem the License. You may obtain a copy of the License at -rem -rem http://www.apache.org/licenses/LICENSE-2.0 -rem -rem Unless required by applicable law or agreed to in writing, software -rem distributed under the License is distributed on an "AS IS" BASIS, -rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -rem See the License for the specific language governing permissions and -rem limitations under the License. - -if "%OS%" == "Windows_NT" setlocal -rem --------------------------------------------------------------------------- -rem Version script for the CATALINA Server -rem -rem $Id: version.bat 895392 2010-01-03 14:02:31Z kkolinko $ -rem --------------------------------------------------------------------------- - -rem Guess CATALINA_HOME if not defined -set "CURRENT_DIR=%cd%" -if not "%CATALINA_HOME%" == "" goto gotHome -set "CATALINA_HOME=%CURRENT_DIR%" -if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome -cd .. -set "CATALINA_HOME=%cd%" -cd "%CURRENT_DIR%" -:gotHome -if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome -echo The CATALINA_HOME environment variable is not defined correctly -echo This environment variable is needed to run this program -goto end -:okHome - -set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat" - -rem Check that target executable exists -if exist "%EXECUTABLE%" goto okExec -echo Cannot find "%EXECUTABLE%" -echo This file is needed to run this program -goto end -:okExec - -rem Get remaining unshifted command line arguments and save them in the -set CMD_LINE_ARGS= -:setArgs -if ""%1""=="""" goto doneSetArgs -set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1 -shift -goto setArgs -:doneSetArgs - -call "%EXECUTABLE%" version %CMD_LINE_ARGS% - -:end +@echo off +rem Licensed to the Apache Software Foundation (ASF) under one or more +rem contributor license agreements. See the NOTICE file distributed with +rem this work for additional information regarding copyright ownership. +rem The ASF licenses this file to You under the Apache License, Version 2.0 +rem (the "License"); you may not use this file except in compliance with +rem the License. You may obtain a copy of the License at +rem +rem http://www.apache.org/licenses/LICENSE-2.0 +rem +rem Unless required by applicable law or agreed to in writing, software +rem distributed under the License is distributed on an "AS IS" BASIS, +rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +rem See the License for the specific language governing permissions and +rem limitations under the License. + +if "%OS%" == "Windows_NT" setlocal +rem --------------------------------------------------------------------------- +rem Version script for the CATALINA Server +rem +rem $Id: version.bat 895392 2010-01-03 14:02:31Z kkolinko $ +rem --------------------------------------------------------------------------- + +rem Guess CATALINA_HOME if not defined +set "CURRENT_DIR=%cd%" +if not "%CATALINA_HOME%" == "" goto gotHome +set "CATALINA_HOME=%CURRENT_DIR%" +if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome +cd .. +set "CATALINA_HOME=%cd%" +cd "%CURRENT_DIR%" +:gotHome +if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome +echo The CATALINA_HOME environment variable is not defined correctly +echo This environment variable is needed to run this program +goto end +:okHome + +set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat" + +rem Check that target executable exists +if exist "%EXECUTABLE%" goto okExec +echo Cannot find "%EXECUTABLE%" +echo This file is needed to run this program +goto end +:okExec + +rem Get remaining unshifted command line arguments and save them in the +set CMD_LINE_ARGS= +:setArgs +if ""%1""=="""" goto doneSetArgs +set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1 +shift +goto setArgs +:doneSetArgs + +call "%EXECUTABLE%" version %CMD_LINE_ARGS% + +:end diff --git a/bin/version.sh b/bin/version.sh old mode 100644 new mode 100755 diff --git a/conf/Catalina/localhost/ROOT.xml.sample b/conf/Catalina/localhost/ROOT.xml.sample old mode 100644 new mode 100755 diff --git a/conf/catalina.policy b/conf/catalina.policy old mode 100644 new mode 100755 index 3c7748e..7f23e25 --- a/conf/catalina.policy +++ b/conf/catalina.policy @@ -1,246 +1,246 @@ -// Licensed to the Apache Software Foundation (ASF) under one or more -// contributor license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright ownership. -// The ASF licenses this file to You under the Apache License, Version 2.0 -// (the "License"); you may not use this file except in compliance with -// the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// ============================================================================ -// catalina.policy - Security Policy Permissions for Tomcat 7 -// -// This file contains a default set of security policies to be enforced (by the -// JVM) when Catalina is executed with the "-security" option. In addition -// to the permissions granted here, the following additional permissions are -// granted to each web application: -// -// * Read access to the web application's document root directory -// * Read, write and delete access to the web application's working directory -// -// $Id: catalina.policy 1220297 2011-12-17 22:55:28Z markt $ -// ============================================================================ - - -// ========== SYSTEM CODE PERMISSIONS ========================================= - - -// These permissions apply to javac -grant codeBase "file:${java.home}/lib/-" { - permission java.security.AllPermission; -}; - -// These permissions apply to all shared system extensions -grant codeBase "file:${java.home}/jre/lib/ext/-" { - permission java.security.AllPermission; -}; - -// These permissions apply to javac when ${java.home] points at $JAVA_HOME/jre -grant codeBase "file:${java.home}/../lib/-" { - permission java.security.AllPermission; -}; - -// These permissions apply to all shared system extensions when -// ${java.home} points at $JAVA_HOME/jre -grant codeBase "file:${java.home}/lib/ext/-" { - permission java.security.AllPermission; -}; - - -// ========== CATALINA CODE PERMISSIONS ======================================= - - -// These permissions apply to the daemon code -grant codeBase "file:${catalina.home}/bin/commons-daemon.jar" { - permission java.security.AllPermission; -}; - -// These permissions apply to the logging API -// Note: If tomcat-juli.jar is in ${catalina.base} and not in ${catalina.home}, -// update this section accordingly. -// grant codeBase "file:${catalina.base}/bin/tomcat-juli.jar" {..} -grant codeBase "file:${catalina.home}/bin/tomcat-juli.jar" { - permission java.io.FilePermission - "${java.home}${file.separator}lib${file.separator}logging.properties", "read"; - - permission java.io.FilePermission - "${catalina.base}${file.separator}conf${file.separator}logging.properties", "read"; - permission java.io.FilePermission - "${catalina.base}${file.separator}logs", "read, write"; - permission java.io.FilePermission - "${catalina.base}${file.separator}logs${file.separator}*", "read, write"; - - permission java.lang.RuntimePermission "shutdownHooks"; - permission java.lang.RuntimePermission "getClassLoader"; - permission java.lang.RuntimePermission "setContextClassLoader"; - - permission java.util.logging.LoggingPermission "control"; - - permission java.util.PropertyPermission "java.util.logging.config.class", "read"; - permission java.util.PropertyPermission "java.util.logging.config.file", "read"; - permission java.util.PropertyPermission "catalina.base", "read"; - permission java.util.PropertyPermission - "org.apache.juli.logging.UserDataHelper.CONFIG", "read"; - permission java.util.PropertyPermission - "org.apache.juli.logging.UserDataHelper.SUPPRESSION_TIME", "read"; - - // Note: To enable per context logging configuration, permit read access to - // the appropriate file. Be sure that the logging configuration is - // secure before enabling such access. - // E.g. for the examples web application (uncomment and unwrap - // the following to be on a single line): - // permission java.io.FilePermission "${catalina.base}${file.separator} - // webapps${file.separator}examples${file.separator}WEB-INF - // ${file.separator}classes${file.separator}logging.properties", "read"; -}; - -// These permissions apply to the server startup code -grant codeBase "file:${catalina.home}/bin/bootstrap.jar" { - permission java.security.AllPermission; -}; - -// These permissions apply to the servlet API classes -// and those that are shared across all class loaders -// located in the "lib" directory -grant codeBase "file:${catalina.home}/lib/-" { - permission java.security.AllPermission; -}; - - -// If using a per instance lib directory, i.e. ${catalina.base}/lib, -// then the following permission will need to be uncommented -// grant codeBase "file:${catalina.base}/lib/-" { -// permission java.security.AllPermission; -// }; - - -// ========== WEB APPLICATION PERMISSIONS ===================================== - - -// These permissions are granted by default to all web applications -// In addition, a web application will be given a read FilePermission -// and JndiPermission for all files and directories in its document root. -grant { - // Required for JNDI lookup of named JDBC DataSource's and - // javamail named MimePart DataSource used to send mail - permission java.util.PropertyPermission "java.home", "read"; - permission java.util.PropertyPermission "java.naming.*", "read"; - permission java.util.PropertyPermission "javax.sql.*", "read"; - - // OS Specific properties to allow read access - permission java.util.PropertyPermission "os.name", "read"; - permission java.util.PropertyPermission "os.version", "read"; - permission java.util.PropertyPermission "os.arch", "read"; - permission java.util.PropertyPermission "file.separator", "read"; - permission java.util.PropertyPermission "path.separator", "read"; - permission java.util.PropertyPermission "line.separator", "read"; - - // JVM properties to allow read access - permission java.util.PropertyPermission "java.version", "read"; - permission java.util.PropertyPermission "java.vendor", "read"; - permission java.util.PropertyPermission "java.vendor.url", "read"; - permission java.util.PropertyPermission "java.class.version", "read"; - permission java.util.PropertyPermission "java.specification.version", "read"; - permission java.util.PropertyPermission "java.specification.vendor", "read"; - permission java.util.PropertyPermission "java.specification.name", "read"; - - permission java.util.PropertyPermission "java.vm.specification.version", "read"; - permission java.util.PropertyPermission "java.vm.specification.vendor", "read"; - permission java.util.PropertyPermission "java.vm.specification.name", "read"; - permission java.util.PropertyPermission "java.vm.version", "read"; - permission java.util.PropertyPermission "java.vm.vendor", "read"; - permission java.util.PropertyPermission "java.vm.name", "read"; - - // Required for OpenJMX - permission java.lang.RuntimePermission "getAttribute"; - - // Allow read of JAXP compliant XML parser debug - permission java.util.PropertyPermission "jaxp.debug", "read"; - - // All JSPs need to be able to read this package - permission java.lang.RuntimePermission "accessClassInPackage.org.apache.tomcat"; - - // Precompiled JSPs need access to these packages. - permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.el"; - permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime"; - permission java.lang.RuntimePermission - "accessClassInPackage.org.apache.jasper.runtime.*"; - - // Precompiled JSPs need access to these system properties. - permission java.util.PropertyPermission - "org.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER", "read"; - permission java.util.PropertyPermission - "org.apache.el.parser.COERCE_TO_ZERO", "read"; - - // The cookie code needs these. - permission java.util.PropertyPermission - "org.apache.catalina.STRICT_SERVLET_COMPLIANCE", "read"; - permission java.util.PropertyPermission - "org.apache.tomcat.util.http.ServerCookie.STRICT_NAMING", "read"; - permission java.util.PropertyPermission - "org.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR", "read"; - - // Applications using Comet need to be able to access this package - permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.comet"; -}; - - -// The Manager application needs access to the following packages to support the -// session display functionality. These settings support the following -// configurations: -// - default CATALINA_HOME == CATALINA_BASE -// - CATALINA_HOME != CATALINA_BASE, per instance Manager in CATALINA_BASE -// - CATALINA_HOME != CATALINA_BASE, shared Manager in CATALINA_HOME -grant codeBase "file:${catalina.base}/webapps/manager/-" { - permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina"; - permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.ha.session"; - permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager"; - permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager.util"; - permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.util"; -}; -grant codeBase "file:${catalina.home}/webapps/manager/-" { - permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina"; - permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.ha.session"; - permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager"; - permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager.util"; - permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.util"; -}; - -// You can assign additional permissions to particular web applications by -// adding additional "grant" entries here, based on the code base for that -// application, /WEB-INF/classes/, or /WEB-INF/lib/ jar files. -// -// Different permissions can be granted to JSP pages, classes loaded from -// the /WEB-INF/classes/ directory, all jar files in the /WEB-INF/lib/ -// directory, or even to individual jar files in the /WEB-INF/lib/ directory. -// -// For instance, assume that the standard "examples" application -// included a JDBC driver that needed to establish a network connection to the -// corresponding database and used the scrape taglib to get the weather from -// the NOAA web server. You might create a "grant" entries like this: -// -// The permissions granted to the context root directory apply to JSP pages. -// grant codeBase "file:${catalina.base}/webapps/examples/-" { -// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect"; -// permission java.net.SocketPermission "*.noaa.gov:80", "connect"; -// }; -// -// The permissions granted to the context WEB-INF/classes directory -// grant codeBase "file:${catalina.base}/webapps/examples/WEB-INF/classes/-" { -// }; -// -// The permission granted to your JDBC driver -// grant codeBase "jar:file:${catalina.base}/webapps/examples/WEB-INF/lib/driver.jar!/-" { -// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect"; -// }; -// The permission granted to the scrape taglib -// grant codeBase "jar:file:${catalina.base}/webapps/examples/WEB-INF/lib/scrape.jar!/-" { -// permission java.net.SocketPermission "*.noaa.gov:80", "connect"; -// }; - +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// ============================================================================ +// catalina.policy - Security Policy Permissions for Tomcat 7 +// +// This file contains a default set of security policies to be enforced (by the +// JVM) when Catalina is executed with the "-security" option. In addition +// to the permissions granted here, the following additional permissions are +// granted to each web application: +// +// * Read access to the web application's document root directory +// * Read, write and delete access to the web application's working directory +// +// $Id: catalina.policy 1220297 2011-12-17 22:55:28Z markt $ +// ============================================================================ + + +// ========== SYSTEM CODE PERMISSIONS ========================================= + + +// These permissions apply to javac +grant codeBase "file:${java.home}/lib/-" { + permission java.security.AllPermission; +}; + +// These permissions apply to all shared system extensions +grant codeBase "file:${java.home}/jre/lib/ext/-" { + permission java.security.AllPermission; +}; + +// These permissions apply to javac when ${java.home] points at $JAVA_HOME/jre +grant codeBase "file:${java.home}/../lib/-" { + permission java.security.AllPermission; +}; + +// These permissions apply to all shared system extensions when +// ${java.home} points at $JAVA_HOME/jre +grant codeBase "file:${java.home}/lib/ext/-" { + permission java.security.AllPermission; +}; + + +// ========== CATALINA CODE PERMISSIONS ======================================= + + +// These permissions apply to the daemon code +grant codeBase "file:${catalina.home}/bin/commons-daemon.jar" { + permission java.security.AllPermission; +}; + +// These permissions apply to the logging API +// Note: If tomcat-juli.jar is in ${catalina.base} and not in ${catalina.home}, +// update this section accordingly. +// grant codeBase "file:${catalina.base}/bin/tomcat-juli.jar" {..} +grant codeBase "file:${catalina.home}/bin/tomcat-juli.jar" { + permission java.io.FilePermission + "${java.home}${file.separator}lib${file.separator}logging.properties", "read"; + + permission java.io.FilePermission + "${catalina.base}${file.separator}conf${file.separator}logging.properties", "read"; + permission java.io.FilePermission + "${catalina.base}${file.separator}logs", "read, write"; + permission java.io.FilePermission + "${catalina.base}${file.separator}logs${file.separator}*", "read, write"; + + permission java.lang.RuntimePermission "shutdownHooks"; + permission java.lang.RuntimePermission "getClassLoader"; + permission java.lang.RuntimePermission "setContextClassLoader"; + + permission java.util.logging.LoggingPermission "control"; + + permission java.util.PropertyPermission "java.util.logging.config.class", "read"; + permission java.util.PropertyPermission "java.util.logging.config.file", "read"; + permission java.util.PropertyPermission "catalina.base", "read"; + permission java.util.PropertyPermission + "org.apache.juli.logging.UserDataHelper.CONFIG", "read"; + permission java.util.PropertyPermission + "org.apache.juli.logging.UserDataHelper.SUPPRESSION_TIME", "read"; + + // Note: To enable per context logging configuration, permit read access to + // the appropriate file. Be sure that the logging configuration is + // secure before enabling such access. + // E.g. for the examples web application (uncomment and unwrap + // the following to be on a single line): + // permission java.io.FilePermission "${catalina.base}${file.separator} + // webapps${file.separator}examples${file.separator}WEB-INF + // ${file.separator}classes${file.separator}logging.properties", "read"; +}; + +// These permissions apply to the server startup code +grant codeBase "file:${catalina.home}/bin/bootstrap.jar" { + permission java.security.AllPermission; +}; + +// These permissions apply to the servlet API classes +// and those that are shared across all class loaders +// located in the "lib" directory +grant codeBase "file:${catalina.home}/lib/-" { + permission java.security.AllPermission; +}; + + +// If using a per instance lib directory, i.e. ${catalina.base}/lib, +// then the following permission will need to be uncommented +// grant codeBase "file:${catalina.base}/lib/-" { +// permission java.security.AllPermission; +// }; + + +// ========== WEB APPLICATION PERMISSIONS ===================================== + + +// These permissions are granted by default to all web applications +// In addition, a web application will be given a read FilePermission +// and JndiPermission for all files and directories in its document root. +grant { + // Required for JNDI lookup of named JDBC DataSource's and + // javamail named MimePart DataSource used to send mail + permission java.util.PropertyPermission "java.home", "read"; + permission java.util.PropertyPermission "java.naming.*", "read"; + permission java.util.PropertyPermission "javax.sql.*", "read"; + + // OS Specific properties to allow read access + permission java.util.PropertyPermission "os.name", "read"; + permission java.util.PropertyPermission "os.version", "read"; + permission java.util.PropertyPermission "os.arch", "read"; + permission java.util.PropertyPermission "file.separator", "read"; + permission java.util.PropertyPermission "path.separator", "read"; + permission java.util.PropertyPermission "line.separator", "read"; + + // JVM properties to allow read access + permission java.util.PropertyPermission "java.version", "read"; + permission java.util.PropertyPermission "java.vendor", "read"; + permission java.util.PropertyPermission "java.vendor.url", "read"; + permission java.util.PropertyPermission "java.class.version", "read"; + permission java.util.PropertyPermission "java.specification.version", "read"; + permission java.util.PropertyPermission "java.specification.vendor", "read"; + permission java.util.PropertyPermission "java.specification.name", "read"; + + permission java.util.PropertyPermission "java.vm.specification.version", "read"; + permission java.util.PropertyPermission "java.vm.specification.vendor", "read"; + permission java.util.PropertyPermission "java.vm.specification.name", "read"; + permission java.util.PropertyPermission "java.vm.version", "read"; + permission java.util.PropertyPermission "java.vm.vendor", "read"; + permission java.util.PropertyPermission "java.vm.name", "read"; + + // Required for OpenJMX + permission java.lang.RuntimePermission "getAttribute"; + + // Allow read of JAXP compliant XML parser debug + permission java.util.PropertyPermission "jaxp.debug", "read"; + + // All JSPs need to be able to read this package + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.tomcat"; + + // Precompiled JSPs need access to these packages. + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.el"; + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime"; + permission java.lang.RuntimePermission + "accessClassInPackage.org.apache.jasper.runtime.*"; + + // Precompiled JSPs need access to these system properties. + permission java.util.PropertyPermission + "org.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER", "read"; + permission java.util.PropertyPermission + "org.apache.el.parser.COERCE_TO_ZERO", "read"; + + // The cookie code needs these. + permission java.util.PropertyPermission + "org.apache.catalina.STRICT_SERVLET_COMPLIANCE", "read"; + permission java.util.PropertyPermission + "org.apache.tomcat.util.http.ServerCookie.STRICT_NAMING", "read"; + permission java.util.PropertyPermission + "org.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR", "read"; + + // Applications using Comet need to be able to access this package + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.comet"; +}; + + +// The Manager application needs access to the following packages to support the +// session display functionality. These settings support the following +// configurations: +// - default CATALINA_HOME == CATALINA_BASE +// - CATALINA_HOME != CATALINA_BASE, per instance Manager in CATALINA_BASE +// - CATALINA_HOME != CATALINA_BASE, shared Manager in CATALINA_HOME +grant codeBase "file:${catalina.base}/webapps/manager/-" { + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina"; + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.ha.session"; + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager"; + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager.util"; + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.util"; +}; +grant codeBase "file:${catalina.home}/webapps/manager/-" { + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina"; + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.ha.session"; + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager"; + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager.util"; + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.util"; +}; + +// You can assign additional permissions to particular web applications by +// adding additional "grant" entries here, based on the code base for that +// application, /WEB-INF/classes/, or /WEB-INF/lib/ jar files. +// +// Different permissions can be granted to JSP pages, classes loaded from +// the /WEB-INF/classes/ directory, all jar files in the /WEB-INF/lib/ +// directory, or even to individual jar files in the /WEB-INF/lib/ directory. +// +// For instance, assume that the standard "examples" application +// included a JDBC driver that needed to establish a network connection to the +// corresponding database and used the scrape taglib to get the weather from +// the NOAA web server. You might create a "grant" entries like this: +// +// The permissions granted to the context root directory apply to JSP pages. +// grant codeBase "file:${catalina.base}/webapps/examples/-" { +// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect"; +// permission java.net.SocketPermission "*.noaa.gov:80", "connect"; +// }; +// +// The permissions granted to the context WEB-INF/classes directory +// grant codeBase "file:${catalina.base}/webapps/examples/WEB-INF/classes/-" { +// }; +// +// The permission granted to your JDBC driver +// grant codeBase "jar:file:${catalina.base}/webapps/examples/WEB-INF/lib/driver.jar!/-" { +// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect"; +// }; +// The permission granted to the scrape taglib +// grant codeBase "jar:file:${catalina.base}/webapps/examples/WEB-INF/lib/scrape.jar!/-" { +// permission java.net.SocketPermission "*.noaa.gov:80", "connect"; +// }; + diff --git a/conf/catalina.properties b/conf/catalina.properties old mode 100644 new mode 100755 index 652a57c..724a4da --- a/conf/catalina.properties +++ b/conf/catalina.properties @@ -1,119 +1,119 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# -# List of comma-separated packages that start with or equal this string -# will cause a security exception to be thrown when -# passed to checkPackageAccess unless the -# corresponding RuntimePermission ("accessClassInPackage."+package) has -# been granted. -package.access=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper. -# -# List of comma-separated packages that start with or equal this string -# will cause a security exception to be thrown when -# passed to checkPackageDefinition unless the -# corresponding RuntimePermission ("defineClassInPackage."+package) has -# been granted. -# -# by default, no packages are restricted for definition, and none of -# the class loaders supplied with the JDK call checkPackageDefinition. -# -package.definition=sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper. - -# -# -# List of comma-separated paths defining the contents of the "common" -# classloader. Prefixes should be used to define what is the repository type. -# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute. -# If left as blank,the JVM system loader will be used as Catalina's "common" -# loader. -# Examples: -# "foo": Add this folder as a class repository -# "foo/*.jar": Add all the JARs of the specified folder as class -# repositories -# "foo/bar.jar": Add bar.jar as a class repository -common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar - -# -# List of comma-separated paths defining the contents of the "server" -# classloader. Prefixes should be used to define what is the repository type. -# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute. -# If left as blank, the "common" loader will be used as Catalina's "server" -# loader. -# Examples: -# "foo": Add this folder as a class repository -# "foo/*.jar": Add all the JARs of the specified folder as class -# repositories -# "foo/bar.jar": Add bar.jar as a class repository -server.loader= - -# -# List of comma-separated paths defining the contents of the "shared" -# classloader. Prefixes should be used to define what is the repository type. -# Path may be relative to the CATALINA_BASE path or absolute. If left as blank, -# the "common" loader will be used as Catalina's "shared" loader. -# Examples: -# "foo": Add this folder as a class repository -# "foo/*.jar": Add all the JARs of the specified folder as class -# repositories -# "foo/bar.jar": Add bar.jar as a class repository -# Please note that for single jars, e.g. bar.jar, you need the URL form -# starting with file:. -shared.loader= - -# List of JAR files that should not be scanned for configuration information -# such as web fragments, TLD files etc. It must be a comma separated list of -# JAR file names. -# The JARs listed below include: -# - Tomcat Bootstrap JARs -# - Tomcat API JARs -# - Catalina JARs -# - Jasper JARs -# - Tomcat JARs -# - Common non-Tomcat JARs -# - Sun JDK JARs -# - Apple JDK JARs -tomcat.util.scan.DefaultJarScanner.jarsToSkip=\ -bootstrap.jar,commons-daemon.jar,tomcat-juli.jar,\ -annotations-api.jar,el-api.jar,jsp-api.jar,servlet-api.jar,\ -catalina.jar,catalina-ant.jar,catalina-ha.jar,catalina-tribes.jar,\ -jasper.jar,jasper-el.jar,ecj-*.jar,\ -tomcat-api.jar,tomcat-util.jar,tomcat-coyote.jar,tomcat-dbcp.jar,\ -tomcat-i18n-en.jar,tomcat-i18n-es.jar,tomcat-i18n-fr.jar,tomcat-i18n-ja.jar,\ -tomcat-juli-adapters.jar,catalina-jmx-remote.jar,catalina-ws.jar,\ -tomcat-jdbc.jar,\ -commons-beanutils*.jar,commons-codec*.jar,commons-collections*.jar,\ -commons-dbcp*.jar,commons-digester*.jar,commons-fileupload*.jar,\ -commons-httpclient*.jar,commons-io*.jar,commons-lang*.jar,commons-logging*.jar,\ -commons-math*.jar,commons-pool*.jar,\ -jstl.jar,\ -geronimo-spec-jaxrpc*.jar,wsdl4j*.jar,\ -ant.jar,ant-junit*.jar,aspectj*.jar,jmx.jar,h2*.jar,hibernate*.jar,httpclient*.jar,\ -jmx-tools.jar,jta*.jar,log4j*.jar,mail*.jar,slf4j*.jar,\ -xercesImpl.jar,xmlParserAPIs.jar,xml-apis.jar,\ -dnsns.jar,ldapsec.jar,localedata.jar,sunjce_provider.jar,sunmscapi.jar,\ -sunpkcs11.jar,jhall.jar,tools.jar,\ -sunec.jar,zipfs.jar,\ -apple_provider.jar,AppleScriptEngine.jar,CoreAudio.jar,dns_sd.jar,\ -j3daudio.jar,j3dcore.jar,j3dutils.jar,jai_core.jar,jai_codec.jar,\ -mlibwrapper_jai.jar,MRJToolkit.jar,vecmath.jar,\ -junit.jar,junit-*.jar,ant-launcher.jar - -# -# String cache configuration. -tomcat.util.buf.StringCache.byte.enabled=true -#tomcat.util.buf.StringCache.char.enabled=true -#tomcat.util.buf.StringCache.trainThreshold=500000 -#tomcat.util.buf.StringCache.cacheSize=5000 +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# List of comma-separated packages that start with or equal this string +# will cause a security exception to be thrown when +# passed to checkPackageAccess unless the +# corresponding RuntimePermission ("accessClassInPackage."+package) has +# been granted. +package.access=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper. +# +# List of comma-separated packages that start with or equal this string +# will cause a security exception to be thrown when +# passed to checkPackageDefinition unless the +# corresponding RuntimePermission ("defineClassInPackage."+package) has +# been granted. +# +# by default, no packages are restricted for definition, and none of +# the class loaders supplied with the JDK call checkPackageDefinition. +# +package.definition=sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper. + +# +# +# List of comma-separated paths defining the contents of the "common" +# classloader. Prefixes should be used to define what is the repository type. +# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute. +# If left as blank,the JVM system loader will be used as Catalina's "common" +# loader. +# Examples: +# "foo": Add this folder as a class repository +# "foo/*.jar": Add all the JARs of the specified folder as class +# repositories +# "foo/bar.jar": Add bar.jar as a class repository +common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar + +# +# List of comma-separated paths defining the contents of the "server" +# classloader. Prefixes should be used to define what is the repository type. +# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute. +# If left as blank, the "common" loader will be used as Catalina's "server" +# loader. +# Examples: +# "foo": Add this folder as a class repository +# "foo/*.jar": Add all the JARs of the specified folder as class +# repositories +# "foo/bar.jar": Add bar.jar as a class repository +server.loader= + +# +# List of comma-separated paths defining the contents of the "shared" +# classloader. Prefixes should be used to define what is the repository type. +# Path may be relative to the CATALINA_BASE path or absolute. If left as blank, +# the "common" loader will be used as Catalina's "shared" loader. +# Examples: +# "foo": Add this folder as a class repository +# "foo/*.jar": Add all the JARs of the specified folder as class +# repositories +# "foo/bar.jar": Add bar.jar as a class repository +# Please note that for single jars, e.g. bar.jar, you need the URL form +# starting with file:. +shared.loader= + +# List of JAR files that should not be scanned for configuration information +# such as web fragments, TLD files etc. It must be a comma separated list of +# JAR file names. +# The JARs listed below include: +# - Tomcat Bootstrap JARs +# - Tomcat API JARs +# - Catalina JARs +# - Jasper JARs +# - Tomcat JARs +# - Common non-Tomcat JARs +# - Sun JDK JARs +# - Apple JDK JARs +tomcat.util.scan.DefaultJarScanner.jarsToSkip=\ +bootstrap.jar,commons-daemon.jar,tomcat-juli.jar,\ +annotations-api.jar,el-api.jar,jsp-api.jar,servlet-api.jar,\ +catalina.jar,catalina-ant.jar,catalina-ha.jar,catalina-tribes.jar,\ +jasper.jar,jasper-el.jar,ecj-*.jar,\ +tomcat-api.jar,tomcat-util.jar,tomcat-coyote.jar,tomcat-dbcp.jar,\ +tomcat-i18n-en.jar,tomcat-i18n-es.jar,tomcat-i18n-fr.jar,tomcat-i18n-ja.jar,\ +tomcat-juli-adapters.jar,catalina-jmx-remote.jar,catalina-ws.jar,\ +tomcat-jdbc.jar,\ +commons-beanutils*.jar,commons-codec*.jar,commons-collections*.jar,\ +commons-dbcp*.jar,commons-digester*.jar,commons-fileupload*.jar,\ +commons-httpclient*.jar,commons-io*.jar,commons-lang*.jar,commons-logging*.jar,\ +commons-math*.jar,commons-pool*.jar,\ +jstl.jar,\ +geronimo-spec-jaxrpc*.jar,wsdl4j*.jar,\ +ant.jar,ant-junit*.jar,aspectj*.jar,jmx.jar,h2*.jar,hibernate*.jar,httpclient*.jar,\ +jmx-tools.jar,jta*.jar,log4j*.jar,mail*.jar,slf4j*.jar,\ +xercesImpl.jar,xmlParserAPIs.jar,xml-apis.jar,\ +dnsns.jar,ldapsec.jar,localedata.jar,sunjce_provider.jar,sunmscapi.jar,\ +sunpkcs11.jar,jhall.jar,tools.jar,\ +sunec.jar,zipfs.jar,\ +apple_provider.jar,AppleScriptEngine.jar,CoreAudio.jar,dns_sd.jar,\ +j3daudio.jar,j3dcore.jar,j3dutils.jar,jai_core.jar,jai_codec.jar,\ +mlibwrapper_jai.jar,MRJToolkit.jar,vecmath.jar,\ +junit.jar,junit-*.jar,ant-launcher.jar + +# +# String cache configuration. +tomcat.util.buf.StringCache.byte.enabled=true +#tomcat.util.buf.StringCache.char.enabled=true +#tomcat.util.buf.StringCache.trainThreshold=500000 +#tomcat.util.buf.StringCache.cacheSize=5000 diff --git a/conf/context.xml b/conf/context.xml old mode 100644 new mode 100755 index 745bf95..e313459 --- a/conf/context.xml +++ b/conf/context.xml @@ -1,35 +1,35 @@ - - - - - - - WEB-INF/web.xml - - - - - - - + + + + + + + WEB-INF/web.xml + + + + + + + \ No newline at end of file diff --git a/conf/logging.properties b/conf/logging.properties old mode 100644 new mode 100755 index 76c9512..90d7ea7 --- a/conf/logging.properties +++ b/conf/logging.properties @@ -1,64 +1,64 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -handlers = 1catalina.org.apache.juli.FileHandler, 2localhost.org.apache.juli.FileHandler, 3manager.org.apache.juli.FileHandler, 4host-manager.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler - -.handlers = 1catalina.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler - -############################################################ -# Handler specific properties. -# Describes specific configuration info for Handlers. -############################################################ - -1catalina.org.apache.juli.FileHandler.level = FINE -1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs -1catalina.org.apache.juli.FileHandler.prefix = catalina. - -2localhost.org.apache.juli.FileHandler.level = FINE -2localhost.org.apache.juli.FileHandler.directory = ${catalina.base}/logs -2localhost.org.apache.juli.FileHandler.prefix = localhost. - -3manager.org.apache.juli.FileHandler.level = FINE -3manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs -3manager.org.apache.juli.FileHandler.prefix = manager. - -4host-manager.org.apache.juli.FileHandler.level = FINE -4host-manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs -4host-manager.org.apache.juli.FileHandler.prefix = host-manager. - -java.util.logging.ConsoleHandler.level = FINE -java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter - - -############################################################ -# Facility specific properties. -# Provides extra control for each logger. -############################################################ - -org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO -org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler - -org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO -org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler - -org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO -org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler - -# For example, set the org.apache.catalina.util.LifecycleBase logger to log -# each component that extends LifecycleBase changing state: -#org.apache.catalina.util.LifecycleBase.level = FINE - -# To see debug messages in TldLocationsCache, uncomment the following line: -#org.apache.jasper.compiler.TldLocationsCache.level = FINE +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +handlers = 1catalina.org.apache.juli.FileHandler, 2localhost.org.apache.juli.FileHandler, 3manager.org.apache.juli.FileHandler, 4host-manager.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler + +.handlers = 1catalina.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler + +############################################################ +# Handler specific properties. +# Describes specific configuration info for Handlers. +############################################################ + +1catalina.org.apache.juli.FileHandler.level = FINE +1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs +1catalina.org.apache.juli.FileHandler.prefix = catalina. + +2localhost.org.apache.juli.FileHandler.level = FINE +2localhost.org.apache.juli.FileHandler.directory = ${catalina.base}/logs +2localhost.org.apache.juli.FileHandler.prefix = localhost. + +3manager.org.apache.juli.FileHandler.level = FINE +3manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs +3manager.org.apache.juli.FileHandler.prefix = manager. + +4host-manager.org.apache.juli.FileHandler.level = FINE +4host-manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs +4host-manager.org.apache.juli.FileHandler.prefix = host-manager. + +java.util.logging.ConsoleHandler.level = FINE +java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter + + +############################################################ +# Facility specific properties. +# Provides extra control for each logger. +############################################################ + +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler + +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler + +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO +org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler + +# For example, set the org.apache.catalina.util.LifecycleBase logger to log +# each component that extends LifecycleBase changing state: +#org.apache.catalina.util.LifecycleBase.level = FINE + +# To see debug messages in TldLocationsCache, uncomment the following line: +#org.apache.jasper.compiler.TldLocationsCache.level = FINE diff --git a/conf/server.xml b/conf/server.xml old mode 100644 new mode 100755 index b8a10f9..2a11ded --- a/conf/server.xml +++ b/conf/server.xml @@ -1,142 +1,142 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/tomcat-users.xml b/conf/tomcat-users.xml old mode 100644 new mode 100755 index 7f022ff..34e268d --- a/conf/tomcat-users.xml +++ b/conf/tomcat-users.xml @@ -1,36 +1,36 @@ - - - - - - - + + + + + + + diff --git a/conf/web.xml b/conf/web.xml old mode 100644 new mode 100755 index cc8383c..762c168 --- a/conf/web.xml +++ b/conf/web.xml @@ -1,4283 +1,4283 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - default - org.apache.catalina.servlets.DefaultServlet - - debug - 0 - - - listings - false - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - jsp - org.apache.jasper.servlet.JspServlet - - fork - false - - - xpoweredBy - false - - 3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - default - / - - - - - jsp - *.jsp - *.jspx - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 30 - - - - - - - - - - - - 123 - application/vnd.lotus-1-2-3 - - - 3dml - text/vnd.in3d.3dml - - - 3g2 - video/3gpp2 - - - 3gp - video/3gpp - - - 7z - application/x-7z-compressed - - - aab - application/x-authorware-bin - - - aac - audio/x-aac - - - aam - application/x-authorware-map - - - aas - application/x-authorware-seg - - - abs - audio/x-mpeg - - - abw - application/x-abiword - - - ac - application/pkix-attr-cert - - - acc - application/vnd.americandynamics.acc - - - ace - application/x-ace-compressed - - - acu - application/vnd.acucobol - - - acutc - application/vnd.acucorp - - - adp - audio/adpcm - - - aep - application/vnd.audiograph - - - afm - application/x-font-type1 - - - afp - application/vnd.ibm.modcap - - - ahead - application/vnd.ahead.space - - - ai - application/postscript - - - aif - audio/x-aiff - - - aifc - audio/x-aiff - - - aiff - audio/x-aiff - - - aim - application/x-aim - - - air - application/vnd.adobe.air-application-installer-package+zip - - - ait - application/vnd.dvb.ait - - - ami - application/vnd.amiga.ami - - - anx - application/annodex - - - apk - application/vnd.android.package-archive - - - application - application/x-ms-application - - - apr - application/vnd.lotus-approach - - - art - image/x-jg - - - asc - application/pgp-signature - - - asf - video/x-ms-asf - - - asm - text/x-asm - - - aso - application/vnd.accpac.simply.aso - - - asx - video/x-ms-asf - - - atc - application/vnd.acucorp - - - atom - application/atom+xml - - - atomcat - application/atomcat+xml - - - atomsvc - application/atomsvc+xml - - - atx - application/vnd.antix.game-component - - - au - audio/basic - - - avi - video/x-msvideo - - - avx - video/x-rad-screenplay - - - aw - application/applixware - - - axa - audio/annodex - - - axv - video/annodex - - - azf - application/vnd.airzip.filesecure.azf - - - azs - application/vnd.airzip.filesecure.azs - - - azw - application/vnd.amazon.ebook - - - bat - application/x-msdownload - - - bcpio - application/x-bcpio - - - bdf - application/x-font-bdf - - - bdm - application/vnd.syncml.dm+wbxml - - - bed - application/vnd.realvnc.bed - - - bh2 - application/vnd.fujitsu.oasysprs - - - bin - application/octet-stream - - - bmi - application/vnd.bmi - - - bmp - image/bmp - - - body - text/html - - - book - application/vnd.framemaker - - - box - application/vnd.previewsystems.box - - - boz - application/x-bzip2 - - - bpk - application/octet-stream - - - btif - image/prs.btif - - - bz - application/x-bzip - - - bz2 - application/x-bzip2 - - - c - text/x-c - - - c11amc - application/vnd.cluetrust.cartomobile-config - - - c11amz - application/vnd.cluetrust.cartomobile-config-pkg - - - c4d - application/vnd.clonk.c4group - - - c4f - application/vnd.clonk.c4group - - - c4g - application/vnd.clonk.c4group - - - c4p - application/vnd.clonk.c4group - - - c4u - application/vnd.clonk.c4group - - - cab - application/vnd.ms-cab-compressed - - - cap - application/vnd.tcpdump.pcap - - - car - application/vnd.curl.car - - - cat - application/vnd.ms-pki.seccat - - - cc - text/x-c - - - cct - application/x-director - - - ccxml - application/ccxml+xml - - - cdbcmsg - application/vnd.contact.cmsg - - - cdf - application/x-cdf - - - cdkey - application/vnd.mediastation.cdkey - - - cdmia - application/cdmi-capability - - - cdmic - application/cdmi-container - - - cdmid - application/cdmi-domain - - - cdmio - application/cdmi-object - - - cdmiq - application/cdmi-queue - - - cdx - chemical/x-cdx - - - cdxml - application/vnd.chemdraw+xml - - - cdy - application/vnd.cinderella - - - cer - application/pkix-cert - - - cgm - image/cgm - - - chat - application/x-chat - - - chm - application/vnd.ms-htmlhelp - - - chrt - application/vnd.kde.kchart - - - cif - chemical/x-cif - - - cii - application/vnd.anser-web-certificate-issue-initiation - - - cil - application/vnd.ms-artgalry - - - cla - application/vnd.claymore - - - class - application/java - - - clkk - application/vnd.crick.clicker.keyboard - - - clkp - application/vnd.crick.clicker.palette - - - clkt - application/vnd.crick.clicker.template - - - clkw - application/vnd.crick.clicker.wordbank - - - clkx - application/vnd.crick.clicker - - - clp - application/x-msclip - - - cmc - application/vnd.cosmocaller - - - cmdf - chemical/x-cmdf - - - cml - chemical/x-cml - - - cmp - application/vnd.yellowriver-custom-menu - - - cmx - image/x-cmx - - - cod - application/vnd.rim.cod - - - com - application/x-msdownload - - - conf - text/plain - - - cpio - application/x-cpio - - - cpp - text/x-c - - - cpt - application/mac-compactpro - - - crd - application/x-mscardfile - - - crl - application/pkix-crl - - - crt - application/x-x509-ca-cert - - - cryptonote - application/vnd.rig.cryptonote - - - csh - application/x-csh - - - csml - chemical/x-csml - - - csp - application/vnd.commonspace - - - css - text/css - - - cst - application/x-director - - - csv - text/csv - - - cu - application/cu-seeme - - - curl - text/vnd.curl - - - cww - application/prs.cww - - - cxt - application/x-director - - - cxx - text/x-c - - - dae - model/vnd.collada+xml - - - daf - application/vnd.mobius.daf - - - dataless - application/vnd.fdsn.seed - - - davmount - application/davmount+xml - - - dcr - application/x-director - - - dcurl - text/vnd.curl.dcurl - - - dd2 - application/vnd.oma.dd2+xml - - - ddd - application/vnd.fujixerox.ddd - - - deb - application/x-debian-package - - - def - text/plain - - - deploy - application/octet-stream - - - der - application/x-x509-ca-cert - - - dfac - application/vnd.dreamfactory - - - dib - image/bmp - - - dic - text/x-c - - - dir - application/x-director - - - dis - application/vnd.mobius.dis - - - dist - application/octet-stream - - - distz - application/octet-stream - - - djv - image/vnd.djvu - - - djvu - image/vnd.djvu - - - dll - application/x-msdownload - - - dmg - application/octet-stream - - - dmp - application/vnd.tcpdump.pcap - - - dms - application/octet-stream - - - dna - application/vnd.dna - - - doc - application/msword - - - docm - application/vnd.ms-word.document.macroenabled.12 - - - docx - application/vnd.openxmlformats-officedocument.wordprocessingml.document - - - dot - application/msword - - - dotm - application/vnd.ms-word.template.macroenabled.12 - - - dotx - application/vnd.openxmlformats-officedocument.wordprocessingml.template - - - dp - application/vnd.osgi.dp - - - dpg - application/vnd.dpgraph - - - dra - audio/vnd.dra - - - dsc - text/prs.lines.tag - - - dssc - application/dssc+der - - - dtb - application/x-dtbook+xml - - - dtd - application/xml-dtd - - - dts - audio/vnd.dts - - - dtshd - audio/vnd.dts.hd - - - dump - application/octet-stream - - - dv - video/x-dv - - - dvb - video/vnd.dvb.file - - - dvi - application/x-dvi - - - dwf - model/vnd.dwf - - - dwg - image/vnd.dwg - - - dxf - image/vnd.dxf - - - dxp - application/vnd.spotfire.dxp - - - dxr - application/x-director - - - ecelp4800 - audio/vnd.nuera.ecelp4800 - - - ecelp7470 - audio/vnd.nuera.ecelp7470 - - - ecelp9600 - audio/vnd.nuera.ecelp9600 - - - ecma - application/ecmascript - - - edm - application/vnd.novadigm.edm - - - edx - application/vnd.novadigm.edx - - - efif - application/vnd.picsel - - - ei6 - application/vnd.pg.osasli - - - elc - application/octet-stream - - - eml - message/rfc822 - - - emma - application/emma+xml - - - eol - audio/vnd.digital-winds - - - eot - application/vnd.ms-fontobject - - - eps - application/postscript - - - epub - application/epub+zip - - - es3 - application/vnd.eszigno3+xml - - - esf - application/vnd.epson.esf - - - et3 - application/vnd.eszigno3+xml - - - etx - text/x-setext - - - exe - application/octet-stream - - - exi - application/exi - - - ext - application/vnd.novadigm.ext - - - ez - application/andrew-inset - - - ez2 - application/vnd.ezpix-album - - - ez3 - application/vnd.ezpix-package - - - f - text/x-fortran - - - f4v - video/x-f4v - - - f77 - text/x-fortran - - - f90 - text/x-fortran - - - fbs - image/vnd.fastbidsheet - - - fcs - application/vnd.isac.fcs - - - fdf - application/vnd.fdf - - - fe_launch - application/vnd.denovo.fcselayout-link - - - fg5 - application/vnd.fujitsu.oasysgp - - - fgd - application/x-director - - - fh - image/x-freehand - - - fh4 - image/x-freehand - - - fh5 - image/x-freehand - - - fh7 - image/x-freehand - - - fhc - image/x-freehand - - - fig - application/x-xfig - - - flac - audio/flac - - - fli - video/x-fli - - - flo - application/vnd.micrografx.flo - - - flv - video/x-flv - - - flw - application/vnd.kde.kivio - - - flx - text/vnd.fmi.flexstor - - - fly - text/vnd.fly - - - fm - application/vnd.framemaker - - - fnc - application/vnd.frogans.fnc - - - for - text/x-fortran - - - fpx - image/vnd.fpx - - - frame - application/vnd.framemaker - - - fsc - application/vnd.fsc.weblaunch - - - fst - image/vnd.fst - - - ftc - application/vnd.fluxtime.clip - - - fti - application/vnd.anser-web-funds-transfer-initiation - - - fvt - video/vnd.fvt - - - fxp - application/vnd.adobe.fxp - - - fxpl - application/vnd.adobe.fxp - - - fzs - application/vnd.fuzzysheet - - - g2w - application/vnd.geoplan - - - g3 - image/g3fax - - - g3w - application/vnd.geospace - - - gac - application/vnd.groove-account - - - gbr - application/rpki-ghostbusters - - - gdl - model/vnd.gdl - - - geo - application/vnd.dynageo - - - gex - application/vnd.geometry-explorer - - - ggb - application/vnd.geogebra.file - - - ggt - application/vnd.geogebra.tool - - - ghf - application/vnd.groove-help - - - gif - image/gif - - - gim - application/vnd.groove-identity-message - - - gmx - application/vnd.gmx - - - gnumeric - application/x-gnumeric - - - gph - application/vnd.flographit - - - gqf - application/vnd.grafeq - - - gqs - application/vnd.grafeq - - - gram - application/srgs - - - gre - application/vnd.geometry-explorer - - - grv - application/vnd.groove-injector - - - grxml - application/srgs+xml - - - gsf - application/x-font-ghostscript - - - gtar - application/x-gtar - - - gtm - application/vnd.groove-tool-message - - - gtw - model/vnd.gtw - - - gv - text/vnd.graphviz - - - gxt - application/vnd.geonext - - - gz - application/x-gzip - - - h - text/x-c - - - h261 - video/h261 - - - h263 - video/h263 - - - h264 - video/h264 - - - hal - application/vnd.hal+xml - - - hbci - application/vnd.hbci - - - hdf - application/x-hdf - - - hh - text/x-c - - - hlp - application/winhlp - - - hpgl - application/vnd.hp-hpgl - - - hpid - application/vnd.hp-hpid - - - hps - application/vnd.hp-hps - - - hqx - application/mac-binhex40 - - - htc - text/x-component - - - htke - application/vnd.kenameaapp - - - htm - text/html - - - html - text/html - - - hvd - application/vnd.yamaha.hv-dic - - - hvp - application/vnd.yamaha.hv-voice - - - hvs - application/vnd.yamaha.hv-script - - - i2g - application/vnd.intergeo - - - icc - application/vnd.iccprofile - - - ice - x-conference/x-cooltalk - - - icm - application/vnd.iccprofile - - - ico - image/x-icon - - - ics - text/calendar - - - ief - image/ief - - - ifb - text/calendar - - - ifm - application/vnd.shana.informed.formdata - - - iges - model/iges - - - igl - application/vnd.igloader - - - igm - application/vnd.insors.igm - - - igs - model/iges - - - igx - application/vnd.micrografx.igx - - - iif - application/vnd.shana.informed.interchange - - - imp - application/vnd.accpac.simply.imp - - - ims - application/vnd.ms-ims - - - in - text/plain - - - ink - application/inkml+xml - - - inkml - application/inkml+xml - - - iota - application/vnd.astraea-software.iota - - - ipfix - application/ipfix - - - ipk - application/vnd.shana.informed.package - - - irm - application/vnd.ibm.rights-management - - - irp - application/vnd.irepository.package+xml - - - iso - application/octet-stream - - - itp - application/vnd.shana.informed.formtemplate - - - ivp - application/vnd.immervision-ivp - - - ivu - application/vnd.immervision-ivu - - - jad - text/vnd.sun.j2me.app-descriptor - - - jam - application/vnd.jam - - - jar - application/java-archive - - - java - text/x-java-source - - - jisp - application/vnd.jisp - - - jlt - application/vnd.hp-jlyt - - - jnlp - application/x-java-jnlp-file - - - joda - application/vnd.joost.joda-archive - - - jpe - image/jpeg - - - jpeg - image/jpeg - - - jpg - image/jpeg - - - jpgm - video/jpm - - - jpgv - video/jpeg - - - jpm - video/jpm - - - js - application/javascript - - - jsf - text/plain - - - json - application/json - - - jspf - text/plain - - - kar - audio/midi - - - karbon - application/vnd.kde.karbon - - - kfo - application/vnd.kde.kformula - - - kia - application/vnd.kidspiration - - - kml - application/vnd.google-earth.kml+xml - - - kmz - application/vnd.google-earth.kmz - - - kne - application/vnd.kinar - - - knp - application/vnd.kinar - - - kon - application/vnd.kde.kontour - - - kpr - application/vnd.kde.kpresenter - - - kpt - application/vnd.kde.kpresenter - - - ksp - application/vnd.kde.kspread - - - ktr - application/vnd.kahootz - - - ktx - image/ktx - - - ktz - application/vnd.kahootz - - - kwd - application/vnd.kde.kword - - - kwt - application/vnd.kde.kword - - - lasxml - application/vnd.las.las+xml - - - latex - application/x-latex - - - lbd - application/vnd.llamagraphics.life-balance.desktop - - - lbe - application/vnd.llamagraphics.life-balance.exchange+xml - - - les - application/vnd.hhe.lesson-player - - - lha - application/octet-stream - - - link66 - application/vnd.route66.link66+xml - - - list - text/plain - - - list3820 - application/vnd.ibm.modcap - - - listafp - application/vnd.ibm.modcap - - - log - text/plain - - - lostxml - application/lost+xml - - - lrf - application/octet-stream - - - lrm - application/vnd.ms-lrm - - - ltf - application/vnd.frogans.ltf - - - lvp - audio/vnd.lucent.voice - - - lwp - application/vnd.lotus-wordpro - - - lzh - application/octet-stream - - - m13 - application/x-msmediaview - - - m14 - application/x-msmediaview - - - m1v - video/mpeg - - - m21 - application/mp21 - - - m2a - audio/mpeg - - - m2v - video/mpeg - - - m3a - audio/mpeg - - - m3u - audio/x-mpegurl - - - m3u8 - application/vnd.apple.mpegurl - - - m4a - audio/mp4 - - - m4b - audio/mp4 - - - m4r - audio/mp4 - - - m4u - video/vnd.mpegurl - - - m4v - video/mp4 - - - ma - application/mathematica - - - mac - image/x-macpaint - - - mads - application/mads+xml - - - mag - application/vnd.ecowin.chart - - - maker - application/vnd.framemaker - - - man - text/troff - - - mathml - application/mathml+xml - - - mb - application/mathematica - - - mbk - application/vnd.mobius.mbk - - - mbox - application/mbox - - - mc1 - application/vnd.medcalcdata - - - mcd - application/vnd.mcd - - - mcurl - text/vnd.curl.mcurl - - - mdb - application/x-msaccess - - - mdi - image/vnd.ms-modi - - - me - text/troff - - - mesh - model/mesh - - - meta4 - application/metalink4+xml - - - mets - application/mets+xml - - - mfm - application/vnd.mfmp - - - mft - application/rpki-manifest - - - mgp - application/vnd.osgeo.mapguide.package - - - mgz - application/vnd.proteus.magazine - - - mid - audio/midi - - - midi - audio/midi - - - mif - application/x-mif - - - mime - message/rfc822 - - - mj2 - video/mj2 - - - mjp2 - video/mj2 - - - mlp - application/vnd.dolby.mlp - - - mmd - application/vnd.chipnuts.karaoke-mmd - - - mmf - application/vnd.smaf - - - mmr - image/vnd.fujixerox.edmics-mmr - - - mny - application/x-msmoney - - - mobi - application/x-mobipocket-ebook - - - mods - application/mods+xml - - - mov - video/quicktime - - - movie - video/x-sgi-movie - - - mp1 - audio/mpeg - - - mp2 - audio/mpeg - - - mp21 - application/mp21 - - - mp2a - audio/mpeg - - - mp3 - audio/mpeg - - - mp4 - video/mp4 - - - mp4a - audio/mp4 - - - mp4s - application/mp4 - - - mp4v - video/mp4 - - - mpa - audio/mpeg - - - mpc - application/vnd.mophun.certificate - - - mpe - video/mpeg - - - mpeg - video/mpeg - - - mpega - audio/x-mpeg - - - mpg - video/mpeg - - - mpg4 - video/mp4 - - - mpga - audio/mpeg - - - mpkg - application/vnd.apple.installer+xml - - - mpm - application/vnd.blueice.multipass - - - mpn - application/vnd.mophun.application - - - mpp - application/vnd.ms-project - - - mpt - application/vnd.ms-project - - - mpv2 - video/mpeg2 - - - mpy - application/vnd.ibm.minipay - - - mqy - application/vnd.mobius.mqy - - - mrc - application/marc - - - mrcx - application/marcxml+xml - - - ms - text/troff - - - mscml - application/mediaservercontrol+xml - - - mseed - application/vnd.fdsn.mseed - - - mseq - application/vnd.mseq - - - msf - application/vnd.epson.msf - - - msh - model/mesh - - - msi - application/x-msdownload - - - msl - application/vnd.mobius.msl - - - msty - application/vnd.muvee.style - - - mts - model/vnd.mts - - - mus - application/vnd.musician - - - musicxml - application/vnd.recordare.musicxml+xml - - - mvb - application/x-msmediaview - - - mwf - application/vnd.mfer - - - mxf - application/mxf - - - mxl - application/vnd.recordare.musicxml - - - mxml - application/xv+xml - - - mxs - application/vnd.triscape.mxs - - - mxu - video/vnd.mpegurl - - - n-gage - application/vnd.nokia.n-gage.symbian.install - - - n3 - text/n3 - - - nb - application/mathematica - - - nbp - application/vnd.wolfram.player - - - nc - application/x-netcdf - - - ncx - application/x-dtbncx+xml - - - ngdat - application/vnd.nokia.n-gage.data - - - nlu - application/vnd.neurolanguage.nlu - - - nml - application/vnd.enliven - - - nnd - application/vnd.noblenet-directory - - - nns - application/vnd.noblenet-sealer - - - nnw - application/vnd.noblenet-web - - - npx - image/vnd.net-fpx - - - nsf - application/vnd.lotus-notes - - - oa2 - application/vnd.fujitsu.oasys2 - - - oa3 - application/vnd.fujitsu.oasys3 - - - oas - application/vnd.fujitsu.oasys - - - obd - application/x-msbinder - - - oda - application/oda - - - - odb - application/vnd.oasis.opendocument.database - - - - odc - application/vnd.oasis.opendocument.chart - - - - odf - application/vnd.oasis.opendocument.formula - - - odft - application/vnd.oasis.opendocument.formula-template - - - - odg - application/vnd.oasis.opendocument.graphics - - - - odi - application/vnd.oasis.opendocument.image - - - - odm - application/vnd.oasis.opendocument.text-master - - - - odp - application/vnd.oasis.opendocument.presentation - - - - ods - application/vnd.oasis.opendocument.spreadsheet - - - - odt - application/vnd.oasis.opendocument.text - - - oga - audio/ogg - - - ogg - audio/ogg - - - ogv - video/ogg - - - - ogx - application/ogg - - - onepkg - application/onenote - - - onetmp - application/onenote - - - onetoc - application/onenote - - - onetoc2 - application/onenote - - - opf - application/oebps-package+xml - - - oprc - application/vnd.palm - - - org - application/vnd.lotus-organizer - - - osf - application/vnd.yamaha.openscoreformat - - - osfpvg - application/vnd.yamaha.openscoreformat.osfpvg+xml - - - otc - application/vnd.oasis.opendocument.chart-template - - - otf - application/x-font-otf - - - - otg - application/vnd.oasis.opendocument.graphics-template - - - - oth - application/vnd.oasis.opendocument.text-web - - - oti - application/vnd.oasis.opendocument.image-template - - - - otp - application/vnd.oasis.opendocument.presentation-template - - - - ots - application/vnd.oasis.opendocument.spreadsheet-template - - - - ott - application/vnd.oasis.opendocument.text-template - - - oxps - application/oxps - - - oxt - application/vnd.openofficeorg.extension - - - p - text/x-pascal - - - p10 - application/pkcs10 - - - p12 - application/x-pkcs12 - - - p7b - application/x-pkcs7-certificates - - - p7c - application/pkcs7-mime - - - p7m - application/pkcs7-mime - - - p7r - application/x-pkcs7-certreqresp - - - p7s - application/pkcs7-signature - - - p8 - application/pkcs8 - - - pas - text/x-pascal - - - paw - application/vnd.pawaafile - - - pbd - application/vnd.powerbuilder6 - - - pbm - image/x-portable-bitmap - - - pcap - application/vnd.tcpdump.pcap - - - pcf - application/x-font-pcf - - - pcl - application/vnd.hp-pcl - - - pclxl - application/vnd.hp-pclxl - - - pct - image/pict - - - pcurl - application/vnd.curl.pcurl - - - pcx - image/x-pcx - - - pdb - application/vnd.palm - - - pdf - application/pdf - - - pfa - application/x-font-type1 - - - pfb - application/x-font-type1 - - - pfm - application/x-font-type1 - - - pfr - application/font-tdpfr - - - pfx - application/x-pkcs12 - - - pgm - image/x-portable-graymap - - - pgn - application/x-chess-pgn - - - pgp - application/pgp-encrypted - - - pic - image/pict - - - pict - image/pict - - - pkg - application/octet-stream - - - pki - application/pkixcmp - - - pkipath - application/pkix-pkipath - - - plb - application/vnd.3gpp.pic-bw-large - - - plc - application/vnd.mobius.plc - - - plf - application/vnd.pocketlearn - - - pls - audio/x-scpls - - - pml - application/vnd.ctc-posml - - - png - image/png - - - pnm - image/x-portable-anymap - - - pnt - image/x-macpaint - - - portpkg - application/vnd.macports.portpkg - - - pot - application/vnd.ms-powerpoint - - - potm - application/vnd.ms-powerpoint.template.macroenabled.12 - - - potx - application/vnd.openxmlformats-officedocument.presentationml.template - - - ppam - application/vnd.ms-powerpoint.addin.macroenabled.12 - - - ppd - application/vnd.cups-ppd - - - ppm - image/x-portable-pixmap - - - pps - application/vnd.ms-powerpoint - - - ppsm - application/vnd.ms-powerpoint.slideshow.macroenabled.12 - - - ppsx - application/vnd.openxmlformats-officedocument.presentationml.slideshow - - - ppt - application/vnd.ms-powerpoint - - - pptm - application/vnd.ms-powerpoint.presentation.macroenabled.12 - - - pptx - application/vnd.openxmlformats-officedocument.presentationml.presentation - - - pqa - application/vnd.palm - - - prc - application/x-mobipocket-ebook - - - pre - application/vnd.lotus-freelance - - - prf - application/pics-rules - - - ps - application/postscript - - - psb - application/vnd.3gpp.pic-bw-small - - - psd - image/vnd.adobe.photoshop - - - psf - application/x-font-linux-psf - - - pskcxml - application/pskc+xml - - - ptid - application/vnd.pvi.ptid1 - - - pub - application/x-mspublisher - - - pvb - application/vnd.3gpp.pic-bw-var - - - pwn - application/vnd.3m.post-it-notes - - - pya - audio/vnd.ms-playready.media.pya - - - pyv - video/vnd.ms-playready.media.pyv - - - qam - application/vnd.epson.quickanime - - - qbo - application/vnd.intu.qbo - - - qfx - application/vnd.intu.qfx - - - qps - application/vnd.publishare-delta-tree - - - qt - video/quicktime - - - qti - image/x-quicktime - - - qtif - image/x-quicktime - - - qwd - application/vnd.quark.quarkxpress - - - qwt - application/vnd.quark.quarkxpress - - - qxb - application/vnd.quark.quarkxpress - - - qxd - application/vnd.quark.quarkxpress - - - qxl - application/vnd.quark.quarkxpress - - - qxt - application/vnd.quark.quarkxpress - - - ra - audio/x-pn-realaudio - - - ram - audio/x-pn-realaudio - - - rar - application/x-rar-compressed - - - ras - image/x-cmu-raster - - - rcprofile - application/vnd.ipunplugged.rcprofile - - - rdf - application/rdf+xml - - - rdz - application/vnd.data-vision.rdz - - - rep - application/vnd.businessobjects - - - res - application/x-dtbresource+xml - - - rgb - image/x-rgb - - - rif - application/reginfo+xml - - - rip - audio/vnd.rip - - - rl - application/resource-lists+xml - - - rlc - image/vnd.fujixerox.edmics-rlc - - - rld - application/resource-lists-diff+xml - - - rm - application/vnd.rn-realmedia - - - rmi - audio/midi - - - rmp - audio/x-pn-realaudio-plugin - - - rms - application/vnd.jcp.javame.midlet-rms - - - rnc - application/relax-ng-compact-syntax - - - roa - application/rpki-roa - - - roff - text/troff - - - rp9 - application/vnd.cloanto.rp9 - - - rpss - application/vnd.nokia.radio-presets - - - rpst - application/vnd.nokia.radio-preset - - - rq - application/sparql-query - - - rs - application/rls-services+xml - - - rsd - application/rsd+xml - - - rss - application/rss+xml - - - rtf - application/rtf - - - rtx - text/richtext - - - s - text/x-asm - - - saf - application/vnd.yamaha.smaf-audio - - - sbml - application/sbml+xml - - - sc - application/vnd.ibm.secure-container - - - scd - application/x-msschedule - - - scm - application/vnd.lotus-screencam - - - scq - application/scvp-cv-request - - - scs - application/scvp-cv-response - - - scurl - text/vnd.curl.scurl - - - sda - application/vnd.stardivision.draw - - - sdc - application/vnd.stardivision.calc - - - sdd - application/vnd.stardivision.impress - - - sdkd - application/vnd.solent.sdkm+xml - - - sdkm - application/vnd.solent.sdkm+xml - - - sdp - application/sdp - - - sdw - application/vnd.stardivision.writer - - - see - application/vnd.seemail - - - seed - application/vnd.fdsn.seed - - - sema - application/vnd.sema - - - semd - application/vnd.semd - - - semf - application/vnd.semf - - - ser - application/java-serialized-object - - - setpay - application/set-payment-initiation - - - setreg - application/set-registration-initiation - - - sfd-hdstx - application/vnd.hydrostatix.sof-data - - - sfs - application/vnd.spotfire.sfs - - - sgl - application/vnd.stardivision.writer-global - - - sgm - text/sgml - - - sgml - text/sgml - - - sh - application/x-sh - - - shar - application/x-shar - - - shf - application/shf+xml - - - - sig - application/pgp-signature - - - silo - model/mesh - - - sis - application/vnd.symbian.install - - - sisx - application/vnd.symbian.install - - - sit - application/x-stuffit - - - sitx - application/x-stuffitx - - - skd - application/vnd.koan - - - skm - application/vnd.koan - - - skp - application/vnd.koan - - - skt - application/vnd.koan - - - sldm - application/vnd.ms-powerpoint.slide.macroenabled.12 - - - sldx - application/vnd.openxmlformats-officedocument.presentationml.slide - - - slt - application/vnd.epson.salt - - - sm - application/vnd.stepmania.stepchart - - - smf - application/vnd.stardivision.math - - - smi - application/smil+xml - - - smil - application/smil+xml - - - smzip - application/vnd.stepmania.package - - - snd - audio/basic - - - snf - application/x-font-snf - - - so - application/octet-stream - - - spc - application/x-pkcs7-certificates - - - spf - application/vnd.yamaha.smaf-phrase - - - spl - application/x-futuresplash - - - spot - text/vnd.in3d.spot - - - spp - application/scvp-vp-response - - - spq - application/scvp-vp-request - - - spx - audio/ogg - - - src - application/x-wais-source - - - sru - application/sru+xml - - - srx - application/sparql-results+xml - - - sse - application/vnd.kodak-descriptor - - - ssf - application/vnd.epson.ssf - - - ssml - application/ssml+xml - - - st - application/vnd.sailingtracker.track - - - stc - application/vnd.sun.xml.calc.template - - - std - application/vnd.sun.xml.draw.template - - - stf - application/vnd.wt.stf - - - sti - application/vnd.sun.xml.impress.template - - - stk - application/hyperstudio - - - stl - application/vnd.ms-pki.stl - - - str - application/vnd.pg.format - - - stw - application/vnd.sun.xml.writer.template - - - sub - text/vnd.dvb.subtitle - - - sus - application/vnd.sus-calendar - - - susp - application/vnd.sus-calendar - - - sv4cpio - application/x-sv4cpio - - - sv4crc - application/x-sv4crc - - - svc - application/vnd.dvb.service - - - svd - application/vnd.svd - - - svg - image/svg+xml - - - svgz - image/svg+xml - - - swa - application/x-director - - - swf - application/x-shockwave-flash - - - swi - application/vnd.aristanetworks.swi - - - sxc - application/vnd.sun.xml.calc - - - sxd - application/vnd.sun.xml.draw - - - sxg - application/vnd.sun.xml.writer.global - - - sxi - application/vnd.sun.xml.impress - - - sxm - application/vnd.sun.xml.math - - - sxw - application/vnd.sun.xml.writer - - - t - text/troff - - - taglet - application/vnd.mynfc - - - tao - application/vnd.tao.intent-module-archive - - - tar - application/x-tar - - - tcap - application/vnd.3gpp2.tcap - - - tcl - application/x-tcl - - - teacher - application/vnd.smart.teacher - - - tei - application/tei+xml - - - teicorpus - application/tei+xml - - - tex - application/x-tex - - - texi - application/x-texinfo - - - texinfo - application/x-texinfo - - - text - text/plain - - - tfi - application/thraud+xml - - - tfm - application/x-tex-tfm - - - thmx - application/vnd.ms-officetheme - - - tif - image/tiff - - - tiff - image/tiff - - - tmo - application/vnd.tmobile-livetv - - - torrent - application/x-bittorrent - - - tpl - application/vnd.groove-tool-template - - - tpt - application/vnd.trid.tpt - - - tr - text/troff - - - tra - application/vnd.trueapp - - - trm - application/x-msterminal - - - tsd - application/timestamped-data - - - tsv - text/tab-separated-values - - - ttc - application/x-font-ttf - - - ttf - application/x-font-ttf - - - ttl - text/turtle - - - twd - application/vnd.simtech-mindmapper - - - twds - application/vnd.simtech-mindmapper - - - txd - application/vnd.genomatix.tuxedo - - - txf - application/vnd.mobius.txf - - - txt - text/plain - - - u32 - application/x-authorware-bin - - - udeb - application/x-debian-package - - - ufd - application/vnd.ufdl - - - ufdl - application/vnd.ufdl - - - ulw - audio/basic - - - umj - application/vnd.umajin - - - unityweb - application/vnd.unity - - - uoml - application/vnd.uoml+xml - - - uri - text/uri-list - - - uris - text/uri-list - - - urls - text/uri-list - - - ustar - application/x-ustar - - - utz - application/vnd.uiq.theme - - - uu - text/x-uuencode - - - uva - audio/vnd.dece.audio - - - uvd - application/vnd.dece.data - - - uvf - application/vnd.dece.data - - - uvg - image/vnd.dece.graphic - - - uvh - video/vnd.dece.hd - - - uvi - image/vnd.dece.graphic - - - uvm - video/vnd.dece.mobile - - - uvp - video/vnd.dece.pd - - - uvs - video/vnd.dece.sd - - - uvt - application/vnd.dece.ttml+xml - - - uvu - video/vnd.uvvu.mp4 - - - uvv - video/vnd.dece.video - - - uvva - audio/vnd.dece.audio - - - uvvd - application/vnd.dece.data - - - uvvf - application/vnd.dece.data - - - uvvg - image/vnd.dece.graphic - - - uvvh - video/vnd.dece.hd - - - uvvi - image/vnd.dece.graphic - - - uvvm - video/vnd.dece.mobile - - - uvvp - video/vnd.dece.pd - - - uvvs - video/vnd.dece.sd - - - uvvt - application/vnd.dece.ttml+xml - - - uvvu - video/vnd.uvvu.mp4 - - - uvvv - video/vnd.dece.video - - - uvvx - application/vnd.dece.unspecified - - - uvvz - application/vnd.dece.zip - - - uvx - application/vnd.dece.unspecified - - - uvz - application/vnd.dece.zip - - - vcard - text/vcard - - - vcd - application/x-cdlink - - - vcf - text/x-vcard - - - vcg - application/vnd.groove-vcard - - - vcs - text/x-vcalendar - - - vcx - application/vnd.vcx - - - vis - application/vnd.visionary - - - viv - video/vnd.vivo - - - vor - application/vnd.stardivision.writer - - - vox - application/x-authorware-bin - - - vrml - model/vrml - - - vsd - application/vnd.visio - - - vsf - application/vnd.vsf - - - vss - application/vnd.visio - - - vst - application/vnd.visio - - - vsw - application/vnd.visio - - - vtu - model/vnd.vtu - - - vxml - application/voicexml+xml - - - w3d - application/x-director - - - wad - application/x-doom - - - wav - audio/x-wav - - - wax - audio/x-ms-wax - - - - wbmp - image/vnd.wap.wbmp - - - wbs - application/vnd.criticaltools.wbs+xml - - - wbxml - application/vnd.wap.wbxml - - - wcm - application/vnd.ms-works - - - wdb - application/vnd.ms-works - - - weba - audio/webm - - - webm - video/webm - - - webp - image/webp - - - wg - application/vnd.pmi.widget - - - wgt - application/widget - - - wks - application/vnd.ms-works - - - wm - video/x-ms-wm - - - wma - audio/x-ms-wma - - - wmd - application/x-ms-wmd - - - wmf - application/x-msmetafile - - - - wml - text/vnd.wap.wml - - - - wmlc - application/vnd.wap.wmlc - - - - wmls - text/vnd.wap.wmlscript - - - - wmlsc - application/vnd.wap.wmlscriptc - - - wmv - video/x-ms-wmv - - - wmx - video/x-ms-wmx - - - wmz - application/x-ms-wmz - - - woff - application/x-font-woff - - - wpd - application/vnd.wordperfect - - - wpl - application/vnd.ms-wpl - - - wps - application/vnd.ms-works - - - wqd - application/vnd.wqd - - - wri - application/x-mswrite - - - wrl - model/vrml - - - wsdl - application/wsdl+xml - - - wspolicy - application/wspolicy+xml - - - wtb - application/vnd.webturbo - - - wvx - video/x-ms-wvx - - - x32 - application/x-authorware-bin - - - x3d - application/vnd.hzn-3d-crossword - - - xap - application/x-silverlight-app - - - xar - application/vnd.xara - - - xbap - application/x-ms-xbap - - - xbd - application/vnd.fujixerox.docuworks.binder - - - xbm - image/x-xbitmap - - - xdf - application/xcap-diff+xml - - - xdm - application/vnd.syncml.dm+xml - - - xdp - application/vnd.adobe.xdp+xml - - - xdssc - application/dssc+xml - - - xdw - application/vnd.fujixerox.docuworks - - - xenc - application/xenc+xml - - - xer - application/patch-ops-error+xml - - - xfdf - application/vnd.adobe.xfdf - - - xfdl - application/vnd.xfdl - - - xht - application/xhtml+xml - - - xhtml - application/xhtml+xml - - - xhvml - application/xv+xml - - - xif - image/vnd.xiff - - - xla - application/vnd.ms-excel - - - xlam - application/vnd.ms-excel.addin.macroenabled.12 - - - xlc - application/vnd.ms-excel - - - xlm - application/vnd.ms-excel - - - xls - application/vnd.ms-excel - - - xlsb - application/vnd.ms-excel.sheet.binary.macroenabled.12 - - - xlsm - application/vnd.ms-excel.sheet.macroenabled.12 - - - xlsx - application/vnd.openxmlformats-officedocument.spreadsheetml.sheet - - - xlt - application/vnd.ms-excel - - - xltm - application/vnd.ms-excel.template.macroenabled.12 - - - xltx - application/vnd.openxmlformats-officedocument.spreadsheetml.template - - - xlw - application/vnd.ms-excel - - - xml - application/xml - - - xo - application/vnd.olpc-sugar - - - xop - application/xop+xml - - - xpi - application/x-xpinstall - - - xpm - image/x-xpixmap - - - xpr - application/vnd.is-xpr - - - xps - application/vnd.ms-xpsdocument - - - xpw - application/vnd.intercon.formnet - - - xpx - application/vnd.intercon.formnet - - - xsl - application/xml - - - xslt - application/xslt+xml - - - xsm - application/vnd.syncml+xml - - - xspf - application/xspf+xml - - - xul - application/vnd.mozilla.xul+xml - - - xvm - application/xv+xml - - - xvml - application/xv+xml - - - xwd - image/x-xwindowdump - - - xyz - chemical/x-xyz - - - yang - application/yang - - - yin - application/yin+xml - - - z - application/x-compress - - - Z - application/x-compress - - - zaz - application/vnd.zzazz.deck+xml - - - zip - application/zip - - - zir - application/vnd.zul - - - zirz - application/vnd.zul - - - zmm - application/vnd.handheld-entertainment+xml - - - - - - - - - - - - - - - - - - index.html - index.htm - index.jsp - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + default + org.apache.catalina.servlets.DefaultServlet + + debug + 0 + + + listings + false + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jsp + org.apache.jasper.servlet.JspServlet + + fork + false + + + xpoweredBy + false + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + default + / + + + + + jsp + *.jsp + *.jspx + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 30 + + + + + + + + + + + + 123 + application/vnd.lotus-1-2-3 + + + 3dml + text/vnd.in3d.3dml + + + 3g2 + video/3gpp2 + + + 3gp + video/3gpp + + + 7z + application/x-7z-compressed + + + aab + application/x-authorware-bin + + + aac + audio/x-aac + + + aam + application/x-authorware-map + + + aas + application/x-authorware-seg + + + abs + audio/x-mpeg + + + abw + application/x-abiword + + + ac + application/pkix-attr-cert + + + acc + application/vnd.americandynamics.acc + + + ace + application/x-ace-compressed + + + acu + application/vnd.acucobol + + + acutc + application/vnd.acucorp + + + adp + audio/adpcm + + + aep + application/vnd.audiograph + + + afm + application/x-font-type1 + + + afp + application/vnd.ibm.modcap + + + ahead + application/vnd.ahead.space + + + ai + application/postscript + + + aif + audio/x-aiff + + + aifc + audio/x-aiff + + + aiff + audio/x-aiff + + + aim + application/x-aim + + + air + application/vnd.adobe.air-application-installer-package+zip + + + ait + application/vnd.dvb.ait + + + ami + application/vnd.amiga.ami + + + anx + application/annodex + + + apk + application/vnd.android.package-archive + + + application + application/x-ms-application + + + apr + application/vnd.lotus-approach + + + art + image/x-jg + + + asc + application/pgp-signature + + + asf + video/x-ms-asf + + + asm + text/x-asm + + + aso + application/vnd.accpac.simply.aso + + + asx + video/x-ms-asf + + + atc + application/vnd.acucorp + + + atom + application/atom+xml + + + atomcat + application/atomcat+xml + + + atomsvc + application/atomsvc+xml + + + atx + application/vnd.antix.game-component + + + au + audio/basic + + + avi + video/x-msvideo + + + avx + video/x-rad-screenplay + + + aw + application/applixware + + + axa + audio/annodex + + + axv + video/annodex + + + azf + application/vnd.airzip.filesecure.azf + + + azs + application/vnd.airzip.filesecure.azs + + + azw + application/vnd.amazon.ebook + + + bat + application/x-msdownload + + + bcpio + application/x-bcpio + + + bdf + application/x-font-bdf + + + bdm + application/vnd.syncml.dm+wbxml + + + bed + application/vnd.realvnc.bed + + + bh2 + application/vnd.fujitsu.oasysprs + + + bin + application/octet-stream + + + bmi + application/vnd.bmi + + + bmp + image/bmp + + + body + text/html + + + book + application/vnd.framemaker + + + box + application/vnd.previewsystems.box + + + boz + application/x-bzip2 + + + bpk + application/octet-stream + + + btif + image/prs.btif + + + bz + application/x-bzip + + + bz2 + application/x-bzip2 + + + c + text/x-c + + + c11amc + application/vnd.cluetrust.cartomobile-config + + + c11amz + application/vnd.cluetrust.cartomobile-config-pkg + + + c4d + application/vnd.clonk.c4group + + + c4f + application/vnd.clonk.c4group + + + c4g + application/vnd.clonk.c4group + + + c4p + application/vnd.clonk.c4group + + + c4u + application/vnd.clonk.c4group + + + cab + application/vnd.ms-cab-compressed + + + cap + application/vnd.tcpdump.pcap + + + car + application/vnd.curl.car + + + cat + application/vnd.ms-pki.seccat + + + cc + text/x-c + + + cct + application/x-director + + + ccxml + application/ccxml+xml + + + cdbcmsg + application/vnd.contact.cmsg + + + cdf + application/x-cdf + + + cdkey + application/vnd.mediastation.cdkey + + + cdmia + application/cdmi-capability + + + cdmic + application/cdmi-container + + + cdmid + application/cdmi-domain + + + cdmio + application/cdmi-object + + + cdmiq + application/cdmi-queue + + + cdx + chemical/x-cdx + + + cdxml + application/vnd.chemdraw+xml + + + cdy + application/vnd.cinderella + + + cer + application/pkix-cert + + + cgm + image/cgm + + + chat + application/x-chat + + + chm + application/vnd.ms-htmlhelp + + + chrt + application/vnd.kde.kchart + + + cif + chemical/x-cif + + + cii + application/vnd.anser-web-certificate-issue-initiation + + + cil + application/vnd.ms-artgalry + + + cla + application/vnd.claymore + + + class + application/java + + + clkk + application/vnd.crick.clicker.keyboard + + + clkp + application/vnd.crick.clicker.palette + + + clkt + application/vnd.crick.clicker.template + + + clkw + application/vnd.crick.clicker.wordbank + + + clkx + application/vnd.crick.clicker + + + clp + application/x-msclip + + + cmc + application/vnd.cosmocaller + + + cmdf + chemical/x-cmdf + + + cml + chemical/x-cml + + + cmp + application/vnd.yellowriver-custom-menu + + + cmx + image/x-cmx + + + cod + application/vnd.rim.cod + + + com + application/x-msdownload + + + conf + text/plain + + + cpio + application/x-cpio + + + cpp + text/x-c + + + cpt + application/mac-compactpro + + + crd + application/x-mscardfile + + + crl + application/pkix-crl + + + crt + application/x-x509-ca-cert + + + cryptonote + application/vnd.rig.cryptonote + + + csh + application/x-csh + + + csml + chemical/x-csml + + + csp + application/vnd.commonspace + + + css + text/css + + + cst + application/x-director + + + csv + text/csv + + + cu + application/cu-seeme + + + curl + text/vnd.curl + + + cww + application/prs.cww + + + cxt + application/x-director + + + cxx + text/x-c + + + dae + model/vnd.collada+xml + + + daf + application/vnd.mobius.daf + + + dataless + application/vnd.fdsn.seed + + + davmount + application/davmount+xml + + + dcr + application/x-director + + + dcurl + text/vnd.curl.dcurl + + + dd2 + application/vnd.oma.dd2+xml + + + ddd + application/vnd.fujixerox.ddd + + + deb + application/x-debian-package + + + def + text/plain + + + deploy + application/octet-stream + + + der + application/x-x509-ca-cert + + + dfac + application/vnd.dreamfactory + + + dib + image/bmp + + + dic + text/x-c + + + dir + application/x-director + + + dis + application/vnd.mobius.dis + + + dist + application/octet-stream + + + distz + application/octet-stream + + + djv + image/vnd.djvu + + + djvu + image/vnd.djvu + + + dll + application/x-msdownload + + + dmg + application/octet-stream + + + dmp + application/vnd.tcpdump.pcap + + + dms + application/octet-stream + + + dna + application/vnd.dna + + + doc + application/msword + + + docm + application/vnd.ms-word.document.macroenabled.12 + + + docx + application/vnd.openxmlformats-officedocument.wordprocessingml.document + + + dot + application/msword + + + dotm + application/vnd.ms-word.template.macroenabled.12 + + + dotx + application/vnd.openxmlformats-officedocument.wordprocessingml.template + + + dp + application/vnd.osgi.dp + + + dpg + application/vnd.dpgraph + + + dra + audio/vnd.dra + + + dsc + text/prs.lines.tag + + + dssc + application/dssc+der + + + dtb + application/x-dtbook+xml + + + dtd + application/xml-dtd + + + dts + audio/vnd.dts + + + dtshd + audio/vnd.dts.hd + + + dump + application/octet-stream + + + dv + video/x-dv + + + dvb + video/vnd.dvb.file + + + dvi + application/x-dvi + + + dwf + model/vnd.dwf + + + dwg + image/vnd.dwg + + + dxf + image/vnd.dxf + + + dxp + application/vnd.spotfire.dxp + + + dxr + application/x-director + + + ecelp4800 + audio/vnd.nuera.ecelp4800 + + + ecelp7470 + audio/vnd.nuera.ecelp7470 + + + ecelp9600 + audio/vnd.nuera.ecelp9600 + + + ecma + application/ecmascript + + + edm + application/vnd.novadigm.edm + + + edx + application/vnd.novadigm.edx + + + efif + application/vnd.picsel + + + ei6 + application/vnd.pg.osasli + + + elc + application/octet-stream + + + eml + message/rfc822 + + + emma + application/emma+xml + + + eol + audio/vnd.digital-winds + + + eot + application/vnd.ms-fontobject + + + eps + application/postscript + + + epub + application/epub+zip + + + es3 + application/vnd.eszigno3+xml + + + esf + application/vnd.epson.esf + + + et3 + application/vnd.eszigno3+xml + + + etx + text/x-setext + + + exe + application/octet-stream + + + exi + application/exi + + + ext + application/vnd.novadigm.ext + + + ez + application/andrew-inset + + + ez2 + application/vnd.ezpix-album + + + ez3 + application/vnd.ezpix-package + + + f + text/x-fortran + + + f4v + video/x-f4v + + + f77 + text/x-fortran + + + f90 + text/x-fortran + + + fbs + image/vnd.fastbidsheet + + + fcs + application/vnd.isac.fcs + + + fdf + application/vnd.fdf + + + fe_launch + application/vnd.denovo.fcselayout-link + + + fg5 + application/vnd.fujitsu.oasysgp + + + fgd + application/x-director + + + fh + image/x-freehand + + + fh4 + image/x-freehand + + + fh5 + image/x-freehand + + + fh7 + image/x-freehand + + + fhc + image/x-freehand + + + fig + application/x-xfig + + + flac + audio/flac + + + fli + video/x-fli + + + flo + application/vnd.micrografx.flo + + + flv + video/x-flv + + + flw + application/vnd.kde.kivio + + + flx + text/vnd.fmi.flexstor + + + fly + text/vnd.fly + + + fm + application/vnd.framemaker + + + fnc + application/vnd.frogans.fnc + + + for + text/x-fortran + + + fpx + image/vnd.fpx + + + frame + application/vnd.framemaker + + + fsc + application/vnd.fsc.weblaunch + + + fst + image/vnd.fst + + + ftc + application/vnd.fluxtime.clip + + + fti + application/vnd.anser-web-funds-transfer-initiation + + + fvt + video/vnd.fvt + + + fxp + application/vnd.adobe.fxp + + + fxpl + application/vnd.adobe.fxp + + + fzs + application/vnd.fuzzysheet + + + g2w + application/vnd.geoplan + + + g3 + image/g3fax + + + g3w + application/vnd.geospace + + + gac + application/vnd.groove-account + + + gbr + application/rpki-ghostbusters + + + gdl + model/vnd.gdl + + + geo + application/vnd.dynageo + + + gex + application/vnd.geometry-explorer + + + ggb + application/vnd.geogebra.file + + + ggt + application/vnd.geogebra.tool + + + ghf + application/vnd.groove-help + + + gif + image/gif + + + gim + application/vnd.groove-identity-message + + + gmx + application/vnd.gmx + + + gnumeric + application/x-gnumeric + + + gph + application/vnd.flographit + + + gqf + application/vnd.grafeq + + + gqs + application/vnd.grafeq + + + gram + application/srgs + + + gre + application/vnd.geometry-explorer + + + grv + application/vnd.groove-injector + + + grxml + application/srgs+xml + + + gsf + application/x-font-ghostscript + + + gtar + application/x-gtar + + + gtm + application/vnd.groove-tool-message + + + gtw + model/vnd.gtw + + + gv + text/vnd.graphviz + + + gxt + application/vnd.geonext + + + gz + application/x-gzip + + + h + text/x-c + + + h261 + video/h261 + + + h263 + video/h263 + + + h264 + video/h264 + + + hal + application/vnd.hal+xml + + + hbci + application/vnd.hbci + + + hdf + application/x-hdf + + + hh + text/x-c + + + hlp + application/winhlp + + + hpgl + application/vnd.hp-hpgl + + + hpid + application/vnd.hp-hpid + + + hps + application/vnd.hp-hps + + + hqx + application/mac-binhex40 + + + htc + text/x-component + + + htke + application/vnd.kenameaapp + + + htm + text/html + + + html + text/html + + + hvd + application/vnd.yamaha.hv-dic + + + hvp + application/vnd.yamaha.hv-voice + + + hvs + application/vnd.yamaha.hv-script + + + i2g + application/vnd.intergeo + + + icc + application/vnd.iccprofile + + + ice + x-conference/x-cooltalk + + + icm + application/vnd.iccprofile + + + ico + image/x-icon + + + ics + text/calendar + + + ief + image/ief + + + ifb + text/calendar + + + ifm + application/vnd.shana.informed.formdata + + + iges + model/iges + + + igl + application/vnd.igloader + + + igm + application/vnd.insors.igm + + + igs + model/iges + + + igx + application/vnd.micrografx.igx + + + iif + application/vnd.shana.informed.interchange + + + imp + application/vnd.accpac.simply.imp + + + ims + application/vnd.ms-ims + + + in + text/plain + + + ink + application/inkml+xml + + + inkml + application/inkml+xml + + + iota + application/vnd.astraea-software.iota + + + ipfix + application/ipfix + + + ipk + application/vnd.shana.informed.package + + + irm + application/vnd.ibm.rights-management + + + irp + application/vnd.irepository.package+xml + + + iso + application/octet-stream + + + itp + application/vnd.shana.informed.formtemplate + + + ivp + application/vnd.immervision-ivp + + + ivu + application/vnd.immervision-ivu + + + jad + text/vnd.sun.j2me.app-descriptor + + + jam + application/vnd.jam + + + jar + application/java-archive + + + java + text/x-java-source + + + jisp + application/vnd.jisp + + + jlt + application/vnd.hp-jlyt + + + jnlp + application/x-java-jnlp-file + + + joda + application/vnd.joost.joda-archive + + + jpe + image/jpeg + + + jpeg + image/jpeg + + + jpg + image/jpeg + + + jpgm + video/jpm + + + jpgv + video/jpeg + + + jpm + video/jpm + + + js + application/javascript + + + jsf + text/plain + + + json + application/json + + + jspf + text/plain + + + kar + audio/midi + + + karbon + application/vnd.kde.karbon + + + kfo + application/vnd.kde.kformula + + + kia + application/vnd.kidspiration + + + kml + application/vnd.google-earth.kml+xml + + + kmz + application/vnd.google-earth.kmz + + + kne + application/vnd.kinar + + + knp + application/vnd.kinar + + + kon + application/vnd.kde.kontour + + + kpr + application/vnd.kde.kpresenter + + + kpt + application/vnd.kde.kpresenter + + + ksp + application/vnd.kde.kspread + + + ktr + application/vnd.kahootz + + + ktx + image/ktx + + + ktz + application/vnd.kahootz + + + kwd + application/vnd.kde.kword + + + kwt + application/vnd.kde.kword + + + lasxml + application/vnd.las.las+xml + + + latex + application/x-latex + + + lbd + application/vnd.llamagraphics.life-balance.desktop + + + lbe + application/vnd.llamagraphics.life-balance.exchange+xml + + + les + application/vnd.hhe.lesson-player + + + lha + application/octet-stream + + + link66 + application/vnd.route66.link66+xml + + + list + text/plain + + + list3820 + application/vnd.ibm.modcap + + + listafp + application/vnd.ibm.modcap + + + log + text/plain + + + lostxml + application/lost+xml + + + lrf + application/octet-stream + + + lrm + application/vnd.ms-lrm + + + ltf + application/vnd.frogans.ltf + + + lvp + audio/vnd.lucent.voice + + + lwp + application/vnd.lotus-wordpro + + + lzh + application/octet-stream + + + m13 + application/x-msmediaview + + + m14 + application/x-msmediaview + + + m1v + video/mpeg + + + m21 + application/mp21 + + + m2a + audio/mpeg + + + m2v + video/mpeg + + + m3a + audio/mpeg + + + m3u + audio/x-mpegurl + + + m3u8 + application/vnd.apple.mpegurl + + + m4a + audio/mp4 + + + m4b + audio/mp4 + + + m4r + audio/mp4 + + + m4u + video/vnd.mpegurl + + + m4v + video/mp4 + + + ma + application/mathematica + + + mac + image/x-macpaint + + + mads + application/mads+xml + + + mag + application/vnd.ecowin.chart + + + maker + application/vnd.framemaker + + + man + text/troff + + + mathml + application/mathml+xml + + + mb + application/mathematica + + + mbk + application/vnd.mobius.mbk + + + mbox + application/mbox + + + mc1 + application/vnd.medcalcdata + + + mcd + application/vnd.mcd + + + mcurl + text/vnd.curl.mcurl + + + mdb + application/x-msaccess + + + mdi + image/vnd.ms-modi + + + me + text/troff + + + mesh + model/mesh + + + meta4 + application/metalink4+xml + + + mets + application/mets+xml + + + mfm + application/vnd.mfmp + + + mft + application/rpki-manifest + + + mgp + application/vnd.osgeo.mapguide.package + + + mgz + application/vnd.proteus.magazine + + + mid + audio/midi + + + midi + audio/midi + + + mif + application/x-mif + + + mime + message/rfc822 + + + mj2 + video/mj2 + + + mjp2 + video/mj2 + + + mlp + application/vnd.dolby.mlp + + + mmd + application/vnd.chipnuts.karaoke-mmd + + + mmf + application/vnd.smaf + + + mmr + image/vnd.fujixerox.edmics-mmr + + + mny + application/x-msmoney + + + mobi + application/x-mobipocket-ebook + + + mods + application/mods+xml + + + mov + video/quicktime + + + movie + video/x-sgi-movie + + + mp1 + audio/mpeg + + + mp2 + audio/mpeg + + + mp21 + application/mp21 + + + mp2a + audio/mpeg + + + mp3 + audio/mpeg + + + mp4 + video/mp4 + + + mp4a + audio/mp4 + + + mp4s + application/mp4 + + + mp4v + video/mp4 + + + mpa + audio/mpeg + + + mpc + application/vnd.mophun.certificate + + + mpe + video/mpeg + + + mpeg + video/mpeg + + + mpega + audio/x-mpeg + + + mpg + video/mpeg + + + mpg4 + video/mp4 + + + mpga + audio/mpeg + + + mpkg + application/vnd.apple.installer+xml + + + mpm + application/vnd.blueice.multipass + + + mpn + application/vnd.mophun.application + + + mpp + application/vnd.ms-project + + + mpt + application/vnd.ms-project + + + mpv2 + video/mpeg2 + + + mpy + application/vnd.ibm.minipay + + + mqy + application/vnd.mobius.mqy + + + mrc + application/marc + + + mrcx + application/marcxml+xml + + + ms + text/troff + + + mscml + application/mediaservercontrol+xml + + + mseed + application/vnd.fdsn.mseed + + + mseq + application/vnd.mseq + + + msf + application/vnd.epson.msf + + + msh + model/mesh + + + msi + application/x-msdownload + + + msl + application/vnd.mobius.msl + + + msty + application/vnd.muvee.style + + + mts + model/vnd.mts + + + mus + application/vnd.musician + + + musicxml + application/vnd.recordare.musicxml+xml + + + mvb + application/x-msmediaview + + + mwf + application/vnd.mfer + + + mxf + application/mxf + + + mxl + application/vnd.recordare.musicxml + + + mxml + application/xv+xml + + + mxs + application/vnd.triscape.mxs + + + mxu + video/vnd.mpegurl + + + n-gage + application/vnd.nokia.n-gage.symbian.install + + + n3 + text/n3 + + + nb + application/mathematica + + + nbp + application/vnd.wolfram.player + + + nc + application/x-netcdf + + + ncx + application/x-dtbncx+xml + + + ngdat + application/vnd.nokia.n-gage.data + + + nlu + application/vnd.neurolanguage.nlu + + + nml + application/vnd.enliven + + + nnd + application/vnd.noblenet-directory + + + nns + application/vnd.noblenet-sealer + + + nnw + application/vnd.noblenet-web + + + npx + image/vnd.net-fpx + + + nsf + application/vnd.lotus-notes + + + oa2 + application/vnd.fujitsu.oasys2 + + + oa3 + application/vnd.fujitsu.oasys3 + + + oas + application/vnd.fujitsu.oasys + + + obd + application/x-msbinder + + + oda + application/oda + + + + odb + application/vnd.oasis.opendocument.database + + + + odc + application/vnd.oasis.opendocument.chart + + + + odf + application/vnd.oasis.opendocument.formula + + + odft + application/vnd.oasis.opendocument.formula-template + + + + odg + application/vnd.oasis.opendocument.graphics + + + + odi + application/vnd.oasis.opendocument.image + + + + odm + application/vnd.oasis.opendocument.text-master + + + + odp + application/vnd.oasis.opendocument.presentation + + + + ods + application/vnd.oasis.opendocument.spreadsheet + + + + odt + application/vnd.oasis.opendocument.text + + + oga + audio/ogg + + + ogg + audio/ogg + + + ogv + video/ogg + + + + ogx + application/ogg + + + onepkg + application/onenote + + + onetmp + application/onenote + + + onetoc + application/onenote + + + onetoc2 + application/onenote + + + opf + application/oebps-package+xml + + + oprc + application/vnd.palm + + + org + application/vnd.lotus-organizer + + + osf + application/vnd.yamaha.openscoreformat + + + osfpvg + application/vnd.yamaha.openscoreformat.osfpvg+xml + + + otc + application/vnd.oasis.opendocument.chart-template + + + otf + application/x-font-otf + + + + otg + application/vnd.oasis.opendocument.graphics-template + + + + oth + application/vnd.oasis.opendocument.text-web + + + oti + application/vnd.oasis.opendocument.image-template + + + + otp + application/vnd.oasis.opendocument.presentation-template + + + + ots + application/vnd.oasis.opendocument.spreadsheet-template + + + + ott + application/vnd.oasis.opendocument.text-template + + + oxps + application/oxps + + + oxt + application/vnd.openofficeorg.extension + + + p + text/x-pascal + + + p10 + application/pkcs10 + + + p12 + application/x-pkcs12 + + + p7b + application/x-pkcs7-certificates + + + p7c + application/pkcs7-mime + + + p7m + application/pkcs7-mime + + + p7r + application/x-pkcs7-certreqresp + + + p7s + application/pkcs7-signature + + + p8 + application/pkcs8 + + + pas + text/x-pascal + + + paw + application/vnd.pawaafile + + + pbd + application/vnd.powerbuilder6 + + + pbm + image/x-portable-bitmap + + + pcap + application/vnd.tcpdump.pcap + + + pcf + application/x-font-pcf + + + pcl + application/vnd.hp-pcl + + + pclxl + application/vnd.hp-pclxl + + + pct + image/pict + + + pcurl + application/vnd.curl.pcurl + + + pcx + image/x-pcx + + + pdb + application/vnd.palm + + + pdf + application/pdf + + + pfa + application/x-font-type1 + + + pfb + application/x-font-type1 + + + pfm + application/x-font-type1 + + + pfr + application/font-tdpfr + + + pfx + application/x-pkcs12 + + + pgm + image/x-portable-graymap + + + pgn + application/x-chess-pgn + + + pgp + application/pgp-encrypted + + + pic + image/pict + + + pict + image/pict + + + pkg + application/octet-stream + + + pki + application/pkixcmp + + + pkipath + application/pkix-pkipath + + + plb + application/vnd.3gpp.pic-bw-large + + + plc + application/vnd.mobius.plc + + + plf + application/vnd.pocketlearn + + + pls + audio/x-scpls + + + pml + application/vnd.ctc-posml + + + png + image/png + + + pnm + image/x-portable-anymap + + + pnt + image/x-macpaint + + + portpkg + application/vnd.macports.portpkg + + + pot + application/vnd.ms-powerpoint + + + potm + application/vnd.ms-powerpoint.template.macroenabled.12 + + + potx + application/vnd.openxmlformats-officedocument.presentationml.template + + + ppam + application/vnd.ms-powerpoint.addin.macroenabled.12 + + + ppd + application/vnd.cups-ppd + + + ppm + image/x-portable-pixmap + + + pps + application/vnd.ms-powerpoint + + + ppsm + application/vnd.ms-powerpoint.slideshow.macroenabled.12 + + + ppsx + application/vnd.openxmlformats-officedocument.presentationml.slideshow + + + ppt + application/vnd.ms-powerpoint + + + pptm + application/vnd.ms-powerpoint.presentation.macroenabled.12 + + + pptx + application/vnd.openxmlformats-officedocument.presentationml.presentation + + + pqa + application/vnd.palm + + + prc + application/x-mobipocket-ebook + + + pre + application/vnd.lotus-freelance + + + prf + application/pics-rules + + + ps + application/postscript + + + psb + application/vnd.3gpp.pic-bw-small + + + psd + image/vnd.adobe.photoshop + + + psf + application/x-font-linux-psf + + + pskcxml + application/pskc+xml + + + ptid + application/vnd.pvi.ptid1 + + + pub + application/x-mspublisher + + + pvb + application/vnd.3gpp.pic-bw-var + + + pwn + application/vnd.3m.post-it-notes + + + pya + audio/vnd.ms-playready.media.pya + + + pyv + video/vnd.ms-playready.media.pyv + + + qam + application/vnd.epson.quickanime + + + qbo + application/vnd.intu.qbo + + + qfx + application/vnd.intu.qfx + + + qps + application/vnd.publishare-delta-tree + + + qt + video/quicktime + + + qti + image/x-quicktime + + + qtif + image/x-quicktime + + + qwd + application/vnd.quark.quarkxpress + + + qwt + application/vnd.quark.quarkxpress + + + qxb + application/vnd.quark.quarkxpress + + + qxd + application/vnd.quark.quarkxpress + + + qxl + application/vnd.quark.quarkxpress + + + qxt + application/vnd.quark.quarkxpress + + + ra + audio/x-pn-realaudio + + + ram + audio/x-pn-realaudio + + + rar + application/x-rar-compressed + + + ras + image/x-cmu-raster + + + rcprofile + application/vnd.ipunplugged.rcprofile + + + rdf + application/rdf+xml + + + rdz + application/vnd.data-vision.rdz + + + rep + application/vnd.businessobjects + + + res + application/x-dtbresource+xml + + + rgb + image/x-rgb + + + rif + application/reginfo+xml + + + rip + audio/vnd.rip + + + rl + application/resource-lists+xml + + + rlc + image/vnd.fujixerox.edmics-rlc + + + rld + application/resource-lists-diff+xml + + + rm + application/vnd.rn-realmedia + + + rmi + audio/midi + + + rmp + audio/x-pn-realaudio-plugin + + + rms + application/vnd.jcp.javame.midlet-rms + + + rnc + application/relax-ng-compact-syntax + + + roa + application/rpki-roa + + + roff + text/troff + + + rp9 + application/vnd.cloanto.rp9 + + + rpss + application/vnd.nokia.radio-presets + + + rpst + application/vnd.nokia.radio-preset + + + rq + application/sparql-query + + + rs + application/rls-services+xml + + + rsd + application/rsd+xml + + + rss + application/rss+xml + + + rtf + application/rtf + + + rtx + text/richtext + + + s + text/x-asm + + + saf + application/vnd.yamaha.smaf-audio + + + sbml + application/sbml+xml + + + sc + application/vnd.ibm.secure-container + + + scd + application/x-msschedule + + + scm + application/vnd.lotus-screencam + + + scq + application/scvp-cv-request + + + scs + application/scvp-cv-response + + + scurl + text/vnd.curl.scurl + + + sda + application/vnd.stardivision.draw + + + sdc + application/vnd.stardivision.calc + + + sdd + application/vnd.stardivision.impress + + + sdkd + application/vnd.solent.sdkm+xml + + + sdkm + application/vnd.solent.sdkm+xml + + + sdp + application/sdp + + + sdw + application/vnd.stardivision.writer + + + see + application/vnd.seemail + + + seed + application/vnd.fdsn.seed + + + sema + application/vnd.sema + + + semd + application/vnd.semd + + + semf + application/vnd.semf + + + ser + application/java-serialized-object + + + setpay + application/set-payment-initiation + + + setreg + application/set-registration-initiation + + + sfd-hdstx + application/vnd.hydrostatix.sof-data + + + sfs + application/vnd.spotfire.sfs + + + sgl + application/vnd.stardivision.writer-global + + + sgm + text/sgml + + + sgml + text/sgml + + + sh + application/x-sh + + + shar + application/x-shar + + + shf + application/shf+xml + + + + sig + application/pgp-signature + + + silo + model/mesh + + + sis + application/vnd.symbian.install + + + sisx + application/vnd.symbian.install + + + sit + application/x-stuffit + + + sitx + application/x-stuffitx + + + skd + application/vnd.koan + + + skm + application/vnd.koan + + + skp + application/vnd.koan + + + skt + application/vnd.koan + + + sldm + application/vnd.ms-powerpoint.slide.macroenabled.12 + + + sldx + application/vnd.openxmlformats-officedocument.presentationml.slide + + + slt + application/vnd.epson.salt + + + sm + application/vnd.stepmania.stepchart + + + smf + application/vnd.stardivision.math + + + smi + application/smil+xml + + + smil + application/smil+xml + + + smzip + application/vnd.stepmania.package + + + snd + audio/basic + + + snf + application/x-font-snf + + + so + application/octet-stream + + + spc + application/x-pkcs7-certificates + + + spf + application/vnd.yamaha.smaf-phrase + + + spl + application/x-futuresplash + + + spot + text/vnd.in3d.spot + + + spp + application/scvp-vp-response + + + spq + application/scvp-vp-request + + + spx + audio/ogg + + + src + application/x-wais-source + + + sru + application/sru+xml + + + srx + application/sparql-results+xml + + + sse + application/vnd.kodak-descriptor + + + ssf + application/vnd.epson.ssf + + + ssml + application/ssml+xml + + + st + application/vnd.sailingtracker.track + + + stc + application/vnd.sun.xml.calc.template + + + std + application/vnd.sun.xml.draw.template + + + stf + application/vnd.wt.stf + + + sti + application/vnd.sun.xml.impress.template + + + stk + application/hyperstudio + + + stl + application/vnd.ms-pki.stl + + + str + application/vnd.pg.format + + + stw + application/vnd.sun.xml.writer.template + + + sub + text/vnd.dvb.subtitle + + + sus + application/vnd.sus-calendar + + + susp + application/vnd.sus-calendar + + + sv4cpio + application/x-sv4cpio + + + sv4crc + application/x-sv4crc + + + svc + application/vnd.dvb.service + + + svd + application/vnd.svd + + + svg + image/svg+xml + + + svgz + image/svg+xml + + + swa + application/x-director + + + swf + application/x-shockwave-flash + + + swi + application/vnd.aristanetworks.swi + + + sxc + application/vnd.sun.xml.calc + + + sxd + application/vnd.sun.xml.draw + + + sxg + application/vnd.sun.xml.writer.global + + + sxi + application/vnd.sun.xml.impress + + + sxm + application/vnd.sun.xml.math + + + sxw + application/vnd.sun.xml.writer + + + t + text/troff + + + taglet + application/vnd.mynfc + + + tao + application/vnd.tao.intent-module-archive + + + tar + application/x-tar + + + tcap + application/vnd.3gpp2.tcap + + + tcl + application/x-tcl + + + teacher + application/vnd.smart.teacher + + + tei + application/tei+xml + + + teicorpus + application/tei+xml + + + tex + application/x-tex + + + texi + application/x-texinfo + + + texinfo + application/x-texinfo + + + text + text/plain + + + tfi + application/thraud+xml + + + tfm + application/x-tex-tfm + + + thmx + application/vnd.ms-officetheme + + + tif + image/tiff + + + tiff + image/tiff + + + tmo + application/vnd.tmobile-livetv + + + torrent + application/x-bittorrent + + + tpl + application/vnd.groove-tool-template + + + tpt + application/vnd.trid.tpt + + + tr + text/troff + + + tra + application/vnd.trueapp + + + trm + application/x-msterminal + + + tsd + application/timestamped-data + + + tsv + text/tab-separated-values + + + ttc + application/x-font-ttf + + + ttf + application/x-font-ttf + + + ttl + text/turtle + + + twd + application/vnd.simtech-mindmapper + + + twds + application/vnd.simtech-mindmapper + + + txd + application/vnd.genomatix.tuxedo + + + txf + application/vnd.mobius.txf + + + txt + text/plain + + + u32 + application/x-authorware-bin + + + udeb + application/x-debian-package + + + ufd + application/vnd.ufdl + + + ufdl + application/vnd.ufdl + + + ulw + audio/basic + + + umj + application/vnd.umajin + + + unityweb + application/vnd.unity + + + uoml + application/vnd.uoml+xml + + + uri + text/uri-list + + + uris + text/uri-list + + + urls + text/uri-list + + + ustar + application/x-ustar + + + utz + application/vnd.uiq.theme + + + uu + text/x-uuencode + + + uva + audio/vnd.dece.audio + + + uvd + application/vnd.dece.data + + + uvf + application/vnd.dece.data + + + uvg + image/vnd.dece.graphic + + + uvh + video/vnd.dece.hd + + + uvi + image/vnd.dece.graphic + + + uvm + video/vnd.dece.mobile + + + uvp + video/vnd.dece.pd + + + uvs + video/vnd.dece.sd + + + uvt + application/vnd.dece.ttml+xml + + + uvu + video/vnd.uvvu.mp4 + + + uvv + video/vnd.dece.video + + + uvva + audio/vnd.dece.audio + + + uvvd + application/vnd.dece.data + + + uvvf + application/vnd.dece.data + + + uvvg + image/vnd.dece.graphic + + + uvvh + video/vnd.dece.hd + + + uvvi + image/vnd.dece.graphic + + + uvvm + video/vnd.dece.mobile + + + uvvp + video/vnd.dece.pd + + + uvvs + video/vnd.dece.sd + + + uvvt + application/vnd.dece.ttml+xml + + + uvvu + video/vnd.uvvu.mp4 + + + uvvv + video/vnd.dece.video + + + uvvx + application/vnd.dece.unspecified + + + uvvz + application/vnd.dece.zip + + + uvx + application/vnd.dece.unspecified + + + uvz + application/vnd.dece.zip + + + vcard + text/vcard + + + vcd + application/x-cdlink + + + vcf + text/x-vcard + + + vcg + application/vnd.groove-vcard + + + vcs + text/x-vcalendar + + + vcx + application/vnd.vcx + + + vis + application/vnd.visionary + + + viv + video/vnd.vivo + + + vor + application/vnd.stardivision.writer + + + vox + application/x-authorware-bin + + + vrml + model/vrml + + + vsd + application/vnd.visio + + + vsf + application/vnd.vsf + + + vss + application/vnd.visio + + + vst + application/vnd.visio + + + vsw + application/vnd.visio + + + vtu + model/vnd.vtu + + + vxml + application/voicexml+xml + + + w3d + application/x-director + + + wad + application/x-doom + + + wav + audio/x-wav + + + wax + audio/x-ms-wax + + + + wbmp + image/vnd.wap.wbmp + + + wbs + application/vnd.criticaltools.wbs+xml + + + wbxml + application/vnd.wap.wbxml + + + wcm + application/vnd.ms-works + + + wdb + application/vnd.ms-works + + + weba + audio/webm + + + webm + video/webm + + + webp + image/webp + + + wg + application/vnd.pmi.widget + + + wgt + application/widget + + + wks + application/vnd.ms-works + + + wm + video/x-ms-wm + + + wma + audio/x-ms-wma + + + wmd + application/x-ms-wmd + + + wmf + application/x-msmetafile + + + + wml + text/vnd.wap.wml + + + + wmlc + application/vnd.wap.wmlc + + + + wmls + text/vnd.wap.wmlscript + + + + wmlsc + application/vnd.wap.wmlscriptc + + + wmv + video/x-ms-wmv + + + wmx + video/x-ms-wmx + + + wmz + application/x-ms-wmz + + + woff + application/x-font-woff + + + wpd + application/vnd.wordperfect + + + wpl + application/vnd.ms-wpl + + + wps + application/vnd.ms-works + + + wqd + application/vnd.wqd + + + wri + application/x-mswrite + + + wrl + model/vrml + + + wsdl + application/wsdl+xml + + + wspolicy + application/wspolicy+xml + + + wtb + application/vnd.webturbo + + + wvx + video/x-ms-wvx + + + x32 + application/x-authorware-bin + + + x3d + application/vnd.hzn-3d-crossword + + + xap + application/x-silverlight-app + + + xar + application/vnd.xara + + + xbap + application/x-ms-xbap + + + xbd + application/vnd.fujixerox.docuworks.binder + + + xbm + image/x-xbitmap + + + xdf + application/xcap-diff+xml + + + xdm + application/vnd.syncml.dm+xml + + + xdp + application/vnd.adobe.xdp+xml + + + xdssc + application/dssc+xml + + + xdw + application/vnd.fujixerox.docuworks + + + xenc + application/xenc+xml + + + xer + application/patch-ops-error+xml + + + xfdf + application/vnd.adobe.xfdf + + + xfdl + application/vnd.xfdl + + + xht + application/xhtml+xml + + + xhtml + application/xhtml+xml + + + xhvml + application/xv+xml + + + xif + image/vnd.xiff + + + xla + application/vnd.ms-excel + + + xlam + application/vnd.ms-excel.addin.macroenabled.12 + + + xlc + application/vnd.ms-excel + + + xlm + application/vnd.ms-excel + + + xls + application/vnd.ms-excel + + + xlsb + application/vnd.ms-excel.sheet.binary.macroenabled.12 + + + xlsm + application/vnd.ms-excel.sheet.macroenabled.12 + + + xlsx + application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + + + xlt + application/vnd.ms-excel + + + xltm + application/vnd.ms-excel.template.macroenabled.12 + + + xltx + application/vnd.openxmlformats-officedocument.spreadsheetml.template + + + xlw + application/vnd.ms-excel + + + xml + application/xml + + + xo + application/vnd.olpc-sugar + + + xop + application/xop+xml + + + xpi + application/x-xpinstall + + + xpm + image/x-xpixmap + + + xpr + application/vnd.is-xpr + + + xps + application/vnd.ms-xpsdocument + + + xpw + application/vnd.intercon.formnet + + + xpx + application/vnd.intercon.formnet + + + xsl + application/xml + + + xslt + application/xslt+xml + + + xsm + application/vnd.syncml+xml + + + xspf + application/xspf+xml + + + xul + application/vnd.mozilla.xul+xml + + + xvm + application/xv+xml + + + xvml + application/xv+xml + + + xwd + image/x-xwindowdump + + + xyz + chemical/x-xyz + + + yang + application/yang + + + yin + application/yin+xml + + + z + application/x-compress + + + Z + application/x-compress + + + zaz + application/vnd.zzazz.deck+xml + + + zip + application/zip + + + zir + application/vnd.zul + + + zirz + application/vnd.zul + + + zmm + application/vnd.handheld-entertainment+xml + + + + + + + + + + + + + + + + + + index.html + index.htm + index.jsp + + + diff --git a/jdk/bin/ControlPanel b/jdk/bin/ControlPanel old mode 100644 new mode 100755 diff --git a/jdk/bin/HtmlConverter b/jdk/bin/HtmlConverter old mode 100644 new mode 100755 diff --git a/jdk/bin/appletviewer b/jdk/bin/appletviewer old mode 100644 new mode 100755 diff --git a/jdk/bin/apt b/jdk/bin/apt old mode 100644 new mode 100755 diff --git a/jdk/bin/extcheck b/jdk/bin/extcheck old mode 100644 new mode 100755 diff --git a/jdk/bin/idlj b/jdk/bin/idlj old mode 100644 new mode 100755 diff --git a/jdk/bin/jar b/jdk/bin/jar old mode 100644 new mode 100755 diff --git a/jdk/bin/jarsigner b/jdk/bin/jarsigner old mode 100644 new mode 100755 diff --git a/jdk/bin/java b/jdk/bin/java old mode 100644 new mode 100755 diff --git a/jdk/bin/java-rmi.cgi b/jdk/bin/java-rmi.cgi old mode 100644 new mode 100755 diff --git a/jdk/bin/javac b/jdk/bin/javac old mode 100644 new mode 100755 diff --git a/jdk/bin/javadoc b/jdk/bin/javadoc old mode 100644 new mode 100755 diff --git a/jdk/bin/javah b/jdk/bin/javah old mode 100644 new mode 100755 diff --git a/jdk/bin/javap b/jdk/bin/javap old mode 100644 new mode 100755 diff --git a/jdk/bin/javaws b/jdk/bin/javaws old mode 100644 new mode 100755 diff --git a/jdk/bin/jconsole b/jdk/bin/jconsole old mode 100644 new mode 100755 diff --git a/jdk/bin/jcontrol b/jdk/bin/jcontrol old mode 100644 new mode 100755 diff --git a/jdk/bin/jdb b/jdk/bin/jdb old mode 100644 new mode 100755 diff --git a/jdk/bin/jhat b/jdk/bin/jhat old mode 100644 new mode 100755 diff --git a/jdk/bin/jinfo b/jdk/bin/jinfo old mode 100644 new mode 100755 diff --git a/jdk/bin/jmap b/jdk/bin/jmap old mode 100644 new mode 100755 diff --git a/jdk/bin/jps b/jdk/bin/jps old mode 100644 new mode 100755 diff --git a/jdk/bin/jrunscript b/jdk/bin/jrunscript old mode 100644 new mode 100755 diff --git a/jdk/bin/jsadebugd b/jdk/bin/jsadebugd old mode 100644 new mode 100755 diff --git a/jdk/bin/jstack b/jdk/bin/jstack old mode 100644 new mode 100755 diff --git a/jdk/bin/jstat b/jdk/bin/jstat old mode 100644 new mode 100755 diff --git a/jdk/bin/jstatd b/jdk/bin/jstatd old mode 100644 new mode 100755 diff --git a/jdk/bin/jvisualvm b/jdk/bin/jvisualvm old mode 100644 new mode 100755 diff --git a/jdk/bin/keytool b/jdk/bin/keytool old mode 100644 new mode 100755 diff --git a/jdk/bin/native2ascii b/jdk/bin/native2ascii old mode 100644 new mode 100755 diff --git a/jdk/bin/orbd b/jdk/bin/orbd old mode 100644 new mode 100755 diff --git a/jdk/bin/pack200 b/jdk/bin/pack200 old mode 100644 new mode 100755 diff --git a/jdk/bin/policytool b/jdk/bin/policytool old mode 100644 new mode 100755 diff --git a/jdk/bin/rmic b/jdk/bin/rmic old mode 100644 new mode 100755 diff --git a/jdk/bin/rmid b/jdk/bin/rmid old mode 100644 new mode 100755 diff --git a/jdk/bin/rmiregistry b/jdk/bin/rmiregistry old mode 100644 new mode 100755 diff --git a/jdk/bin/schemagen b/jdk/bin/schemagen old mode 100644 new mode 100755 diff --git a/jdk/bin/serialver b/jdk/bin/serialver old mode 100644 new mode 100755 diff --git a/jdk/bin/servertool b/jdk/bin/servertool old mode 100644 new mode 100755 diff --git a/jdk/bin/tnameserv b/jdk/bin/tnameserv old mode 100644 new mode 100755 diff --git a/jdk/bin/unpack200 b/jdk/bin/unpack200 old mode 100644 new mode 100755 diff --git a/jdk/bin/wsgen b/jdk/bin/wsgen old mode 100644 new mode 100755 diff --git a/jdk/bin/wsimport b/jdk/bin/wsimport old mode 100644 new mode 100755 diff --git a/jdk/bin/xjc b/jdk/bin/xjc old mode 100644 new mode 100755 diff --git a/jdk/jre/bin/ControlPanel b/jdk/jre/bin/ControlPanel old mode 100644 new mode 100755 diff --git a/jdk/jre/bin/java b/jdk/jre/bin/java old mode 100644 new mode 100755 diff --git a/jdk/jre/bin/java_vm b/jdk/jre/bin/java_vm old mode 100644 new mode 100755 diff --git a/jdk/jre/bin/javaws b/jdk/jre/bin/javaws old mode 100644 new mode 100755 diff --git a/jdk/jre/bin/jcontrol b/jdk/jre/bin/jcontrol old mode 100644 new mode 100755 diff --git a/jdk/jre/bin/keytool b/jdk/jre/bin/keytool old mode 100644 new mode 100755 diff --git a/jdk/jre/bin/orbd b/jdk/jre/bin/orbd old mode 100644 new mode 100755 diff --git a/jdk/jre/bin/pack200 b/jdk/jre/bin/pack200 old mode 100644 new mode 100755 diff --git a/jdk/jre/bin/policytool b/jdk/jre/bin/policytool old mode 100644 new mode 100755 diff --git a/jdk/jre/bin/rmid b/jdk/jre/bin/rmid old mode 100644 new mode 100755 diff --git a/jdk/jre/bin/rmiregistry b/jdk/jre/bin/rmiregistry old mode 100644 new mode 100755 diff --git a/jdk/jre/bin/servertool b/jdk/jre/bin/servertool old mode 100644 new mode 100755 diff --git a/jdk/jre/bin/tnameserv b/jdk/jre/bin/tnameserv old mode 100644 new mode 100755 diff --git a/jdk/jre/bin/unpack200 b/jdk/jre/bin/unpack200 old mode 100644 new mode 100755 diff --git a/jdk/jre/javaws/javaws b/jdk/jre/javaws/javaws old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/deploy/messages_zh_HK.properties b/jdk/jre/lib/deploy/messages_zh_HK.properties old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/client/libjsig.so b/jdk/jre/lib/i386/client/libjsig.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/client/libjvm.so b/jdk/jre/lib/i386/client/libjvm.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/headless/libmawt.so b/jdk/jre/lib/i386/headless/libmawt.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/jli/libjli.so b/jdk/jre/lib/i386/jli/libjli.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libJdbcOdbc.so b/jdk/jre/lib/i386/libJdbcOdbc.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libattach.so b/jdk/jre/lib/i386/libattach.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libawt.so b/jdk/jre/lib/i386/libawt.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libcmm.so b/jdk/jre/lib/i386/libcmm.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libdcpr.so b/jdk/jre/lib/i386/libdcpr.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libdeploy.so b/jdk/jre/lib/i386/libdeploy.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libdt_socket.so b/jdk/jre/lib/i386/libdt_socket.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libfontmanager.so b/jdk/jre/lib/i386/libfontmanager.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libhprof.so b/jdk/jre/lib/i386/libhprof.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libinstrument.so b/jdk/jre/lib/i386/libinstrument.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libioser12.so b/jdk/jre/lib/i386/libioser12.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libj2gss.so b/jdk/jre/lib/i386/libj2gss.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libj2pcsc.so b/jdk/jre/lib/i386/libj2pcsc.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libj2pkcs11.so b/jdk/jre/lib/i386/libj2pkcs11.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libjaas_unix.so b/jdk/jre/lib/i386/libjaas_unix.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libjava.so b/jdk/jre/lib/i386/libjava.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libjava_crw_demo.so b/jdk/jre/lib/i386/libjava_crw_demo.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libjavaplugin_jni.so b/jdk/jre/lib/i386/libjavaplugin_jni.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libjavaplugin_nscp.so b/jdk/jre/lib/i386/libjavaplugin_nscp.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libjavaplugin_nscp_gcc29.so b/jdk/jre/lib/i386/libjavaplugin_nscp_gcc29.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libjawt.so b/jdk/jre/lib/i386/libjawt.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libjdwp.so b/jdk/jre/lib/i386/libjdwp.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libjpeg.so b/jdk/jre/lib/i386/libjpeg.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libjsig.so b/jdk/jre/lib/i386/libjsig.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libjsound.so b/jdk/jre/lib/i386/libjsound.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libjsoundalsa.so b/jdk/jre/lib/i386/libjsoundalsa.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libmanagement.so b/jdk/jre/lib/i386/libmanagement.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libmlib_image.so b/jdk/jre/lib/i386/libmlib_image.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libnet.so b/jdk/jre/lib/i386/libnet.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libnio.so b/jdk/jre/lib/i386/libnio.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libnpjp2.so b/jdk/jre/lib/i386/libnpjp2.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libnpt.so b/jdk/jre/lib/i386/libnpt.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/librmi.so b/jdk/jre/lib/i386/librmi.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libsaproc.so b/jdk/jre/lib/i386/libsaproc.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libsplashscreen.so b/jdk/jre/lib/i386/libsplashscreen.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libunpack.so b/jdk/jre/lib/i386/libunpack.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libverify.so b/jdk/jre/lib/i386/libverify.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/libzip.so b/jdk/jre/lib/i386/libzip.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/motif21/libmawt.so b/jdk/jre/lib/i386/motif21/libmawt.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/native_threads/libhpi.so b/jdk/jre/lib/i386/native_threads/libhpi.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/server/libjsig.so b/jdk/jre/lib/i386/server/libjsig.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/server/libjvm.so b/jdk/jre/lib/i386/server/libjvm.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/i386/xawt/libmawt.so b/jdk/jre/lib/i386/xawt/libmawt.so old mode 100644 new mode 100755 diff --git a/jdk/jre/lib/jexec b/jdk/jre/lib/jexec old mode 100644 new mode 100755 diff --git a/jdk/jre/plugin/i386/ns7-gcc29/libjavaplugin_oji.so b/jdk/jre/plugin/i386/ns7-gcc29/libjavaplugin_oji.so old mode 100644 new mode 100755 diff --git a/jdk/jre/plugin/i386/ns7/libjavaplugin_oji.so b/jdk/jre/plugin/i386/ns7/libjavaplugin_oji.so old mode 100644 new mode 100755 diff --git a/jdk/lib/jexec b/jdk/lib/jexec old mode 100644 new mode 100755 diff --git a/lib/activation.jar b/lib/activation.jar old mode 100644 new mode 100755 diff --git a/lib/annotations-api.jar b/lib/annotations-api.jar old mode 100644 new mode 100755 diff --git a/lib/catalina-ant.jar b/lib/catalina-ant.jar old mode 100644 new mode 100755 diff --git a/lib/catalina-ha.jar b/lib/catalina-ha.jar old mode 100644 new mode 100755 diff --git a/lib/catalina-tribes.jar b/lib/catalina-tribes.jar old mode 100644 new mode 100755 diff --git a/lib/catalina.jar b/lib/catalina.jar old mode 100644 new mode 100755 diff --git a/lib/derby.jar b/lib/derby.jar old mode 100644 new mode 100755 diff --git a/lib/ecj-3.7.2.jar b/lib/ecj-3.7.2.jar old mode 100644 new mode 100755 diff --git a/lib/el-api.jar b/lib/el-api.jar old mode 100644 new mode 100755 diff --git a/lib/jasper-el.jar b/lib/jasper-el.jar old mode 100644 new mode 100755 diff --git a/lib/jasper.jar b/lib/jasper.jar old mode 100644 new mode 100755 diff --git a/lib/jcr-2.0.jar b/lib/jcr-2.0.jar old mode 100644 new mode 100755 diff --git a/lib/jsp-api.jar b/lib/jsp-api.jar old mode 100644 new mode 100755 diff --git a/lib/mail.jar b/lib/mail.jar old mode 100644 new mode 100755 diff --git a/lib/mysql-connector-java-5.0.4-bin.jar b/lib/mysql-connector-java-5.0.4-bin.jar old mode 100644 new mode 100755 diff --git a/lib/postgresql.jar b/lib/postgresql.jar old mode 100644 new mode 100755 diff --git a/lib/servlet-api.jar b/lib/servlet-api.jar old mode 100644 new mode 100755 diff --git a/lib/tomcat-api.jar b/lib/tomcat-api.jar old mode 100644 new mode 100755 diff --git a/lib/tomcat-coyote.jar b/lib/tomcat-coyote.jar old mode 100644 new mode 100755 diff --git a/lib/tomcat-dbcp.jar b/lib/tomcat-dbcp.jar old mode 100644 new mode 100755 diff --git a/lib/tomcat-i18n-es.jar b/lib/tomcat-i18n-es.jar old mode 100644 new mode 100755 diff --git a/lib/tomcat-i18n-fr.jar b/lib/tomcat-i18n-fr.jar old mode 100644 new mode 100755 diff --git a/lib/tomcat-i18n-ja.jar b/lib/tomcat-i18n-ja.jar old mode 100644 new mode 100755 diff --git a/lib/tomcat-jdbc.jar b/lib/tomcat-jdbc.jar old mode 100644 new mode 100755 diff --git a/lib/tomcat-util.jar b/lib/tomcat-util.jar old mode 100644 new mode 100755 diff --git a/source/ngasi/caimito/CaimitoConfig.java b/source/ngasi/caimito/CaimitoConfig.java old mode 100644 new mode 100755 index 877ee79..4b2f832 --- a/source/ngasi/caimito/CaimitoConfig.java +++ b/source/ngasi/caimito/CaimitoConfig.java @@ -51,6 +51,7 @@ public class CaimitoConfig{ public static boolean cacheable = true; public static String serverinfo = "Caimito"; public static String CAIMITO_CSS = null; + public static String version = "0.2"; public static void init()throws CaimitoException{ if (! new File(getConfigFile()).exists()) { diff --git a/source/ngasi/caimito/CaimitoDefaultServlet.java b/source/ngasi/caimito/CaimitoDefaultServlet.java old mode 100644 new mode 100755 index 2f6ffe4..e83a8d0 --- a/source/ngasi/caimito/CaimitoDefaultServlet.java +++ b/source/ngasi/caimito/CaimitoDefaultServlet.java @@ -1,2246 +1,2246 @@ -/* - Copyright (c) 2011-2012, the Caimito project (http://caimito.ngasi.com/). All rights reserved. -Apache Software License 2.0 -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WebAppShowCase -OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package ngasi.caimito; - -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.io.RandomAccessFile; -import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.StringTokenizer; -import java.util.Enumeration; - -import javax.naming.InitialContext; -import javax.naming.NameClassPair; -import javax.naming.NamingEnumeration; -import javax.naming.NamingException; -import javax.naming.directory.DirContext; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletOutputStream; -import javax.servlet.ServletResponse; -import javax.servlet.ServletResponseWrapper; -import javax.servlet.UnavailableException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; - -import org.apache.catalina.Globals; -import org.apache.catalina.connector.RequestFacade; -import org.apache.catalina.connector.ResponseFacade; -import org.apache.catalina.util.RequestUtil; -import org.apache.catalina.util.ServerInfo; -import org.apache.catalina.util.URLEncoder; -import org.apache.naming.resources.CacheEntry; -import org.apache.naming.resources.ProxyDirContext; -import org.apache.naming.resources.Resource; -import org.apache.naming.resources.ResourceAttributes; -//import org.apache.tomcat.util.res.StringManager; -import org.apache.catalina.servlets.*; -import ngasi.caimito.resource.*; - -/** - *

The default resource-serving servlet for most web applications, - * used to serve static resources such as HTML pages and images. - *

- *

- * This servlet is intended to be mapped to / e.g.: - *

- *
- *   <servlet-mapping>
- *       <servlet-name>default</servlet-name>
- *       <url-pattern>/</url-pattern>
- *   </servlet-mapping>
- * 
- *

It can be mapped to sub-paths, however in all cases resources are served - * from the web appplication resource root using the full path from the root - * of the web application context. - *
e.g. given a web application structure: - *

- *
- * /context
- *   /images
- *     tomcat2.jpg
- *   /static
- *     /images
- *       tomcat.jpg
- * 
- *

- * ... and a servlet mapping that maps only /static/* to the default servlet: - *

- *
- *   <servlet-mapping>
- *       <servlet-name>default</servlet-name>
- *       <url-pattern>/static/*</url-pattern>
- *   </servlet-mapping>
- * 
- *

- * Then a request to /context/static/images/tomcat.jpg will succeed - * while a request to /context/images/tomcat2.jpg will fail. - *

- * @author Craig R. McClanahan - * @author Remy Maucherat - * @version $Id: DefaultServlet.java 1200163 2011-11-10 05:40:04Z kkolinko $ - */ - -public class CaimitoDefaultServlet - extends HttpServlet { - - private static final long serialVersionUID = 1L; - - // ----------------------------------------------------- Instance Variables - - - /** - * The debugging detail level for this servlet. - */ - protected int debug = 0; - - - /** - * The input buffer size to use when serving resources. - */ - protected int input = 2048; - - - /** - * Should we generate directory listings? - */ - protected boolean listings = false; - - - /** - * Read only flag. By default, it's set to true. - */ - protected boolean readOnly = true; - - - /** - * The output buffer size to use when serving resources. - */ - protected int output = 2048; - - - /** - * Array containing the safe characters set. - */ - protected static URLEncoder urlEncoder; - - - /** - * Allow customized directory listing per directory. - */ - protected String localXsltFile = null; - - - /** - * Allow customized directory listing per context. - */ - protected String contextXsltFile = null; - - - /** - * Allow customized directory listing per instance. - */ - protected String globalXsltFile = null; - - - /** - * Allow a readme file to be included. - */ - protected String readmeFile = null; - - - /** - * Proxy directory context. - */ - protected transient ProxyDirContext resources = null; - - - /** - * File encoding to be used when reading static files. If none is specified - * the platform default is used. - */ - protected String fileEncoding = null; - - - /** - * Minimum size for sendfile usage in bytes. - */ - protected int sendfileSize = 48 * 1024; - - /** - * Should the Accept-Ranges: bytes header be send with static resources? - */ - protected boolean useAcceptRanges = true; - - /** - * Full range marker. - */ - protected static ArrayList FULL = new ArrayList(); - - - // ----------------------------------------------------- Static Initializer - - - /** - * GMT timezone - all HTTP dates are on GMT - */ - static { - urlEncoder = new URLEncoder(); - urlEncoder.addSafeCharacter('-'); - urlEncoder.addSafeCharacter('_'); - urlEncoder.addSafeCharacter('.'); - urlEncoder.addSafeCharacter('*'); - urlEncoder.addSafeCharacter('/'); - } - - - /** - * MIME multipart separation string - */ - protected static final String mimeSeparation = "CATALINA_MIME_BOUNDARY"; - - - /** - * JNDI resources name. - */ - protected static final String RESOURCES_JNDI_NAME = "java:/comp/Resources"; - - - /** - * The string manager for this package. - */ - //protected static final StringManager sm = - // StringManager.getManager(Constants.Package); - - - /** - * Size of file transfer buffer in bytes. - */ - protected static final int BUFFER_SIZE = 4096; - - - // --------------------------------------------------------- Public Methods - - - /** - * Finalize this servlet. - */ - @Override - public void destroy() { - // NOOP - } - - - /** - * Initialize this servlet. - */ - @Override - public void init() throws ServletException { - - if (getServletConfig().getInitParameter("debug") != null) - debug = Integer.parseInt(getServletConfig().getInitParameter("debug")); - - if (getServletConfig().getInitParameter("input") != null) - input = Integer.parseInt(getServletConfig().getInitParameter("input")); - - if (getServletConfig().getInitParameter("output") != null) - output = Integer.parseInt(getServletConfig().getInitParameter("output")); - - listings = Boolean.parseBoolean(getServletConfig().getInitParameter("listings")); - - if (getServletConfig().getInitParameter("readonly") != null) - readOnly = Boolean.parseBoolean(getServletConfig().getInitParameter("readonly")); - - if (getServletConfig().getInitParameter("sendfileSize") != null) - sendfileSize = - Integer.parseInt(getServletConfig().getInitParameter("sendfileSize")) * 1024; - - fileEncoding = getServletConfig().getInitParameter("fileEncoding"); - - globalXsltFile = getServletConfig().getInitParameter("globalXsltFile"); - contextXsltFile = getServletConfig().getInitParameter("contextXsltFile"); - localXsltFile = getServletConfig().getInitParameter("localXsltFile"); - readmeFile = getServletConfig().getInitParameter("readmeFile"); - - if (getServletConfig().getInitParameter("useAcceptRanges") != null) - useAcceptRanges = Boolean.parseBoolean(getServletConfig().getInitParameter("useAcceptRanges")); - - // Sanity check on the specified buffer sizes - if (input < 256) - input = 256; - if (output < 256) - output = 256; - - if (debug > 0) { - log("DefaultServlet.init: input buffer size=" + input + - ", output buffer size=" + output); - } - - // Load the proxy dir context. - resources = (ProxyDirContext) getServletContext() - .getAttribute(Globals.RESOURCES_ATTR); - if (resources == null) { - try { - resources = - (ProxyDirContext) new InitialContext() - .lookup(RESOURCES_JNDI_NAME); - } catch (NamingException e) { - // Failed - throw new ServletException("No resources", e); - } - } - - if (resources == null) { - throw new UnavailableException("No resources"); - } - - } - - protected String smgetString(String msg,HttpServletRequest request){ - return smgetString(msg,null,request); - } - protected String smgetString(String msg,String val,HttpServletRequest request){ - try{ - String ms2 = (String)CaimitoConfig.getConfig().get(msg); - if (ms2 != null) - return ms2; - }catch (Exception e){ - e.printStackTrace(); - } - return msg; - } - - - - /*protected String checkAccess(String path, HttpServletRequest request, - HttpServletResponse response, - int acc) - throws CaimitoException { - if (path.equals("/") - { - - } - return path; - }*/ - - // ------------------------------------------------------ Protected Methods - - - /** - * Return the relative path associated with this servlet. - * - * @param request The servlet request we are processing - */ - protected String getRelativePath(HttpServletRequest request) { - // IMPORTANT: DefaultServlet can be mapped to '/' or '/path/*' but always - // serves resources from the web app root with context rooted paths. - // i.e. it can not be used to mount the web app root under a sub-path - // This method must construct a complete context rooted path, although - // subclasses can change this behaviour. - - // Are we being processed by a RequestDispatcher.include()? - if (request.getAttribute( - RequestDispatcher.INCLUDE_REQUEST_URI) != null) { - String result = (String) request.getAttribute( - RequestDispatcher.INCLUDE_PATH_INFO); - if (result == null) { - result = (String) request.getAttribute( - RequestDispatcher.INCLUDE_SERVLET_PATH); - } else { - result = (String) request.getAttribute( - RequestDispatcher.INCLUDE_SERVLET_PATH) + result; - } - if ((result == null) || (result.equals(""))) { - result = "/"; - } - result = tools.util.StringUtil.replaceSubstring(result,"..",""); - result = tools.util.StringUtil.replaceSubstring(result,"//","\\"); - result = tools.util.StringUtil.replaceSubstring(result,"\\","/"); - result = tools.util.StringUtil.replaceSubstring(result,":",""); - - return (result); - } - - // No, extract the desired path directly from the request - String result = request.getPathInfo(); - if (result == null) { - result = request.getServletPath(); - } else { - result = request.getServletPath() + result; - } - if ((result == null) || (result.equals(""))) { - result = "/"; - } - result = tools.util.StringUtil.replaceSubstring(result,"..",""); - result = tools.util.StringUtil.replaceSubstring(result,"//","\\"); - result = tools.util.StringUtil.replaceSubstring(result,"\\","/"); - result = tools.util.StringUtil.replaceSubstring(result,":",""); - - return (result); - - } - - - /** - * Determines the appropriate path to prepend resources with - * when generating directory listings. Depending on the behaviour of - * {@link #getRelativePath(HttpServletRequest)} this will change. - * @param request the request to determine the path for - * @return the prefix to apply to all resources in the listing. - */ - protected String getPathPrefix(final HttpServletRequest request) { - return request.getContextPath(); - } - - - /** - * Process a GET request for the specified resource. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * - * @exception IOException if an input/output error occurs - * @exception ServletException if a servlet-specified error occurs - */ - @Override - protected void doGet(HttpServletRequest request, - HttpServletResponse response) - throws IOException, ServletException { - - // Serve the requested resource, including the data content - serveResource(request, response, true); - - } - - - /** - * Process a HEAD request for the specified resource. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * - * @exception IOException if an input/output error occurs - * @exception ServletException if a servlet-specified error occurs - */ - @Override - protected void doHead(HttpServletRequest request, - HttpServletResponse response) - throws IOException, ServletException { - - // Serve the requested resource, without the data content - serveResource(request, response, false); - - } - - - /** - * Override default implementation to ensure that TRACE is correctly - * handled. - * - * @param req the {@link HttpServletRequest} object that - * contains the request the client made of - * the servlet - * - * @param resp the {@link HttpServletResponse} object that - * contains the response the servlet returns - * to the client - * - * @exception IOException if an input or output error occurs - * while the servlet is handling the - * OPTIONS request - * - * @exception ServletException if the request for the - * OPTIONS cannot be handled - */ - /*@Override - protected void doOptions(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - //("DOP 1"); - StringBuilder allow = new StringBuilder(); - // There is a doGet method - allow.append("GET, HEAD"); - // There is a doPost - allow.append(", POST"); - // There is a doPut - allow.append(", PUT"); - // There is a doDelete - allow.append(", DELETE"); - // Trace - assume disabled unless we can prove otherwise - if (req instanceof RequestFacade && - ((RequestFacade) req).getAllowTrace()) { - allow.append(", TRACE"); - } - // Always allow options - allow.append(", OPTIONS"); - - resp.setHeader("Allow", allow.toString()); - }*/ - - - /** - * Process a POST request for the specified resource. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * - * @exception IOException if an input/output error occurs - * @exception ServletException if a servlet-specified error occurs - */ - @Override - protected void doPost(HttpServletRequest request, - HttpServletResponse response) - throws IOException, ServletException { - doGet(request, response); - } - - - /** - * Process a PUT request for the specified resource. - * - * @param req The servlet request we are processing - * @param resp The servlet response we are creating - * - * @exception IOException if an input/output error occurs - * @exception ServletException if a servlet-specified error occurs - */ - @Override - protected void doPut(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - - String path = getRelativePath(req); - - ResourceObj ro = ResourceStore.lookup(path,req,resp,ResourceStore.WRITE); - if (ro == null)return; - if (ro == null) { - resp.sendError(HttpServletResponse.SC_FORBIDDEN); - return; - } - - - boolean exists = ro.exists(); - //(path + " EXISTSRE " + exists); - - //boolean result = true; - - // Temp. content file used to support partial PUT - //File contentFile = null; - - //Range range = parseContentRange(req, resp); - - InputStream resourceInputStream = null; - - // Append data specified in ranges to existing content for this - // resource - create a temp. file on the local filesystem to - // perform this operation - // Assume just one range is specified for now - //if (range != null) { - // contentFile = executePartialPut(req, range, path); - // resourceInputStream = new FileInputStream(contentFile); - // } else { - resourceInputStream = req.getInputStream(); - // } - - String ct = getServletContext().getMimeType(ro.getName()); - ro.contentType = ct; - ro.contentLength = req.getContentLength(); - ro.write(resourceInputStream); - - /*try { - Resource newResource = new Resource(resourceInputStream); - // FIXME: Add attributes - if (exists) { - resources.rebind(path, newResource); - } else { - resources.bind(path, newResource); - } - } catch(NamingException e) { - result = false; - }*/ - - //if (result) { - if (exists) { - resp.setStatus(HttpServletResponse.SC_NO_CONTENT); - } else { - resp.setStatus(HttpServletResponse.SC_CREATED); - } - // } else { - // resp.sendError(HttpServletResponse.SC_CONFLICT); - // } - - } - - - /** - * Handle a partial PUT. New content specified in request is appended to - * existing content in oldRevisionContent (if present). This code does - * not support simultaneous partial updates to the same resource. - */ - /*protected File executePartialPut(HttpServletRequest req, Range range, - String path) - throws IOException { - - // Append data specified in ranges to existing content for this - // resource - create a temp. file on the local filesystem to - // perform this operation - File tempDir = (File) getServletContext().getAttribute - (ServletContext.TEMPDIR); - // Convert all '/' characters to '.' in resourcePath - String convertedResourcePath = path.replace('/', '.'); - File contentFile = new File(tempDir, convertedResourcePath); - if (contentFile.createNewFile()) { - // Clean up contentFile when Tomcat is terminated - contentFile.deleteOnExit(); - } - - RandomAccessFile randAccessContentFile = - new RandomAccessFile(contentFile, "rw"); - - Resource oldResource = null; - try { - Object obj = resources.lookup(path); - if (obj instanceof Resource) - oldResource = (Resource) obj; - } catch (NamingException e) { - // Ignore - } - - // Copy data in oldRevisionContent to contentFile - if (oldResource != null) { - BufferedInputStream bufOldRevStream = - new BufferedInputStream(oldResource.streamContent(), - BUFFER_SIZE); - - int numBytesRead; - byte[] copyBuffer = new byte[BUFFER_SIZE]; - while ((numBytesRead = bufOldRevStream.read(copyBuffer)) != -1) { - randAccessContentFile.write(copyBuffer, 0, numBytesRead); - } - - bufOldRevStream.close(); - } - - randAccessContentFile.setLength(range.length); - - // Append data in request input stream to contentFile - randAccessContentFile.seek(range.start); - int numBytesRead; - byte[] transferBuffer = new byte[BUFFER_SIZE]; - BufferedInputStream requestBufInStream = - new BufferedInputStream(req.getInputStream(), BUFFER_SIZE); - while ((numBytesRead = requestBufInStream.read(transferBuffer)) != -1) { - randAccessContentFile.write(transferBuffer, 0, numBytesRead); - } - randAccessContentFile.close(); - requestBufInStream.close(); - - return contentFile; - - }*/ - - - /** - * Process a DELETE request for the specified resource. - * - * @param req The servlet request we are processing - * @param resp The servlet response we are creating - * - * @exception IOException if an input/output error occurs - * @exception ServletException if a servlet-specified error occurs - */ - @Override - protected void doDelete(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - /*if (readOnly) { - resp.sendError(HttpServletResponse.SC_FORBIDDEN); - return; - }*/ - - String path = getRelativePath(req); - ResourceObj ro = ResourceStore.lookup(path,req,resp,ResourceStore.WRITE); - if (ro == null)return; - - if (!ro.canWrite()) { - resp.sendError(HttpServletResponse.SC_FORBIDDEN); - return; - } - - boolean exists = ro.exists(); - - - /*try { - resources.lookup(path); - } catch (NamingException e) { - exists = false; - }*/ - - if (exists) { - boolean result = true; - try { - ro.delete(); - } catch (Exception e) { - result = false; - } - if (result) { - resp.setStatus(HttpServletResponse.SC_NO_CONTENT); - } else { - resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED); - } - } else { - resp.sendError(HttpServletResponse.SC_NOT_FOUND); - } - - } - - - /** - * Check if the conditions specified in the optional If headers are - * satisfied. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * @param resourceAttributes The resource information - * @return boolean true if the resource meets all the specified conditions, - * and false if any of the conditions is not satisfied, in which case - * request processing is stopped - */ - protected boolean checkIfHeaders(HttpServletRequest request, - HttpServletResponse response, - ResourceObj resourceAttributes) - throws IOException,CaimitoException { - - return checkIfMatch(request, response, resourceAttributes) - && checkIfModifiedSince(request, response, resourceAttributes) - && checkIfNoneMatch(request, response, resourceAttributes) - && checkIfUnmodifiedSince(request, response, resourceAttributes); - - } - - - /** - * URL rewriter. - * - * @param path Path which has to be rewritten - */ - protected String rewriteUrl(String path) { - return urlEncoder.encode( path ); - } - - - /** - * Display the size of a file. - */ - protected void displaySize(StringBuilder buf, int filesize) { - - int leftside = filesize / 1024; - int rightside = (filesize % 1024) / 103; // makes 1 digit - // To avoid 0.0 for non-zero file, we bump to 0.1 - if (leftside == 0 && rightside == 0 && filesize != 0) - rightside = 1; - buf.append(leftside).append(".").append(rightside); - buf.append(" KB"); - - } - - - /** - * Serve the specified resource, optionally including the data content. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * @param content Should the content be included? - * - * @exception IOException if an input/output error occurs - * @exception ServletException if a servlet-specified error occurs - */ - protected void serveResource(HttpServletRequest request, - HttpServletResponse response, - boolean content) - throws IOException, ServletException { - - boolean serveContent = content; - - // Identify the requested resource path - String path = getRelativePath(request); - ResourceObj ro = ResourceStore.lookup(path,request,response,ResourceStore.READ); - - if (ro == null)return; - - if (!ro.canRead()) { - response.sendError(HttpServletResponse.SC_FORBIDDEN); - return; - } - - if (debug > 0) { - if (serveContent) - log("DefaultServlet.serveResource: Serving resource '" + - path + "' headers and data"); - else - log("DefaultServlet.serveResource: Serving resource '" + - path + "' headers only"); - } - - // CacheEntry cacheEntry = resources.lookupCache(path); - - if (!ro.exists()) { - // Check if we're included so we can return the appropriate - // missing resource name in the error - String requestUri = (String) request.getAttribute( - RequestDispatcher.INCLUDE_REQUEST_URI); - if (requestUri == null) { - requestUri = request.getRequestURI(); - } else { - // We're included - // SRV.9.3 says we must throw a FNFE - throw new FileNotFoundException( - "defaultServlet.missingResource"); - } - - response.sendError(HttpServletResponse.SC_NOT_FOUND, - requestUri); - return; - } - - // If the resource is not a collection, and the resource path - // ends with "/" or "\", return NOT FOUND - if (!ro.isDirectory()) { - if (path.endsWith("/") || (path.endsWith("\\"))) { - // Check if we're included so we can return the appropriate - // missing resource name in the error - String requestUri = (String) request.getAttribute( - RequestDispatcher.INCLUDE_REQUEST_URI); - if (requestUri == null) { - requestUri = request.getRequestURI(); - } - response.sendError(HttpServletResponse.SC_NOT_FOUND, - requestUri); - return; - } - } - - boolean isError = - response.getStatus() >= HttpServletResponse.SC_BAD_REQUEST; - - // Check if the conditions specified in the optional If headers are - // satisfied. - if (!ro.isDirectory()) { - - // Checking If headers - boolean included = (request.getAttribute( - RequestDispatcher.INCLUDE_CONTEXT_PATH) != null); - if (!included && !isError && - !checkIfHeaders(request, response, ro)) { - return; - } - - } - - // Find content type. - String contentType = ro.getMimeType(); - if (contentType == null) { - contentType = getServletContext().getMimeType(ro.path); - ro.setMimeType(contentType); - } - - ArrayList ranges = null; - long contentLength = -1L; - - if (ro.isDirectory()) { - - // Skip directory listings if we have been configured to - // suppress them - if (!ro.listings()) { - response.sendError(HttpServletResponse.SC_NOT_FOUND, - request.getRequestURI()); - return; - } - contentType = "text/html;charset=UTF-8"; - - } else { - if (!isError) { - if (useAcceptRanges) { - // Accept ranges header - response.setHeader("Accept-Ranges", "bytes"); - } - - // Parse range specifier - ranges = parseRange(request, response, ro); - - // ETag header - response.setHeader("ETag", ro.getETag()); - - // Last-Modified header - response.setHeader("Last-Modified", - ro.getLastModifiedHttp()); - } - - // Get content length - contentLength = ro.getContentLength(); - // Special case for zero length files, which would cause a - // (silent) ISE when setting the output buffer size - if (contentLength == 0L) { - serveContent = false; - //("SERVER CONTENT = fale"); - } - - } -//(contentType + " serveContent " + serveContent); - ServletOutputStream ostream = null; - PrintWriter writer = null; - - if (serveContent) { - - // Trying to retrieve the servlet output stream - - try { - ostream = response.getOutputStream(); - } catch (IllegalStateException e) { - // If it fails, we try to get a Writer instead if we're - // trying to serve a text file - if ( (contentType == null) - || (contentType.startsWith("text")) - || (contentType.endsWith("xml")) - || (contentType.contains("/javascript")) ) { - writer = response.getWriter(); - // Cannot reliably serve partial content with a Writer - ranges = FULL; - } else { - throw e; - } - } - - } - - // Check to see if a Filter, Valve of wrapper has written some content. - // If it has, disable range requests and setting of a content length - // since neither can be done reliably. - ServletResponse r = response; - long contentWritten = 0; - while (r instanceof ServletResponseWrapper) { - r = ((ServletResponseWrapper) r).getResponse(); - } - if (r instanceof ResponseFacade) { - contentWritten = ((ResponseFacade) r).getContentWritten(); - } - if (contentWritten > 0) { - ranges = FULL; - } - - if ( (ro.isDirectory()) - || isError - || ( ((ranges == null) || (ranges.isEmpty())) - && (request.getHeader("Range") == null) ) - || (ranges == FULL) ) { - - // Set the appropriate output headers - if (contentType != null) { - if (debug > 0) - log("DefaultServlet.serveFile: contentType='" + - contentType + "'"); - response.setContentType(contentType); - } - //???(cacheEntry.resource != null) && - if ( (contentLength >= 0) - && (!serveContent || ostream != null)) { - if (debug > 0) - log("DefaultServlet.serveFile: contentLength=" + - contentLength); - // Don't set a content length if something else has already - // written to the response. - if (contentWritten == 0) { - if (contentLength < Integer.MAX_VALUE) { - response.setContentLength((int) contentLength); - } else { - // Set the content-length as String to be able to use a - // long - response.setHeader("content-length", - "" + contentLength); - } - } - } - - InputStream renderResult = null; - if (ro.isDirectory()) { - - if (serveContent) { - // Serve the directory browser - renderResult = render(getPathPrefix(request), ro,request); - } - - } - - // Copy the input stream to our output stream (if requested) - if (serveContent) { - try { - response.setBufferSize(output); - } catch (IllegalStateException e) { - // Silent catch - } - if (ostream != null ) { - if (!checkSendfile(request, response, ro, contentLength, null)) - copy(ro, renderResult, ostream); - } else { - //(writer + " SENDY FDIR " + renderResult); - copy(ro, renderResult, writer); - } - } - - } else { - - if ((ranges == null) || (ranges.isEmpty())) - return; - - // Partial content response. - - response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); - - if (ranges.size() == 1) { - - Range range = ranges.get(0); - response.addHeader("Content-Range", "bytes " - + range.start - + "-" + range.end + "/" - + range.length); - long length = range.end - range.start + 1; - if (length < Integer.MAX_VALUE) { - response.setContentLength((int) length); - } else { - // Set the content-length as String to be able to use a long - response.setHeader("content-length", "" + length); - } - - if (contentType != null) { - if (debug > 0) - log("DefaultServlet.serveFile: contentType='" + - contentType + "'"); - response.setContentType(contentType); - } - - if (serveContent) { - try { - response.setBufferSize(output); - } catch (IllegalStateException e) { - // Silent catch - } - if (ostream != null) { - if (!checkSendfile(request, response, ro, range.end - range.start + 1, range)) - copy(ro, ostream, range,request); - } else { - // we should not get here - throw new IllegalStateException(); - } - } - - } else { - - response.setContentType("multipart/byteranges; boundary=" - + mimeSeparation); - - if (serveContent) { - try { - response.setBufferSize(output); - } catch (IllegalStateException e) { - // Silent catch - } - if (ostream != null) { - copy(ro, ostream, ranges.iterator(), - contentType,request); - } else { - // we should not get here - throw new IllegalStateException(); - } - } - - } - - } - - } - - - /** - * Parse the content-range header. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * @return Range - */ - protected Range parseContentRange(HttpServletRequest request, - HttpServletResponse response) - throws IOException { - - // Retrieving the content-range header (if any is specified - String rangeHeader = request.getHeader("Content-Range"); - - if (rangeHeader == null) - return null; - - // bytes is the only range unit supported - if (!rangeHeader.startsWith("bytes")) { - response.sendError(HttpServletResponse.SC_BAD_REQUEST); - return null; - } - - rangeHeader = rangeHeader.substring(6).trim(); - - int dashPos = rangeHeader.indexOf('-'); - int slashPos = rangeHeader.indexOf('/'); - - if (dashPos == -1) { - response.sendError(HttpServletResponse.SC_BAD_REQUEST); - return null; - } - - if (slashPos == -1) { - response.sendError(HttpServletResponse.SC_BAD_REQUEST); - return null; - } - - Range range = new Range(); - - try { - range.start = Long.parseLong(rangeHeader.substring(0, dashPos)); - range.end = - Long.parseLong(rangeHeader.substring(dashPos + 1, slashPos)); - range.length = Long.parseLong - (rangeHeader.substring(slashPos + 1, rangeHeader.length())); - } catch (NumberFormatException e) { - response.sendError(HttpServletResponse.SC_BAD_REQUEST); - return null; - } - - if (!range.validate()) { - response.sendError(HttpServletResponse.SC_BAD_REQUEST); - return null; - } - - return range; - - } - - - /** - * Parse the range header. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * @return Vector of ranges - */ - protected ArrayList parseRange(HttpServletRequest request, - HttpServletResponse response, - ResourceObj resourceAttributes) throws CaimitoException,IOException { - - // Checking If-Range - String headerValue = request.getHeader("If-Range"); - - if (headerValue != null) { - - long headerValueTime = (-1L); - try { - headerValueTime = request.getDateHeader("If-Range"); - } catch (IllegalArgumentException e) { - // Ignore - } - - String eTag = resourceAttributes.getETag(); - long lastModified = resourceAttributes.getLastModified(); - - if (headerValueTime == (-1L)) { - - // If the ETag the client gave does not match the entity - // etag, then the entire entity is returned. - if (!eTag.equals(headerValue.trim())) - return FULL; - - } else { - - // If the timestamp of the entity the client got is older than - // the last modification date of the entity, the entire entity - // is returned. - if (lastModified > (headerValueTime + 1000)) - return FULL; - - } - - } - - long fileLength = resourceAttributes.getContentLength(); - - if (fileLength == 0) - return null; - - // Retrieving the range header (if any is specified - String rangeHeader = request.getHeader("Range"); - - if (rangeHeader == null) - return null; - // bytes is the only range unit supported (and I don't see the point - // of adding new ones). - if (!rangeHeader.startsWith("bytes")) { - response.addHeader("Content-Range", "bytes */" + fileLength); - response.sendError - (HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); - return null; - } - - rangeHeader = rangeHeader.substring(6); - - // Vector which will contain all the ranges which are successfully - // parsed. - ArrayList result = new ArrayList(); - StringTokenizer commaTokenizer = new StringTokenizer(rangeHeader, ","); - - // Parsing the range list - while (commaTokenizer.hasMoreTokens()) { - String rangeDefinition = commaTokenizer.nextToken().trim(); - - Range currentRange = new Range(); - currentRange.length = fileLength; - - int dashPos = rangeDefinition.indexOf('-'); - - if (dashPos == -1) { - response.addHeader("Content-Range", "bytes */" + fileLength); - response.sendError - (HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); - return null; - } - - if (dashPos == 0) { - - try { - long offset = Long.parseLong(rangeDefinition); - currentRange.start = fileLength + offset; - currentRange.end = fileLength - 1; - } catch (NumberFormatException e) { - response.addHeader("Content-Range", - "bytes */" + fileLength); - response.sendError - (HttpServletResponse - .SC_REQUESTED_RANGE_NOT_SATISFIABLE); - return null; - } - - } else { - - try { - currentRange.start = Long.parseLong - (rangeDefinition.substring(0, dashPos)); - if (dashPos < rangeDefinition.length() - 1) - currentRange.end = Long.parseLong - (rangeDefinition.substring - (dashPos + 1, rangeDefinition.length())); - else - currentRange.end = fileLength - 1; - } catch (NumberFormatException e) { - response.addHeader("Content-Range", - "bytes */" + fileLength); - response.sendError - (HttpServletResponse - .SC_REQUESTED_RANGE_NOT_SATISFIABLE); - return null; - } - - } - - if (!currentRange.validate()) { - response.addHeader("Content-Range", "bytes */" + fileLength); - response.sendError - (HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); - return null; - } - - result.add(currentRange); - } - - return result; - } - - - - /** - * Decide which way to render. HTML or XML. - */ - protected InputStream render(String contextPath, ResourceObj cacheEntry,HttpServletRequest request) - throws IOException, ServletException { - - //InputStream xsltInputStream = - // findXsltInputStream(cacheEntry.context); - - //if (xsltInputStream==null) { - return renderHtml(contextPath, cacheEntry,request); - //} - //return renderXml(contextPath, cacheEntry, xsltInputStream); - - } - - /** - * Return an InputStream to an HTML representation of the contents - * of this directory. - * - * @param contextPath Context path to which our internal paths are - * relative - */ - protected InputStream renderXml(String contextPath, - ResourceObj ro, - InputStream xsltInputStream) - throws IOException, ServletException { - - StringBuilder sb = new StringBuilder(); - - sb.append(""); - sb.append(""); - - sb.append(""); - - try { - - // Render the directory entries within this directory - Enumeration enumeration = - ro.list().elements(); - - // rewriteUrl(contextPath) is expensive. cache result for later reuse - String rewrittenContextPath = rewriteUrl(contextPath); - - while (enumeration.hasMoreElements()) { - - ResourceObj ncPair = enumeration.nextElement(); - String resourceName = ncPair.getName(); - String trimmed = resourceName/*.substring(trim)*/; - // if (trimmed.equalsIgnoreCase("WEB-INF") || - // trimmed.equalsIgnoreCase("META-INF") || - // trimmed.equalsIgnoreCase(localXsltFile)) - // continue; - - // if ((cacheEntry.name + trimmed).equals(contextXsltFile)) - // continue; - - // CacheEntry childCacheEntry = - // resources.lookupCache(cacheEntry.name + resourceName); - // if (!childCacheEntry.exists) { - // continue; - // } - - sb.append(""); - sb.append(RequestUtil.filter(trimmed)); - if (ncPair.isDirectory()) - sb.append("/"); - sb.append(""); - - } - - } catch (Exception e) { - // Something went wrong - throw new ServletException("Error accessing resource", e); - } - - sb.append(""); - - String readme = getReadme(ro); - - if (readme!=null) { - sb.append(""); - } - - - sb.append(""); - - - try { - TransformerFactory tFactory = TransformerFactory.newInstance(); - Source xmlSource = new StreamSource(new StringReader(sb.toString())); - Source xslSource = new StreamSource(xsltInputStream); - Transformer transformer = tFactory.newTransformer(xslSource); - - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - OutputStreamWriter osWriter = new OutputStreamWriter(stream, "UTF8"); - StreamResult out = new StreamResult(osWriter); - transformer.transform(xmlSource, out); - osWriter.flush(); - return (new ByteArrayInputStream(stream.toByteArray())); - } catch (TransformerException e) { - throw new ServletException("XSL transformer error", e); - } - } - - /** - * Return an InputStream to an HTML representation of the contents - * of this directory. - * - * @param contextPath Context path to which our internal paths are - * relative - */ - protected InputStream renderHtml(String contextPath, ResourceObj ro,HttpServletRequest request) - throws IOException, ServletException { - - String name = ro.path; - - // Prepare a writer to a buffered area - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - OutputStreamWriter osWriter = new OutputStreamWriter(stream, "UTF8"); - PrintWriter writer = new PrintWriter(osWriter); - - StringBuilder sb = new StringBuilder(); - - // rewriteUrl(contextPath) is expensive. cache result for later reuse - String rewrittenContextPath = rewriteUrl(contextPath); - - // Render the page header - sb.append("\r\n"); - sb.append("\r\n"); - sb.append(""); - sb.append(smgetString("directory.title", name,request)); - sb.append("\r\n"); - sb.append(" "); - sb.append("\r\n"); - sb.append(""); - sb.append("

"); - sb.append(smgetString("directory.title", name,request)); - - // Render the link to our parent (if required) - String parentDirectory = name; - if (parentDirectory.endsWith("/")) { - parentDirectory = - parentDirectory.substring(0, parentDirectory.length() - 1); - } - int slash = parentDirectory.lastIndexOf('/'); - if (slash >= 0) { - String parent = name.substring(0, slash); - sb.append(" - "); - sb.append(""); - sb.append(smgetString("directory.parent", parent,request)); - sb.append(""); - sb.append(""); - } - - sb.append("

"); - sb.append("
"); - - sb.append("\r\n"); - - // Render the column headings - sb.append("\r\n"); - sb.append("\r\n"); - sb.append("\r\n"); - sb.append("\r\n"); - sb.append(""); - - try { - - // Render the directory entries within this directory - Enumeration enumeration = - ro.list().elements(); - boolean shade = false; - while (enumeration.hasMoreElements()) { - - ResourceObj ncPair = enumeration.nextElement(); - String resourceName = ncPair.getName(); - //(ro.path + " GET 1 " + ncPair + ":" + resourceName); - String trimmed = resourceName/*.substring(trim)*/; - //if (trimmed.equalsIgnoreCase("WEB-INF") || - // trimmed.equalsIgnoreCase("META-INF")) - // continue; - - // CacheEntry childCacheEntry = - // resources.lookupCache(cacheEntry.name + resourceName); - //if (!childCacheEntry.exists) { - // continue; - //} - - sb.append("\r\n"); - shade = !shade; - - sb.append("\r\n"); - - sb.append("\r\n"); - - sb.append("\r\n"); - - sb.append("\r\n"); - } - - } catch (Exception e) { - // Something went wrong - throw new ServletException("Error accessing resource", e); - } - - // Render the page footer - sb.append("
"); - sb.append(smgetString("directory.filename",request)); - sb.append(""); - sb.append(smgetString("directory.size",request)); - sb.append(""); - sb.append(smgetString("directory.lastModified",request)); - sb.append("
  \r\n"); - sb.append(""); - sb.append(RequestUtil.filter(trimmed)); - if (ncPair.isDirectory()) - sb.append("/"); - sb.append(""); - if (ncPair.isDirectory()) - sb.append(" "); - else - sb.append(renderSize(ncPair.getContentLength())); - sb.append(""); - sb.append(ncPair.getLastModifiedHttp()); - sb.append("
\r\n"); - - sb.append("
"); - - String readme = getReadme(ro); - if (readme!=null) { - sb.append(readme); - sb.append("
"); - } - - sb.append("

").append(CaimitoConfig.serverinfo).append("

"); - sb.append("\r\n"); - sb.append("\r\n"); - - // Return an input stream to the underlying bytes - writer.write(sb.toString()); - writer.flush(); - return (new ByteArrayInputStream(stream.toByteArray())); - - } - - - /** - * Render the specified file size (in bytes). - * - * @param size File size (in bytes) - */ - protected String renderSize(long size) { - - long leftSide = size / 1024; - long rightSide = (size % 1024) / 103; // Makes 1 digit - if ((leftSide == 0) && (rightSide == 0) && (size > 0)) - rightSide = 1; - - return ("" + leftSide + "." + rightSide + " kb"); - - } - - - /** - * Get the readme file as a string. - */ - protected String getReadme(ResourceObj directory) - throws CaimitoException,IOException { - ResourceObj rmf = directory.getReadmeFile(); - if (rmf != null) { - try { - //Object obj = directory.lookup(readmeFile); - // if ((obj != null) && (obj instanceof Resource)) { - StringWriter buffer = new StringWriter(); - InputStream is = rmf.getInputStream(); - //((Resource) obj).streamContent(); - copyRange(new InputStreamReader(is), - new PrintWriter(buffer)); - return buffer.toString(); - // } - } catch (Exception e) { - if (debug > 10) - log("readme '" + readmeFile + "' not found", e); - - return null; - } - } - - return null; - } - - - /** - * Return the xsl template inputstream (if possible) - */ - protected InputStream findXsltInputStream(DirContext directory) - throws IOException { - - if (localXsltFile != null) { - try { - Object obj = directory.lookup(localXsltFile); - if ((obj != null) && (obj instanceof Resource)) { - InputStream is = ((Resource) obj).streamContent(); - if (is != null) - return is; - } - } catch (NamingException e) { - if (debug > 10) - log("localXsltFile '" + localXsltFile + "' not found", e); - } - } - - if (contextXsltFile != null) { - InputStream is = - getServletContext().getResourceAsStream(contextXsltFile); - if (is != null) - return is; - - if (debug > 10) - log("contextXsltFile '" + contextXsltFile + "' not found"); - } - - /* Open and read in file in one fell swoop to reduce chance - * chance of leaving handle open. - */ - if (globalXsltFile!=null) { - FileInputStream fis = null; - - try { - File f = new File(globalXsltFile); - if (f.exists()){ - fis =new FileInputStream(f); - byte b[] = new byte[(int)f.length()]; /* danger! */ - fis.read(b); - return new ByteArrayInputStream(b); - } - } finally { - if (fis!=null) - fis.close(); - } - } - - return null; - - } - - - // -------------------------------------------------------- protected Methods - - - /** - * Check if sendfile can be used. - */ - protected boolean checkSendfile(HttpServletRequest request, - HttpServletResponse response, - ResourceObj entry, - long length, Range range) { - /*if ((sendfileSize > 0) - - && ((length > sendfileSize) || (entry.getContentLength() > 0)) - && (entry.getCanonicalPath() != null) - && (Boolean.TRUE == request.getAttribute("org.apache.tomcat.sendfile.support")) - && (request.getClass().getName().equals("org.apache.catalina.connector.RequestFacade")) - && (response.getClass().getName().equals("org.apache.catalina.connector.ResponseFacade"))) { - request.setAttribute("org.apache.tomcat.sendfile.filename", entry.getCanonicalPath()); - if (range == null) { - request.setAttribute("org.apache.tomcat.sendfile.start", Long.valueOf(0L)); - request.setAttribute("org.apache.tomcat.sendfile.end", Long.valueOf(length)); - } else { - request.setAttribute("org.apache.tomcat.sendfile.start", Long.valueOf(range.start)); - request.setAttribute("org.apache.tomcat.sendfile.end", Long.valueOf(range.end + 1)); - } - return true; - }*/ - return false; - } - - - /** - * Check if the if-match condition is satisfied. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * @param resourceAttributes File object - * @return boolean true if the resource meets the specified condition, - * and false if the condition is not satisfied, in which case request - * processing is stopped - */ - protected boolean checkIfMatch(HttpServletRequest request, - HttpServletResponse response, - ResourceObj resourceAttributes) - throws CaimitoException,IOException { - - String eTag = resourceAttributes.getETag(); - String headerValue = request.getHeader("If-Match"); - if (headerValue != null) { - if (headerValue.indexOf('*') == -1) { - - StringTokenizer commaTokenizer = new StringTokenizer - (headerValue, ","); - boolean conditionSatisfied = false; - - while (!conditionSatisfied && commaTokenizer.hasMoreTokens()) { - String currentToken = commaTokenizer.nextToken(); - if (currentToken.trim().equals(eTag)) - conditionSatisfied = true; - } - - // If none of the given ETags match, 412 Precodition failed is - // sent back - if (!conditionSatisfied) { - response.sendError - (HttpServletResponse.SC_PRECONDITION_FAILED); - return false; - } - - } - } - return true; - - } - - - /** - * Check if the if-modified-since condition is satisfied. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * @param resourceAttributes File object - * @return boolean true if the resource meets the specified condition, - * and false if the condition is not satisfied, in which case request - * processing is stopped - */ - protected boolean checkIfModifiedSince(HttpServletRequest request, - HttpServletResponse response, - ResourceObj resourceAttributes) { - try { - long headerValue = request.getDateHeader("If-Modified-Since"); - long lastModified = resourceAttributes.getLastModified(); - if (headerValue != -1) { - - // If an If-None-Match header has been specified, if modified since - // is ignored. - if ((request.getHeader("If-None-Match") == null) - && (lastModified < headerValue + 1000)) { - // The entity has not been modified since the date - // specified by the client. This is not an error case. - response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); - response.setHeader("ETag", resourceAttributes.getETag()); - - return false; - } - } - } catch (Exception illegalArgument) { - return true; - } - return true; - - } - - - /** - * Check if the if-none-match condition is satisfied. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * @param resourceAttributes File object - * @return boolean true if the resource meets the specified condition, - * and false if the condition is not satisfied, in which case request - * processing is stopped - */ - protected boolean checkIfNoneMatch(HttpServletRequest request, - HttpServletResponse response, - ResourceObj resourceAttributes) - throws CaimitoException,IOException { - - String eTag = resourceAttributes.getETag(); - String headerValue = request.getHeader("If-None-Match"); - if (headerValue != null) { - - boolean conditionSatisfied = false; - - if (!headerValue.equals("*")) { - - StringTokenizer commaTokenizer = - new StringTokenizer(headerValue, ","); - - while (!conditionSatisfied && commaTokenizer.hasMoreTokens()) { - String currentToken = commaTokenizer.nextToken(); - if (currentToken.trim().equals(eTag)) - conditionSatisfied = true; - } - - } else { - conditionSatisfied = true; - } - - if (conditionSatisfied) { - - // For GET and HEAD, we should respond with - // 304 Not Modified. - // For every other method, 412 Precondition Failed is sent - // back. - if ( ("GET".equals(request.getMethod())) - || ("HEAD".equals(request.getMethod())) ) { - response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); - response.setHeader("ETag", eTag); - - return false; - } - response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED); - return false; - } - } - return true; - - } - - - /** - * Check if the if-unmodified-since condition is satisfied. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * @param resourceAttributes File object - * @return boolean true if the resource meets the specified condition, - * and false if the condition is not satisfied, in which case request - * processing is stopped - */ - protected boolean checkIfUnmodifiedSince(HttpServletRequest request, - HttpServletResponse response, - ResourceObj resourceAttributes) - throws CaimitoException { - try { - long lastModified = resourceAttributes.getLastModified(); - long headerValue = request.getDateHeader("If-Unmodified-Since"); - if (headerValue != -1) { - if ( lastModified >= (headerValue + 1000)) { - // The entity has not been modified since the date - // specified by the client. This is not an error case. - response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED); - return false; - } - } - } catch(Exception illegalArgument) { - return true; - } - return true; - - } - - - /** - * Copy the contents of the specified input stream to the specified - * output stream, and ensure that both streams are closed before returning - * (even in the face of an exception). - * - * @param cacheEntry The cache entry for the source resource - * @param is The input stream to read the source resource from - * @param ostream The output stream to write to - * - * @exception IOException if an input/output error occurs - */ - protected void copy(ResourceObj cacheEntry, InputStream is, - ServletOutputStream ostream) - throws CaimitoException,IOException { - - IOException exception = null; - InputStream resourceInputStream = null; - - // Optimization: If the binary content has already been loaded, send - // it directly - //("cacheEntry.resource 1 " + cacheEntry); - if (!cacheEntry.isDirectory() && cacheEntry.getContentLength() >0) { - /*byte buffer[] = cacheEntry.resource.getContent(); - if (buffer != null) { - //("cacheEntry.resource 2 " + cacheEntry); - - ostream.write(buffer, 0, buffer.length); - return; - }*/ - resourceInputStream = cacheEntry.getInputStream(); - } else { - resourceInputStream = is; - } - - InputStream istream = new BufferedInputStream - (resourceInputStream, input); - - // Copy the input stream to the output stream - exception = copyRange(istream, ostream); - - // Clean up the input stream - istream.close(); - - // Rethrow any exception that has occurred - if (exception != null) - throw exception; - - } - - - /** - * Copy the contents of the specified input stream to the specified - * output stream, and ensure that both streams are closed before returning - * (even in the face of an exception). - * - * @param cacheEntry The cache entry for the source resource - * @param is The input stream to read the source resource from - * @param writer The writer to write to - * - * @exception IOException if an input/output error occurs - */ - protected void copy(ResourceObj cacheEntry, InputStream is, PrintWriter writer) - throws CaimitoException,IOException { - - IOException exception = null; - - InputStream resourceInputStream = null; - if (!cacheEntry.isDirectory() && cacheEntry.getContentLength() > 0) { - resourceInputStream = cacheEntry.getInputStream(); - } else { - resourceInputStream = is; - } - - Reader reader; - if (fileEncoding == null) { - reader = new InputStreamReader(resourceInputStream); - } else { - reader = new InputStreamReader(resourceInputStream, - fileEncoding); - } - - // Copy the input stream to the output stream - exception = copyRange(reader, writer); - - // Clean up the reader - reader.close(); - - // Rethrow any exception that has occurred - if (exception != null) - throw exception; - - } - - - /** - * Copy the contents of the specified input stream to the specified - * output stream, and ensure that both streams are closed before returning - * (even in the face of an exception). - * - * @param cacheEntry The cache entry for the source resource - * @param ostream The output stream to write to - * @param range Range the client wanted to retrieve - * @exception IOException if an input/output error occurs - */ - protected void copy(ResourceObj cacheEntry, ServletOutputStream ostream, - Range range,HttpServletRequest request) - throws CaimitoException,IOException { - - IOException exception = null; - - InputStream resourceInputStream = cacheEntry.getInputStream(); - InputStream istream = - new BufferedInputStream(resourceInputStream, input); - exception = copyRange(istream, ostream, range.start, range.end,request); - - // Clean up the input stream - istream.close(); - - // Rethrow any exception that has occurred - if (exception != null) - throw exception; - - } - - - /** - * Copy the contents of the specified input stream to the specified - * output stream, and ensure that both streams are closed before returning - * (even in the face of an exception). - * - * @param cacheEntry The cache entry for the source resource - * @param ostream The output stream to write to - * @param ranges Enumeration of the ranges the client wanted to retrieve - * @param contentType Content type of the resource - * @exception IOException if an input/output error occurs - */ - protected void copy(ResourceObj cacheEntry, ServletOutputStream ostream, - Iterator ranges, String contentType,HttpServletRequest request) - throws CaimitoException,IOException { - - IOException exception = null; - - while ( (exception == null) && (ranges.hasNext()) ) { - - InputStream resourceInputStream = cacheEntry.getInputStream(); - InputStream istream = - new BufferedInputStream(resourceInputStream, input); - - Range currentRange = ranges.next(); - - // Writing MIME header. - ostream.println(); - ostream.println("--" + mimeSeparation); - if (contentType != null) - ostream.println("Content-Type: " + contentType); - ostream.println("Content-Range: bytes " + currentRange.start - + "-" + currentRange.end + "/" - + currentRange.length); - ostream.println(); - - // Printing content - exception = copyRange(istream, ostream, currentRange.start, - currentRange.end,request); - - istream.close(); - - } - - ostream.println(); - ostream.print("--" + mimeSeparation + "--"); - - // Rethrow any exception that has occurred - if (exception != null) - throw exception; - - } - - - /** - * Copy the contents of the specified input stream to the specified - * output stream, and ensure that both streams are closed before returning - * (even in the face of an exception). - * - * @param istream The input stream to read from - * @param ostream The output stream to write to - * @return Exception which occurred during processing - */ - protected IOException copyRange(InputStream istream, - ServletOutputStream ostream) { - - // Copy the input stream to the output stream - IOException exception = null; - byte buffer[] = new byte[input]; - int len = buffer.length; - while (true) { - try { - len = istream.read(buffer); - if (len == -1) - break; - ostream.write(buffer, 0, len); - } catch (IOException e) { - exception = e; - len = -1; - break; - } - } - return exception; - - } - - - /** - * Copy the contents of the specified input stream to the specified - * output stream, and ensure that both streams are closed before returning - * (even in the face of an exception). - * - * @param reader The reader to read from - * @param writer The writer to write to - * @return Exception which occurred during processing - */ - protected IOException copyRange(Reader reader, PrintWriter writer) { - - // Copy the input stream to the output stream - IOException exception = null; - char buffer[] = new char[input]; - int len = buffer.length; - while (true) { - try { - len = reader.read(buffer); - if (len == -1) - break; - writer.write(buffer, 0, len); - } catch (IOException e) { - exception = e; - len = -1; - break; - } - } - return exception; - - } - - - /** - * Copy the contents of the specified input stream to the specified - * output stream, and ensure that both streams are closed before returning - * (even in the face of an exception). - * - * @param istream The input stream to read from - * @param ostream The output stream to write to - * @param start Start of the range which will be copied - * @param end End of the range which will be copied - * @return Exception which occurred during processing - */ - protected IOException copyRange(InputStream istream, - ServletOutputStream ostream, - long start, long end,HttpServletRequest request) { - - if (debug > 10) - log("Serving bytes:" + start + "-" + end); - - long skipped = 0; - try { - skipped = istream.skip(start); - } catch (IOException e) { - return e; - } - if (skipped < start) { - return new IOException(smgetString("defaultservlet.skipfail", - ("" +skipped),request)); - } - - IOException exception = null; - long bytesToRead = end - start + 1; - - byte buffer[] = new byte[input]; - int len = buffer.length; - while ( (bytesToRead > 0) && (len >= buffer.length)) { - try { - len = istream.read(buffer); - if (bytesToRead >= len) { - ostream.write(buffer, 0, len); - bytesToRead -= len; - } else { - ostream.write(buffer, 0, (int) bytesToRead); - bytesToRead = 0; - } - } catch (IOException e) { - exception = e; - len = -1; - } - if (len < buffer.length) - break; - } - - return exception; - - } - - - // ------------------------------------------------------ Range Inner Class - - - protected static class Range { - - public long start; - public long end; - public long length; - - /** - * Validate range. - */ - public boolean validate() { - if (end >= length) - end = length - 1; - return (start >= 0) && (end >= 0) && (start <= end) && (length > 0); - } - } -} +/* + Copyright (c) 2011-2012, the Caimito project (http://caimito.ngasi.com/). All rights reserved. +Apache Software License 2.0 +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WebAppShowCase +OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package ngasi.caimito; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.RandomAccessFile; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.StringTokenizer; +import java.util.Enumeration; + +import javax.naming.InitialContext; +import javax.naming.NameClassPair; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.DirContext; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.ServletResponse; +import javax.servlet.ServletResponseWrapper; +import javax.servlet.UnavailableException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import org.apache.catalina.Globals; +import org.apache.catalina.connector.RequestFacade; +import org.apache.catalina.connector.ResponseFacade; +import org.apache.catalina.util.RequestUtil; +import org.apache.catalina.util.ServerInfo; +import org.apache.catalina.util.URLEncoder; +import org.apache.naming.resources.CacheEntry; +import org.apache.naming.resources.ProxyDirContext; +import org.apache.naming.resources.Resource; +import org.apache.naming.resources.ResourceAttributes; +//import org.apache.tomcat.util.res.StringManager; +import org.apache.catalina.servlets.*; +import ngasi.caimito.resource.*; + +/** + *

The default resource-serving servlet for most web applications, + * used to serve static resources such as HTML pages and images. + *

+ *

+ * This servlet is intended to be mapped to / e.g.: + *

+ *
+ *   <servlet-mapping>
+ *       <servlet-name>default</servlet-name>
+ *       <url-pattern>/</url-pattern>
+ *   </servlet-mapping>
+ * 
+ *

It can be mapped to sub-paths, however in all cases resources are served + * from the web appplication resource root using the full path from the root + * of the web application context. + *
e.g. given a web application structure: + *

+ *
+ * /context
+ *   /images
+ *     tomcat2.jpg
+ *   /static
+ *     /images
+ *       tomcat.jpg
+ * 
+ *

+ * ... and a servlet mapping that maps only /static/* to the default servlet: + *

+ *
+ *   <servlet-mapping>
+ *       <servlet-name>default</servlet-name>
+ *       <url-pattern>/static/*</url-pattern>
+ *   </servlet-mapping>
+ * 
+ *

+ * Then a request to /context/static/images/tomcat.jpg will succeed + * while a request to /context/images/tomcat2.jpg will fail. + *

+ * @author Craig R. McClanahan + * @author Remy Maucherat + * @version $Id: DefaultServlet.java 1200163 2011-11-10 05:40:04Z kkolinko $ + */ + +public class CaimitoDefaultServlet + extends HttpServlet { + + private static final long serialVersionUID = 1L; + + // ----------------------------------------------------- Instance Variables + + + /** + * The debugging detail level for this servlet. + */ + protected int debug = 0; + + + /** + * The input buffer size to use when serving resources. + */ + protected int input = 2048; + + + /** + * Should we generate directory listings? + */ + protected boolean listings = false; + + + /** + * Read only flag. By default, it's set to true. + */ + protected boolean readOnly = true; + + + /** + * The output buffer size to use when serving resources. + */ + protected int output = 2048; + + + /** + * Array containing the safe characters set. + */ + protected static URLEncoder urlEncoder; + + + /** + * Allow customized directory listing per directory. + */ + protected String localXsltFile = null; + + + /** + * Allow customized directory listing per context. + */ + protected String contextXsltFile = null; + + + /** + * Allow customized directory listing per instance. + */ + protected String globalXsltFile = null; + + + /** + * Allow a readme file to be included. + */ + protected String readmeFile = null; + + + /** + * Proxy directory context. + */ + protected transient ProxyDirContext resources = null; + + + /** + * File encoding to be used when reading static files. If none is specified + * the platform default is used. + */ + protected String fileEncoding = null; + + + /** + * Minimum size for sendfile usage in bytes. + */ + protected int sendfileSize = 48 * 1024; + + /** + * Should the Accept-Ranges: bytes header be send with static resources? + */ + protected boolean useAcceptRanges = true; + + /** + * Full range marker. + */ + protected static ArrayList FULL = new ArrayList(); + + + // ----------------------------------------------------- Static Initializer + + + /** + * GMT timezone - all HTTP dates are on GMT + */ + static { + urlEncoder = new URLEncoder(); + urlEncoder.addSafeCharacter('-'); + urlEncoder.addSafeCharacter('_'); + urlEncoder.addSafeCharacter('.'); + urlEncoder.addSafeCharacter('*'); + urlEncoder.addSafeCharacter('/'); + } + + + /** + * MIME multipart separation string + */ + protected static final String mimeSeparation = "CATALINA_MIME_BOUNDARY"; + + + /** + * JNDI resources name. + */ + protected static final String RESOURCES_JNDI_NAME = "java:/comp/Resources"; + + + /** + * The string manager for this package. + */ + //protected static final StringManager sm = + // StringManager.getManager(Constants.Package); + + + /** + * Size of file transfer buffer in bytes. + */ + protected static final int BUFFER_SIZE = 4096; + + + // --------------------------------------------------------- Public Methods + + + /** + * Finalize this servlet. + */ + @Override + public void destroy() { + // NOOP + } + + + /** + * Initialize this servlet. + */ + @Override + public void init() throws ServletException { + + if (getServletConfig().getInitParameter("debug") != null) + debug = Integer.parseInt(getServletConfig().getInitParameter("debug")); + + if (getServletConfig().getInitParameter("input") != null) + input = Integer.parseInt(getServletConfig().getInitParameter("input")); + + if (getServletConfig().getInitParameter("output") != null) + output = Integer.parseInt(getServletConfig().getInitParameter("output")); + + listings = Boolean.parseBoolean(getServletConfig().getInitParameter("listings")); + + if (getServletConfig().getInitParameter("readonly") != null) + readOnly = Boolean.parseBoolean(getServletConfig().getInitParameter("readonly")); + + if (getServletConfig().getInitParameter("sendfileSize") != null) + sendfileSize = + Integer.parseInt(getServletConfig().getInitParameter("sendfileSize")) * 1024; + + fileEncoding = getServletConfig().getInitParameter("fileEncoding"); + + globalXsltFile = getServletConfig().getInitParameter("globalXsltFile"); + contextXsltFile = getServletConfig().getInitParameter("contextXsltFile"); + localXsltFile = getServletConfig().getInitParameter("localXsltFile"); + readmeFile = getServletConfig().getInitParameter("readmeFile"); + + if (getServletConfig().getInitParameter("useAcceptRanges") != null) + useAcceptRanges = Boolean.parseBoolean(getServletConfig().getInitParameter("useAcceptRanges")); + + // Sanity check on the specified buffer sizes + if (input < 256) + input = 256; + if (output < 256) + output = 256; + + if (debug > 0) { + log("DefaultServlet.init: input buffer size=" + input + + ", output buffer size=" + output); + } + + // Load the proxy dir context. + resources = (ProxyDirContext) getServletContext() + .getAttribute(Globals.RESOURCES_ATTR); + if (resources == null) { + try { + resources = + (ProxyDirContext) new InitialContext() + .lookup(RESOURCES_JNDI_NAME); + } catch (NamingException e) { + // Failed + throw new ServletException("No resources", e); + } + } + + if (resources == null) { + throw new UnavailableException("No resources"); + } + + } + + protected String smgetString(String msg,HttpServletRequest request){ + return smgetString(msg,null,request); + } + protected String smgetString(String msg,String val,HttpServletRequest request){ + try{ + String ms2 = (String)CaimitoConfig.getConfig().get(msg); + if (ms2 != null) + return ms2; + }catch (Exception e){ + e.printStackTrace(); + } + return msg; + } + + + + /*protected String checkAccess(String path, HttpServletRequest request, + HttpServletResponse response, + int acc) + throws CaimitoException { + if (path.equals("/") + { + + } + return path; + }*/ + + // ------------------------------------------------------ Protected Methods + + + /** + * Return the relative path associated with this servlet. + * + * @param request The servlet request we are processing + */ + protected String getRelativePath(HttpServletRequest request) { + // IMPORTANT: DefaultServlet can be mapped to '/' or '/path/*' but always + // serves resources from the web app root with context rooted paths. + // i.e. it can not be used to mount the web app root under a sub-path + // This method must construct a complete context rooted path, although + // subclasses can change this behaviour. + + // Are we being processed by a RequestDispatcher.include()? + if (request.getAttribute( + RequestDispatcher.INCLUDE_REQUEST_URI) != null) { + String result = (String) request.getAttribute( + RequestDispatcher.INCLUDE_PATH_INFO); + if (result == null) { + result = (String) request.getAttribute( + RequestDispatcher.INCLUDE_SERVLET_PATH); + } else { + result = (String) request.getAttribute( + RequestDispatcher.INCLUDE_SERVLET_PATH) + result; + } + if ((result == null) || (result.equals(""))) { + result = "/"; + } + result = tools.util.StringUtil.replaceSubstring(result,"..",""); + result = tools.util.StringUtil.replaceSubstring(result,"//","\\"); + result = tools.util.StringUtil.replaceSubstring(result,"\\","/"); + result = tools.util.StringUtil.replaceSubstring(result,":",""); + + return (result); + } + + // No, extract the desired path directly from the request + String result = request.getPathInfo(); + if (result == null) { + result = request.getServletPath(); + } else { + result = request.getServletPath() + result; + } + if ((result == null) || (result.equals(""))) { + result = "/"; + } + result = tools.util.StringUtil.replaceSubstring(result,"..",""); + result = tools.util.StringUtil.replaceSubstring(result,"//","\\"); + result = tools.util.StringUtil.replaceSubstring(result,"\\","/"); + result = tools.util.StringUtil.replaceSubstring(result,":",""); + + return (result); + + } + + + /** + * Determines the appropriate path to prepend resources with + * when generating directory listings. Depending on the behaviour of + * {@link #getRelativePath(HttpServletRequest)} this will change. + * @param request the request to determine the path for + * @return the prefix to apply to all resources in the listing. + */ + protected String getPathPrefix(final HttpServletRequest request) { + return request.getContextPath(); + } + + + /** + * Process a GET request for the specified resource. + * + * @param request The servlet request we are processing + * @param response The servlet response we are creating + * + * @exception IOException if an input/output error occurs + * @exception ServletException if a servlet-specified error occurs + */ + @Override + protected void doGet(HttpServletRequest request, + HttpServletResponse response) + throws IOException, ServletException { + + // Serve the requested resource, including the data content + serveResource(request, response, true); + + } + + + /** + * Process a HEAD request for the specified resource. + * + * @param request The servlet request we are processing + * @param response The servlet response we are creating + * + * @exception IOException if an input/output error occurs + * @exception ServletException if a servlet-specified error occurs + */ + @Override + protected void doHead(HttpServletRequest request, + HttpServletResponse response) + throws IOException, ServletException { + + // Serve the requested resource, without the data content + serveResource(request, response, false); + + } + + + /** + * Override default implementation to ensure that TRACE is correctly + * handled. + * + * @param req the {@link HttpServletRequest} object that + * contains the request the client made of + * the servlet + * + * @param resp the {@link HttpServletResponse} object that + * contains the response the servlet returns + * to the client + * + * @exception IOException if an input or output error occurs + * while the servlet is handling the + * OPTIONS request + * + * @exception ServletException if the request for the + * OPTIONS cannot be handled + */ + /*@Override + protected void doOptions(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + //("DOP 1"); + StringBuilder allow = new StringBuilder(); + // There is a doGet method + allow.append("GET, HEAD"); + // There is a doPost + allow.append(", POST"); + // There is a doPut + allow.append(", PUT"); + // There is a doDelete + allow.append(", DELETE"); + // Trace - assume disabled unless we can prove otherwise + if (req instanceof RequestFacade && + ((RequestFacade) req).getAllowTrace()) { + allow.append(", TRACE"); + } + // Always allow options + allow.append(", OPTIONS"); + + resp.setHeader("Allow", allow.toString()); + }*/ + + + /** + * Process a POST request for the specified resource. + * + * @param request The servlet request we are processing + * @param response The servlet response we are creating + * + * @exception IOException if an input/output error occurs + * @exception ServletException if a servlet-specified error occurs + */ + @Override + protected void doPost(HttpServletRequest request, + HttpServletResponse response) + throws IOException, ServletException { + doGet(request, response); + } + + + /** + * Process a PUT request for the specified resource. + * + * @param req The servlet request we are processing + * @param resp The servlet response we are creating + * + * @exception IOException if an input/output error occurs + * @exception ServletException if a servlet-specified error occurs + */ + @Override + protected void doPut(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + + String path = getRelativePath(req); + + ResourceObj ro = ResourceStore.lookup(path,req,resp,ResourceStore.WRITE); + if (ro == null)return; + if (ro == null) { + resp.sendError(HttpServletResponse.SC_FORBIDDEN); + return; + } + + + boolean exists = ro.exists(); + //(path + " EXISTSRE " + exists); + + //boolean result = true; + + // Temp. content file used to support partial PUT + //File contentFile = null; + + //Range range = parseContentRange(req, resp); + + InputStream resourceInputStream = null; + + // Append data specified in ranges to existing content for this + // resource - create a temp. file on the local filesystem to + // perform this operation + // Assume just one range is specified for now + //if (range != null) { + // contentFile = executePartialPut(req, range, path); + // resourceInputStream = new FileInputStream(contentFile); + // } else { + resourceInputStream = req.getInputStream(); + // } + + String ct = getServletContext().getMimeType(ro.getName()); + ro.contentType = ct; + ro.contentLength = req.getContentLength(); + ro.write(resourceInputStream); + + /*try { + Resource newResource = new Resource(resourceInputStream); + // FIXME: Add attributes + if (exists) { + resources.rebind(path, newResource); + } else { + resources.bind(path, newResource); + } + } catch(NamingException e) { + result = false; + }*/ + + //if (result) { + if (exists) { + resp.setStatus(HttpServletResponse.SC_NO_CONTENT); + } else { + resp.setStatus(HttpServletResponse.SC_CREATED); + } + // } else { + // resp.sendError(HttpServletResponse.SC_CONFLICT); + // } + + } + + + /** + * Handle a partial PUT. New content specified in request is appended to + * existing content in oldRevisionContent (if present). This code does + * not support simultaneous partial updates to the same resource. + */ + /*protected File executePartialPut(HttpServletRequest req, Range range, + String path) + throws IOException { + + // Append data specified in ranges to existing content for this + // resource - create a temp. file on the local filesystem to + // perform this operation + File tempDir = (File) getServletContext().getAttribute + (ServletContext.TEMPDIR); + // Convert all '/' characters to '.' in resourcePath + String convertedResourcePath = path.replace('/', '.'); + File contentFile = new File(tempDir, convertedResourcePath); + if (contentFile.createNewFile()) { + // Clean up contentFile when Tomcat is terminated + contentFile.deleteOnExit(); + } + + RandomAccessFile randAccessContentFile = + new RandomAccessFile(contentFile, "rw"); + + Resource oldResource = null; + try { + Object obj = resources.lookup(path); + if (obj instanceof Resource) + oldResource = (Resource) obj; + } catch (NamingException e) { + // Ignore + } + + // Copy data in oldRevisionContent to contentFile + if (oldResource != null) { + BufferedInputStream bufOldRevStream = + new BufferedInputStream(oldResource.streamContent(), + BUFFER_SIZE); + + int numBytesRead; + byte[] copyBuffer = new byte[BUFFER_SIZE]; + while ((numBytesRead = bufOldRevStream.read(copyBuffer)) != -1) { + randAccessContentFile.write(copyBuffer, 0, numBytesRead); + } + + bufOldRevStream.close(); + } + + randAccessContentFile.setLength(range.length); + + // Append data in request input stream to contentFile + randAccessContentFile.seek(range.start); + int numBytesRead; + byte[] transferBuffer = new byte[BUFFER_SIZE]; + BufferedInputStream requestBufInStream = + new BufferedInputStream(req.getInputStream(), BUFFER_SIZE); + while ((numBytesRead = requestBufInStream.read(transferBuffer)) != -1) { + randAccessContentFile.write(transferBuffer, 0, numBytesRead); + } + randAccessContentFile.close(); + requestBufInStream.close(); + + return contentFile; + + }*/ + + + /** + * Process a DELETE request for the specified resource. + * + * @param req The servlet request we are processing + * @param resp The servlet response we are creating + * + * @exception IOException if an input/output error occurs + * @exception ServletException if a servlet-specified error occurs + */ + @Override + protected void doDelete(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + /*if (readOnly) { + resp.sendError(HttpServletResponse.SC_FORBIDDEN); + return; + }*/ + + String path = getRelativePath(req); + ResourceObj ro = ResourceStore.lookup(path,req,resp,ResourceStore.WRITE); + if (ro == null)return; + + if (!ro.canWrite()) { + resp.sendError(HttpServletResponse.SC_FORBIDDEN); + return; + } + + boolean exists = ro.exists(); + + + /*try { + resources.lookup(path); + } catch (NamingException e) { + exists = false; + }*/ + + if (exists) { + boolean result = true; + try { + ro.delete(); + } catch (Exception e) { + result = false; + } + if (result) { + resp.setStatus(HttpServletResponse.SC_NO_CONTENT); + } else { + resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED); + } + } else { + resp.sendError(HttpServletResponse.SC_NOT_FOUND); + } + + } + + + /** + * Check if the conditions specified in the optional If headers are + * satisfied. + * + * @param request The servlet request we are processing + * @param response The servlet response we are creating + * @param resourceAttributes The resource information + * @return boolean true if the resource meets all the specified conditions, + * and false if any of the conditions is not satisfied, in which case + * request processing is stopped + */ + protected boolean checkIfHeaders(HttpServletRequest request, + HttpServletResponse response, + ResourceObj resourceAttributes) + throws IOException,CaimitoException { + + return checkIfMatch(request, response, resourceAttributes) + && checkIfModifiedSince(request, response, resourceAttributes) + && checkIfNoneMatch(request, response, resourceAttributes) + && checkIfUnmodifiedSince(request, response, resourceAttributes); + + } + + + /** + * URL rewriter. + * + * @param path Path which has to be rewritten + */ + protected String rewriteUrl(String path) { + return urlEncoder.encode( path ); + } + + + /** + * Display the size of a file. + */ + protected void displaySize(StringBuilder buf, int filesize) { + + int leftside = filesize / 1024; + int rightside = (filesize % 1024) / 103; // makes 1 digit + // To avoid 0.0 for non-zero file, we bump to 0.1 + if (leftside == 0 && rightside == 0 && filesize != 0) + rightside = 1; + buf.append(leftside).append(".").append(rightside); + buf.append(" KB"); + + } + + + /** + * Serve the specified resource, optionally including the data content. + * + * @param request The servlet request we are processing + * @param response The servlet response we are creating + * @param content Should the content be included? + * + * @exception IOException if an input/output error occurs + * @exception ServletException if a servlet-specified error occurs + */ + protected void serveResource(HttpServletRequest request, + HttpServletResponse response, + boolean content) + throws IOException, ServletException { + + boolean serveContent = content; + + // Identify the requested resource path + String path = getRelativePath(request); + ResourceObj ro = ResourceStore.lookup(path,request,response,ResourceStore.READ); + + if (ro == null)return; + + if (!ro.canRead()) { + response.sendError(HttpServletResponse.SC_FORBIDDEN); + return; + } + + if (debug > 0) { + if (serveContent) + log("DefaultServlet.serveResource: Serving resource '" + + path + "' headers and data"); + else + log("DefaultServlet.serveResource: Serving resource '" + + path + "' headers only"); + } + + // CacheEntry cacheEntry = resources.lookupCache(path); + + if (!ro.exists()) { + // Check if we're included so we can return the appropriate + // missing resource name in the error + String requestUri = (String) request.getAttribute( + RequestDispatcher.INCLUDE_REQUEST_URI); + if (requestUri == null) { + requestUri = request.getRequestURI(); + } else { + // We're included + // SRV.9.3 says we must throw a FNFE + throw new FileNotFoundException( + "defaultServlet.missingResource"); + } + + response.sendError(HttpServletResponse.SC_NOT_FOUND, + requestUri); + return; + } + + // If the resource is not a collection, and the resource path + // ends with "/" or "\", return NOT FOUND + if (!ro.isDirectory()) { + if (path.endsWith("/") || (path.endsWith("\\"))) { + // Check if we're included so we can return the appropriate + // missing resource name in the error + String requestUri = (String) request.getAttribute( + RequestDispatcher.INCLUDE_REQUEST_URI); + if (requestUri == null) { + requestUri = request.getRequestURI(); + } + response.sendError(HttpServletResponse.SC_NOT_FOUND, + requestUri); + return; + } + } + + boolean isError = + response.getStatus() >= HttpServletResponse.SC_BAD_REQUEST; + + // Check if the conditions specified in the optional If headers are + // satisfied. + if (!ro.isDirectory()) { + + // Checking If headers + boolean included = (request.getAttribute( + RequestDispatcher.INCLUDE_CONTEXT_PATH) != null); + if (!included && !isError && + !checkIfHeaders(request, response, ro)) { + return; + } + + } + + // Find content type. + String contentType = ro.getMimeType(); + if (contentType == null) { + contentType = getServletContext().getMimeType(ro.path); + ro.setMimeType(contentType); + } + + ArrayList ranges = null; + long contentLength = -1L; + + if (ro.isDirectory()) { + + // Skip directory listings if we have been configured to + // suppress them + if (!ro.listings()) { + response.sendError(HttpServletResponse.SC_NOT_FOUND, + request.getRequestURI()); + return; + } + contentType = "text/html;charset=UTF-8"; + + } else { + if (!isError) { + if (useAcceptRanges) { + // Accept ranges header + response.setHeader("Accept-Ranges", "bytes"); + } + + // Parse range specifier + ranges = parseRange(request, response, ro); + + // ETag header + response.setHeader("ETag", ro.getETag()); + + // Last-Modified header + response.setHeader("Last-Modified", + ro.getLastModifiedHttp()); + } + + // Get content length + contentLength = ro.getContentLength(); + // Special case for zero length files, which would cause a + // (silent) ISE when setting the output buffer size + if (contentLength == 0L) { + serveContent = false; + //("SERVER CONTENT = fale"); + } + + } +//(contentType + " serveContent " + serveContent); + ServletOutputStream ostream = null; + PrintWriter writer = null; + + if (serveContent) { + + // Trying to retrieve the servlet output stream + + try { + ostream = response.getOutputStream(); + } catch (IllegalStateException e) { + // If it fails, we try to get a Writer instead if we're + // trying to serve a text file + if ( (contentType == null) + || (contentType.startsWith("text")) + || (contentType.endsWith("xml")) + || (contentType.contains("/javascript")) ) { + writer = response.getWriter(); + // Cannot reliably serve partial content with a Writer + ranges = FULL; + } else { + throw e; + } + } + + } + + // Check to see if a Filter, Valve of wrapper has written some content. + // If it has, disable range requests and setting of a content length + // since neither can be done reliably. + ServletResponse r = response; + long contentWritten = 0; + while (r instanceof ServletResponseWrapper) { + r = ((ServletResponseWrapper) r).getResponse(); + } + if (r instanceof ResponseFacade) { + contentWritten = ((ResponseFacade) r).getContentWritten(); + } + if (contentWritten > 0) { + ranges = FULL; + } + + if ( (ro.isDirectory()) + || isError + || ( ((ranges == null) || (ranges.isEmpty())) + && (request.getHeader("Range") == null) ) + || (ranges == FULL) ) { + + // Set the appropriate output headers + if (contentType != null) { + if (debug > 0) + log("DefaultServlet.serveFile: contentType='" + + contentType + "'"); + response.setContentType(contentType); + } + //???(cacheEntry.resource != null) && + if ( (contentLength >= 0) + && (!serveContent || ostream != null)) { + if (debug > 0) + log("DefaultServlet.serveFile: contentLength=" + + contentLength); + // Don't set a content length if something else has already + // written to the response. + if (contentWritten == 0) { + if (contentLength < Integer.MAX_VALUE) { + response.setContentLength((int) contentLength); + } else { + // Set the content-length as String to be able to use a + // long + response.setHeader("content-length", + "" + contentLength); + } + } + } + + InputStream renderResult = null; + if (ro.isDirectory()) { + + if (serveContent) { + // Serve the directory browser + renderResult = render(getPathPrefix(request), ro,request); + } + + } + + // Copy the input stream to our output stream (if requested) + if (serveContent) { + try { + response.setBufferSize(output); + } catch (IllegalStateException e) { + // Silent catch + } + if (ostream != null ) { + if (!checkSendfile(request, response, ro, contentLength, null)) + copy(ro, renderResult, ostream); + } else { + //(writer + " SENDY FDIR " + renderResult); + copy(ro, renderResult, writer); + } + } + + } else { + + if ((ranges == null) || (ranges.isEmpty())) + return; + + // Partial content response. + + response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); + + if (ranges.size() == 1) { + + Range range = ranges.get(0); + response.addHeader("Content-Range", "bytes " + + range.start + + "-" + range.end + "/" + + range.length); + long length = range.end - range.start + 1; + if (length < Integer.MAX_VALUE) { + response.setContentLength((int) length); + } else { + // Set the content-length as String to be able to use a long + response.setHeader("content-length", "" + length); + } + + if (contentType != null) { + if (debug > 0) + log("DefaultServlet.serveFile: contentType='" + + contentType + "'"); + response.setContentType(contentType); + } + + if (serveContent) { + try { + response.setBufferSize(output); + } catch (IllegalStateException e) { + // Silent catch + } + if (ostream != null) { + if (!checkSendfile(request, response, ro, range.end - range.start + 1, range)) + copy(ro, ostream, range,request); + } else { + // we should not get here + throw new IllegalStateException(); + } + } + + } else { + + response.setContentType("multipart/byteranges; boundary=" + + mimeSeparation); + + if (serveContent) { + try { + response.setBufferSize(output); + } catch (IllegalStateException e) { + // Silent catch + } + if (ostream != null) { + copy(ro, ostream, ranges.iterator(), + contentType,request); + } else { + // we should not get here + throw new IllegalStateException(); + } + } + + } + + } + + } + + + /** + * Parse the content-range header. + * + * @param request The servlet request we are processing + * @param response The servlet response we are creating + * @return Range + */ + protected Range parseContentRange(HttpServletRequest request, + HttpServletResponse response) + throws IOException { + + // Retrieving the content-range header (if any is specified + String rangeHeader = request.getHeader("Content-Range"); + + if (rangeHeader == null) + return null; + + // bytes is the only range unit supported + if (!rangeHeader.startsWith("bytes")) { + response.sendError(HttpServletResponse.SC_BAD_REQUEST); + return null; + } + + rangeHeader = rangeHeader.substring(6).trim(); + + int dashPos = rangeHeader.indexOf('-'); + int slashPos = rangeHeader.indexOf('/'); + + if (dashPos == -1) { + response.sendError(HttpServletResponse.SC_BAD_REQUEST); + return null; + } + + if (slashPos == -1) { + response.sendError(HttpServletResponse.SC_BAD_REQUEST); + return null; + } + + Range range = new Range(); + + try { + range.start = Long.parseLong(rangeHeader.substring(0, dashPos)); + range.end = + Long.parseLong(rangeHeader.substring(dashPos + 1, slashPos)); + range.length = Long.parseLong + (rangeHeader.substring(slashPos + 1, rangeHeader.length())); + } catch (NumberFormatException e) { + response.sendError(HttpServletResponse.SC_BAD_REQUEST); + return null; + } + + if (!range.validate()) { + response.sendError(HttpServletResponse.SC_BAD_REQUEST); + return null; + } + + return range; + + } + + + /** + * Parse the range header. + * + * @param request The servlet request we are processing + * @param response The servlet response we are creating + * @return Vector of ranges + */ + protected ArrayList parseRange(HttpServletRequest request, + HttpServletResponse response, + ResourceObj resourceAttributes) throws CaimitoException,IOException { + + // Checking If-Range + String headerValue = request.getHeader("If-Range"); + + if (headerValue != null) { + + long headerValueTime = (-1L); + try { + headerValueTime = request.getDateHeader("If-Range"); + } catch (IllegalArgumentException e) { + // Ignore + } + + String eTag = resourceAttributes.getETag(); + long lastModified = resourceAttributes.getLastModified(); + + if (headerValueTime == (-1L)) { + + // If the ETag the client gave does not match the entity + // etag, then the entire entity is returned. + if (!eTag.equals(headerValue.trim())) + return FULL; + + } else { + + // If the timestamp of the entity the client got is older than + // the last modification date of the entity, the entire entity + // is returned. + if (lastModified > (headerValueTime + 1000)) + return FULL; + + } + + } + + long fileLength = resourceAttributes.getContentLength(); + + if (fileLength == 0) + return null; + + // Retrieving the range header (if any is specified + String rangeHeader = request.getHeader("Range"); + + if (rangeHeader == null) + return null; + // bytes is the only range unit supported (and I don't see the point + // of adding new ones). + if (!rangeHeader.startsWith("bytes")) { + response.addHeader("Content-Range", "bytes */" + fileLength); + response.sendError + (HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); + return null; + } + + rangeHeader = rangeHeader.substring(6); + + // Vector which will contain all the ranges which are successfully + // parsed. + ArrayList result = new ArrayList(); + StringTokenizer commaTokenizer = new StringTokenizer(rangeHeader, ","); + + // Parsing the range list + while (commaTokenizer.hasMoreTokens()) { + String rangeDefinition = commaTokenizer.nextToken().trim(); + + Range currentRange = new Range(); + currentRange.length = fileLength; + + int dashPos = rangeDefinition.indexOf('-'); + + if (dashPos == -1) { + response.addHeader("Content-Range", "bytes */" + fileLength); + response.sendError + (HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); + return null; + } + + if (dashPos == 0) { + + try { + long offset = Long.parseLong(rangeDefinition); + currentRange.start = fileLength + offset; + currentRange.end = fileLength - 1; + } catch (NumberFormatException e) { + response.addHeader("Content-Range", + "bytes */" + fileLength); + response.sendError + (HttpServletResponse + .SC_REQUESTED_RANGE_NOT_SATISFIABLE); + return null; + } + + } else { + + try { + currentRange.start = Long.parseLong + (rangeDefinition.substring(0, dashPos)); + if (dashPos < rangeDefinition.length() - 1) + currentRange.end = Long.parseLong + (rangeDefinition.substring + (dashPos + 1, rangeDefinition.length())); + else + currentRange.end = fileLength - 1; + } catch (NumberFormatException e) { + response.addHeader("Content-Range", + "bytes */" + fileLength); + response.sendError + (HttpServletResponse + .SC_REQUESTED_RANGE_NOT_SATISFIABLE); + return null; + } + + } + + if (!currentRange.validate()) { + response.addHeader("Content-Range", "bytes */" + fileLength); + response.sendError + (HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); + return null; + } + + result.add(currentRange); + } + + return result; + } + + + + /** + * Decide which way to render. HTML or XML. + */ + protected InputStream render(String contextPath, ResourceObj cacheEntry,HttpServletRequest request) + throws IOException, ServletException { + + //InputStream xsltInputStream = + // findXsltInputStream(cacheEntry.context); + + //if (xsltInputStream==null) { + return renderHtml(contextPath, cacheEntry,request); + //} + //return renderXml(contextPath, cacheEntry, xsltInputStream); + + } + + /** + * Return an InputStream to an HTML representation of the contents + * of this directory. + * + * @param contextPath Context path to which our internal paths are + * relative + */ + protected InputStream renderXml(String contextPath, + ResourceObj ro, + InputStream xsltInputStream) + throws IOException, ServletException { + + StringBuilder sb = new StringBuilder(); + + sb.append(""); + sb.append(""); + + sb.append(""); + + try { + + // Render the directory entries within this directory + Enumeration enumeration = + ro.list().elements(); + + // rewriteUrl(contextPath) is expensive. cache result for later reuse + String rewrittenContextPath = rewriteUrl(contextPath); + + while (enumeration.hasMoreElements()) { + + ResourceObj ncPair = enumeration.nextElement(); + String resourceName = ncPair.getName(); + String trimmed = resourceName/*.substring(trim)*/; + // if (trimmed.equalsIgnoreCase("WEB-INF") || + // trimmed.equalsIgnoreCase("META-INF") || + // trimmed.equalsIgnoreCase(localXsltFile)) + // continue; + + // if ((cacheEntry.name + trimmed).equals(contextXsltFile)) + // continue; + + // CacheEntry childCacheEntry = + // resources.lookupCache(cacheEntry.name + resourceName); + // if (!childCacheEntry.exists) { + // continue; + // } + + sb.append(""); + sb.append(RequestUtil.filter(trimmed)); + if (ncPair.isDirectory()) + sb.append("/"); + sb.append(""); + + } + + } catch (Exception e) { + // Something went wrong + throw new ServletException("Error accessing resource", e); + } + + sb.append(""); + + String readme = getReadme(ro); + + if (readme!=null) { + sb.append(""); + } + + + sb.append(""); + + + try { + TransformerFactory tFactory = TransformerFactory.newInstance(); + Source xmlSource = new StreamSource(new StringReader(sb.toString())); + Source xslSource = new StreamSource(xsltInputStream); + Transformer transformer = tFactory.newTransformer(xslSource); + + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + OutputStreamWriter osWriter = new OutputStreamWriter(stream, "UTF8"); + StreamResult out = new StreamResult(osWriter); + transformer.transform(xmlSource, out); + osWriter.flush(); + return (new ByteArrayInputStream(stream.toByteArray())); + } catch (TransformerException e) { + throw new ServletException("XSL transformer error", e); + } + } + + /** + * Return an InputStream to an HTML representation of the contents + * of this directory. + * + * @param contextPath Context path to which our internal paths are + * relative + */ + protected InputStream renderHtml(String contextPath, ResourceObj ro,HttpServletRequest request) + throws IOException, ServletException { + + String name = ro.path; + + // Prepare a writer to a buffered area + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + OutputStreamWriter osWriter = new OutputStreamWriter(stream, "UTF8"); + PrintWriter writer = new PrintWriter(osWriter); + + StringBuilder sb = new StringBuilder(); + + // rewriteUrl(contextPath) is expensive. cache result for later reuse + String rewrittenContextPath = rewriteUrl(contextPath); + + // Render the page header + sb.append("\r\n"); + sb.append("\r\n"); + sb.append(""); + sb.append(smgetString("directory.title", name,request)); + sb.append("\r\n"); + sb.append(" "); + sb.append("\r\n"); + sb.append(""); + sb.append("

"); + sb.append(smgetString("directory.title", name,request)); + + // Render the link to our parent (if required) + String parentDirectory = name; + if (parentDirectory.endsWith("/")) { + parentDirectory = + parentDirectory.substring(0, parentDirectory.length() - 1); + } + int slash = parentDirectory.lastIndexOf('/'); + if (slash >= 0) { + String parent = name.substring(0, slash); + sb.append(" - "); + sb.append(""); + sb.append(smgetString("directory.parent", parent,request)); + sb.append(""); + sb.append(""); + } + + sb.append("

"); + sb.append("
"); + + sb.append("\r\n"); + + // Render the column headings + sb.append("\r\n"); + sb.append("\r\n"); + sb.append("\r\n"); + sb.append("\r\n"); + sb.append(""); + + try { + + // Render the directory entries within this directory + Enumeration enumeration = + ro.list().elements(); + boolean shade = false; + while (enumeration.hasMoreElements()) { + + ResourceObj ncPair = enumeration.nextElement(); + String resourceName = ncPair.getName(); + //(ro.path + " GET 1 " + ncPair + ":" + resourceName); + String trimmed = resourceName/*.substring(trim)*/; + //if (trimmed.equalsIgnoreCase("WEB-INF") || + // trimmed.equalsIgnoreCase("META-INF")) + // continue; + + // CacheEntry childCacheEntry = + // resources.lookupCache(cacheEntry.name + resourceName); + //if (!childCacheEntry.exists) { + // continue; + //} + + sb.append("\r\n"); + shade = !shade; + + sb.append("\r\n"); + + sb.append("\r\n"); + + sb.append("\r\n"); + + sb.append("\r\n"); + } + + } catch (Exception e) { + // Something went wrong + throw new ServletException("Error accessing resource", e); + } + + // Render the page footer + sb.append("
"); + sb.append(smgetString("directory.filename",request)); + sb.append(""); + sb.append(smgetString("directory.size",request)); + sb.append(""); + sb.append(smgetString("directory.lastModified",request)); + sb.append("
  \r\n"); + sb.append(""); + sb.append(RequestUtil.filter(trimmed)); + if (ncPair.isDirectory()) + sb.append("/"); + sb.append(""); + if (ncPair.isDirectory()) + sb.append(" "); + else + sb.append(renderSize(ncPair.getContentLength())); + sb.append(""); + sb.append(ncPair.getLastModifiedHttp()); + sb.append("
\r\n"); + + sb.append("
"); + + String readme = getReadme(ro); + if (readme!=null) { + sb.append(readme); + sb.append("
"); + } + + sb.append("

").append(CaimitoConfig.serverinfo).append("

"); + sb.append("\r\n"); + sb.append("\r\n"); + + // Return an input stream to the underlying bytes + writer.write(sb.toString()); + writer.flush(); + return (new ByteArrayInputStream(stream.toByteArray())); + + } + + + /** + * Render the specified file size (in bytes). + * + * @param size File size (in bytes) + */ + protected String renderSize(long size) { + + long leftSide = size / 1024; + long rightSide = (size % 1024) / 103; // Makes 1 digit + if ((leftSide == 0) && (rightSide == 0) && (size > 0)) + rightSide = 1; + + return ("" + leftSide + "." + rightSide + " kb"); + + } + + + /** + * Get the readme file as a string. + */ + protected String getReadme(ResourceObj directory) + throws CaimitoException,IOException { + ResourceObj rmf = directory.getReadmeFile(); + if (rmf != null) { + try { + //Object obj = directory.lookup(readmeFile); + // if ((obj != null) && (obj instanceof Resource)) { + StringWriter buffer = new StringWriter(); + InputStream is = rmf.getInputStream(); + //((Resource) obj).streamContent(); + copyRange(new InputStreamReader(is), + new PrintWriter(buffer)); + return buffer.toString(); + // } + } catch (Exception e) { + if (debug > 10) + log("readme '" + readmeFile + "' not found", e); + + return null; + } + } + + return null; + } + + + /** + * Return the xsl template inputstream (if possible) + */ + protected InputStream findXsltInputStream(DirContext directory) + throws IOException { + + if (localXsltFile != null) { + try { + Object obj = directory.lookup(localXsltFile); + if ((obj != null) && (obj instanceof Resource)) { + InputStream is = ((Resource) obj).streamContent(); + if (is != null) + return is; + } + } catch (NamingException e) { + if (debug > 10) + log("localXsltFile '" + localXsltFile + "' not found", e); + } + } + + if (contextXsltFile != null) { + InputStream is = + getServletContext().getResourceAsStream(contextXsltFile); + if (is != null) + return is; + + if (debug > 10) + log("contextXsltFile '" + contextXsltFile + "' not found"); + } + + /* Open and read in file in one fell swoop to reduce chance + * chance of leaving handle open. + */ + if (globalXsltFile!=null) { + FileInputStream fis = null; + + try { + File f = new File(globalXsltFile); + if (f.exists()){ + fis =new FileInputStream(f); + byte b[] = new byte[(int)f.length()]; /* danger! */ + fis.read(b); + return new ByteArrayInputStream(b); + } + } finally { + if (fis!=null) + fis.close(); + } + } + + return null; + + } + + + // -------------------------------------------------------- protected Methods + + + /** + * Check if sendfile can be used. + */ + protected boolean checkSendfile(HttpServletRequest request, + HttpServletResponse response, + ResourceObj entry, + long length, Range range) { + /*if ((sendfileSize > 0) + + && ((length > sendfileSize) || (entry.getContentLength() > 0)) + && (entry.getCanonicalPath() != null) + && (Boolean.TRUE == request.getAttribute("org.apache.tomcat.sendfile.support")) + && (request.getClass().getName().equals("org.apache.catalina.connector.RequestFacade")) + && (response.getClass().getName().equals("org.apache.catalina.connector.ResponseFacade"))) { + request.setAttribute("org.apache.tomcat.sendfile.filename", entry.getCanonicalPath()); + if (range == null) { + request.setAttribute("org.apache.tomcat.sendfile.start", Long.valueOf(0L)); + request.setAttribute("org.apache.tomcat.sendfile.end", Long.valueOf(length)); + } else { + request.setAttribute("org.apache.tomcat.sendfile.start", Long.valueOf(range.start)); + request.setAttribute("org.apache.tomcat.sendfile.end", Long.valueOf(range.end + 1)); + } + return true; + }*/ + return false; + } + + + /** + * Check if the if-match condition is satisfied. + * + * @param request The servlet request we are processing + * @param response The servlet response we are creating + * @param resourceAttributes File object + * @return boolean true if the resource meets the specified condition, + * and false if the condition is not satisfied, in which case request + * processing is stopped + */ + protected boolean checkIfMatch(HttpServletRequest request, + HttpServletResponse response, + ResourceObj resourceAttributes) + throws CaimitoException,IOException { + + String eTag = resourceAttributes.getETag(); + String headerValue = request.getHeader("If-Match"); + if (headerValue != null) { + if (headerValue.indexOf('*') == -1) { + + StringTokenizer commaTokenizer = new StringTokenizer + (headerValue, ","); + boolean conditionSatisfied = false; + + while (!conditionSatisfied && commaTokenizer.hasMoreTokens()) { + String currentToken = commaTokenizer.nextToken(); + if (currentToken.trim().equals(eTag)) + conditionSatisfied = true; + } + + // If none of the given ETags match, 412 Precodition failed is + // sent back + if (!conditionSatisfied) { + response.sendError + (HttpServletResponse.SC_PRECONDITION_FAILED); + return false; + } + + } + } + return true; + + } + + + /** + * Check if the if-modified-since condition is satisfied. + * + * @param request The servlet request we are processing + * @param response The servlet response we are creating + * @param resourceAttributes File object + * @return boolean true if the resource meets the specified condition, + * and false if the condition is not satisfied, in which case request + * processing is stopped + */ + protected boolean checkIfModifiedSince(HttpServletRequest request, + HttpServletResponse response, + ResourceObj resourceAttributes) { + try { + long headerValue = request.getDateHeader("If-Modified-Since"); + long lastModified = resourceAttributes.getLastModified(); + if (headerValue != -1) { + + // If an If-None-Match header has been specified, if modified since + // is ignored. + if ((request.getHeader("If-None-Match") == null) + && (lastModified < headerValue + 1000)) { + // The entity has not been modified since the date + // specified by the client. This is not an error case. + response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); + response.setHeader("ETag", resourceAttributes.getETag()); + + return false; + } + } + } catch (Exception illegalArgument) { + return true; + } + return true; + + } + + + /** + * Check if the if-none-match condition is satisfied. + * + * @param request The servlet request we are processing + * @param response The servlet response we are creating + * @param resourceAttributes File object + * @return boolean true if the resource meets the specified condition, + * and false if the condition is not satisfied, in which case request + * processing is stopped + */ + protected boolean checkIfNoneMatch(HttpServletRequest request, + HttpServletResponse response, + ResourceObj resourceAttributes) + throws CaimitoException,IOException { + + String eTag = resourceAttributes.getETag(); + String headerValue = request.getHeader("If-None-Match"); + if (headerValue != null) { + + boolean conditionSatisfied = false; + + if (!headerValue.equals("*")) { + + StringTokenizer commaTokenizer = + new StringTokenizer(headerValue, ","); + + while (!conditionSatisfied && commaTokenizer.hasMoreTokens()) { + String currentToken = commaTokenizer.nextToken(); + if (currentToken.trim().equals(eTag)) + conditionSatisfied = true; + } + + } else { + conditionSatisfied = true; + } + + if (conditionSatisfied) { + + // For GET and HEAD, we should respond with + // 304 Not Modified. + // For every other method, 412 Precondition Failed is sent + // back. + if ( ("GET".equals(request.getMethod())) + || ("HEAD".equals(request.getMethod())) ) { + response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); + response.setHeader("ETag", eTag); + + return false; + } + response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED); + return false; + } + } + return true; + + } + + + /** + * Check if the if-unmodified-since condition is satisfied. + * + * @param request The servlet request we are processing + * @param response The servlet response we are creating + * @param resourceAttributes File object + * @return boolean true if the resource meets the specified condition, + * and false if the condition is not satisfied, in which case request + * processing is stopped + */ + protected boolean checkIfUnmodifiedSince(HttpServletRequest request, + HttpServletResponse response, + ResourceObj resourceAttributes) + throws CaimitoException { + try { + long lastModified = resourceAttributes.getLastModified(); + long headerValue = request.getDateHeader("If-Unmodified-Since"); + if (headerValue != -1) { + if ( lastModified >= (headerValue + 1000)) { + // The entity has not been modified since the date + // specified by the client. This is not an error case. + response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED); + return false; + } + } + } catch(Exception illegalArgument) { + return true; + } + return true; + + } + + + /** + * Copy the contents of the specified input stream to the specified + * output stream, and ensure that both streams are closed before returning + * (even in the face of an exception). + * + * @param cacheEntry The cache entry for the source resource + * @param is The input stream to read the source resource from + * @param ostream The output stream to write to + * + * @exception IOException if an input/output error occurs + */ + protected void copy(ResourceObj cacheEntry, InputStream is, + ServletOutputStream ostream) + throws CaimitoException,IOException { + + IOException exception = null; + InputStream resourceInputStream = null; + + // Optimization: If the binary content has already been loaded, send + // it directly + //("cacheEntry.resource 1 " + cacheEntry); + if (!cacheEntry.isDirectory() && cacheEntry.getContentLength() >0) { + /*byte buffer[] = cacheEntry.resource.getContent(); + if (buffer != null) { + //("cacheEntry.resource 2 " + cacheEntry); + + ostream.write(buffer, 0, buffer.length); + return; + }*/ + resourceInputStream = cacheEntry.getInputStream(); + } else { + resourceInputStream = is; + } + + InputStream istream = new BufferedInputStream + (resourceInputStream, input); + + // Copy the input stream to the output stream + exception = copyRange(istream, ostream); + + // Clean up the input stream + istream.close(); + + // Rethrow any exception that has occurred + if (exception != null) + throw exception; + + } + + + /** + * Copy the contents of the specified input stream to the specified + * output stream, and ensure that both streams are closed before returning + * (even in the face of an exception). + * + * @param cacheEntry The cache entry for the source resource + * @param is The input stream to read the source resource from + * @param writer The writer to write to + * + * @exception IOException if an input/output error occurs + */ + protected void copy(ResourceObj cacheEntry, InputStream is, PrintWriter writer) + throws CaimitoException,IOException { + + IOException exception = null; + + InputStream resourceInputStream = null; + if (!cacheEntry.isDirectory() && cacheEntry.getContentLength() > 0) { + resourceInputStream = cacheEntry.getInputStream(); + } else { + resourceInputStream = is; + } + + Reader reader; + if (fileEncoding == null) { + reader = new InputStreamReader(resourceInputStream); + } else { + reader = new InputStreamReader(resourceInputStream, + fileEncoding); + } + + // Copy the input stream to the output stream + exception = copyRange(reader, writer); + + // Clean up the reader + reader.close(); + + // Rethrow any exception that has occurred + if (exception != null) + throw exception; + + } + + + /** + * Copy the contents of the specified input stream to the specified + * output stream, and ensure that both streams are closed before returning + * (even in the face of an exception). + * + * @param cacheEntry The cache entry for the source resource + * @param ostream The output stream to write to + * @param range Range the client wanted to retrieve + * @exception IOException if an input/output error occurs + */ + protected void copy(ResourceObj cacheEntry, ServletOutputStream ostream, + Range range,HttpServletRequest request) + throws CaimitoException,IOException { + + IOException exception = null; + + InputStream resourceInputStream = cacheEntry.getInputStream(); + InputStream istream = + new BufferedInputStream(resourceInputStream, input); + exception = copyRange(istream, ostream, range.start, range.end,request); + + // Clean up the input stream + istream.close(); + + // Rethrow any exception that has occurred + if (exception != null) + throw exception; + + } + + + /** + * Copy the contents of the specified input stream to the specified + * output stream, and ensure that both streams are closed before returning + * (even in the face of an exception). + * + * @param cacheEntry The cache entry for the source resource + * @param ostream The output stream to write to + * @param ranges Enumeration of the ranges the client wanted to retrieve + * @param contentType Content type of the resource + * @exception IOException if an input/output error occurs + */ + protected void copy(ResourceObj cacheEntry, ServletOutputStream ostream, + Iterator ranges, String contentType,HttpServletRequest request) + throws CaimitoException,IOException { + + IOException exception = null; + + while ( (exception == null) && (ranges.hasNext()) ) { + + InputStream resourceInputStream = cacheEntry.getInputStream(); + InputStream istream = + new BufferedInputStream(resourceInputStream, input); + + Range currentRange = ranges.next(); + + // Writing MIME header. + ostream.println(); + ostream.println("--" + mimeSeparation); + if (contentType != null) + ostream.println("Content-Type: " + contentType); + ostream.println("Content-Range: bytes " + currentRange.start + + "-" + currentRange.end + "/" + + currentRange.length); + ostream.println(); + + // Printing content + exception = copyRange(istream, ostream, currentRange.start, + currentRange.end,request); + + istream.close(); + + } + + ostream.println(); + ostream.print("--" + mimeSeparation + "--"); + + // Rethrow any exception that has occurred + if (exception != null) + throw exception; + + } + + + /** + * Copy the contents of the specified input stream to the specified + * output stream, and ensure that both streams are closed before returning + * (even in the face of an exception). + * + * @param istream The input stream to read from + * @param ostream The output stream to write to + * @return Exception which occurred during processing + */ + protected IOException copyRange(InputStream istream, + ServletOutputStream ostream) { + + // Copy the input stream to the output stream + IOException exception = null; + byte buffer[] = new byte[input]; + int len = buffer.length; + while (true) { + try { + len = istream.read(buffer); + if (len == -1) + break; + ostream.write(buffer, 0, len); + } catch (IOException e) { + exception = e; + len = -1; + break; + } + } + return exception; + + } + + + /** + * Copy the contents of the specified input stream to the specified + * output stream, and ensure that both streams are closed before returning + * (even in the face of an exception). + * + * @param reader The reader to read from + * @param writer The writer to write to + * @return Exception which occurred during processing + */ + protected IOException copyRange(Reader reader, PrintWriter writer) { + + // Copy the input stream to the output stream + IOException exception = null; + char buffer[] = new char[input]; + int len = buffer.length; + while (true) { + try { + len = reader.read(buffer); + if (len == -1) + break; + writer.write(buffer, 0, len); + } catch (IOException e) { + exception = e; + len = -1; + break; + } + } + return exception; + + } + + + /** + * Copy the contents of the specified input stream to the specified + * output stream, and ensure that both streams are closed before returning + * (even in the face of an exception). + * + * @param istream The input stream to read from + * @param ostream The output stream to write to + * @param start Start of the range which will be copied + * @param end End of the range which will be copied + * @return Exception which occurred during processing + */ + protected IOException copyRange(InputStream istream, + ServletOutputStream ostream, + long start, long end,HttpServletRequest request) { + + if (debug > 10) + log("Serving bytes:" + start + "-" + end); + + long skipped = 0; + try { + skipped = istream.skip(start); + } catch (IOException e) { + return e; + } + if (skipped < start) { + return new IOException(smgetString("defaultservlet.skipfail", + ("" +skipped),request)); + } + + IOException exception = null; + long bytesToRead = end - start + 1; + + byte buffer[] = new byte[input]; + int len = buffer.length; + while ( (bytesToRead > 0) && (len >= buffer.length)) { + try { + len = istream.read(buffer); + if (bytesToRead >= len) { + ostream.write(buffer, 0, len); + bytesToRead -= len; + } else { + ostream.write(buffer, 0, (int) bytesToRead); + bytesToRead = 0; + } + } catch (IOException e) { + exception = e; + len = -1; + } + if (len < buffer.length) + break; + } + + return exception; + + } + + + // ------------------------------------------------------ Range Inner Class + + + protected static class Range { + + public long start; + public long end; + public long length; + + /** + * Validate range. + */ + public boolean validate() { + if (end >= length) + end = length - 1; + return (start >= 0) && (end >= 0) && (start <= end) && (length > 0); + } + } +} diff --git a/source/ngasi/caimito/CaimitoException.java b/source/ngasi/caimito/CaimitoException.java old mode 100644 new mode 100755 index fcd89f3..b4b0474 --- a/source/ngasi/caimito/CaimitoException.java +++ b/source/ngasi/caimito/CaimitoException.java @@ -59,4 +59,4 @@ public static void throwException(Throwable e)throws CaimitoException{ public void throwIt()throws CaimitoException{ throw this; } -} \ No newline at end of file +} diff --git a/source/ngasi/caimito/CaimitoUtil.java b/source/ngasi/caimito/CaimitoUtil.java old mode 100644 new mode 100755 diff --git a/source/ngasi/caimito/CaimitoWebdavServlet.java b/source/ngasi/caimito/CaimitoWebdavServlet.java old mode 100644 new mode 100755 index 2c63ddf..25b09e9 --- a/source/ngasi/caimito/CaimitoWebdavServlet.java +++ b/source/ngasi/caimito/CaimitoWebdavServlet.java @@ -1,3458 +1,3457 @@ -/* - Copyright (c) 2011-2012, the Caimito project (http://caimito.ngasi.com/). All rights reserved. -Apache Software License 2.0 -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WebAppShowCase -OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package ngasi.caimito; - - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.StringReader; -import java.io.StringWriter; -import java.io.Writer; -import java.nio.charset.Charset; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Locale; -import java.util.Stack; -import java.util.TimeZone; -import java.util.Vector; - -import javax.naming.NameClassPair; -import javax.naming.NamingEnumeration; -import javax.naming.NamingException; -import javax.naming.directory.DirContext; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.UnavailableException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import org.apache.catalina.util.DOMWriter; -import org.apache.catalina.util.MD5Encoder; -import org.apache.catalina.util.XMLWriter; -import org.apache.naming.resources.CacheEntry; -import org.apache.naming.resources.Resource; -import org.apache.naming.resources.ResourceAttributes; -import org.apache.tomcat.util.http.FastHttpDateFormat; -import org.apache.tomcat.util.http.RequestUtil; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.EntityResolver; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.apache.catalina.servlets.*; -import ngasi.caimito.resource.*; - - - -/** - * Servlet which adds support for WebDAV level 2. All the basic HTTP requests - * are handled by the DefaultServlet. The WebDAVServlet must not be used as the - * default servlet (ie mapped to '/') as it will not work in this configuration. - *

- * Mapping a subpath (e.g. /webdav/* to this servlet has the effect - * of re-mounting the entire web application under that sub-path, with WebDAV - * access to all the resources. This WEB-INF and META-INF - * directories are protected in this re-mounted resource tree. - *

- * To enable WebDAV for a context add the following to web.xml: - *

- * <servlet>
- *  <servlet-name>webdav</servlet-name>
- *  <servlet-class>org.apache.catalina.servlets.WebdavServlet</servlet-class>
- *    <init-param>
- *      <param-name>debug</param-name>
- *      <param-value>0</param-value>
- *    </init-param>
- *    <init-param>
- *      <param-name>listings</param-name>
- *      <param-value>false</param-value>
- *    </init-param>
- *  </servlet>
- *  <servlet-mapping>
- *    <servlet-name>webdav</servlet-name>
- *    <url-pattern>/*</url-pattern>
- *  </servlet-mapping>
- * 
- * This will enable read only access. To enable read-write access add: - *
- *  <init-param>
- *    <param-name>readonly</param-name>
- *    <param-value>false</param-value>
- *  </init-param>
- * 
- * To make the content editable via a different URL, use the following - * mapping: - *
- *  <servlet-mapping>
- *    <servlet-name>webdav</servlet-name>
- *    <url-pattern>/webdavedit/*</url-pattern>
- *  </servlet-mapping>
- * 
- * By default access to /WEB-INF and META-INF are not available via WebDAV. To - * enable access to these URLs, use add: - *
- *  <init-param>
- *    <param-name>allowSpecialPaths</param-name>
- *    <param-value>true</param-value>
- *  </init-param>
- * 
- * Don't forget to secure access appropriately to the editing URLs, especially - * if allowSpecialPaths is used. With the mapping configuration above, the - * context will be accessible to normal users as before. Those users with the - * necessary access will be able to edit content available via - * http://host:port/context/content using - * http://host:port/context/webdavedit/content - * - * @author Remy Maucherat - * @version $Id: WebdavServlet.java 1239053 2012-02-01 10:52:00Z markt $ - */ - -public class CaimitoWebdavServlet - extends CaimitoDefaultServlet { - - private static final long serialVersionUID = 1L; - - - // -------------------------------------------------------------- Constants - - private static final String METHOD_PROPFIND = "PROPFIND"; - private static final String METHOD_PROPPATCH = "PROPPATCH"; - private static final String METHOD_MKCOL = "MKCOL"; - private static final String METHOD_COPY = "COPY"; - private static final String METHOD_MOVE = "MOVE"; - private static final String METHOD_LOCK = "LOCK"; - private static final String METHOD_UNLOCK = "UNLOCK"; - - - /** - * PROPFIND - Specify a property mask. - */ - private static final int FIND_BY_PROPERTY = 0; - - - /** - * PROPFIND - Display all properties. - */ - private static final int FIND_ALL_PROP = 1; - - - /** - * PROPFIND - Return property names. - */ - private static final int FIND_PROPERTY_NAMES = 2; - - - /** - * Create a new lock. - */ - private static final int LOCK_CREATION = 0; - - - /** - * Refresh lock. - */ - private static final int LOCK_REFRESH = 1; - - - /** - * Default lock timeout value. - */ - private static final int DEFAULT_TIMEOUT = 3600; - - - /** - * Maximum lock timeout. - */ - private static final int MAX_TIMEOUT = 604800; - - - /** - * Default namespace. - */ - protected static final String DEFAULT_NAMESPACE = "DAV:"; - - - /** - * Simple date format for the creation date ISO representation (partial). - */ - protected static final SimpleDateFormat creationDateFormat = - new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); - - - /** - * MD5 message digest provider. - */ - protected static MessageDigest md5Helper; - - - /** - * The MD5 helper object for this class. - */ - protected static final MD5Encoder md5Encoder = new MD5Encoder(); - - - - static { - creationDateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); - } - - - // ----------------------------------------------------- Instance Variables - - - /** - * Repository of the locks put on single resources. - *

- * Key : path
- * Value : LockInfo - */ - private Hashtable resourceLocks = - new Hashtable(); - - - /** - * Repository of the lock-null resources. - *

- * Key : path of the collection containing the lock-null resource
- * Value : Vector of lock-null resource which are members of the - * collection. Each element of the Vector is the path associated with - * the lock-null resource. - */ - private Hashtable> lockNullResources = - new Hashtable>(); - - - /** - * Vector of the heritable locks. - *

- * Key : path
- * Value : LockInfo - */ - private Vector collectionLocks = new Vector(); - - - /** - * Secret information used to generate reasonably secure lock ids. - */ - private String secret = "catalina"; - - - /** - * Default depth in spec is infinite. Limit depth to 3 by default as - * infinite depth makes operations very expensive. - */ - private int maxDepth = 3; - - - /** - * Is access allowed via WebDAV to the special paths (/WEB-INF and - * /META-INF)? - */ - private boolean allowSpecialPaths = false; - - - // --------------------------------------------------------- Public Methods - - - /** - * Initialize this servlet. - */ - @Override - public void init() - throws ServletException { - - super.init(); - - if (getServletConfig().getInitParameter("secret") != null) - secret = getServletConfig().getInitParameter("secret"); - - if (getServletConfig().getInitParameter("maxDepth") != null) - maxDepth = Integer.parseInt( - getServletConfig().getInitParameter("maxDepth")); - - if (getServletConfig().getInitParameter("allowSpecialPaths") != null) - allowSpecialPaths = Boolean.parseBoolean( - getServletConfig().getInitParameter("allowSpecialPaths")); - - // Load the MD5 helper used to calculate signatures. - try { - md5Helper = MessageDigest.getInstance("MD5"); - } catch (NoSuchAlgorithmException e) { - throw new UnavailableException("No MD5"); - } - - String rootPath = getServletConfig().getServletContext().getRealPath("/"); - CaimitoConfig.caimitoroot = rootPath; - //(rootPath + " YELLOW ini " + CaimitoConfig.caimitoroot); - CaimitoConfig.init(); - - } - - - // ------------------------------------------------------ Protected Methods - - - /** - * Return JAXP document builder instance. - */ - protected DocumentBuilder getDocumentBuilder() - throws ServletException { - DocumentBuilder documentBuilder = null; - DocumentBuilderFactory documentBuilderFactory = null; - try { - documentBuilderFactory = DocumentBuilderFactory.newInstance(); - documentBuilderFactory.setNamespaceAware(true); - documentBuilderFactory.setExpandEntityReferences(false); - documentBuilder = documentBuilderFactory.newDocumentBuilder(); - documentBuilder.setEntityResolver( - new WebdavResolver(this.getServletContext())); - } catch(ParserConfigurationException e) { - throw new ServletException - ("webdavservlet.jaxpfailed"); - } - return documentBuilder; - } - - - /** - * Handles the special WebDAV methods. - */ - @Override - protected void service(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - final String path = getRelativePath(req); - - // Block access to special subdirectories. - // DefaultServlet assumes it services resources from the root of the web app - // and doesn't add any special path protection - // WebdavServlet remounts the webapp under a new path, so this check is - // necessary on all methods (including GET). - // if (isSpecialPath(path)) { - // resp.sendError(WebdavServletStatus.SC_NOT_FOUND); - // return; - //} - - final String method = req.getMethod(); - //(method + " SEEERVICE CAMITO WEBDAV " + path); - - if (debug > 0) { - log("[" + method + "] " + path); - } - - if (method.equals(METHOD_PROPFIND)) { - doPropfind(req, resp); - } else if (method.equals(METHOD_PROPPATCH)) { - doProppatch(req, resp); - } else if (method.equals(METHOD_MKCOL)) { - doMkcol(req, resp); - } else if (method.equals(METHOD_COPY)) { - doCopy(req, resp); - } else if (method.equals(METHOD_MOVE)) { - doMove(req, resp); - } else if (method.equals(METHOD_LOCK)) { - doLock(req, resp); - } else if (method.equals(METHOD_UNLOCK)) { - doUnlock(req, resp); - } else { - // DefaultServlet processing - super.service(req, resp); - } - - } - - - /** - * Checks whether a given path refers to a resource under - * WEB-INF or META-INF. - * @param path the full path of the resource being accessed - * @return true if the resource specified is under a special path - */ - private final boolean isSpecialPath(final String path) { - return !allowSpecialPaths && ( - path.toUpperCase(Locale.ENGLISH).startsWith("/WEB-INF") || - path.toUpperCase(Locale.ENGLISH).startsWith("/META-INF")); - } - - - /** - * Check if the conditions specified in the optional If headers are - * satisfied. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * @param resourceAttributes The resource information - * @return boolean true if the resource meets all the specified conditions, - * and false if any of the conditions is not satisfied, in which case - * request processing is stopped - */ - /*@Override - protected boolean checkIfHeaders(HttpServletRequest request, - HttpServletResponse response, - ResourceAttributes resourceAttributes) - throws IOException { - - if (!super.checkIfHeaders(request, response, resourceAttributes)) - return false; - - // TODO : Checking the WebDAV If header - return true; - - }*/ - - - /** - * Override the DefaultServlet implementation and only use the PathInfo. If - * the ServletPath is non-null, it will be because the WebDAV servlet has - * been mapped to a url other than /* to configure editing at different url - * than normal viewing. - * - * @param request The servlet request we are processing - */ - @Override - protected String getRelativePath(HttpServletRequest request) { - // Are we being processed by a RequestDispatcher.include()? - if (request.getAttribute( - RequestDispatcher.INCLUDE_REQUEST_URI) != null) { - String result = (String) request.getAttribute( - RequestDispatcher.INCLUDE_PATH_INFO); - if ((result == null) || (result.equals(""))) - result = "/"; - /* result = tools.util.StringUtil.replaceSubstring(result,"..",""); - result = tools.util.StringUtil.replaceSubstring(result,"//","\\"); - result = tools.util.StringUtil.replaceSubstring(result,"\\","/"); - result = tools.util.StringUtil.replaceSubstring(result,":",""); -*/ - result = CaimitoUtil.normalize(result); - return (result); - } - - // No, extract the desired path directly from the request - String result = request.getPathInfo(); - if ((result == null) || (result.equals(""))) { - result = "/"; - } - /* - result = tools.util.StringUtil.replaceSubstring(result,"..",""); - result = tools.util.StringUtil.replaceSubstring(result,"//","\\"); - result = tools.util.StringUtil.replaceSubstring(result,"\\","/"); - result = tools.util.StringUtil.replaceSubstring(result,":",""); -*/ - result = CaimitoUtil.normalize(result); - - return (result); - - } - - - /** - * Determines the prefix for standard directory GET listings. - */ - @Override - protected String getPathPrefix(final HttpServletRequest request) { - // Repeat the servlet path (e.g. /webdav/) in the listing path - String contextPath = request.getContextPath(); - if (request.getServletPath() != null) { - contextPath = contextPath + request.getServletPath(); - } - return contextPath; - } - - - /** - * OPTIONS Method. - * - * @param req The request - * @param resp The response - * @throws ServletException If an error occurs - * @throws IOException If an IO error occurs - */ - @Override - protected void doOptions(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - resp.addHeader("DAV", "1,2"); - - StringBuilder methodsAllowed = determineMethodsAllowed(req,resp); - //(methodsAllowed + " DOP 2"); - - resp.addHeader("Allow", methodsAllowed.toString()); - resp.addHeader("MS-Author-Via", "DAV"); - - } - - - /** - * PROPFIND Method. - */ - protected void doPropfind(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - - - String path = getRelativePath(req); - if (path.endsWith("/")) - path = path.substring(0, path.length() - 1); - - ResourceObj ro = ResourceStore.lookup(path,req,resp,ResourceStore.READ); - if (ro == null)return; - - if (!ro.listings()) { - // Get allowed methods - StringBuilder methodsAllowed = determineMethodsAllowed( req,resp); - - resp.addHeader("Allow", methodsAllowed.toString()); - resp.sendError(WebdavServletStatus.SC_METHOD_NOT_ALLOWED); - return; - } - - // Properties which are to be displayed. - Vector properties = null; - // Propfind depth - int depth = maxDepth; - // Propfind type - int type = FIND_ALL_PROP; - - String depthStr = req.getHeader("Depth"); - - if (depthStr == null) { - depth = maxDepth; - } else { - if (depthStr.equals("0")) { - depth = 0; - } else if (depthStr.equals("1")) { - depth = 1; - } else if (depthStr.equals("infinity")) { - depth = maxDepth; - } - } - - Node propNode = null; - - if (req.getContentLength() > 0) { - DocumentBuilder documentBuilder = getDocumentBuilder(); - - try { - Document document = documentBuilder.parse - (new InputSource(req.getInputStream())); - - // Get the root element of the document - Element rootElement = document.getDocumentElement(); - NodeList childList = rootElement.getChildNodes(); - - for (int i=0; i < childList.getLength(); i++) { - Node currentNode = childList.item(i); - switch (currentNode.getNodeType()) { - case Node.TEXT_NODE: - break; - case Node.ELEMENT_NODE: - if (currentNode.getNodeName().endsWith("prop")) { - type = FIND_BY_PROPERTY; - propNode = currentNode; - } - if (currentNode.getNodeName().endsWith("propname")) { - type = FIND_PROPERTY_NAMES; - } - if (currentNode.getNodeName().endsWith("allprop")) { - type = FIND_ALL_PROP; - } - break; - } - } - } catch (SAXException e) { - // Something went wrong - bad request - resp.sendError(WebdavServletStatus.SC_BAD_REQUEST); - } catch (IOException e) { - // Something went wrong - bad request - resp.sendError(WebdavServletStatus.SC_BAD_REQUEST); - } - } - - //(path + " PROP FINDE TYPE " + type ); - if (type == FIND_BY_PROPERTY) { - properties = new Vector(); - // propNode must be non-null if type == FIND_BY_PROPERTY - @SuppressWarnings("null") - NodeList childList = propNode.getChildNodes(); - - for (int i=0; i < childList.getLength(); i++) { - Node currentNode = childList.item(i); - switch (currentNode.getNodeType()) { - case Node.TEXT_NODE: - break; - case Node.ELEMENT_NODE: - String nodeName = currentNode.getNodeName(); - String propertyName = null; - if (nodeName.indexOf(':') != -1) { - propertyName = nodeName.substring - (nodeName.indexOf(':') + 1); - } else { - propertyName = nodeName; - } - // href is a live property which is handled differently - properties.addElement(propertyName); - break; - } - } - - } - - boolean exists = ro.exists(); - /*Object object = null; - try { - object = resources.lookup(path); - } catch (NamingException e) { - exists = false; - int slash = path.lastIndexOf('/'); - if (slash != -1) { - String parentPath = path.substring(0, slash); - Vector currentLockNullResources = - lockNullResources.get(parentPath); - if (currentLockNullResources != null) { - Enumeration lockNullResourcesList = - currentLockNullResources.elements(); - while (lockNullResourcesList.hasMoreElements()) { - String lockNullPath = - lockNullResourcesList.nextElement(); - if (lockNullPath.equals(path)) { - resp.setStatus(WebdavServletStatus.SC_MULTI_STATUS); - resp.setContentType("text/xml; charset=UTF-8"); - // Create multistatus object - XMLWriter generatedXML = - new XMLWriter(resp.getWriter()); - generatedXML.writeXMLHeader(); - generatedXML.writeElement("D", DEFAULT_NAMESPACE, - "multistatus", XMLWriter.OPENING); - parseLockNullProperties - (req, generatedXML, lockNullPath, type, - properties); - generatedXML.writeElement("D", "multistatus", - XMLWriter.CLOSING); - generatedXML.sendData(); - return; - } - } - } - } - }*/ - - if (!exists) { - resp.sendError(HttpServletResponse.SC_NOT_FOUND, path); - return; - } - - resp.setStatus(WebdavServletStatus.SC_MULTI_STATUS); - - resp.setContentType("text/xml; charset=UTF-8"); - - // Create multistatus object - XMLWriter generatedXML = new XMLWriter(resp.getWriter()); - generatedXML.writeXMLHeader(); - - generatedXML.writeElement("D", DEFAULT_NAMESPACE, "multistatus", - XMLWriter.OPENING); - - if (depth == 0) { - parseProperties(req,resp, generatedXML, path, type, - properties); - } else { - // The stack always contains the object of the current level - Stack stack = new Stack(); - stack.push(path); - - // Stack of the objects one level below - Stack stackBelow = new Stack(); - ResourceObj rob = null; - while ((!stack.isEmpty()) && (depth >= 0)) { - - String currentPath = stack.pop(); - parseProperties(req,resp, generatedXML, currentPath, - type, properties); - - // try { - //object = resources.lookup(currentPath); - rob = ResourceStore.lookup(currentPath,req,resp,ResourceStore.READ); - - // } catch (Exception e) { - // continue; - // } - - if ((rob.isDirectory()) && (depth > 0)) { - - try { - Enumeration enumeration = - rob.list().elements(); - while (enumeration.hasMoreElements()) { - ResourceObj ncPair = enumeration.nextElement(); - //String newPath = currentPath; - //if (!(newPath.endsWith("/"))) - // newPath += "/"; - //newPath += ncPair.getName(); - stackBelow.push(ncPair.path); - } - } catch (Exception e) { - e.printStackTrace(); - resp.sendError - (HttpServletResponse.SC_INTERNAL_SERVER_ERROR, - path); - return; - } - - // Displaying the lock-null resources present in that - // collection - String lockPath = currentPath; - if (lockPath.endsWith("/")) - lockPath = - lockPath.substring(0, lockPath.length() - 1); - Vector currentLockNullResources = - lockNullResources.get(lockPath); - if (currentLockNullResources != null) { - Enumeration lockNullResourcesList = - currentLockNullResources.elements(); - while (lockNullResourcesList.hasMoreElements()) { - String lockNullPath = - lockNullResourcesList.nextElement(); - parseLockNullProperties - (req, generatedXML, lockNullPath, type, - properties); - } - } - - } - - if (stack.isEmpty()) { - depth--; - stack = stackBelow; - stackBelow = new Stack(); - } - - generatedXML.sendData(); - - } - } - - generatedXML.writeElement("D", "multistatus", XMLWriter.CLOSING); - - generatedXML.sendData(); - //("generatedXML,value " + generatedXML); - - } - - - /** - * PROPPATCH Method. - */ - protected void doProppatch(HttpServletRequest req, HttpServletResponse resp) - throws IOException { -/* - if (readOnly) { - resp.sendError(WebdavServletStatus.SC_FORBIDDEN); - return; - } - - if (isLocked(req)) { - resp.sendError(WebdavServletStatus.SC_LOCKED); - return; - } - - resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); -*/ - //resp.setStatus(200); - resp.setContentType("text/xml"); - String propr = "\r\n" + -"\r\n" + -" \r\n" + - " \r\n" + - " HTTP/1.1 200 OK\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + -"\r\n"; -resp.getWriter().print(propr); - - } - - - /** - * MKCOL Method. - */ - protected void doMkcol(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - /*if (readOnly) { - resp.sendError(WebdavServletStatus.SC_FORBIDDEN); - return; - } - - if (isLocked(req)) { - resp.sendError(WebdavServletStatus.SC_LOCKED); - return; - }*/ - - String path = getRelativePath(req); - - /*boolean exists = true; - try { - resources.lookup(path); - } catch (NamingException e) { - exists = false; - }*/ - - // Can't create a collection if a resource already exists at the given - // path - - - ResourceObj ro = ResourceStore.lookup(path,req,resp,ResourceStore.WRITE); - if (ro == null)return; - - if (!ro.canWrite()) { - resp.sendError(HttpServletResponse.SC_FORBIDDEN); - return; - } - - boolean exists = ro.exists(); - - if (exists) { - // Get allowed methods - StringBuilder methodsAllowed = determineMethodsAllowed( req,resp); - - resp.addHeader("Allow", methodsAllowed.toString()); - - resp.sendError(WebdavServletStatus.SC_METHOD_NOT_ALLOWED); - return; - } - - if (req.getContentLength() > 0) { - //("MKCOL IS MORE DATA"); - DocumentBuilder documentBuilder = getDocumentBuilder(); - try { - // Document document = - documentBuilder.parse(new InputSource(req.getInputStream())); - // TODO : Process this request body - resp.sendError(WebdavServletStatus.SC_NOT_IMPLEMENTED); - return; - - } catch(SAXException saxe) { - // Parse error - assume invalid content - resp.sendError(WebdavServletStatus.SC_UNSUPPORTED_MEDIA_TYPE); - return; - } - } - - try{ - ro.mkdir(); - resp.setStatus(WebdavServletStatus.SC_CREATED); - - }catch (Exception e){ - e.printStackTrace(); - resp.sendError(WebdavServletStatus.SC_CONFLICT, - WebdavServletStatus.getStatusText - (WebdavServletStatus.SC_CONFLICT)); - } - - /*boolean result = true; - try { - resources.createSubcontext(path); - } catch (NamingException e) { - result = false; - } - - if (!result) { - resp.sendError(WebdavServletStatus.SC_CONFLICT, - WebdavServletStatus.getStatusText - (WebdavServletStatus.SC_CONFLICT)); - } else { - resp.setStatus(WebdavServletStatus.SC_CREATED); - // Removing any lock-null resource which would be present - lockNullResources.remove(path); - }*/ - - } - - - /** - * DELETE Method. - */ - /*@Override - protected void doDelete(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - if (readOnly) { - resp.sendError(WebdavServletStatus.SC_FORBIDDEN); - return; - } - - if (isLocked(req)) { - resp.sendError(WebdavServletStatus.SC_LOCKED); - return; - } - - deleteResource(req, resp); - - }*/ - - - /** - * Process a PUT request for the specified resource. - * - * @param req The servlet request we are processing - * @param resp The servlet response we are creating - * - * @exception IOException if an input/output error occurs - * @exception ServletException if a servlet-specified error occurs - */ - @Override - protected void doPut(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - String path = getRelativePath(req); - - if (isLocked(req)) { - //(path + " IS A LIOCLLERD "); - resp.sendError(WebdavServletStatus.SC_LOCKED); - return; - } - - super.doPut(req, resp); - - - // Removing any lock-null resource which would be present - lockNullResources.remove(path); - - } - - /** - * COPY Method. - */ - protected void doCopy(HttpServletRequest req, HttpServletResponse resp) - throws ServletException,IOException { - - /// if (readOnly) { - // resp.sendError(WebdavServletStatus.SC_FORBIDDEN); - // return; - // } - - copyResource(req, resp); - - } - - - - private boolean moveResource(HttpServletRequest req, - HttpServletResponse resp) - throws CaimitoException,IOException { - - // Parsing destination header - - String destinationPath = req.getHeader("Destination"); - - if (destinationPath == null) { - resp.sendError(WebdavServletStatus.SC_BAD_REQUEST); - return false; - } - - // Remove url encoding from destination - destinationPath = org.apache.catalina.util.RequestUtil.URLDecode( - destinationPath, "UTF8"); - - int protocolIndex = destinationPath.indexOf("://"); - if (protocolIndex >= 0) { - // if the Destination URL contains the protocol, we can safely - // trim everything upto the first "/" character after "://" - int firstSeparator = - destinationPath.indexOf("/", protocolIndex + 4); - if (firstSeparator < 0) { - destinationPath = "/"; - } else { - destinationPath = destinationPath.substring(firstSeparator); - } - } else { - String hostName = req.getServerName(); - if ((hostName != null) && (destinationPath.startsWith(hostName))) { - destinationPath = destinationPath.substring(hostName.length()); - } - - int portIndex = destinationPath.indexOf(":"); - if (portIndex >= 0) { - destinationPath = destinationPath.substring(portIndex); - } - - if (destinationPath.startsWith(":")) { - int firstSeparator = destinationPath.indexOf("/"); - if (firstSeparator < 0) { - destinationPath = "/"; - } else { - destinationPath = - destinationPath.substring(firstSeparator); - } - } - } - - // Normalise destination path (remove '.' and '..') - destinationPath = RequestUtil.normalize(destinationPath); - - String contextPath = req.getContextPath(); - if ((contextPath != null) && - (destinationPath.startsWith(contextPath))) { - destinationPath = destinationPath.substring(contextPath.length()); - } - - String pathInfo = req.getPathInfo(); - if (pathInfo != null) { - String servletPath = req.getServletPath(); - if ((servletPath != null) && - (destinationPath.startsWith(servletPath))) { - destinationPath = destinationPath - .substring(servletPath.length()); - } - } - - if (debug > 0) - log("Dest path :" + destinationPath); - - // Check destination path to protect special subdirectories - //if (isSpecialPath(destinationPath)) { - // resp.sendError(WebdavServletStatus.SC_FORBIDDEN); - // return false; - //} - - String path = getRelativePath(req); - - if (destinationPath.equals(path)) { - resp.sendError(WebdavServletStatus.SC_FORBIDDEN); - return false; - } - - // Parsing overwrite header - - boolean overwrite = true; - String overwriteHeader = req.getHeader("Overwrite"); - - if (overwriteHeader != null) { - if (overwriteHeader.equalsIgnoreCase("T")) { - overwrite = true; - } else { - overwrite = false; - } - } - - // Overwriting the destination - ResourceObj ro = ResourceStore.lookup(destinationPath,req,resp,ResourceStore.WRITE); - if (ro == null) - return false; - - ResourceObj ros = ResourceStore.lookup(path,req,resp,ResourceStore.READ); - - // if (!ro.canWrite() || !ros.canWrite()) { - if (ro == null || ros == null){ - - //resp.sendError(WebdavServletStatus.SC_FORBIDDEN); - //return false; - return false; - } - - boolean exists = ro.exists(); - /*try { - resources.lookup(destinationPath); - } catch (NamingException e) { - exists = false; - }*/ - - if (overwrite) { - - // destination resource, if it exists - if (exists) { - //if (! Resource(destinationPath, req, resp, true)) { - // return false; - //} - ro.delete(); - } else { - resp.setStatus(WebdavServletStatus.SC_CREATED); - } - - } else { - - // If the destination exists, then it's a conflict - if (exists) { - resp.sendError(WebdavServletStatus.SC_PRECONDITION_FAILED); - return false; - } - - } - - // Copying source to destination - - ros.move(ro); - /*Hashtable errorList = new Hashtable(); - - boolean result = copyResource(resources, errorList, - path, destinationPath); - - if ((!result) || (!errorList.isEmpty())) { - if (errorList.size() == 1) { - resp.sendError(errorList.elements().nextElement().intValue()); - } else { - sendReport(req, resp, errorList); - } - return false; - }*/ - - // Copy was successful - if (exists) { - resp.setStatus(WebdavServletStatus.SC_NO_CONTENT); - } else { - resp.setStatus(WebdavServletStatus.SC_CREATED); - } - - // Removing any lock-null resource which would be present at - // the destination path - lockNullResources.remove(destinationPath); - - return true; - - } - - /** - * MOVE Method. - */ - protected void doMove(HttpServletRequest req, HttpServletResponse resp) - throws ServletException,IOException { - - /*if (readOnly) { - resp.sendError(WebdavServletStatus.SC_FORBIDDEN); - return; - } - - if (isLocked(req)) { - resp.sendError(WebdavServletStatus.SC_LOCKED); - return; - }*/ - - /*String path = getRelativePath(req); - ResourceObj ros = ResourceStore.lookup(path,req,resp); - - if (!ros.canWrite()) { - resp.sendError(WebdavServletStatus.SC_FORBIDDEN); - return ; - }*/ - - moveResource(req, resp); - // Resource(path, req, resp, false); - //ros.move(); - //} - - } - - - /** - * LOCK Method. - */ - - /* - protected void doLock(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - }*/ - protected void doLock(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - /*if (readOnly) { - resp.sendError(WebdavServletStatus.SC_FORBIDDEN); - return; - } - - if (isLocked(req)) { - resp.sendError(WebdavServletStatus.SC_LOCKED); - return; - }*/ - - LockInfo lock = new LockInfo(); - - - String depthStr = req.getHeader("Depth"); - - if (depthStr == null) { - lock.depth = maxDepth; - } else { - if (depthStr.equals("0")) { - lock.depth = 0; - } else { - lock.depth = maxDepth; - } - } - - // Parsing timeout header - - int lockDuration = DEFAULT_TIMEOUT; - String lockDurationStr = req.getHeader("Timeout"); - if (lockDurationStr == null) { - lockDuration = DEFAULT_TIMEOUT; - } else { - int commaPos = lockDurationStr.indexOf(","); - // If multiple timeouts, just use the first - if (commaPos != -1) { - lockDurationStr = lockDurationStr.substring(0,commaPos); - } - if (lockDurationStr.startsWith("Second-")) { - lockDuration = - (new Integer(lockDurationStr.substring(7))).intValue(); - } else { - if (lockDurationStr.equalsIgnoreCase("infinity")) { - lockDuration = MAX_TIMEOUT; - } else { - try { - lockDuration = - (new Integer(lockDurationStr)).intValue(); - } catch (NumberFormatException e) { - lockDuration = MAX_TIMEOUT; - } - } - } - if (lockDuration == 0) { - lockDuration = DEFAULT_TIMEOUT; - } - if (lockDuration > MAX_TIMEOUT) { - lockDuration = MAX_TIMEOUT; - } - } - lock.expiresAt = System.currentTimeMillis() + (lockDuration * 1000); - - int lockRequestType = LOCK_CREATION; - - Node lockInfoNode = null; - - DocumentBuilder documentBuilder = getDocumentBuilder(); - - try { - Document document = documentBuilder.parse(new InputSource - (req.getInputStream())); - - // Get the root element of the document - Element rootElement = document.getDocumentElement(); - lockInfoNode = rootElement; - } catch (IOException e) { - lockRequestType = LOCK_REFRESH; - } catch (SAXException e) { - lockRequestType = LOCK_REFRESH; - } - - if (lockInfoNode != null) { - - // Reading lock information - - NodeList childList = lockInfoNode.getChildNodes(); - StringWriter strWriter = null; - DOMWriter domWriter = null; - - Node lockScopeNode = null; - Node lockTypeNode = null; - Node lockOwnerNode = null; - - for (int i=0; i < childList.getLength(); i++) { - Node currentNode = childList.item(i); - switch (currentNode.getNodeType()) { - case Node.TEXT_NODE: - break; - case Node.ELEMENT_NODE: - String nodeName = currentNode.getNodeName(); - if (nodeName.endsWith("lockscope")) { - lockScopeNode = currentNode; - } - if (nodeName.endsWith("locktype")) { - lockTypeNode = currentNode; - } - if (nodeName.endsWith("owner")) { - lockOwnerNode = currentNode; - } - break; - } - } - - if (lockScopeNode != null) { - - childList = lockScopeNode.getChildNodes(); - for (int i=0; i < childList.getLength(); i++) { - Node currentNode = childList.item(i); - switch (currentNode.getNodeType()) { - case Node.TEXT_NODE: - break; - case Node.ELEMENT_NODE: - String tempScope = currentNode.getNodeName(); - if (tempScope.indexOf(':') != -1) { - lock.scope = tempScope.substring - (tempScope.indexOf(':') + 1); - } else { - lock.scope = tempScope; - } - break; - } - } - - if (lock.scope == null) { - // Bad request - resp.setStatus(WebdavServletStatus.SC_BAD_REQUEST); - } - - } else { - // Bad request - resp.setStatus(WebdavServletStatus.SC_BAD_REQUEST); - } - - if (lockTypeNode != null) { - - childList = lockTypeNode.getChildNodes(); - for (int i=0; i < childList.getLength(); i++) { - Node currentNode = childList.item(i); - switch (currentNode.getNodeType()) { - case Node.TEXT_NODE: - break; - case Node.ELEMENT_NODE: - String tempType = currentNode.getNodeName(); - if (tempType.indexOf(':') != -1) { - lock.type = - tempType.substring(tempType.indexOf(':') + 1); - } else { - lock.type = tempType; - } - break; - } - } - - if (lock.type == null) { - // Bad request - resp.setStatus(WebdavServletStatus.SC_BAD_REQUEST); - } - - } else { - // Bad request - resp.setStatus(WebdavServletStatus.SC_BAD_REQUEST); - } - - if (lockOwnerNode != null) { - - childList = lockOwnerNode.getChildNodes(); - for (int i=0; i < childList.getLength(); i++) { - Node currentNode = childList.item(i); - switch (currentNode.getNodeType()) { - case Node.TEXT_NODE: - lock.owner += currentNode.getNodeValue(); - break; - case Node.ELEMENT_NODE: - strWriter = new StringWriter(); - domWriter = new DOMWriter(strWriter, true); - domWriter.setQualifiedNames(false); - domWriter.print(currentNode); - lock.owner += strWriter.toString(); - break; - } - } - - if (lock.owner == null) { - // Bad request - resp.setStatus(WebdavServletStatus.SC_BAD_REQUEST); - } - - } else { - lock.owner = ""; - } - - } - - String path = getRelativePath(req); - - lock.path = path; - ResourceObj ro = ResourceStore.lookup(path,req,resp,ResourceStore.WRITE); - if (ro == null)return; - boolean exists = ro.exists(); - /*Object object = null; - try { - object = resources.lookup(path); - } catch (NamingException e) { - exists = false; - }*/ - - Enumeration locksList = null; - - if (lockRequestType == LOCK_CREATION) { - - // Generating lock id - String lockTokenStr = req.getServletPath() + "-" + lock.type + "-" - + lock.scope + "-" + req.getUserPrincipal() + "-" - + lock.depth + "-" + lock.owner + "-" + lock.tokens + "-" - + lock.expiresAt + "-" + System.currentTimeMillis() + "-" - + secret; - String lockToken = md5Encoder.encode(md5Helper.digest( - lockTokenStr.getBytes(Charset.defaultCharset()))); - - if ( (exists) && (ro.isDirectory()) && - (lock.depth == maxDepth) ) { - - // Locking a collection (and all its member resources) - - // Checking if a child resource of this collection is - // already locked - Vector lockPaths = new Vector(); - locksList = collectionLocks.elements(); - while (locksList.hasMoreElements()) { - LockInfo currentLock = locksList.nextElement(); - if (currentLock.hasExpired()) { - resourceLocks.remove(currentLock.path); - continue; - } - if ( (currentLock.path.startsWith(lock.path)) && - ((currentLock.isExclusive()) || - (lock.isExclusive())) ) { - // A child collection of this collection is locked - lockPaths.addElement(currentLock.path); - } - } - locksList = resourceLocks.elements(); - while (locksList.hasMoreElements()) { - LockInfo currentLock = locksList.nextElement(); - if (currentLock.hasExpired()) { - resourceLocks.remove(currentLock.path); - continue; - } - if ( (currentLock.path.startsWith(lock.path)) && - ((currentLock.isExclusive()) || - (lock.isExclusive())) ) { - // A child resource of this collection is locked - lockPaths.addElement(currentLock.path); - } - } - - if (!lockPaths.isEmpty()) { - - // One of the child paths was locked - // We generate a multistatus error report - - Enumeration lockPathsList = lockPaths.elements(); - - resp.setStatus(WebdavServletStatus.SC_CONFLICT); - - XMLWriter generatedXML = new XMLWriter(); - generatedXML.writeXMLHeader(); - - generatedXML.writeElement("D", DEFAULT_NAMESPACE, - "multistatus", XMLWriter.OPENING); - - while (lockPathsList.hasMoreElements()) { - generatedXML.writeElement("D", "response", - XMLWriter.OPENING); - generatedXML.writeElement("D", "href", - XMLWriter.OPENING); - generatedXML.writeText(lockPathsList.nextElement()); - generatedXML.writeElement("D", "href", - XMLWriter.CLOSING); - generatedXML.writeElement("D", "status", - XMLWriter.OPENING); - generatedXML - .writeText("HTTP/1.1 " + WebdavServletStatus.SC_LOCKED - + " " + WebdavServletStatus - .getStatusText(WebdavServletStatus.SC_LOCKED)); - generatedXML.writeElement("D", "status", - XMLWriter.CLOSING); - - generatedXML.writeElement("D", "response", - XMLWriter.CLOSING); - } - - generatedXML.writeElement("D", "multistatus", - XMLWriter.CLOSING); - - Writer writer = resp.getWriter(); - writer.write(generatedXML.toString()); - writer.close(); - - return; - - } - - boolean addLock = true; - - // Checking if there is already a shared lock on this path - locksList = collectionLocks.elements(); - while (locksList.hasMoreElements()) { - - LockInfo currentLock = locksList.nextElement(); - if (currentLock.path.equals(lock.path)) { - - if (currentLock.isExclusive()) { - resp.sendError(WebdavServletStatus.SC_LOCKED); - return; - } else { - if (lock.isExclusive()) { - resp.sendError(WebdavServletStatus.SC_LOCKED); - return; - } - } - - currentLock.tokens.addElement(lockToken); - lock = currentLock; - addLock = false; - - } - - } - - if (addLock) { - lock.tokens.addElement(lockToken); - collectionLocks.addElement(lock); - } - - } else { - - // Locking a single resource - - // Retrieving an already existing lock on that resource - LockInfo presentLock = resourceLocks.get(lock.path); - if (presentLock != null) { - - if ((presentLock.isExclusive()) || (lock.isExclusive())) { - // If either lock is exclusive, the lock can't be - // granted - resp.sendError(WebdavServletStatus.SC_PRECONDITION_FAILED); - return; - } else { - presentLock.tokens.addElement(lockToken); - lock = presentLock; - } - - } else { - - lock.tokens.addElement(lockToken); - //FREE WORLD - //resourceLocks.put(lock.path, lock); - - // Checking if a resource exists at this path - /*exists = true; - try { - object = resources.lookup(path); - } catch (NamingException e) { - exists = false; - }*/ - if (!exists) { - - // "Creating" a lock-null resource - int slash = lock.path.lastIndexOf('/'); - String parentPath = lock.path.substring(0, slash); - - Vector lockNulls = - lockNullResources.get(parentPath); - if (lockNulls == null) { - lockNulls = new Vector(); - //FREE WORLD - //lockNullResources.put(parentPath, lockNulls); - } - - //FREE WORLD - //lockNulls.addElement(lock.path); - - } - // Add the Lock-Token header as by RFC 2518 8.10.1 - // - only do this for newly created locks - resp.addHeader("Lock-Token", ""); - //(" LOCKY TOKEN " + lockToken); - } - - } - - } - - if (lockRequestType == LOCK_REFRESH) { - - String ifHeader = req.getHeader("If"); - if (ifHeader == null) - ifHeader = ""; - - // Checking resource locks - - LockInfo toRenew = resourceLocks.get(path); - Enumeration tokenList = null; - - if (toRenew != null) { - // At least one of the tokens of the locks must have been given - tokenList = toRenew.tokens.elements(); - while (tokenList.hasMoreElements()) { - String token = tokenList.nextElement(); - if (ifHeader.indexOf(token) != -1) { - toRenew.expiresAt = lock.expiresAt; - lock = toRenew; - } - } - } - - // Checking inheritable collection locks - - Enumeration collectionLocksList = - collectionLocks.elements(); - while (collectionLocksList.hasMoreElements()) { - toRenew = collectionLocksList.nextElement(); - if (path.equals(toRenew.path)) { - - tokenList = toRenew.tokens.elements(); - while (tokenList.hasMoreElements()) { - String token = tokenList.nextElement(); - if (ifHeader.indexOf(token) != -1) { - toRenew.expiresAt = lock.expiresAt; - lock = toRenew; - } - } - - } - } - - } - - // Set the status, then generate the XML response containing - // the lock information - XMLWriter generatedXML = new XMLWriter(); - generatedXML.writeXMLHeader(); - generatedXML.writeElement("D", DEFAULT_NAMESPACE, "prop", - XMLWriter.OPENING); - - generatedXML.writeElement("D", "lockdiscovery", XMLWriter.OPENING); - - lock.toXML(generatedXML); - - generatedXML.writeElement("D", "lockdiscovery", XMLWriter.CLOSING); - - generatedXML.writeElement("D", "prop", XMLWriter.CLOSING); - - resp.setStatus(WebdavServletStatus.SC_OK); - resp.setContentType("text/xml; charset=UTF-8"); - Writer writer = resp.getWriter(); - writer.write(generatedXML.toString()); - //(path + " XMLE RITER W " + generatedXML.toString()); - writer.close(); - - } - - - /** - * UNLOCK Method. - */ - protected void doUnlock(HttpServletRequest req, HttpServletResponse resp) - throws IOException { - - } - - protected void doUnlock1(HttpServletRequest req, HttpServletResponse resp) - throws IOException { - - if (readOnly) { - resp.sendError(WebdavServletStatus.SC_FORBIDDEN); - return; - } - - if (isLocked(req)) { - resp.sendError(WebdavServletStatus.SC_LOCKED); - return; - } - - String path = getRelativePath(req); - - String lockTokenHeader = req.getHeader("Lock-Token"); - if (lockTokenHeader == null) - lockTokenHeader = ""; - - // Checking resource locks - - LockInfo lock = resourceLocks.get(path); - Enumeration tokenList = null; - if (lock != null) { - - // At least one of the tokens of the locks must have been given - - tokenList = lock.tokens.elements(); - while (tokenList.hasMoreElements()) { - String token = tokenList.nextElement(); - if (lockTokenHeader.indexOf(token) != -1) { - lock.tokens.removeElement(token); - } - } - - if (lock.tokens.isEmpty()) { - resourceLocks.remove(path); - // Removing any lock-null resource which would be present - lockNullResources.remove(path); - } - - } - - // Checking inheritable collection locks - - Enumeration collectionLocksList = collectionLocks.elements(); - while (collectionLocksList.hasMoreElements()) { - lock = collectionLocksList.nextElement(); - if (path.equals(lock.path)) { - - tokenList = lock.tokens.elements(); - while (tokenList.hasMoreElements()) { - String token = tokenList.nextElement(); - if (lockTokenHeader.indexOf(token) != -1) { - lock.tokens.removeElement(token); - break; - } - } - - if (lock.tokens.isEmpty()) { - collectionLocks.removeElement(lock); - // Removing any lock-null resource which would be present - lockNullResources.remove(path); - } - - } - } - - resp.setStatus(WebdavServletStatus.SC_NO_CONTENT); - - } - - // -------------------------------------------------------- Private Methods - - /** - * Check to see if a resource is currently write locked. The method - * will look at the "If" header to make sure the client - * has give the appropriate lock tokens. - * - * @param req Servlet request - * @return boolean true if the resource is locked (and no appropriate - * lock token has been found for at least one of the non-shared locks which - * are present on the resource). - */ - private boolean isLocked(HttpServletRequest req) { - - String path = getRelativePath(req); - - String ifHeader = req.getHeader("If"); - if (ifHeader == null) - ifHeader = ""; - - String lockTokenHeader = req.getHeader("Lock-Token"); - if (lockTokenHeader == null) - lockTokenHeader = ""; - - return isLocked(path, ifHeader + lockTokenHeader); - - } - - - /** - * Check to see if a resource is currently write locked. - * - * @param path Path of the resource - * @param ifHeader "If" HTTP header which was included in the request - * @return boolean true if the resource is locked (and no appropriate - * lock token has been found for at least one of the non-shared locks which - * are present on the resource). - */ - private boolean isLocked(String path, String ifHeader) { - - // Checking resource locks - - LockInfo lock = resourceLocks.get(path); - Enumeration tokenList = null; - if ((lock != null) && (lock.hasExpired())) { - resourceLocks.remove(path); - } else if (lock != null) { - - // At least one of the tokens of the locks must have been given - - tokenList = lock.tokens.elements(); - boolean tokenMatch = false; - while (tokenList.hasMoreElements()) { - String token = tokenList.nextElement(); - if (ifHeader.indexOf(token) != -1) - tokenMatch = true; - } - if (!tokenMatch) - return true; - - } - - // Checking inheritable collection locks - - Enumeration collectionLocksList = collectionLocks.elements(); - while (collectionLocksList.hasMoreElements()) { - lock = collectionLocksList.nextElement(); - if (lock.hasExpired()) { - collectionLocks.removeElement(lock); - } else if (path.startsWith(lock.path)) { - - tokenList = lock.tokens.elements(); - boolean tokenMatch = false; - while (tokenList.hasMoreElements()) { - String token = tokenList.nextElement(); - if (ifHeader.indexOf(token) != -1) - tokenMatch = true; - } - if (!tokenMatch) - return true; - - } - } - - return false; - - } - - - /** - * Copy a resource. - * - * @param req Servlet request - * @param resp Servlet response - * @return boolean true if the copy is successful - */ - private boolean copyResource(HttpServletRequest req, - HttpServletResponse resp) - throws CaimitoException,IOException { - - // Parsing destination header - - String destinationPath = req.getHeader("Destination"); - - if (destinationPath == null) { - resp.sendError(WebdavServletStatus.SC_BAD_REQUEST); - return false; - } - - // Remove url encoding from destination - destinationPath = org.apache.catalina.util.RequestUtil.URLDecode( - destinationPath, "UTF8"); - - int protocolIndex = destinationPath.indexOf("://"); - if (protocolIndex >= 0) { - // if the Destination URL contains the protocol, we can safely - // trim everything upto the first "/" character after "://" - int firstSeparator = - destinationPath.indexOf("/", protocolIndex + 4); - if (firstSeparator < 0) { - destinationPath = "/"; - } else { - destinationPath = destinationPath.substring(firstSeparator); - } - } else { - String hostName = req.getServerName(); - if ((hostName != null) && (destinationPath.startsWith(hostName))) { - destinationPath = destinationPath.substring(hostName.length()); - } - - int portIndex = destinationPath.indexOf(":"); - if (portIndex >= 0) { - destinationPath = destinationPath.substring(portIndex); - } - - if (destinationPath.startsWith(":")) { - int firstSeparator = destinationPath.indexOf("/"); - if (firstSeparator < 0) { - destinationPath = "/"; - } else { - destinationPath = - destinationPath.substring(firstSeparator); - } - } - } - - // Normalise destination path (remove '.' and '..') - destinationPath = RequestUtil.normalize(destinationPath); - - String contextPath = req.getContextPath(); - if ((contextPath != null) && - (destinationPath.startsWith(contextPath))) { - destinationPath = destinationPath.substring(contextPath.length()); - } - - String pathInfo = req.getPathInfo(); - if (pathInfo != null) { - String servletPath = req.getServletPath(); - if ((servletPath != null) && - (destinationPath.startsWith(servletPath))) { - destinationPath = destinationPath - .substring(servletPath.length()); - } - } - - if (debug > 0) - log("Dest path :" + destinationPath); - - // Check destination path to protect special subdirectories - //if (isSpecialPath(destinationPath)) { - // resp.sendError(WebdavServletStatus.SC_FORBIDDEN); - // return false; - //} - - String path = getRelativePath(req); - - if (destinationPath.equals(path)) { - resp.sendError(WebdavServletStatus.SC_FORBIDDEN); - return false; - } - - // Parsing overwrite header - - boolean overwrite = true; - String overwriteHeader = req.getHeader("Overwrite"); - - if (overwriteHeader != null) { - if (overwriteHeader.equalsIgnoreCase("T")) { - overwrite = true; - } else { - overwrite = false; - } - } - - // Overwriting the destination - ResourceObj ro = ResourceStore.lookup(destinationPath,req,resp,ResourceStore.WRITE); - ResourceObj ros = ResourceStore.lookup(path,req,resp,ResourceStore.READ); - - if (ro == null || ros == null){ - - //if (!ro.canWrite() || !ros.canRead()) { - //resp.sendError(WebdavServletStatus.SC_FORBIDDEN); - return false; - } - - boolean exists = ro.exists(); - /*try { - resources.lookup(destinationPath); - } catch (NamingException e) { - exists = false; - }*/ - - if (overwrite) { - - // destination resource, if it exists - if (exists) { - //if (! Resource(destinationPath, req, resp, true)) { - // return false; - //} - ro.delete(); - } else { - resp.setStatus(WebdavServletStatus.SC_CREATED); - } - - } else { - - // If the destination exists, then it's a conflict - if (exists) { - resp.sendError(WebdavServletStatus.SC_PRECONDITION_FAILED); - return false; - } - - } - - // Copying source to destination - - ros.copy(ro); - /*Hashtable errorList = new Hashtable(); - - boolean result = copyResource(resources, errorList, - path, destinationPath); - - if ((!result) || (!errorList.isEmpty())) { - if (errorList.size() == 1) { - resp.sendError(errorList.elements().nextElement().intValue()); - } else { - sendReport(req, resp, errorList); - } - return false; - }*/ - - // Copy was successful - if (exists) { - resp.setStatus(WebdavServletStatus.SC_NO_CONTENT); - } else { - resp.setStatus(WebdavServletStatus.SC_CREATED); - } - - // Removing any lock-null resource which would be present at - // the destination path - lockNullResources.remove(destinationPath); - - return true; - - } - - - /** - * Copy a collection. - * - * @param dirContext Resources implementation to be used - * @param errorList Hashtable containing the list of errors which occurred - * during the copy operation - * @param source Path of the resource to be copied - * @param dest Destination path - */ - private boolean copyResource(DirContext dirContext, - Hashtable errorList, String source, String dest) { - - if (debug > 1) - log("Copy: " + source + " To: " + dest); - - Object object = null; - try { - object = dirContext.lookup(source); - } catch (NamingException e) { - // Ignore - } - - if (object instanceof DirContext) { - - try { - dirContext.createSubcontext(dest); - } catch (NamingException e) { - errorList.put - (dest, new Integer(WebdavServletStatus.SC_CONFLICT)); - return false; - } - - try { - NamingEnumeration enumeration = - dirContext.list(source); - while (enumeration.hasMoreElements()) { - NameClassPair ncPair = enumeration.nextElement(); - String childDest = dest; - if (!childDest.equals("/")) - childDest += "/"; - childDest += ncPair.getName(); - String childSrc = source; - if (!childSrc.equals("/")) - childSrc += "/"; - childSrc += ncPair.getName(); - copyResource(dirContext, errorList, childSrc, childDest); - } - } catch (NamingException e) { - errorList.put - (dest, new Integer(WebdavServletStatus.SC_INTERNAL_SERVER_ERROR)); - return false; - } - - } else { - - if (object instanceof Resource) { - try { - dirContext.bind(dest, object); - } catch (NamingException e) { - if (e.getCause() instanceof FileNotFoundException) { - // We know the source exists so it must be the - // destination dir that can't be found - errorList.put(source, - new Integer(WebdavServletStatus.SC_CONFLICT)); - } else { - errorList.put(source, - new Integer(WebdavServletStatus.SC_INTERNAL_SERVER_ERROR)); - } - return false; - } - } else { - errorList.put - (source, - new Integer(WebdavServletStatus.SC_INTERNAL_SERVER_ERROR)); - return false; - } - - } - - return true; - - } - - - /** - * Delete a resource. - * - * @param req Servlet request - * @param resp Servlet response - * @return boolean true if the copy is successful - */ - private boolean deleteResource(HttpServletRequest req, - HttpServletResponse resp) - throws IOException { - - String path = getRelativePath(req); - - return deleteResource(path, req, resp, true); - - } - - - /** - * Delete a resource. - * - * @param path Path of the resource which is to be deleted - * @param req Servlet request - * @param resp Servlet response - * @param setStatus Should the response status be set on successful - * completion - */ - private boolean deleteResource(String path, HttpServletRequest req, - HttpServletResponse resp, boolean setStatus) - throws IOException { - - String ifHeader = req.getHeader("If"); - if (ifHeader == null) - ifHeader = ""; - - String lockTokenHeader = req.getHeader("Lock-Token"); - if (lockTokenHeader == null) - lockTokenHeader = ""; - - if (isLocked(path, ifHeader + lockTokenHeader)) { - resp.sendError(WebdavServletStatus.SC_LOCKED); - return false; - } - - boolean exists = true; - Object object = null; - try { - object = resources.lookup(path); - } catch (NamingException e) { - exists = false; - } - - if (!exists) { - resp.sendError(WebdavServletStatus.SC_NOT_FOUND); - return false; - } - - boolean collection = (object instanceof DirContext); - - if (!collection) { - try { - resources.unbind(path); - } catch (NamingException e) { - resp.sendError(WebdavServletStatus.SC_INTERNAL_SERVER_ERROR); - return false; - } - } else { - - Hashtable errorList = - new Hashtable(); - - deleteCollection(req, resources, path, errorList); - try { - resources.unbind(path); - } catch (NamingException e) { - errorList.put(path, new Integer - (WebdavServletStatus.SC_INTERNAL_SERVER_ERROR)); - } - - if (!errorList.isEmpty()) { - - sendReport(req, resp, errorList); - return false; - - } - - } - if (setStatus) { - resp.setStatus(WebdavServletStatus.SC_NO_CONTENT); - } - return true; - - } - - - /** - * Deletes a collection. - * - * @param dirContext Resources implementation associated with the context - * @param path Path to the collection to be deleted - * @param errorList Contains the list of the errors which occurred - */ - private void deleteCollection(HttpServletRequest req, - DirContext dirContext, - String path, - Hashtable errorList) { - - if (debug > 1) - log("Delete:" + path); - - // Prevent deletion of special subdirectories - if (isSpecialPath(path)) { - errorList.put(path, new Integer(WebdavServletStatus.SC_FORBIDDEN)); - return; - } - - String ifHeader = req.getHeader("If"); - if (ifHeader == null) - ifHeader = ""; - - String lockTokenHeader = req.getHeader("Lock-Token"); - if (lockTokenHeader == null) - lockTokenHeader = ""; - - Enumeration enumeration = null; - try { - enumeration = dirContext.list(path); - } catch (NamingException e) { - errorList.put(path, new Integer - (WebdavServletStatus.SC_INTERNAL_SERVER_ERROR)); - return; - } - - while (enumeration.hasMoreElements()) { - NameClassPair ncPair = enumeration.nextElement(); - String childName = path; - if (!childName.equals("/")) - childName += "/"; - childName += ncPair.getName(); - - if (isLocked(childName, ifHeader + lockTokenHeader)) { - - errorList.put(childName, new Integer(WebdavServletStatus.SC_LOCKED)); - - } else { - - try { - Object object = dirContext.lookup(childName); - if (object instanceof DirContext) { - deleteCollection(req, dirContext, childName, errorList); - } - - try { - dirContext.unbind(childName); - } catch (NamingException e) { - if (!(object instanceof DirContext)) { - // If it's not a collection, then it's an unknown - // error - errorList.put - (childName, new Integer - (WebdavServletStatus.SC_INTERNAL_SERVER_ERROR)); - } - } - } catch (NamingException e) { - errorList.put - (childName, new Integer - (WebdavServletStatus.SC_INTERNAL_SERVER_ERROR)); - } - } - - } - - } - - - /** - * Send a multistatus element containing a complete error report to the - * client. - * - * @param req Servlet request - * @param resp Servlet response - * @param errorList List of error to be displayed - */ - private void sendReport(HttpServletRequest req, HttpServletResponse resp, - Hashtable errorList) - throws IOException { - - resp.setStatus(WebdavServletStatus.SC_MULTI_STATUS); - - String absoluteUri = req.getRequestURI(); - String relativePath = getRelativePath(req); - - XMLWriter generatedXML = new XMLWriter(); - generatedXML.writeXMLHeader(); - - generatedXML.writeElement("D", DEFAULT_NAMESPACE, "multistatus", - XMLWriter.OPENING); - - Enumeration pathList = errorList.keys(); - while (pathList.hasMoreElements()) { - - String errorPath = pathList.nextElement(); - int errorCode = errorList.get(errorPath).intValue(); - - generatedXML.writeElement("D", "response", XMLWriter.OPENING); - - generatedXML.writeElement("D", "href", XMLWriter.OPENING); - String toAppend = errorPath.substring(relativePath.length()); - if (!toAppend.startsWith("/")) - toAppend = "/" + toAppend; - generatedXML.writeText(absoluteUri + toAppend); - generatedXML.writeElement("D", "href", XMLWriter.CLOSING); - generatedXML.writeElement("D", "status", XMLWriter.OPENING); - generatedXML.writeText("HTTP/1.1 " + errorCode + " " - + WebdavServletStatus.getStatusText(errorCode)); - generatedXML.writeElement("D", "status", XMLWriter.CLOSING); - - generatedXML.writeElement("D", "response", XMLWriter.CLOSING); - - } - - generatedXML.writeElement("D", "multistatus", XMLWriter.CLOSING); - - Writer writer = resp.getWriter(); - writer.write(generatedXML.toString()); - writer.close(); - - } - - - /** - * Propfind helper method. - * - * @param req The servlet request - * @param resources Resources object associated with this context - * @param generatedXML XML response to the Propfind request - * @param path Path of the current resource - * @param type Propfind type - * @param propertiesVector If the propfind type is find properties by - * name, then this Vector contains those properties - */ - private void parseProperties(HttpServletRequest req,HttpServletResponse resp, - XMLWriter generatedXML, - String path, int type, - Vector propertiesVector) throws CaimitoException { - - // Exclude any resource in the /WEB-INF and /META-INF subdirectories - // if (isSpecialPath(path)) - // return; - - // CacheEntry cacheEntry = resources.lookupCache(path); - //(type + " parseProperties Z Prop " + path); - ResourceObj cacheEntry = ResourceStore.lookup(path,req,resp,ResourceStore.READ); - - if (!cacheEntry.exists()) { - // File is in directory listing but doesn't appear to exist - // Broken symlink or odd permission settings? - return; - } - - generatedXML.writeElement("D", "response", XMLWriter.OPENING); - String status = "HTTP/1.1 " + WebdavServletStatus.SC_OK + " " + - WebdavServletStatus.getStatusText(WebdavServletStatus.SC_OK); - - // Generating href element - generatedXML.writeElement("D", "href", XMLWriter.OPENING); - - String href = req.getContextPath() + req.getServletPath(); - if ((href.endsWith("/")) && (path.startsWith("/"))) - href += path.substring(1); - else - href += path; - if ((cacheEntry.isDirectory()) && (!href.endsWith("/"))) - href += "/"; - - generatedXML.writeText(rewriteUrl(href)); - - generatedXML.writeElement("D", "href", XMLWriter.CLOSING); - - String resourceName = path; - int lastSlash = path.lastIndexOf('/'); - if (lastSlash != -1) - resourceName = resourceName.substring(lastSlash + 1); - - switch (type) { - - case FIND_ALL_PROP : - - generatedXML.writeElement("D", "propstat", XMLWriter.OPENING); - generatedXML.writeElement("D", "prop", XMLWriter.OPENING); - - generatedXML.writeProperty("D", "creationdate", - getISOCreationDate(cacheEntry.getCreation())); - generatedXML.writeElement("D", "displayname", XMLWriter.OPENING); - generatedXML.writeData(resourceName); - generatedXML.writeElement("D", "displayname", XMLWriter.CLOSING); - //if (!cacheEntry.isDirectory()) { - generatedXML.writeProperty - ("D", "getlastmodified", FastHttpDateFormat.formatDate - (cacheEntry.getLastModified(), null)); - if (!cacheEntry.isDirectory()) { - generatedXML.writeProperty - ("D", "getcontentlength", - String.valueOf(cacheEntry.getContentLength())); - String contentType = getServletContext().getMimeType - (cacheEntry.getName()); - if (contentType != null) { - generatedXML.writeProperty("D", "getcontenttype", - contentType); - } - generatedXML.writeProperty("D", "getetag", - cacheEntry.getETag()); - generatedXML.writeElement("D", "resourcetype", - XMLWriter.NO_CONTENT); - } else { - generatedXML.writeElement("D", "resourcetype", - XMLWriter.OPENING); - generatedXML.writeElement("D", "collection", - XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "resourcetype", - XMLWriter.CLOSING); - } - - generatedXML.writeProperty("D", "source", ""); - - String supportedLocks = "" - + "" - + "" - + "" + "" - + "" - + "" - + ""; - generatedXML.writeElement("D", "supportedlock", XMLWriter.OPENING); - generatedXML.writeText(supportedLocks); - generatedXML.writeElement("D", "supportedlock", XMLWriter.CLOSING); - - generateLockDiscovery(path, generatedXML); - - generatedXML.writeElement("D", "prop", XMLWriter.CLOSING); - generatedXML.writeElement("D", "status", XMLWriter.OPENING); - generatedXML.writeText(status); - generatedXML.writeElement("D", "status", XMLWriter.CLOSING); - generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING); - - break; - - case FIND_PROPERTY_NAMES : - - generatedXML.writeElement("D", "propstat", XMLWriter.OPENING); - generatedXML.writeElement("D", "prop", XMLWriter.OPENING); - - generatedXML.writeElement("D", "creationdate", - XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "displayname", XMLWriter.NO_CONTENT); - if (!cacheEntry.isDirectory()) { - generatedXML.writeElement("D", "getcontentlanguage", - XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "getcontentlength", - XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "getcontenttype", - XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "getetag", XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "getlastmodified", - XMLWriter.NO_CONTENT); - } - generatedXML.writeElement("D", "resourcetype", - XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "source", XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "lockdiscovery", - XMLWriter.NO_CONTENT); - - generatedXML.writeElement("D", "prop", XMLWriter.CLOSING); - generatedXML.writeElement("D", "status", XMLWriter.OPENING); - generatedXML.writeText(status); - generatedXML.writeElement("D", "status", XMLWriter.CLOSING); - generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING); - - break; - - case FIND_BY_PROPERTY : - - Vector propertiesNotFound = new Vector(); - - // Parse the list of properties - - generatedXML.writeElement("D", "propstat", XMLWriter.OPENING); - generatedXML.writeElement("D", "prop", XMLWriter.OPENING); - - Enumeration properties = propertiesVector.elements(); - - while (properties.hasMoreElements()) { - - String property = properties.nextElement(); - - if (property.equals("creationdate")) { - generatedXML.writeProperty - ("D", "creationdate", - getISOCreationDate(cacheEntry.getCreation())); - } else if (property.equals("displayname")) { - generatedXML.writeElement - ("D", "displayname", XMLWriter.OPENING); - generatedXML.writeData(resourceName); - generatedXML.writeElement - ("D", "displayname", XMLWriter.CLOSING); - } else if (property.equals("getcontentlanguage")) { - if (cacheEntry.isDirectory()) { - propertiesNotFound.addElement(property); - } else { - generatedXML.writeElement("D", "getcontentlanguage", - XMLWriter.NO_CONTENT); - } - } else if (property.equals("getcontentlength")) { - if (cacheEntry.isDirectory()) { - propertiesNotFound.addElement(property); - } else { - generatedXML.writeProperty - ("D", "getcontentlength", - (String.valueOf(cacheEntry.getContentLength()))); - } - } else if (property.equals("getcontenttype")) { - if (cacheEntry.isDirectory()) { - propertiesNotFound.addElement(property); - } else { - //(cacheEntry.getName() + " MIMEO TYPE " + getServletContext().getMimeType(cacheEntry.getName())); - generatedXML.writeProperty - ("D", "getcontenttype", - getServletContext().getMimeType - (cacheEntry.getName())); - } - } else if (property.equals("getetag")) { - if (cacheEntry.isDirectory()) { - propertiesNotFound.addElement(property); - } else { - generatedXML.writeProperty - ("D", "getetag", cacheEntry.getETag()); - } - } else if (property.equals("getlastmodified")) { - //if (cacheEntry.isDirectory()) { - // propertiesNotFound.addElement(property); - //} else { - generatedXML.writeProperty - ("D", "getlastmodified", FastHttpDateFormat.formatDate - (cacheEntry.getLastModified(), null)); - //} - } else if (property.equals("resourcetype")) { - if (cacheEntry.isDirectory()) { - generatedXML.writeElement("D", "resourcetype", - XMLWriter.OPENING); - generatedXML.writeElement("D", "collection", - XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "resourcetype", - XMLWriter.CLOSING); - } else { - generatedXML.writeElement("D", "resourcetype", - XMLWriter.NO_CONTENT); - } - } else if (property.equals("source")) { - generatedXML.writeProperty("D", "source", ""); - } else if (property.equals("supportedlock")) { - supportedLocks = "" - + "" - + "" - + "" + "" - + "" - + "" - + ""; - generatedXML.writeElement("D", "supportedlock", - XMLWriter.OPENING); - generatedXML.writeText(supportedLocks); - generatedXML.writeElement("D", "supportedlock", - XMLWriter.CLOSING); - } else if (property.equals("lockdiscovery")) { - if (!generateLockDiscovery(path, generatedXML)) - propertiesNotFound.addElement(property); - } else { - propertiesNotFound.addElement(property); - } - - } - - //(cacheEntry.getName() + ":" + propertiesVector + " property e propertiesNotFoundList " + propertiesNotFound); - generatedXML.writeElement("D", "prop", XMLWriter.CLOSING); - generatedXML.writeElement("D", "status", XMLWriter.OPENING); - generatedXML.writeText(status); - generatedXML.writeElement("D", "status", XMLWriter.CLOSING); - generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING); - - Enumeration propertiesNotFoundList = - propertiesNotFound.elements(); - - if (propertiesNotFoundList.hasMoreElements()) { - - status = "HTTP/1.1 " + WebdavServletStatus.SC_NOT_FOUND + " " + - WebdavServletStatus.getStatusText(WebdavServletStatus.SC_NOT_FOUND); - - generatedXML.writeElement("D", "propstat", XMLWriter.OPENING); - generatedXML.writeElement("D", "prop", XMLWriter.OPENING); - - while (propertiesNotFoundList.hasMoreElements()) { - generatedXML.writeElement - ("D", propertiesNotFoundList.nextElement(), - XMLWriter.NO_CONTENT); - } - - generatedXML.writeElement("D", "prop", XMLWriter.CLOSING); - generatedXML.writeElement("D", "status", XMLWriter.OPENING); - generatedXML.writeText(status); - generatedXML.writeElement("D", "status", XMLWriter.CLOSING); - generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING); - - } - - break; - - } - - generatedXML.writeElement("D", "response", XMLWriter.CLOSING); - - } - - - /** - * Propfind helper method. Displays the properties of a lock-null resource. - * - * @param resources Resources object associated with this context - * @param generatedXML XML response to the Propfind request - * @param path Path of the current resource - * @param type Propfind type - * @param propertiesVector If the propfind type is find properties by - * name, then this Vector contains those properties - */ - private void parseLockNullProperties(HttpServletRequest req, - XMLWriter generatedXML, - String path, int type, - Vector propertiesVector) { - - // Exclude any resource in the /WEB-INF and /META-INF subdirectories - //if (isSpecialPath(path)) - // return; - - Thread.dumpStack(); - // Retrieving the lock associated with the lock-null resource - LockInfo lock = resourceLocks.get(path); - - if (lock == null) - return; - - generatedXML.writeElement("D", "response", XMLWriter.OPENING); - String status = "HTTP/1.1 " + WebdavServletStatus.SC_OK + " " + - WebdavServletStatus.getStatusText(WebdavServletStatus.SC_OK); - - // Generating href element - generatedXML.writeElement("D", "href", XMLWriter.OPENING); - - String absoluteUri = req.getRequestURI(); - String relativePath = getRelativePath(req); - String toAppend = path.substring(relativePath.length()); - if (!toAppend.startsWith("/")) - toAppend = "/" + toAppend; - - generatedXML.writeText(rewriteUrl(RequestUtil.normalize( - absoluteUri + toAppend))); - - generatedXML.writeElement("D", "href", XMLWriter.CLOSING); - - String resourceName = path; - int lastSlash = path.lastIndexOf('/'); - if (lastSlash != -1) - resourceName = resourceName.substring(lastSlash + 1); - - switch (type) { - - case FIND_ALL_PROP : - - generatedXML.writeElement("D", "propstat", XMLWriter.OPENING); - generatedXML.writeElement("D", "prop", XMLWriter.OPENING); - - generatedXML.writeProperty("D", "creationdate", - getISOCreationDate(lock.creationDate.getTime())); - generatedXML.writeElement("D", "displayname", XMLWriter.OPENING); - generatedXML.writeData(resourceName); - generatedXML.writeElement("D", "displayname", XMLWriter.CLOSING); - generatedXML.writeProperty("D", "getlastmodified", - FastHttpDateFormat.formatDate - (lock.creationDate.getTime(), null)); - generatedXML.writeProperty("D", "getcontentlength", - String.valueOf(0)); - generatedXML.writeProperty("D", "getcontenttype", ""); - generatedXML.writeProperty("D", "getetag", ""); - generatedXML.writeElement("D", "resourcetype", XMLWriter.OPENING); - generatedXML.writeElement("D", "lock-null", XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "resourcetype", XMLWriter.CLOSING); - - generatedXML.writeProperty("D", "source", ""); - - String supportedLocks = "" - + "" - + "" - + "" + "" - + "" - + "" - + ""; - generatedXML.writeElement("D", "supportedlock", XMLWriter.OPENING); - generatedXML.writeText(supportedLocks); - generatedXML.writeElement("D", "supportedlock", XMLWriter.CLOSING); - - generateLockDiscovery(path, generatedXML); - - generatedXML.writeElement("D", "prop", XMLWriter.CLOSING); - generatedXML.writeElement("D", "status", XMLWriter.OPENING); - generatedXML.writeText(status); - generatedXML.writeElement("D", "status", XMLWriter.CLOSING); - generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING); - - break; - - case FIND_PROPERTY_NAMES : - - generatedXML.writeElement("D", "propstat", XMLWriter.OPENING); - generatedXML.writeElement("D", "prop", XMLWriter.OPENING); - - generatedXML.writeElement("D", "creationdate", - XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "displayname", XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "getcontentlanguage", - XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "getcontentlength", - XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "getcontenttype", - XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "getetag", XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "getlastmodified", - XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "resourcetype", - XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "source", XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "lockdiscovery", - XMLWriter.NO_CONTENT); - - generatedXML.writeElement("D", "prop", XMLWriter.CLOSING); - generatedXML.writeElement("D", "status", XMLWriter.OPENING); - generatedXML.writeText(status); - generatedXML.writeElement("D", "status", XMLWriter.CLOSING); - generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING); - - break; - - case FIND_BY_PROPERTY : - - Vector propertiesNotFound = new Vector(); - - // Parse the list of properties - - generatedXML.writeElement("D", "propstat", XMLWriter.OPENING); - generatedXML.writeElement("D", "prop", XMLWriter.OPENING); - - Enumeration properties = propertiesVector.elements(); - - while (properties.hasMoreElements()) { - - String property = properties.nextElement(); - - if (property.equals("creationdate")) { - generatedXML.writeProperty("D", "creationdate", - getISOCreationDate(lock.creationDate.getTime())); - } else if (property.equals("displayname")) { - generatedXML.writeElement("D", "displayname", - XMLWriter.OPENING); - generatedXML.writeData(resourceName); - generatedXML.writeElement("D", "displayname", - XMLWriter.CLOSING); - } else if (property.equals("getcontentlanguage")) { - generatedXML.writeElement("D", "getcontentlanguage", - XMLWriter.NO_CONTENT); - } else if (property.equals("getcontentlength")) { - generatedXML.writeProperty("D", "getcontentlength", - (String.valueOf(0))); - } else if (property.equals("getcontenttype")) { - generatedXML.writeProperty("D", "getcontenttype", ""); - } else if (property.equals("getetag")) { - generatedXML.writeProperty("D", "getetag", ""); - } else if (property.equals("getlastmodified")) { - generatedXML.writeProperty - ("D", "getlastmodified", - FastHttpDateFormat.formatDate - (lock.creationDate.getTime(), null)); - } else if (property.equals("resourcetype")) { - generatedXML.writeElement("D", "resourcetype", - XMLWriter.OPENING); - generatedXML.writeElement("D", "lock-null", - XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "resourcetype", - XMLWriter.CLOSING); - } else if (property.equals("source")) { - generatedXML.writeProperty("D", "source", ""); - } else if (property.equals("supportedlock")) { - supportedLocks = "" - + "" - + "" - + "" + "" - + "" - + "" - + ""; - generatedXML.writeElement("D", "supportedlock", - XMLWriter.OPENING); - generatedXML.writeText(supportedLocks); - generatedXML.writeElement("D", "supportedlock", - XMLWriter.CLOSING); - } else if (property.equals("lockdiscovery")) { - if (!generateLockDiscovery(path, generatedXML)) - propertiesNotFound.addElement(property); - } else { - propertiesNotFound.addElement(property); - } - - } - - generatedXML.writeElement("D", "prop", XMLWriter.CLOSING); - generatedXML.writeElement("D", "status", XMLWriter.OPENING); - generatedXML.writeText(status); - generatedXML.writeElement("D", "status", XMLWriter.CLOSING); - generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING); - - Enumeration propertiesNotFoundList = propertiesNotFound.elements(); - - if (propertiesNotFoundList.hasMoreElements()) { - - status = "HTTP/1.1 " + WebdavServletStatus.SC_NOT_FOUND + " " + - WebdavServletStatus.getStatusText(WebdavServletStatus.SC_NOT_FOUND); - - generatedXML.writeElement("D", "propstat", XMLWriter.OPENING); - generatedXML.writeElement("D", "prop", XMLWriter.OPENING); - - while (propertiesNotFoundList.hasMoreElements()) { - generatedXML.writeElement - ("D", propertiesNotFoundList.nextElement(), - XMLWriter.NO_CONTENT); - } - - generatedXML.writeElement("D", "prop", XMLWriter.CLOSING); - generatedXML.writeElement("D", "status", XMLWriter.OPENING); - generatedXML.writeText(status); - generatedXML.writeElement("D", "status", XMLWriter.CLOSING); - generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING); - - } - - break; - - } - - generatedXML.writeElement("D", "response", XMLWriter.CLOSING); - - } - - - /** - * Print the lock discovery information associated with a path. - * - * @param path Path - * @param generatedXML XML data to which the locks info will be appended - * @return true if at least one lock was displayed - */ - private boolean generateLockDiscovery - (String path, XMLWriter generatedXML) { - - LockInfo resourceLock = resourceLocks.get(path); - Enumeration collectionLocksList = collectionLocks.elements(); - - boolean wroteStart = false; - - if (resourceLock != null) { - wroteStart = true; - generatedXML.writeElement("D", "lockdiscovery", XMLWriter.OPENING); - resourceLock.toXML(generatedXML); - } - - while (collectionLocksList.hasMoreElements()) { - LockInfo currentLock = collectionLocksList.nextElement(); - if (path.startsWith(currentLock.path)) { - if (!wroteStart) { - wroteStart = true; - generatedXML.writeElement("D", "lockdiscovery", - XMLWriter.OPENING); - } - currentLock.toXML(generatedXML); - } - } - - if (wroteStart) { - generatedXML.writeElement("D", "lockdiscovery", XMLWriter.CLOSING); - } else { - return false; - } - - return true; - - } - - - /** - * Get creation date in ISO format. - */ - private String getISOCreationDate(long creationDate) { - StringBuilder creationDateValue = new StringBuilder - (creationDateFormat.format - (new Date(creationDate))); - /* - int offset = Calendar.getInstance().getTimeZone().getRawOffset() - / 3600000; // FIXME ? - if (offset < 0) { - creationDateValue.append("-"); - offset = -offset; - } else if (offset > 0) { - creationDateValue.append("+"); - } - if (offset != 0) { - if (offset < 10) - creationDateValue.append("0"); - creationDateValue.append(offset + ":00"); - } else { - creationDateValue.append("Z"); - } - */ - return creationDateValue.toString(); - } - - /** - * Determines the methods normally allowed for the resource. - * - */ - private StringBuilder determineMethodsAllowed(HttpServletRequest req,HttpServletResponse resp) throws CaimitoException { - - StringBuilder methodsAllowed = new StringBuilder(); - - String path = getRelativePath(req); - //(" determineMethodsAllowed path " + path); - ResourceObj ro = ResourceStore.lookup(path,req,resp,ResourceStore.READ); - //if (ro == null)return methodsAllowed; - boolean exists = true; - if (ro != null) - exists = ro.exists(); - - - - if (!exists) { - methodsAllowed.append("OPTIONS, MKCOL, PUT, LOCK"); - return methodsAllowed; - } -//PROPPATCH, - methodsAllowed.append("OPTIONS, GET, HEAD, POST, DELETE, TRACE"); - methodsAllowed.append(", COPY, MOVE, LOCK, UNLOCK"); - - if (ro == null || ro.listings()) { - methodsAllowed.append(", PROPFIND"); - } - - if (ro != null && !(ro.isDirectory())) { - methodsAllowed.append(", PUT"); - } - - return methodsAllowed; - } - - // -------------------------------------------------- LockInfo Inner Class - - - /** - * Holds a lock information. - */ - private class LockInfo { - - - // -------------------------------------------------------- Constructor - - - /** - * Constructor. - */ - public LockInfo() { - // Ignore - } - - - // ------------------------------------------------- Instance Variables - - - String path = "/"; - String type = "write"; - String scope = "exclusive"; - int depth = 0; - String owner = ""; - Vector tokens = new Vector(); - long expiresAt = 0; - Date creationDate = new Date(); - - - // ----------------------------------------------------- Public Methods - - - /** - * Get a String representation of this lock token. - */ - @Override - public String toString() { - - StringBuilder result = new StringBuilder("Type:"); - result.append(type); - result.append("\nScope:"); - result.append(scope); - result.append("\nDepth:"); - result.append(depth); - result.append("\nOwner:"); - result.append(owner); - result.append("\nExpiration:"); - result.append(FastHttpDateFormat.formatDate(expiresAt, null)); - Enumeration tokensList = tokens.elements(); - while (tokensList.hasMoreElements()) { - result.append("\nToken:"); - result.append(tokensList.nextElement()); - } - result.append("\n"); - return result.toString(); - } - - - /** - * Return true if the lock has expired. - */ - public boolean hasExpired() { - return (System.currentTimeMillis() > expiresAt); - } - - - /** - * Return true if the lock is exclusive. - */ - public boolean isExclusive() { - - return (scope.equals("exclusive")); - - } - - - /** - * Get an XML representation of this lock token. This method will - * append an XML fragment to the given XML writer. - */ - public void toXML(XMLWriter generatedXML) { - - generatedXML.writeElement("D", "activelock", XMLWriter.OPENING); - - generatedXML.writeElement("D", "locktype", XMLWriter.OPENING); - generatedXML.writeElement("D", type, XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "locktype", XMLWriter.CLOSING); - - generatedXML.writeElement("D", "lockscope", XMLWriter.OPENING); - generatedXML.writeElement("D", scope, XMLWriter.NO_CONTENT); - generatedXML.writeElement("D", "lockscope", XMLWriter.CLOSING); - - generatedXML.writeElement("D", "depth", XMLWriter.OPENING); - if (depth == maxDepth) { - generatedXML.writeText("Infinity"); - } else { - generatedXML.writeText("0"); - } - generatedXML.writeElement("D", "depth", XMLWriter.CLOSING); - - generatedXML.writeElement("D", "owner", XMLWriter.OPENING); - generatedXML.writeText(owner); - generatedXML.writeElement("D", "owner", XMLWriter.CLOSING); - - generatedXML.writeElement("D", "timeout", XMLWriter.OPENING); - long timeout = (expiresAt - System.currentTimeMillis()) / 1000; - generatedXML.writeText("Second-" + timeout); - generatedXML.writeElement("D", "timeout", XMLWriter.CLOSING); - - generatedXML.writeElement("D", "locktoken", XMLWriter.OPENING); - Enumeration tokensList = tokens.elements(); - while (tokensList.hasMoreElements()) { - generatedXML.writeElement("D", "href", XMLWriter.OPENING); - generatedXML.writeText("opaquelocktoken:" - + tokensList.nextElement()); - generatedXML.writeElement("D", "href", XMLWriter.CLOSING); - } - generatedXML.writeElement("D", "locktoken", XMLWriter.CLOSING); - - generatedXML.writeElement("D", "activelock", XMLWriter.CLOSING); - - } - - - } - - - // --------------------------------------------- WebdavResolver Inner Class - /** - * Work around for XML parsers that don't fully respect - * {@link DocumentBuilderFactory#setExpandEntityReferences(boolean)} when - * called with false. External references are filtered out for - * security reasons. See CVE-2007-5461. - */ - private static class WebdavResolver implements EntityResolver { - private ServletContext context; - - public WebdavResolver(ServletContext theContext) { - context = theContext; - } - - @Override - public InputSource resolveEntity (String publicId, String systemId) { - context.log("webdavservlet.enternalEntityIgnored"); - return new InputSource( - new StringReader("Ignored external entity")); - } - } -} - - -// -------------------------------------------------------- WebdavServletStatus Class - - -/** - * Wraps the HttpServletResponse class to abstract the - * specific protocol used. To support other protocols - * we would only need to modify this class and the - * WebDavRetCode classes. - * - * @author Marc Eaddy - * @version 1.0, 16 Nov 1997 - */ -class WebdavServletStatus { - - - // ----------------------------------------------------- Instance Variables - - - /** - * This Hashtable contains the mapping of HTTP and WebDAV - * status codes to descriptive text. This is a static - * variable. - */ - private static Hashtable mapStatusCodes = - new Hashtable(); - - - // ------------------------------------------------------ HTTP Status Codes - - - /** - * Status code (200) indicating the request succeeded normally. - */ - public static final int SC_OK = HttpServletResponse.SC_OK; - - - /** - * Status code (201) indicating the request succeeded and created - * a new resource on the server. - */ - public static final int SC_CREATED = HttpServletResponse.SC_CREATED; - - - /** - * Status code (202) indicating that a request was accepted for - * processing, but was not completed. - */ - public static final int SC_ACCEPTED = HttpServletResponse.SC_ACCEPTED; - - - /** - * Status code (204) indicating that the request succeeded but that - * there was no new information to return. - */ - public static final int SC_NO_CONTENT = HttpServletResponse.SC_NO_CONTENT; - - - /** - * Status code (301) indicating that the resource has permanently - * moved to a new location, and that future references should use a - * new URI with their requests. - */ - public static final int SC_MOVED_PERMANENTLY = - HttpServletResponse.SC_MOVED_PERMANENTLY; - - - /** - * Status code (302) indicating that the resource has temporarily - * moved to another location, but that future references should - * still use the original URI to access the resource. - */ - public static final int SC_MOVED_TEMPORARILY = - HttpServletResponse.SC_MOVED_TEMPORARILY; - - - /** - * Status code (304) indicating that a conditional GET operation - * found that the resource was available and not modified. - */ - public static final int SC_NOT_MODIFIED = - HttpServletResponse.SC_NOT_MODIFIED; - - - /** - * Status code (400) indicating the request sent by the client was - * syntactically incorrect. - */ - public static final int SC_BAD_REQUEST = - HttpServletResponse.SC_BAD_REQUEST; - - - /** - * Status code (401) indicating that the request requires HTTP - * authentication. - */ - public static final int SC_UNAUTHORIZED = - HttpServletResponse.SC_UNAUTHORIZED; - - - /** - * Status code (403) indicating the server understood the request - * but refused to fulfill it. - */ - public static final int SC_FORBIDDEN = HttpServletResponse.SC_FORBIDDEN; - - - /** - * Status code (404) indicating that the requested resource is not - * available. - */ - public static final int SC_NOT_FOUND = HttpServletResponse.SC_NOT_FOUND; - - - /** - * Status code (500) indicating an error inside the HTTP service - * which prevented it from fulfilling the request. - */ - public static final int SC_INTERNAL_SERVER_ERROR = - HttpServletResponse.SC_INTERNAL_SERVER_ERROR; - - - /** - * Status code (501) indicating the HTTP service does not support - * the functionality needed to fulfill the request. - */ - public static final int SC_NOT_IMPLEMENTED = - HttpServletResponse.SC_NOT_IMPLEMENTED; - - - /** - * Status code (502) indicating that the HTTP server received an - * invalid response from a server it consulted when acting as a - * proxy or gateway. - */ - public static final int SC_BAD_GATEWAY = - HttpServletResponse.SC_BAD_GATEWAY; - - - /** - * Status code (503) indicating that the HTTP service is - * temporarily overloaded, and unable to handle the request. - */ - public static final int SC_SERVICE_UNAVAILABLE = - HttpServletResponse.SC_SERVICE_UNAVAILABLE; - - - /** - * Status code (100) indicating the client may continue with - * its request. This interim response is used to inform the - * client that the initial part of the request has been - * received and has not yet been rejected by the server. - */ - public static final int SC_CONTINUE = 100; - - - /** - * Status code (405) indicating the method specified is not - * allowed for the resource. - */ - public static final int SC_METHOD_NOT_ALLOWED = 405; - - - /** - * Status code (409) indicating that the request could not be - * completed due to a conflict with the current state of the - * resource. - */ - public static final int SC_CONFLICT = 409; - - - /** - * Status code (412) indicating the precondition given in one - * or more of the request-header fields evaluated to false - * when it was tested on the server. - */ - public static final int SC_PRECONDITION_FAILED = 412; - - - /** - * Status code (413) indicating the server is refusing to - * process a request because the request entity is larger - * than the server is willing or able to process. - */ - public static final int SC_REQUEST_TOO_LONG = 413; - - - /** - * Status code (415) indicating the server is refusing to service - * the request because the entity of the request is in a format - * not supported by the requested resource for the requested - * method. - */ - public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415; - - - // -------------------------------------------- Extended WebDav status code - - - /** - * Status code (207) indicating that the response requires - * providing status for multiple independent operations. - */ - public static final int SC_MULTI_STATUS = 207; - // This one collides with HTTP 1.1 - // "207 Partial Update OK" - - - /** - * Status code (418) indicating the entity body submitted with - * the PATCH method was not understood by the resource. - */ - public static final int SC_UNPROCESSABLE_ENTITY = 418; - // This one collides with HTTP 1.1 - // "418 Reauthentication Required" - - - /** - * Status code (419) indicating that the resource does not have - * sufficient space to record the state of the resource after the - * execution of this method. - */ - public static final int SC_INSUFFICIENT_SPACE_ON_RESOURCE = 419; - // This one collides with HTTP 1.1 - // "419 Proxy Reauthentication Required" - - - /** - * Status code (420) indicating the method was not executed on - * a particular resource within its scope because some part of - * the method's execution failed causing the entire method to be - * aborted. - */ - public static final int SC_METHOD_FAILURE = 420; - - - /** - * Status code (423) indicating the destination resource of a - * method is locked, and either the request did not contain a - * valid Lock-Info header, or the Lock-Info header identifies - * a lock held by another principal. - */ - public static final int SC_LOCKED = 423; - - - // ------------------------------------------------------------ Initializer - - - static { - // HTTP 1.0 status Code - addStatusCodeMap(SC_OK, "OK"); - addStatusCodeMap(SC_CREATED, "Created"); - addStatusCodeMap(SC_ACCEPTED, "Accepted"); - addStatusCodeMap(SC_NO_CONTENT, "No Content"); - addStatusCodeMap(SC_MOVED_PERMANENTLY, "Moved Permanently"); - addStatusCodeMap(SC_MOVED_TEMPORARILY, "Moved Temporarily"); - addStatusCodeMap(SC_NOT_MODIFIED, "Not Modified"); - addStatusCodeMap(SC_BAD_REQUEST, "Bad Request"); - addStatusCodeMap(SC_UNAUTHORIZED, "Unauthorized"); - addStatusCodeMap(SC_FORBIDDEN, "Forbidden"); - addStatusCodeMap(SC_NOT_FOUND, "Not Found"); - addStatusCodeMap(SC_INTERNAL_SERVER_ERROR, "Internal Server Error"); - addStatusCodeMap(SC_NOT_IMPLEMENTED, "Not Implemented"); - addStatusCodeMap(SC_BAD_GATEWAY, "Bad Gateway"); - addStatusCodeMap(SC_SERVICE_UNAVAILABLE, "Service Unavailable"); - addStatusCodeMap(SC_CONTINUE, "Continue"); - addStatusCodeMap(SC_METHOD_NOT_ALLOWED, "Method Not Allowed"); - addStatusCodeMap(SC_CONFLICT, "Conflict"); - addStatusCodeMap(SC_PRECONDITION_FAILED, "Precondition Failed"); - addStatusCodeMap(SC_REQUEST_TOO_LONG, "Request Too Long"); - addStatusCodeMap(SC_UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type"); - // WebDav Status Codes - addStatusCodeMap(SC_MULTI_STATUS, "Multi-Status"); - addStatusCodeMap(SC_UNPROCESSABLE_ENTITY, "Unprocessable Entity"); - addStatusCodeMap(SC_INSUFFICIENT_SPACE_ON_RESOURCE, - "Insufficient Space On Resource"); - addStatusCodeMap(SC_METHOD_FAILURE, "Method Failure"); - addStatusCodeMap(SC_LOCKED, "Locked"); - } - - - // --------------------------------------------------------- Public Methods - - - /** - * Returns the HTTP status text for the HTTP or WebDav status code - * specified by looking it up in the static mapping. This is a - * static function. - * - * @param nHttpStatusCode [IN] HTTP or WebDAV status code - * @return A string with a short descriptive phrase for the - * HTTP status code (e.g., "OK"). - */ - public static String getStatusText(int nHttpStatusCode) { - Integer intKey = Integer.valueOf(nHttpStatusCode); - - if (!mapStatusCodes.containsKey(intKey)) { - return ""; - } else { - return mapStatusCodes.get(intKey); - } - } - - - // -------------------------------------------------------- Private Methods - - - /** - * Adds a new status code -> status text mapping. This is a static - * method because the mapping is a static variable. - * - * @param nKey [IN] HTTP or WebDAV status code - * @param strVal [IN] HTTP status text - */ - private static void addStatusCodeMap(int nKey, String strVal) { - mapStatusCodes.put(Integer.valueOf(nKey), strVal); - } - -} - - +/* + Copyright (c) 2011-2012, the Caimito project (http://caimito.ngasi.com/). All rights reserved. +Apache Software License 2.0 +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WebAppShowCase +OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package ngasi.caimito; + + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; +import java.nio.charset.Charset; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Locale; +import java.util.Stack; +import java.util.TimeZone; +import java.util.Vector; + +import javax.naming.NameClassPair; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.DirContext; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.UnavailableException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.catalina.util.DOMWriter; +import org.apache.catalina.util.MD5Encoder; +import org.apache.catalina.util.XMLWriter; +import org.apache.naming.resources.CacheEntry; +import org.apache.naming.resources.Resource; +import org.apache.naming.resources.ResourceAttributes; +import org.apache.tomcat.util.http.FastHttpDateFormat; +import org.apache.tomcat.util.http.RequestUtil; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.apache.catalina.servlets.*; +import ngasi.caimito.resource.*; + + + +/** + * Servlet which adds support for WebDAV level 2. All the basic HTTP requests + * are handled by the DefaultServlet. The WebDAVServlet must not be used as the + * default servlet (ie mapped to '/') as it will not work in this configuration. + *

+ * Mapping a subpath (e.g. /webdav/* to this servlet has the effect + * of re-mounting the entire web application under that sub-path, with WebDAV + * access to all the resources. This WEB-INF and META-INF + * directories are protected in this re-mounted resource tree. + *

+ * To enable WebDAV for a context add the following to web.xml: + *

+ * <servlet>
+ *  <servlet-name>webdav</servlet-name>
+ *  <servlet-class>org.apache.catalina.servlets.WebdavServlet</servlet-class>
+ *    <init-param>
+ *      <param-name>debug</param-name>
+ *      <param-value>0</param-value>
+ *    </init-param>
+ *    <init-param>
+ *      <param-name>listings</param-name>
+ *      <param-value>false</param-value>
+ *    </init-param>
+ *  </servlet>
+ *  <servlet-mapping>
+ *    <servlet-name>webdav</servlet-name>
+ *    <url-pattern>/*</url-pattern>
+ *  </servlet-mapping>
+ * 
+ * This will enable read only access. To enable read-write access add: + *
+ *  <init-param>
+ *    <param-name>readonly</param-name>
+ *    <param-value>false</param-value>
+ *  </init-param>
+ * 
+ * To make the content editable via a different URL, use the following + * mapping: + *
+ *  <servlet-mapping>
+ *    <servlet-name>webdav</servlet-name>
+ *    <url-pattern>/webdavedit/*</url-pattern>
+ *  </servlet-mapping>
+ * 
+ * By default access to /WEB-INF and META-INF are not available via WebDAV. To + * enable access to these URLs, use add: + *
+ *  <init-param>
+ *    <param-name>allowSpecialPaths</param-name>
+ *    <param-value>true</param-value>
+ *  </init-param>
+ * 
+ * Don't forget to secure access appropriately to the editing URLs, especially + * if allowSpecialPaths is used. With the mapping configuration above, the + * context will be accessible to normal users as before. Those users with the + * necessary access will be able to edit content available via + * http://host:port/context/content using + * http://host:port/context/webdavedit/content + * + * @author Remy Maucherat + * @version $Id: WebdavServlet.java 1239053 2012-02-01 10:52:00Z markt $ + */ + +public class CaimitoWebdavServlet + extends CaimitoDefaultServlet { + + private static final long serialVersionUID = 1L; + + + // -------------------------------------------------------------- Constants + + private static final String METHOD_PROPFIND = "PROPFIND"; + private static final String METHOD_PROPPATCH = "PROPPATCH"; + private static final String METHOD_MKCOL = "MKCOL"; + private static final String METHOD_COPY = "COPY"; + private static final String METHOD_MOVE = "MOVE"; + private static final String METHOD_LOCK = "LOCK"; + private static final String METHOD_UNLOCK = "UNLOCK"; + + + /** + * PROPFIND - Specify a property mask. + */ + private static final int FIND_BY_PROPERTY = 0; + + + /** + * PROPFIND - Display all properties. + */ + private static final int FIND_ALL_PROP = 1; + + + /** + * PROPFIND - Return property names. + */ + private static final int FIND_PROPERTY_NAMES = 2; + + + /** + * Create a new lock. + */ + private static final int LOCK_CREATION = 0; + + + /** + * Refresh lock. + */ + private static final int LOCK_REFRESH = 1; + + + /** + * Default lock timeout value. + */ + private static final int DEFAULT_TIMEOUT = 3600; + + + /** + * Maximum lock timeout. + */ + private static final int MAX_TIMEOUT = 604800; + + + /** + * Default namespace. + */ + protected static final String DEFAULT_NAMESPACE = "DAV:"; + + + /** + * Simple date format for the creation date ISO representation (partial). + */ + protected static final SimpleDateFormat creationDateFormat = + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); + + + /** + * MD5 message digest provider. + */ + protected static MessageDigest md5Helper; + + + /** + * The MD5 helper object for this class. + */ + protected static final MD5Encoder md5Encoder = new MD5Encoder(); + + + + static { + creationDateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); + } + + + // ----------------------------------------------------- Instance Variables + + + /** + * Repository of the locks put on single resources. + *

+ * Key : path
+ * Value : LockInfo + */ + private Hashtable resourceLocks = + new Hashtable(); + + + /** + * Repository of the lock-null resources. + *

+ * Key : path of the collection containing the lock-null resource
+ * Value : Vector of lock-null resource which are members of the + * collection. Each element of the Vector is the path associated with + * the lock-null resource. + */ + private Hashtable> lockNullResources = + new Hashtable>(); + + + /** + * Vector of the heritable locks. + *

+ * Key : path
+ * Value : LockInfo + */ + private Vector collectionLocks = new Vector(); + + + /** + * Secret information used to generate reasonably secure lock ids. + */ + private String secret = "catalina"; + + + /** + * Default depth in spec is infinite. Limit depth to 3 by default as + * infinite depth makes operations very expensive. + */ + private int maxDepth = 3; + + + /** + * Is access allowed via WebDAV to the special paths (/WEB-INF and + * /META-INF)? + */ + private boolean allowSpecialPaths = false; + + + // --------------------------------------------------------- Public Methods + + + /** + * Initialize this servlet. + */ + @Override + public void init() + throws ServletException { + + super.init(); + if (getServletConfig().getInitParameter("secret") != null) + secret = getServletConfig().getInitParameter("secret"); + + if (getServletConfig().getInitParameter("maxDepth") != null) + maxDepth = Integer.parseInt( + getServletConfig().getInitParameter("maxDepth")); + + if (getServletConfig().getInitParameter("allowSpecialPaths") != null) + allowSpecialPaths = Boolean.parseBoolean( + getServletConfig().getInitParameter("allowSpecialPaths")); + + // Load the MD5 helper used to calculate signatures. + try { + md5Helper = MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException e) { + throw new UnavailableException("No MD5"); + } + + String rootPath = getServletConfig().getServletContext().getRealPath("/"); + CaimitoConfig.caimitoroot = rootPath; + System.out.println(" Caimito Version " + CaimitoConfig.version); + CaimitoConfig.init(); + + } + + + // ------------------------------------------------------ Protected Methods + + + /** + * Return JAXP document builder instance. + */ + protected DocumentBuilder getDocumentBuilder() + throws ServletException { + DocumentBuilder documentBuilder = null; + DocumentBuilderFactory documentBuilderFactory = null; + try { + documentBuilderFactory = DocumentBuilderFactory.newInstance(); + documentBuilderFactory.setNamespaceAware(true); + documentBuilderFactory.setExpandEntityReferences(false); + documentBuilder = documentBuilderFactory.newDocumentBuilder(); + documentBuilder.setEntityResolver( + new WebdavResolver(this.getServletContext())); + } catch(ParserConfigurationException e) { + throw new ServletException + ("webdavservlet.jaxpfailed"); + } + return documentBuilder; + } + + + /** + * Handles the special WebDAV methods. + */ + @Override + protected void service(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + final String path = getRelativePath(req); + + // Block access to special subdirectories. + // DefaultServlet assumes it services resources from the root of the web app + // and doesn't add any special path protection + // WebdavServlet remounts the webapp under a new path, so this check is + // necessary on all methods (including GET). + // if (isSpecialPath(path)) { + // resp.sendError(WebdavServletStatus.SC_NOT_FOUND); + // return; + //} + + final String method = req.getMethod(); + //(method + " SEEERVICE CAMITO WEBDAV " + path); + + if (debug > 0) { + log("[" + method + "] " + path); + } + + if (method.equals(METHOD_PROPFIND)) { + doPropfind(req, resp); + } else if (method.equals(METHOD_PROPPATCH)) { + doProppatch(req, resp); + } else if (method.equals(METHOD_MKCOL)) { + doMkcol(req, resp); + } else if (method.equals(METHOD_COPY)) { + doCopy(req, resp); + } else if (method.equals(METHOD_MOVE)) { + doMove(req, resp); + } else if (method.equals(METHOD_LOCK)) { + doLock(req, resp); + } else if (method.equals(METHOD_UNLOCK)) { + doUnlock(req, resp); + } else { + // DefaultServlet processing + super.service(req, resp); + } + + } + + + /** + * Checks whether a given path refers to a resource under + * WEB-INF or META-INF. + * @param path the full path of the resource being accessed + * @return true if the resource specified is under a special path + */ + private final boolean isSpecialPath(final String path) { + return !allowSpecialPaths && ( + path.toUpperCase(Locale.ENGLISH).startsWith("/WEB-INF") || + path.toUpperCase(Locale.ENGLISH).startsWith("/META-INF")); + } + + + /** + * Check if the conditions specified in the optional If headers are + * satisfied. + * + * @param request The servlet request we are processing + * @param response The servlet response we are creating + * @param resourceAttributes The resource information + * @return boolean true if the resource meets all the specified conditions, + * and false if any of the conditions is not satisfied, in which case + * request processing is stopped + */ + /*@Override + protected boolean checkIfHeaders(HttpServletRequest request, + HttpServletResponse response, + ResourceAttributes resourceAttributes) + throws IOException { + + if (!super.checkIfHeaders(request, response, resourceAttributes)) + return false; + + // TODO : Checking the WebDAV If header + return true; + + }*/ + + + /** + * Override the DefaultServlet implementation and only use the PathInfo. If + * the ServletPath is non-null, it will be because the WebDAV servlet has + * been mapped to a url other than /* to configure editing at different url + * than normal viewing. + * + * @param request The servlet request we are processing + */ + @Override + protected String getRelativePath(HttpServletRequest request) { + // Are we being processed by a RequestDispatcher.include()? + if (request.getAttribute( + RequestDispatcher.INCLUDE_REQUEST_URI) != null) { + String result = (String) request.getAttribute( + RequestDispatcher.INCLUDE_PATH_INFO); + if ((result == null) || (result.equals(""))) + result = "/"; + /* result = tools.util.StringUtil.replaceSubstring(result,"..",""); + result = tools.util.StringUtil.replaceSubstring(result,"//","\\"); + result = tools.util.StringUtil.replaceSubstring(result,"\\","/"); + result = tools.util.StringUtil.replaceSubstring(result,":",""); +*/ + result = CaimitoUtil.normalize(result); + return (result); + } + + // No, extract the desired path directly from the request + String result = request.getPathInfo(); + if ((result == null) || (result.equals(""))) { + result = "/"; + } + /* + result = tools.util.StringUtil.replaceSubstring(result,"..",""); + result = tools.util.StringUtil.replaceSubstring(result,"//","\\"); + result = tools.util.StringUtil.replaceSubstring(result,"\\","/"); + result = tools.util.StringUtil.replaceSubstring(result,":",""); +*/ + result = CaimitoUtil.normalize(result); + + return (result); + + } + + + /** + * Determines the prefix for standard directory GET listings. + */ + @Override + protected String getPathPrefix(final HttpServletRequest request) { + // Repeat the servlet path (e.g. /webdav/) in the listing path + String contextPath = request.getContextPath(); + if (request.getServletPath() != null) { + contextPath = contextPath + request.getServletPath(); + } + return contextPath; + } + + + /** + * OPTIONS Method. + * + * @param req The request + * @param resp The response + * @throws ServletException If an error occurs + * @throws IOException If an IO error occurs + */ + @Override + protected void doOptions(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + resp.addHeader("DAV", "1,2"); + + StringBuilder methodsAllowed = determineMethodsAllowed(req,resp); + //(methodsAllowed + " DOP 2"); + + resp.addHeader("Allow", methodsAllowed.toString()); + resp.addHeader("MS-Author-Via", "DAV"); + + } + + + /** + * PROPFIND Method. + */ + protected void doPropfind(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + + + String path = getRelativePath(req); + if (path.endsWith("/")) + path = path.substring(0, path.length() - 1); + + ResourceObj ro = ResourceStore.lookup(path,req,resp,ResourceStore.READ); + if (ro == null)return; + + if (!ro.listings()) { + // Get allowed methods + StringBuilder methodsAllowed = determineMethodsAllowed( req,resp); + + resp.addHeader("Allow", methodsAllowed.toString()); + resp.sendError(WebdavServletStatus.SC_METHOD_NOT_ALLOWED); + return; + } + + // Properties which are to be displayed. + Vector properties = null; + // Propfind depth + int depth = maxDepth; + // Propfind type + int type = FIND_ALL_PROP; + + String depthStr = req.getHeader("Depth"); + + if (depthStr == null) { + depth = maxDepth; + } else { + if (depthStr.equals("0")) { + depth = 0; + } else if (depthStr.equals("1")) { + depth = 1; + } else if (depthStr.equals("infinity")) { + depth = maxDepth; + } + } + + Node propNode = null; + + if (req.getContentLength() > 0) { + DocumentBuilder documentBuilder = getDocumentBuilder(); + + try { + Document document = documentBuilder.parse + (new InputSource(req.getInputStream())); + + // Get the root element of the document + Element rootElement = document.getDocumentElement(); + NodeList childList = rootElement.getChildNodes(); + + for (int i=0; i < childList.getLength(); i++) { + Node currentNode = childList.item(i); + switch (currentNode.getNodeType()) { + case Node.TEXT_NODE: + break; + case Node.ELEMENT_NODE: + if (currentNode.getNodeName().endsWith("prop")) { + type = FIND_BY_PROPERTY; + propNode = currentNode; + } + if (currentNode.getNodeName().endsWith("propname")) { + type = FIND_PROPERTY_NAMES; + } + if (currentNode.getNodeName().endsWith("allprop")) { + type = FIND_ALL_PROP; + } + break; + } + } + } catch (SAXException e) { + // Something went wrong - bad request + resp.sendError(WebdavServletStatus.SC_BAD_REQUEST); + } catch (IOException e) { + // Something went wrong - bad request + resp.sendError(WebdavServletStatus.SC_BAD_REQUEST); + } + } + + //(path + " PROP FINDE TYPE " + type ); + if (type == FIND_BY_PROPERTY) { + properties = new Vector(); + // propNode must be non-null if type == FIND_BY_PROPERTY + @SuppressWarnings("null") + NodeList childList = propNode.getChildNodes(); + + for (int i=0; i < childList.getLength(); i++) { + Node currentNode = childList.item(i); + switch (currentNode.getNodeType()) { + case Node.TEXT_NODE: + break; + case Node.ELEMENT_NODE: + String nodeName = currentNode.getNodeName(); + String propertyName = null; + if (nodeName.indexOf(':') != -1) { + propertyName = nodeName.substring + (nodeName.indexOf(':') + 1); + } else { + propertyName = nodeName; + } + // href is a live property which is handled differently + properties.addElement(propertyName); + break; + } + } + + } + + boolean exists = ro.exists(); + /*Object object = null; + try { + object = resources.lookup(path); + } catch (NamingException e) { + exists = false; + int slash = path.lastIndexOf('/'); + if (slash != -1) { + String parentPath = path.substring(0, slash); + Vector currentLockNullResources = + lockNullResources.get(parentPath); + if (currentLockNullResources != null) { + Enumeration lockNullResourcesList = + currentLockNullResources.elements(); + while (lockNullResourcesList.hasMoreElements()) { + String lockNullPath = + lockNullResourcesList.nextElement(); + if (lockNullPath.equals(path)) { + resp.setStatus(WebdavServletStatus.SC_MULTI_STATUS); + resp.setContentType("text/xml; charset=UTF-8"); + // Create multistatus object + XMLWriter generatedXML = + new XMLWriter(resp.getWriter()); + generatedXML.writeXMLHeader(); + generatedXML.writeElement("D", DEFAULT_NAMESPACE, + "multistatus", XMLWriter.OPENING); + parseLockNullProperties + (req, generatedXML, lockNullPath, type, + properties); + generatedXML.writeElement("D", "multistatus", + XMLWriter.CLOSING); + generatedXML.sendData(); + return; + } + } + } + } + }*/ + + if (!exists) { + resp.sendError(HttpServletResponse.SC_NOT_FOUND, path); + return; + } + + resp.setStatus(WebdavServletStatus.SC_MULTI_STATUS); + + resp.setContentType("text/xml; charset=UTF-8"); + + // Create multistatus object + XMLWriter generatedXML = new XMLWriter(resp.getWriter()); + generatedXML.writeXMLHeader(); + + generatedXML.writeElement("D", DEFAULT_NAMESPACE, "multistatus", + XMLWriter.OPENING); + + if (depth == 0) { + parseProperties(req,resp, generatedXML, path, type, + properties); + } else { + // The stack always contains the object of the current level + Stack stack = new Stack(); + stack.push(path); + + // Stack of the objects one level below + Stack stackBelow = new Stack(); + ResourceObj rob = null; + while ((!stack.isEmpty()) && (depth >= 0)) { + + String currentPath = stack.pop(); + parseProperties(req,resp, generatedXML, currentPath, + type, properties); + + // try { + //object = resources.lookup(currentPath); + rob = ResourceStore.lookup(currentPath,req,resp,ResourceStore.READ); + + // } catch (Exception e) { + // continue; + // } + + if ((rob.isDirectory()) && (depth > 0)) { + + try { + Enumeration enumeration = + rob.list().elements(); + while (enumeration.hasMoreElements()) { + ResourceObj ncPair = enumeration.nextElement(); + //String newPath = currentPath; + //if (!(newPath.endsWith("/"))) + // newPath += "/"; + //newPath += ncPair.getName(); + stackBelow.push(ncPair.path); + } + } catch (Exception e) { + e.printStackTrace(); + resp.sendError + (HttpServletResponse.SC_INTERNAL_SERVER_ERROR, + path); + return; + } + + // Displaying the lock-null resources present in that + // collection + String lockPath = currentPath; + if (lockPath.endsWith("/")) + lockPath = + lockPath.substring(0, lockPath.length() - 1); + Vector currentLockNullResources = + lockNullResources.get(lockPath); + if (currentLockNullResources != null) { + Enumeration lockNullResourcesList = + currentLockNullResources.elements(); + while (lockNullResourcesList.hasMoreElements()) { + String lockNullPath = + lockNullResourcesList.nextElement(); + parseLockNullProperties + (req, generatedXML, lockNullPath, type, + properties); + } + } + + } + + if (stack.isEmpty()) { + depth--; + stack = stackBelow; + stackBelow = new Stack(); + } + + generatedXML.sendData(); + + } + } + + generatedXML.writeElement("D", "multistatus", XMLWriter.CLOSING); + + generatedXML.sendData(); + //("generatedXML,value " + generatedXML); + + } + + + /** + * PROPPATCH Method. + */ + protected void doProppatch(HttpServletRequest req, HttpServletResponse resp) + throws IOException { +/* + if (readOnly) { + resp.sendError(WebdavServletStatus.SC_FORBIDDEN); + return; + } + + if (isLocked(req)) { + resp.sendError(WebdavServletStatus.SC_LOCKED); + return; + } + + resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); +*/ + //resp.setStatus(200); + resp.setContentType("text/xml"); + String propr = "\r\n" + +"\r\n" + +" \r\n" + + " \r\n" + + " HTTP/1.1 200 OK\r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + +"\r\n"; +resp.getWriter().print(propr); + + } + + + /** + * MKCOL Method. + */ + protected void doMkcol(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + /*if (readOnly) { + resp.sendError(WebdavServletStatus.SC_FORBIDDEN); + return; + } + + if (isLocked(req)) { + resp.sendError(WebdavServletStatus.SC_LOCKED); + return; + }*/ + + String path = getRelativePath(req); + + /*boolean exists = true; + try { + resources.lookup(path); + } catch (NamingException e) { + exists = false; + }*/ + + // Can't create a collection if a resource already exists at the given + // path + + + ResourceObj ro = ResourceStore.lookup(path,req,resp,ResourceStore.WRITE); + if (ro == null)return; + + if (!ro.canWrite()) { + resp.sendError(HttpServletResponse.SC_FORBIDDEN); + return; + } + + boolean exists = ro.exists(); + + if (exists) { + // Get allowed methods + StringBuilder methodsAllowed = determineMethodsAllowed( req,resp); + + resp.addHeader("Allow", methodsAllowed.toString()); + + resp.sendError(WebdavServletStatus.SC_METHOD_NOT_ALLOWED); + return; + } + + if (req.getContentLength() > 0) { + //("MKCOL IS MORE DATA"); + DocumentBuilder documentBuilder = getDocumentBuilder(); + try { + // Document document = + documentBuilder.parse(new InputSource(req.getInputStream())); + // TODO : Process this request body + resp.sendError(WebdavServletStatus.SC_NOT_IMPLEMENTED); + return; + + } catch(SAXException saxe) { + // Parse error - assume invalid content + resp.sendError(WebdavServletStatus.SC_UNSUPPORTED_MEDIA_TYPE); + return; + } + } + + try{ + ro.mkdir(); + resp.setStatus(WebdavServletStatus.SC_CREATED); + + }catch (Exception e){ + e.printStackTrace(); + resp.sendError(WebdavServletStatus.SC_CONFLICT, + WebdavServletStatus.getStatusText + (WebdavServletStatus.SC_CONFLICT)); + } + + /*boolean result = true; + try { + resources.createSubcontext(path); + } catch (NamingException e) { + result = false; + } + + if (!result) { + resp.sendError(WebdavServletStatus.SC_CONFLICT, + WebdavServletStatus.getStatusText + (WebdavServletStatus.SC_CONFLICT)); + } else { + resp.setStatus(WebdavServletStatus.SC_CREATED); + // Removing any lock-null resource which would be present + lockNullResources.remove(path); + }*/ + + } + + + /** + * DELETE Method. + */ + /*@Override + protected void doDelete(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + if (readOnly) { + resp.sendError(WebdavServletStatus.SC_FORBIDDEN); + return; + } + + if (isLocked(req)) { + resp.sendError(WebdavServletStatus.SC_LOCKED); + return; + } + + deleteResource(req, resp); + + }*/ + + + /** + * Process a PUT request for the specified resource. + * + * @param req The servlet request we are processing + * @param resp The servlet response we are creating + * + * @exception IOException if an input/output error occurs + * @exception ServletException if a servlet-specified error occurs + */ + @Override + protected void doPut(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + String path = getRelativePath(req); + + if (isLocked(req)) { + //(path + " IS A LIOCLLERD "); + resp.sendError(WebdavServletStatus.SC_LOCKED); + return; + } + + super.doPut(req, resp); + + + // Removing any lock-null resource which would be present + lockNullResources.remove(path); + + } + + /** + * COPY Method. + */ + protected void doCopy(HttpServletRequest req, HttpServletResponse resp) + throws ServletException,IOException { + + /// if (readOnly) { + // resp.sendError(WebdavServletStatus.SC_FORBIDDEN); + // return; + // } + + copyResource(req, resp); + + } + + + + private boolean moveResource(HttpServletRequest req, + HttpServletResponse resp) + throws CaimitoException,IOException { + + // Parsing destination header + + String destinationPath = req.getHeader("Destination"); + + if (destinationPath == null) { + resp.sendError(WebdavServletStatus.SC_BAD_REQUEST); + return false; + } + + // Remove url encoding from destination + destinationPath = org.apache.catalina.util.RequestUtil.URLDecode( + destinationPath, "UTF8"); + + int protocolIndex = destinationPath.indexOf("://"); + if (protocolIndex >= 0) { + // if the Destination URL contains the protocol, we can safely + // trim everything upto the first "/" character after "://" + int firstSeparator = + destinationPath.indexOf("/", protocolIndex + 4); + if (firstSeparator < 0) { + destinationPath = "/"; + } else { + destinationPath = destinationPath.substring(firstSeparator); + } + } else { + String hostName = req.getServerName(); + if ((hostName != null) && (destinationPath.startsWith(hostName))) { + destinationPath = destinationPath.substring(hostName.length()); + } + + int portIndex = destinationPath.indexOf(":"); + if (portIndex >= 0) { + destinationPath = destinationPath.substring(portIndex); + } + + if (destinationPath.startsWith(":")) { + int firstSeparator = destinationPath.indexOf("/"); + if (firstSeparator < 0) { + destinationPath = "/"; + } else { + destinationPath = + destinationPath.substring(firstSeparator); + } + } + } + + // Normalise destination path (remove '.' and '..') + destinationPath = RequestUtil.normalize(destinationPath); + + String contextPath = req.getContextPath(); + if ((contextPath != null) && + (destinationPath.startsWith(contextPath))) { + destinationPath = destinationPath.substring(contextPath.length()); + } + + String pathInfo = req.getPathInfo(); + if (pathInfo != null) { + String servletPath = req.getServletPath(); + if ((servletPath != null) && + (destinationPath.startsWith(servletPath))) { + destinationPath = destinationPath + .substring(servletPath.length()); + } + } + + if (debug > 0) + log("Dest path :" + destinationPath); + + // Check destination path to protect special subdirectories + //if (isSpecialPath(destinationPath)) { + // resp.sendError(WebdavServletStatus.SC_FORBIDDEN); + // return false; + //} + + String path = getRelativePath(req); + + if (destinationPath.equals(path)) { + resp.sendError(WebdavServletStatus.SC_FORBIDDEN); + return false; + } + + // Parsing overwrite header + + boolean overwrite = true; + String overwriteHeader = req.getHeader("Overwrite"); + + if (overwriteHeader != null) { + if (overwriteHeader.equalsIgnoreCase("T")) { + overwrite = true; + } else { + overwrite = false; + } + } + + // Overwriting the destination + ResourceObj ro = ResourceStore.lookup(destinationPath,req,resp,ResourceStore.WRITE); + if (ro == null) + return false; + + ResourceObj ros = ResourceStore.lookup(path,req,resp,ResourceStore.READ); + + // if (!ro.canWrite() || !ros.canWrite()) { + if (ro == null || ros == null){ + + //resp.sendError(WebdavServletStatus.SC_FORBIDDEN); + //return false; + return false; + } + + boolean exists = ro.exists(); + /*try { + resources.lookup(destinationPath); + } catch (NamingException e) { + exists = false; + }*/ + + if (overwrite) { + + // destination resource, if it exists + if (exists) { + //if (! Resource(destinationPath, req, resp, true)) { + // return false; + //} + ro.delete(); + } else { + resp.setStatus(WebdavServletStatus.SC_CREATED); + } + + } else { + + // If the destination exists, then it's a conflict + if (exists) { + resp.sendError(WebdavServletStatus.SC_PRECONDITION_FAILED); + return false; + } + + } + + // Copying source to destination + + ros.move(ro); + /*Hashtable errorList = new Hashtable(); + + boolean result = copyResource(resources, errorList, + path, destinationPath); + + if ((!result) || (!errorList.isEmpty())) { + if (errorList.size() == 1) { + resp.sendError(errorList.elements().nextElement().intValue()); + } else { + sendReport(req, resp, errorList); + } + return false; + }*/ + + // Copy was successful + if (exists) { + resp.setStatus(WebdavServletStatus.SC_NO_CONTENT); + } else { + resp.setStatus(WebdavServletStatus.SC_CREATED); + } + + // Removing any lock-null resource which would be present at + // the destination path + lockNullResources.remove(destinationPath); + + return true; + + } + + /** + * MOVE Method. + */ + protected void doMove(HttpServletRequest req, HttpServletResponse resp) + throws ServletException,IOException { + + /*if (readOnly) { + resp.sendError(WebdavServletStatus.SC_FORBIDDEN); + return; + } + + if (isLocked(req)) { + resp.sendError(WebdavServletStatus.SC_LOCKED); + return; + }*/ + + /*String path = getRelativePath(req); + ResourceObj ros = ResourceStore.lookup(path,req,resp); + + if (!ros.canWrite()) { + resp.sendError(WebdavServletStatus.SC_FORBIDDEN); + return ; + }*/ + + moveResource(req, resp); + // Resource(path, req, resp, false); + //ros.move(); + //} + + } + + + /** + * LOCK Method. + */ + + /* + protected void doLock(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + }*/ + protected void doLock(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + /*if (readOnly) { + resp.sendError(WebdavServletStatus.SC_FORBIDDEN); + return; + } + + if (isLocked(req)) { + resp.sendError(WebdavServletStatus.SC_LOCKED); + return; + }*/ + + LockInfo lock = new LockInfo(); + + + String depthStr = req.getHeader("Depth"); + + if (depthStr == null) { + lock.depth = maxDepth; + } else { + if (depthStr.equals("0")) { + lock.depth = 0; + } else { + lock.depth = maxDepth; + } + } + + // Parsing timeout header + + int lockDuration = DEFAULT_TIMEOUT; + String lockDurationStr = req.getHeader("Timeout"); + if (lockDurationStr == null) { + lockDuration = DEFAULT_TIMEOUT; + } else { + int commaPos = lockDurationStr.indexOf(","); + // If multiple timeouts, just use the first + if (commaPos != -1) { + lockDurationStr = lockDurationStr.substring(0,commaPos); + } + if (lockDurationStr.startsWith("Second-")) { + lockDuration = + (new Integer(lockDurationStr.substring(7))).intValue(); + } else { + if (lockDurationStr.equalsIgnoreCase("infinity")) { + lockDuration = MAX_TIMEOUT; + } else { + try { + lockDuration = + (new Integer(lockDurationStr)).intValue(); + } catch (NumberFormatException e) { + lockDuration = MAX_TIMEOUT; + } + } + } + if (lockDuration == 0) { + lockDuration = DEFAULT_TIMEOUT; + } + if (lockDuration > MAX_TIMEOUT) { + lockDuration = MAX_TIMEOUT; + } + } + lock.expiresAt = System.currentTimeMillis() + (lockDuration * 1000); + + int lockRequestType = LOCK_CREATION; + + Node lockInfoNode = null; + + DocumentBuilder documentBuilder = getDocumentBuilder(); + + try { + Document document = documentBuilder.parse(new InputSource + (req.getInputStream())); + + // Get the root element of the document + Element rootElement = document.getDocumentElement(); + lockInfoNode = rootElement; + } catch (IOException e) { + lockRequestType = LOCK_REFRESH; + } catch (SAXException e) { + lockRequestType = LOCK_REFRESH; + } + + if (lockInfoNode != null) { + + // Reading lock information + + NodeList childList = lockInfoNode.getChildNodes(); + StringWriter strWriter = null; + DOMWriter domWriter = null; + + Node lockScopeNode = null; + Node lockTypeNode = null; + Node lockOwnerNode = null; + + for (int i=0; i < childList.getLength(); i++) { + Node currentNode = childList.item(i); + switch (currentNode.getNodeType()) { + case Node.TEXT_NODE: + break; + case Node.ELEMENT_NODE: + String nodeName = currentNode.getNodeName(); + if (nodeName.endsWith("lockscope")) { + lockScopeNode = currentNode; + } + if (nodeName.endsWith("locktype")) { + lockTypeNode = currentNode; + } + if (nodeName.endsWith("owner")) { + lockOwnerNode = currentNode; + } + break; + } + } + + if (lockScopeNode != null) { + + childList = lockScopeNode.getChildNodes(); + for (int i=0; i < childList.getLength(); i++) { + Node currentNode = childList.item(i); + switch (currentNode.getNodeType()) { + case Node.TEXT_NODE: + break; + case Node.ELEMENT_NODE: + String tempScope = currentNode.getNodeName(); + if (tempScope.indexOf(':') != -1) { + lock.scope = tempScope.substring + (tempScope.indexOf(':') + 1); + } else { + lock.scope = tempScope; + } + break; + } + } + + if (lock.scope == null) { + // Bad request + resp.setStatus(WebdavServletStatus.SC_BAD_REQUEST); + } + + } else { + // Bad request + resp.setStatus(WebdavServletStatus.SC_BAD_REQUEST); + } + + if (lockTypeNode != null) { + + childList = lockTypeNode.getChildNodes(); + for (int i=0; i < childList.getLength(); i++) { + Node currentNode = childList.item(i); + switch (currentNode.getNodeType()) { + case Node.TEXT_NODE: + break; + case Node.ELEMENT_NODE: + String tempType = currentNode.getNodeName(); + if (tempType.indexOf(':') != -1) { + lock.type = + tempType.substring(tempType.indexOf(':') + 1); + } else { + lock.type = tempType; + } + break; + } + } + + if (lock.type == null) { + // Bad request + resp.setStatus(WebdavServletStatus.SC_BAD_REQUEST); + } + + } else { + // Bad request + resp.setStatus(WebdavServletStatus.SC_BAD_REQUEST); + } + + if (lockOwnerNode != null) { + + childList = lockOwnerNode.getChildNodes(); + for (int i=0; i < childList.getLength(); i++) { + Node currentNode = childList.item(i); + switch (currentNode.getNodeType()) { + case Node.TEXT_NODE: + lock.owner += currentNode.getNodeValue(); + break; + case Node.ELEMENT_NODE: + strWriter = new StringWriter(); + domWriter = new DOMWriter(strWriter, true); + domWriter.setQualifiedNames(false); + domWriter.print(currentNode); + lock.owner += strWriter.toString(); + break; + } + } + + if (lock.owner == null) { + // Bad request + resp.setStatus(WebdavServletStatus.SC_BAD_REQUEST); + } + + } else { + lock.owner = ""; + } + + } + + String path = getRelativePath(req); + + lock.path = path; + ResourceObj ro = ResourceStore.lookup(path,req,resp,ResourceStore.WRITE); + if (ro == null)return; + boolean exists = ro.exists(); + /*Object object = null; + try { + object = resources.lookup(path); + } catch (NamingException e) { + exists = false; + }*/ + + Enumeration locksList = null; + + if (lockRequestType == LOCK_CREATION) { + + // Generating lock id + String lockTokenStr = req.getServletPath() + "-" + lock.type + "-" + + lock.scope + "-" + req.getUserPrincipal() + "-" + + lock.depth + "-" + lock.owner + "-" + lock.tokens + "-" + + lock.expiresAt + "-" + System.currentTimeMillis() + "-" + + secret; + String lockToken = md5Encoder.encode(md5Helper.digest( + lockTokenStr.getBytes(Charset.defaultCharset()))); + + if ( (exists) && (ro.isDirectory()) && + (lock.depth == maxDepth) ) { + + // Locking a collection (and all its member resources) + + // Checking if a child resource of this collection is + // already locked + Vector lockPaths = new Vector(); + locksList = collectionLocks.elements(); + while (locksList.hasMoreElements()) { + LockInfo currentLock = locksList.nextElement(); + if (currentLock.hasExpired()) { + resourceLocks.remove(currentLock.path); + continue; + } + if ( (currentLock.path.startsWith(lock.path)) && + ((currentLock.isExclusive()) || + (lock.isExclusive())) ) { + // A child collection of this collection is locked + lockPaths.addElement(currentLock.path); + } + } + locksList = resourceLocks.elements(); + while (locksList.hasMoreElements()) { + LockInfo currentLock = locksList.nextElement(); + if (currentLock.hasExpired()) { + resourceLocks.remove(currentLock.path); + continue; + } + if ( (currentLock.path.startsWith(lock.path)) && + ((currentLock.isExclusive()) || + (lock.isExclusive())) ) { + // A child resource of this collection is locked + lockPaths.addElement(currentLock.path); + } + } + + if (!lockPaths.isEmpty()) { + + // One of the child paths was locked + // We generate a multistatus error report + + Enumeration lockPathsList = lockPaths.elements(); + + resp.setStatus(WebdavServletStatus.SC_CONFLICT); + + XMLWriter generatedXML = new XMLWriter(); + generatedXML.writeXMLHeader(); + + generatedXML.writeElement("D", DEFAULT_NAMESPACE, + "multistatus", XMLWriter.OPENING); + + while (lockPathsList.hasMoreElements()) { + generatedXML.writeElement("D", "response", + XMLWriter.OPENING); + generatedXML.writeElement("D", "href", + XMLWriter.OPENING); + generatedXML.writeText(lockPathsList.nextElement()); + generatedXML.writeElement("D", "href", + XMLWriter.CLOSING); + generatedXML.writeElement("D", "status", + XMLWriter.OPENING); + generatedXML + .writeText("HTTP/1.1 " + WebdavServletStatus.SC_LOCKED + + " " + WebdavServletStatus + .getStatusText(WebdavServletStatus.SC_LOCKED)); + generatedXML.writeElement("D", "status", + XMLWriter.CLOSING); + + generatedXML.writeElement("D", "response", + XMLWriter.CLOSING); + } + + generatedXML.writeElement("D", "multistatus", + XMLWriter.CLOSING); + + Writer writer = resp.getWriter(); + writer.write(generatedXML.toString()); + writer.close(); + + return; + + } + + boolean addLock = true; + + // Checking if there is already a shared lock on this path + locksList = collectionLocks.elements(); + while (locksList.hasMoreElements()) { + + LockInfo currentLock = locksList.nextElement(); + if (currentLock.path.equals(lock.path)) { + + if (currentLock.isExclusive()) { + resp.sendError(WebdavServletStatus.SC_LOCKED); + return; + } else { + if (lock.isExclusive()) { + resp.sendError(WebdavServletStatus.SC_LOCKED); + return; + } + } + + currentLock.tokens.addElement(lockToken); + lock = currentLock; + addLock = false; + + } + + } + + if (addLock) { + lock.tokens.addElement(lockToken); + collectionLocks.addElement(lock); + } + + } else { + + // Locking a single resource + + // Retrieving an already existing lock on that resource + LockInfo presentLock = resourceLocks.get(lock.path); + if (presentLock != null) { + + if ((presentLock.isExclusive()) || (lock.isExclusive())) { + // If either lock is exclusive, the lock can't be + // granted + resp.sendError(WebdavServletStatus.SC_PRECONDITION_FAILED); + return; + } else { + presentLock.tokens.addElement(lockToken); + lock = presentLock; + } + + } else { + + lock.tokens.addElement(lockToken); + //FREE WORLD + //resourceLocks.put(lock.path, lock); + + // Checking if a resource exists at this path + /*exists = true; + try { + object = resources.lookup(path); + } catch (NamingException e) { + exists = false; + }*/ + if (!exists) { + + // "Creating" a lock-null resource + int slash = lock.path.lastIndexOf('/'); + String parentPath = lock.path.substring(0, slash); + + Vector lockNulls = + lockNullResources.get(parentPath); + if (lockNulls == null) { + lockNulls = new Vector(); + //FREE WORLD + //lockNullResources.put(parentPath, lockNulls); + } + + //FREE WORLD + //lockNulls.addElement(lock.path); + + } + // Add the Lock-Token header as by RFC 2518 8.10.1 + // - only do this for newly created locks + resp.addHeader("Lock-Token", ""); + //(" LOCKY TOKEN " + lockToken); + } + + } + + } + + if (lockRequestType == LOCK_REFRESH) { + + String ifHeader = req.getHeader("If"); + if (ifHeader == null) + ifHeader = ""; + + // Checking resource locks + + LockInfo toRenew = resourceLocks.get(path); + Enumeration tokenList = null; + + if (toRenew != null) { + // At least one of the tokens of the locks must have been given + tokenList = toRenew.tokens.elements(); + while (tokenList.hasMoreElements()) { + String token = tokenList.nextElement(); + if (ifHeader.indexOf(token) != -1) { + toRenew.expiresAt = lock.expiresAt; + lock = toRenew; + } + } + } + + // Checking inheritable collection locks + + Enumeration collectionLocksList = + collectionLocks.elements(); + while (collectionLocksList.hasMoreElements()) { + toRenew = collectionLocksList.nextElement(); + if (path.equals(toRenew.path)) { + + tokenList = toRenew.tokens.elements(); + while (tokenList.hasMoreElements()) { + String token = tokenList.nextElement(); + if (ifHeader.indexOf(token) != -1) { + toRenew.expiresAt = lock.expiresAt; + lock = toRenew; + } + } + + } + } + + } + + // Set the status, then generate the XML response containing + // the lock information + XMLWriter generatedXML = new XMLWriter(); + generatedXML.writeXMLHeader(); + generatedXML.writeElement("D", DEFAULT_NAMESPACE, "prop", + XMLWriter.OPENING); + + generatedXML.writeElement("D", "lockdiscovery", XMLWriter.OPENING); + + lock.toXML(generatedXML); + + generatedXML.writeElement("D", "lockdiscovery", XMLWriter.CLOSING); + + generatedXML.writeElement("D", "prop", XMLWriter.CLOSING); + + resp.setStatus(WebdavServletStatus.SC_OK); + resp.setContentType("text/xml; charset=UTF-8"); + Writer writer = resp.getWriter(); + writer.write(generatedXML.toString()); + //(path + " XMLE RITER W " + generatedXML.toString()); + writer.close(); + + } + + + /** + * UNLOCK Method. + */ + protected void doUnlock(HttpServletRequest req, HttpServletResponse resp) + throws IOException { + + } + + protected void doUnlock1(HttpServletRequest req, HttpServletResponse resp) + throws IOException { + + if (readOnly) { + resp.sendError(WebdavServletStatus.SC_FORBIDDEN); + return; + } + + if (isLocked(req)) { + resp.sendError(WebdavServletStatus.SC_LOCKED); + return; + } + + String path = getRelativePath(req); + + String lockTokenHeader = req.getHeader("Lock-Token"); + if (lockTokenHeader == null) + lockTokenHeader = ""; + + // Checking resource locks + + LockInfo lock = resourceLocks.get(path); + Enumeration tokenList = null; + if (lock != null) { + + // At least one of the tokens of the locks must have been given + + tokenList = lock.tokens.elements(); + while (tokenList.hasMoreElements()) { + String token = tokenList.nextElement(); + if (lockTokenHeader.indexOf(token) != -1) { + lock.tokens.removeElement(token); + } + } + + if (lock.tokens.isEmpty()) { + resourceLocks.remove(path); + // Removing any lock-null resource which would be present + lockNullResources.remove(path); + } + + } + + // Checking inheritable collection locks + + Enumeration collectionLocksList = collectionLocks.elements(); + while (collectionLocksList.hasMoreElements()) { + lock = collectionLocksList.nextElement(); + if (path.equals(lock.path)) { + + tokenList = lock.tokens.elements(); + while (tokenList.hasMoreElements()) { + String token = tokenList.nextElement(); + if (lockTokenHeader.indexOf(token) != -1) { + lock.tokens.removeElement(token); + break; + } + } + + if (lock.tokens.isEmpty()) { + collectionLocks.removeElement(lock); + // Removing any lock-null resource which would be present + lockNullResources.remove(path); + } + + } + } + + resp.setStatus(WebdavServletStatus.SC_NO_CONTENT); + + } + + // -------------------------------------------------------- Private Methods + + /** + * Check to see if a resource is currently write locked. The method + * will look at the "If" header to make sure the client + * has give the appropriate lock tokens. + * + * @param req Servlet request + * @return boolean true if the resource is locked (and no appropriate + * lock token has been found for at least one of the non-shared locks which + * are present on the resource). + */ + private boolean isLocked(HttpServletRequest req) { + + String path = getRelativePath(req); + + String ifHeader = req.getHeader("If"); + if (ifHeader == null) + ifHeader = ""; + + String lockTokenHeader = req.getHeader("Lock-Token"); + if (lockTokenHeader == null) + lockTokenHeader = ""; + + return isLocked(path, ifHeader + lockTokenHeader); + + } + + + /** + * Check to see if a resource is currently write locked. + * + * @param path Path of the resource + * @param ifHeader "If" HTTP header which was included in the request + * @return boolean true if the resource is locked (and no appropriate + * lock token has been found for at least one of the non-shared locks which + * are present on the resource). + */ + private boolean isLocked(String path, String ifHeader) { + + // Checking resource locks + + LockInfo lock = resourceLocks.get(path); + Enumeration tokenList = null; + if ((lock != null) && (lock.hasExpired())) { + resourceLocks.remove(path); + } else if (lock != null) { + + // At least one of the tokens of the locks must have been given + + tokenList = lock.tokens.elements(); + boolean tokenMatch = false; + while (tokenList.hasMoreElements()) { + String token = tokenList.nextElement(); + if (ifHeader.indexOf(token) != -1) + tokenMatch = true; + } + if (!tokenMatch) + return true; + + } + + // Checking inheritable collection locks + + Enumeration collectionLocksList = collectionLocks.elements(); + while (collectionLocksList.hasMoreElements()) { + lock = collectionLocksList.nextElement(); + if (lock.hasExpired()) { + collectionLocks.removeElement(lock); + } else if (path.startsWith(lock.path)) { + + tokenList = lock.tokens.elements(); + boolean tokenMatch = false; + while (tokenList.hasMoreElements()) { + String token = tokenList.nextElement(); + if (ifHeader.indexOf(token) != -1) + tokenMatch = true; + } + if (!tokenMatch) + return true; + + } + } + + return false; + + } + + + /** + * Copy a resource. + * + * @param req Servlet request + * @param resp Servlet response + * @return boolean true if the copy is successful + */ + private boolean copyResource(HttpServletRequest req, + HttpServletResponse resp) + throws CaimitoException,IOException { + + // Parsing destination header + + String destinationPath = req.getHeader("Destination"); + + if (destinationPath == null) { + resp.sendError(WebdavServletStatus.SC_BAD_REQUEST); + return false; + } + + // Remove url encoding from destination + destinationPath = org.apache.catalina.util.RequestUtil.URLDecode( + destinationPath, "UTF8"); + + int protocolIndex = destinationPath.indexOf("://"); + if (protocolIndex >= 0) { + // if the Destination URL contains the protocol, we can safely + // trim everything upto the first "/" character after "://" + int firstSeparator = + destinationPath.indexOf("/", protocolIndex + 4); + if (firstSeparator < 0) { + destinationPath = "/"; + } else { + destinationPath = destinationPath.substring(firstSeparator); + } + } else { + String hostName = req.getServerName(); + if ((hostName != null) && (destinationPath.startsWith(hostName))) { + destinationPath = destinationPath.substring(hostName.length()); + } + + int portIndex = destinationPath.indexOf(":"); + if (portIndex >= 0) { + destinationPath = destinationPath.substring(portIndex); + } + + if (destinationPath.startsWith(":")) { + int firstSeparator = destinationPath.indexOf("/"); + if (firstSeparator < 0) { + destinationPath = "/"; + } else { + destinationPath = + destinationPath.substring(firstSeparator); + } + } + } + + // Normalise destination path (remove '.' and '..') + destinationPath = RequestUtil.normalize(destinationPath); + + String contextPath = req.getContextPath(); + if ((contextPath != null) && + (destinationPath.startsWith(contextPath))) { + destinationPath = destinationPath.substring(contextPath.length()); + } + + String pathInfo = req.getPathInfo(); + if (pathInfo != null) { + String servletPath = req.getServletPath(); + if ((servletPath != null) && + (destinationPath.startsWith(servletPath))) { + destinationPath = destinationPath + .substring(servletPath.length()); + } + } + + if (debug > 0) + log("Dest path :" + destinationPath); + + // Check destination path to protect special subdirectories + //if (isSpecialPath(destinationPath)) { + // resp.sendError(WebdavServletStatus.SC_FORBIDDEN); + // return false; + //} + + String path = getRelativePath(req); + + if (destinationPath.equals(path)) { + resp.sendError(WebdavServletStatus.SC_FORBIDDEN); + return false; + } + + // Parsing overwrite header + + boolean overwrite = true; + String overwriteHeader = req.getHeader("Overwrite"); + + if (overwriteHeader != null) { + if (overwriteHeader.equalsIgnoreCase("T")) { + overwrite = true; + } else { + overwrite = false; + } + } + + // Overwriting the destination + ResourceObj ro = ResourceStore.lookup(destinationPath,req,resp,ResourceStore.WRITE); + ResourceObj ros = ResourceStore.lookup(path,req,resp,ResourceStore.READ); + + if (ro == null || ros == null){ + + //if (!ro.canWrite() || !ros.canRead()) { + //resp.sendError(WebdavServletStatus.SC_FORBIDDEN); + return false; + } + + boolean exists = ro.exists(); + /*try { + resources.lookup(destinationPath); + } catch (NamingException e) { + exists = false; + }*/ + + if (overwrite) { + + // destination resource, if it exists + if (exists) { + //if (! Resource(destinationPath, req, resp, true)) { + // return false; + //} + ro.delete(); + } else { + resp.setStatus(WebdavServletStatus.SC_CREATED); + } + + } else { + + // If the destination exists, then it's a conflict + if (exists) { + resp.sendError(WebdavServletStatus.SC_PRECONDITION_FAILED); + return false; + } + + } + + // Copying source to destination + + ros.copy(ro); + /*Hashtable errorList = new Hashtable(); + + boolean result = copyResource(resources, errorList, + path, destinationPath); + + if ((!result) || (!errorList.isEmpty())) { + if (errorList.size() == 1) { + resp.sendError(errorList.elements().nextElement().intValue()); + } else { + sendReport(req, resp, errorList); + } + return false; + }*/ + + // Copy was successful + if (exists) { + resp.setStatus(WebdavServletStatus.SC_NO_CONTENT); + } else { + resp.setStatus(WebdavServletStatus.SC_CREATED); + } + + // Removing any lock-null resource which would be present at + // the destination path + lockNullResources.remove(destinationPath); + + return true; + + } + + + /** + * Copy a collection. + * + * @param dirContext Resources implementation to be used + * @param errorList Hashtable containing the list of errors which occurred + * during the copy operation + * @param source Path of the resource to be copied + * @param dest Destination path + */ + private boolean copyResource(DirContext dirContext, + Hashtable errorList, String source, String dest) { + + if (debug > 1) + log("Copy: " + source + " To: " + dest); + + Object object = null; + try { + object = dirContext.lookup(source); + } catch (NamingException e) { + // Ignore + } + + if (object instanceof DirContext) { + + try { + dirContext.createSubcontext(dest); + } catch (NamingException e) { + errorList.put + (dest, new Integer(WebdavServletStatus.SC_CONFLICT)); + return false; + } + + try { + NamingEnumeration enumeration = + dirContext.list(source); + while (enumeration.hasMoreElements()) { + NameClassPair ncPair = enumeration.nextElement(); + String childDest = dest; + if (!childDest.equals("/")) + childDest += "/"; + childDest += ncPair.getName(); + String childSrc = source; + if (!childSrc.equals("/")) + childSrc += "/"; + childSrc += ncPair.getName(); + copyResource(dirContext, errorList, childSrc, childDest); + } + } catch (NamingException e) { + errorList.put + (dest, new Integer(WebdavServletStatus.SC_INTERNAL_SERVER_ERROR)); + return false; + } + + } else { + + if (object instanceof Resource) { + try { + dirContext.bind(dest, object); + } catch (NamingException e) { + if (e.getCause() instanceof FileNotFoundException) { + // We know the source exists so it must be the + // destination dir that can't be found + errorList.put(source, + new Integer(WebdavServletStatus.SC_CONFLICT)); + } else { + errorList.put(source, + new Integer(WebdavServletStatus.SC_INTERNAL_SERVER_ERROR)); + } + return false; + } + } else { + errorList.put + (source, + new Integer(WebdavServletStatus.SC_INTERNAL_SERVER_ERROR)); + return false; + } + + } + + return true; + + } + + + /** + * Delete a resource. + * + * @param req Servlet request + * @param resp Servlet response + * @return boolean true if the copy is successful + */ + private boolean deleteResource(HttpServletRequest req, + HttpServletResponse resp) + throws IOException { + + String path = getRelativePath(req); + + return deleteResource(path, req, resp, true); + + } + + + /** + * Delete a resource. + * + * @param path Path of the resource which is to be deleted + * @param req Servlet request + * @param resp Servlet response + * @param setStatus Should the response status be set on successful + * completion + */ + private boolean deleteResource(String path, HttpServletRequest req, + HttpServletResponse resp, boolean setStatus) + throws IOException { + + String ifHeader = req.getHeader("If"); + if (ifHeader == null) + ifHeader = ""; + + String lockTokenHeader = req.getHeader("Lock-Token"); + if (lockTokenHeader == null) + lockTokenHeader = ""; + + if (isLocked(path, ifHeader + lockTokenHeader)) { + resp.sendError(WebdavServletStatus.SC_LOCKED); + return false; + } + + boolean exists = true; + Object object = null; + try { + object = resources.lookup(path); + } catch (NamingException e) { + exists = false; + } + + if (!exists) { + resp.sendError(WebdavServletStatus.SC_NOT_FOUND); + return false; + } + + boolean collection = (object instanceof DirContext); + + if (!collection) { + try { + resources.unbind(path); + } catch (NamingException e) { + resp.sendError(WebdavServletStatus.SC_INTERNAL_SERVER_ERROR); + return false; + } + } else { + + Hashtable errorList = + new Hashtable(); + + deleteCollection(req, resources, path, errorList); + try { + resources.unbind(path); + } catch (NamingException e) { + errorList.put(path, new Integer + (WebdavServletStatus.SC_INTERNAL_SERVER_ERROR)); + } + + if (!errorList.isEmpty()) { + + sendReport(req, resp, errorList); + return false; + + } + + } + if (setStatus) { + resp.setStatus(WebdavServletStatus.SC_NO_CONTENT); + } + return true; + + } + + + /** + * Deletes a collection. + * + * @param dirContext Resources implementation associated with the context + * @param path Path to the collection to be deleted + * @param errorList Contains the list of the errors which occurred + */ + private void deleteCollection(HttpServletRequest req, + DirContext dirContext, + String path, + Hashtable errorList) { + + if (debug > 1) + log("Delete:" + path); + + // Prevent deletion of special subdirectories + if (isSpecialPath(path)) { + errorList.put(path, new Integer(WebdavServletStatus.SC_FORBIDDEN)); + return; + } + + String ifHeader = req.getHeader("If"); + if (ifHeader == null) + ifHeader = ""; + + String lockTokenHeader = req.getHeader("Lock-Token"); + if (lockTokenHeader == null) + lockTokenHeader = ""; + + Enumeration enumeration = null; + try { + enumeration = dirContext.list(path); + } catch (NamingException e) { + errorList.put(path, new Integer + (WebdavServletStatus.SC_INTERNAL_SERVER_ERROR)); + return; + } + + while (enumeration.hasMoreElements()) { + NameClassPair ncPair = enumeration.nextElement(); + String childName = path; + if (!childName.equals("/")) + childName += "/"; + childName += ncPair.getName(); + + if (isLocked(childName, ifHeader + lockTokenHeader)) { + + errorList.put(childName, new Integer(WebdavServletStatus.SC_LOCKED)); + + } else { + + try { + Object object = dirContext.lookup(childName); + if (object instanceof DirContext) { + deleteCollection(req, dirContext, childName, errorList); + } + + try { + dirContext.unbind(childName); + } catch (NamingException e) { + if (!(object instanceof DirContext)) { + // If it's not a collection, then it's an unknown + // error + errorList.put + (childName, new Integer + (WebdavServletStatus.SC_INTERNAL_SERVER_ERROR)); + } + } + } catch (NamingException e) { + errorList.put + (childName, new Integer + (WebdavServletStatus.SC_INTERNAL_SERVER_ERROR)); + } + } + + } + + } + + + /** + * Send a multistatus element containing a complete error report to the + * client. + * + * @param req Servlet request + * @param resp Servlet response + * @param errorList List of error to be displayed + */ + private void sendReport(HttpServletRequest req, HttpServletResponse resp, + Hashtable errorList) + throws IOException { + + resp.setStatus(WebdavServletStatus.SC_MULTI_STATUS); + + String absoluteUri = req.getRequestURI(); + String relativePath = getRelativePath(req); + + XMLWriter generatedXML = new XMLWriter(); + generatedXML.writeXMLHeader(); + + generatedXML.writeElement("D", DEFAULT_NAMESPACE, "multistatus", + XMLWriter.OPENING); + + Enumeration pathList = errorList.keys(); + while (pathList.hasMoreElements()) { + + String errorPath = pathList.nextElement(); + int errorCode = errorList.get(errorPath).intValue(); + + generatedXML.writeElement("D", "response", XMLWriter.OPENING); + + generatedXML.writeElement("D", "href", XMLWriter.OPENING); + String toAppend = errorPath.substring(relativePath.length()); + if (!toAppend.startsWith("/")) + toAppend = "/" + toAppend; + generatedXML.writeText(absoluteUri + toAppend); + generatedXML.writeElement("D", "href", XMLWriter.CLOSING); + generatedXML.writeElement("D", "status", XMLWriter.OPENING); + generatedXML.writeText("HTTP/1.1 " + errorCode + " " + + WebdavServletStatus.getStatusText(errorCode)); + generatedXML.writeElement("D", "status", XMLWriter.CLOSING); + + generatedXML.writeElement("D", "response", XMLWriter.CLOSING); + + } + + generatedXML.writeElement("D", "multistatus", XMLWriter.CLOSING); + + Writer writer = resp.getWriter(); + writer.write(generatedXML.toString()); + writer.close(); + + } + + + /** + * Propfind helper method. + * + * @param req The servlet request + * @param resources Resources object associated with this context + * @param generatedXML XML response to the Propfind request + * @param path Path of the current resource + * @param type Propfind type + * @param propertiesVector If the propfind type is find properties by + * name, then this Vector contains those properties + */ + private void parseProperties(HttpServletRequest req,HttpServletResponse resp, + XMLWriter generatedXML, + String path, int type, + Vector propertiesVector) throws CaimitoException { + + // Exclude any resource in the /WEB-INF and /META-INF subdirectories + // if (isSpecialPath(path)) + // return; + + // CacheEntry cacheEntry = resources.lookupCache(path); + //(type + " parseProperties Z Prop " + path); + ResourceObj cacheEntry = ResourceStore.lookup(path,req,resp,ResourceStore.READ); + + if (!cacheEntry.exists()) { + // File is in directory listing but doesn't appear to exist + // Broken symlink or odd permission settings? + return; + } + + generatedXML.writeElement("D", "response", XMLWriter.OPENING); + String status = "HTTP/1.1 " + WebdavServletStatus.SC_OK + " " + + WebdavServletStatus.getStatusText(WebdavServletStatus.SC_OK); + + // Generating href element + generatedXML.writeElement("D", "href", XMLWriter.OPENING); + + String href = req.getContextPath() + req.getServletPath(); + if ((href.endsWith("/")) && (path.startsWith("/"))) + href += path.substring(1); + else + href += path; + if ((cacheEntry.isDirectory()) && (!href.endsWith("/"))) + href += "/"; + + generatedXML.writeText(rewriteUrl(href)); + + generatedXML.writeElement("D", "href", XMLWriter.CLOSING); + + String resourceName = path; + int lastSlash = path.lastIndexOf('/'); + if (lastSlash != -1) + resourceName = resourceName.substring(lastSlash + 1); + + switch (type) { + + case FIND_ALL_PROP : + + generatedXML.writeElement("D", "propstat", XMLWriter.OPENING); + generatedXML.writeElement("D", "prop", XMLWriter.OPENING); + + generatedXML.writeProperty("D", "creationdate", + getISOCreationDate(cacheEntry.getCreation())); + generatedXML.writeElement("D", "displayname", XMLWriter.OPENING); + generatedXML.writeData(resourceName); + generatedXML.writeElement("D", "displayname", XMLWriter.CLOSING); + //if (!cacheEntry.isDirectory()) { + generatedXML.writeProperty + ("D", "getlastmodified", FastHttpDateFormat.formatDate + (cacheEntry.getLastModified(), null)); + if (!cacheEntry.isDirectory()) { + generatedXML.writeProperty + ("D", "getcontentlength", + String.valueOf(cacheEntry.getContentLength())); + String contentType = getServletContext().getMimeType + (cacheEntry.getName()); + if (contentType != null) { + generatedXML.writeProperty("D", "getcontenttype", + contentType); + } + generatedXML.writeProperty("D", "getetag", + cacheEntry.getETag()); + generatedXML.writeElement("D", "resourcetype", + XMLWriter.NO_CONTENT); + } else { + generatedXML.writeElement("D", "resourcetype", + XMLWriter.OPENING); + generatedXML.writeElement("D", "collection", + XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "resourcetype", + XMLWriter.CLOSING); + } + + generatedXML.writeProperty("D", "source", ""); + + String supportedLocks = "" + + "" + + "" + + "" + "" + + "" + + "" + + ""; + generatedXML.writeElement("D", "supportedlock", XMLWriter.OPENING); + generatedXML.writeText(supportedLocks); + generatedXML.writeElement("D", "supportedlock", XMLWriter.CLOSING); + + generateLockDiscovery(path, generatedXML); + + generatedXML.writeElement("D", "prop", XMLWriter.CLOSING); + generatedXML.writeElement("D", "status", XMLWriter.OPENING); + generatedXML.writeText(status); + generatedXML.writeElement("D", "status", XMLWriter.CLOSING); + generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING); + + break; + + case FIND_PROPERTY_NAMES : + + generatedXML.writeElement("D", "propstat", XMLWriter.OPENING); + generatedXML.writeElement("D", "prop", XMLWriter.OPENING); + + generatedXML.writeElement("D", "creationdate", + XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "displayname", XMLWriter.NO_CONTENT); + if (!cacheEntry.isDirectory()) { + generatedXML.writeElement("D", "getcontentlanguage", + XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "getcontentlength", + XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "getcontenttype", + XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "getetag", XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "getlastmodified", + XMLWriter.NO_CONTENT); + } + generatedXML.writeElement("D", "resourcetype", + XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "source", XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "lockdiscovery", + XMLWriter.NO_CONTENT); + + generatedXML.writeElement("D", "prop", XMLWriter.CLOSING); + generatedXML.writeElement("D", "status", XMLWriter.OPENING); + generatedXML.writeText(status); + generatedXML.writeElement("D", "status", XMLWriter.CLOSING); + generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING); + + break; + + case FIND_BY_PROPERTY : + + Vector propertiesNotFound = new Vector(); + + // Parse the list of properties + + generatedXML.writeElement("D", "propstat", XMLWriter.OPENING); + generatedXML.writeElement("D", "prop", XMLWriter.OPENING); + + Enumeration properties = propertiesVector.elements(); + + while (properties.hasMoreElements()) { + + String property = properties.nextElement(); + + if (property.equals("creationdate")) { + generatedXML.writeProperty + ("D", "creationdate", + getISOCreationDate(cacheEntry.getCreation())); + } else if (property.equals("displayname")) { + generatedXML.writeElement + ("D", "displayname", XMLWriter.OPENING); + generatedXML.writeData(resourceName); + generatedXML.writeElement + ("D", "displayname", XMLWriter.CLOSING); + } else if (property.equals("getcontentlanguage")) { + if (cacheEntry.isDirectory()) { + propertiesNotFound.addElement(property); + } else { + generatedXML.writeElement("D", "getcontentlanguage", + XMLWriter.NO_CONTENT); + } + } else if (property.equals("getcontentlength")) { + if (cacheEntry.isDirectory()) { + propertiesNotFound.addElement(property); + } else { + generatedXML.writeProperty + ("D", "getcontentlength", + (String.valueOf(cacheEntry.getContentLength()))); + } + } else if (property.equals("getcontenttype")) { + if (cacheEntry.isDirectory()) { + propertiesNotFound.addElement(property); + } else { + //(cacheEntry.getName() + " MIMEO TYPE " + getServletContext().getMimeType(cacheEntry.getName())); + generatedXML.writeProperty + ("D", "getcontenttype", + getServletContext().getMimeType + (cacheEntry.getName())); + } + } else if (property.equals("getetag")) { + if (cacheEntry.isDirectory()) { + propertiesNotFound.addElement(property); + } else { + generatedXML.writeProperty + ("D", "getetag", cacheEntry.getETag()); + } + } else if (property.equals("getlastmodified")) { + //if (cacheEntry.isDirectory()) { + // propertiesNotFound.addElement(property); + //} else { + generatedXML.writeProperty + ("D", "getlastmodified", FastHttpDateFormat.formatDate + (cacheEntry.getLastModified(), null)); + //} + } else if (property.equals("resourcetype")) { + if (cacheEntry.isDirectory()) { + generatedXML.writeElement("D", "resourcetype", + XMLWriter.OPENING); + generatedXML.writeElement("D", "collection", + XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "resourcetype", + XMLWriter.CLOSING); + } else { + generatedXML.writeElement("D", "resourcetype", + XMLWriter.NO_CONTENT); + } + } else if (property.equals("source")) { + generatedXML.writeProperty("D", "source", ""); + } else if (property.equals("supportedlock")) { + supportedLocks = "" + + "" + + "" + + "" + "" + + "" + + "" + + ""; + generatedXML.writeElement("D", "supportedlock", + XMLWriter.OPENING); + generatedXML.writeText(supportedLocks); + generatedXML.writeElement("D", "supportedlock", + XMLWriter.CLOSING); + } else if (property.equals("lockdiscovery")) { + if (!generateLockDiscovery(path, generatedXML)) + propertiesNotFound.addElement(property); + } else { + propertiesNotFound.addElement(property); + } + + } + + //(cacheEntry.getName() + ":" + propertiesVector + " property e propertiesNotFoundList " + propertiesNotFound); + generatedXML.writeElement("D", "prop", XMLWriter.CLOSING); + generatedXML.writeElement("D", "status", XMLWriter.OPENING); + generatedXML.writeText(status); + generatedXML.writeElement("D", "status", XMLWriter.CLOSING); + generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING); + + Enumeration propertiesNotFoundList = + propertiesNotFound.elements(); + + if (propertiesNotFoundList.hasMoreElements()) { + + status = "HTTP/1.1 " + WebdavServletStatus.SC_NOT_FOUND + " " + + WebdavServletStatus.getStatusText(WebdavServletStatus.SC_NOT_FOUND); + + generatedXML.writeElement("D", "propstat", XMLWriter.OPENING); + generatedXML.writeElement("D", "prop", XMLWriter.OPENING); + + while (propertiesNotFoundList.hasMoreElements()) { + generatedXML.writeElement + ("D", propertiesNotFoundList.nextElement(), + XMLWriter.NO_CONTENT); + } + + generatedXML.writeElement("D", "prop", XMLWriter.CLOSING); + generatedXML.writeElement("D", "status", XMLWriter.OPENING); + generatedXML.writeText(status); + generatedXML.writeElement("D", "status", XMLWriter.CLOSING); + generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING); + + } + + break; + + } + + generatedXML.writeElement("D", "response", XMLWriter.CLOSING); + + } + + + /** + * Propfind helper method. Displays the properties of a lock-null resource. + * + * @param resources Resources object associated with this context + * @param generatedXML XML response to the Propfind request + * @param path Path of the current resource + * @param type Propfind type + * @param propertiesVector If the propfind type is find properties by + * name, then this Vector contains those properties + */ + private void parseLockNullProperties(HttpServletRequest req, + XMLWriter generatedXML, + String path, int type, + Vector propertiesVector) { + + // Exclude any resource in the /WEB-INF and /META-INF subdirectories + //if (isSpecialPath(path)) + // return; + + Thread.dumpStack(); + // Retrieving the lock associated with the lock-null resource + LockInfo lock = resourceLocks.get(path); + + if (lock == null) + return; + + generatedXML.writeElement("D", "response", XMLWriter.OPENING); + String status = "HTTP/1.1 " + WebdavServletStatus.SC_OK + " " + + WebdavServletStatus.getStatusText(WebdavServletStatus.SC_OK); + + // Generating href element + generatedXML.writeElement("D", "href", XMLWriter.OPENING); + + String absoluteUri = req.getRequestURI(); + String relativePath = getRelativePath(req); + String toAppend = path.substring(relativePath.length()); + if (!toAppend.startsWith("/")) + toAppend = "/" + toAppend; + + generatedXML.writeText(rewriteUrl(RequestUtil.normalize( + absoluteUri + toAppend))); + + generatedXML.writeElement("D", "href", XMLWriter.CLOSING); + + String resourceName = path; + int lastSlash = path.lastIndexOf('/'); + if (lastSlash != -1) + resourceName = resourceName.substring(lastSlash + 1); + + switch (type) { + + case FIND_ALL_PROP : + + generatedXML.writeElement("D", "propstat", XMLWriter.OPENING); + generatedXML.writeElement("D", "prop", XMLWriter.OPENING); + + generatedXML.writeProperty("D", "creationdate", + getISOCreationDate(lock.creationDate.getTime())); + generatedXML.writeElement("D", "displayname", XMLWriter.OPENING); + generatedXML.writeData(resourceName); + generatedXML.writeElement("D", "displayname", XMLWriter.CLOSING); + generatedXML.writeProperty("D", "getlastmodified", + FastHttpDateFormat.formatDate + (lock.creationDate.getTime(), null)); + generatedXML.writeProperty("D", "getcontentlength", + String.valueOf(0)); + generatedXML.writeProperty("D", "getcontenttype", ""); + generatedXML.writeProperty("D", "getetag", ""); + generatedXML.writeElement("D", "resourcetype", XMLWriter.OPENING); + generatedXML.writeElement("D", "lock-null", XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "resourcetype", XMLWriter.CLOSING); + + generatedXML.writeProperty("D", "source", ""); + + String supportedLocks = "" + + "" + + "" + + "" + "" + + "" + + "" + + ""; + generatedXML.writeElement("D", "supportedlock", XMLWriter.OPENING); + generatedXML.writeText(supportedLocks); + generatedXML.writeElement("D", "supportedlock", XMLWriter.CLOSING); + + generateLockDiscovery(path, generatedXML); + + generatedXML.writeElement("D", "prop", XMLWriter.CLOSING); + generatedXML.writeElement("D", "status", XMLWriter.OPENING); + generatedXML.writeText(status); + generatedXML.writeElement("D", "status", XMLWriter.CLOSING); + generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING); + + break; + + case FIND_PROPERTY_NAMES : + + generatedXML.writeElement("D", "propstat", XMLWriter.OPENING); + generatedXML.writeElement("D", "prop", XMLWriter.OPENING); + + generatedXML.writeElement("D", "creationdate", + XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "displayname", XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "getcontentlanguage", + XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "getcontentlength", + XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "getcontenttype", + XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "getetag", XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "getlastmodified", + XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "resourcetype", + XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "source", XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "lockdiscovery", + XMLWriter.NO_CONTENT); + + generatedXML.writeElement("D", "prop", XMLWriter.CLOSING); + generatedXML.writeElement("D", "status", XMLWriter.OPENING); + generatedXML.writeText(status); + generatedXML.writeElement("D", "status", XMLWriter.CLOSING); + generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING); + + break; + + case FIND_BY_PROPERTY : + + Vector propertiesNotFound = new Vector(); + + // Parse the list of properties + + generatedXML.writeElement("D", "propstat", XMLWriter.OPENING); + generatedXML.writeElement("D", "prop", XMLWriter.OPENING); + + Enumeration properties = propertiesVector.elements(); + + while (properties.hasMoreElements()) { + + String property = properties.nextElement(); + + if (property.equals("creationdate")) { + generatedXML.writeProperty("D", "creationdate", + getISOCreationDate(lock.creationDate.getTime())); + } else if (property.equals("displayname")) { + generatedXML.writeElement("D", "displayname", + XMLWriter.OPENING); + generatedXML.writeData(resourceName); + generatedXML.writeElement("D", "displayname", + XMLWriter.CLOSING); + } else if (property.equals("getcontentlanguage")) { + generatedXML.writeElement("D", "getcontentlanguage", + XMLWriter.NO_CONTENT); + } else if (property.equals("getcontentlength")) { + generatedXML.writeProperty("D", "getcontentlength", + (String.valueOf(0))); + } else if (property.equals("getcontenttype")) { + generatedXML.writeProperty("D", "getcontenttype", ""); + } else if (property.equals("getetag")) { + generatedXML.writeProperty("D", "getetag", ""); + } else if (property.equals("getlastmodified")) { + generatedXML.writeProperty + ("D", "getlastmodified", + FastHttpDateFormat.formatDate + (lock.creationDate.getTime(), null)); + } else if (property.equals("resourcetype")) { + generatedXML.writeElement("D", "resourcetype", + XMLWriter.OPENING); + generatedXML.writeElement("D", "lock-null", + XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "resourcetype", + XMLWriter.CLOSING); + } else if (property.equals("source")) { + generatedXML.writeProperty("D", "source", ""); + } else if (property.equals("supportedlock")) { + supportedLocks = "" + + "" + + "" + + "" + "" + + "" + + "" + + ""; + generatedXML.writeElement("D", "supportedlock", + XMLWriter.OPENING); + generatedXML.writeText(supportedLocks); + generatedXML.writeElement("D", "supportedlock", + XMLWriter.CLOSING); + } else if (property.equals("lockdiscovery")) { + if (!generateLockDiscovery(path, generatedXML)) + propertiesNotFound.addElement(property); + } else { + propertiesNotFound.addElement(property); + } + + } + + generatedXML.writeElement("D", "prop", XMLWriter.CLOSING); + generatedXML.writeElement("D", "status", XMLWriter.OPENING); + generatedXML.writeText(status); + generatedXML.writeElement("D", "status", XMLWriter.CLOSING); + generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING); + + Enumeration propertiesNotFoundList = propertiesNotFound.elements(); + + if (propertiesNotFoundList.hasMoreElements()) { + + status = "HTTP/1.1 " + WebdavServletStatus.SC_NOT_FOUND + " " + + WebdavServletStatus.getStatusText(WebdavServletStatus.SC_NOT_FOUND); + + generatedXML.writeElement("D", "propstat", XMLWriter.OPENING); + generatedXML.writeElement("D", "prop", XMLWriter.OPENING); + + while (propertiesNotFoundList.hasMoreElements()) { + generatedXML.writeElement + ("D", propertiesNotFoundList.nextElement(), + XMLWriter.NO_CONTENT); + } + + generatedXML.writeElement("D", "prop", XMLWriter.CLOSING); + generatedXML.writeElement("D", "status", XMLWriter.OPENING); + generatedXML.writeText(status); + generatedXML.writeElement("D", "status", XMLWriter.CLOSING); + generatedXML.writeElement("D", "propstat", XMLWriter.CLOSING); + + } + + break; + + } + + generatedXML.writeElement("D", "response", XMLWriter.CLOSING); + + } + + + /** + * Print the lock discovery information associated with a path. + * + * @param path Path + * @param generatedXML XML data to which the locks info will be appended + * @return true if at least one lock was displayed + */ + private boolean generateLockDiscovery + (String path, XMLWriter generatedXML) { + + LockInfo resourceLock = resourceLocks.get(path); + Enumeration collectionLocksList = collectionLocks.elements(); + + boolean wroteStart = false; + + if (resourceLock != null) { + wroteStart = true; + generatedXML.writeElement("D", "lockdiscovery", XMLWriter.OPENING); + resourceLock.toXML(generatedXML); + } + + while (collectionLocksList.hasMoreElements()) { + LockInfo currentLock = collectionLocksList.nextElement(); + if (path.startsWith(currentLock.path)) { + if (!wroteStart) { + wroteStart = true; + generatedXML.writeElement("D", "lockdiscovery", + XMLWriter.OPENING); + } + currentLock.toXML(generatedXML); + } + } + + if (wroteStart) { + generatedXML.writeElement("D", "lockdiscovery", XMLWriter.CLOSING); + } else { + return false; + } + + return true; + + } + + + /** + * Get creation date in ISO format. + */ + private String getISOCreationDate(long creationDate) { + StringBuilder creationDateValue = new StringBuilder + (creationDateFormat.format + (new Date(creationDate))); + /* + int offset = Calendar.getInstance().getTimeZone().getRawOffset() + / 3600000; // FIXME ? + if (offset < 0) { + creationDateValue.append("-"); + offset = -offset; + } else if (offset > 0) { + creationDateValue.append("+"); + } + if (offset != 0) { + if (offset < 10) + creationDateValue.append("0"); + creationDateValue.append(offset + ":00"); + } else { + creationDateValue.append("Z"); + } + */ + return creationDateValue.toString(); + } + + /** + * Determines the methods normally allowed for the resource. + * + */ + private StringBuilder determineMethodsAllowed(HttpServletRequest req,HttpServletResponse resp) throws CaimitoException { + + StringBuilder methodsAllowed = new StringBuilder(); + + String path = getRelativePath(req); + //(" determineMethodsAllowed path " + path); + ResourceObj ro = ResourceStore.lookup(path,req,resp,ResourceStore.READ); + //if (ro == null)return methodsAllowed; + boolean exists = true; + if (ro != null) + exists = ro.exists(); + + + + if (!exists) { + methodsAllowed.append("OPTIONS, MKCOL, PUT, LOCK"); + return methodsAllowed; + } +//PROPPATCH, + methodsAllowed.append("OPTIONS, GET, HEAD, POST, DELETE, TRACE"); + methodsAllowed.append(", COPY, MOVE, LOCK, UNLOCK"); + + if (ro == null || ro.listings()) { + methodsAllowed.append(", PROPFIND"); + } + + if (ro != null && !(ro.isDirectory())) { + methodsAllowed.append(", PUT"); + } + + return methodsAllowed; + } + + // -------------------------------------------------- LockInfo Inner Class + + + /** + * Holds a lock information. + */ + private class LockInfo { + + + // -------------------------------------------------------- Constructor + + + /** + * Constructor. + */ + public LockInfo() { + // Ignore + } + + + // ------------------------------------------------- Instance Variables + + + String path = "/"; + String type = "write"; + String scope = "exclusive"; + int depth = 0; + String owner = ""; + Vector tokens = new Vector(); + long expiresAt = 0; + Date creationDate = new Date(); + + + // ----------------------------------------------------- Public Methods + + + /** + * Get a String representation of this lock token. + */ + @Override + public String toString() { + + StringBuilder result = new StringBuilder("Type:"); + result.append(type); + result.append("\nScope:"); + result.append(scope); + result.append("\nDepth:"); + result.append(depth); + result.append("\nOwner:"); + result.append(owner); + result.append("\nExpiration:"); + result.append(FastHttpDateFormat.formatDate(expiresAt, null)); + Enumeration tokensList = tokens.elements(); + while (tokensList.hasMoreElements()) { + result.append("\nToken:"); + result.append(tokensList.nextElement()); + } + result.append("\n"); + return result.toString(); + } + + + /** + * Return true if the lock has expired. + */ + public boolean hasExpired() { + return (System.currentTimeMillis() > expiresAt); + } + + + /** + * Return true if the lock is exclusive. + */ + public boolean isExclusive() { + + return (scope.equals("exclusive")); + + } + + + /** + * Get an XML representation of this lock token. This method will + * append an XML fragment to the given XML writer. + */ + public void toXML(XMLWriter generatedXML) { + + generatedXML.writeElement("D", "activelock", XMLWriter.OPENING); + + generatedXML.writeElement("D", "locktype", XMLWriter.OPENING); + generatedXML.writeElement("D", type, XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "locktype", XMLWriter.CLOSING); + + generatedXML.writeElement("D", "lockscope", XMLWriter.OPENING); + generatedXML.writeElement("D", scope, XMLWriter.NO_CONTENT); + generatedXML.writeElement("D", "lockscope", XMLWriter.CLOSING); + + generatedXML.writeElement("D", "depth", XMLWriter.OPENING); + if (depth == maxDepth) { + generatedXML.writeText("Infinity"); + } else { + generatedXML.writeText("0"); + } + generatedXML.writeElement("D", "depth", XMLWriter.CLOSING); + + generatedXML.writeElement("D", "owner", XMLWriter.OPENING); + generatedXML.writeText(owner); + generatedXML.writeElement("D", "owner", XMLWriter.CLOSING); + + generatedXML.writeElement("D", "timeout", XMLWriter.OPENING); + long timeout = (expiresAt - System.currentTimeMillis()) / 1000; + generatedXML.writeText("Second-" + timeout); + generatedXML.writeElement("D", "timeout", XMLWriter.CLOSING); + + generatedXML.writeElement("D", "locktoken", XMLWriter.OPENING); + Enumeration tokensList = tokens.elements(); + while (tokensList.hasMoreElements()) { + generatedXML.writeElement("D", "href", XMLWriter.OPENING); + generatedXML.writeText("opaquelocktoken:" + + tokensList.nextElement()); + generatedXML.writeElement("D", "href", XMLWriter.CLOSING); + } + generatedXML.writeElement("D", "locktoken", XMLWriter.CLOSING); + + generatedXML.writeElement("D", "activelock", XMLWriter.CLOSING); + + } + + + } + + + // --------------------------------------------- WebdavResolver Inner Class + /** + * Work around for XML parsers that don't fully respect + * {@link DocumentBuilderFactory#setExpandEntityReferences(boolean)} when + * called with false. External references are filtered out for + * security reasons. See CVE-2007-5461. + */ + private static class WebdavResolver implements EntityResolver { + private ServletContext context; + + public WebdavResolver(ServletContext theContext) { + context = theContext; + } + + @Override + public InputSource resolveEntity (String publicId, String systemId) { + context.log("webdavservlet.enternalEntityIgnored"); + return new InputSource( + new StringReader("Ignored external entity")); + } + } +} + + +// -------------------------------------------------------- WebdavServletStatus Class + + +/** + * Wraps the HttpServletResponse class to abstract the + * specific protocol used. To support other protocols + * we would only need to modify this class and the + * WebDavRetCode classes. + * + * @author Marc Eaddy + * @version 1.0, 16 Nov 1997 + */ +class WebdavServletStatus { + + + // ----------------------------------------------------- Instance Variables + + + /** + * This Hashtable contains the mapping of HTTP and WebDAV + * status codes to descriptive text. This is a static + * variable. + */ + private static Hashtable mapStatusCodes = + new Hashtable(); + + + // ------------------------------------------------------ HTTP Status Codes + + + /** + * Status code (200) indicating the request succeeded normally. + */ + public static final int SC_OK = HttpServletResponse.SC_OK; + + + /** + * Status code (201) indicating the request succeeded and created + * a new resource on the server. + */ + public static final int SC_CREATED = HttpServletResponse.SC_CREATED; + + + /** + * Status code (202) indicating that a request was accepted for + * processing, but was not completed. + */ + public static final int SC_ACCEPTED = HttpServletResponse.SC_ACCEPTED; + + + /** + * Status code (204) indicating that the request succeeded but that + * there was no new information to return. + */ + public static final int SC_NO_CONTENT = HttpServletResponse.SC_NO_CONTENT; + + + /** + * Status code (301) indicating that the resource has permanently + * moved to a new location, and that future references should use a + * new URI with their requests. + */ + public static final int SC_MOVED_PERMANENTLY = + HttpServletResponse.SC_MOVED_PERMANENTLY; + + + /** + * Status code (302) indicating that the resource has temporarily + * moved to another location, but that future references should + * still use the original URI to access the resource. + */ + public static final int SC_MOVED_TEMPORARILY = + HttpServletResponse.SC_MOVED_TEMPORARILY; + + + /** + * Status code (304) indicating that a conditional GET operation + * found that the resource was available and not modified. + */ + public static final int SC_NOT_MODIFIED = + HttpServletResponse.SC_NOT_MODIFIED; + + + /** + * Status code (400) indicating the request sent by the client was + * syntactically incorrect. + */ + public static final int SC_BAD_REQUEST = + HttpServletResponse.SC_BAD_REQUEST; + + + /** + * Status code (401) indicating that the request requires HTTP + * authentication. + */ + public static final int SC_UNAUTHORIZED = + HttpServletResponse.SC_UNAUTHORIZED; + + + /** + * Status code (403) indicating the server understood the request + * but refused to fulfill it. + */ + public static final int SC_FORBIDDEN = HttpServletResponse.SC_FORBIDDEN; + + + /** + * Status code (404) indicating that the requested resource is not + * available. + */ + public static final int SC_NOT_FOUND = HttpServletResponse.SC_NOT_FOUND; + + + /** + * Status code (500) indicating an error inside the HTTP service + * which prevented it from fulfilling the request. + */ + public static final int SC_INTERNAL_SERVER_ERROR = + HttpServletResponse.SC_INTERNAL_SERVER_ERROR; + + + /** + * Status code (501) indicating the HTTP service does not support + * the functionality needed to fulfill the request. + */ + public static final int SC_NOT_IMPLEMENTED = + HttpServletResponse.SC_NOT_IMPLEMENTED; + + + /** + * Status code (502) indicating that the HTTP server received an + * invalid response from a server it consulted when acting as a + * proxy or gateway. + */ + public static final int SC_BAD_GATEWAY = + HttpServletResponse.SC_BAD_GATEWAY; + + + /** + * Status code (503) indicating that the HTTP service is + * temporarily overloaded, and unable to handle the request. + */ + public static final int SC_SERVICE_UNAVAILABLE = + HttpServletResponse.SC_SERVICE_UNAVAILABLE; + + + /** + * Status code (100) indicating the client may continue with + * its request. This interim response is used to inform the + * client that the initial part of the request has been + * received and has not yet been rejected by the server. + */ + public static final int SC_CONTINUE = 100; + + + /** + * Status code (405) indicating the method specified is not + * allowed for the resource. + */ + public static final int SC_METHOD_NOT_ALLOWED = 405; + + + /** + * Status code (409) indicating that the request could not be + * completed due to a conflict with the current state of the + * resource. + */ + public static final int SC_CONFLICT = 409; + + + /** + * Status code (412) indicating the precondition given in one + * or more of the request-header fields evaluated to false + * when it was tested on the server. + */ + public static final int SC_PRECONDITION_FAILED = 412; + + + /** + * Status code (413) indicating the server is refusing to + * process a request because the request entity is larger + * than the server is willing or able to process. + */ + public static final int SC_REQUEST_TOO_LONG = 413; + + + /** + * Status code (415) indicating the server is refusing to service + * the request because the entity of the request is in a format + * not supported by the requested resource for the requested + * method. + */ + public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415; + + + // -------------------------------------------- Extended WebDav status code + + + /** + * Status code (207) indicating that the response requires + * providing status for multiple independent operations. + */ + public static final int SC_MULTI_STATUS = 207; + // This one collides with HTTP 1.1 + // "207 Partial Update OK" + + + /** + * Status code (418) indicating the entity body submitted with + * the PATCH method was not understood by the resource. + */ + public static final int SC_UNPROCESSABLE_ENTITY = 418; + // This one collides with HTTP 1.1 + // "418 Reauthentication Required" + + + /** + * Status code (419) indicating that the resource does not have + * sufficient space to record the state of the resource after the + * execution of this method. + */ + public static final int SC_INSUFFICIENT_SPACE_ON_RESOURCE = 419; + // This one collides with HTTP 1.1 + // "419 Proxy Reauthentication Required" + + + /** + * Status code (420) indicating the method was not executed on + * a particular resource within its scope because some part of + * the method's execution failed causing the entire method to be + * aborted. + */ + public static final int SC_METHOD_FAILURE = 420; + + + /** + * Status code (423) indicating the destination resource of a + * method is locked, and either the request did not contain a + * valid Lock-Info header, or the Lock-Info header identifies + * a lock held by another principal. + */ + public static final int SC_LOCKED = 423; + + + // ------------------------------------------------------------ Initializer + + + static { + // HTTP 1.0 status Code + addStatusCodeMap(SC_OK, "OK"); + addStatusCodeMap(SC_CREATED, "Created"); + addStatusCodeMap(SC_ACCEPTED, "Accepted"); + addStatusCodeMap(SC_NO_CONTENT, "No Content"); + addStatusCodeMap(SC_MOVED_PERMANENTLY, "Moved Permanently"); + addStatusCodeMap(SC_MOVED_TEMPORARILY, "Moved Temporarily"); + addStatusCodeMap(SC_NOT_MODIFIED, "Not Modified"); + addStatusCodeMap(SC_BAD_REQUEST, "Bad Request"); + addStatusCodeMap(SC_UNAUTHORIZED, "Unauthorized"); + addStatusCodeMap(SC_FORBIDDEN, "Forbidden"); + addStatusCodeMap(SC_NOT_FOUND, "Not Found"); + addStatusCodeMap(SC_INTERNAL_SERVER_ERROR, "Internal Server Error"); + addStatusCodeMap(SC_NOT_IMPLEMENTED, "Not Implemented"); + addStatusCodeMap(SC_BAD_GATEWAY, "Bad Gateway"); + addStatusCodeMap(SC_SERVICE_UNAVAILABLE, "Service Unavailable"); + addStatusCodeMap(SC_CONTINUE, "Continue"); + addStatusCodeMap(SC_METHOD_NOT_ALLOWED, "Method Not Allowed"); + addStatusCodeMap(SC_CONFLICT, "Conflict"); + addStatusCodeMap(SC_PRECONDITION_FAILED, "Precondition Failed"); + addStatusCodeMap(SC_REQUEST_TOO_LONG, "Request Too Long"); + addStatusCodeMap(SC_UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type"); + // WebDav Status Codes + addStatusCodeMap(SC_MULTI_STATUS, "Multi-Status"); + addStatusCodeMap(SC_UNPROCESSABLE_ENTITY, "Unprocessable Entity"); + addStatusCodeMap(SC_INSUFFICIENT_SPACE_ON_RESOURCE, + "Insufficient Space On Resource"); + addStatusCodeMap(SC_METHOD_FAILURE, "Method Failure"); + addStatusCodeMap(SC_LOCKED, "Locked"); + } + + + // --------------------------------------------------------- Public Methods + + + /** + * Returns the HTTP status text for the HTTP or WebDav status code + * specified by looking it up in the static mapping. This is a + * static function. + * + * @param nHttpStatusCode [IN] HTTP or WebDAV status code + * @return A string with a short descriptive phrase for the + * HTTP status code (e.g., "OK"). + */ + public static String getStatusText(int nHttpStatusCode) { + Integer intKey = Integer.valueOf(nHttpStatusCode); + + if (!mapStatusCodes.containsKey(intKey)) { + return ""; + } else { + return mapStatusCodes.get(intKey); + } + } + + + // -------------------------------------------------------- Private Methods + + + /** + * Adds a new status code -> status text mapping. This is a static + * method because the mapping is a static variable. + * + * @param nKey [IN] HTTP or WebDAV status code + * @param strVal [IN] HTTP status text + */ + private static void addStatusCodeMap(int nKey, String strVal) { + mapStatusCodes.put(Integer.valueOf(nKey), strVal); + } + +} + + diff --git a/source/ngasi/caimito/resource/CacheMgr.java b/source/ngasi/caimito/resource/CacheMgr.java old mode 100644 new mode 100755 index 4a24b71..ef09e73 --- a/source/ngasi/caimito/resource/CacheMgr.java +++ b/source/ngasi/caimito/resource/CacheMgr.java @@ -1,105 +1,105 @@ -/* - Copyright (c) 2011-2012, the Caimito project (http://caimito.ngasi.com/). All rights reserved. -Apache Software License 2.0 -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WebAppShowCase -OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - - - - -package ngasi.caimito.resource; -import java.nio.charset.Charset; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import ngasi.caimito.*; -import org.shaft.server.auth.*; -import tools.util.*; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Enumeration; -import java.io.UnsupportedEncodingException; -import org.shaft.server.utils.*; -import tools.util.*; -import java.util.Hashtable; - - -public class CacheMgr - { - int defwaitsleep = 1000; - long defwait = 1800; - - static CacheMgr defc = new CacheMgr(); - public static CacheMgr getCacheMgr(){ - return defc; - } - - public boolean waitFor(String n)throws Exception{ - boolean b = false; - for (int ct = 0; ct < defwait;ct++) - { - b = getBoolean(n); - // if (b == null) - // if (!tf)return tf; - if (!b) - return true; - Thread.sleep(defwaitsleep); - } - return false; - } - - - - public void put(String n)throws Exception{ - for (int ct = 0;ct < defwait;ct++){ - - if (get(n) == null) - break; - Thread.sleep(defwaitsleep); - - } - if (get(n) != null) - CaimitoException.throwException("unable_to_lock_cache"); - cache.put(n,true); - } - - -NameValuePairs cache = new NameValuePairs(); - - - - public Object get(String n)throws Exception{ - return cache.get(n); - } - public Object remove(String n)throws Exception{ - return cache.remove(n); - } - - public boolean getBoolean(String n)throws Exception{ - return cache.getBoolean(n); - } - +/* + Copyright (c) 2011-2012, the Caimito project (http://caimito.ngasi.com/). All rights reserved. +Apache Software License 2.0 +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WebAppShowCase +OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + + + + +package ngasi.caimito.resource; +import java.nio.charset.Charset; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import ngasi.caimito.*; +import org.shaft.server.auth.*; +import tools.util.*; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Enumeration; +import java.io.UnsupportedEncodingException; +import org.shaft.server.utils.*; +import tools.util.*; +import java.util.Hashtable; + + +public class CacheMgr + { + int defwaitsleep = 1000; + long defwait = 1800; + + static CacheMgr defc = new CacheMgr(); + public static CacheMgr getCacheMgr(){ + return defc; + } + + public boolean waitFor(String n)throws Exception{ + boolean b = false; + for (int ct = 0; ct < defwait;ct++) + { + b = getBoolean(n); + // if (b == null) + // if (!tf)return tf; + if (!b) + return true; + Thread.sleep(defwaitsleep); + } + return false; + } + + + + public void put(String n)throws Exception{ + for (int ct = 0;ct < defwait;ct++){ + + if (get(n) == null) + break; + Thread.sleep(defwaitsleep); + + } + if (get(n) != null) + CaimitoException.throwException("unable_to_lock_cache"); + cache.put(n,true); + } + + +NameValuePairs cache = new NameValuePairs(); + + + + public Object get(String n)throws Exception{ + return cache.get(n); + } + public Object remove(String n)throws Exception{ + return cache.remove(n); + } + + public boolean getBoolean(String n)throws Exception{ + return cache.getBoolean(n); + } + } \ No newline at end of file diff --git a/source/ngasi/caimito/resource/CloudResourceObj.java b/source/ngasi/caimito/resource/CloudResourceObj.java old mode 100644 new mode 100755 index 941e42b..924d708 --- a/source/ngasi/caimito/resource/CloudResourceObj.java +++ b/source/ngasi/caimito/resource/CloudResourceObj.java @@ -1,120 +1,120 @@ -/* - Copyright (c) 2011-2012, the Caimito project (http://caimito.ngasi.com/). All rights reserved. -Apache Software License 2.0 -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WebAppShowCase -OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - - - - -package ngasi.caimito.resource; -import ngasi.caimito.*; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; -import java.util.TimeZone; -import java.util.Vector; -import java.io.InputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.InputStream; -import tools.util.FileUtil; -public abstract class CloudResourceObj extends ResourceObj - { - public InputStream doGetInputStream()throws CaimitoException{ - try{ - String tf = CaimitoConfig.cachedir + path; - if (CaimitoConfig.cacheable){ - File ftf = new File(tf); - if (ftf.exists() && ftf.lastModified() == getLastModified()) - { - //("CACHE obje " + tf); - return new FileInputStream(tf); - } - //else - //(ftf.exists() + ":" + tf + ":" + new Date(ftf.lastModified()) + " NO CACHE obje " + new Date(getLastModified()) ); - - - } - //StringUtil.replaceSubstring(path,"/" , "_"); - CacheMgr cmr = CacheMgr.getCacheMgr(); - boolean rl = false; - if (cmr.getBoolean(tf)) - cmr.waitFor(tf); - else{ - - cmr.put(tf); - rl = true; - } - - try{ - - new File(tf).delete(); - int i = tf.lastIndexOf("/"); - new File (tf.substring(0,i)).mkdirs(); - - retrieveCloudFile(path,tf); - if (CaimitoConfig.cacheable) - new File(tf).setLastModified(getLastModified()); - }finally{ - if (rl) - cmr.remove(tf); - } - - return new FileInputStream(tf); - }catch (Exception e){ - e.printStackTrace(); - CaimitoException.throwException(e); - - } - return null; - - } - - public void doDelete()throws CaimitoException{ - try{ - - try{ - deleteCloudFile(); - }finally{ - String tf = CaimitoConfig.cachedir + path; - FileUtil.deleteAll(tf); - new File(tf).delete(); - } - }catch (Exception e){ - e.printStackTrace(); - CaimitoException.throwException(e); - - } - } - - public abstract void retrieveCloudFile(String path,String tf)throws CaimitoException; - public abstract void deleteCloudFile()throws CaimitoException; - -} - - +/* + Copyright (c) 2011-2012, the Caimito project (http://caimito.ngasi.com/). All rights reserved. +Apache Software License 2.0 +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WebAppShowCase +OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + + + + +package ngasi.caimito.resource; +import ngasi.caimito.*; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; +import java.util.Vector; +import java.io.InputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import tools.util.FileUtil; +public abstract class CloudResourceObj extends ResourceObj + { + public InputStream doGetInputStream()throws CaimitoException{ + try{ + String tf = CaimitoConfig.cachedir + path; + if (CaimitoConfig.cacheable){ + File ftf = new File(tf); + if (ftf.exists() && ftf.lastModified() == getLastModified()) + { + //("CACHE obje " + tf); + return new FileInputStream(tf); + } + //else + //(ftf.exists() + ":" + tf + ":" + new Date(ftf.lastModified()) + " NO CACHE obje " + new Date(getLastModified()) ); + + + } + //StringUtil.replaceSubstring(path,"/" , "_"); + CacheMgr cmr = CacheMgr.getCacheMgr(); + boolean rl = false; + if (cmr.getBoolean(tf)) + cmr.waitFor(tf); + else{ + + cmr.put(tf); + rl = true; + } + + try{ + + new File(tf).delete(); + int i = tf.lastIndexOf("/"); + new File (tf.substring(0,i)).mkdirs(); + + retrieveCloudFile(path,tf); + if (CaimitoConfig.cacheable) + new File(tf).setLastModified(getLastModified()); + }finally{ + if (rl) + cmr.remove(tf); + } + + return new FileInputStream(tf); + }catch (Exception e){ + e.printStackTrace(); + CaimitoException.throwException(e); + + } + return null; + + } + + public void doDelete()throws CaimitoException{ + try{ + + try{ + deleteCloudFile(); + }finally{ + String tf = CaimitoConfig.cachedir + path; + FileUtil.deleteAll(tf); + new File(tf).delete(); + } + }catch (Exception e){ + e.printStackTrace(); + CaimitoException.throwException(e); + + } + } + + public abstract void retrieveCloudFile(String path,String tf)throws CaimitoException; + public abstract void deleteCloudFile()throws CaimitoException; + +} + + diff --git a/source/ngasi/caimito/resource/FileResourceObj.java b/source/ngasi/caimito/resource/FileResourceObj.java old mode 100644 new mode 100755 index 263f316..5ce51de --- a/source/ngasi/caimito/resource/FileResourceObj.java +++ b/source/ngasi/caimito/resource/FileResourceObj.java @@ -1,197 +1,197 @@ -/* - Copyright (c) 2011-2012, the Caimito project (http://caimito.ngasi.com/). All rights reserved. -Apache Software License 2.0 -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WebAppShowCase -OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - - - - -package ngasi.caimito.resource; -import ngasi.caimito.*; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.InputStream; - -import tools.util.*; -import java.util.Vector; - -public class FileResourceObj extends ResourceObj - { - private static String home = "/usr/caimito/drive"; - protected static final int BUFFER_SIZE = 2048; - - static{ - try{ - home = CaimitoConfig.getConfig().getString("file.resource.dir"); - new File(home).mkdirs(); - }catch (Exception e){ - e.printStackTrace(); - } - } - - protected String getHome(){ - return home; - } - public InputStream doGetInputStream()throws CaimitoException{ - try{ - - return new FileInputStream(getHome() + path); - }catch (Exception e){ - e.printStackTrace(); - CaimitoException.throwException(e); - - } - return null; - - } - - - public void doWrite(InputStream dest)throws CaimitoException{ - try{ - if (dest.available() < 0)return; - FileOutputStream fout = new FileOutputStream(getHome() + path); - try{ - //(getHome() + path + " dO THE WRITE THING " + dest.available()); - StreamUtil.write(dest,fout); - - byte buffer[] = new byte[BUFFER_SIZE]; - int len = -1; - while (true) { - len = dest.read(buffer); - //(getHome() + path + " dO THE WRITE THING ********* " + len); - - if (len == -1) - break; - fout.write(buffer, 0, len); - } - - - }finally{ - fout.close(); - } - }catch (Exception e){ - e.printStackTrace(); - CaimitoException.throwException(e); - - } - } - - - public void doCopy(ResourceObj dest)throws CaimitoException{ - try{ - - if (new File(getHome() + path).isDirectory()) - new File(getHome() + dest.path).mkdirs(); - - FileUtil.copy(getHome() + path,getHome() + dest.path); - }catch (Exception e){ - e.printStackTrace(); - CaimitoException.throwException(e); - - } - } - - - public void doMove(ResourceObj dest)throws CaimitoException{ - try{ - - // if (new File(getHome() + path).isDirectory()) - // new File(getHome() + dest.path).mkdirs(); - - new File(getHome() + path).renameTo(new File(getHome() + dest.path)); - }catch (Exception e){ - e.printStackTrace(); - CaimitoException.throwException(e); - - } - } - - public boolean doExists()throws CaimitoException{ - - return new File(getHome() + path).exists(); - } - public void doDelete()throws CaimitoException{ - try{ - - FileUtil.deleteAll(getHome() + path); - new File(getHome() + path).delete(); - }catch (Exception e){ - e.printStackTrace(); - CaimitoException.throwException(e); - } - } - - public void doMkdir()throws CaimitoException{ - try{ - - new File(getHome() + path).mkdirs(); - }catch (Exception e){ - e.printStackTrace(); - CaimitoException.throwException(e); - } - } - - public long getLastModified()throws CaimitoException{ - return new File(getHome() + path).lastModified(); - } - - public boolean isDirectory()throws CaimitoException{ - return new File(getHome() + path).isDirectory(); - } - public long getContentLength()throws CaimitoException{ - //(getHome() + path + " GET THE LENGTH " + new File(getHome() + path).length() ); - return new File(getHome() + path).length(); - } - - public Vector doList()throws CaimitoException{ - Vector l = new Vector(); - - String[] dl = new File(getHome() + path).list(); - String ps = ""; - if (!path.endsWith("/")) - ps = "/"; - if (dl != null){ - FileResourceObj ro = null; - for (int ct = 0; ct < dl.length;ct++){ - ro = new FileResourceObj(); - ro.path = path + ps + dl[ct]; - //(getHome() + path + ps + " DO LISTER " + dl[ct]); - ro.user = user; - ro.listing = listing; - l.add(ro); - } - } - - return l; - - } - - -} - - +/* + Copyright (c) 2011-2012, the Caimito project (http://caimito.ngasi.com/). All rights reserved. +Apache Software License 2.0 +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WebAppShowCase +OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + + + + +package ngasi.caimito.resource; +import ngasi.caimito.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; + +import tools.util.*; +import java.util.Vector; + +public class FileResourceObj extends ResourceObj + { + private static String home = "/usr/caimito/drive"; + protected static final int BUFFER_SIZE = 2048; + + static{ + try{ + home = CaimitoConfig.getConfig().getString("file.resource.dir"); + new File(home).mkdirs(); + }catch (Exception e){ + e.printStackTrace(); + } + } + + protected String getHome(){ + return home; + } + public InputStream doGetInputStream()throws CaimitoException{ + try{ + + return new FileInputStream(getHome() + path); + }catch (Exception e){ + e.printStackTrace(); + CaimitoException.throwException(e); + + } + return null; + + } + + + public void doWrite(InputStream dest)throws CaimitoException{ + try{ + if (dest.available() < 0)return; + FileOutputStream fout = new FileOutputStream(getHome() + path); + try{ + //(getHome() + path + " dO THE WRITE THING " + dest.available()); + StreamUtil.write(dest,fout); + + byte buffer[] = new byte[BUFFER_SIZE]; + int len = -1; + while (true) { + len = dest.read(buffer); + //(getHome() + path + " dO THE WRITE THING ********* " + len); + + if (len == -1) + break; + fout.write(buffer, 0, len); + } + + + }finally{ + fout.close(); + } + }catch (Exception e){ + e.printStackTrace(); + CaimitoException.throwException(e); + + } + } + + + public void doCopy(ResourceObj dest)throws CaimitoException{ + try{ + + if (new File(getHome() + path).isDirectory()) + new File(getHome() + dest.path).mkdirs(); + + FileUtil.copy(getHome() + path,getHome() + dest.path); + }catch (Exception e){ + e.printStackTrace(); + CaimitoException.throwException(e); + + } + } + + + public void doMove(ResourceObj dest)throws CaimitoException{ + try{ + + // if (new File(getHome() + path).isDirectory()) + // new File(getHome() + dest.path).mkdirs(); + + new File(getHome() + path).renameTo(new File(getHome() + dest.path)); + }catch (Exception e){ + e.printStackTrace(); + CaimitoException.throwException(e); + + } + } + + public boolean doExists()throws CaimitoException{ + + return new File(getHome() + path).exists(); + } + public void doDelete()throws CaimitoException{ + try{ + + FileUtil.deleteAll(getHome() + path); + new File(getHome() + path).delete(); + }catch (Exception e){ + e.printStackTrace(); + CaimitoException.throwException(e); + } + } + + public void doMkdir()throws CaimitoException{ + try{ + + new File(getHome() + path).mkdirs(); + }catch (Exception e){ + e.printStackTrace(); + CaimitoException.throwException(e); + } + } + + public long getLastModified()throws CaimitoException{ + return new File(getHome() + path).lastModified(); + } + + public boolean isDirectory()throws CaimitoException{ + return new File(getHome() + path).isDirectory(); + } + public long getContentLength()throws CaimitoException{ + //(getHome() + path + " GET THE LENGTH " + new File(getHome() + path).length() ); + return new File(getHome() + path).length(); + } + + public Vector doList()throws CaimitoException{ + Vector l = new Vector(); + + String[] dl = new File(getHome() + path).list(); + String ps = ""; + if (!path.endsWith("/")) + ps = "/"; + if (dl != null){ + FileResourceObj ro = null; + for (int ct = 0; ct < dl.length;ct++){ + ro = new FileResourceObj(); + ro.path = path + ps + dl[ct]; + //(getHome() + path + ps + " DO LISTER " + dl[ct]); + ro.user = user; + ro.listing = listing; + l.add(ro); + } + } + + return l; + + } + + +} + + diff --git a/source/ngasi/caimito/resource/OpenStackResourceObj.java b/source/ngasi/caimito/resource/OpenStackResourceObj.java old mode 100644 new mode 100755 index 1940aba..925c8bc --- a/source/ngasi/caimito/resource/OpenStackResourceObj.java +++ b/source/ngasi/caimito/resource/OpenStackResourceObj.java @@ -1,716 +1,787 @@ -/* - Copyright (c) 2011-2012, the Caimito project (http://caimito.ngasi.com/). All rights reserved. -Apache Software License 2.0 -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WebAppShowCase -OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - - - - -package ngasi.caimito.resource; -import ngasi.caimito.*; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.InputStream; - -import tools.util.*; -import java.util.Vector; -import java.util.Hashtable; -import com.google.gson.*; -import java.lang.reflect.*; -import com.google.gson.reflect.*; -import java.util.List; -import java.text.*; -import java.util.Locale; -import java.util.Date; -import java.util.Enumeration; -import java.util.Map; -import java.io.ByteArrayInputStream; - -public class OpenStackResourceObj extends CloudResourceObj - { - protected static final int BUFFER_SIZE = 2048; - - - static DateFormat dfm = null; - - static long maxautint = 0; - - - - static{ - try{ - maxautint = CaimitoConfig.getConfig().getLong("cloud.max_auth_interval") * 60* 1000L; - }catch (Exception e){ - e.printStackTrace(); - } - try{ - - dfm = new SimpleDateFormat(CaimitoConfig.getConfig().getString("cloud.obj.details.dateformat")); - }catch (Throwable e){ - e.printStackTrace(); - } - } - - - public void retrieveCloudFile(String path,String tf)throws CaimitoException{ - try{ - auth(); - Hashtable h = new Hashtable(); - h.put("X-Auth-Token",X_Auth_Token); - - - HttpClientUtil.trustGetToFile(h,X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + CaimitoUtil.urlEncode(path),tf); - }catch (Exception e){ - e.printStackTrace(); - CaimitoException.throwException(e); - - } - - } - - - public void doWrite(InputStream dest)throws CaimitoException{ - try{ - if (dest.available() < 0)return; - - - Hashtable h = new Hashtable(); - h.put("X-Auth-Token",X_Auth_Token); - if (contentType != null) - h.put("Content-Type",contentType); - - // if (contentLength > -1 ) - // h.put("Content-Length",String.valueOf(contentLength)); - - - String nv = null; - - - nv = HttpClientUtil.trustPut(h,X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + CaimitoUtil.urlEncode(path),dest); - //(path + " put me " + nv); - - }catch (Exception e){ - e.printStackTrace(); - CaimitoException.throwException(e); - - } - } - - - - -public void doCopy(ResourceObj dest)throws CaimitoException - { - String fs = path; - String t = dest.path; -// if (!isDirectory()) -// return; - if ( !t.endsWith("/")) - t = t + "/"; - -// Vector flist = doList(); - - //----------- - - - auth(); - - Hashtable h = new Hashtable(); - h.put("X-Auth-Token",X_Auth_Token); - if (isDirectory()) - h.put("Content-Type","application/directory"); - //h.put("Content-Length","0"); - - String tp = path; - if (tp.endsWith("/")) - tp = tp.substring(0,tp.length() -1); - h.put("X_COPY_FROM",CaimitoConfig.getConfig().getString("cloud.store") + tp); - String tp2 = dest.path; - if (tp2.endsWith("/")) - tp2 = tp2.substring(0,tp2.length() -1); -try{ - - String nv = HttpClientUtil.trustPut(h,X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + tp2); - //(X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + tp + "-->" + h + " ******************X_COPY_FROM 1111 " + nv + ":" + tp2); - }catch (Exception e){ - e.printStackTrace(); - CaimitoException.throwException(e); - - } - - if (!isDirectory()) - { - - return; - } - Vector flist = doList(); - - if (flist == null || flist.size() < 1) - return; - for(int i = 0 ; i < flist.size() ; i++) -{ - OpenStackResourceObj nf = (OpenStackResourceObj)flist.elementAt(i); - String nt = t; - boolean isd = false; - if (nf.isDirectory()) - { - nt = nt + nf.path.substring(path.length(),nf.path.length()); - OpenStackResourceObj dr = new OpenStackResourceObj(); - dr.path = nt; - dr.doMkdir(); - isd = true; - nf.doCopy(dr); - } - else - try - { - ResourceObj dr = new OpenStackResourceObj(); - dr.path = t + nf.getName(); - - nf.xCopy(dr); - }catch (Exception e){ - e.printStackTrace(); - CaimitoException.throwException(e); - - } - -} - - - } - - public void xCopy(ResourceObj dest)throws CaimitoException{ - try{ - - - auth(); - - Hashtable h = new Hashtable(); - h.put("X-Auth-Token",X_Auth_Token); - if (isDirectory()) - h.put("Content-Type","application/directory"); - //h.put("Content-Length","0"); - - String tp = path; - if (tp.endsWith("/")) - tp = tp.substring(0,tp.length() -1); - h.put("X_COPY_FROM",CaimitoConfig.getConfig().getString("cloud.store") + tp); - String tp2 = dest.path; - if (tp2.endsWith("/")) - tp2 = tp2.substring(0,tp2.length() -1); - - String nv = HttpClientUtil.trustPut(h,X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + tp2); - //(X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + tp + "-->" + h + " ******************X_COPY_FROM " + nv + ":" + tp2); - - - - }catch (Exception e){ - e.printStackTrace(); - CaimitoException.throwException(e); - - } - } - - - public void doMove(ResourceObj dest)throws CaimitoException{ - try{ - - doCopy(dest); - doDelete(); - - }catch (Exception e){ - e.printStackTrace(); - CaimitoException.throwException(e); - - } - } - - public boolean doExists()throws CaimitoException{ - if (path.equals("") || path.equals("/")) - return true; - - //("OEXISTST " + path); - init(); - return ex; - //return new File(root + path).exists(); - } - public void deleteCloudFile()throws CaimitoException{ - - -try{ - - auth(); - - - - if (isDirectory()) - { - - Vector flist = doList(); - - if (flist != null && flist.size() > 0) - for(int i = 0 ; i < flist.size() ; i++) -{ - OpenStackResourceObj nf = (OpenStackResourceObj)flist.elementAt(i); - nf.doDelete(); - /*String nt = t; - boolean isd = false; - if (nf.isDirectory()) - { - nt = nt + nf.path.substring(path.length(),nf.path.length()); - OpenStackResourceObj dr = new OpenStackResourceObj(); - dr.path = nt; - dr.doMkdir(); - isd = true; - nf.doCopy(dr); - } - else - try - { - ResourceObj dr = new OpenStackResourceObj(); - dr.path = t + nf.getName(); - - nf.xCopy(dr); - }catch (Exception e){ - e.printStackTrace(); - CaimitoException.throwException(e); - - }*/ - -} - } - - - - - Hashtable h = new Hashtable(); - h.put("X-Auth-Token",X_Auth_Token); - //( "DEO DELOET " + X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + CaimitoUtil.urlEncode(path) + "?format=json"); - - String nv = null; - String p2 = path; - if (p2.endsWith("/")) - p2 = p2.substring(0,p2.length() -1); - - nv = HttpClientUtil.trustDelete(h,X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + CaimitoUtil.urlEncode(p2) ); - - - //("DELETE OF he2 " + nv); - - - - - - - - - - - - - - - - - - - }catch (Exception e){ - e.printStackTrace(); - CaimitoException.throwException(e); - } - } - - protected void init(){ - if (init)return; -try{ - init = true; - if (path.equals("") || path.equals("/")) - return ; - - auth(); - - Hashtable h = new Hashtable(); - h.put("X-Auth-Token",X_Auth_Token); - //("INIT 1 " + X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + CaimitoUtil.urlEncode(path) + "?format=json"); - - //String nv = null; - //try{ - String p2 = path; - if (p2.endsWith("/")) - p2 = p2.substring(0,p2.length() -1); - int nv = HttpClientUtil.trustHead(h,X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + CaimitoUtil.urlEncode(p2) + "?format=json"); - if (nv == 404)return; - /*}catch (Exception e){ - try{ - - nv = HttpClientUtil.trustGet(h,X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + CaimitoUtil.urlEncode(path + "/") + "?format=json"); - }catch (Exception e2){ - //("INIT 2 OPR.initerr " + e2.toString()); - return; - } - isd = true; - //("CLOUD STORE 2"); - }*/ - //(X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + path + "-->" + h + " THEY find file AUTHO2 " + nv); -// Last-Modified=Tue, 24 Apr 2012 00:05:15 GMT, Accept-Ranges=bytes, Content-Length=0, X-Trans-Id=txd7c65f16aa884af9a09266da2636daf5, Date=Tue, 24 Apr 2012 03:15:30 GMT, X-Auth-Token=AUTH_tke0c45f67d4fb47189ad41fc771b4b53f, Content-Type=application/x-www-form-urlencoded; charset=ISO-8859-1, Connection=keep-alive, Etag=d41d8cd98f00b204e9800998ecf8427e - // nv = nv.substring(1,nv.length() - 1); - //("DEVALUE OF he2 " + nv); - - - - NameValuePairs nvp = new NameValuePairs(h); - -/* if (StringUtil.isRealString(nv)) - { - if (nv.equals(".")) - isd = true; - else{ - - Gson gson = new Gson(); - OSRAttribute oa = gson.fromJson(nv, new TypeToken() {}.getType()); - cl = oa.bytes; - lm = oa.lastModified(); - ex = true; - if (oa.content_type != null && oa.content_type.equals("application/directory")) - isd = true; - - return; - } - }*/ - - //(X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + path + "-->" + h + " THEY find file AUTHO3 " + nvp); - - cl = nvp.getLong("Content-Length"); - lm = dfm.parse(nvp.getString("Last-Modified")).getTime(); - if (nvp.getString("Content-Type").equals("application/directory")) - isd = true; - - //init = true; - ex = true; -}catch (Throwable e){ - e.printStackTrace(); -} - - - } - - protected boolean ex = false; - protected boolean init = false; - protected boolean isd = false; - protected long lm = 0; - protected long cl = 0; - //protected OSRAttribute attributes = null; - - public void doMkdir()throws CaimitoException{ - try{ - - //new File(root + path).mkdirs(); - - - - auth(); - - Hashtable h = new Hashtable(); - h.put("X-Auth-Token",X_Auth_Token); - h.put("Content-Type","application/directory"); - String tp = path; - if (tp.endsWith("/")) - //tp = tp + "/"; - tp = tp.substring(0,tp.length() -1); - String nv = HttpClientUtil.trustPut(h,X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + tp); - //(X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + tp + "-->" + h + " THEY AUTHOiniyt " + nv); - - - }catch (Exception e){ - e.printStackTrace(); - CaimitoException.throwException(e); - } - } - - public long getLastModified()throws CaimitoException{ - //return new File(root + path).lastModified(); - init(); - return lm; - } - - public boolean isDirectory()throws CaimitoException{ - if (path.equals("") || path.equals("/")) - return true; - init(); - return isd; - } - public long getContentLength()throws CaimitoException{ - init(); - return cl; - } - - protected static String X_Auth_Token = null; - protected static String X_Storage_Url = null; - protected static long authtime = 0; - void auth()throws CaimitoException{ - try{ - if (X_Auth_Token != null && X_Storage_Url != null && !((System.currentTimeMillis() - authtime) > maxautint))return; - Hashtable h = new Hashtable(); - h.put("X-Auth-User",CaimitoConfig.getConfig().getString("cloud.username")); - h.put("X-Auth-Key",CaimitoConfig.getConfig().getString("cloud.api.key_password")); - String nv = HttpClientUtil.trustGet(h,CaimitoConfig.getConfig().getString("cloud.url")); - //(h + " THEY AUTHO " + nv); - - - - X_Storage_Url = h.get("X-Storage-Url"); - X_Auth_Token = h.get("X-Auth-Token"); - authtime = System.currentTimeMillis(); - }catch (Throwable e){ - e.printStackTrace(); - CaimitoException.throwException(e); - } - } - - public Vector doList()throws CaimitoException{ - //doDelete(); - Vector l = new Vector(); - - try{ - - auth(); - - Hashtable h = new Hashtable(); - h.put("X-Auth-Token",X_Auth_Token); - String p2 = path; - if (p2.endsWith("/")) - p2 = p2.substring(0,p2.length() -1); - //p2 = p2 + "/"; - // ?prefix=photos/&delimiter=/ - boolean isroot = (p2.equals("/") || p2.equals("")); - String pars = "?delimiter=/"; - if (!isroot){ - String p2b = p2; - if (p2b.startsWith("/")) - p2b = p2b.substring(1,p2b.length()); - pars = pars + "&prefix=" + CaimitoUtil.urlEncode(p2b) + "/"; - } - //pars = ""; - //("***doList1 " + X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + CaimitoUtil.urlEncode(p2) + pars + " --> " + h + " h <-->nv "); -//+ CaimitoUtil.urlEncode(p2) - String nv = HttpClientUtil.trustGet(h,X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + pars); - //("doList " + X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + CaimitoUtil.urlEncode(p2) + pars + " --> " + h + " h <-->nv " + nv); - if (nv == null || nv.length() < 1)return l; - ByteArrayInputStream bin = new ByteArrayInputStream(nv.getBytes()); - EZArrayList lblv = new EZArrayList(bin); - bin.close(); - String oa = null; - OpenStackResourceObj ro = null; - String dn = ""; - String ps = ""; - - if (!path.endsWith("/")) - ps = "/"; - for (int ct = 0;ct < lblv.size();ct++) - { - dn = lblv.elementAt(ct).toString(); - /*//("****************************DN= " + dn); - ro = new OpenStackResourceObj(); - - ro.path = "/" + dn; - ro.user = user; - ro.listing = listing; - ro.ex = true; - try{ - - ro.doDelete(); - }catch (Exception e){ - e.printStackTrace(); - }*/ - if (dn.equals(".")){ - //("****************************DN= " + dn); - - continue; - } - if (dn.endsWith("/")) - { - //("****************************DN= " + dn); - - continue; - - } - //(path + " OS LIST " + dn); - ro = new OpenStackResourceObj(); - - ro.path = "/" + dn; - ro.user = user; - ro.listing = listing; - ro.ex = true; - - - l.add(ro); - - - } - - - - /* Gson gson = new Gson(); - - List attrs = gson.fromJson(nv, new TypeToken>() {}.getType()); - - Vector lblv = new Vector(attrs); - OSRAttribute oa = null; - OpenStackResourceObj ro = null; - String ps = ""; - if (!path.endsWith("/")) - ps = "/"; - String dn = null; - for (int ct = 0;ct < lblv.size();ct++) - { - oa = lblv.elementAt(ct); - //(path + " OS LIST " + oa); - ro = new OpenStackResourceObj(); - dn = oa.name; - if (dn.endsWith("/")) - { - dn = dn.substring(0,dn.length() -1); - ro.isd = true; - - } - ro.path = path + ps + dn; - ro.user = user; - ro.listing = listing; - ro.cl = oa.bytes; - ro.init = true; - ro.ex = true; - ro.lm = oa.lastModified(); - l.add(ro); - - - }*/ -/* - String[] dl = new File(root + path).list(); - String ps = ""; - if (!path.endsWith("/")) - ps = "/"; - if (dl != null){ - FileResourceObj ro = null; - for (int ct = 0; ct < dl.length;ct++){ - ro = new FileResourceObj(); - ro.path = path + ps + dl[ct]; - ro.user = user; - ro.listing = listing; - l.add(ro); - } - }*/ - - }catch (Throwable e){ - e.printStackTrace(); - CaimitoException.throwException(e); - } - return l; - - } - - -} - -class OSRAttribute{ - - static DateFormat dfm = null; - static boolean rmdend = false; - static{ - try{ - //("DATE FORMAT " + CaimitoConfig.getConfig().getString("cloud.dateformat")); - if (CaimitoConfig.getConfig().getBoolean("cloud.date.remove.end")) - { - rmdend = true; - } - dfm = new SimpleDateFormat(CaimitoConfig.getConfig().getString("cloud.dateformat")); - }catch (Throwable e){ - e.printStackTrace(); - } - } - - - String name = null; - String hash = null; - long bytes = 0; - String content_type = null; - String last_modified = null; - public long lastModified()throws Exception{ - if (rmdend) - { - String lm = last_modified; - int i = lm.lastIndexOf("."); - if (i > 0){ - lm = lm.substring(0,i); - return dfm.parse(lm).getTime(); - - } - } - return dfm.parse(last_modified).getTime(); - } - -} - -/*class OSRObjDetails{ - - static DateFormat dfm = null; - static boolean rmdend = false; - static{ - try{ - //("DATE FORMAT " + CaimitoConfig.getConfig().getString("cloud.dateformat")); - if (CaimitoConfig.getConfig().getBoolean("cloud.date.remove.end")) - { - rmdend = true; - } - dfm = new SimpleDateFormat(CaimitoConfig.getConfig().getString("cloud.dateformat")); - }catch (Throwable e){ - e.printStackTrace(); - } - } - - - -Last-Modified=Tue, 24 Apr 2012 00:05:15 GMT, Accept-Ranges=bytes, Content-Length=0, X-Trans-Id=txd7c65f16aa884af9a09266da2636daf5, Date=Tue, 24 Apr 2012 03:15:30 GMT, X-Auth-Token=AUTH_tke0c45f67d4fb47189ad41fc771b4b53f, Content-Type=application/x-www-form-urlencoded; charset=ISO-8859-1, Connection=keep-alive, Etag=d41d8cd98f00b204e9800998ecf8427e - - - - public long lastModified()throws Exception{ - if (rmdend) - { - String lm = last_modified; - int i = lm.lastIndexOf("."); - if (i > 0){ - lm = lm.substring(0,i); - return dfm.parse(lm).getTime(); - - } - } - return dfm.parse(last_modified).getTime(); - } - -}*/ - +/* + Copyright (c) 2011-2012, the Caimito project (http://caimito.ngasi.com/). All rights reserved. +Apache Software License 2.0 +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WebAppShowCase +OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + + + + +package ngasi.caimito.resource; +import ngasi.caimito.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; + +import tools.util.*; +import java.util.Vector; +import java.util.Hashtable; +import com.google.gson.*; +import java.lang.reflect.*; +import com.google.gson.reflect.*; +import java.util.List; +import java.text.*; +import java.util.Locale; +import java.util.Date; +import java.util.Enumeration; +import java.util.Map; +import java.io.ByteArrayInputStream; +import java.util.Iterator; + +public class OpenStackResourceObj extends CloudResourceObj + { + protected static final int BUFFER_SIZE = 2048; + + + static DateFormat dfm = null; + + static long maxautint = 0; + + + + static{ + try{ + maxautint = CaimitoConfig.getConfig().getLong("cloud.max_auth_interval") * 60* 1000L; + }catch (Exception e){ + e.printStackTrace(); + } + try{ + + dfm = new SimpleDateFormat(CaimitoConfig.getConfig().getString("cloud.obj.details.dateformat")); + }catch (Throwable e){ + e.printStackTrace(); + } + } + + + public void retrieveCloudFile(String path,String tf)throws CaimitoException{ + try{ + auth(); + Hashtable h = new Hashtable(); + h.put("X-Auth-Token",X_Auth_Token); + + + HttpClientUtil.trustGetToFile(h,X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + CaimitoUtil.urlEncode(path),tf); + }catch (Exception e){ + e.printStackTrace(); + CaimitoException.throwException(e); + + } + + } + + + public void doWrite(InputStream dest)throws CaimitoException{ + try{ + if (dest.available() < 0)return; + + + Hashtable h = new Hashtable(); + h.put("X-Auth-Token",X_Auth_Token); + if (contentType != null) + h.put("Content-Type",contentType); + + // if (contentLength > -1 ) + // h.put("Content-Length",String.valueOf(contentLength)); + + + String nv = null; + + + nv = HttpClientUtil.trustPut(h,X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + CaimitoUtil.urlEncode(path),dest); + //(path + " put me " + nv); + + }catch (Exception e){ + e.printStackTrace(); + CaimitoException.throwException(e); + + } + } + + + + +public void doCopy(ResourceObj dest)throws CaimitoException + { + String fs = path; + String t = dest.path; +// if (!isDirectory()) +// return; + if ( !t.endsWith("/")) + t = t + "/"; + +// Vector flist = doList(); + + //----------- + + + auth(); + + Hashtable h = new Hashtable(); + h.put("X-Auth-Token",X_Auth_Token); + if (isDirectory()) + h.put("Content-Type","application/directory"); + //h.put("Content-Length","0"); + + String tp = path; + if (tp.endsWith("/")) + tp = tp.substring(0,tp.length() -1); + h.put("X_COPY_FROM",CaimitoConfig.getConfig().getString("cloud.store") + tp); + String tp2 = dest.path; + if (tp2.endsWith("/")) + tp2 = tp2.substring(0,tp2.length() -1); +try{ + + String nv = HttpClientUtil.trustPut(h,X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + tp2); + //(X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + tp + "-->" + h + " ******************X_COPY_FROM 1111 " + nv + ":" + tp2); + }catch (Exception e){ + e.printStackTrace(); + CaimitoException.throwException(e); + + } + + if (!isDirectory()) + { + + return; + } + Vector flist = doList(); + + if (flist == null || flist.size() < 1) + return; + for(int i = 0 ; i < flist.size() ; i++) +{ + OpenStackResourceObj nf = (OpenStackResourceObj)flist.elementAt(i); + String nt = t; + boolean isd = false; + if (nf.isDirectory()) + { + nt = nt + nf.path.substring(path.length(),nf.path.length()); + OpenStackResourceObj dr = new OpenStackResourceObj(); + dr.path = nt; + dr.doMkdir(); + isd = true; + nf.doCopy(dr); + } + else + try + { + ResourceObj dr = new OpenStackResourceObj(); + dr.path = t + nf.getName(); + + nf.xCopy(dr); + }catch (Exception e){ + e.printStackTrace(); + CaimitoException.throwException(e); + + } + +} + + + } + + public void xCopy(ResourceObj dest)throws CaimitoException{ + try{ + + + auth(); + + Hashtable h = new Hashtable(); + h.put("X-Auth-Token",X_Auth_Token); + if (isDirectory()) + h.put("Content-Type","application/directory"); + //h.put("Content-Length","0"); + + String tp = path; + if (tp.endsWith("/")) + tp = tp.substring(0,tp.length() -1); + h.put("X_COPY_FROM",CaimitoConfig.getConfig().getString("cloud.store") + tp); + String tp2 = dest.path; + if (tp2.endsWith("/")) + tp2 = tp2.substring(0,tp2.length() -1); + + String nv = HttpClientUtil.trustPut(h,X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + tp2); + //(X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + tp + "-->" + h + " ******************X_COPY_FROM " + nv + ":" + tp2); + + + + }catch (Exception e){ + e.printStackTrace(); + CaimitoException.throwException(e); + + } + } + + + public void doMove(ResourceObj dest)throws CaimitoException{ + try{ + + doCopy(dest); + doDelete(); + + }catch (Exception e){ + e.printStackTrace(); + CaimitoException.throwException(e); + + } + } + + public boolean doExists()throws CaimitoException{ + if (path.equals("") || path.equals("/")) + return true; + + //("OEXISTST " + path); + init(); + return ex; + //return new File(root + path).exists(); + } + public void deleteCloudFile()throws CaimitoException{ + + +try{ + + auth(); + + + + if (isDirectory()) + { + + Vector flist = doList(); + + if (flist != null && flist.size() > 0) + for(int i = 0 ; i < flist.size() ; i++) +{ + OpenStackResourceObj nf = (OpenStackResourceObj)flist.elementAt(i); + nf.doDelete(); + /*String nt = t; + boolean isd = false; + if (nf.isDirectory()) + { + nt = nt + nf.path.substring(path.length(),nf.path.length()); + OpenStackResourceObj dr = new OpenStackResourceObj(); + dr.path = nt; + dr.doMkdir(); + isd = true; + nf.doCopy(dr); + } + else + try + { + ResourceObj dr = new OpenStackResourceObj(); + dr.path = t + nf.getName(); + + nf.xCopy(dr); + }catch (Exception e){ + e.printStackTrace(); + CaimitoException.throwException(e); + + }*/ + +} + } + + + + + Hashtable h = new Hashtable(); + h.put("X-Auth-Token",X_Auth_Token); + //( "DEO DELOET " + X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + CaimitoUtil.urlEncode(path) + "?format=json"); + + String nv = null; + String p2 = path; + if (p2.endsWith("/")) + p2 = p2.substring(0,p2.length() -1); + + nv = HttpClientUtil.trustDelete(h,X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + CaimitoUtil.urlEncode(p2) ); + + + //("DELETE OF he2 " + nv); + + + + + + + + + + + + + + + + + + + }catch (Exception e){ + e.printStackTrace(); + CaimitoException.throwException(e); + } + } + + protected void init(){ + if (init)return; +try{ + init = true; + if (path.equals("") || path.equals("/")) + return ; + + auth(); + + Hashtable h = new Hashtable(); + h.put("X-Auth-Token",X_Auth_Token); + //("INIT 1 " + X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + CaimitoUtil.urlEncode(path) + "?format=json"); + + //String nv = null; + //try{ + String p2 = path; + if (p2.endsWith("/")) + p2 = p2.substring(0,p2.length() -1); + int nv = HttpClientUtil.trustHead(h,X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + CaimitoUtil.urlEncode(p2) + "?format=json"); + if (nv == 404)return; + /*}catch (Exception e){ + try{ + + nv = HttpClientUtil.trustGet(h,X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + CaimitoUtil.urlEncode(path + "/") + "?format=json"); + }catch (Exception e2){ + //("INIT 2 OPR.initerr " + e2.toString()); + return; + } + isd = true; + //("CLOUD STORE 2"); + }*/ + //(X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + path + "-->" + h + " THEY find file AUTHO2 " + nv); +// Last-Modified=Tue, 24 Apr 2012 00:05:15 GMT, Accept-Ranges=bytes, Content-Length=0, X-Trans-Id=txd7c65f16aa884af9a09266da2636daf5, Date=Tue, 24 Apr 2012 03:15:30 GMT, X-Auth-Token=AUTH_tke0c45f67d4fb47189ad41fc771b4b53f, Content-Type=application/x-www-form-urlencoded; charset=ISO-8859-1, Connection=keep-alive, Etag=d41d8cd98f00b204e9800998ecf8427e + // nv = nv.substring(1,nv.length() - 1); + //("DEVALUE OF he2 " + nv); + + + + NameValuePairs nvp = new NameValuePairs(h); + +/* if (StringUtil.isRealString(nv)) + { + if (nv.equals(".")) + isd = true; + else{ + + Gson gson = new Gson(); + OSRAttribute oa = gson.fromJson(nv, new TypeToken() {}.getType()); + cl = oa.bytes; + lm = oa.lastModified(); + ex = true; + if (oa.content_type != null && oa.content_type.equals("application/directory")) + isd = true; + + return; + } + }*/ + + //(X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + path + "-->" + h + " THEY find file AUTHO3 " + nvp); + + cl = nvp.getLong("Content-Length"); + lm = dfm.parse(nvp.getString("Last-Modified")).getTime(); + if (nvp.getString("Content-Type").equals("application/directory")) + isd = true; + + //init = true; + ex = true; +}catch (Throwable e){ + e.printStackTrace(); +} + + + } + + protected boolean ex = false; + protected boolean init = false; + protected boolean isd = false; + protected long lm = 0; + protected long cl = 0; + //protected OSRAttribute attributes = null; + + public void doMkdir()throws CaimitoException{ + try{ + + //new File(root + path).mkdirs(); + + + + auth(); + + Hashtable h = new Hashtable(); + h.put("X-Auth-Token",X_Auth_Token); + h.put("Content-Type","application/directory"); + String tp = path; + if (tp.endsWith("/")) + //tp = tp + "/"; + tp = tp.substring(0,tp.length() -1); + String nv = HttpClientUtil.trustPut(h,X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + tp); + //(X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + tp + "-->" + h + " THEY AUTHOiniyt " + nv); + + + }catch (Exception e){ + e.printStackTrace(); + CaimitoException.throwException(e); + } + } + + public long getLastModified()throws CaimitoException{ + //return new File(root + path).lastModified(); + init(); + return lm; + } + + public boolean isDirectory()throws CaimitoException{ + if (path.equals("") || path.equals("/")) + return true; + init(); + return isd; + } + public long getContentLength()throws CaimitoException{ + init(); + return cl; + } + + protected static String X_Auth_Token = null; //"5bba5c21-3c8c-4f6b-8b17-9adb7c2ad4ea"; + protected static String X_Storage_Url = null; //"http://swift.rc.nectar.org.au:8888/v1/AUTH_793"; + protected static long authtime = 0; + void auth()throws CaimitoException{ + try{ + if (X_Auth_Token != null && X_Storage_Url != null && !((System.currentTimeMillis() - authtime) > maxautint))return; + Hashtable h = new Hashtable(); + h.put("X-Auth-User",CaimitoConfig.getConfig().getString("cloud.username")); + h.put("X-Auth-Key",CaimitoConfig.getConfig().getString("cloud.api.key_password")); + String curl = CaimitoConfig.getConfig().getString("cloud.url"); + if (curl.endsWith("/")) + curl = curl.substring(0,curl.length() - 1); + String nv = HttpClientUtil.trustGet(h,curl); + + X_Storage_Url = h.get("X-Storage-Url"); + X_Auth_Token = h.get("X-Auth-Token"); + if (X_Storage_Url == null || X_Auth_Token == null){ + + if (!curl.endsWith("/tokens")) + curl = curl + "/tokens"; + Hashtable pc = new Hashtable(); + pc.put("username",CaimitoConfig.getConfig().getString("cloud.username")); + pc.put("password",CaimitoConfig.getConfig().getString("cloud.api.key_password")); + + Hashtable> auh = new Hashtable>(); + auh.put("passwordCredentials",pc); + + Hashtable tl = new Hashtable(); + tl.put("auth",auh); + + h = new Hashtable(); + h.put("Content-type","application/json"); + + Gson gson = new Gson(); + String json = gson.toJson(tl); + ByteArrayInputStream dest = new ByteArrayInputStream(json.getBytes()); + + nv = HttpClientUtil.trustPost(h,curl,dest); + //Gson gson = new Gson(); + OSV2TokenResponse oa = gson.fromJson(nv, new TypeToken() {}.getType()); + Map eps = oa.getResponse(); + if (CaimitoConfig.getConfig().getString("cloud.endpoint.access").equals("internal")) + X_Storage_Url = eps.get("internalURL"); + else + X_Storage_Url = eps.get("publicURL"); + X_Auth_Token = oa.access.token.id; + if (X_Storage_Url == null || X_Auth_Token == null) + CaimitoException.throwException("unable_to_auth"); + + + } + authtime = System.currentTimeMillis(); + }catch (Throwable e){ + e.printStackTrace(); + CaimitoException.throwException(e); + } + } + + public Vector doList()throws CaimitoException{ + //doDelete(); + Vector l = new Vector(); + + try{ + + auth(); + + Hashtable h = new Hashtable(); + h.put("X-Auth-Token",X_Auth_Token); + String p2 = path; + if (p2.endsWith("/")) + p2 = p2.substring(0,p2.length() -1); + //p2 = p2 + "/"; + // ?prefix=photos/&delimiter=/ + boolean isroot = (p2.equals("/") || p2.equals("")); + String pars = "?delimiter=/"; + if (!isroot){ + String p2b = p2; + if (p2b.startsWith("/")) + p2b = p2b.substring(1,p2b.length()); + pars = pars + "&prefix=" + CaimitoUtil.urlEncode(p2b) + "/"; + } + //pars = ""; + //("***doList1 " + X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + CaimitoUtil.urlEncode(p2) + pars + " --> " + h + " h <-->nv "); +//+ CaimitoUtil.urlEncode(p2) + String nv = HttpClientUtil.trustGet(h,X_Storage_Url + "/" + CaimitoConfig.getConfig().getString("cloud.store") + pars); + + if (nv == null || nv.length() < 1)return l; + ByteArrayInputStream bin = new ByteArrayInputStream(nv.getBytes()); + EZArrayList lblv = new EZArrayList(bin); + bin.close(); + String oa = null; + OpenStackResourceObj ro = null; + String dn = ""; + String ps = ""; + + if (!path.endsWith("/")) + ps = "/"; + for (int ct = 0;ct < lblv.size();ct++) + { + dn = lblv.elementAt(ct).toString(); + /*//("****************************DN= " + dn); + ro = new OpenStackResourceObj(); + + ro.path = "/" + dn; + ro.user = user; + ro.listing = listing; + ro.ex = true; + try{ + + ro.doDelete(); + }catch (Exception e){ + e.printStackTrace(); + }*/ + if (dn.equals(".")){ + //("****************************DN= " + dn); + + continue; + } + if (dn.endsWith("/")) + { + //("****************************DN= " + dn); + + continue; + + } + //(path + " OS LIST " + dn); + ro = new OpenStackResourceObj(); + + ro.path = "/" + dn; + ro.user = user; + ro.listing = listing; + ro.ex = true; + + + l.add(ro); + + + } + + + + /* Gson gson = new Gson(); + + List attrs = gson.fromJson(nv, new TypeToken>() {}.getType()); + + Vector lblv = new Vector(attrs); + OSRAttribute oa = null; + OpenStackResourceObj ro = null; + String ps = ""; + if (!path.endsWith("/")) + ps = "/"; + String dn = null; + for (int ct = 0;ct < lblv.size();ct++) + { + oa = lblv.elementAt(ct); + //(path + " OS LIST " + oa); + ro = new OpenStackResourceObj(); + dn = oa.name; + if (dn.endsWith("/")) + { + dn = dn.substring(0,dn.length() -1); + ro.isd = true; + + } + ro.path = path + ps + dn; + ro.user = user; + ro.listing = listing; + ro.cl = oa.bytes; + ro.init = true; + ro.ex = true; + ro.lm = oa.lastModified(); + l.add(ro); + + + }*/ +/* + String[] dl = new File(root + path).list(); + String ps = ""; + if (!path.endsWith("/")) + ps = "/"; + if (dl != null){ + FileResourceObj ro = null; + for (int ct = 0; ct < dl.length;ct++){ + ro = new FileResourceObj(); + ro.path = path + ps + dl[ct]; + ro.user = user; + ro.listing = listing; + l.add(ro); + } + }*/ + + }catch (Throwable e){ + e.printStackTrace(); + CaimitoException.throwException(e); + } + return l; + + } + + +} + +class OSRAttribute{ + + static DateFormat dfm = null; + static boolean rmdend = false; + static{ + try{ + //("DATE FORMAT " + CaimitoConfig.getConfig().getString("cloud.dateformat")); + if (CaimitoConfig.getConfig().getBoolean("cloud.date.remove.end")) + { + rmdend = true; + } + dfm = new SimpleDateFormat(CaimitoConfig.getConfig().getString("cloud.dateformat")); + }catch (Throwable e){ + e.printStackTrace(); + } + } + + + String name = null; + String hash = null; + long bytes = 0; + String content_type = null; + String last_modified = null; + public long lastModified()throws Exception{ + if (rmdend) + { + String lm = last_modified; + int i = lm.lastIndexOf("."); + if (i > 0){ + lm = lm.substring(0,i); + return dfm.parse(lm).getTime(); + + } + } + return dfm.parse(last_modified).getTime(); + } + +} +class OSV2TokenResponse { + public TokenObj access = null; + + //public Hashtable> access = null; + public Map getResponse(){ + Hashtable res = new Hashtable(); + Iterator en = access.serviceCatalog.iterator(); + //String n = null; + EndPoints v = null; + while(en.hasNext()){ + v = en.next(); + if (v.type.equals("object-store") && v.name.equals("swift")){ + Iterator> enp = v.endpoints.iterator(); + + if(enp.hasNext()) + return enp.next(); + } + } + return res; + } + +} + class TokenObj{ + public TokenObj2 token = null; + public List serviceCatalog = null; + + } + class EndPoints{ + public List> endpoints = null; + public String type = null; + public String name = null; + + } + class TokenObj2{ + public String id = null; + } +/*class OSRObjDetails{ + + static DateFormat dfm = null; + static boolean rmdend = false; + static{ + try{ + //("DATE FORMAT " + CaimitoConfig.getConfig().getString("cloud.dateformat")); + if (CaimitoConfig.getConfig().getBoolean("cloud.date.remove.end")) + { + rmdend = true; + } + dfm = new SimpleDateFormat(CaimitoConfig.getConfig().getString("cloud.dateformat")); + }catch (Throwable e){ + e.printStackTrace(); + } + } + + + +Last-Modified=Tue, 24 Apr 2012 00:05:15 GMT, Accept-Ranges=bytes, Content-Length=0, X-Trans-Id=txd7c65f16aa884af9a09266da2636daf5, Date=Tue, 24 Apr 2012 03:15:30 GMT, X-Auth-Token=AUTH_tke0c45f67d4fb47189ad41fc771b4b53f, Content-Type=application/x-www-form-urlencoded; charset=ISO-8859-1, Connection=keep-alive, Etag=d41d8cd98f00b204e9800998ecf8427e + + + + public long lastModified()throws Exception{ + if (rmdend) + { + String lm = last_modified; + int i = lm.lastIndexOf("."); + if (i > 0){ + lm = lm.substring(0,i); + return dfm.parse(lm).getTime(); + + } + } + return dfm.parse(last_modified).getTime(); + } + +}*/ + diff --git a/source/ngasi/caimito/resource/ResourceObj.java b/source/ngasi/caimito/resource/ResourceObj.java old mode 100644 new mode 100755 index 7d3e383..86933ad --- a/source/ngasi/caimito/resource/ResourceObj.java +++ b/source/ngasi/caimito/resource/ResourceObj.java @@ -1,186 +1,186 @@ -/* - Copyright (c) 2011-2012, the Caimito project (http://caimito.ngasi.com/). All rights reserved. -Apache Software License 2.0 -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WebAppShowCase -OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - - - - -package ngasi.caimito.resource; -import ngasi.caimito.*; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; -import java.util.TimeZone; -import java.util.Vector; -import java.io.InputStream; - -public abstract class ResourceObj - { - public String contentType = null; - public long contentLength = -1; - - public boolean listing = false; - public String user = null; - public String path = null; - String mt = null; - //public String root = null; - public String privilege = null; //r,w,a - - protected static final SimpleDateFormat format = - new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US); - protected static final TimeZone gmtZone = TimeZone.getTimeZone("GMT"); - - static { - - format.setTimeZone(gmtZone); - - - } - - public boolean canRead()throws CaimitoException{ - return true; - } - public boolean canWrite()throws CaimitoException{ - return true; - } - - - public void checkRead()throws CaimitoException{ - if (!canRead()) - CaimitoException.throwException("forbidden"); - } - public void checkWrite()throws CaimitoException{ - if (!canWrite()) - CaimitoException.throwException("forbidden"); - - } - public ResourceObj getReadmeFile()throws CaimitoException{ - return null; - } - - public boolean listings()throws CaimitoException{ - checkRead(); - return listing; - } - - public String getName()throws CaimitoException{ - int i = path.lastIndexOf("/"); - if (i > -1 && path.length() > 1){ - return path.substring(i + 1,path.length()); - } - return null; - } - - public String getLastModifiedHttp() throws CaimitoException{ - synchronized (format) { - return format.format(new Date(getLastModified())); - } - } - - public long getCreation() throws CaimitoException{ - return getLastModified(); - } - - - public InputStream getInputStream()throws CaimitoException{ - checkRead(); - return doGetInputStream(); - } - - public Vector list()throws CaimitoException{ - checkRead(); - return doList(); - } - public boolean exists()throws CaimitoException{ - checkRead(); - return doExists(); - } - public void delete()throws CaimitoException{ - checkWrite(); - doDelete(); - } - - public void mkdir()throws CaimitoException{ - checkWrite(); - doMkdir(); - } - - public void write(InputStream inp)throws CaimitoException{ - checkWrite(); - doWrite(inp); - } - - - public void copy(ResourceObj dest)throws CaimitoException{ - checkRead(); - dest.checkWrite(); - doCopy(dest); - } - - public void move(ResourceObj dest)throws CaimitoException{ - checkWrite(); - dest.checkWrite(); - doMove(dest); - } - - public String getMimeType(){ - return mt; - } - public void setMimeType(String t){ - mt = t; - } - public String getETag()throws CaimitoException{ - - long contentLength = getContentLength(); - long lastModified = getLastModified(); - if ((contentLength >= 0) || (lastModified >= 0)) { - return "W/\"" + contentLength + "-" + - lastModified + "\""; - } - - return null; - } - public abstract void doMove(ResourceObj dest)throws CaimitoException; - - public abstract void doCopy(ResourceObj dest)throws CaimitoException; - public abstract void doWrite(InputStream dest)throws CaimitoException; - - public abstract InputStream doGetInputStream()throws CaimitoException; - public abstract long getContentLength()throws CaimitoException; - - public abstract Vector doList()throws CaimitoException; - public abstract boolean doExists()throws CaimitoException; - public abstract void doDelete()throws CaimitoException; - public abstract void doMkdir()throws CaimitoException; - - public abstract boolean isDirectory()throws CaimitoException; - - public abstract long getLastModified()throws CaimitoException; -} - - +/* + Copyright (c) 2011-2012, the Caimito project (http://caimito.ngasi.com/). All rights reserved. +Apache Software License 2.0 +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WebAppShowCase +OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + + + + +package ngasi.caimito.resource; +import ngasi.caimito.*; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; +import java.util.Vector; +import java.io.InputStream; + +public abstract class ResourceObj + { + public String contentType = null; + public long contentLength = -1; + + public boolean listing = false; + public String user = null; + public String path = null; + String mt = null; + //public String root = null; + public String privilege = null; //r,w,a + + protected static final SimpleDateFormat format = + new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US); + protected static final TimeZone gmtZone = TimeZone.getTimeZone("GMT"); + + static { + + format.setTimeZone(gmtZone); + + + } + + public boolean canRead()throws CaimitoException{ + return true; + } + public boolean canWrite()throws CaimitoException{ + return true; + } + + + public void checkRead()throws CaimitoException{ + if (!canRead()) + CaimitoException.throwException("forbidden"); + } + public void checkWrite()throws CaimitoException{ + if (!canWrite()) + CaimitoException.throwException("forbidden"); + + } + public ResourceObj getReadmeFile()throws CaimitoException{ + return null; + } + + public boolean listings()throws CaimitoException{ + checkRead(); + return listing; + } + + public String getName()throws CaimitoException{ + int i = path.lastIndexOf("/"); + if (i > -1 && path.length() > 1){ + return path.substring(i + 1,path.length()); + } + return null; + } + + public String getLastModifiedHttp() throws CaimitoException{ + synchronized (format) { + return format.format(new Date(getLastModified())); + } + } + + public long getCreation() throws CaimitoException{ + return getLastModified(); + } + + + public InputStream getInputStream()throws CaimitoException{ + checkRead(); + return doGetInputStream(); + } + + public Vector list()throws CaimitoException{ + checkRead(); + return doList(); + } + public boolean exists()throws CaimitoException{ + checkRead(); + return doExists(); + } + public void delete()throws CaimitoException{ + checkWrite(); + doDelete(); + } + + public void mkdir()throws CaimitoException{ + checkWrite(); + doMkdir(); + } + + public void write(InputStream inp)throws CaimitoException{ + checkWrite(); + doWrite(inp); + } + + + public void copy(ResourceObj dest)throws CaimitoException{ + checkRead(); + dest.checkWrite(); + doCopy(dest); + } + + public void move(ResourceObj dest)throws CaimitoException{ + checkWrite(); + dest.checkWrite(); + doMove(dest); + } + + public String getMimeType(){ + return mt; + } + public void setMimeType(String t){ + mt = t; + } + public String getETag()throws CaimitoException{ + + long contentLength = getContentLength(); + long lastModified = getLastModified(); + if ((contentLength >= 0) || (lastModified >= 0)) { + return "W/\"" + contentLength + "-" + + lastModified + "\""; + } + + return null; + } + public abstract void doMove(ResourceObj dest)throws CaimitoException; + + public abstract void doCopy(ResourceObj dest)throws CaimitoException; + public abstract void doWrite(InputStream dest)throws CaimitoException; + + public abstract InputStream doGetInputStream()throws CaimitoException; + public abstract long getContentLength()throws CaimitoException; + + public abstract Vector doList()throws CaimitoException; + public abstract boolean doExists()throws CaimitoException; + public abstract void doDelete()throws CaimitoException; + public abstract void doMkdir()throws CaimitoException; + + public abstract boolean isDirectory()throws CaimitoException; + + public abstract long getLastModified()throws CaimitoException; +} + + diff --git a/source/ngasi/caimito/resource/ResourceStore.java b/source/ngasi/caimito/resource/ResourceStore.java old mode 100644 new mode 100755 index 6459ab8..09a30b8 --- a/source/ngasi/caimito/resource/ResourceStore.java +++ b/source/ngasi/caimito/resource/ResourceStore.java @@ -1,733 +1,733 @@ -/* - Copyright (c) 2011-2012, the Caimito project (http://caimito.ngasi.com/). All rights reserved. -Apache Software License 2.0 -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WebAppShowCase -OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - - - - -package ngasi.caimito.resource; -import java.nio.charset.Charset; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import ngasi.caimito.*; -import org.shaft.server.auth.*; -import tools.util.*; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Enumeration; -import java.io.UnsupportedEncodingException; -import org.shaft.server.utils.*; -import tools.util.*; -import java.sql.Connection; -import java.sql.ResultSet; - - -public class ResourceStore - { - public static int READ = 1; - public static int WRITE = 2; - protected static MessageDigest md5Helper = null; - - static{ - - try { - md5Helper = MessageDigest.getInstance("MD5"); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } - } - - public static ResourceObj lookup(String path, HttpServletRequest request) - throws CaimitoException { - String u = (String)request.getAttribute(CaimitoConfig.caimitouserreqobj); - if (u == null) - u = login(request); - return lookup(path,u); - } - - //public static ResourceObj lookup(String path, HttpServletRequest request, - // HttpServletResponse response) - //throws CaimitoException { - // - //} - protected static Connection getConnection()throws Exception{ - return DBConMgr.getConnection(ShaftRestConfig.datasourceName); - } - public static boolean isPublicPath(String path,CaimitoBooleanHolder l,String u) - throws CaimitoException { - try{ - if (path.startsWith("/" + CaimitoConfig.shaftapp + "/") || path.equals("/favicon.ico")) - return true; - if (path.startsWith("/")) - path = path.substring(1,path.length()); - if (path.endsWith("/")) - path = path.substring(0,path.length() -1); - - return pathMatch(path,"publicpaths",l,u); - }catch (Exception e){ - //e.printStackTrace(); - //(path + " isPublicPath.error " + e.toString()); - } - return false; - } - - - public static boolean pathMatch(String path,String table,CaimitoBooleanHolder l,String u)throws Exception - { - - if (doPathMatch(path,table,l,u)) - return true; - - int i = path.lastIndexOf("/"); - while (i > 0) - { - path = path.substring(0,i); - if (doPathMatch(path,table,l,u)) - return true; - i = path.lastIndexOf("/"); - } - if (i < 0) - return doPathMatch(path,table,l,u); - - return false; - } - - protected static boolean doPathMatch(String path,String table,CaimitoBooleanHolder l,String u)throws Exception - { - SPQueryAndUpdate spq = new SPQueryAndUpdate(getConnection()); - try{ - String sql = "SELECT path,shaftowner,listing from " + CaimitoConfig.shaftapp + "_" + table + " where path = ?"; - spq.setTemplate(sql); - spq.addVariable(path); - ResultSet res = spq.query(); - //(path + " doPathMatch 1 " + table); - - if (res.next()){ - String su = res.getString(2); - NameValuePairs nvp = getUserPriv(su); - //(path + ":" + res.getString(2) + " doPathMatch 2 " + nvp); - if (nvp == null || nvp.size() < 1) - return false; - if (!path.startsWith(nvp.getString("path") + "/") && !(path + "/").startsWith(nvp.getString("path") + "/")) - return false; - if (u == null || (!su.equals(u) && !UserMgr.getUserMgr(CaimitoConfig.shaftapp).isAdminOrOwnerOf(CaimitoConfig.shaftapp,u,su))) - l.value = (res.getBoolean(3)); - else - l.value = CaimitoConfig.getConfig().getBoolean("resource.dir.listing"); - return true; - } - } - - finally{ - if (spq != null)spq.close(); - } - return false; - } - - - - protected static NameValuePairs getUserPrivFromDB(String u)throws Exception - { - try{ - - SPQueryAndUpdate spq = new SPQueryAndUpdate(getConnection()); - try{ - String sql = "SELECT * from " + CaimitoConfig.shaftapp + "_pathprivileges where resourceuser = ? AND shaftowner = ?"; - - // username = UserMgr. (CaimitoConfig.shaftapp).getOwner(CaimitoConfig.shaftapp,username); - // if (username == null) - // break; - boolean isadmin = false; - if (RealmMgr.getRealmMgr(CaimitoConfig.shaftapp).isAdmin(CaimitoConfig.shaftapp,u)){ -sql = "SELECT * from " + CaimitoConfig.shaftapp + "_pathprivileges where resourceuser = ?"; - - isadmin = true; - } - - spq.setTemplate(sql); - spq.addVariable(u); - if (!isadmin) - spq.addVariable(UserMgr.getUserMgr(CaimitoConfig.shaftapp).getOwner(CaimitoConfig.shaftapp,u)); - - return spq.getHash(); - } - - finally{ - if (spq != null)spq.close(); - } - }catch (Exception e){ - //(u + " getUserPrivFromDB " + e.toString() + ":" ); - e.printStackTrace(); - - } - return null; - } - - protected static NameValuePairs getUserPriv(String u)throws Exception - { - try{ - - - - NameValuePairs nvp = getUserPrivFromDB(u); - if (nvp == null || nvp.size() < 1) - return nvp; - String path2 = null; - String username = u; - while (true){ - username = UserMgr.getUserMgr(CaimitoConfig.shaftapp).getOwner(CaimitoConfig.shaftapp,username); - if (username == null) - break; - if (RealmMgr.getRealmMgr(CaimitoConfig.shaftapp).isAdmin(CaimitoConfig.shaftapp,username)) - break; - if (path2 == null)path2 = ""; - path2 = getUserPrivFromDB(username).getString("path") + "/" + path2; - } - if (path2 != null){ - path2 = path2 + "/" + nvp.getString("path"); - //("ZEPATH@ A " + path2); - - path2 = CaimitoUtil.normalize(path2); - //("ZEPATH@ " + path2); - - nvp.put("path",path2); - - - } - return nvp; - - - - }catch (Exception e){ - //(u + " getUserPriv.error " + e.toString() + ":" ); - e.printStackTrace(); - - } - return null; - } - - - public static ResourceObj lookup(String path, HttpServletRequest request, - HttpServletResponse response,int action) - throws CaimitoException { - String u = null; - //ResourceObj ro = null; - - if (path.equals("/") || path.equals("")) - { - if (CaimitoConfig.protectedRoot) - { - - u = login(request,response); - if (u == null)return null; - } - } - - if (u == null) - { - u = (String)request.getAttribute(CaimitoConfig.caimitouserreqobj); - if (u == null) - u = login(request); - } -try{ - //(action + ":" + path + " THE USER IS " + u); - if (RealmMgr.getRealmMgr(CaimitoConfig.shaftapp).isAdmin(CaimitoConfig.shaftapp,u)) - return lookup(path,u); - - - if (action == READ){ - - CaimitoBooleanHolder l = new CaimitoBooleanHolder(); - if (isPublicPath(path,l,u)){ - - ResourceObj ro = lookup(path,u); - if (ro != null) - ro.listing = l.value; - return ro; - } - } - if (u == null){ - - u = login(request,response); - if (u == null)return null; - } - - - - NameValuePairs nvp = getUserPriv(u); - //(u + " PRIVILEGE GO " + nvp); - if (nvp == null || nvp.size() < 1) - { - response.sendError(HttpServletResponse.SC_FORBIDDEN); - return null; - } - - - if (action == WRITE && (nvp.getInt("privilege") != WRITE ||(path.startsWith("/" + CaimitoConfig.shaftapp + "/") || path.equals("/favicon.ico")))) - { - //(u + " PRIVILEGE GO 2 " + nvp); - - response.sendError(HttpServletResponse.SC_FORBIDDEN); - return null; - } - if (!path.startsWith("/" + nvp.getString("path") + "/") && !(path + "/").startsWith("/" + nvp.getString("path") + "/")) - { - //(path + " PRIVILEGE GO 3 " + nvp); - - response.sendError(HttpServletResponse.SC_FORBIDDEN); - return null; - }else lookup("/" + nvp.getString("path") + "/",u) .mkdir(); - return lookup(path,u); - - }catch (Exception e){ - - e.printStackTrace(); - return null; - } - /*//(u + " WOWWW SD 1 " + CaimitoConfig.resource + ":" + path); - if (CaimitoConfig.resource.equals("file")){ - ro = new FileResourceObj(); - } - //(u + " WOWWW SD 2 " + ro); - - if (ro != null){ - ro.user = u; - ro.path = path; - } - return ro;*/ -// return null; - } - - - public static ResourceObj lookup(String path,String u) - throws CaimitoException { - ResourceObj ro = null; - //if (u == null) - // Thread.dumpStack(); - //(u + " WOWWW SD 1 " + CaimitoConfig.resource + ":" + path); - if (path.startsWith("/" + CaimitoConfig.shaftapp + "/") || path.equals("/favicon.ico")) - { - if (!path.startsWith("/" + CaimitoConfig.shaftapp + "/public/")) - path = "/" + CaimitoConfig.shaftapp + "/public/" + path.substring(CaimitoConfig.shaftapp.length() + 1,path.length()); - ro = new ShaftResourceObj(); - - } - else if (CaimitoConfig.resource.equals("file")){ - ro = new FileResourceObj(); - } - else if (CaimitoConfig.resource.equals("openstack")){ - //(u + " WOWWW SD 2 " + CaimitoConfig.resource + ":" + path); - - ro = new OpenStackResourceObj(); - } - //(u + " WOWWW SD 2 " + ro); - - if (ro != null){ - ro.user = u; - ro.path = path; - ro.listing = CaimitoConfig.getConfig().getBoolean("resource.dir.listing"); - } - return ro; - } - - - public static String login( HttpServletRequest request ) - throws CaimitoException { - return login(request,null); - } - - - - - protected static String getDigest(String username, String realmName)throws CaimitoException { - -try{ - - return UserMgr.getUserMgr(CaimitoConfig.shaftapp).getMD5Digest(CaimitoConfig.shaftapp,username); - /*String digestValue = username + ":" + realmName + ":" - + UserMgr. (CaimitoConfig.shaftapp).getPasswd(CaimitoConfig.shaftapp,username); - - byte[] valueBytes = null; - valueBytes = digestValue.getBytes(Charset.defaultCharset()); - - byte[] digest = null; - synchronized(md5Helper) { - digest = md5Helper.digest(valueBytes); - } - - return md5Encode(digest);*/ -}catch (Exception e){ - e.printStackTrace(); - CaimitoException.throwException(e); -} -return null; - } - - - - protected static String authenticate(NameValuePairs nvp) throws CaimitoException{ - // username="caimitoadmin", realm="Caimito", nonce="", uri="/", response="2fb52dbbcb7b25fd33840eac3027e9c5" - -String username = (String)nvp.get("username"); - String clientDigest = (String)nvp.get("response"); - String nonce = (String)nvp.get("nonce"); - String nc = (String)nvp.get("nc"); -String cnonce = (String)nvp.get("cnonce"); -String qop = (String)nvp.get("qop"); -String realm = (String)nvp.get("realm"); - String a2 = nvp.get("method") + ":" + nvp.get("uri"); - - byte[] buffer; - synchronized (md5Helper) { - buffer = md5Helper.digest(a2.getBytes(Charset.defaultCharset())); - } - String md5a2 = md5Encode(buffer); - - - String md5a1 = getDigest(username, realm); - if (md5a1 == null) - return null; - String serverDigestValue; - if (qop == null) { - serverDigestValue = md5a1 + ":" + nonce + ":" + md5a2; - } else { - serverDigestValue = md5a1 + ":" + nonce + ":" + nc + ":" + - cnonce + ":" + qop + ":" + md5a2; - } - - byte[] valueBytes = null; - // try { - valueBytes = serverDigestValue.getBytes(Charset.defaultCharset()); - // } catch (UnsupportedEncodingException uee) { - // log.error("Illegal digestEncoding: " + getDigestEncoding(), uee); - // throw new IllegalArgumentException(uee.getMessage()); - //} - - String serverDigest = null; - // Bugzilla 32137 - synchronized(md5Helper) { - serverDigest = md5Encode(md5Helper.digest(valueBytes)); - } - - /*if (log.isDebugEnabled()) { - log.debug("Digest : " + clientDigest + " Username:" + username - + " ClientSigest:" + clientDigest + " nonce:" + nonce - + " nc:" + nc + " cnonce:" + cnonce + " qop:" + qop - + " realm:" + realm + "md5a2:" + md5a2 - + " Server digest:" + serverDigest); - }*/ - - if (serverDigest.equals(clientDigest)) { - return (username); - } - - return null; - } - - - - public static String login( HttpServletRequest request, - HttpServletResponse response - ) - throws CaimitoException { - String ua = request.getHeader("user-agent"); - //if (ua.equals("Microsoft Data Access Internet Publishing Provider DAV") || ua.indexOf("davfs2") > -1 || CaimitoConfig.getConfig().getString(ua + ".auth").equals("basic")) - // return basicLogin(request,response); - //("USER AGAENT " + ua); - if (CaimitoConfig.getConfig().getString(ua + ".auth").equals("digest")) - return digestLogin(request,response); - return basicLogin(request,response); - } - - - public static String digestLogin( HttpServletRequest request, - HttpServletResponse response - ) - throws CaimitoException { - NameValuePairs nvp = new NameValuePairs(); - String hr = request.getHeader("Authorization"); - if (hr != null) - { - if (hr.startsWith("Digest ")) - { -try{ - //hr = SharedMethods.replaceSubstring(hr,"Digest ",""); - hr = hr.trim(); - hr = hr.substring(7,hr.length()); - // username="caimitoadmin", realm="Caimito", nonce="", uri="/", response="2fb52dbbcb7b25fd33840eac3027e9c5" - NameValuePairs nvp1 = NameValuePairs.toNameValuePair(hr,"=",","); - Enumeration nvp1e = nvp1.keys(); - String k = null; - String v = null; - while(nvp1e.hasMoreElements()) - { - k = (String)nvp1e.nextElement(); - v = nvp1.getString(k); - nvp.put(k.trim(),StringUtil.getTrimmedValue(v.trim())); - } - nvp.put("method",request.getMethod()); - //(nvp + " DIGEST 1 " + hr); - //byte[] b = Base64Decoder.fromBase64(hr.getBytes()); - //String auth = new String(b); - //String name = auth.substring(0,auth.indexOf(":")); - //String pass = auth.substring(auth.indexOf(":") + 1,auth.length()); - - - String name = authenticate(nvp); - //if (UserMgr. (CaimitoConfig.shaftapp).login(CaimitoConfig.shaftapp,name,pass) != null) - if (name != null) - { - //request.setPrincipal(RealmEngine.get().getPrincipal(name)); - //request.setAuthType("BASIC"); - // request.getSession() - request.setAttribute(CaimitoConfig.caimitouserreqobj,name); - return name; - } - }catch (Exception e){ - e.printStackTrace(); - //return null; - } - } - } - if (response != null) - sendError(request,response,nvp.getString("nonce").trim()); - return null; - - } - - - - protected static boolean isNonceStale(String nonce){ - - - int i = nonce.indexOf(":"); - if (i < 0 || (i + 1) == nonce.length()) { - return true; - } - long nonceTime; - try { - nonceTime = Long.parseLong(nonce.substring(0, i)); - } catch (NumberFormatException nfe) { - return true; - } - //String md5clientIpTimeKey = nonce.substring(i + 1); - long currentTime = System.currentTimeMillis(); - //(currentTime + ":" + nonceTime + ":" + CaimitoConfig.nonceValidity + ":IS NONE STALE ##########################"); - if ((currentTime - nonceTime) > CaimitoConfig.nonceValidity) { - return true; - } - else return false; -// return true; - - } - - - public static void sendError( HttpServletRequest request,HttpServletResponse response,String nonce1) - { - try - { - String nonce = generateNonce(request); - boolean isn = isNonceStale(nonce1); - //(nonce1 + " IS NOT STALE " + isn); - setAuthenticateHeader(request, response, nonce, - isn); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED); - } - catch (Exception e) - { - e.printStackTrace(); - - } - } - - - protected static String generateNonce(HttpServletRequest request) { - - long currentTime = System.currentTimeMillis(); - - - String ipTimeKey = - request.getRemoteAddr() + ":" + currentTime + ":" + randomGenerate(); - - byte[] buffer; - synchronized (md5Helper) { - buffer = md5Helper.digest( - ipTimeKey.getBytes(Charset.defaultCharset())); - } - - return currentTime + ":" + md5Encode(buffer); - } - - private static final char[] hexadecimal = - {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'a', 'b', 'c', 'd', 'e', 'f'}; - - - // --------------------------------------------------------- Public Methods - - - /** - * Encodes the 128 bit (16 bytes) MD5 into a 32 character String. - * - * @param binaryData Array containing the digest - * @return Encoded MD5, or null if encoding failed - */ - protected static String md5Encode( byte[] binaryData ) { - - if (binaryData.length != 16) - return null; - - char[] buffer = new char[32]; - - for (int i=0; i<16; i++) { - int low = binaryData[i] & 0x0f; - int high = (binaryData[i] & 0xf0) >> 4; - buffer[i*2] = hexadecimal[high]; - buffer[i*2 + 1] = hexadecimal[low]; - } - - return new String(buffer); - - } - - - - protected static String randomGenerate(){ - - String tid = AlphaNumeric.generateRandomAlphNumeric(CaimitoConfig.digestLength); -String dig = CaimitoConfig.defaultDigest; -if (dig != null) -tid = Crypto.digest(tid,dig); - return tid; - } - - protected static final String AUTH_HEADER_NAME = "WWW-Authenticate"; - protected static final String QOP = "auth"; - - protected static void setAuthenticateHeader(HttpServletRequest request, - HttpServletResponse response, - String nonce, - boolean isNonceStale) { - - // Get the realm name - String realmName = CaimitoConfig.SecurityRealmName; - - String authenticateHeader; - if (isNonceStale) { - authenticateHeader = "Digest realm=\"" + realmName + "\", " + - "qop=\"" + QOP + "\", nonce=\"" + nonce + "\", " + "opaque=\"" + - randomGenerate() + "\", stale=true"; - } else { - authenticateHeader = "Digest realm=\"" + realmName + "\", " + - "qop=\"" + QOP + "\", nonce=\"" + nonce + "\", " + "opaque=\"" + - randomGenerate() + "\""; - } - - -//("authenticateHeader 1 " + authenticateHeader); - response.setHeader(AUTH_HEADER_NAME, authenticateHeader); - - } - - - - public static String basicLogin( HttpServletRequest request, - HttpServletResponse response - ) - throws CaimitoException { - - String hr = request.getHeader("Authorization"); - if (hr != null) - { - if (hr.startsWith("Basic ")) - { - - //hr = SharedMethods.replaceSubstring(hr,"Digest ",""); - hr = hr.trim(); - hr = hr.substring(6,hr.length()); - // username="caimitoadmin", realm="Caimito", nonce="", uri="/", response="2fb52dbbcb7b25fd33840eac3027e9c5" - NameValuePairs nvp = NameValuePairs.toNameValuePair(hr,"=",","); - //(nvp + " BASIC 1 " + hr); - byte[] b = Base64Decoder.fromBase64(hr.getBytes()); - String auth = new String(b); - String name = auth.substring(0,auth.indexOf(":")); - String pass = auth.substring(auth.indexOf(":") + 1,auth.length()); - try{ - - if (UserMgr.getUserMgr(CaimitoConfig.shaftapp).login(CaimitoConfig.shaftapp,name,pass,false) != null) - { - //request.setPrincipal(RealmEngine.get().getPrincipal(name)); - //request.setAuthType("BASIC"); - // request.getSession() - request.setAttribute(CaimitoConfig.caimitouserreqobj,name); - return name; - } - }catch (Exception e){ - e.printStackTrace(); - //return null; - } - } - } - if (response != null) - sendBasicError(request,response); - return null; - - } - - public static void sendBasicError( HttpServletRequest request,HttpServletResponse response) - { - try - { - /* - if (DeploymentDescriptor.isSecureLoginRequired() && !request.getScheme().equalsIgnoreCase("https")) - { - String fau = request.getTrimmedRequestURI(); - if (request.getQueryString() != null) - fau = fau + "?" + request.getQueryString(); - if (!fau.startsWith("/")) - fau = "/" + fau; - response.sendRedirect("https://" + request.getServerName() + fau); - return; - }*/ - response.setHeader("Content-Type","text/html"); - String rn = CaimitoConfig.SecurityRealmName; - response.setHeader("WWW-Authenticate","Basic realm=\"" + rn + "\""); - response.sendError(401); - } - catch (Exception e) - { - e.printStackTrace(); - - } - } -} - -class CaimitoBooleanHolder{ - public boolean value = false; -} +/* + Copyright (c) 2011-2012, the Caimito project (http://caimito.ngasi.com/). All rights reserved. +Apache Software License 2.0 +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WebAppShowCase +OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + + + + +package ngasi.caimito.resource; +import java.nio.charset.Charset; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import ngasi.caimito.*; +import org.shaft.server.auth.*; +import tools.util.*; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Enumeration; +import java.io.UnsupportedEncodingException; +import org.shaft.server.utils.*; +import tools.util.*; +import java.sql.Connection; +import java.sql.ResultSet; + + +public class ResourceStore + { + public static int READ = 1; + public static int WRITE = 2; + protected static MessageDigest md5Helper = null; + + static{ + + try { + md5Helper = MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + } + + public static ResourceObj lookup(String path, HttpServletRequest request) + throws CaimitoException { + String u = (String)request.getAttribute(CaimitoConfig.caimitouserreqobj); + if (u == null) + u = login(request); + return lookup(path,u); + } + + //public static ResourceObj lookup(String path, HttpServletRequest request, + // HttpServletResponse response) + //throws CaimitoException { + // + //} + protected static Connection getConnection()throws Exception{ + return DBConMgr.getConnection(ShaftRestConfig.datasourceName); + } + public static boolean isPublicPath(String path,CaimitoBooleanHolder l,String u) + throws CaimitoException { + try{ + if (path.startsWith("/" + CaimitoConfig.shaftapp + "/") || path.equals("/favicon.ico")) + return true; + if (path.startsWith("/")) + path = path.substring(1,path.length()); + if (path.endsWith("/")) + path = path.substring(0,path.length() -1); + + return pathMatch(path,"publicpaths",l,u); + }catch (Exception e){ + //e.printStackTrace(); + //(path + " isPublicPath.error " + e.toString()); + } + return false; + } + + + public static boolean pathMatch(String path,String table,CaimitoBooleanHolder l,String u)throws Exception + { + + if (doPathMatch(path,table,l,u)) + return true; + + int i = path.lastIndexOf("/"); + while (i > 0) + { + path = path.substring(0,i); + if (doPathMatch(path,table,l,u)) + return true; + i = path.lastIndexOf("/"); + } + if (i < 0) + return doPathMatch(path,table,l,u); + + return false; + } + + protected static boolean doPathMatch(String path,String table,CaimitoBooleanHolder l,String u)throws Exception + { + SPQueryAndUpdate spq = new SPQueryAndUpdate(getConnection()); + try{ + String sql = "SELECT path,shaftowner,listing from " + CaimitoConfig.shaftapp + "_" + table + " where path = ?"; + spq.setTemplate(sql); + spq.addVariable(path); + ResultSet res = spq.query(); + //(path + " doPathMatch 1 " + table); + + if (res.next()){ + String su = res.getString(2); + NameValuePairs nvp = getUserPriv(su); + //(path + ":" + res.getString(2) + " doPathMatch 2 " + nvp); + if (nvp == null || nvp.size() < 1) + return false; + if (!path.startsWith(nvp.getString("path") + "/") && !(path + "/").startsWith(nvp.getString("path") + "/")) + return false; + if (u == null || (!su.equals(u) && !UserMgr.getUserMgr(CaimitoConfig.shaftapp).isAdminOrOwnerOf(CaimitoConfig.shaftapp,u,su))) + l.value = (res.getBoolean(3)); + else + l.value = CaimitoConfig.getConfig().getBoolean("resource.dir.listing"); + return true; + } + } + + finally{ + if (spq != null)spq.close(); + } + return false; + } + + + + protected static NameValuePairs getUserPrivFromDB(String u)throws Exception + { + try{ + + SPQueryAndUpdate spq = new SPQueryAndUpdate(getConnection()); + try{ + String sql = "SELECT * from " + CaimitoConfig.shaftapp + "_pathprivileges where resourceuser = ? AND shaftowner = ?"; + + // username = UserMgr. (CaimitoConfig.shaftapp).getOwner(CaimitoConfig.shaftapp,username); + // if (username == null) + // break; + boolean isadmin = false; + if (RealmMgr.getRealmMgr(CaimitoConfig.shaftapp).isAdmin(CaimitoConfig.shaftapp,u)){ +sql = "SELECT * from " + CaimitoConfig.shaftapp + "_pathprivileges where resourceuser = ?"; + + isadmin = true; + } + + spq.setTemplate(sql); + spq.addVariable(u); + if (!isadmin) + spq.addVariable(UserMgr.getUserMgr(CaimitoConfig.shaftapp).getOwner(CaimitoConfig.shaftapp,u)); + + return spq.getHash(); + } + + finally{ + if (spq != null)spq.close(); + } + }catch (Exception e){ + //(u + " getUserPrivFromDB " + e.toString() + ":" ); + e.printStackTrace(); + + } + return null; + } + + protected static NameValuePairs getUserPriv(String u)throws Exception + { + try{ + + + + NameValuePairs nvp = getUserPrivFromDB(u); + if (nvp == null || nvp.size() < 1) + return nvp; + String path2 = null; + String username = u; + while (true){ + username = UserMgr.getUserMgr(CaimitoConfig.shaftapp).getOwner(CaimitoConfig.shaftapp,username); + if (username == null) + break; + if (RealmMgr.getRealmMgr(CaimitoConfig.shaftapp).isAdmin(CaimitoConfig.shaftapp,username)) + break; + if (path2 == null)path2 = ""; + path2 = getUserPrivFromDB(username).getString("path") + "/" + path2; + } + if (path2 != null){ + path2 = path2 + "/" + nvp.getString("path"); + //("ZEPATH@ A " + path2); + + path2 = CaimitoUtil.normalize(path2); + //("ZEPATH@ " + path2); + + nvp.put("path",path2); + + + } + return nvp; + + + + }catch (Exception e){ + //(u + " getUserPriv.error " + e.toString() + ":" ); + e.printStackTrace(); + + } + return null; + } + + + public static ResourceObj lookup(String path, HttpServletRequest request, + HttpServletResponse response,int action) + throws CaimitoException { + String u = null; + //ResourceObj ro = null; + + if (path.equals("/") || path.equals("")) + { + if (CaimitoConfig.protectedRoot) + { + + u = login(request,response); + if (u == null)return null; + } + } + + if (u == null) + { + u = (String)request.getAttribute(CaimitoConfig.caimitouserreqobj); + if (u == null) + u = login(request); + } +try{ + //(action + ":" + path + " THE USER IS " + u); + if (RealmMgr.getRealmMgr(CaimitoConfig.shaftapp).isAdmin(CaimitoConfig.shaftapp,u)) + return lookup(path,u); + + + if (action == READ){ + + CaimitoBooleanHolder l = new CaimitoBooleanHolder(); + if (isPublicPath(path,l,u)){ + + ResourceObj ro = lookup(path,u); + if (ro != null) + ro.listing = l.value; + return ro; + } + } + if (u == null){ + + u = login(request,response); + if (u == null)return null; + } + + + + NameValuePairs nvp = getUserPriv(u); + //(u + " PRIVILEGE GO " + nvp); + if (nvp == null || nvp.size() < 1) + { + response.sendError(HttpServletResponse.SC_FORBIDDEN); + return null; + } + + + if (action == WRITE && (nvp.getInt("privilege") != WRITE ||(path.startsWith("/" + CaimitoConfig.shaftapp + "/") || path.equals("/favicon.ico")))) + { + //(u + " PRIVILEGE GO 2 " + nvp); + + response.sendError(HttpServletResponse.SC_FORBIDDEN); + return null; + } + if (!path.startsWith("/" + nvp.getString("path") + "/") && !(path + "/").startsWith("/" + nvp.getString("path") + "/")) + { + //(path + " PRIVILEGE GO 3 " + nvp); + + response.sendError(HttpServletResponse.SC_FORBIDDEN); + return null; + }else lookup("/" + nvp.getString("path") + "/",u) .mkdir(); + return lookup(path,u); + + }catch (Exception e){ + + e.printStackTrace(); + return null; + } + /*//(u + " WOWWW SD 1 " + CaimitoConfig.resource + ":" + path); + if (CaimitoConfig.resource.equals("file")){ + ro = new FileResourceObj(); + } + //(u + " WOWWW SD 2 " + ro); + + if (ro != null){ + ro.user = u; + ro.path = path; + } + return ro;*/ +// return null; + } + + + public static ResourceObj lookup(String path,String u) + throws CaimitoException { + ResourceObj ro = null; + //if (u == null) + // Thread.dumpStack(); + //(u + " WOWWW SD 1 " + CaimitoConfig.resource + ":" + path); + if (path.startsWith("/" + CaimitoConfig.shaftapp + "/") || path.equals("/favicon.ico")) + { + if (!path.startsWith("/" + CaimitoConfig.shaftapp + "/public/")) + path = "/" + CaimitoConfig.shaftapp + "/public/" + path.substring(CaimitoConfig.shaftapp.length() + 1,path.length()); + ro = new ShaftResourceObj(); + + } + else if (CaimitoConfig.resource.equals("file")){ + ro = new FileResourceObj(); + } + else if (CaimitoConfig.resource.equals("openstack")){ + //(u + " WOWWW SD 2 " + CaimitoConfig.resource + ":" + path); + + ro = new OpenStackResourceObj(); + } + //(u + " WOWWW SD 2 " + ro); + + if (ro != null){ + ro.user = u; + ro.path = path; + ro.listing = CaimitoConfig.getConfig().getBoolean("resource.dir.listing"); + } + return ro; + } + + + public static String login( HttpServletRequest request ) + throws CaimitoException { + return login(request,null); + } + + + + + protected static String getDigest(String username, String realmName)throws CaimitoException { + +try{ + + return UserMgr.getUserMgr(CaimitoConfig.shaftapp).getMD5Digest(CaimitoConfig.shaftapp,username); + /*String digestValue = username + ":" + realmName + ":" + + UserMgr. (CaimitoConfig.shaftapp).getPasswd(CaimitoConfig.shaftapp,username); + + byte[] valueBytes = null; + valueBytes = digestValue.getBytes(Charset.defaultCharset()); + + byte[] digest = null; + synchronized(md5Helper) { + digest = md5Helper.digest(valueBytes); + } + + return md5Encode(digest);*/ +}catch (Exception e){ + e.printStackTrace(); + CaimitoException.throwException(e); +} +return null; + } + + + + protected static String authenticate(NameValuePairs nvp) throws CaimitoException{ + // username="caimitoadmin", realm="Caimito", nonce="", uri="/", response="2fb52dbbcb7b25fd33840eac3027e9c5" + +String username = (String)nvp.get("username"); + String clientDigest = (String)nvp.get("response"); + String nonce = (String)nvp.get("nonce"); + String nc = (String)nvp.get("nc"); +String cnonce = (String)nvp.get("cnonce"); +String qop = (String)nvp.get("qop"); +String realm = (String)nvp.get("realm"); + String a2 = nvp.get("method") + ":" + nvp.get("uri"); + + byte[] buffer; + synchronized (md5Helper) { + buffer = md5Helper.digest(a2.getBytes(Charset.defaultCharset())); + } + String md5a2 = md5Encode(buffer); + + + String md5a1 = getDigest(username, realm); + if (md5a1 == null) + return null; + String serverDigestValue; + if (qop == null) { + serverDigestValue = md5a1 + ":" + nonce + ":" + md5a2; + } else { + serverDigestValue = md5a1 + ":" + nonce + ":" + nc + ":" + + cnonce + ":" + qop + ":" + md5a2; + } + + byte[] valueBytes = null; + // try { + valueBytes = serverDigestValue.getBytes(Charset.defaultCharset()); + // } catch (UnsupportedEncodingException uee) { + // log.error("Illegal digestEncoding: " + getDigestEncoding(), uee); + // throw new IllegalArgumentException(uee.getMessage()); + //} + + String serverDigest = null; + // Bugzilla 32137 + synchronized(md5Helper) { + serverDigest = md5Encode(md5Helper.digest(valueBytes)); + } + + /*if (log.isDebugEnabled()) { + log.debug("Digest : " + clientDigest + " Username:" + username + + " ClientSigest:" + clientDigest + " nonce:" + nonce + + " nc:" + nc + " cnonce:" + cnonce + " qop:" + qop + + " realm:" + realm + "md5a2:" + md5a2 + + " Server digest:" + serverDigest); + }*/ + + if (serverDigest.equals(clientDigest)) { + return (username); + } + + return null; + } + + + + public static String login( HttpServletRequest request, + HttpServletResponse response + ) + throws CaimitoException { + String ua = request.getHeader("user-agent"); + //if (ua.equals("Microsoft Data Access Internet Publishing Provider DAV") || ua.indexOf("davfs2") > -1 || CaimitoConfig.getConfig().getString(ua + ".auth").equals("basic")) + // return basicLogin(request,response); + //("USER AGAENT " + ua); + if (CaimitoConfig.getConfig().getString(ua + ".auth").equals("digest")) + return digestLogin(request,response); + return basicLogin(request,response); + } + + + public static String digestLogin( HttpServletRequest request, + HttpServletResponse response + ) + throws CaimitoException { + NameValuePairs nvp = new NameValuePairs(); + String hr = request.getHeader("Authorization"); + if (hr != null) + { + if (hr.startsWith("Digest ")) + { +try{ + //hr = SharedMethods.replaceSubstring(hr,"Digest ",""); + hr = hr.trim(); + hr = hr.substring(7,hr.length()); + // username="caimitoadmin", realm="Caimito", nonce="", uri="/", response="2fb52dbbcb7b25fd33840eac3027e9c5" + NameValuePairs nvp1 = NameValuePairs.toNameValuePair(hr,"=",","); + Enumeration nvp1e = nvp1.keys(); + String k = null; + String v = null; + while(nvp1e.hasMoreElements()) + { + k = (String)nvp1e.nextElement(); + v = nvp1.getString(k); + nvp.put(k.trim(),StringUtil.getTrimmedValue(v.trim())); + } + nvp.put("method",request.getMethod()); + //(nvp + " DIGEST 1 " + hr); + //byte[] b = Base64Decoder.fromBase64(hr.getBytes()); + //String auth = new String(b); + //String name = auth.substring(0,auth.indexOf(":")); + //String pass = auth.substring(auth.indexOf(":") + 1,auth.length()); + + + String name = authenticate(nvp); + //if (UserMgr. (CaimitoConfig.shaftapp).login(CaimitoConfig.shaftapp,name,pass) != null) + if (name != null) + { + //request.setPrincipal(RealmEngine.get().getPrincipal(name)); + //request.setAuthType("BASIC"); + // request.getSession() + request.setAttribute(CaimitoConfig.caimitouserreqobj,name); + return name; + } + }catch (Exception e){ + e.printStackTrace(); + //return null; + } + } + } + if (response != null) + sendError(request,response,nvp.getString("nonce").trim()); + return null; + + } + + + + protected static boolean isNonceStale(String nonce){ + + + int i = nonce.indexOf(":"); + if (i < 0 || (i + 1) == nonce.length()) { + return true; + } + long nonceTime; + try { + nonceTime = Long.parseLong(nonce.substring(0, i)); + } catch (NumberFormatException nfe) { + return true; + } + //String md5clientIpTimeKey = nonce.substring(i + 1); + long currentTime = System.currentTimeMillis(); + //(currentTime + ":" + nonceTime + ":" + CaimitoConfig.nonceValidity + ":IS NONE STALE ##########################"); + if ((currentTime - nonceTime) > CaimitoConfig.nonceValidity) { + return true; + } + else return false; +// return true; + + } + + + public static void sendError( HttpServletRequest request,HttpServletResponse response,String nonce1) + { + try + { + String nonce = generateNonce(request); + boolean isn = isNonceStale(nonce1); + //(nonce1 + " IS NOT STALE " + isn); + setAuthenticateHeader(request, response, nonce, + isn); + response.sendError(HttpServletResponse.SC_UNAUTHORIZED); + } + catch (Exception e) + { + e.printStackTrace(); + + } + } + + + protected static String generateNonce(HttpServletRequest request) { + + long currentTime = System.currentTimeMillis(); + + + String ipTimeKey = + request.getRemoteAddr() + ":" + currentTime + ":" + randomGenerate(); + + byte[] buffer; + synchronized (md5Helper) { + buffer = md5Helper.digest( + ipTimeKey.getBytes(Charset.defaultCharset())); + } + + return currentTime + ":" + md5Encode(buffer); + } + + private static final char[] hexadecimal = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f'}; + + + // --------------------------------------------------------- Public Methods + + + /** + * Encodes the 128 bit (16 bytes) MD5 into a 32 character String. + * + * @param binaryData Array containing the digest + * @return Encoded MD5, or null if encoding failed + */ + protected static String md5Encode( byte[] binaryData ) { + + if (binaryData.length != 16) + return null; + + char[] buffer = new char[32]; + + for (int i=0; i<16; i++) { + int low = binaryData[i] & 0x0f; + int high = (binaryData[i] & 0xf0) >> 4; + buffer[i*2] = hexadecimal[high]; + buffer[i*2 + 1] = hexadecimal[low]; + } + + return new String(buffer); + + } + + + + protected static String randomGenerate(){ + + String tid = AlphaNumeric.generateRandomAlphNumeric(CaimitoConfig.digestLength); +String dig = CaimitoConfig.defaultDigest; +if (dig != null) +tid = Crypto.digest(tid,dig); + return tid; + } + + protected static final String AUTH_HEADER_NAME = "WWW-Authenticate"; + protected static final String QOP = "auth"; + + protected static void setAuthenticateHeader(HttpServletRequest request, + HttpServletResponse response, + String nonce, + boolean isNonceStale) { + + // Get the realm name + String realmName = CaimitoConfig.SecurityRealmName; + + String authenticateHeader; + if (isNonceStale) { + authenticateHeader = "Digest realm=\"" + realmName + "\", " + + "qop=\"" + QOP + "\", nonce=\"" + nonce + "\", " + "opaque=\"" + + randomGenerate() + "\", stale=true"; + } else { + authenticateHeader = "Digest realm=\"" + realmName + "\", " + + "qop=\"" + QOP + "\", nonce=\"" + nonce + "\", " + "opaque=\"" + + randomGenerate() + "\""; + } + + +//("authenticateHeader 1 " + authenticateHeader); + response.setHeader(AUTH_HEADER_NAME, authenticateHeader); + + } + + + + public static String basicLogin( HttpServletRequest request, + HttpServletResponse response + ) + throws CaimitoException { + + String hr = request.getHeader("Authorization"); + if (hr != null) + { + if (hr.startsWith("Basic ")) + { + + //hr = SharedMethods.replaceSubstring(hr,"Digest ",""); + hr = hr.trim(); + hr = hr.substring(6,hr.length()); + // username="caimitoadmin", realm="Caimito", nonce="", uri="/", response="2fb52dbbcb7b25fd33840eac3027e9c5" + NameValuePairs nvp = NameValuePairs.toNameValuePair(hr,"=",","); + //(nvp + " BASIC 1 " + hr); + byte[] b = Base64Decoder.fromBase64(hr.getBytes()); + String auth = new String(b); + String name = auth.substring(0,auth.indexOf(":")); + String pass = auth.substring(auth.indexOf(":") + 1,auth.length()); + try{ + + if (UserMgr.getUserMgr(CaimitoConfig.shaftapp).login(CaimitoConfig.shaftapp,name,pass,false) != null) + { + //request.setPrincipal(RealmEngine.get().getPrincipal(name)); + //request.setAuthType("BASIC"); + // request.getSession() + request.setAttribute(CaimitoConfig.caimitouserreqobj,name); + return name; + } + }catch (Exception e){ + e.printStackTrace(); + //return null; + } + } + } + if (response != null) + sendBasicError(request,response); + return null; + + } + + public static void sendBasicError( HttpServletRequest request,HttpServletResponse response) + { + try + { + /* + if (DeploymentDescriptor.isSecureLoginRequired() && !request.getScheme().equalsIgnoreCase("https")) + { + String fau = request.getTrimmedRequestURI(); + if (request.getQueryString() != null) + fau = fau + "?" + request.getQueryString(); + if (!fau.startsWith("/")) + fau = "/" + fau; + response.sendRedirect("https://" + request.getServerName() + fau); + return; + }*/ + response.setHeader("Content-Type","text/html"); + String rn = CaimitoConfig.SecurityRealmName; + response.setHeader("WWW-Authenticate","Basic realm=\"" + rn + "\""); + response.sendError(401); + } + catch (Exception e) + { + e.printStackTrace(); + + } + } +} + +class CaimitoBooleanHolder{ + public boolean value = false; +} diff --git a/source/ngasi/caimito/resource/ShaftAppMgr.java b/source/ngasi/caimito/resource/ShaftAppMgr.java old mode 100644 new mode 100755 index 4fdb118..8e196ab --- a/source/ngasi/caimito/resource/ShaftAppMgr.java +++ b/source/ngasi/caimito/resource/ShaftAppMgr.java @@ -1,53 +1,53 @@ -/* - Copyright (c) 2011-2012, the Caimito project (http://caimito.ngasi.com/). All rights reserved. -Apache Software License 2.0 -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WebAppShowCase -OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - - - - -package ngasi.caimito.resource; -import java.nio.charset.Charset; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import ngasi.caimito.*; -import org.shaft.server.auth.*; -import tools.util.*; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Enumeration; -import java.io.UnsupportedEncodingException; -import org.shaft.server.utils.*; -import tools.util.*; -import java.sql.Connection; -import java.sql.ResultSet; - - -public class ShaftAppMgr - { +/* + Copyright (c) 2011-2012, the Caimito project (http://caimito.ngasi.com/). All rights reserved. +Apache Software License 2.0 +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WebAppShowCase +OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + + + + +package ngasi.caimito.resource; +import java.nio.charset.Charset; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import ngasi.caimito.*; +import org.shaft.server.auth.*; +import tools.util.*; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Enumeration; +import java.io.UnsupportedEncodingException; +import org.shaft.server.utils.*; +import tools.util.*; +import java.sql.Connection; +import java.sql.ResultSet; + + +public class ShaftAppMgr + { } \ No newline at end of file diff --git a/source/ngasi/caimito/resource/ShaftResourceObj.java b/source/ngasi/caimito/resource/ShaftResourceObj.java old mode 100644 new mode 100755 index 61905d4..03955bf --- a/source/ngasi/caimito/resource/ShaftResourceObj.java +++ b/source/ngasi/caimito/resource/ShaftResourceObj.java @@ -1,58 +1,58 @@ -/* - Copyright (c) 2011-2012, the Caimito project (http://caimito.ngasi.com/). All rights reserved. -Apache Software License 2.0 -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WebAppShowCase -OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - - - - -package ngasi.caimito.resource; -import java.nio.charset.Charset; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import ngasi.caimito.*; -import org.shaft.server.auth.*; -import tools.util.*; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Enumeration; -import java.io.UnsupportedEncodingException; -import org.shaft.server.utils.*; -import tools.util.*; -import java.sql.Connection; -import java.sql.ResultSet; - - -public class ShaftResourceObj extends FileResourceObj - { - - - protected String getHome(){ - return CaimitoConfig.caimitoroot; - } +/* + Copyright (c) 2011-2012, the Caimito project (http://caimito.ngasi.com/). All rights reserved. +Apache Software License 2.0 +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WebAppShowCase +OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + + + + +package ngasi.caimito.resource; +import java.nio.charset.Charset; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import ngasi.caimito.*; +import org.shaft.server.auth.*; +import tools.util.*; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Enumeration; +import java.io.UnsupportedEncodingException; +import org.shaft.server.utils.*; +import tools.util.*; +import java.sql.Connection; +import java.sql.ResultSet; + + +public class ShaftResourceObj extends FileResourceObj + { + + + protected String getHome(){ + return CaimitoConfig.caimitoroot; + } } \ No newline at end of file diff --git a/webapps/RELEASE-NOTES.txt b/webapps/RELEASE-NOTES.txt old mode 100644 new mode 100755 index f6f9391..a811a2b --- a/webapps/RELEASE-NOTES.txt +++ b/webapps/RELEASE-NOTES.txt @@ -1,228 +1,228 @@ -================================================================================ - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -================================================================================ - -$Id: RELEASE-NOTES 1189163 2011-10-26 12:19:26Z kkolinko $ - - - Apache Tomcat Version 7.0.27 - Release Notes - - -========= -CONTENTS: -========= - -* Dependency Changes -* API Stability -* JNI Based Applications -* Bundled APIs -* Web application reloading and static fields in shared libraries -* Tomcat on Linux -* Enabling SSI and CGI Support -* Security manager URLs -* Symlinking static resources -* Viewing the Tomcat Change Log -* Cryptographic software notice -* When all else fails - - -=================== -Dependency Changes: -=================== -Tomcat 7.0 is designed to run on Java SE 6 and later. - -In addition, Tomcat 7.0 uses the Eclipse JDT Java compiler for -compiling JSP pages. This means you no longer need to have the complete -Java Development Kit (JDK) to run Tomcat, but a Java Runtime Environment -(JRE) is sufficient. The Eclipse JDT Java compiler is bundled with the -binary Tomcat distributions. Tomcat can also be configured to use the -compiler from the JDK to compile JSPs, or any other Java compiler supported -by Apache Ant. - - -============== -API Stability: -============== -The public interfaces for the following classes are fixed and will not be -changed at all during the remaining lifetime of the 7.x series: -- javax/**/* - -The public interfaces for the following classes may be added to in order to -resolve bugs and/or add new features. No existing interface will be removed or -changed although it may be deprecated. -- org/apache/catalina/* -- org/apache/catalina/comet/* - -Note: As Tomcat 7 matures, the above list will be added to. The list is not - considered complete at this time. - -The remaining classes are considered part of the Tomcat internals and may change -without notice between point releases. - - -======================= -JNI Based Applications: -======================= -Applications that require native libraries must ensure that the libraries have -been loaded prior to use. Typically, this is done with a call like: - - static { - System.loadLibrary("path-to-library-file"); - } - -in some class. However, the application must also ensure that the library is -not loaded more than once. If the above code were placed in a class inside -the web application (i.e. under /WEB-INF/classes or /WEB-INF/lib), and the -application were reloaded, the loadLibrary() call would be attempted a second -time. - -To avoid this problem, place classes that load native libraries outside of the -web application, and ensure that the loadLibrary() call is executed only once -during the lifetime of a particular JVM. - - -============= -Bundled APIs: -============= -A standard installation of Tomcat 7.0 makes all of the following APIs available -for use by web applications (by placing them in "lib"): -* annotations-api.jar (Annotations package) -* catalina.jar (Tomcat Catalina implementation) -* catalina-ant.jar (Tomcat Catalina Ant tasks) -* catalina-ha.jar (High availability package) -* catalina-tribes.jar (Group communication) -* ecj-3.7.2.jar (Eclipse JDT Java compiler) -* el-api.jar (EL 2.2 API) -* jasper.jar (Jasper 2 Compiler and Runtime) -* jasper-el.jar (Jasper 2 EL implementation) -* jsp-api.jar (JSP 2.2 API) -* servlet-api.jar (Servlet 3.0 API) -* tomcat-api.jar (Interfaces shared by Catalina and Jasper) -* tomcat-coyote.jar (Tomcat connectors and utility classes) -* tomcat-dbcp.jar (package renamed database connection pool based on Commons DBCP) - -You can make additional APIs available to all of your web applications by -putting unpacked classes into a "classes" directory (not created by default), -or by placing them in JAR files in the "lib" directory. - -To override the XML parser implementation or interfaces, use the endorsed -mechanism of the JVM. The default configuration defines JARs located in -"endorsed" as endorsed. - - -================================================================ -Web application reloading and static fields in shared libraries: -================================================================ -Some shared libraries (many are part of the JDK) keep references to objects -instantiated by the web application. To avoid class loading related problems -(ClassCastExceptions, messages indicating that the classloader -is stopped, etc.), the shared libraries state should be reinitialized. - -Something which might help is to avoid putting classes which would be -referenced by a shared static field in the web application classloader, -and putting them in the shared classloader instead (JARs should be put in the -"lib" folder, and classes should be put in the "classes" folder). - - -================ -Tomcat on Linux: -================ -GLIBC 2.2 / Linux 2.4 users should define an environment variable: -export LD_ASSUME_KERNEL=2.2.5 - -Redhat Linux 9.0 users should use the following setting to avoid -stability problems: -export LD_ASSUME_KERNEL=2.4.1 - -There are some Linux bugs reported against the NIO sendfile behavior, make sure you -have a JDK that is up to date, or disable sendfile behavior in the Connector.
-6427312: (fc) FileChannel.transferTo() throws IOException "system call interrupted"
-5103988: (fc) FileChannel.transferTo should return -1 for EAGAIN instead throws IOException
-6253145: (fc) FileChannel.transferTo on Linux fails when going beyond 2GB boundary
-6470086: (fc) FileChannel.transferTo(2147483647, 1, channel) cause "Value too large" exception
- - -============================= -Enabling SSI and CGI Support: -============================= -Because of the security risks associated with CGI and SSI available -to web applications, these features are disabled by default. - -To enable and configure CGI support, please see the cgi-howto.html page. - -To enable and configue SSI support, please see the ssi-howto.html page. - - -====================== -Security manager URLs: -====================== -In order to grant security permissions to JARs located inside the -web application repository, use URLs of of the following format -in your policy file: - -file:${catalina.base}/webapps/examples/WEB-INF/lib/driver.jar - - -============================ -Symlinking static resources: -============================ -By default, Unix symlinks will not work when used in a web application to link -resources located outside the web application root directory. - -This behavior is optional, and the "allowLinking" flag may be used to disable -the check. - - -============================== -Viewing the Tomcat Change Log: -============================== -See changelog.html in this directory. - - -============================= -Cryptographic software notice -============================= -This distribution includes cryptographic software. The country in -which you currently reside may have restrictions on the import, -possession, use, and/or re-export to another country, of -encryption software. BEFORE using any encryption software, please -check your country's laws, regulations and policies concerning the -import, possession, or use, and re-export of encryption software, to -see if this is permitted. See for more -information. - -The U.S. Government Department of Commerce, Bureau of Industry and -Security (BIS), has classified this software as Export Commodity -Control Number (ECCN) 5D002.C.1, which includes information security -software using or performing cryptographic functions with asymmetric -algorithms. The form and manner of this Apache Software Foundation -distribution makes it eligible for export under the License Exception -ENC Technology Software Unrestricted (TSU) exception (see the BIS -Export Administration Regulations, Section 740.13) for both object -code and source code. - -The following provides more details on the included cryptographic -software: - - Tomcat includes code designed to work with JSSE - - Tomcat includes code designed to work with OpenSSL - - -==================== -When all else fails: -==================== -See the FAQ -http://tomcat.apache.org/faq/ +================================================================================ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +================================================================================ + +$Id: RELEASE-NOTES 1189163 2011-10-26 12:19:26Z kkolinko $ + + + Apache Tomcat Version 7.0.27 + Release Notes + + +========= +CONTENTS: +========= + +* Dependency Changes +* API Stability +* JNI Based Applications +* Bundled APIs +* Web application reloading and static fields in shared libraries +* Tomcat on Linux +* Enabling SSI and CGI Support +* Security manager URLs +* Symlinking static resources +* Viewing the Tomcat Change Log +* Cryptographic software notice +* When all else fails + + +=================== +Dependency Changes: +=================== +Tomcat 7.0 is designed to run on Java SE 6 and later. + +In addition, Tomcat 7.0 uses the Eclipse JDT Java compiler for +compiling JSP pages. This means you no longer need to have the complete +Java Development Kit (JDK) to run Tomcat, but a Java Runtime Environment +(JRE) is sufficient. The Eclipse JDT Java compiler is bundled with the +binary Tomcat distributions. Tomcat can also be configured to use the +compiler from the JDK to compile JSPs, or any other Java compiler supported +by Apache Ant. + + +============== +API Stability: +============== +The public interfaces for the following classes are fixed and will not be +changed at all during the remaining lifetime of the 7.x series: +- javax/**/* + +The public interfaces for the following classes may be added to in order to +resolve bugs and/or add new features. No existing interface will be removed or +changed although it may be deprecated. +- org/apache/catalina/* +- org/apache/catalina/comet/* + +Note: As Tomcat 7 matures, the above list will be added to. The list is not + considered complete at this time. + +The remaining classes are considered part of the Tomcat internals and may change +without notice between point releases. + + +======================= +JNI Based Applications: +======================= +Applications that require native libraries must ensure that the libraries have +been loaded prior to use. Typically, this is done with a call like: + + static { + System.loadLibrary("path-to-library-file"); + } + +in some class. However, the application must also ensure that the library is +not loaded more than once. If the above code were placed in a class inside +the web application (i.e. under /WEB-INF/classes or /WEB-INF/lib), and the +application were reloaded, the loadLibrary() call would be attempted a second +time. + +To avoid this problem, place classes that load native libraries outside of the +web application, and ensure that the loadLibrary() call is executed only once +during the lifetime of a particular JVM. + + +============= +Bundled APIs: +============= +A standard installation of Tomcat 7.0 makes all of the following APIs available +for use by web applications (by placing them in "lib"): +* annotations-api.jar (Annotations package) +* catalina.jar (Tomcat Catalina implementation) +* catalina-ant.jar (Tomcat Catalina Ant tasks) +* catalina-ha.jar (High availability package) +* catalina-tribes.jar (Group communication) +* ecj-3.7.2.jar (Eclipse JDT Java compiler) +* el-api.jar (EL 2.2 API) +* jasper.jar (Jasper 2 Compiler and Runtime) +* jasper-el.jar (Jasper 2 EL implementation) +* jsp-api.jar (JSP 2.2 API) +* servlet-api.jar (Servlet 3.0 API) +* tomcat-api.jar (Interfaces shared by Catalina and Jasper) +* tomcat-coyote.jar (Tomcat connectors and utility classes) +* tomcat-dbcp.jar (package renamed database connection pool based on Commons DBCP) + +You can make additional APIs available to all of your web applications by +putting unpacked classes into a "classes" directory (not created by default), +or by placing them in JAR files in the "lib" directory. + +To override the XML parser implementation or interfaces, use the endorsed +mechanism of the JVM. The default configuration defines JARs located in +"endorsed" as endorsed. + + +================================================================ +Web application reloading and static fields in shared libraries: +================================================================ +Some shared libraries (many are part of the JDK) keep references to objects +instantiated by the web application. To avoid class loading related problems +(ClassCastExceptions, messages indicating that the classloader +is stopped, etc.), the shared libraries state should be reinitialized. + +Something which might help is to avoid putting classes which would be +referenced by a shared static field in the web application classloader, +and putting them in the shared classloader instead (JARs should be put in the +"lib" folder, and classes should be put in the "classes" folder). + + +================ +Tomcat on Linux: +================ +GLIBC 2.2 / Linux 2.4 users should define an environment variable: +export LD_ASSUME_KERNEL=2.2.5 + +Redhat Linux 9.0 users should use the following setting to avoid +stability problems: +export LD_ASSUME_KERNEL=2.4.1 + +There are some Linux bugs reported against the NIO sendfile behavior, make sure you +have a JDK that is up to date, or disable sendfile behavior in the Connector.
+6427312: (fc) FileChannel.transferTo() throws IOException "system call interrupted"
+5103988: (fc) FileChannel.transferTo should return -1 for EAGAIN instead throws IOException
+6253145: (fc) FileChannel.transferTo on Linux fails when going beyond 2GB boundary
+6470086: (fc) FileChannel.transferTo(2147483647, 1, channel) cause "Value too large" exception
+ + +============================= +Enabling SSI and CGI Support: +============================= +Because of the security risks associated with CGI and SSI available +to web applications, these features are disabled by default. + +To enable and configure CGI support, please see the cgi-howto.html page. + +To enable and configue SSI support, please see the ssi-howto.html page. + + +====================== +Security manager URLs: +====================== +In order to grant security permissions to JARs located inside the +web application repository, use URLs of of the following format +in your policy file: + +file:${catalina.base}/webapps/examples/WEB-INF/lib/driver.jar + + +============================ +Symlinking static resources: +============================ +By default, Unix symlinks will not work when used in a web application to link +resources located outside the web application root directory. + +This behavior is optional, and the "allowLinking" flag may be used to disable +the check. + + +============================== +Viewing the Tomcat Change Log: +============================== +See changelog.html in this directory. + + +============================= +Cryptographic software notice +============================= +This distribution includes cryptographic software. The country in +which you currently reside may have restrictions on the import, +possession, use, and/or re-export to another country, of +encryption software. BEFORE using any encryption software, please +check your country's laws, regulations and policies concerning the +import, possession, or use, and re-export of encryption software, to +see if this is permitted. See for more +information. + +The U.S. Government Department of Commerce, Bureau of Industry and +Security (BIS), has classified this software as Export Commodity +Control Number (ECCN) 5D002.C.1, which includes information security +software using or performing cryptographic functions with asymmetric +algorithms. The form and manner of this Apache Software Foundation +distribution makes it eligible for export under the License Exception +ENC Technology Software Unrestricted (TSU) exception (see the BIS +Export Administration Regulations, Section 740.13) for both object +code and source code. + +The following provides more details on the included cryptographic +software: + - Tomcat includes code designed to work with JSSE + - Tomcat includes code designed to work with OpenSSL + + +==================== +When all else fails: +==================== +See the FAQ +http://tomcat.apache.org/faq/ diff --git a/webapps/WEB-INF/caimito/config.properties.sample b/webapps/WEB-INF/caimito/config.properties.sample old mode 100644 new mode 100755 index 49e6dfa..b873074 --- a/webapps/WEB-INF/caimito/config.properties.sample +++ b/webapps/WEB-INF/caimito/config.properties.sample @@ -1,37 +1,40 @@ -#file,openstack +#file,openstack + +resource=file +#A Container or Bucket +cloud.store=store1 +cloud.username=SLOS11111-1:SL11111 +cloud.api.key_password=fffffffffffffffffffffffffffffffffff + +cloud.url=https://dal05.objectstorage.softlayer.net/auth/v1.0/ +#cloud.url=https://dal05.objectstorage.service.networklayer.com/auth/v1.0 -resource=file -#A Container or Bucket -cloud.store=store1 -cloud.username=SLOS11111-1:SL11111 -cloud.api.key_password=fffffffffffffffffffffffffffffffffff +#public,internal +cloud.endpoint.access=public -cloud.url=https://dal05.objectstorage.softlayer.net/auth/v1.0/ -#cloud.url=https://dal05.objectstorage.service.networklayer.com/auth/v1.0 - -#minutes -cloud.max_auth_interval=20 -#Tue, 24 Apr 2012 00:05:15 GMT -cloud.obj.details.dateformat=EEE, dd MMM yyyy HH:mm:ss z -#2012-04-24T00:05:15.474470 -#%Y-%m-%dT%H:%M:%S.000Z -cloud.date.remove.end=true -cloud.dateformat=yyyy-MM-dd'T'HH:mm:ss -#%Y-%m-%dT%H:%M:%S.000Z -#yyyy-MM-dd'T'HH:mm:ss.'Z' -maxspace.units=GB -file.resource.dir=/usr/caimito/drive -SecurityRealmName=Caimito -shaft.app=ca -resource.dir.listing=true -Microsoft-WebDAV-MiniRedir/6.1.7601.auth=digest -protectedRoot=true -cacheable=true -cachedir=/usr/caimito/cache -serverinfo=Caimito -CAIMITO_CSS=H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#FF8FC2;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#FF8FC2;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#FF8FC2;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#FF8FC2;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #FF8FC2;} -directory.title=Directory -directory.parent=Parent -directory.filename=Name -directory.size=Size -directory.lastModified=Date \ No newline at end of file +#minutes +cloud.max_auth_interval=20 +#Tue, 24 Apr 2012 00:05:15 GMT +cloud.obj.details.dateformat=EEE, dd MMM yyyy HH:mm:ss z +#2012-04-24T00:05:15.474470 +#%Y-%m-%dT%H:%M:%S.000Z +cloud.date.remove.end=true +cloud.dateformat=yyyy-MM-dd'T'HH:mm:ss +#%Y-%m-%dT%H:%M:%S.000Z +#yyyy-MM-dd'T'HH:mm:ss.'Z' +maxspace.units=GB +file.resource.dir=/usr/caimito/drive +SecurityRealmName=Caimito +shaft.app=ca +resource.dir.listing=true +Microsoft-WebDAV-MiniRedir/6.1.7601.auth=digest +protectedRoot=true +cacheable=true +cachedir=/usr/caimito/cache +serverinfo=Caimito +CAIMITO_CSS=H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#FF8FC2;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#FF8FC2;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#FF8FC2;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#FF8FC2;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #FF8FC2;} +directory.title=Directory +directory.parent=Parent +directory.filename=Name +directory.size=Size +directory.lastModified=Date diff --git a/webapps/WEB-INF/classes/ngasi/caimito/CaimitoConfig.class b/webapps/WEB-INF/classes/ngasi/caimito/CaimitoConfig.class index dd0b489fc6c37502019779a86fdf4b962497101c..12d0a77d267a762f7d0b2d299d2120fa45ac969c 100644 GIT binary patch literal 2819 zcmaJ@X>$`t5PgeE0MMGnMBXfaXaN3m|5^#pO&5ObzRPl z1N7zHe99iMvQFCZPto@PeQA5xDrNm0PR1^BUo<%ptIzkGe5S>KO6%36ozM6qJlADl zMkO0hN1s)hrF2ed19K{lQqlH2`(bzJxPf}UD%g;7)A`W?FP8LOH(N}Ud?%aewsMkN z$=+i*UXgE|(`Tnj9y9H=t!z$~4Vc9dYuL96JZyS)(Jgr?@usZQh@Eyk19jT8hO%@= z`0`PkcNlh=aC>Xl?ymlxqwRft2Ez0g9XHRjTT@vl@A%sc)HE~>7znkyX}b;vmMct0 z?Q|9b2%Y^)T&onqFiqUb&3!vt#kE$U4iT{$6lOq))ub>J5fkfKn*AMZ&0XD{)#}N5 zTw#{1*UMz1LVXb6c7@rPW8zNcS1Gb=xLYAAyEhw{ma@dtqA*uH_cGgIC#$o)PhlP+ zVYC`pIJtyvB`2GG!2Mx#UPq$7Q$^p-DeQz)I%E5LJhxzb z!kM)VHxi`rMpp#8use+8^QnU+}XZbEKza0k@4&o3)l2mq{)NP(BAM?!kf|<5;v%~ ziFqcb%h7if-o<-_lWT3%Hrt}aOi5BgvB1QKLPwFbIO%6%p@~H%=1Zhc6+Xk~M2(Rq z^+-jRuVq-JZ6f#rUxo3dfw>bJPz6QdYavE`fs)9~t<*#Po+bKe@PGa_6tA8jKW6HU zyRCvIn2GO2+_lWd`H2x#aBLP=F5GYD3Ohtn&Ikia_*rUm(ZHf>J8B}fh;5`#OSlk+ z-=2!-1!RiL4X~0#tDykTrpi){Y1N4Y>yf&vN2;zKskwTjw(60x%Fz^2)pM$-9;uyr zq+aTg4XH=AqaN9edSol=k^RT9mXU7366Uj%v)^=9Kq^$mvUylh#>(jGGS93yW7}11AB?t*W5+lixPm>G(LaX4F&r+#V!V{> zws|ZQb;@|?5??nBIX*k}Mb;pMwM?mj-;G9!{yJ*LdMraTRw2%n1U(!0w-I;pC&V7y zj(*&MLCy~2E(~Ec@;V}T6)HvLLJ5ur{nMMSz@2zyt#$@SRImXL!{f#}6nS_WeA*$d zlmr)JIdPFN7p`L8;5bfP!6RdM^h3n;m7nBg>EvajPxDbRpRJmNU>whn<8<`ZF}y~| z#C%Je+r&IOhPR2gnD1*dCFTcu!xk|=(xxru$J)$@`NK)XzPMqe~@hrM{au?1c$=2%D zxC%(;3CIO}!#Lmae+EJ=e`BaEj4wh&jhe|V!lA7d4lNaIE~D{3GBgW5-|;~>E^=Q` z{GbwhtHrCs57kJUE0Gr8j98Py?7JomMRIZ(FdV;l2bkcQpqM|B%NL+Dc1`2> ziOUyxn_B)JSx|-W7TrgKd>*9t2tRH|$&_PQfpit3h3uvYi1;&ifbf_M6;SW;zq1yK A^#A|> literal 2676 zcma)8`EyfM6#iZtnwRjPG!)8CSZxC<o0K+7>E>(3U2aMOj{x*Y=epFTA|4x#7Ox zj-uju@cI zEg14+IEY6v5=0GbSw{Uh7DOF}bYw(kb>wt7qUM7*gyUlF>gWz)6$$}vJRQ457Ikcu z!xOSOsbi1GQ#wwIJfovWKv=6OF}2x2MD%H~B`UefWhj#q+s6|V)D z)$4Njh97T=5A!^Px2CWPz<2%+xjLugZISQD@~)2ebaaXOzK#!ce5m8RA0PSgv4&}R z*YT{BXQlfc$J3x4kw-*3eKnC>AW&wT?T3qZ;b@ zsj@-VN#{=FHO!BDj*}_Gik_W`^_W@7t!VX`wp-v=8xmHk=rYrO%gkiuT7zB~F^4=e zPiNh=3Qo~Y$!W?=jaX^h)eumsIhf&bkRLx`v4$as33s-4@99qV9_dUZG}LXibGFx} zp|-hYK!dN-Nz4)%-<)UAX*GOYZ9tEPNl58XFEBXOiOrX>ewDLuOgEkOuBks@Z$nahApogvdfmD z8k<`t1*^6wNVBAs&2LvARDGBw?H`1)zBQGpU=d6xJj>q+{iB?yu);te_L2>XA+{3} zLj#9#L@qut@F_mi(DZNqbQJAO+G1y?Vb7uQ7xKj~<%=c;4Sa>K4RoX3z;0Q-!6gG* zvCY69Y$G8QW1^&tfn9RnBTKI=-{Lz1akOigIgxY~egl`W*T8nM+#yB{W%5S(vhtSe z*%mo4T^ysf6ZNur^3RVe2ELbku8P|e*vYc*i@p@`gMl_YMjj@1(&2IO>OiN48T)p0 ztm*FQs&lH^vBk3dNh zTS>kGCCPgwNqx#XX!4r5_H!4b)F`J!Zb7?2r3Q(L5wHwN>PFcBPhx<(0QS+jMx3=3 zs8x4A-bT%Van#;|Zwyl|qV+cF4%~u2q>mxMbFQJ_ggUjVj=>nmv~f%i)sJCD2@Rr# zlsZ$?#xcw)VYaAEN}VI>TxBp%)cHzXAnHP;E)sR|7{b3|dPQa2C0C*Ej*Ma14d&a1 zOMKu%7+{HKdObj#eYIRwB&31NTGYXjU;=?(LqWI|paEdpJ|+-m;sB{3dCvD)(@8 z36ZNX6kd^Wtl{-_W>JTkm|cZ!5&X<;KTi+x{3ve@p^4SaXLgH`s>0GlzD~g6N6i2s z(I-Ko)A$Y?L-I2`*TdhZX zeM1O_I<{Ty_)?z!wFJVFLJ_flz5X9i4p8XVaPGc7KpY=D>=p`hR2D zmMjSBU6Poz8S5-FSrIFQwMY2m+{US5mF;-^Lp(-y!i>b_7}+CZ4!*?2`V+1~MqT`gdE;){JuNh1XCIk4lOG literal 555 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 X#V+)h;wP~J-vFGmTk#`=<>dY!d2?6t diff --git a/webapps/WEB-INF/classes/ngasi/caimito/CaimitoException.class b/webapps/WEB-INF/classes/ngasi/caimito/CaimitoException.class index c65f71c2d67bd7f8ab4ed7d47a740326186fe141..e3527ccd35a916f402a43cb688efe85931b312ea 100644 GIT binary patch literal 1241 zcmb7@Z%@-u6vm&k&2_6~47TC?haezZr&M{NMhI_E6O-wi5)xmQ*^H}OOWJ~b6+eb= z#AqV=)(>So_qHjunpYnC%PCeRVuOaDzSPVB`|!`~JWg?K^>x`{b|`9g2{!)c?23EdnXTL~ueo zYbo{2uB4rLX{V7B?HvaGduc*hZ)GyNxK5}=QkI?&^mHBSAXMdW)j$h%!g|(3@-7)} z=B0|`aH!)ZZfRH~G%gZK=?0dtOsGVDe2viTbSGhi89QM?b!O6b}j&@@#p zT?UaJ^TTQ?&leG)*pa2wZT~nJxX*) B*kAwv literal 943 zcma)4%TC)s6g?A%ICY)y3J@OU6`?pr#lQk8fhtvqN|k6giI7;DV1xW|3(*ZJ9@7uMXvCUuJagx$-! z*AhJN6(=u_!{8$7F&NRl%~0+q_MDQvb5-HiPk*|tB+HugkWrMSt}K5D2F;SOjcRZn z*1hjsMjhL6`56~Mlww7WYT^S7SwBzPI>)B1IpNv6pYb zu4%_$QZ-b!gaIrmd@c!}isQ?Kw@5v&_)^~@Uq-9>0PVoOMfwf{ah6R<5~U!YwfYd=GKQdw@0A-N~gPN|9WgalUUe%9!` zj$t}cb~7eC@*l!_g75|jZ<6qrBw>0q6ner_bO-XrQnt+2eT|IjZ1+W>Us7T){tge+ Brt$y) diff --git a/webapps/WEB-INF/classes/ngasi/caimito/CaimitoUtil.class b/webapps/WEB-INF/classes/ngasi/caimito/CaimitoUtil.class index 7e1ad172a93f8b0c7ba047563cf3a42af82af3ca..92e78a37a2f7b1893b1791660e06bf7cdacb6212 100644 GIT binary patch literal 972 zcmZ`%TXWJt6#kY=6OamBt+r6K7om{01o762#4vC5w1H4{P4tCptF^#B zbA>4(!jL-BUTdnUSv_^Hdt~S?!_+-t3HLrjxKP|@h}7&uBaSd)2}Ci)kZcIcXb$^b z!|7;U(_r8YTi48e%@N*yGRT&uu_FP7m%v~8*84$-3 zRwOJ_u4~)oKpj%Y)PUY=UIN#UqtcFXY-+mE9(D)5Vur^PYK`Aw+%xg2tE5P!kvPU+ zXwq!>cpk%a+tu_}PqgDv=VL?1tXn#bO~wWh$8xMsyF@8U)uFhJCA7yhD5!tU?Yz@G)goI>;*k{8K9t%#|<92%$;y767#GR+b}IX=nW&&7#@$27&UT~8RIreD9}F;UP+J{5EL&` zR-`xig|zww>>~k&OB6E^xr{7kaG7wp^5AoW>t}nKtUCm2xLy7 z(l()d1%E=@L^=j(k&QtnUON5tN&P_DiKyxVof}Za3Tjw|iU!uOiFG`{20D~oq17~X zQK?X4vws`gK5ML~ikz5;_48sf1{2~!1i~uuYyv65w@Km-*|3RuY|+XbaS2@g4Sffv A?f?J) diff --git a/webapps/WEB-INF/classes/ngasi/caimito/CaimitoWebdavServlet$LockInfo.class b/webapps/WEB-INF/classes/ngasi/caimito/CaimitoWebdavServlet$LockInfo.class index ec4ac7bba2805b873c47621af5c9403ef081e2ac..76042478ffd046628c50d199e3d2e2da01305efb 100644 GIT binary patch literal 3444 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 JzIyLP*k`aVES=@kxsMhHoF7Tf2E0r zXcK>cKgxKASszVmjUl@;cV_N6XU@ILx9?xR0@%i`g#^Q6zsn=(wz=#{6}UAsz7ees z9~_Br;0d*9qC*h{-av#Fk_hFkqV{Xt&ZlVCKWvL?3QG(d@5VKWJ*x=vGW5A;IO<(L z2t_A@+qh#P&yc^)VFxQ%C7-;Y%P@C^xKh)?8pFb01XqY33|w=eL%};DOyMr2 z#cB#v?6JlIiKSMsv5xz?MyoaoDCt?5VJ7A$B!f}aMNOUcTb^v!JGxlEdo4DP_M`Ji ziJsoKjZ6DdS9a;D2CirT2B+@(BCL5libP~#n_>OmrDmAE-2Nn;tfS`!Jqg`m^fe`D zo`y~D3`P4CCup?GBRJ))Psn~4pSeZvY08DOi=^`eY3C_&v^H-}V+OMnQ6A<9mCw>iSS5sL3=KLO2>Ly}mYA>&k$b@s4Gqh=}? gj9*N7Y~cYh5H23lOzWEQO-oRus7tut; zN8$n8cnJ^S35FT*L4mBmkbz-| z2u38r7!}9~ObSf-mq-3rIw-U4;DhI-LMNsb;z$IKY-&wlMj;QAp|9>%t*f(|<=IzO z(K)|p?A9;bvSvu1+D+R!sav}Z_r$60XuG1_;FxFPZJ61XS%En}zO=}Y*w>|s-Q3Y$ zz1Gw&gDN_Xb~kIb=V^~2`3tMrPSx5fo$7MKKO7OEnfx9@*1ydL1|JS?ct6Ye$=o$Y zY04M~LWj4TrVVh)JCP*qB4?846s6e$GiM*b@5nKvND~MFY8f4B1yQw1)o!H!-W6y` zbc?Kc51tA=ql4oW;e%I14pO28qlKt-`;U_CPt-bMYJ;*Ks&n*Wf}$j##2CgQe*oKz BN0I;l diff --git a/webapps/WEB-INF/classes/ngasi/caimito/CaimitoWebdavServlet.class b/webapps/WEB-INF/classes/ngasi/caimito/CaimitoWebdavServlet.class index 2a46573b3c2be5f0e9aa555dbc259c150bdced71..210dcb1c08d8398e0508ab3d419c0fcd230ad14d 100644 GIT binary patch literal 39667 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 xnRJBgH5= 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 literal 1519 zcma)6SyR(c6#j10Hf;!dQIP@y0&P&L2m%5XDT^>{4hSPJObDR_O2ecn_yfdW;FIG! zFFv@jjLi6`GyVyE^fx$e=cZ*T!f0o5nse@1zVn@P^ZD2N4**&)BB2Z|ew5;thYa)+ zeOzl5(I&y0Il9d)?GlL&37xpZ-@1J0me7MJ_qxkP7Z<%;bcndeeOg5HG02Ph(xz(I zsf4btGq7O>F>4}iguzXk#!xewjH@XlqN&E3VVe<4Pnl^;(<3oeTh_p-%^sn9~Q6?teQ zeGY!qqAr^+=wu@tZ{UA*6yD(8p+@$2qAjHP_i(dl1<>rgr49bh#&_ce}Z=##YY%igyE}m@DaX}{CyPAk*~?U zi^5sXPX<{7u>p)h#ss07q)9v=uE(hBXVgtMNReP)VFCjxzl9Bopa1C%&FKq;+F T;4S>eYm*6Wr$jd#s&4)P0plor diff --git a/webapps/WEB-INF/classes/ngasi/caimito/resource/CaimitoBooleanHolder.class b/webapps/WEB-INF/classes/ngasi/caimito/resource/CaimitoBooleanHolder.class index 677b931705a8b49a7c4dd78c0e9e22a6091c4fbe..e8f87d10f1b79aaea8d47b72a299b5ea367f97d3 100644 GIT binary patch delta 208 zcmeBWde6jr>ff$?3=9lL3?l3dOcSg0#Ml{F7#Rez63Y_xa}x8?_5G8wQj<$2N-4Q< zF)%Z5^DwY8aBwm(GVt;+urjbQGVuFk=B4_T<|d^Ug(N2Bq%txH`Q#@j=7c2{WrFxn zL6(w?%wk3cU7v}y+Kko{{gl`k6o95MPdq5?Zo|L?WHK;tX>A8$=B*4o8-Y9~20kFk j2eg!d={5rk(;Ws*Ak7aHff$?3=9lL41!z?EDXGy49pCC>_1ab(7i$Ok_-{2COWv$-^_?I0a?&w0;zug~+on|uHK@*9Bt_)0^S zKw~2*QVe#4=P1tc;pzqd%7#Gn_$v%rXROqjp@khIGeN`=ZeAPMBGN=I9bW7Y5iN zuqt8q8g3+=$+-irW9TV?^-ayui~5uvGVM^s0WSx;r{hM(HSKg(L#@Ep`F_HMf|M_5 zSW9c3DN9c$Lv&!KlU+H}N*GQ6>rk&@y}+hLt%U9LxS5pLfQCQ+Dmbp}^V_Ae9lS z`t6f=68i-LUU>?{5ThCn3dj#j{ki z^sF1R6Xv*SFnk{O1)1n`63?sSl}W>mR@~6gRYI6#QLZWo6T~s)wHv(}dIYx3hk34R z6tuCVBXI%|f#q}&E{X(pGWEykv1;9TK_ZG68A|Og+qMiny##Pfw;LxVUR2k$%ev|I z*p8B&mKacQ``8MqBxfXsyjmp;%W#bvoD~ou#kEn1mvD}us$xab31eC@Yf+j+)cp$* zFXI)$l+BH0y&e!)*A$5?%DV#?lZbncQRhR`upIT7+W% zVHgRkaxx_@Vv;y!=i^8UH}xqdbR#8^hE0k%M#`R|{dpZzqJM>hViN^%37iV-&^2>S zSRMrut~bXroB$j&dVF%w(c>iMYD`I7#S^9kn+V-3}VM)X+tZHMMzElC+`GPt*c0D&Y{2xFXEV<@#d_C59TE~sNya(UroY3 z?y*II_L0QLUeW~ul_3k_Q+%%BGa7M8)odu|nwHl*XSk5~La{JVP&#HY#NdGUeJQ|Q zw{VEJt8)8y(4mjtC~#&8_0ix{<1WOvP|}v$sJY2S6@q-KW1t<&`ILnVe6Qe+6~#*4 zTE(@WyVc4}RfA^|cyI@6MsA^Q7MpHkN6Syxl}BS9tQQz7B`-Ca^rzVeu$x!NPkw#*=)j9SARmffA(l;eoG+O+>R%WBAeY0q=e>Piy&Sf&`TtDJ49cSrn1ovs-PfnM=aKXdoga_h- zA~yB-5wBt+QE6m6uiT=VxA|I1qcs&^d9F)l3`C^ zJ5222INXOx7HtB3-1l>T9u|wA!Wie^IJH%aw6K&+p$NlvHiv?tiaMp$g?WXR@bja0 frG-BMFV*lzAcr^0Q*J3rI2kG>Tz^RqRk-#qjl_VI literal 2261 zcmZ`*TT@e46#h2E95`%6K@{(bwuWn}RcpagAu7fucp)0Wsy!r!aPZ`un4AE;+UxYS z51r1?AD}aR^3q0IXX;EJwGVyh^sPUn)7tjiCj^4P46MEPI_vtawb#zme}DQJz(IVW zqYXzjyso1LN9)mxKD9emk3D!p?fMn(O%2C&)MG%AK}8}u1x{!aHyKJ5;fUew7Iy%8^O8d-tOq4wC6F>Qn`H(d3h zPhjncXQXb#jhwHn;cX39HC*%m=r$pspPWsZInQ#Pf`;n?b!qp6X`3EBZOEHm-ZH1n zi0u~Br!3`tf2i!qHk?eD{w*idx16IAXiWQNs&w@cx0p|vWkW6ghYM!G=bas&>QNa; z?8QDN^77$?~CozLriFfgy#QVzXt2iX_0X~%Y2)6{97h_(4 zRN`aollTOmN*u;M4WCJTjw!9pP8n9#^4xHK9)|FXpa`_BB3XqTdt%Xdxh4X; zR?&+XsYx@Q$u9{wF`0K~%I&ptsa~WU;X+0N+g22axXy%?Vf&<%{j^2m$&h0*g9nbN1}SD(X>YT_}zh{Oc&NDHM$^hmwH=vo}~7rrcO~ zF|R=AOgp0p=FO}-&3pdxN~l#8lo!@ad9>M>;|$;=;+RR~jTBYad8(VLI;OSS)&jpz z4T)xtxD>)g&$9h1d663?Q_g+BwgY=OC)+r_fi)0nIFP=?(+;jeaXTJD+~bBJlLmce z59xk{IMOL9Zc{bLZ+|>S&FDka-bbKBz3&m^Qi2w{kGeU89;1G=^C9$jR|ySsXyqb1 zN?7~#w~&vqPJL^<`v~jfwf$Y4C2W|3RBKc64s^9?4)j+{l&~?`+0;_PrXvBLSKC6D zn`yj+)?|lrO@%GK-{y*v@>RmtLPQ}(vea8vIZ9_!1;Eo+`E#1W&wj?PEeDefY` ziFg|inBfEb;IF_Sp7E)P;HkgX_}ENgD`gI%m6K~H4iTZleD97@>NtilfGD-j^EAfC z>N+_FVw{|D&cR`PiF5dhU%$Zx`bywCT%@N2e&qTKU$JKx#jn)-4Oj3xuA!ZtdQkTd zA{siLW0QtX5&Rn`Vj8-hqX8Pa|3b}wsDscbND{^?)CsV12l#)Gh4!n5KT%6AkRd+1 zR;wV9*j>Rzfc0IWRxq#I3c-( z>IC@cY=?#2m_irdnJ~|%d5-aXnddRSCs$z;j4a0CP~)Z#i$uUB3LS&Yxo$D(fKU$# UQ(u6A9KIRV9PW?McMV?qANg4%PXGV_ diff --git a/webapps/WEB-INF/classes/ngasi/caimito/resource/FileResourceObj.class b/webapps/WEB-INF/classes/ngasi/caimito/resource/FileResourceObj.class index 5fb3972a784f2418d726748edfa6e85b1327386b..8cf5e94502e6cde7521f346a1f13a9c7ec325014 100644 GIT binary patch literal 4935 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 literal 4102 zcmbVPZF>|~8NO$;yEB;%1Of}BytIJig-xphKO{L%b;Aek?|G=wyNxjdR>}EF`iuJ?JoO#YU&+Gl% z=j`9^esTvu3qI5F2%fG)9geDaMun-vkEeBhkBU)D%*4gW(oumi72`S{z%d=2uyq{A z2^9$)RT$GTfuxW);xi>4Csm|%gv4A3nMxX>rVv~mS)3B1)8cVPd_F5i-xrVP#N!7l zeyC%!a3qAY8qR5WUdIdgk&5%eH|g*N;oFbJvY%*pQO8C6RKrU;eukG-yrRH=%$cwh zR7a1Sr_4ygOpZqe-L#z?Z&&a@=YgJ{?)^sxdk=RjPvEDA*G#$x%|zC!05m8F z?y!@#+o7PMzTqG>b~$lstcu!6t3Nw2YNdzF(F7&xxaIDa)>hXyEM;#++NDy=QNc zmWG2YjEdJ(yv{J`2VCCv4Y=q^*pTO~I|xJKbmOjGK{3I4lLbtb`?O(~G_naXZbFFac3B|0TE%CRp1MOUxHmAC&R;*rJT9#j7Y2%>p?F9>rq@zK#~wOhSpN77L4tmY*pC zS!dQx#I3Y}cI+_l2HrIAbF>)vh4_3FR}`#Tz-6Jj2Hq0JuHu@Cw++05cUj?LqXSvD zfFTvXH1I22H}Gq`Cq}<9@ID?>U=;5#@D!p3ev7Dz-x-+12L^tRKN$F<5Pyg(20jv_ zKVhGNKVu)uB)1nO*1!!+DPTh=5f;P1P25sYdk-irN}_?=BJOGA49sAb4H?O1(gg&@ z)AlJ##m5Fd!JLAXW6W%G9+u4nmx@mf`~`OuY`KTQqKYZlRJy3k19~CB3VcU8OL9MS zEbW~3+IZEGC3|{wPq@1C5iH;`R*$!e0wC2t#tU-Uz8c0u!jYTWl zIP*9CQ>dJ;xkKn!XE zpK;vBp~3yjrf9XE1b&E?58<$U11jQ-NP{WgUSvI3$u&_*`?zBtny{ZW8bm7&Fo}m4 z$q0I=;VB%YWP+9nZrp;M=1qju0>KJZNh zIq(YB<5e=iWzM|DB)rZ9Tw(&=SO|V+S@8V@PfyN!`pA9Vsae9Et*9-yuT7`!`T2zJWB~{>6?klTYyST9Lm#EzTe|Y)u zVlO`^Q8|bqwg*XDQCR`OnpfwrnS{M1df!TH?W_J;zra%Uwj64&Ay~bwzwxgaQQG_! zt$|RW@y>gomO5&yZ}Zpq^C0w&0J5yw7z(s_L^2Jn#!p=h(`b-`?bFyEt|9M+hc5(_ z$uDk&#hK#~Xb1nXg7;yKH{mcZ!p*$&wqc6od6U82;z4kmZ8wc!l7gX3HQBq1t2B3vc{U9^cu`A#e&8$-FcBe$Ded@BI7U?@s|-#FhrmaMrDv zft|BVyKYM_=ZnB=`j*J86j!fG>D%R|6dK|T$G6P8X3jC)T5hGhB`nDht5oX@!-epR z6x%X)-IQX{^XsOZW$5zj72#GG*g8YpHS2;Q899e(ij>~1kz;(*3^o~#mG4Orkoye= z!}44yT)83dH7KmtF$1|#_bPVP7L+kDXF0ZO%PZ7GD!oQ2=DmvO2E%g(j-g9g!v-`Y zbezCR4WkUF4&HP=y79c{R_&UBQy63Dt_c|(FpQ_t1?hQCkZVfY$t_d+Yo^l_w@lj) zW)qlT7_uC%S;-A0xP8N ztd93k)UbMBsv?dIl<+=7kE)P&D`I=4dW1CcD$553KE!PzIcS!HaGpr`seC@Y54852 z>G%krX!w|Bq$8(}kPLi^4I09R=?8@Rxuca5&Vve^)nUTYP-f^0Q|^5+Pys=rk-kf| zntSfhOTldVSiuci#hHyhFSKDt7Jug|6jxY&Au^MW!5}{3oqE{`7 z+;Amo!)zOPB zq<1kxPTwJMGt5EflbK(!P?$%_DSQZr6di7o$zlHw?hA-B literal 1531 zcmZ`(S#uLd5dLN)Ygg;_fsAczY?A%5fWe83Y!ORw0y&)3Y9ud_c2&D0 zVxDq5q*6Jk%2g@npej#!$^#HYDyhm3;73vESs5!X@PoR0N8R6afAh`UfAIIe08YR* zZ~({S7{v)?o>AsmWu8;!q%zOzc)`GncuAR4YGvNQX`C_eGF~xo7Uy&<7&wm$8WwfD zs>0U{>_bk&l7V4d)R5P(%n+$m8w?})tJXCuE5)YFp0}h}^!$b;Pcg*&Mn$+426lxZ z>RJuKkmw}WEw`2}O5bs7lo;Kxf(?eA@^vW!N?&3yZO@g$mFx0)lgj$)Rv_0KUd5?8 zf)Hc#j_b%X)Iu_~MgR+5g|Y_njw@DLjk54dR=G|qrm9=sDWhz{?kh^m{$SZ^ZYLQR zHf_e6Bu3M<1yC~f%O zhl(r{WlS?1acfrKWNpi7IMU1d+hb-6#nrQt4y@dg#KT}0fCvz_+=aQr=dQ%gaWnL) zGs(FXv013nkjY0Ck;*Z|gH|~R1wsl-=5nb=(-`)58TkL~Jx$9GsLP{|!|vd;q*D*o zO7iOuQFc}sw3?75N6GczZZ;M=tSoqL)u~aBl=m>6Os4YE^Xfr11X>}ruUYk$xMVqg zK%0#1`6o$?aL!S!u-rWep$nuodr0BT-h=JFS&wCxF3doat{%bBJt+B>El91S^l$(g zbR|lPbR}8xP?`=s$vX6;?9h|ALr?l9AE6&z0Wi!^v_#*G{8aiLSeo4hS0<8<-$hhK zJ<7yxQ3k_PWXBN$_(zEHZxH9-qMv_k+Qn>Evx_TbNG&iCBI% zp|=q~J#iDmvyq85jQnl%&bDE;(f0?1Drx(RDtWly6io{LBVv3Dz5FL6_|F*OzhIL8 ziX{IHY09Jtl9;6+N-fM0A;)&c`#4;q2bbMJZ{!ZNztEo;Xk%~-T9iKj!M@9CDbdEz zJ?y8X-=SYjw=r^yuyh({jvmrZD>H~wE1%HlpF-!K(b%73lz)K~{~B}rOB~~0;W)n$ SwxlC6TGEhF9c9B|p8gNtkzc<6 diff --git a/webapps/WEB-INF/classes/ngasi/caimito/resource/OpenStackResourceObj$1.class b/webapps/WEB-INF/classes/ngasi/caimito/resource/OpenStackResourceObj$1.class index 776ee5586d2b6eb35f56f65a6a5c6d46c4b11aa1..ce55df437001d3cc482e01ef76f4defc62339b07 100644 GIT binary patch delta 343 zcmXX>y-ve07`(4Z2nh)-tEB$R_l$#Tkw!WH7tL%KX~JPJxu%0x+V`E?XrM$k zO1a}|JUwZIt!{EJ)s57TiPExt+UCp8RXw#ZyH*s0bbtTx6jxm~3wP5iwulK?)wc zdGRMa_#eedXP9|!m^Z`wZv2YqXa4yG;1KIRTyz2mbUpMu^vj2r4MO`;8+BDYr7F8k z(y1c&H~P^ew#b-YRBv=Fug|Q_bXr(-bW+{ZUiC+v?m%LQNTPwJgolW*Up~jZtpfrG za$=0i&ZkM9tGqnjrkIzn1fh+#1b1im4kI=s*c*jm{iSAH9+nt=W}9$0fnXeefW|X8 j?+Z=9y;*BX@O_IX2NKH*TtS;rAjB%xm<6nJ89Dv|5s)fB diff --git a/webapps/WEB-INF/classes/ngasi/caimito/resource/OpenStackResourceObj.class b/webapps/WEB-INF/classes/ngasi/caimito/resource/OpenStackResourceObj.class index 1ed3c1146f1e5bd91e0831cefea60d7918c55dd6..2a0c8443abaa62e165f1730e659a64e408d34e9d 100644 GIT binary patch literal 11529 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 BJf{Ev literal 7974 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

a;1q)N~Ec367Or`VHc-oyk7_MfvLe7CD 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 literal 4040 zcma)8i+fvj8GcWi=C;#|S=YhV(hD23X}7S6Q`S7AScK&95T1zOAig7u?+SS`gr_2S8s8K0 zeIY-P+s_2?tQ;y2NeXfM#D5$>@)XbOGdZkT29|jvlQGh zFgTshXeA?_(u|y8nen1tGRwu39zWtv4$m)A>5%KHk{GC4hqN5IJILL@)f;(XS}R#e zGi@vwdV12b3QnYg_ydE*7*Q|1p>W!>nc&?0n8gutbl=LOap}B#yp4G+4&AHQQg9*}n)^YkR z1CH@^8rm^UnT2HqcMg0SX*NU7JVO!Unj|yD$>R+r?`o4P&YRZ4D&a`XYE0rl+DzIo zoQ&HF1k>&*KX!zK9VOqp}n z!^(hQ;*~q4)eKZ}5_p5jh z*M%!_J|gJCR5X_omam$z-y3nZMr2$&p-cq*Ur%Sy>6Z+`!*ddGrJ;};Zk|NWcO|bodZ)- z4I7Pr;Gk5%Hn%d?13cRBc0el>^gP??jz*RAu}0=bl&zqPV*bx@$THVVb*#7bm^M?I zbXebgjJx|q@*EJB-J$AJ2VvCN@!k^yqxL;}ckMgk^or_gpaGbxbPXTnN?WNiZuUBF zZF_X^sK1Y2*}M6c2t$$b6i>5Q?hT&>|}PY?WJSE+`~OA=0suT+sn)4H`R71GLtgp&cUHVWQpJ80|2=R&R}R ziDDfeI`+@h$iH{p{_UP1-{!>Y=EWMO<9NVjs&#V(w^rlhxY?vD3N_3R z(kV@LR@XCcsb{vxT=p=ZpjJM7otmAzNuVp(S|8{of-HML6lm*NI_SxgF52B)Em0@m zA13o7EY?SB0OoHBa9cgVV+44d08i8aq>y$U7~?3Z7NPX6*iZ#M^$1TA;VE{Br)v;& z#@Fc$yIq7 zDm%Tg+x2TR>myu^s#CHr^U%Ped$r$HKM)&YpR5XV(&s#D;sS4;Uayh@#W&MoBQ&@F z9+J*|J>hc~5bg_~JCE(xar@jVwnevBa7RxCcSZ*|>66JICl$oJb=qkoy-NBTYxQ+> z;thTv-n0uR1mAzq>E~x;yUQ`(tJ~ottZs+TH+o_nnO(!q zb;{(MuI?`1c6B>^=+*6%KgPvJqxTL&c-H2Uk6D6Vm0#a=49!J{FJs3lc3we8G=2?t kUBNCkqs!P;!R~5+oV?nDHo9yxAG^K$S}Ir~h!4yE19Dm>y8r+H diff --git a/webapps/WEB-INF/classes/ngasi/caimito/resource/ResourceStore.class b/webapps/WEB-INF/classes/ngasi/caimito/resource/ResourceStore.class index cfdc46fa95390c1902db5ca9a958dd02b701ade4..85bf31d15e1fc3adf0c2f7d645465f14f3d9992b 100644 GIT binary patch literal 15321 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 BHs$~T diff --git a/webapps/WEB-INF/classes/ngasi/caimito/resource/ShaftAppMgr.class b/webapps/WEB-INF/classes/ngasi/caimito/resource/ShaftAppMgr.class index acad9166433456691eb82255734d5d9e0df500f1..fd079c78ecdf4d284cbf2fc03634da97cd00fd11 100644 GIT binary patch literal 304 zcmaivu};H45JYDkI|dVo#UFqufP#~t1R)_LDg#AO`n5TnjT}2VU-&O7Bnm!&k3#HO z6m&E*JG0X2?br9mCxCP0DI&sQTXQd_Vp)mrjI({Wag{Z*1;6;4_4>YcDPlst5 zma$(*PdF<6C%GhKvw`nU!oBIa(8MxUQco-SjY%=pQOY9gKm^C!R7#Ucc^HWk8 z8TfrN^HTjvbCXhwLK2g5QYY?JVC7+8VPKues~W<{Adr<x3s1Qi90eP}uJ_7@*)^-NQjbLeZAjt+4W?(P|k{m#qiGdRU=(!rc diff --git a/webapps/WEB-INF/classes/ngasi/caimito/resource/ShaftResourceObj.class b/webapps/WEB-INF/classes/ngasi/caimito/resource/ShaftResourceObj.class index f83fe4eb6f0e5218eb8c4556e09074f8edce74ba..498de30cf534092bf915801055452e59b8c9a5f4 100644 GIT binary patch delta 300 zcmbQj+`z(n>ff$?3=9lL3=-@NOcSSSF|#wUOx&+6$7Yk6msw)R$iS?j8OF%K;+&t7 z%EiFUz{$hF%D^_!KtxW+CqFqcCoHijGchSAH3UQe)s0z@DC3 z;*p;Vlo8R;^vOyrOVrOv%uCk~E-A{)OSk4^5M&T$XAqkBLXMS(L4-kcG8?1v#AMZa z21N#-)j)?aFfajGKr4YHJCLUjq#1!UtJZb~j*VbxE+7e#W?(R8;0BUB5CuS*7sz8_ o;A7wiihwlh0cnsrmQ4%-8-O$u146F_l3o@8sAfh6F|aam0NE=megFUf delta 221 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%0DQPs4m{mVzx7w+&IY+^rsYEm)&q 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

Z!gf#oDuuxysB_j6`9^2${nIq+DMiKI7 zlQ^1e#C!V-xu{4O=>~1LZz)2xWsasUVJ>!MJ6+1{_$P%Jen0WFW}VW|&ORIClo;ry z%q~u+?oST{Yy~(-wmhl3Y}^@dcBW{a?LTWbVNbqII4q`mr;WTxd4`v#rhTQP@lXw; zyC&?WQe@%QKlr5D z?nsxqKHP9>2H~KdYQAB3dh8$zyIJFGQ95;(bH=r%^ElF7B|!2i1s^rSQWzu18spK4 z$VoYK?*meXXwwS3x1sOU0aIKn6g5qnvFpYp*@I#~QC9V2oIJ27O|L2t>B>rb0b3u{ zDkj+u)vzrFf5LVIxe|1HBaytKcI4O=Z+l@aY+XNk_ayoZ{onU9a}GPtg>Q;dU%4LP zcENpc0YrC&{d@js{T)Dh1&}?$BizS5qPsKH3U{Hw6Cv~p$b6%)IW}!p2Uv{cPWydCFV2q)eynw2le7GDynG(l4sKJ=f_mpX3j|jQ0(b|Xq``0(rs#x2cPOlrV zQkMJ>q5=B$h``Krg7Nm0x^bKkd^@qLke$U{707J-<+*eEP?tZFu5>4r9YUnV&IZ&C zgPMTjn6sUy+Wiw?7yic^LHRR(V}aJkZA_fQH6E+lyZB(^qx}-#cJ%N=`%?_}XAUqH zk`GGv_CWMf0{DF~CU{g4z|x>A(pM`$g16&nu8`%qij0|0+8-GHTx`9H25D3tzvf|E zC235k=xp+@4+`UVio+WV<=$>$?rz@jC%DFl?E>jHkuZHv@~(hVmo(Sgb`rLSHsZAQ zsI0l|ba5lah^*m@br|a%G?q_FyyT$l;PlH2z!^q(hlN>W*m}}-@ouPK_bm3H!0dDD z+-~2Or#a2z)T!p#n{Q{Z&Z{ZSBZ1K;1nN5%^&F|r=UvsgQZYun_3E^)0Ro)9h4j4W55Gv6THGMeih z-OEGm%L7&4-)!cFp|gWsAXKLZ%jPm~jAGB?(-*nR%-sw3K+pZ?5#R|)cgoEBWqizh z2eSZ70l;KQW4GLrkP@>C<|8Rh#nS#$VMTW*pdazwnxjQG@2-YBz836aku`CXFiECd zb}G6)m3z>cWq*rn7?xpn#2s~ch_wW5E98Tutzlbbw9~szxRm{Fx3|a~$4DQlrP|Z1 z&0*ifa`GWsLk$r!X)xCJU2SG%RpV6cGFS)p|)As-p-4QLt0fvB{hqQ|}s` z;3?oL0+xWJ`}lH^1$>qWC}lvDat65xwTyxhehRV$a|=QmIlzkF2c{)m;Ni?Tykyh? zaI0Fj*t|e##eq{y(Sc|~A;Dx0?prYZ7lK47t_^T;=0Nu8`WumQ)tE?-%7M5&Rw4gd z$;udyAeR|v?2t6zrSZtxr5ovo2pF>l2IZfS>kgD(_NeGw1@z-Y*)5(jX#29%gnXmk zBPazN+k!p&=^TfE?;zt`xU4;d37FRQ*5YoYCAr{oiB(4WKZ7?Cp`Y$o%NSm~0e26! zc3e!*B;+%dt~N~!7Ju&JmcRN<&uH$->YWs#U{11ZI9gdJD?q5S*CCOYm*6aFGG~;l z>3`yImzod}uq~9F7K(`{p4!lTYH7_IcTookqpNx-`C-dJ>n3bvv6q++8lyPVjO$P!m&b^vLXjM$-i!E@r zt7nR3mib-|yCtprY@{E5Y1N>ke4~5LqWu`R!9dIr@(vJ@4mnTNEjVX3{C6R~m|3$w zu`HhCqNemINZ_6QEqSvq4`n8?~f765cV%7LphB zjP2EI?bZMU%f6fA-pF!Ww?!3jB~(@S4;W;uy%Fp04)6Myp#zk=63k2D%acOONTKme zhzoGv_m500Qt8N@XadJ#uLI6f^E!jM<9f zhB_Y+w7XO;Wbp7iI#|p}iKD5M7Qt5fGFv<>F_#`xE+*8wIoMLCltvFv$zU#EMHl|= zsLa<9M(dO060B6sqj4&Kd7jhP5{;juyRcz7-qNM2nIt${U%%*IxgKxsNH* zUd%I!a*B&DIG`#|%_BYhYvg&0v6dp88s9;kD^t(>-boIAggqp>r*xipx#hnyQY%#3 z#J@^jp8W?QQ%~v+7f^Grj{>p&jC11s6H>}-A2;|LAw?Xbl8ye!z4IBQl`G*{-E)$% zTMj$+jkk`r)3mRjA=mqAZzw{x{AgjqQ*@&O-KoSfQ>$$uo~prP0nUWm5@C_oqTD&A zjmX}#s$*XQ`;J==U(fiaKe4;`ptpx`3ybZcMAWCg1Q3yoyfh02b#6Mr677Lge-DQI zPI~Z0lXTu%uFx%5`L9RjD;<+QCk!ufg;RG}rjQ}VLkPtXWZ(S{8+mo9070&t4tyUB z86o6_TH>p4NWIt(dhlzVSWfARK*O*ZwclQ+__B(_ytzouEB|!L0JUX;#IBOB?&HvX`A~tf1ca51aqJ63{IQ-qhWe zuq_z{cSec;68V<@9@Uz3v%#bQSDAxu9B@B>8nnQD*Y45u*K!#LC&|!D^wBL;Z>8eV1qy&P&q$C0wA`81Cs!q88zQ2 zzvrhLpTk4m;W6Rptnv}2;vY{`Pe@gxI#KxQdEMU$cy>`DED9Al8+hqF7z%Dm(jV)H z5m*)9(y2mbT-)$xkS5+@X{JZZ*k8m+T-=9~0{|V)#ZUiLpL1TENz!w1YJ*OODd7^l z*eElfGDd@dk4Dy7e46>?7nF!Zm7|e~RwOv`+Tgn<$`<+B;+uXqfBY_*RO3q@5nzlS zK4P&j&!`VVMV~ZFug^-sqB@g$tYuS~2Q%cCIN=~mcONM>%7IKupWrfmfMus zx;qgGyKwO^b%8GE8oOx+o2!VDkD`k}NyO!g^E?zYjB-1UM5m=kZ%>rQcfr z2R0;R?C9iR>;8Yr{r{ub^5Zgt^vGGOm;!=%a?cHpl)?pwWW)$)DT+!d1rBiK%b3OX z$!%p`sECn6{_uN+2y_&Z@q2rxtx=}j&zm2URDL*CYGVi|(JTB~=a?u;F-BH|-m1&0 zIgF?v`WAW~>k&n(>^FbP1k>!nMV1@IJ{V(OAO=4ul}`M^C4C85FG1|fuogs63*o5Q zgRIOObAa`?`Vm4P-Bp7dHmr3g&lWo2i1YU>cA+nHiW1%%DWoKag9<)!!Fyy&kQn5i zi)8C!J$tUuiwD;Rusb{NY`P`(f~O~5j6k3%bTF_Y)mrKvKTvw2*wy+e`z;=yUil?% z;I*fPD6L9Nt}|{#dbs7sqeUx48>$DdLBd&FvW{!iUFe zmxx9sx3X`Q_HmB_f#A;&3}HAN038;DK;HaPWBLhy#2P6|Of}O&1{*PMAZtt&)3=pS zsqg&i2R@M^c%fVdh%csmk{P+YkI0zngF)KA|Ksf~YKj}F_@xdg(EnHHvW%RAt)a2w ze}X&zWn8ED|K$yA8PnM?bmM|pz?|dA^%D@HK#9Yy;`I>c^bGo}6S{~C6VvIT12!zm zEwwKZ*@Vg^HP{fO`SM#fDxA$Pb*iB)Dw~xxtuHm=zfXJEBnO&ucU52Scf3z`9BbX^xgY8MELax!Vg}0Gh!G={Ne=quln?LCinb$$VcL+PWMQiym4boxYbZmj^hSv8 z_{g8iQz+5rh1juSTq%y8zz`WClXChtQuyd+zBq&b)C+ZH-ADzY)}j=c-?8xGwt9FR zCdFG;TdUYX&tKqANl{NZZ>u(TF*@Xw0v3Oj>($24GXQ-|T!7pdXDwb2B+q6Y z2OeLRpj*+a27I@Z0xPp(iaA^u;>_X~6{_ArP;8)>Pnk+DR^NNKCRZn7Ml(%+rR@>@ z1oQB$rl%E!5DqwlBf}bfJ^^TUw zzpJh@u*VxbK#E6;7>f)E|HRwaAPjymKuX^qWaKK)_Yg+cferXR!hZ`qR+7+t&J;#huP9Rh>kMN+)Z;R~-%c^9ENjVAOly zs8(=cpGSz~0mq_AS@%c-NYQWVRyOKp3}mvw*{H7ArjSto=JRVDB3;=q&eN_du^|I2c(CiIHj2k*%e9B#8>~g7Tr2mct-$fB)=Ee)9b8$xgI?=P8M0A?}XNM8%j zoqtptYe=)LX(&#x;WcFu`>3M5df5A;jeo?c>q(B-$jSXmQmOi`M4$Co4jx;NP~-~Y zhRe+_T5K*TK#wMy;U-bH52wCgc}Ff1+Y94$>1qs`r$FEaSjs(@Jn zu{ey&U0U}OAvQGnYhj9}k7`k6W^8b2aJ9WaKDc12#t9=pjvHNtl-p%>AS|^fA}iJP zP!Z0%$C9y@6DD%5w#hMA*(h!7(%sKaDxF@TZHjfsrR1cvMv~7t6WHor6JG2;f42-a z=pQF*0<9}pRXJk17mJ~6-yVf9o>6XBi*~#BxBhW9$X4BDs48jZ9`4)Vpf5B{a53hYC|e z6hmqxik`h+T0-BR-k!=?h50KghBsT$$eP%q%o`bQY!7A>@E6GMP zE-RuW0zm55^8;pGY=#|szwLeuV6-)%T(pmqHgMYEu77*=CcQ5JbWqz^Etnit zEXn=9NyBpP3*pj@YW6;?ylTz;#8$d$LmF-1sr_o7ki0BbnPS1pvler9gwODt?W zKTaBqi7m9l0yDIdZ5DcOoNy0mF%L{vTolH;;$}tEn?1%c-l%{CIW&){wu25o=&5NZ zh4JRe5oIuSVWX&u#Tpe&LXj_)9{Lhq`9wM@qYLRA9?L?lonqSj%U4ub?L?&`Z+LwR zWb^~KctQ^@S@^hw#*s@&QEtnM{$Squ=8YU^E$5CEVM44Lnk^cWokLk%6y+`mD&99) zK3UxQrKR;i4^+Q^$RLeZ6LPwY@)I&xQ-L+LbH z)9tuOu6tG@&mS#APr|3L2SDq+dI-E*F_M$u_Qsc4na@^NqfH(@T8d8F_%>^P;)83f z34$$(QO_eZnoaWZ#Oy6cCVYEp16p3K0qLt!63|R%Zc+kNUp)!^y21##ePvl;g&1r2 zvm^-k2pe@dJFg5BiO!T_&pYRBQ-QcQTN7B_?69ro;AjdL*KL8WvIo;&PPLH=l>d-E zlTL@mi|uYj{QdJbqQ}8*nC%Y2=;S*>_2feO#`$zXcd;3>AXF{m?szswJX?zDj#eIX zqU=1dx09mY*War5KPwyWZDk0oG6LyabL}@6v$%5luVw5VTkP93v+m`GHZODedU}Hd zKwzHC&0^-9op35oF`{PEG0s(zCPE3f;A;;BftvYr6O@O+Ln_^5R8ZK+l&7*s@!iEb z$XwwPP3z)gtyyZeFxW4F%OTw+OYoeNA6yA zS3rDRz4}=Bi=Dc>IJ>fVaOiJOYRc(JIfFY%W>33z5!}Hlmb|&80(F(JtnHxfRrXW) z(aGp-L{9N1>Zu{LAU9O%p@hkMp+yHLck-PpW2wJmyD#n^XP!UK1hP6)JMNHhd$sxD zZ2_k>M(aHh>b@+KA1u_7-c|6cjA%86Jvy>uTYNKZT&ZdLI_ER&HphhGz#vVFREQ+^>9#+s;C5SDXG zSF9G*$`PbL8Cd9)IV0{+b-P14o)&Nh z%JfWxl_=YFKg|S#Eq_;y@kg>%)~-!CecNtbhA{YqmsznLUQAzT3mge7p(O0>m{^M1 zv)m*Vh9co`)P)@0vqU7N*2#o2)Qi& zOmVqFy}3l;A7cyep8Ciuhr{35B~Sl2PYkAiP$q}UGRn2`3s_bPwhjJQ1L|&(6fdl_ z2e$=SceJeZ^)B~hi$t$}W^Zu{JO|dkqmr-awM_dxM|3&ZUK5$Tiovg1(j%1>n7Wnf zYt<+Eu@=g-%?iimI>+*mGWUtufBYaE>{xT!E?1@9;dqwAi;9vNfI+&k_7vNXAI~g&B%j{oSI4tZN#3UB z@?a!%trMpYk|Y}?GYiO+d;b9cPdN+6m2M6BD`n6BcRYiPzV-j{F8B{A`(MQ+VQt0&yF%JwLv1!~}u$jZ8-nO-wX48MqG;cpRS+_AB5g z`H<$O!y+sA?99}Rr>)6~@6Xpaa31t1pNt+86p-!76wxuq=#3Jbwk<6zGKfuXC-mx_ zmhV9qUiPHDQQpuydnJ%5zTmOPMI_gK5nn%eLbKc`unSB4ym(oOqC2aU$)+yBoK`c; z{)47nY&6QM#&>vdsYc-^0Zd8OcOqY~!(U#B;xG~3E#jWi*)is6oYlneHZz%DF$Iy2_f8M>_P|xq4%xFYx z525r1zk@YfUd2O8-m}ZGZ{}9y@~r1v#P;-Xq^%eYN$9Qgxk%aU*@_>-ryhRMl_pKJ zw$i|7ly96Qvul!XRE*8FVg0HH_I(NGrk6Owur*I1*;ZXs<$|w((w@pSUb*5O(B~dw zh2qzW&Ltlb%O8xKQsnKVf-Jc!-|i6K_8>abSC^GvyQ)Y`U+qsbNUf>9Ptt3mN^N5mjN*x zUP7IfI{IWvy&b)!IWdjS^+YGtBsjrH5*3NR11KmGBsTN6GQ4o+naWMfK zvV^!9L{JIB%TG_bcC<=ki{$H@>i9!9UQl!_pc4V&ogj+X+#jh1$*M=Q1Vp(iGpA z^m?++YT?gr9;G~G%NDXD2hUEPt;;>2T%N4L0^vroRYY4DEu3jk9<0Id3H2bT0)3x4 zdX20t!x0BPgAqZV1LDw1%O`RJ8tlHAW8lyChbm=*9Q3L+Z9)bDy+gyV3Sm~k1%yOG zXMkAqYE5*Afc^tP$yycSEu6%TlN%G7_UfpYb@$=sEd}FBVad|_Wy@Qujq4G$&B=0G z$d;jS0&^fa+5KBauINgnY{ts$YkFn^`$x-y0x?ur;ZE+A^m5f@NfB4D&J@H(1~moZ z9)uX0II&L}cSdR;X=*Ar0X}9WD@DN+ffH#^b3htJXG#_RmT6ty|{c_L+E6+yWLl^Z0e)?7s zS*V{^(`W-q7RPH~!lv^Mb@Rsh>sJl&mE3H!c_VmqB3QJ_FrShu!@qj6&5&4SK=dnjxO4j?`IgBp4RE4U|ilYDzo+b+Ckj zn4=QhS0+bs_#Qb0j^>77DWRJVJlc8-q-Bf7lg~$-Ta-}qCThCu^&?Qi3fLYS^?WEm zW;lpUQ3wXODly|)qsV^YbnwDlgf0HMWoA+6?4xNB6Ct6Pn{0ZD!%B#G*cwI)D&&J) z9iU~YsN?TNgu;bKHkk$UN@fes$V4@KD0x1fZ?wXO=2=_b^7C$#Q(Q-%V{;@Cq;a}8 zw93r!P+v|MYJaz7RryBb0n^(g=8-9rI(t=|uu;+!Z2s4Mo~7YhZAhnpjObJLn{J%Pd`Y~k3(h;vq zqQn7w$M_m3$|bsNH&k*Zw{fm&NZ78A2`bQCsBOAXB+Ri-DmAH2lHfe7&w;tr=X@#~ z^WajV>n=XqC7FDuAsdBgx+Q;y_dpv#tuN3Xx5;+FG(Pw%+*`cM?-<@Q4SD)`XB-`^ zo^{+yO!EC5=4L7z(#ILqE5cz+9L~x``YAs@dXVsjDB;oK6y)#Rv*bkMBAr?)$$K{k zesriP>{}ver&JECT71bD)<)Pj#X*WSIIyyD<5s1sP;j6{p#Lf&^Rt+F&C!PFjvJi76a}jT>Ax06GUAJ77lGwV2>BVeET;(Y3N8 zSJf7`6a2`na>tGf{Eehg`-(4BL==BQWXPn@n@O4Q_YCD9F)gb*qlBNnqQDn>K979G z+9h~T5l@T=vaYvmHERIWq0NJdH7h!6DsdGLJ zk9QFewY4?)8DJt+pXxorFiu-7m3>*b9&T9%D0?l@OlV;`pLkielwsuKd z1((t0U$yMzm>Q~@Hq8NPzJaR0fT5IJw&hn~$20~wfBGl|7b=A3b@$~rDcPf3A;^aj z6K+^ZWRpDByeAG0w#bf3p!R)+H%S`btE#>8#RST(l)O-t$G3$eWb-H!>105Q_aF86 z1V=nvbREX}5pbk?hMFy#hpM0K%@2XPGU<{ZdWl7~N?skt0RhjKt7DSSTBUjr8C;E| z=hi7QYY|-A1LU=QGHXpLxF-SxSXU=*z8t<;B5F}C8JxMJ%_2MCrqOhLk5mY@UApm` zYz{J|zcW$|E(>D}ULp+QBd_&2zEy@h0Hzm5iF`(itg&vRi$RRPaEZVtLMlEEZ|Y8f zP^lcN%yP$F+YO>Klg2-^7$hu&Uab6XPdtY%2?Ivh_M7JrMs5_ndXI3I+Ur5AXiAx| z?L%XvI1{|z2<+c~nc`5`1eOLGgzXSd|o!n*|mQY*|r8`59F`Z&vAd*zT zQPfvwc8nb`pHFm)=52hkmNx13m$^9@dk#{+#TdjSsKkP9!f{WU5QN@WAi(7+CH_3jWFnfL50aud| zy7T!BIPYQ_(<;4Z^GB+RUjWQ1Xc8e>H#YaNT8Rx?EEs#MuQ>oeaUVyAJaxMm@i(do zcIJwx5zRZ>+L@u9Zy2DqI%EP#$EUg%tr`XPwbxYK-OY)wTzbagR=8^NZA$W_^M3IeflBE;a}#D(fb1Y(1;sq}lmS9|(qXB@9WlDU-qm zW!ME4i7PFnfk{Ts_5<~%#}q?m>8%~4>#J_%R6t+`$3&$VffB@3lUm=`!TqD;C(voq zH)36uW){IFeof}z!9OvFC&(E_2z7?4cOamSQ}T24hfS~5xgB~KcGAo+krWs&IO4%Q zm?YpMA3pl8|M^1|XQ#M;!F(2`?V?7lz zjHa1lI)>gAv_jH7#7;%(Xi^!WQXV23#xE%{G7m`xZojP#zdIp68I{bu9DNk|0*zpd z7%Z|ou3>?A*4i~4jSUBMx2ZtTD2imu!;@Xj847auhkNgpGi1P^Pe!AZ%(GtwV~kYO zF8vvia6jC;g&jtM=n~%~z!YAeo-m8!h_AxHrQHQZKAWi1L33XJXlGSo*rL0&K0ULA z$T-FVB3Q3DlT|uon@Ltc3OsPKo?w^FvWe2BWOWga?;%O@`&mjw8q^)4ixegdGhSfB ze?!kqs-J%iV1}8EDJxi%uU$1$6$$+lz&>N?Pa=+mzZ5c{k;+I7X=xQCUq3z|UyjhW zG4l^;q6-N>L%L8DL!JmMpzQa^W=VtDf-cw$I-)|Pk9nv6mx44Yp7}iwu)JB|y?WwR z-xDj_9^s75C2hpTsf)-oxn8m7&seez7>s;i)pr3SZHkpufxY<%2oyWrfF2g8qE#jf zVK}UJxSm!;)V5dmmUal225p=Uf$MBI9BpDaouqR}0$eu0z5Jnk4;+T>%2{%H@E%Kq z$~_j*?r2+z7MbMEf@FiePa*Z2GO6Ucq@DB>muo}4YFKw=DzjVfHa|7F)JRCOjMQ=t zoc9{%T$><9D~9U@=RYQsl)+_x4lyk=n{sstf%C0mbY{eI*R+_!<6*=1$w@xRD!Lt; zb=w5V5F{>fnUZsIO2>bxqQcDKQul{Ec>ObcKQ?2kpzl7+C>NLLRSA|1$!C{pn5DIc z*>8|*bgSX-=|`4a-q}Z5WL$@eS(o-RuXoJKx}_Y4i%-osT~m4KuiSvLrhYa4m2~Xx zywe_XxsC-v#(z7|5vlVTx1w8BtG)(B3BoyuZEL5)x?UQ2>?`0f?mFq10F2Kv| z|B9$EY&)D?M}XH6h~l|(Ba1D8kW>X6WaQU0<|ixz)MJEJ&s%|917ov(GDptz!xUik z+2%KEgo8H4Xz)A!RUv2ODP|z0p*OFu^Q5)5ON-X8o}+|Pfsxa6Tn2m}ph;3)*WwtO zGt+`J@>)|7v!(@$SYSuypA}HM;rwT+=M1Rc)`;OJ>_fP#=xm_d%673YwKNNUk=c;f zBb-axM5xo`!Dt@LXX&V-L81{@st_%Bi6e)q{vH^J42@f)Q^wGfi`c*QwS;E$j}q^1 z+WF{I%vTdrT4OFPR7`Q?%c4#DE)w-O6}oZVt3z5M%v3@wmGNe3{q+SbN8sb~ms53= z4jCR>TMULlk9wyW+8PJsoa&&mYzWtkfAmx^zym#JF6v%u20zkzhK-rHY zfEm}`I-sA+fvYO2-?t9<0kRS+pK?0Dyl5Mm=%x!b;5~f~3tynw%c zNK3K(`UyJRcJajYGw*M zc-87l`3yRQQZ3p_SEK?5r2%gh{?$N&>ynB2vV2Itc zcphAD>Y$h+SMcbXj{DL@&$|rQaZJaP#EdA=ID$40Yg5{~;Qv+%}M_-RC9aiX5_-8TLPHo*tBf(l(YEE70tj%3S+ z?dd%=>bf>e$tK=7-m~FAmvL&tV-InDB=skLJL-?##2Z>stMj~rZ})tjkT69k?Lv>t z$x(vr6U^c9{~mjXNuM$vfxhEqeCQT>*;yTE#3BHv=H6UU*i=z_nfYqbck@0EQZruS zYhOjD`=OSgc`*=e5#b02u&MiHU;2!0gzKMakWF6N6CR?P*qQoD!VU$;pKUd;dCfkV zv$LF?>E}|ARUamY(K%eeV$x#RQ!;R9|2YaEr|wT`o>TzQ=%fO1dxB9?U* zZLurMMjDeUv8d#Hy5tizGr0I{EfV)InN0J2@s^WL%qQIIvtyWNTWtsljiA}8E`3P zRV}2v*zMbC4WzO(W%1_l@{s0-r5JL=lWrMvWURR(uRT!#hg5m7;}a>fvYJlOL$)Y9 z%lWJh3%!r5B*YX-*H+)MEAHA}Ni=03dJQ<0$D(5yWYvQsfabVrE59D6674K{L-FnUFss~6u zv028B%`dhjOL2-q*~S*}zhsg0-i^kYxvzWl={|KX`A$H(wcOLdoB?F1jc_u^6o^*6$P6XWo_q~9_zXk=E zs=;B1ZXA zJ|YL*sRDNd(|>Dt(faSq1l+Opzs~yKwGOJ8-9OZFYa1Z=$G+2VSaFDd%i(7Aw9vI-HLk_i$>&lVXJY7n1J^IAgwyEpCP|8XvOl{rHK3dm_foyLFF%Rt zTfa-3UWlBYX}?C#0=dyacHjbtz)V{>f5)~;;j&nd10oDpZbcwMjRJ8q5T)gk*ye(= zK~e&AQ+so9`FU--LrK+hrl7ca8Q`O9_hp*b_ggBiF?90N@oo3^E9d3=_s@>$J*2q< zJcYuBH9&;>9qTTLQcm)?kP}+uCVA}U|Harl$JiEi+rH(hUAA4jY}>YN+qP}nHg?&z zZQC|p-Iw=n@||;&dy<)%to7$yee|(LpY7Kg`8d>!ieWtTgxY9ML%g>W-prL01S&U| zZlxf>;m$g4C<)czQnI!w&lpvSr&}ik8&!#cP5@}C02B+&-`ybM34t~M7mYALoRwF+)|OP$Z%b!1=Rf3JhE6kvYTR|eeF@5S_-Weu?^ zF6XKWUe>fbvjeOL)gt6jGEN{4k~*-#9k}VeFm&~`K)aa$w^PW!hy+k~vc@aRUoY2L zkM2m^qYiVd+JY-DIPQU$c{n%bu0h>G-~EqM{2f`|~ss1HLB^CoQNz zg0vT>eww36TRvToB-xwWD+8Zfjl_B#aw)Z-5QQtIH2Ss=zo?hm+d#wrnq@@(@` zXxJ!I4JeRir{=EdtKrO&*J*9!;Q{SoqAhCNvzy)cb&R;Mm8+6?!o1UW_4be+$(0A(FcaFX;jK{{7JL`qnUk+&kGk5X7_QXo+3lJ9zx_kCOsgw$gC}1l z^4H`QunQ(^y?{XdloJA`daN~vU!QsIf(@%zZFVH7MDbrzT%l6JpxzM~{+9I(3e<7W zD^2oazWF>l3+Z;AulkGWZTyG=f{fVj^FKJ3DeAUjcx6 zd3$kv#b7>TnNZQCk8s2lG|HzpYIVkhDS~XJAD&; zLvFupvG>s0f_BD{cQ3O!?Z|njItC*T&M~xaP-gv_#m{EE#&_mY)FgXOOx;;8oBVyi zmo!0^azLEp<&g5R%>Q*E61OKg%;0yQ17*F`kwugDyGPUXn-b0^OQk7zhMZR!oWUWy zJ(`=@%ismV*po`D_m05j_9E^!9-lUsf6vSz+>#?EPKMd4ek9_ z5|StfH9Zye1@XZG;!_^&0lO`O#z-dk0b72hsk*a1^#3`EyfBs>|OzP#X8{85P*@2+nE^+>C)_x6l3pNFP??S$eXrVu~_yQbE z_Jg2*EZZ$Suw9^E83L`0*M5}kGJ$lJvfvnMrYHb=L*!PK(v!th$NXjmYQOz|V z-!sL0y~6^hO(bbOc2CNFppNfrpw#p%zUf9qN>W83b}*B4w&;)rvT_+1X7EKT<^f}D z(1=2S?n-cR06k6t@%l_ukOFnXSh@%^c1hv8FT3H9ufHTCHmh+AiRYVLiEjpxr_wKe zfF)`dTt@m(mNK2GCt+|f$+JI=`~7Er){Qqf;iEWn`;ZW+%w<7zl00KcR#@C~5t{Ch zI(oQcjIZz)L<-B0a<_m)DKA$lD3Nb!hqsd|y$cImxcx+YGS;=q`4ej0nq}S=H4E(n ztjb_#mk&1D7c*?`7xfb+L0T?^MMxI`P>6YXMW)rYw(+1+q4+U+meg1p3Z>B|or`1? zlqoj;hW7kmBGTGd=;(}rQif_}j9SDIdcLTI8G12h;V;{uc!dfHpYBsZtSMwzWn>6A zRd9)_3(*=Z5{GrTU*Q zr{M?e=9|zb0xM(UcZ5-aeu~c{O3Jx}+3gOWQDnImbv|u*F_XNrLG8q;fHR7A(1_%1 z`r5dz!{l9(Rm>9!& zxguGq(55J;9iw$ifDxqv%o%G+zGcCSi)PT2b1|FeGsWYT`sub~aX*!>cWO7aC`&OR z6w(HG5#Ur~I${$D#L5uXbzVj)sFA4}_GVaLNGBww-nw~bN?B?j@vcjkKDR0K{#J%$9_tI|)+giNg zsvsfsv#_S^$qhbVcg*vcSNOt{boPIW2)=vhJukbwta(A8d4xa;9{aLcV15wzYRL>ralMp9tepaNpf41@F zD7*-ZT2CW(dGD7gZV@WhE)d*^r^qN|4&*I4+IBCV*J6g+l3jLIO|m1SVEsfJLkfo=4c`@ zZ9hJcx8|$WRh23W?tg`QT=ov*>DI&PN%1H|=e`!IbQ=7xR6xRqF8GSP-MkI;nSANb za?(a2A^$S$>nP0f->D3#6-|fCY8>fihOqL_B#KpkyV%M!ifiR!cxdn4>yk|dkFw1B zgsuv%Vhf!-{Qd?+wPP3xsX6K_7{KdrXmC9=wjpG(Z{o}g~9L2-nPj_^7 zXD@s52XnP|w`31{{vBXskX$AcYfS`+P8td>!S6~^gHWK z+yCoA>1&!WvTg--jyO=#X$D%mnB+Z;hY2?=%;Tc0Wm-}tjzi1TD7>WvM&26Wpo zt2qd61J{EJ^0Gh+;7U+1(>D9&rN$x2l-;AEs>U&5m1ZT(jOy?#eob@YH^;CpOAC>~qVU$o~z7W-tU#!q)1GYj8w}g!Fq&e+etb7^=d7njhujE3l zG%X?vvBIuE>0q#Io4l}IhJDJ8qHL`EaqVsh*Az_?a2YsE)2V6Ucci5ZJ^RLxGkEU} zJ8|#C@L<`N(T3|Rt@k)mE=*PXkX=+%9e7ll!o|!e1j&TJ{pG?XcH%XQaZsqZJLkSr z_-`r0yzo@1lDj9+MmX^GQiJ7u6)dvrAI{tH2 zxU|xSD6x)WfXq#!AJ+;epT{d(Ja%k5azrc+mC8zLr*GX^rUE7@J~v5nJiabc7C?d9 zZX0zimDnNY_1C}IjK5|f$h7%aT~aa3B%;$2F5?ChevodHDBpgOx3!|^{|_joJwarT z<9gF+nI=)v@GUN;p^a&LC35y$RS#BZf+^Ew6wtj=-!a4F!PuE{Vd7kd#7=YJwV|DL z;A-OBM>s_H$?x_?*_-N*;PKtWjuYlHX7N*|;WK6S4O?aB z_JJ~nxk^Qq?`k=(cLLW54|e>h`yaS=T)R!!ug@EzHCcIR2(j~g+&HR+qJ?(cG;0rj zW6hn{myV^<{H->q!UgB<`VyG^6`a!<#%`#q95ik>TaE%&2RWfNe1NAZW-vPQbmkKS z&>COcv^d1N78NA^6I560G4PZopZ9)rdE_hc~gR|a$~K!MOk); zGG}VbY_S@WrcZstWhF(;a2H!bcdXDTFGcruGo9}*6?A9wWB5zdEhgt>p5zMAkA?pl zQkf4dnwJMg48GAj)DbCNeFkA>v6Ag!7e{6pF79`VJ7(p+|N0wn9iONZB~upm>08Vl zpUXw!o`kP{>m#%QJLGvkcCOW_rXQ)_90@8~iA6$>l|$RzyaH*q^GqvqE-gHNm$#D> z+c37%w0EmsK_b46=B}2TKBayJ^}0d>Zkx*d1{1VgbR&K_~KiG#%)PId?b*gW;9WGBX*UCX(fp+%>}U&rBG)4&nW7ZSw}pW8VL!MSyi zH+5W0#xfA8X{bdk&k=1yr+oWF0UtT?H}8Z3qVj0D$$Mu;g#dyn(TUvXi;h|6OwEthgbA zrHZU=YQ^Y=PPezMS1O&qh}OFaln=JP3u0#=0QE;XqqGlOPk}LJ_#mbGgt9^c#iCeD z8FyX8p+aOF{1NFL!TVIQm;y%IbogiQr3_`56RZ$g-1O+rSmZ8X3TRTCjKStJrt0~>0x=|_$rM!7gYUJui z(i2TfTdtT8`N@i%+#M9Nnq00h`{$d!NN97kd7SsX zh7oW*z0xn%fO}Y|Fw2cLZYpOF$`|^;N)v(;)hu?9(8Q6XPS$QUSC_{MwH;2-kdL1` zU1}R^@iqQ{(BvB1C;zfmY!r=)q>ADR?2EZ4x`u$FPw{vYoVq_vJ(3>(_XL_9V<62tDS+{ z(RsO-0g^*y`jkVA*&eCoHBV>gWYW317P-3o!(F-2VxMKX41QxR1>BMo@IV3sRha-n zqa$~ve%c%>IYTo+vN=KYQYfU*0-r{4pWypmta6^c8iG0-k9?OJ3g*1_h&{@4Mvq7M zl2nITYu9%G4)zXPDD*}-dR+zuDZ(P%CuBOYfn*0GDUBbfeRhg50{4+60xqpOj@U<} zDyI8wgbq{XbANA6_wM^9<~xd4UtrXBeSm~7Vs>FLF`qWtC+byj`wu3;G+eiHINq4y z(ncebi683~G4$NvS?Zk)@Q`9ki2F46NH2HIoesUw-@tS?oUve`kJFY@nZ{Tg!VI(A zFI@Q}yzj?&lKpg!Vc1xo6Z*FU`cX-2ps0TjAm$mz%Zx=gz|apof$n%#9BCsT%DM64 zlMI0ZdMeZ48^JuoNSEb$x_qyAjc4fav~!f-B0`39T&S2(pR;Ouf4`u3J~88G6Jsuh zoNy#7^MglDN1;he&dGcVfno&+=|A^xPh)TYR15kfUJQB%E+g((rhlU#s_s5!9-0Rm z?QjHp75Q)ejl^3(oQyp{szP!njX#NrAAyhQ4k$NN9|!h_ zFF5=D-yvyP1B?Hy2mLQA|NjI@D`?C9uZ*$Z*;xE5D{?R>>S>^??&?5r0O z5%8|sfka>o3SBTHWucrpJHpZiv{5rFc4mekuR&Ib$giHo-oG4}J*3Db&G)(t)rJn= zfiaD5Vyo7?)!rJjcj_04UPTn6`4n;@(Q%fppA2p^{y@jp&17;yz`CUxht~ABKW9&Z zlD~bM$Fs@yO(oQ9X5br4SV6Y+qU9LuJuJ4Y|5#~46(9VCbx%G{O&arexM-_mwb5D7kD6hScbv~BW)nJd;U+n7DQ-qITj z@CHk*u?RkZS`o*O1-+i*gHdi|>lVsp*WMaNo)` z`xNn~v2qA@UheKY232Gy)pWGZw8|T5$Vo&rHz#R2xK8*IciC#Z`Y+1het)H2OPkQoIE_j zC}_?}W0Z>?=kP{}6YF!aGrl({z5gV}&T}{I)bMdUU*nNF(7+PhvFL)Gl=7%FyDvKdY|V^3wAB>*?Bgf!H~<9UNT!G8lI|zvq#S!b5R6Y2$L3nL~BIx zJ3yGUAoibT5hgORhU5i00Oh{4-c$G1r{*iBqTIpO-re*@Xu%<}`zRgwQJsQ9rIRo$ zOcHwGgeekk8we^bRFAz1Sxp&(5Ct8RqRc2J(l}a`Z@d|QVHo05pt0TycJh_|AyQ+R zujUZYzhyc#?qWkY73(!#3p|_2-_30oV%IUI=`vf7);uq?hJD>zi0G9%+YaZs_$_7% zMO+DshRzS82~)k#n<)V!OmIJgpHF0N0zd+xl)#0@2ugVde~f7wP(^Q6H1}!fX@J*GnebvY9XEMP+N^nrWse!g?-)e9 z76?uHVrI*Mz`#}qjD$Qxs29a8^K*FfQ$=Yn$l58R;S@cYfn#tl^Q+{Z80N&5qHkez zy9E6CqMX;(!pkWMzLY}yr@eWu_stfhQ{>E1ghjMVC4X#}+@96Pwk4J4$F)=d5J*Vk zIoKN5kw3}&&W7|ivic(kfglK6Z04|Fg*Dj2#@!9i8-Toc?#F-G7D5{|}unSYBGT{};1>LMb8~ zP5s5RSO*75bm(=WvM>dz9CYmhEhSbOH4Q&ib(rpU;ci7SN`uKn76+~;FFRjMbe^xi zj!=3LGR*&?XK0YK)(KE+TjGE6fn|7ljBd$6w>}0kL5G|JmCckI)Mp!z?c8$Oh#Rx_ zr*0<0c^yKAEY?33@#vQ|UZL+f*cz~}r*0Q@@EXz0T#xLlNFK#cV+x)@J+0}}$t)$) z#S76yGO0+@SsBUm#S;t&R%2ItWu#b%Cb(;Q6yV8-_V=V&%Qr5ibqLC2%5(cNJvKq3 zYdrH_cR*8xG5K81$fb4M2Q|~oSUVt7tH-8PF&uWYj#U*3_)>W=Waw(MT+$ij34bRz zshlPvB9Ac)K`VnPlQbkfof7lUU1Dn>r{zspQ+eEpX&!cNVSA)(&{Y7qGU1~2@7zn-y;lbF7v z+5f#uMXP)$Vy&Qj|3-2MR7D}cX~r?R?5{V#>nZXg)@gqdt|I7xL-&;UT)_nNP88P5=$OK`ToXc=8;JsV^WJ+niZ*^1(17)RPJa2QKY~N%( zWRINV{k(nB0<7QFhd_ezGiJ*iuiu*xuDJ}49wV|Zh^2GaZx(?m^Z&X|k(ihVPew(P zz`)>wIxEDBwZNdS2~nlD5;8%uoE%=n@kx|UXLIE9u~+x{a%GRF*C(+fOCH0#3}NMN z|CoMkPe3jjarlVy<5TP<)GrEY{+uQuuyXzyP>?1J`=w7Kx+*rB)n*D%ENSsDmh^g( zT_$WL!AlYG@t$w)Ic)??v;p;n9f!qy8O;e@eJ?x3xy&s zvyde4(jyp>Q3!WisLMfAstO@%F4se5rF7?<>}aeEBt+BZt13p)87@pbT+uj~Ir4d_ z+begy>oKmJ+^9He z^P5g%rK{nnA^tde2Dd#gxkWBQDf&lqIq65{J@~=m_|$ufeJjTz;x*eUg;C}b&?OKlekide0O(p)a}zC)qPswvC49J93x zr_E5Vwx7$7{Sl#r&7QZ%q@|llidLtyL^4*b)~it+aWs3$$1`QlBCibT8?*9IS&WZC z6UI<66~nb2+D`@hSKms|iMwbobGmtF#34FX=jUDyLG*dy8WABBMfwUYf+q;9s1u)V zgp~03ehL;720YwaNEKQ-Pn&%aZG3s}dLkqkL3hAmpa&%)pqtS7)KnNU4W*z-mv5+W zxM+(aoJ()Hlp8?qF9k*+#Zi)lhC5CFqHf5+Er{k4vi#7kPod=|EedIlDLqu;z96il zmWs9c(}Q5@bjSy<>ft0IWUoGgGS{oaXzd&jVvAbYP{bQ^gfvD^bTOdZS-z*S=F}i_ z+8Tppm4ZP}@G%2KEi>x$df>a`ZIrtu(mcab1h{K!cXgDc`Swhf>@mK!9Tpm1nZp3}6ePvR7 z08_(eA#K`;@xUlmY_g;COX%?q&^e+TnOReRkewN9{>^Grq>|b;P6aUFipm4+XG?Al z0!HVW@-4o`4~}(^?dUrMy+o^P-*Tuaq5~7ets%wMnv3$gB1N9HAt>YnVmlE)+UvcD zVQeXuva#YtOhbiitMg`j6*w04u{{38GyO@HOe{iq-A2^KNY%mpgA~khgxO|4bck zl~+jMo(Yc%HFKPi9+s^wNjBj3-_;m=-l<9zES$>d1PA@(hfR|9m1bokd&#KkjMYJ+ zUKz}FVWND*Q%vyo;gA|3aE=wQqR)5;TnQRV`C?a$aR}gz1uUA~S!-yTLdj0NNScFI zy?Y}-Zr|W}tbCsKFmG>a&`0JUoY3@se_`xXJMb+~Xllawd<8ATaPMZeG9E43sLkZ! zRDj7Ks?U>7Y=jU#DZj7r1loWCL|E4MUFB1XZ*~lLoXzE8%ujDt=q?d5QBn#t1tW_K zrhLc*S_FV=l-XsV2w3S$k>Kuw2sOz*$zgeVPuD4Uhfq1F4dHDYmWjc$ickVYj#X5RogBb4$&Y zm1;$XD@WacrwyQdgP7vqO38MD3C7EuJ^{scEJ zirXyWHarGLE}nSDElCan@*jIr^`wl6A?=^8$`k z10bE1Mn^i3kW+GzW#!X0b55qd%5B(8A}QReQ*NCWV#O05YT|BL*MF6nlm`3&wxzt& z%UppJ9}qt-a`-H+`-E*#xuVP$R`(Z9$>GFemwN59CLSpXX9%AjoXz|M;g`$5uLe2d zRG`OAxOoe8a`$3Mwqm$d`nf{7#VYq38oGk`W+gxS zQKwa>;j*upJc2!OjcK!wQ=@auqo)M*8n<(<{|OfPnpO$^BA?gk2ky|sCNpLlvcBTR zC^{_-8_)Hu2R4&1Cu87xhqnCiDeZu2Teno3&|{g_pIKFZvAA9IOf7NzmU*JB;ggwi zVjudUyU(qWJ3_j-Qy9&A;GI4IjpbK0VGr2$&!ip=Zx5~WX#WG*XK1f@J{9fO(qike zEYwWggJam}8@0#qQkCq7J5!(-l=Z+XdCF^K&3pe+NLp*81SO8GC&6Lru@UJ`C}_*@%DLPsg3{7sc5W1O}y^PYB>eUIrF?~v;KwC6wnS}x(;MWFr; z(X2rK+Yn9O+1T0m_eA|a@f)*N+W3tdhvyb#QHO|>uh|cdBqZ5G6h;6A0R%4CBSE0G zl|eami_d<~jC|36I%QaF@F=g@hlPk}@=2=+SDlH}L`S$twqX%H?r1Xc$ zJtlFA6f!4SnhM2;pQg%&_{GT#2(4ujhcTY{DjI}8{SG9+ea4A=h!b#%rKOn9yJElj zvMr^Ho)A8+M)HQaO=C5$=xEl4V=rUdDO=l-net5AlJia4wB-^7v&m`#%P`K&D%iXv ziy1=%;0cTdUjf)(1eialVvY*HSeGTQP{Ujm8i=4+n-QMI+#1Y6pR9U-4@UqfKFN6E zt^c{gX`uo{xPL5d4P~JzNgIsWc3~WA`FsANe%ZV zZmQk*BkOnbhB+%f`Fds+F*Lv*uvmtMHrOP|GF5gi5j(a(5_V;X^36tsLw5dM& zi;B@_h;42Yd+OHv{sYIWUe{nb4|6~e;>^W?v;IOy7a$MlJu;ba)z0V2^z=g)m8JQD zKfK5s{jcD3?Q2znnPl}UMgog7;e45Maf}>THvSMGtu3o@1>}7i${vhjLH{0O^4!hk z94KaFve)sk;UPznqZn~Iggz7$=Rs6dre&tLfUw{MIjKqcGZicaVGra;!p7v-d!3oF zQ?##k8vJ-t%iXVkLZ)wO)LarH9`eK|S?c1D82lAcFbUh#LLj=H)^gmXm5RN$yXxTz zpP2`=2F=_$KLT?Wg?F&nZ5IIM?!5%Kk*rCXTJ>NbU?q9ETegS7$)Rh{^gJjeb8>mg zOrD7_L}hR;1h*jj5%A%?-rN;1qr@aZjFmq6o+Tb#HjD4|DX&FKGe995Zn&r5=)wLz z4h}X;44#VkR?}YSG7hkktn?s*P+4e)G^(T<{|-3NR=L*}on!Feom5!r8JS*MelU_y zVbk&lB70S#Q&j%sZP}aG1?FL@?y4ffMxz&gPQT#5>Ka6M<8M6q^p7GJe?pIX&-k$d z@e#$vtJA#CQLULUyx3XVTcA%(&zElzO78iE?|&|}zByJxn%`wc0Q28Q761QIlQ#Vy zj4G;ArWBDy(T8)l(~VP&U*SPelKkHE^!ee1m3WeN3(`P=D$Cr)>NxxQj8oRLl^+w* z+(rq00CEx%(O|`g^pq8n$JZQV#)y9eYQm4ta`d;sp))OofJ4F4&w`TF9OUqE>iBBqGVLbk*GX;Xp-Xbti3y7m zst#@c627sc(IE6r64y{Db0)^(^?`{Tg#J0O(ac~C4m{V_wRgx*dMBMdJXYcpAp3S zN0Ux{sIVMF&AgcW_v#M@M&p9S!5Zr4N%*d9SQ9{h5#l|5eU-sXXk!A4v-XU>(^pi6 z=8XIc5v*5j6_(m^ne%q&GA9+^E3}AEr?6-*A zBKRtgBJ3O^^fz7se~PI(uV?{3Vm58$sh7Ku;046_Mp)yO5D}HAdJkU#0-`omq*>BK zBO)O!I4wm39vdN}-lA-K5X(I>4&srS_#~zQF*idvF8JUa;f-zm&Ek4OOS(F2PA(lu znr!M^1m$Olv>tk5MBCKEF=J?(ui?3tQ0q?uPw&57<7QUW=O-op5AY>|#V{6fbFbKh z<%tv~=_Cw^_p}5Pa`TXc<7dVB;w~`-(`qeo)-Z>}1RMEzAmXi}qKyx7@@`S_qnmkB zA$oH2_ymO{BLxKyUSjD>>bsEfR3jwg^n_~#g^+|4a&u!|V(o3=d0p&yyu5m9aqY}j zhN1oQMi&v^i0A7Zk!%H)c(s$SedcDTvjX`W`3fIedFL!_zMNu7WzfX~o*oO!PJP_C zcOHFQ3g=Sp5n<;OFXtufbbadH^e(O#6d|j_N(qYPWCIMe86K@hIJB!bV+ zJ&1t(+i$mAmWjB@Ys3UJ?72739QicKSNrsN5sawS`h6Z=e(e_(MNmPc5d#WTU#FfJ z;Yy7+MvAYjtXQ#E(6gRH?$0pRSwoainwd|3v*nAH5?!4rT$Ofn z5*2v2HXo^FFHIE1E3U28`w(TR!rUm+iRrwoJ@G9{V_i!5RNWNrp^G0uz~dr|^@*{{ zKmH4~IdGdIymPE|PXKqQ@9jqUbv<#rq2e0UpHTnVgGKu&8i2rmjU;|&G5=+f_W$-^ zBPBBjV|^o02U};m|5-Cm-BH9=Mjh#K_0S`k{lrB?AQq&_+(4+cvfJ2fXwRgg1Gy3IO0+Re*u_y>-% z&f$AHR$pTd`Xk0+quj?=7_PxIr)|381TakIv{-+%jrC}Xb{Qow@)|psl@~#vLN5_D ze4r$cYQ>jVL0D?ItgtLo$^hs@&Qxu!tX~4TbqbRws_*#rnzl-PR~AOCRzE}$uw}Tf z^GK;gdMWjMr$u30dW<5FU7X2|pTBOo&vQwnH|#SvZ;z9>2QGEl>l1uDeW!_JmS?G= z1QRwSqmgu^Se8C6Vi<`uM@$=_tdSp+&gM2dNQe7NY5k!zFK!r6w`W;aKBw^u#mHok zF-n(53bhZ~I8_^aY(P=hoZKmA967Pu@Djfcm381XGYvrsm**^&Hzn4K&0q^Fkw)(` zB*7g)HqA+PXRg$N+nJUsPE;ARH*#4XRP+Fxutx`6^Cwl< zUVz*(e%=j*k|1t9*^wPWOHo;nx3$sV(^x@J-be?fq>-aXl7Ez(VX#;5AehWli{pkF zo-emrlo8iM{F=WcD6gVFug-&y+Ys|Npg@aMSJ~9&v^J1ukfL5_!phq}iwZBg@St_| zrpR_QST3WkXi2F|+d@Qin%&%8J3gVUOmPK#_JU|Iz7qJZcX(<#_Iz-@Tsd#fAu?@? zs9HeljtIH!fzN1*m{P4HuBy?qT=fO5whX-5v%#=B*d^{-&9=Ikr*V}ZrENXkg5H3& z8j^YDm>bI7f-vNyZtk!l`=p_+h<)y->gph09Kl!yukBz;*?%CsWyQX`YbW)>(0qUh zeK?)C=vam-J1FkrjQxnM&C`Hh=xQ|j#0Yx=vQQ3JwLzKMbyW>^}T%7)I1Qhm|s27<&R~3 zLf|MiJ+wcCijwm93X^+G*pJd>{@9?|{4|N)2Y7*D8}#E9x*;;_9WWCFxk5LFfMawM zoek7Az#BHF@7w-+@cc^oi<0Z@*W3Wg`BoK&6(z%qyO*Xrf*&+~ zVJ5f4Dpv`FF3;)pbEFaBLn2{tFLM?mjTuNOg?%kqDd~wJ$}1FXe;1{ISWgW-5}f(- ztV@-*oxkwJwn3Uc%&6s-(vVxwijlKSI&P%_LytShCWtxR8so8adhk`BOMM@nOL+fx zgG_kZeh+)tdni#-(bhng^2Q<$c%iQFL`ij<5*JU$XRT_bfANeZ%1 ztjM$IQzG(foKtK#V$g$hq?NugK)ax(nyf*3OPENZ#?-5#+V58SWv3~#iHJndRh{rq zEp)=H?_qLoVRhzPzf;a>Fv=ZWdh)3BX>8^4r~z)qPOEpbEiY6J=D^qN4}MWI)X~_6 zoX!Io5$=&S#7uSI>{e0gYWJkzBg*ndB^R{rf%p^T#pjB!6GCiF4d05KfU2ql8pW(I zYtZ$n$Ma0FXZ97=qDzXCZNfG6d^Yjc29~(%jrHmG00uiisA_#$fg_UD{&nBx+``5s zsSNH+j-X(R=f821Qu|txkLJIOJH{Wl6UW|6`@km0w&E|GDGT6SmA<-8_poR(+h4fa zFs4?|US17wrK^l-)%rJw-oufRmUvXF;84$0GC0Ag=&Wl>AiW3dhuC;St4WeeuK+$|Bc5ogzLQ{ zVylqqPhQ4^lXGy8yN{FB5gv2y{Q|)Z;kT4xh&CXuF*lT#xMFjj>cjgh!E&)X%oODf z&I*NEUBV&iy#_k#>~(R2%;Cv+C!w)WHvy|>V~iK(aXdHe&0s-`Ub4@C_cUp(d2z`{ zQmK>JMmaqATTAwf@#ah=I%rpPPuP;|wgmUL@tgp^Ex}Mrq8jxN-hXbeg4!ufyT6B= zB*_1E$WbtMv~_kc{9hx5|NEN`XBBl-WKrbr2#iyGvN&NDlpz>!^j=~bekL%`!0E7Y z#Q47@re=9f>BH%`e3Q7+lihD=ok!SSi|C@Vlj8SDjtMWHfu9jsS#h=PSm?;1jLI!G zTkTIU_Su;d*Pzg?MMF%7f1M`hRCdbGfZm1Y~kP>bY~ARNTyS z{K@f7AQB~yZAk5faA^-Aey2!fc2=S-DKYQwia>qz8Gn$YTs#?;lIu}Ifo0aEq_I)s zQgZC~pVQcFFb#o%$C<{6LJDOe%!W4`(^(jR{H@jz$r_>-gBZu6i?SV}*aaY+iK!Wl zIYiBo%yEzB4xZEGq5V0+1(3hQCdF6LNOhEyigq5 zJuIk(%mw2nFYEZ9H{rvC-XcbpDPrU#utlSj&y|)&BSRHgS0l-mdp%xjng;c%BCf6`%50oX57U9s73s&B>)tW2r8k=@FNr}P7&{!T<{0`v#hZfg zA`c697U(ZtUxy z(PyRYknj&rrodZe&$gz|Q@8LAa65_{uG3#3OIFyiSXW$Ey&zex<9w-`a$LaI=gY>& z&{aM~3_7mj4I^8@kb||PR1f|wIiqJ--{Ptw=u%Q)Qbbuz)o6x3pzvTadZ1eT*D&7S zS5=X~{yYrX$OVO#9_Su^alUMDKJ4)?#aY^XC&>-UR&m0yq%1cBC|C?XzZ4vlWjW-nJMEt4P)n>ry~i6H)RRXW;|`50 z&C`?dw?{T_>W5=6uj;#t@^yPyncsVolG0Xt?E3ykSr}2@s(}coJ3=_t6}UM^Zpf{cNkJKspF}l3Hu=BjK{r=Oied)=tGu6 z>n#M)K8S)!Rqfo3>&M7CLB2@ZnOuJdpnp_$Xa%v&P0nK0eJ z^F;{QJ;Z7dr*ljAxSs+UL4$bAeD?u>(!ax>VFyuaZxv>1_k6*swYwLVa_)Z2&T&un zqo8sJCFT9#d4B_&`dGmaq#OWA%Ag#$cXj5^#-%!McGQk|FW)&N2xE`th*HnegU zd}m`twz9b>#x*n@TC)P1{3K)Tmy8bx816>wM93zy5PAsa)LZ?um-untaEq~hVacWK zo#p;mKLxXESt=JUr3_#Zfd}kRe>VZFsUuJAWxp5bE(yJF>-Jv1B1QS~NfhG#d%NtQ z+G!sdZDu4ou!%9D?~!_TPXK$Q8`ohG$E%h}JZCe!Hl@!QK+wn<#Ag=dVvIsKAF=mu zL-!vd9X-z4s~zGx>y~Li6FVhYsXbreoao%_BYjo++6egf3Z082n`GtXPaAH?>#|G9 zVipIgcqr+)23?T^dB%L6qTsJ7@ddF$(~uv*q%5F_Sz}>GMl9yNM_8`e1n6oQKL?t! zWOEk$&7YU*m=xFT0=1j@U!|N;PKy-uB)?KlRR93Y{}ebV3aiQKJ2?JNG(4TZ)_zJy zO}r=5M%Pnz{&WPrb<9Hkan^sULg0ho@iRcBrHtg${-U9ao9s`544P_MRyWmZRM$4c zU3f|?DO{kU2_&ghX`obAODZoe*YH?dT7Dcldkg%Wbhwfv(jf)BTZ&zOUAJUk`KH|H zoJ)KJ3BBQX`yc-Ks$jAXaYxDqiI~( zldQl}jvrQHp_@mD3hq@)rZsTvceGQtX>Q$FOI>{i{nWlx&ZpCXsg z!%t8|s&Dm~(cy-Bn3GH`n=j*kv0OzARnsIwn!_%XRjYVeBXdLy=U1tpx$tyLrjfIh z2T2gP)?qrvp$X^8qX3HKH)n9)=r#I6Pci0NZG7(~017{`y~fl3`vm{wU;+32)1 zllYb{sX)GiQ5$G9KX0NqH!Zz^7W?xl%ChzFEaFBFCRNoZe6HJhs^ix+xEuRaE~WHz zc62Z<;zkKxy&V}J`SVE&`tz4EW~9mX#!BsN?vGbDC0NoY(+Gngmw{{}nHFq1?#pH#7!Lq{X7+CUAZ zkt`NJz~*gfI@)vE!I~Iy0Cu$jV@kvTJZ-I(+jZrwK@~1LX=tmk+03q?S1^_RX`u+5 zHlC*d*0Csd=E!D6N0ZnfsV;?)@*vyP*WPR;241%?4t1x3hBw>-|N(XNS%|u)BAXS*K0X& zh+ME^A^gMy@ismRG@LGRZ4>!TT0YfS3LH*Vo&gH{7JTZ}bO&Eur2$nXUQ`jfE-!-i)#xt+`JTQFxnRxV#VFbv#h7B<%OhiSsLo> z5jG~JZ95P64tqO`+Z145*|%;E<=0xT^Y|Sm{!4oUosY3S!;f=#!yQY{=?d0OSp0E$ zRH7%eJ2H9s7#bG9dpft8ky2|RtA+^rxHr_O|(`$xh} zN-VStdxr4G*J%FX5vW;(%_;_BM@rcIP&-$=o_216%+_&II*;x^45tskG0yBT4=u+*Uk2@3QCb17}hUn=G z$Cqvat{l>3m-IW-mvV*aM$E*JS8$WL{b7M0|BoMWibTMBZ&9IwehesjrhKZaIu3O+ z7FR?WUoB%UT_7CzI?*M=8ud{qCu%zgzYrABg4tc01AqN4B$P%8bm8gY8lmtyu|{zf^Pxep};5e@BL$2Z)H@l9dRixS& zC-NS8H$tWi+d8}!BA_ULyvl)3w)8 zWuA_9mOj!9* zT*SbwN}=53_|YzM%}R=iLAqYp6Bt7(+W?u^`w~WSIvjCpvb);U0prFbxqTD**?OX) z46a4h)r*f7iK_F|yDJjI;;MgR&RI!`1$RcJ25g>Ss6>-XdAm>NA`%YMn zITBUpY+-BwJ|9Bo{e*2w{ZeO+NwQ}Evyq=xgqxRbqcb+CMCDRZgctRD{i}_*@U*6= z5H4zvUaNTRX(S5Fh!z$<5BEx`U;-6ifv~wTVtAQx5W!*7Oy%*%)^`UG>k?sLSU7CK zBxI6&z)J~;u)|lJoJU;4Ia=^zZ^484-LWYK*K`e*P}fX4tO7?Gq&AEujiM}$ zOl(qBTE@`CA;v;(a4pr^AkI+qTu= z8+B~6V>@|c+qUhbW7~G7|Czt0X1<%5s&#elU(Uh7%?jbO#h*D3V1S8vXtnq)lt zC(Ix-CYJs{ zjUfz)98p&{6LFoLB`(}Bk%OPQ;hBfjvEoIn*KCc4{sKpZK*bfOTGs7jz$DXs%|r`* zCdD^hj?Hij8{0nO6{dF(OTZ>|#M$e3HORgeF3O3C80$JqD|An~p=G}ben2q85cqs} z?8mtm5Jrp{w#b@Xdw>mXGvpZP1AI!0+>pmH45?u++{F%8lYO{_Y)i7-@jAM)zViXt z%sP+4v*98oq-3lb4bM=HM&t!X6%kC!T-f%;o;@S*qGKvR)h{Ca8Ph52{@bAiD&M%P!==>zh}KNuooFc6#z-l>W2 zOGoG(YhhUK^=03I)h*1-1-{EIc*{PG!`rlE`hr5_*p0GhqDL}Z%%y$)%ax_(M%0wv z<}qi???7<3H?XQO0U$IsmkSq}Oh%n5DYEC27%OE$0Eu>oX`XE6BJ~ZF|B8&87VgPn zssvrj2%#w_O;DY9_386MiN z&1uyH@G6xQCK}115Y;59(^kx3aAPdu0ftyaP30EmIcGau=`PQuP13+2-90dgIsuGj z5y>ksfVT@izKtk$RbvOWKhwIuawCZWCzvp zKulP5(vzn;z8|_LjIBz3xiT#th!<;AChu5Y#Bq zs~=COQSQp&D|HzqCB%do;r91>HBsymdpDXmNIlfsd^RO>&8BKrHmnigp-E|9-R`=& zO?ANUPb8~#QJMHdpz_z>G0h70Qz#Ikss_0?wyC&L6?*`pPJwp=emGsaAw-GF7)WOW z1>?8a8Q{Gms9Dui^pM2x@mzr84}ik_*s`ks%L81!_l9nznB7-n)Hm|LHsV3-Ff!v! zkL89%BxM!>OeTD^*AUA?%GcS2^WYnPr+SRj=wA<&@|hja^PIvr&SNLS{fG+E6Mk3; z>Biy6{yo3Y{ojE5UpD1OG;;-+YF;V3CKk0u;D73uFFLR;LfOn27N7zo*jNxQj9jSTYCOUo$~ zkDWgglnl2fX_cu^_0ohne@b=0T$zyOphYfCQzSNc-7kJhVsZ}JuPz_-;Wn{oMV-*` zX*Z`n(NEXI%Q(^X_gVpg{82k0e+F*m2hV)L`=)PfLy#f1h==yVQ=GshWyYaf$6Y;| zDZ`!D8+CC;$4C3ZMemNN)-Cms_!u>+u47;!arHpxbDd;)7qg0mQ6B{TP=yPe$=3nKxr4x8zcrtG zbK%s18n=c7?!f)tK9g-TALmy)$8AjrRrMDJ+R)~mh@oy;^`4ol?(ygAKVScBYkt&o zew#aA=a*ma2@%yf)mvt}RX9fq7-CLP&f3p+W$?)l|M5ap*QwmLpX%3)QgC-h^ z6t`np?M_h3(aW$jg@5rTm(3MZpYE8q4;cf9jv}iYB5iiAPvwW{)=xMK58^INk=oMj zWXDKaDyn#TbMT*UYex-&vzA>b-cPSW^XG*-Vw6w4ImKF0FKa3`BQIQ}i$_!$H^Y1y z;%cu;plclwT0N8?A^#P&#uWI#N{CUb?ykP;h6F$v=VBnJwMKrREq3$v1}V;U;L_R! zxIFuBabghPU-Bn-%elP7EtggU4fEiDBg6t8fi^{WCj{#}CGoC=?4>i6L;t z|MFA1_%mj@OM3m7(iTW>NS6(=otyK=1U%!aWLvZK-%HpuJAm14omZE7hSC--;Mo)V zMQJth?DjM9&;w<>>HKTq zn%KNYu3&Gl^s{#uY(zeVs5h{t-qSvqB;#V6JA}k* z!A~S>niB5>x+JLFZ+v>w)B_l>NoyhsFb*B#*<5&Mu8tFeaw%i+IiDS@^#5${bN0qv zUw;yu?6+0H4lAE*c-pu~GeTSz>pN3pbEWV>Bgu~jKy?Kg-P4?X4$SVIE3M;?mJ0^7 zd?cmJXZC*2#Dn<$>3pKi{ieUTMZs}Cb@LPUjjuZK$cVtCQHDD zO^%C_T#|}UvIe{nz{N0>8;$`xH6EydWe9p-qsR}%>{`o#Zpc*eYdyc}VQ)I^pJKxt2O~96kXihop z04F+tL%c{;DOu4%?c?{Q$M1i*osN{l9w;v>!Yob*i|AXNH?ZSbA|gq*-wc~W9;+^3 z{F8~NwmCAA?sy$W-41-ReP!#-GGGdp+`j{#QyK^ioK_Qq7q$twrV5S;xzy)Xk+L#M zQ>|x9$iADXjd0`2)In+Snb)9FG(oK~Js`Appbnb}*AC2jm~je_N+N#!W1 zf^TVBBeSUmMH$p#vjSVED&Aiz4P0c#4n5TcoeFHTd<`bLXz=ii&Rr!pY0`gFn>pcn zaNo@6R71#&pUG@L8+<-$&autP&S7-Hh-sI%$Jyb{n#9|oCWjVVrI@1zNHpV+=gpzu z#E}o$MxjBWhg%Q`XLAs;uX^eP%V`Za^89Hv+QZt1fNqIGP>!k}^M3xUG5FMnv`XNzw&u*TGT|CyLq@RZrpmpWZtx)RAv@s10!NYM$_y_i%h+bC;8yx zGqaSPa&<)N2fmJ=`#NRZw0zkH_h1B%U@J+4r)OL^-3SO^IwAh;XpDTtQh6Vm?u>={ zoE+)?hXgL)xFdqhu?Qbpt%1FO{X_09h<1SwxfKg~%?N%y68OBd_m!FQ&Zv8J-MsOgargx`@ktYBCJgoboE`T5&eEpXG~nLi;?3y3VV@5-@EPgy zsBrM(m?$;=cO*r3@VfNR4U@dTS%UW>tc0w2Z3>9U?xyU^jyfmU_~7~IxQOaO4v8nN z4%7a0>iVKfO5_L1OXBVSR`X{x)A?Mgj;duvZNuXl@e=5$H{|Wfyuf@@}XB#u5St@WVftYNXx5*x|`) z3>n7V>TEh2Qs{%6Rv9l?Q&`p~6(;mmXy+$L4y>0b_@(OJVL2%H#@W|%kuP8CdvQ3#2Y4N8P zjRl5aN3uLCY>7bKe5>Pl`f*-&=@OxL$SGGvQs^Uy53>QFHs$5?(h?-gWrAxR)fAae zD7CMcaNSa>$+3>U$Y_(Rg%kGi`du}5RI(iur@HgLO`H)-$35_4SDqOkjt$p|E z`jX5kps;q}c0|mWbG*IrFLak(HRb+kN zaFgCgKqD57+zF@B5cACko!xjdefOSGr@{6>?x`Y(1TAI+P$k|y>Fv*mWi6Ng>I*RU zl$A~4BLN@|%^q%nN(?M`-SZGDGF;&4^ow+#bE9&~6yM_rf{^&pCOLxG?ygFOef(pe z3#@PWfPr(W+E-reGQT^r2uFJ;@2|uT@%y z%P;_+T{IjJCsIX^a_*|^WJ}l6EwphFjR!Z_@(2UO48P9UeO9qQD``11UfVI#Yl>Le z8LLqh>jY)=O*Gk~$D{O>{57=RZK*|Ox5BQHcD&D+x#b=CW1 z5$c8&-Z6QjK}Yio_pMQqK!WF%f$mXIYZ#SopPz2uXB$l-jRL0I*fiw^<>t^SD1zUF zRjY*pmugc&d=BJ9^)JJf)nY**?ht0DrFBOuwqRk|9_%+x24RRI5xD$UaMlr*sf3Yz)lGHg^D*Zh zRe@L}?J^QtcGJSUEZ)g1b}h1+0{kO3DbtxK?D?3@sp*ZWNxBy#`DN;XCN1!q!onJBLHPmB5YfoNa#UyZ53{Qn3qDlyrRp!v3r?I zxU#nHwD;7)yU_-mi5Y=;9jGdgn0bV%I&1-#El3QdKXecDz2>rN0BogyqH*=I0C?m6 zv<9uH1u53owg5px6`KVD-5`}|lDm8g=^JRN{+C#3cTj^sPfco8Q=3veCyV$TFZ1*p z#(`+>>q7x@e|@MmpYCz_GmZE%s*%;TrWqR!CIbkDtGslO5Vqo}EkRro!F`zAS_0d3 zg*T&r5EWf?V($v5nuc+=NBwE%-}AtFt!URG&=6P^;ZFz<-1^09i)+$PZD*<1y8!Xv<0nWV*~SlgEq~vG*gHh{(gevqWPwyhQ@9ep0Lh1_0CCsZ$Awb5N}^`?QF7fC^>oEiU&kp%C3 zY{D8J(I7ba;nVu0viLXiYu91(^|A=wx+i6n;J^~c6X7u-Rd}GzIiRu_-V713x0PTY z&Z8~XKUw1+q}{A&E+-&(XE5-I)m*_y^_S5rNb zyRb^`q!>96A?LX_rc`>!Atge)V@j<=aGW2Aa9%_!+Pje~n9I^@D!?Z7(|=GUSAjt>A-%T@l~rlR?U1 z#;!Q`J6jLPL`Pk>C9FsH0Uqc~hA^EqqH_8W*gA5bhiI*{qOz|C`!0>_JV86hj-SuQP7VQV5URn;DUKawuR6!o)7_pG*igd)P`;9d+*cn zcNxVIX`gm^YFdSxbCG06S2NT$8At!oS)zG9!8A5o`L#ua&MA8GFY!YyWo{1Tu{z5G ztqwbp=EFa4$RCqVYAv%jTCmlo^e*w=Vy}*bdRF|1Nt_EPZ2_VC4HE}$K5%Nfkmdi{8vnR94VAB%sN2@I8=$L{ z%gE26r(yx(3T6!Qy552%e{TwBJ!})hGt`3>vOSYyDvbJ4p9T$tv zQL8k*!QqR?)id53Va?tj(OzAh`T&{vGi`EJSra#MkBms1l723*!=1>tC-l0Ie$cT} z5)M2z{J`W>RPT$ydM~1;)s=@YMBH-WIF-n<#efhmEY(@IKG!7;!e3A_L>EiI4|Tf(me|MzUz;X+GkdX z`!W0>?v&&!*rZon{~bkelcv#@W<22sR(jugQk?y))GNo*#P$NhD-wO2UvAMI)29Ek z<^)-H$}L{xz<&$>Uyp{WgKvXOn0VOTDW2_*8Z*6KD7XQkk}|O2)6GNj)Ts|zJ*e*Y z8?!6dWlV7J!K;6+wH&q48Wy z6z@ZX3xQYBsM{5YMH3#%qa<8wpCe@%^@v^1SH9%BTXXNRfDi$4Rp9^r4e|`6A{7+2 z`=stX;c|_i0eJ+LN%+RhdIp{yNM|r8&gpq%V2!alCw?R>(@3{ag>u?DQCV3jy*fQv|ekp|H8R0$v+Iu@PYB;W!{cz0W~SeYfaEi76mEC zvb*Nhm`CJwTu^MW zl|Q{Bo*M4nt;)8R@WlQI%yJop7+43V3{5dBogqkVqgF0{Q|{xgkSz+G(S}|j);v8UV2Fvb&SVb5ZN4GFO4hNE)}!7eQE%j*A?JBROIP>aON{Si$9Rk zR!i~5%#tZ)6@vM2T_-m(^l=g*xqb+OG2L24!d^o!TC!6b{E)r3c2&L?i(+7s?}g@& zLDd}fe{GiHL;LN6{o_IQqp7?7yw43TG2ZAjNNosst7iRL)x9Ova!#;Ny@`_GpU5L$Ki_U?D%xU@UOn;xLpmcvY!f3wN?oxC z0Qabg$fhP=6c50QR%NxU2NY@pDCyN2EVDD@@fX=2eArW)D?Gy0;ZK;C#A5f~-xp1` zpB#DveS4jy$uAcOQJYU055(~vNZ-lo4C3kxV$QN50=3MUJw*mn!#`B#0ZT%a@PN2Rx%XbBQ#<&Y#cS85vU8+`jvx?;UMyu}oqE`39R z#3mKggBXNE-l%96g192|p3=J)%6lR+*Wwu!wh}Hfo{0_M?HFYBaojEay=GdA5$0`L zxr*iCZ5m>k&5^uko$ZFS+=gqk2VZLezvK;gdJcHfSF5;!8gE(9Yf3+=@G6!5j7ur4 z>K537i+uWT1#!emoPV$(m~Jgt9+S{^i(OZCDZP2;xh;dLRXZSqKEtzL8EefAY|@57 zxeoh4>|eb&JPQj-7^J}RZ`wxes7#xzA8Oh8xgHg^h2;C4_JJJ^4Zl-KZpN;*X5TG= zcjqs=Vc7^%HT_7!LviFqg|T1qoQRsZqYIT|*>z+F3NJ3_waWiCI8JkR!N(+*^F%N? z!6I0xL0v8|&o34IyRHBo|93aDPYn8yl8J#++5mbKZ9_YClzdn&!|ZX1kYhe%Yb zP@PB+ej|w@xERbRdH*ok{Ac_2BJdovs#9hg$2Jw6ZCbi}bCkiI19!Y8peF=jZHSL$ z%$cj4_Y%(~xEqNkq8-l#gNAw)*Ia@CNAX}DJdX)s!HDzFS&$N!K~?jlW9c z+Q^Oj;(q4wUz+KkQZmk6>?$4_pe}(7d@ki%!f<8M_!QxPkE{w>M^nrJ1;KHZ@`(%1 zKp&T%-<7-jaN86y64yM1UtXil!hbxAki{45t*jxNnu_tQH?1m{K9E_IAcoW8tw@mu zsL|<*&a3_aN}=T*1mqq-U6hGQO?`vuPGg+|-qQBYsG^ldER)`X0gENhAv`hiXERJQ z$Ie|m(i2P6I)7G^IpiDI{|_-E#+skfqA=)N$SpuNl~`o(xrbR~zyMTc*e0T_I>~c0 z_`A~_q*+l-6-nTg4OLz<)=P>x`i~^3e%;!Zduc_p?QO!Ak@I=y@8kNMX(7H7 zlAjB;tl*j8P5J>h!)xN_GYGDO>3o~kqPx>OSd?}qjxIIP4<>9iUbbwlbDbkvlH`+W zYn7TK(^uu$#IRv?JQ%Pu^D_l~I14w6_eFhL_L`maI3vH@p4YTG@twz2X0RoL_ya6! z8|ab7+JlVKk59RO;zd9ga17kK!0|`nP9xq{BaOC2jNwN#xrmAK|2V%oi5Lvb zZsjJyKpHw`B2?YVTC>n4VB_F;uv-Pe<91W3%cAaakd>^J>>lPj_(da)S_>5Ne~q6u z5-_HPN}ks$Rz3_;nj9#+g*sIB6_C%BCdwFPBW+QFk}oc(EpQ(sfQ&oD)W%O!7m`#B z2^&wWM>MrkqEHv^;is(SsOIiVQ+ME!4?kgt!kkAb&YQ~nUE9>+<-@c_q_vG{N@Ew} z4AGtfolo*=hsd*^DZ=DmHx*VV$c*v(s$e?#mY+4z~ok*pt(m~Gm>JPd=xzc$sBQf zC}sV`)agL$Coz-T=x`w|poCVlQ5?jYpxxA2H>Q2N1$+4M1Bg$wE_5xJ0! z*$j`f6st;4szD3|6TAMqJ1MQr+v+TznNa%Dn#{ODqP5{e;G6t%WD}Y5T&u`CuK!TE z0{I|Q_#5-+f51fJZ+L>LOYB7<_4Bm!$OvR374Vi1g-FmKYk5y7kvG%W!Wu20HsyHp zaE0h^%?$M7Y|2N6Rk*eQv$lA&st8l6mfOa&*$;#^Y*;*;rJNC_Lz%X*3aOC1@q@!J zoDd*|hbRHLCUFNW&dqvkT}5WF<=oL|qNiGiYdu5W~U3USbZA`CJQH zCI)9=;%rUL>T*s0kG6NL3ekMja2`D>z#ESN<(93lIC(S4;-9|<;Z7Pwx7Nk)z}2A;Ui zu}||ed9iS|d^NbvjGL*7J%yZn51uT_NQ*#W`v@NoPt#KPw&A>>Kj@$e3@yN;j5BEE^ur^uGj zN4Zr?eh@mPb&_%ujUjZ-HNHd5LP88nhPQI!fm=kSh&G-KrRl(4E?#HnzeRYV z$Dm9~CV_z0Z4Mh>2DNg>EX7DA)d5D>cO*o&l>+9s`(4s<5Fv#y^3^#;BA$FFZ*Jo59^n}yTk1>+x8Tb*5!quC}3 zuTv>7^*&38?c&g!($8C!3GX4yIrtNmFy+J8UArVzH{O@~p6i8# z*xiG9I061aX>vlA#K6K{QL_}>>(P-{Ztm+$khWEQ;hu%gMT>6@f0*fGia1JwOqmfl z%tq48PJnE~EP3|X_gk_Mo0+I8#Bc8u{pTC_PUNty<#3K!M+ttX#M5D~4r5J7iJ2UL zr_E(2ehXZr$eugg7BT7oJsu6ZuGlg)HW39yMZj zVbki7hM@6%E?{$q4p|cF;m>7ee!P<$x-heP*5B{N0WB14N%Pni27v9uKop8gqK`VL zOeQ^%L^8AIjl$GUm3MV;shW*s`1lf-^c|ehvxiaq#k-S6!#v$BB-Dsi@rDn$n|FMi ze5SRT9qeEyVQ7-)JOQkIl3D6_{e(*VsBh_t9&@gl7Ru=o1<`$S{aHCe-{gqrW((9J zGU83N(GNQKn&glbGbtzDdY_%@R_MIh~ijT^JG`RP2{0Ldj zoZGbVp8{%GWurL);v>%;uf9P&KR4hXm?NZN>0X3`i1)6~eJ8O*6Ksdhppd`)%jjfB zi+|(2hk2yd`eBrHdAo=XIWkXeLJ3a8a7ndy|W;A9AMNLpj z@e0BhN{sUxe|#zV?Y0}SiLyq+wum8Ls6+)&c-d{C=J@^ojbwiEWSL$a{N8C^ZW{a zz)uop?2uGkneJH1_FHcGYjel%ChSNDRFZX}_EyB>tF8}t(=%ygVW&ScTYCeReoGuA zxc{AjG5C|URo9Nkzk}%h=Idd4?JDB_l~Ta+hGedKxGeRTQYi~Uat&Pi_yR^8 z&5KjxVd)-b#Qee{(~HFPe#l~c9F4{Re>pk-q3INhTA6!9<5IEZJ;m6>e0(S#MYcrV zr&M7m^?8A@MN4-Qp#q52`k`~nz~Fn5kWHdTRI&yXti0`3BzT^sT!sL9pVI!KSg}=* z5z7l8HX|yH=j7g-{g3&+D4}hsqeFr5Y(wL-ZQpM?3}jm*xc20e+E$%nb^LM(`JouE zgIVvR-SZ`a%c@Ozp8ia)!YMpG$6SmQD0cr`3Ug8|SS&-<#X1vW$T8vBq}%k+a@7!0 zyRJO*GW5w%CT&=6?RY!*qZrAAECsej8(~7}B1ok$M}Vwg-O%z{hJ9%ppbyoG_E(c+ zHk*Z(ZH%u;FZ)QD7AhyhE;=ulby22CMg^#)IE;@%>*KL>I{WeZdWO(6U9fCU z^gFEq0W(f#tq7TmDS0c76|0f@suT-!R{$dhvcTa!>m}`OU{$+XXTE}?C?>v_G%&{^ zkY^!Ra!FfmNz&b*NY|rAWGMIJkSIjPQ!E1~y2AO)E)+A;BHOmKG=VCRgPhV#$+OTJ z;n@|spdCLwxu(Ay`&QdFMaDEvTBU+}HjWzN??=SqX(|u$PR@xsRbH#es)11{{1Rtw zLUf-TBkqQ$*fTc1cek1e%`!!pT zQcKyR;rtuNVMWCfJ5k8EhnnYlkMtVM;HG^1bXs1udTDl;t5|=gF~(&I?7xfMhD;!( z@~>3#4i3S$41Yrt6rE*TtjN-k9;L%pH#rVpOKTPBa?Q(5=Grr?&Gx z1$d6nXHPPrS8R)JLv?ZqSDN@t_PR$%hi>r~_#9`?&m(=XwX z3L=h0Wakn5WbD)(KR$K^LUs91%_lb(A15rldZf%SG`01XXvIZ zr0{@s+TK?q;Yu00ZD9(f&U^|#$4B^H(+tOA7r0(6lVSm{T-rozVqf1 zDG8MZLHdwHqPgLDF9cAzk-arIAF}>acsTn|<;7lB83iF{wdF)!T&M{X3KD5|tGwwI zhmvB6ZU)+S#1(E5NhOa7xy_O`!W(bG*_42^M7n$tfHqc{{Vy@0ES)9AQs;MAqQ5HH zxlQy-L)oxvxmP4^4##9mLl%@hS+7zKsW(oRzWYXD5VMFppzGQ4zbui46$%|~{t=|+ z7ulA!Hq@-0pp0ODRpp1Ls9u&h5b69hd7k~Noxc^0`m>t7S8z>_z`hI(mh(DT?zmY^ z`~DJh}l`t(27DOv)Eh3LDyv;#MNEX8s}s|5}QP#t1eU+0>X!i7u;y z?TWT6aX1uJ(bTw~yJIix8J5!F{{n&-w($~awF2TVH&)X`4nzR0v2~riD%e#wgKgi{ z)>+ZfPR!M9rez57+Vow?Lw5ZO7P}nNML=2!qF2%vp%J(RmmyZM0FiA2&y#ZnCQ;g7 z7S$cu1V^jqj4Z|h86rrK>y3Q5W1Qyl&jP0yU#+o@OVyjEFx^<#WR-GIPhW=2V9Jp5 zt1Us7VDCUq^RhQ%nho4-onxo?dXDK|S>)e*_5l`aw<7ef6lrU8%aHj(hxPdl3077T z&81amP$E39)4t@P?QKy(knUJ=%NASe*cOc?-nzr$?4)a_{=M^T&nxsa+HGQL-+4Xd zYsclbcT0QuGTn0<$*z)@GS8XRH?6js9OU!0%pM3uz=o58*1J6z8QNYVc$-8H39{= zCN3-IQe3^EI72X|Bx|*)u9X|2*Br8qOUCs>ucA6F^U5D#&CBC}qdh^AlMf*LpSn6^ zh3-te&CiE`e7X1XgmXcSQ3%39JMM>Kk8e~}bs81<72FTJiwB;U`ozJ8%aDhjuD4^9M z84o=#(!3htGywV2P4Lx!{+I{C8!6eW{SC*oU+(z={Qe!<;qeniSkDKaPzwAtx7af? z`QAcCBN+|+ucV3+EHB!{nzU#I;qTRw>}=R+>$%rz9_`?h$!rz?E9NCwm!vUNM|=>m zq_a2L@2jHyld?uNwuKbiV)gU`WqRzjvQgRExG{6S?G!@2Qq<@A5s?lB>6YPEBN ze`6qD{nprHbr&C?Xr?Vpa-{=xk*|Duy(9uf*Zo2v`PfMqlY)=AFVTLNvC>|0AK%fA z*e`b=ZUj!W+O#%l2($RfF5s}^jNj)YY9=IpuOw#&FI}mB;pP!mpm~czZse*k%IhITi7d2zi|se8FZ1IpVYMuqW+lprEd zY#L2KxNwrSh>cw%eTUn}na;$`H}E+5H@MV>dB`50lP*PPZ`2UqjNU5*u+ZvF@04u| zHU5F%Vppv~<*Wc(HHiLc=T}*u_|pzySs%sI4rW;&hZj>0o}M{!wLD^VEi`t@rikji zsyJ*-($qnbt$7pUb$Wp6^k~kW!cBYfV>LFC_pD^dBP5K;#xAY9grQqs9?^k_)*V%Q zM(S_g>Q_Ka#;=Y;0o&}FUQff2!=BLN9wCA^it%JlrNpj35f`?ELmj9+GsSN4(Ocwr|`8K`QD&+u*qArN*hs2X>RBn)582G+V?`*G#KGT(!Hsww16 zUH1Xgvh;45bSlJOi;T-uks>L>l_8_e!*0;eRDln?tA5;B+)V^3nGUf9avY?pF4vTBp@&Y7j%5T(vZ-;FmAG5 zkyGHpI|tCngHycWaMwt#o_iRDhwZM7UDo6u!OkS}b_irVEf~US+rVq%>)XC4;KpfN z!)xQ|TX|4sm#A)$s8+l|^kKszx5&R&vJeV%ba=>+aSKV$SUrWN4NgD1({~d z<42Bf;n%YEy|t10V=#8H(LV&!gKNNd&!H(koFZ@3!+w4M0u5)#z0qN|`KWeV==xU( zi6RUsUM}VO-TZH|gV4UJq;b?wHDSnpy}i2qH9jCJeKrV=e}_UO8(L;~@)0-p8#RCW zk;V^UzD=BzzHaj5XUHtnojP@)%;beI>54oY^$lS5qJU;yFm`0Z-=6VvGG{)AZur@E zQ6`-JxnS~iq-pHxEa;asb)n7Vg*55QM%Cb_J8Ab3!Q`8PxDRjiM4I;LtYi-S_iW0f zSp(Sn=4Ti+aXrO;KI8X+!qlF*S2C>>cd`!Df(0s0v+` zic8O3t#i@5S+Rnv9OpYB=H2x|f{Vi)pZKB0bN{Ji3~c+4JUAAl2qPu#7=ptlH>|SM zN;=jBK!tAk+Y(Cgzwt_aQ0>@xvF)w2vAuZlP;aG1f+``$qa#vQzi7Gx$ww*M;boMV z%)nbj^wp3JZJc-lsKQ?D@&RnDOjy392BxU26?Z(O?FHQ<#D`%!Cs$<-nqKv-vGq=}!ghEv$u;^!C9SpKb` ztlB7u0aQ7VFDB9Wgx4mT^PFY*s4458vCUwd>#GZB_LM8BT|c!w$14XlUMQ57W3FfG zomDQE2-mC>{?4M2G=tMoX21j6r%@)l*p@|CCtB(yh*5=f4rD1s{Uy7oME^luti@4n zi&bq0sQXPA_}WBOLP+&kV$GJV7KG-W!4MJ){*yXl6K|K)k*M$w-d|}xWgiCmR-PxA zi{BDZjQ~>x%kvojMThjlamNH6j`hMeu*{@|LwV`MUxDUi3RT} zrJwn8btztQWI&Bl{O?de$iFWx#R@3R{7)I)19t*IcHtMi;jdR|Q7r!v9gv)4*qwO< zkhZPExP{g61FMU6PsQY!g_;=XPzK<{;OxGW6@qFQFdauAEp(S4TpWPK#0QF#1A}l3 zHsH})3rfG_9UKP9Cdxif;DUx?nU57!r8d=wIbIgap$Fni|wqaze<5f_He8dVF74R_mGO>(WwtSVZs zDtcoMkHRBbxe(Ps371N~MUnmyzW_{#1@3M}{k|I`B2xTMnrwCm+~~3aaB5Fwd(8WaCoftVyGWV zH>NybVD!mnVlof?W@*X3Cp=%A*zqNq0UC=!SY~0|J3|7-7fUY~hH;j;7ot**@iEyS~09{F=d~B}p4GuMvD(umAsW|&; zE^Vl7=Cqokgk4nQt~foXidCN!3SORCs`iPX)QRx@#T|H1F}r0w+RM0L^2n22y!CIz zqhNf%Lm;)v^wT-inBO(l_fr+F zb(@r0l5!pqz?+-OrBuW)$Iy(oyVlu3&=Mx?jZEs-|zA zQ+nr$GC43fQ4YF-es;&LP%(2_EwdCT@Qi*&Lk$5sw%Spu(NpHS=<#l8S~R12*5o{p zv}3#8rFRwr?6U9nPb=(lw&~I(UMfF7)Q6_|!oLvpMr?jX53-icMm}|`t2jkKDj^ms z7wqTyhS>jLouBjyul5uEycbZfKt|F3jyQSas!K~z zJWol(G#$O0Mv;sxP*QC#IrX9?mFK#cg#B&!uLm}L{bJ&Zq|4ELroAR+zxPw4#0HDFuu$P|#dE)1?wTQZf9Ibp;Iq zU8;qr5u7xJRJ>0JN8Kw7PoMyBX|?Pc5Owh0J{m2NC4kaDr7El-6g@GhTtB3m2VBI* z#JR2mHf$>#T8bn#%5L;G84O6(dA<>z zA9JAOfkGzxsig6e(|2{0DCmo1lI^J*GLvf))nuEpIRDlw2KlS92ws1qx@`IknoSsw ze=)Atro#7(8{nAXHI}%33;y5mJadtx;MhkBU!d=tPm#d322$-sOZ}SJA883$I>u0{1`_G*H z|H0Kc1dGD;Q1;rkZQHhO+qP}nwr$(C^{#EBzv}MMKRK1ml3D5`du{W-&Tq(om-ljH zwm>c7%$Ra)CNY}5g=T7uIG79HL=UmMs1YSgavY#lPv$asXpT10e^($=!Qe#2iD4cj zj0+3KB}S2fWX?9d0*dw~`a0+ocykyRi5&uxQutDFmsPg$WynCORv(98Zmcb$F%t4j z$(QS;k-sKE|Dd($86$E7#@yPK5czX02;)EQ-EOAND~V|% z&u`tw*`r^tdK0Ih-O^z}PLv(~Ry?H|2 zOfwZto)K$IqRd_iFF`zYIGkmI<9?3SjXQ#WUkir7Zc}R7~O#FZeN{V5qxt-cMU%?r>#D;WJmq=7^~8 z3(VO(n!TY2Xs%9}vHC*or8)AJ?{R(92PBJoC)?BlS>4Sw%xsK4D-B>B2_`9$D^rl? z<%ySb1fXV@1r1yQ^_@e$i^BfB7s7mqWBJ7(r?gp$t~RV;veKZJBG)r?nqOA3B1enA zq(Ijrz2P3_z254*#W~oQZ|g>-KOk$0vrVmCVeJjbV>+04XvjBUfI*>7Y3inZkfHA( zHFWaQ<&aVMq5IJ>^zZRfp=Q3?yx7;O|L(2bOMgoZn3BxCpv0FOWZ?~OE2Z68c&MY6 zNU(5uqD=n2vGmZNT&}=h{a^~a9|}iJ%zj?n+FHW4b<-wYyi~M2Yv;Hh5eJHTdcl!_ z3jweEfL;vLl`A>jhJ-~g-3J+h8Br9zmJ$7!D4cf|dw0oYtE` zySs<&*rC@grbSWjte>bY?<5^#W7QSxgzhKrQdox;cE2U-(Y>d1JKvbW+)rA{(FJKo zx!UN4T&0p|zu1FPYGcz3x>?-#(ZZAQ)d@HfOo!m9`Lkm zs@Na0$KD^+!w=4U)T{E^P1$rZZC%PqZPt?UU#dz-9};TYVYb~B*QP#eDW%lbZfH!X z-O6lJTVBiJw3+0U($k@a728}8;{DS=np#WZQ=}E zThLU|$iJ1gKu+-WYuXV^5;n9yKyqvB(iy_TmNtmxPZ&*(g|lxR&J#W60xPkp!i}4Z zr>f6EoHm-cD$toTGBi&7BgeHsH~E=2RGWOm;%NOAE+AEv&2a#@d9z3Bfc-CXN9PS$v^mHeRB(O$T)K&I0U6;pJ^nkp5yH)dk>3^!dWIPsMIvQ3-iIgxuiZ{_k~&QbE>D>EI9 zV2!z$KCYk^r$AI6)1jOsB*qF-Q7??l!kQuPev zT7-JXBZ=~{>TmizE6?N`fnxljt6CC!#Y6kV=tYkSPV;+{B484>pf`0bF_oDkF$%lj zq-^S>Z0%7Q3>)YT2{j$`FAhEt`=E)?gcH*w;N1%vc)nA3Q`K(A713OLm%{-X57f;5 z3F#L8BhpP-q@70E4P1Y!mLGK~PUq51Lg^P`e^EIn39Xbd`h$2D?H|wl-kE3Qmpb3~ z2gqk_Ni(A-9MxkU;m-0T_w=H>#9lYa9q-UD-{5b+vF`+vYaAu#9LRe_^*r+rT|x|v z@-Mn|G_8@5{0W=7p9V?!D{oMdsXH9IwyZPeKKqXi5F7P`FY zgo+=ktm`ZX#v{|T$+`@+XZlAs(h~pg{}>gl!Qx8hNdo|ANGGP7}(1 z6aX9~YN0s#N350lX|R8{!`;l>-JC$Qb-HQpbm!jplzZoM_Qn5pxPI3e&)8PySv(A4 z9xm3G56?Z7n0|+Wfv1@MOw-;3Wvrlh#-F^a}F|1K*d0-EMQo z4?dlfIO{D+&lSzQxz-olTxQ2_u7#ntT9ZjzP%g~kyb*+=JqPE$VVFakIb3fh-ayPL z9h+&<&{S(`djrcR_8hk+(})(18{Esjp&3=W>6le(K+UP`AU333E2~wyX|)FEQ5l2GSzGJ=%IG>5+ANhJ521)r%a! z$F6X#0#u`Z?E=sx1>k~oU@|(_g0URc8x3%$QWO179o%mRlvAV;4|pE(MSleR;Osg4e;|DVswUNP;11Y*g0u}x-A;u z3dfz_eDZWD6m?@Zo`|qto@oYsVJXrqYQxBT!onRuduroYug>ywG86$BcEKT0_*0X; ze+Y)x3qNj7vdNLV7|4-ju@el3x5k}6Dvss}{gE+ZGpVN}tax2*vZBmAWCS zP~s%f4DH8Y`{HCB6tq^=ALEdBhW0pQMw@9uEHdWaa$#(d=`*I>&mA8nEj5w_(@#!GMMY#>6e(+sn;xz#A^ve@dJB6ySv;U zSpt#{ls_)JD!VE_wn>i@wR644*Pc?LT*ZZvB>xd(<}VpT3r3&aTa^7q=l0Juy;+;} zizYU*(I#qljPIh)0l5CxlN z#o!{wX#Xe%F*Tg^i|q?81T#ZvZ#Jv&Q6l4fYwd@qjo%Ewl79%#b%TH1p4E-+K@GpS zR>&+Mb71y(ZJ%(vCCv%HU>b{)CJBt@M zbUyn?gT?MABKN+=Y`*bM5hic*Y0x%PM))`1oSx(Q%axH{Ic6p!Ftk@1F$@?(!iBZ@whGZZsk1CL@owFgs=`O_b#xhbs&VFrG)#lz_<93q|we#~wL z#;AaGpt?3#SI|wz(Zp{KzmBa@=_vf!ct?*eJ{8&U|3vM6G`8ia$lyTzCP5Hz!tVvG z2nBrX+o{u_WH7jXKBlHQu4dY+hE#iK^eQ4c>fa(gInlWv$!^W$mVHq(l&E5M2%%?Q ziySSH?iPJv$1OfgVxm-Ol&)W+iuN_z^e8(iJCYVwd@ zDzoy$S>YO$h@*>~DC`z{k|^*^9M0#2##}WzJKE3W(UwV|Iev~bxLSg?66NnwY_;#* z#$Oqk>1sa25@jp@EGhP|FxiYL)M1Ij3pPkg^Z73!)`#h>=#+ zr)LO%vI|u~M-x41>!mc+<`Ds@!kc`fhx6L&HJb__!w+7ODB!XhLJZlcK-HH^nMcDu z;lqhNxF+F)z&R0-Nwk)Jbo}sbvVH+bwX}W^e~uQUUb91OD{fYO(HrEO2wqHSM`usG zaQy+z#MR2}<3waNRaln4eAtfC43!gNXNLfc0cG(Pd8AXv)1LxMxXdZIGTbM_=ESoR}fx)nxo?}g*nf`Kyt-G)nga38lDW zPQ5%zIy;#h(~j~D9NO6L`yJlPt#(gfKxgesU@NWFl1i@K>CigWs#?N4LbLEc)7)CJ4Vj{~9&3Q;Z$^%!D= z9O(y)fRB|6!)qnWxfrz``9rV3PMp4@v-U?ndoq^r!^EpGaB9CKqWWq+bx(?+EJa(% zbcjEBLw2w{ytbAByUq~n3K&enkPuulsw`VpKXEHievMd9C$Ouz6gvSRwz3Lv8rR+C zg35X~AmLdnD1QU8-QL$1i&Rk^x|nnY4dm9X3fWv@XZa@+r>kx-9417zw%%=J9Kk#nkAs5Bw#&{I`zmc;S>m^ z4+1>N&J4U%3~>GpIhB9(2bM;~&QEPo!-C_6{IHzOCp3v%D0y$bSIi8IOty|g`=GQZ zUdvnm{!)t+en$f!uYxW6bWYHtlnt1Klwyd~)RJo4`{ zNn*Nv|KYY8O)RAYabDvt<=*kx6H6x&^+}$bol3!OF{S#&^IV;0`Qud8k)|rmQ)lqi z0KXFNg4N8y^W|Q}6 zGYfd%t~Z$HnAf)#_+?XfhNN>qQd*EEeNHD_HSsR#_~j#HUwwLzB`x0`q-`5-$|)OB zZ_KIZrEf3UDd*!~LZo2lzOZ}XH^S*i!x-lZM&Y>-R8C97d0Ia;|bV z9TEgQ?Q&og0n|4?VR<<3Vf#Qog>*csCJ4}N4HbEu8URzt5m+TpH?a;r(as`w-`)k% zfdc|@W~LZi)K|BRg<;EbhRvI$gfuaYCA+?xQ~QWzx$_j zaOX@TN{*Nw$hEGC?^26$sKthTl9nF#JkQ|(R<4b6 zY6}7@;f$()Uy>m!OeBchV@2wvsv1C;>BK&ONJL(Zyu`hO2rL?|NJ7U+MTq+`B>n7>LuEHHb#Pn72qfwn$Ecrr~ZC|_Tjuz;qw76@btS!gzxN0nmdvfM)- zZqy7;Wo6)gv@kDdZg%4vk(f(l6Ohc!{o#6rX@vf&MvsFu`Tf0J2A@-iuw6xvUs+>R z_|(C3-~DGZg(M$QJ~4tKQzA(myMTa46S(c)H9 zKJp))BsxE8orC+QcF*>@CHHsg#aFp!=4wT8q)J1OiMA8P#U5Voh&Sh{?Lw-jM_)@m zB-LiD>$!}C$kw^c|6kh^&Zg2Gc{}{;(uutk)h5(SLRK^Me_N9oZ8l`bT%D2=BToUH zbokLoL+#vT$&D;jWr${GQuq{bPAAJH%nICPCrrzdV4@}o%ut?%Q(Xt1#Qc{-029uM zc_-S`RD$ZE2!2&c*sHW-oB3_)dFLYR$}z=z+((N!y3gD?*7&oe@r6r@G`?qVJzqXQ zH3E$3)STA&@%f#EXiaj9O|fQ*5O?!bo<%lUYDmRVroy0a3{v$~Q|Y?a%s4I$PL@C< z_{6EYWv5;q&f9+VeCl^|F1fuq^yO7JgagNAH z-!QcEDHJg90P(sX-vyIir1W*m@Rrv5s}#HhWqY-z={pw6Fdds3c{#Z&443RAM*rkd zRImV?-R!bO45N9p&2TzNDOoNd>noU~dx>e=r9O8|J+RHk*$j&Dvc0~W!{j{Tm7S5 znwNd|nrKR3pDGGQ4N46SX)U})pTZ^MSfncEG?aK^#g{!JS7ymcxhL=b-Phl)qlAlZ#Sw?c^Dmmc9kA=fEeWXJ!vI?ee63e`DK( z?kcX#?4~%6+WIlrJ=$^l*I{9sqrx`o`E>Hc#9p5H7Ix51Ih~en{bA?{YR>-Ge^@=Y zq9E=~dc4|58EevPQmSs{ncBle2X^z397|`P?O#NZV#c|W=_szJt>38{j&#NkNWfYJ zZcs?lc-7hy$4iI#b%^KH3t0cCygF6K*EqfKMjt<8GoDuyhJ zWp&E7oX&86nty21NGdqGo{+z5ZBWcUtxb{M)9U!f94wr|u53moW;ii>EXo5#P<&tE zz%A`%j(9D@w|h~WO=Sn*RhKqDb$%23 zb%D()*~MZFv7hKqclzvRT!B#%sJGxGS|q+swp&byUq5apK$^Y8lT9w`H7Sih0bXdi zYD;1((D0+lEPVohaXbgMK8YIN+3CZWHoryRC~gdf&UPS=*k7ok9w>Ed8(Q&HM&NOn zZ&%uJ?QPpPf&D5hTJ1A5t-oZ(%+a-!W6<%~`eh$p`%U>LfP>V3bnL<$)tBT%P778- zR-iy{F#24Ho7GM~#uqU(QZv77J-PU+I1))00uf{^-2s{X>9@R{9zB_xGxIG8 z+=P&jp3tW0<8eq00s#$F1T={t8v%_}0Ko)Zq2-pS$hFeDkg8~_>1fGb*u(j3F1I_!`Svcy`L5G=)G^vqU&_qm;yx=P zPJqbjfxM`hgUNgLzs&JX4F+4U)6Dc_EEaJWb5>nloMlJVbBa=IYVjiHwbm(NyX$Ff zrE#z&#{Xrib-K+VhDaQz7Qp{G^nKVyTe06|weo6?dlh~v|9*cv>PG0T*`n|kuUN3F zMVI62q1AUz4u=$Z{z%_b2A-)|K}XuuPV}`l_?Y_s3PZ=re^1i-$v6-HI_UFIkK0T3=rVp83$E zr*v4pVDUw=(WePE52yK$7rzJ6;~;dmg_A@0+}#!gBK_ zyZrNu&B7nX0U=$FJL!3(cH!LfP8`P`!1gXSvfITcTZkzXx`uHDb6XGW8eP^N-M*1^ zTR(U3|NiP8+Uz@JHKrED&F*Pzq&YASjO6K|C569&YWmpg^={}7&20u`0wcys($91g zO4F_WThUd6O$4{pH{}lxtM={gITtv_O#%%((J&58q{%aOv+{Ygy<%y9F zCS9NxNc!0Mo2dHye7Rb41}IrjA9>#NV)Pn0THe&p*V4)tOGM@e9^r1Fe{OS;u;3u8 zm<8+X%Su$aur~hW`eF44UAIAdYSZeFOXeh#-Y@Vwyue=86FOBC@!u6|gW2jZd@0am zu43ZO`%H6LfX0J`)jCq2j@fIID=dmIz* z-9^eb9R`l(hV#rB(trT)OaMG4EC2)u`C)`>JJ9V|y)GL3(wK_o$e!^;u3N&8Yky z&WN})?_YrV!s$jy#fiH>p+~Bgy*@@2oFT90^*`~vT63CF<>07wIY772_9ZFPUs%W> ztuVQrYQq$7w`$9dCG7OF73l{9 z$x!KRuzM=|&gpOM~_63@i2E#a_m}I-b|y zi#^{LmK1x4hsQW?KOD6wE@Yq~~+BjqE~8;<`~mifyh4rsbeqlG@Y+nKdi zw=*CY)o*Y@#x}BEgJTsy>q#Tf97Z8j7gjoU@tXZi;ukYzxwm| z^k*pK_QFe^f56<0b%90y<|sp@Pjt}eJ67ErilYX_#Eq)lj6-l)N?%dR$7RFXZt&bK z`!wyN$8==b!XGgCA?5ZO#sG^|oPJ)Gk&m04GZemJe|O{>EL~gXTm@ANPabyMGVBGW z%vFWQtI@SWQ@P)whrv(t+0;#slSiy^gIZ`%p6K%dCtd363DkuUGW-H|Mz-a7JO1}& zP#Z|Un%uGp8J04VLsZ^f!2B1D^#?u8cJv%@JeS4mIarjLJYS*J5+J!pefsS7iP35p zHvT%70@oJA->l|PJ*+Uu;@MTRGodu(*pIAMe+$jdZeR`L(w zGCfoVsGg2P=kRXh;$@76%4U6G#><&w+<9vG>}&=xK2sIZoWV-7(Q^4yszXsOiEbpG znda1I6cf%lI<`Ub*RR>Kp2LR#yxu%7_8}+A<(ZJ52UoR?GT|h~L2NW<5odhXTJ{21 z*k>hA{fBMUcB_XG0;lEWX^hpK4g%`B!761ctJUtwQ^w6%t(!LEDH`Jy1%-cJ!@Ne9 zt96sQXb)tQj3~ay=Lo-&BL8i?HDmrF+ZxRj86PKBkz9w^$81N(dBzo1sWToHP< zUKxAQ_z1vtw13Eqic5f3t3usYt|symr{MRi(tmHDM&TtM5-V^qS2Wj@oGOiTMgDXNAyeGggfEw>dkIEU0NRu= zm$-Y;vnhfu(Q%6|`a(@p=#9hoobU{Q_lPHK3VhK?nOkB6{LI&C(cq{#SwyZVa&D64 zE=%SwHA6o@ZK*SivpOhUU*zq5lasckt1WYlZP`<{h4ikPva94jBafnLrIy;vI%Q)l zivM6!wxo*JH+Dbrz^L;7*dOf#EgcToQrJoFY_#X+++MDQjsNp@FLdGd(6J{8J~1J3 zA}4-R!4fN9ykG&{%`@xLi#U7^YS}S8Ho>^PEAvj+3ibCaiC=^qvJ7nrB*WX)gMjSD z{7AYLg@eCwW1b05INc~+Jl~Q$UjR`p#I88=yG$(FJ$097W}UGu6ZeuiAkuCdF)&Bx**5Jc<}01kicX4W;4JzE1fI?nq!{$)%BJHp^UJ=(w;cZm8mJ+1 z0cq8Erx(=5X)jQenYSYux0OBd<;VOp(3=jGFvYziGq0Y?x(v-dvFN?JXAr;(!#Eaj5u-Cx)GciZy-OX%uy8f=A|`{`_bHPbZ-}fLOK2aAV^?m6VZ|twC!t?VqAPEF z4u%!)UUfk>@jR;{-d-@aJ@C4%c!yi@BA4%*$>g4SF6sI^;9NWpv^L#@5OhzTOWFltG=W>F{)a@CL{UrKkwrH$X#E39HCx*!b z^Xh{wvyI)7Cajc$&{AfwT7218!Ikk4Ra~SQV`qc-V}&{XII4lahq0YC@?Kv3y_1}vjRw~1!x*S}5LkmO*g%A3QAd8{ zZWQ3c=Ws1tIbLwp7p+8jDJ)Cz!XeeVK;ngD<3*LA7=OA2C|88U2w8D9UoTe@r-*2g z#S9-IKI((8y7VNjW@BzBkxWQxEKNY3j7;hyZeMbSqkPcvybPGZFd-dDNzjF>pNg4Z z0U2xWRcxpN8Ve&r6__dd%rkN!e!h%&Fb0kBPrf3?4{E|YQf%o8V2B+cydP!&K^K{M zCWB}}`?m)hv}%{uY-`bzgg&6c4&*Yow`sd&H*}%wrB&W0Tej%K{CLMl7M)Wyjb+mrpX!K))KQTwrr>(Mk9OrG1Qb zz6GjXpf`IbtP0jTs9jt)2kF{Fx89C5+L@uzcrVsUyQlfpo=Ee?P)MSItqe_5NF`&> zJFb&IyyOpX#1k6EFIy^*fn3R(KmkAS<{uCcZfKKt{#*fkf$*;=^u>O_?%x3LS3+M@ zrxWFrE^P|oo)9t5y5^DO79AZ^z;>k52+4!$agK!Rk&z>$lBr8u2Z}tZ7Kf}(Sc(`o z@#x7BluT&ointEsP`3rSwoYiZIRt+OQSEtMh`}L!OQlB26Xc0U5nlUv1wcP}v@ymh z;}q&&AqPear2<=dfo58~9E}lYXSc@gd5jbzLJVXUZIjTe1o^TTgMYK)zlwin^#_3s zw_yf$xnuX4_k+&l#z$?I4X}XG+tpelFRceRv9d>PmuQaWw#gfVHd~s7&@DabADf*$ z0{clw-KT6Ved>8gZ>m;2{rq*z8p?xXl>vHaoGIi^l?um-@QLz}iUPwT>{y_O`2JrOcx8%w-Q@bIv2cW-`1MF%}5$MmdmJGN5lyY8T|DQJ0TuemTT)@ztxbAiWWl0 z(RUcn(oRnJE)?@o-Z9VIUXD6n1%ss7qkw%ZS&}JM%#N=QBZJ;%M=o#rtxsdI-LprI zdF*w$?CS13_Gth}k}x2393&97u>irr8k2*TWB+- zt!{Lxit@m^aJHp;W^|kj5x+W4u=vQwzI!@Y(fe~ev3w&D(H}T3{>-sxg_X_x_E@5$ z$w!nV!ImWN!!AfgLqJbmiYg-YEfK*PB=a)CXd}lTfbx0f*&|OGJmOZ#vPa~sV`9H( zWU^8{8A$ZZZ@C@G^m>d(OgYJ7Iy)W82SQ3X)RYt^Q)CImetpSJGDqmnAEEl$?$!PG zx^(y2$^`?x;asD*ss~wTH`Jk}dIgNx`#ZZ_^BS;Q370e!s7TV3L}`L)mz5GU;PrEZ zFgk+7Bb_cy8luXhR$26G0)A_Yok9HAZHaVX6}HIP7jTYzDNCR$1Z@I#bR{UqN0yF^ zxI(!6z;R3;=0eD#=Mf&#J+>JSIUeH^iio_Fd#L^(&0foZ4|(s%6np7-sQzrsejvLv zzd=rLvY~*!0|XCjT$}Qd#c8#Ez5cB>H`4cxU{cC5}>aExb*pn}6~wn$*`nus^X z4+=x97e@~Yi=-9~6q)xuc0jK&Umyq#VI(Hp_P~$s+@@w4$>e)9zk%hF~tWol8(3qcEm2p@Sr(?9Utr;_{ZKSf~}14#74s{rtFXS7UC&6N<@8Nw0xC7 zw|upB1w<#uOHo`B*w#`~$)}W=l9C!bC$32>%&)dhF{3ckrC5Zq@W)+zfjFK>I$ls- zguN0tEWDELw-I2?3Q2^3P2*-*D_nwRl0VMP8BM3_0Br&2!Ib!3OD?4pH4!vcePL+? zz#dHv&7Q~9QTSm#qWr^PkNO)Yj^uc3iJJ2XqkZ^`Yuz)(cTwnrBKS*z9*`hDoB~8; z`eG#U2s5B|G5(5}@K{_+ZLM?+VyBN%uKSXw5-u&3dJ`{gm39-j21~dISK%vP=c@K| z^$WQBOBRpR7rOc(UCW79aw#T_S+I5iolgSjF+K<8@jmev*0eD`w=q7u^^MNS!PY*Q z*Hm@K>Zr2!-4zkBcOuOolg*_2WIn;%jVJiW>Yeqwje@!8+QN+*PIUi$hkcjx+0X-f z^AyOj-It;(m}b0V(+s~=s`&^=kMIjI8)o7d?H-A)@w|-#rx&N6>&HC6qz+$u*s*RQ z#KF27*-R#Du3GWL#G6prm>*0i9{9z`;cDfxi;gITQ8}JDHv` z<4ilT)#>AzBqKkbmSp4P)Xy_ZR(?ET$*!48U;ZiKAlIL3=xlyG!AYKxq5roV7__OR zRH$;^QdZ((QQ~4r1QTe5S?I}xwY2?oqT^qyGFL3zHqNfqa9ce_x}gZj3*9z^M>U<^ zI_osZ!r!d2xBr=b>%EPn@=8SMUHpSw(R?kvn{Z3~6%Mhbo@cuCZ)Fn`o1{QrVE1Y-o&4UCJY5I(9;!6YmF()hS1yZBUw zl{l~F{F;^`NN7J5eH*d6AG-IWs;5aeb2|H0FeJ=E80i^ zfXA?pWS-59gzANSYf9O*VkY|>`g>UhKj?2F%{{$LOGN#e*zqir-PFYo7STQJZIXNG zNpI0pHBBZwTQvAl;)0RlS|-M}I_#4_shW;w2q&1*_jprL|JX?3M~WY6Qe+N~%8rr0 z_mneBHy(P(Xyk>(<;iEXs1lU{v6ls^sIUml7c@A*o$q93dOb62TUE%=@((s4xHS7H{GkBfa6uNOTvKkiA#VPfnn&UPC zpuX`;$fuG{9AUfqb2R_h=YsxISU6cqs5Q;rPn5uI2AX9HN+x^l!Lexn?!csA`?m^X zVwkkMv9(OBTm8U|8?3VwxoR_x9AWx*Am!Q&8GWXCi(k%BR4Z9hI~it7#1AwpYU^;{Ohd9!={)?{|kXs z%H@&Cko~IzQ_Mc`XJW9wRu4!5r?@1dho!AT#i~yILz#-7Mc_%{FbhN2AlCKqKE6Ab z6Yo6;b*Y11nRPUR{w$KJHr(8a7#-g)?q)rAuG}P9k%inNSCW zRTQPNd##jH8x`yG0{F&M)TxLB3Z}q|Ez8iUk@84*BwhWPJ`AF=jfdt3BaQ#IKLm0g zJ_x$pH2i0My=Gs|LRRphca!apSp06;U=ubZ_>>!T$_+Z}4wZFhl6|%^KTFX`?8^mG z5gxlO`JA&TlEsSXfwLx(D6(U%M&7VD$?he77kK2z(d@rN-MmFPIYo)&uF2V{#wm(X z4<}$mRFl)=v?j}?pPQj%8g9Wxo=nCWnj9?S#6uolvZAmSE-|g0nCqA0$5|>i(wl-6 ziiAf#ReG)dP(Xp8GLMC__kNV`1qDk&A%Y?fwnr; z9;kG;;Pio~OB}y6`&j=>aeo!ylb;7jfSdNmT*)>9)_Ti=flEvn@EPYDp55a;sj>R$cY#+Rii+Wai}rK00*`yk0S5>sSsD z!~aBJYl2<1xS{Yx-CALSEHO)a|9rGd6De3}0gRd@{-$u&QN7gpa88JY6OR>$8{ml% zIv_->ZkEZ5#|kfnR+gHDU!jp#OW8VbZZ-qP>h6B^QDaSCZhg)*LzxKVIh$!POZXctD<}1q$;rv2wSf%+5(R8X4?a7 z1GQ-w4=&=TlWQCK-9gH9Mys|Q(?`#{5Z2Q~28S1n_y-C5Hrvp{%;^@vu~RFk3N_o-$XV^(%0pCB}}Oe3w;r(vEW5x!Hd>{2dxzk+NL$LWwjFzmy1~;6n`VmsHfsZYh`Pj ztToRj(6@Epu|;uFuyrh723Z5t#q|93@fasHv)<#uqHjBSJkmS768l64l^!&U{RXGl z?&Ip%+_eI;VZ1w0#b}%4ko~BJ;WtJR`7Rc@sH-QgrvfyG;F4~(Te{pO?QHhv(Gq+6 z=`$YXy6#8CBeOZyZB?Mi^J>!9HS~5`vosZFUTpnUNj=q+7S)tCM4e+m+d4lIu(~uf zK-C}o85m3)fI=LIQd}VtTc%fqB*BVneznO~L1r!@Ux zoJLfn7FBntvnX7PB-yG3qiQ|E(K;uw9LrEP_|U>aXj%$MNi8d(X(==%g{;)aLRk8J zgGV~1F-;?8UQv5#C7})}tFWCA1;pKNPSXLgV3z&@f?rzyl~-^s$Q!FR!=}L!*~C{0 z_4>U+_I;DHKb2K#46nFn=;NaJOgYPNTclVzI=pGFzV2cH*BcAyaIWjD?I|5nLTgn* zJGBJH2q~@2=JQJPy2-0UV4!KM`*z)ily)PHfkb1dIp!L^fm5_-D?)80N{tpz$`q73 z8iYEmt%>sfG8*5gLT_Lv% zf$D->tE?aHuq%XKt!>%e6>F#1zRY_G*QLKJ`L!x%rL@m7)VNx%+(5E`Lj%bIE)6t0 zm?Yr*|I=+!K)J?qhlEA<8iJICT`_~Am3%u!qC`>Rb1Gt_O&91gh-i_Sh!F*)+LjkEf3{2l_}bdTXp`wE58 zU4u6h4|-T|yFgsdkroQ2y(~lcrxpm`kKzW?^?vq~r-W731b8(OrkA`K`*_R-D}vuE zK~3GbPuVABHjf=m)3ci{YP0vh)gNJX?m}2*8nLlqda_ch+K9SyjwJTLg?8W*cYzas z&_rGVBd&uHHp4AiyfBQq)2&vBS>P|YTH`NQ{UUCRT@pX(Y(+o8UO;xMv4aMbKAYrOlwJ;S&#X z^d&;jw+}h;rbpdJ(?U$KC1vbem>TsLMyj^Ere+~cWG7i-4>&!6`%K*p!#8ki@W3R| z+||5G6v&mdIdWvLzL74rvHE*0Qit|oCEmQX`8%2}G<~-@_Q0lE(QSkJ*Eon$eBz-y zcqj;)LUFNIbBniMX2Usc1iN`~_;0rLS1`$$EXduVDYeeObL1a`Wv?rEb4y@WNJdgx*lR4_m7k z+mR9i! z_Imjrz}!hXI)#g6eQAg+6U}dFAt?E4D@n+DY7Gw6D&5OEK8Xv7NVIdO#?MB=k;Gs? zW!nO=J*8f+LB*d?zjq^U#Y|FRT*04wWuH{V9#LV0{6YHC{6F}aNAx5TEnR1Nj)}2n zH-+?WDvqu|9v#dgLzP~bM51JGPzpn(dM#c|Rlc&9xRxUXTl-sk9a|M6@vrNW&N6vwR9a z@lu}5c`m(mR4)y7%uIhoKgnY<4QxZxbzsmZio&ys!Xpb-g?zc87nJOpvL)9e`gzsD=bB~!q<+&JkivVCE1C^W8cq6X zW-AD2mfZTc|HVp*xH3)LYtf(5-l15Z8u`-+$KJVYS{6muOfMB{p+|n= zosU?bw~pUu-xBroI?e{wxEdj7*S3n=&dG}3yp${Lu{U4p6)1}keTkzNVuv%D>Q%F4oSsay3-0O_X^R+r>8ux~ zZqe0+Rd3G!A?zKZMGJPe-L;o(+qP}nwr$(CZQHhO+uY0c-M4wp_m6QJH5=7UQc2B9 z-lz4-=^V8u@Me+f;!jT`?D@)5vaV3rb7{P(x9-^`_t3(bOYea>#r28~jM(P_Za)Ul z0DGsd83vabtPNmyLrzmD>OXnhqAiO++CpdiY9UJ0gndnIG_6{hW+@c3&{pr2I?Fcz z`S;h%b84zn75GO33Io;khu&MT2)#q22#C7lu}HsIx_J<9M!PFSst5i=Ao#aSHFF>D!(#?S?x{)33ydY>YHOm4pWfmTk3x=`yy@c%jgtZ@=Kb@3EmO0k5v1@(k#|Q%@6~ z`l0p&x2Zo6h5ptTXcdGP<<>%fvJ#3T_z0Gz9}mV|9K%rzEc7SDMrCarV76zNAC%H* z8u3|+VA@tr0T@iDq-H}bp%@DQv(IqbR$iJZuqDqW3j~qY&k$XV)0=JDALE&4k<^$_`!7sxp&qfC-6;9W* z;77QVjEj=VG-F$e5*h$DDUb)`sn8KG=Ec+$rE67XQmn`E&Y)y1N+|7di?gaDG~%47#pUf?fFPn3m#5%{2z%?>^CMZOv1+z~3I-%V5%ETIja7-T?^@JY?JSlJWT z&B7Wq^juzQ;^ql@!@Do6d3u~iq?xL2ef0*8g>Yc4#??chW&7b$*!AVa5~|@UPixIc z^0wsUA(MHlV2W?d0UpUFK4Cv8m?_~_moW`1p3w&6Dt(`H^O!#^VTEq-@~5Tow4jmh zbjp01WUX;43CwpXGRr|gcA+fq#}EmTB|+gb5(K`o^@49vq$scV(K~(f(SV_vy`2K) z`XL8n-Ce6*YjxtuhCp^84GqOu!FuvA4HSJA9hjog-tpAh3Aqr@1P?sK# z9F5#O3q$F@wc{$MFgKzc*AV%KR|a(xWp5-kuamc9Ud(}dFp0*GJH|jyX5D$KycSKl z7EQ%ac{TNM_%xUS#W@RZyQRKnKY@!x4-zcaF~r+D^~A z>QA=M<)yXD<51y9l?{|$<0qO$=oa#%oFU`o>JC&r@P*QmPCKY%6l2WRl%5DlPmIDJ zGYeXes)$n(`_3U@Ue^#M%JJl!&=5e%cDhhDgIQs}GLLP_J>{yhAh=08@I|>8mB{J@oSW80{fZ~+hULk}oHeP9P*KHY{2Vr^1Tt6`taUPQ&tpIDHS5A# zQ5&d!rTUEEiJ@;2(SsSf!wen2rttCU?VX@*e3HUmW*g#LXj^5LUwc6HF|*M~+D%yG z;;^%QKUnP}Wz2AE()5?#HbRjhH{I?4emrEPbga!+Jd?yfQ(;D4lRUGmH`Ow?Ff1j& zt@|st(seM`2&GC%IslMdULk%fAh`kb8QHe=ypr3C;pfCF?3>I-Z84@QYMf58=`-5j zK~O9oY(rbw2ePHO?yvl-e$Kgy2SFZd`D|QVdW_521*~SW=17)`%s%xdyx^Frrh|uQfgDI&rgl+raTxF3&M^LU#B* z#X^|j0AY3}eYZ`K>FWRYtR=@#`UIbDTjv{ zN{4&NBObNjucH}VjXiEiK3k~Z#Og)Z$dD-G>V@4_`rC;pS3^dp@NI~zB7MWZRyt<` zi0Brvn29Yk*%`NKjiLkkA*`8)5y*cH;f8$ibJfrO(NT7gdIb-YfLy!>^9=t~$nsn$2kkye*{dAI1b8}11n7<`PsRTOliC7?l6xcj_;dVmJi9}z zD{xH%Mb|&NU)Gt1y2O7G(07yJ5YI7Iw916?mPpzZ7T}PJcg+pV=Y`2}kLTptE32J_ z%g^uy*Y-#SWe+1i;1(mwKC}2I0fBk@g*Q3j6u$|=aGTRUbnb0Yef*(089ML z6U8ZIDiigj+ho0s@lxfdOpzwbGQ6TJO$6hBBOU%Hw4Iiw-f|G_OEH$|VsdI~u*{rJ zp4pIMa+0V-R5S9185VMZRAFd**3>$~ZglgA0QEA>%>PTholsrAc17jKy9ilj?+5sWORwl`Ju|6GAU~ zAg=f%Z0Ku#Jc5MgJEz^ZbEao5u9q1=kT3Y{nCg)TqGc*inj@uj-B|oZ1TL4H~1V|?=(Ka}=U4waXrnCY5$9-FF_#1g!&WTG2=Em%>7xfitJ6nE# zPS9%-fWio*X@qCbJ|GRa6N~naBC38}&WINJ4o>YHgBR-j<-!1!J;TiA9M6*s|L66Y zNmYS4-jB3fjsv<2FCB<9o!E#Y0XPTFgnpClqthU^_5CnfOE7mU$8lTn9|T*`t&Q#3 zRSrBt5AQo0$2LzNt}qTkSarb%n&Az<=9c=NQUhJu0Cl!aor9dc(jD_%uPdAcHp@=|la>9iz{Vp@1`q0Y_YXn|oWVQZUB&tNmu8;n_tB`u=d+yjbe`{o z_YC2;PFS+<#^$>SGTaN5&n2|jzp1bQEdd8NVshrl(5{pMI;CQ`E|eoaJ*+K-wZMpx z^L?mu{ZE_>m*YI{U4yjdX@ei{ZzsQipt$+t&Fo}cyDvnC;F;vLDv_9ascNT0d7MKL zUMG#*x;=WmhJ$4~8%mPW{Z&0|Cb2NDw5_C}&TKf$v`;Q*mWXy*xK+)h)3>{z0wE_Q zgUWcWT*4cPSy7-w-g&S8-xm@67>uPs0dSVGoGbF&Yi?u0%@RMrqn@5tgpaTUV*VSUZQG z`_)?O5OuLudr)-}saSN_v}{>1C-oRqI#B9R==I(0Tj`@6(xv9r&YP)$t*(C-9?b*( zG&7kq9NUr96gIQek7k8mEYKr-6lk86_+8bl|SL14Hz}8lm zY}|MPtb=L>e~#QhRyxg+Rsq^bcvq{UF(PV~{tZ~ntGR@B;1qrTsv-PR;I?ELi}kG5VT|Yx2m*Um^^)`@ zQuZRwHy&0@ym*bx3GJc*-JMxqE#9kHHVKXA<(Rpb4ehXqcw+RufISQ+{N=(V{V4~R z)h%lu&G|W!MS6@__KE;3tDa%=o&5Xb-`)4zRZg5ppZCVV@^skphc{^gZo*o%IkkCfhT!WWS>~w;nC%qZS-)mJmu9tPAXgI+LqFILgqPZKu zS0c)m$c{NhwO9E!C{tH# zgiGpOLAj-{%7uX1bExH$y{FIC5g%4-18l!*cy6zzh!154X6Zg*3rRnDom6k>U#b#5 zV77#hak=|7@Qo-*bdeX)a-&|(UkJ`;rAZe*(VguygWqptX%Cj;fjB0~@avd@5AT6Giu}`LfAWSCGStYTnFGweBHmMw&LbA&V7m>pp zu7!UM!P7N#M*Roy0PPcFTrc0c@X?58UM1XvGWjqM$(yoR+xV|WQ10AG8)J`ZEPv$> z*vmVJ|NeOlta}JtQ{*CVsQS9%99T5SDLil2M`r2`1K1q^2lrBz?WY~_{;g~cW#>8gJqb$ zQM`i!Z#F^zlAzeR?Wuxji}__b6y^#+-g^`bRjjc?7#|2r9EM`M*hFOML6VKnx6j9~_ z`gh7$7M18l=PMg;n8oT38P;491)1uQ$BB%r*-v+30RuD>85+pld^R)M>-#AhwFZ(H zh~o|{_8iMvtv&X;CaiK5T)4&X>QxYi4`6gkZ}RnXQ1MflwjBUCCp<7u!iN_G<>O@e zw$vhUUH0q?s6r20aH`kPxwf6VxV0J>unrEqa|;U*sk|P1GN0c{kgU@~{9?VaTw{1o zcg&GGY~Q?t);M)u5e1T>WgFndm~5{|J_{y3c1ke zx+{Y7uD5cBKV(k`fjl+Ls3K-`39`{aIF-nVESph{SPmiC&q?sal(j z=HG8c8Mii>-^p6YIn|?YBNLSg#=Y#zJpB$#Jx?^h4YFKv8kWSQ+vL*hTqlPLOY?7? zc5&ZM@kA)*=3XSnsOj3wwvb{s0+F6N!&MzgkzJGJrLJsH54CyvTSUwQo3X!LsidB3 z3(mKgnHM|gm>YlfjhliJW>}95M7WrWEgHuUN*dJ#s-Z+Z1?d;9uEjr7-}hK#m_d8a zoZBBGTnz|uiATDCK7M5>?|KD%x^WKXjDUHru%4>xt~Jmo!JnaRY57^Qo>lb9@^Vg~ z;kt#nB$PQLS?2JO7_|ophG6l^y!?&EXTVG-d3a&>xY(iRG)q5kR`WnW)=xuquYrns z=}52j%lz2SXNHLHT@8r47zA#M+THj>8^b<4;pX-00zwZpN?xz$i?ffRn*+HgI2J(R zwImo&4Bea07kx5pOf&M z1%El!&a)OoH4H)2<;Mf4~lP{a#nFWsgq5Dq(*qzf6BT_&BfPNr=f0|#| z0M2%H)=qRT&KA~mN+!0(G6ojbBJPa;n?Bs4IAy!UkIa+Ao-vx!+8mNNpDgCVEU^?C z41!oEgB4tvEK~V6$9NN+gS8Rocu$ZKut9&UO1zsy{hlJ6%P0zUAT{Kc$L;1Sn+os8 z`v;I8YK@%{TB_iTL%;}eQ?`g|=b+Yv>$-fzfSww6>N>{T0%i+Ai1Y~^l@qR7Om(PX zJ4lr6$>w#RRERbG2_xEP4@(JNlmG<|6uP6oWi*k%Z_4%h4mL>bz3cn8N7+l*atccl zNh2E`KAp@n#j*}ykvv{Vw?GMyTc8Z26j2$GoY-8WUwS^WpZNjW31=(imF%eZ>9x9- zXhoqr;N*#VPu1bWJeY_}pWOAw$D9+Zh>L;J;PYwW1U-iusePG}NMhYu4CtM{nTKs( zoorGJ($7rVI)9)+A}aP4L!%e_=HK6G7@&ZvbOUnWW^d`KEar|YnXiCuE2|ejWxGle zb~(?cr?%sZDGMkU;_EU+J@KB54~uK2WeR#B*VIBhWT%I%ma_D!1~PT|(_%)cN#qoc zBI%CS+D4a@9r=yKg2j^T$+QRMJ9Rlesh7~qnZ1F1I)(i@`YAo5gg$|Uz7a^iVM@O^ zmY+W^KL|2E5Nq#d+oyW8|wAdkv=C2T>Y%gvWL&YB&lNyX{NBgEvS91IZ=3cjHq37AUPM|<_teO9i77cv_R z%q}KZX#eGVd6F$-AOHYR(EnF)&c?vnTG_U1$n)rzL<3a9FUy0~paNQ`gRo!|vo!uXM z;08frQ5xNB@Myn3*i+nKo~259HfDSInyP5n+)fk`%=|Zmw4NfP)iK(fPtX?|e*Kwu zhxlCt8o_6QM7yL+ksDrCn3Q-~0A?o~;nH@s8G^)KdLE6C%00R2mK_Y*ps_(%mMG1nJ zdR|BH0d=$MfKF;atOtTphX^8-%xPEkowq1EL1kAHK`B2~mFb$42wOtjrOu)~R-)Dn z2K8svzW7jQ!b)<8y;jjE7dtg3O|>v z#Dz1Wvx>x3hDJq3Mg|W>oUEFeU$+$=?H=TBu$Jk zj;+xE9H&Lav7nHss%8wJw6V3vmvBbCF83dq4_bt+*4%VNsr$mn0!4cu3!bzt>y04A zz(c93A)M{Uqgt{VTsF+q{UM}{z4iLM@!AnPp6kCp*jF8xif8_-=a86%h8Qsm zYv!5S0#l5deg~m&S{$qenMP=1K+a16sKWIzs52eW*Xsjy{j!?g>mwd4YS)m51T+uI z+#gh$zk>X}kn2NoMNO8}`guSz1uU0ZqG7_disPTi@906{MSs8|R%Cv8pzq;1P4Eu+ z6e1+HO%N5Jy*xioFh>2`d|{LX8}7@(B_pQ+XBw}84O<^z8pg4Pq*z6j{njR zK9L(!?fTzUZ2rm2DaR@V@je&Tg`7=zCJy47$<99bs3uD{m7||lM2Zok!iVV;A7J!} zOOXeRd;@^Udv%9P^|F(fe73#gJ*F(_9)o1Zjj2(Irxd85b>KZtpj1z$6tDO|o*^&N zfpds*st_s)Twl@cuQ2xliB=GOfbh{#Kvy`EMJQSriEm<(j+UF@J(N~`)5zZP{|x6^ zv_o^?%54JGh_tJJWOT06qO8Yy*K!SRP2&dOR7=CrXIzHQWJmF zC|(tnTt_~xxjKw4(H`iwI4-IqU{97q1Dk^>aRX9iR_KpKw|eq~>Qv$7xT%<{WO3X# z3K|Z=QWgw5yld_;J|#FYJf_lttU*OnI!z@eG@y9j=Ri*q;u2?ktv}w|WBXxV{+aI3xA^O~9tzxhqCCf+^>J(V%|zVo zT#6DgVpKH&O@Hr+*{-ZShyf!gyKnIO8RZLy_5{3rU+yu+`qEK|6htg`LEK%&e8dQX9X8!DLEtsLCZ3|LxiETpwgg&{#yL?kwA$-}{R$AdciGQNHk z_~))AN)XGeZ7nrwa9C_Ii89(iE|WC= zE1OsAX)4fSA|LxFA(lyB7GUR7j%eb+$+TV9Sfp;MdE^Z-n6R75)0WjD(b*i~uqRmI zGhp&jpD8baFQ)*Qu?6DkJevh~d+&Z5Q#A>}Wd2}_h>INUwWc7~7C?+0PgRqZZgoIF z@YWsx%PO)dQUvH@?2h9^Sgp*5DgpX3+0bTTm<=bKM>LWwA2x@=Ix}7sN@$C9RD;P- z5(0+3xU%`vcQQK@QRXvlM7L;@|AbOg)*e86vfEK5G1;7L+FHPvkdqzPhL1U7z(S|^ zNF>DCZ1L$fnj}g621+6=nq<9hgf#+@p>b&vysAjci$9MaRr5bL8&Pv-GvlJH(bMPX zG@wmir7C|p{xM?2(-Z(4*8?G;WtB_O%x>GiUSU({IOqi8_Ni^aRpD*{^mk*i1WG{37g5Z|4|WbWaLJMC~0F6tzUOXc3=BigPDPUdz7J*QJ6 z39Vh{`~tZPEmPANyUYc!8}Gt`CkM6`c1a^qL46S&+;&#rDgP_zEr)`j3>jd>-nUjU zIUipKzjsb)8PFtoo7%rV+IQF1cZ&k?<{h`ih&96<*T@iKEss=U+I)v+bPLvgYh*qK z<9tZ!ynTu|OBBicY3Fq9_+`m6BhS)<1CP?(Z;lEJV3GnE=}Dmn&o+^N+0qz-7kKTJGYCK4kOGy zBQeg~rd{wKTsZo^?eBha*RB@uWLq(1P^MJDl!XrlHpI3Jn@+dK2&>h7HkuTH5a}3<14}@piL#QKJrH`TX z$v4*dXM>02f2#BikVHVokO=z3QIT+UXnCq~vp)vb-Zp}{uY#ze7XLb>7I0>dIfs}rOPDfo~!XEdbnEK#uM88kk` zALh{%QVXJMi`)2DP@o0BZk1AUZko=-7Ru#g(2ZDzShl98`f?wNhMp3{OH~t)b&2@^C`?_E2 zf&;kOZ;b*J(xFOu8q%I3_D+?c;dIn1*KPx&#SWcR?`%qoa4+N0-_JN_P%dgPE?(Rj zd;if14V1<>Eke7WVo#>@PR2dg=SZ+* z95St%+P5ypIS4SC9fO`6-n4enQO20`gL;u4*k(qb{UkS>6n4R*olQS4jI(ej?L0oB z_6}7fRuZVUNpLy57KS$~_HL)(Zm`cFb#Sw=jI#! z0&mfG35FWj1cw@U0FSbxwvRXk5t`*2I>?hh)RRBaQ#jkJAMPs>c=rc}$AQpnmBCUc zz?c?Q6Bi#4Rg-`$o3tWdnsuSdJ_t>D@(0fNu%su35K^QcCXCtCYL<0TC;b6J`B{2- zj-wy*xmets)av{5pHAff6<$7p1ptu5@_%FB+0n$nM&;lA|GymS|Dp3;qY34$ypr=X z+r#8!Mw$dhkOu!ik3UC@4uZq1pUgkZkBB@-lrM;z1P`8(E)9Ty!Vq|SSX8?R8M(Z^ zNvVlt=wM-GWwWw+W82lY+Pl2DYTIUuw^gG~|M@-F!;}#`toMB#Xga&?b@QA3=(G3h zGE{}<^9=0IaVZNG8i*4my45A+WoUC|r5L#2k-n_3czP?>wQ_$Q~P}Jh=adaxK zBt4+FRByC!Qe~M&QBE1cKQq{ZrK-GIQ+`$hB6DqnW7FUW;&fWQ0+}naa4HS}SpeUC zH$hGV48F_uPl1Dp^B2=zYU78V_5j|$oGCpHVEn`upLx)Rb5vQ(2@i@>TmMJPS=BD<@n zie~gt)4Q}%(r9gdr8(j_+7ldbdvUdZ-r#8|K2sFL$Oq)zqMH`=Lbre|xs!2qzPY5d zKq<(o;2+mXH3Twbd*S}j_ZZ$IovMsWPf2PQMq}4H?yiiWk-mtA2C_-CjiJg@T&#O} zb%B#loMsyCK$}{g9P_)PQUUiUz<4Z*mBm>Bh{K4w%{L)L%A@dYhRU;(jpgB7A}O#P z7^SdW1QKbCzDbi*CDa}xRX&0T2eu|RL&dQSa*CQ7=ai7D?kZMf+?>U-eJ-@NHuMUc zViYd@Sp2a{w4)e?ZY%}0HXLj9L6^L=Q%F4^MZ2%0rYGk!qr-QBkVfl6yST8dgk+H< z`;pt!NG__J9&=~XgSeDSFjP57o+YfUi;w}TN}HTY7!MD~BqSsT^8G%GQOAx7M+qdb25tZDYgpXwFgZ2{mZ<3k;S?HI4}#L(GUaj+F0uV%8@ z_G4SAx)wd@?W%aTP1{gXQ3pS8xNutUXv~@h8DDO3V5l&`R}P3=NRWXrL3ea8^g_dh z6k0D0rZM(gAp!0{Ayin(Xemjkm4($z)yV^efx&2J1$I?8BP}qs1aBru=X=*S=ZLlR zod$A-NMgV{dsq%8^4TM6U4un+1Z$rV;7+>W`LHtJ!i6%Gnx##)tS!!Afzc>59-@O6 zb3!8JiI@ss?+h+VZG{edhl5E@-(_UgTJ;8RkpmBDu2EIbjs_iVADr(BhE1fUS=l}~ zW}C~4^~OdUGh$r+A|4zDi4=wi%+y&x1e}E;8AMJ)9p{Ppd4#KQ(Tn+;9RHFzdQriZ z0_lSi_})-EO6o7+xmeQ8W94*fK}9(^YLL48jX}4>2ggO?j?ZYkx&(5tt`iigqqh|r zH-hFno>Vd+0XGMs=zuF110yzHe8S%}gqwrV>jo7$VlK>9L?~F{tk` zZ@Tcj{W8>DY}7?^Hd)vMv$qcNCLY9#WcCi_{F#AXgJ|fbC3TkAkhUX+P&SYLPy>v6 z8s+gg(|3V(U!n1&lvMu6jY3aoqQ|i(kcbiAFEAyE#4)&lgLGOdWU-$)_#b@SE1Ov6 zm*&_DR@su{F+3DVNHI1~5g|FZ;_CT0KBlH=8?lXTF7IE(jIsb@xg?_@&?HfieFT0EzJipkC65Ghlp z2!&24s6T||V_azk=GHZB2D=@Ku1df^R*)Gr%je|DnV`NcDeIJ7nWa_}DYMKZ6_$i7 zL*J<9mX}dBFfYR2SExO6UrMP^Yc(}G+UqM@>q{$LRdh}yA$G2#dwyzQxYRQxj#)Y@ z-;0_qkRV031#+e)CwB~0#G*%Q)R|A20SZpVk+>QoLvO_2yrme>DL~ zEKQS3a<&9q{se_&R?!yPD`O1Z%=6}8Alf2FeR_jw>()hCUnko$R68m^E{q@Y>mVwo zNw&Vy``e~Kp%Ao)R|@-C5tmviXK<>dc1v%D0)17|!c|b#tdzc(y9w7)LseLgTyllT zjjR#fRbwTx$L^)$DNn7Wq#8Ex_$F@=v$U5{1LB)Ie6OjF+}29pn&g zX<#Wndj{zs=mcfi;N%RtVhtHTtItbqhKqP*mZ1Nr-<^WVm#~K3HCl?##;UQ0l;j?y zRq{m{YW382S~?sYPKr#SsiCT>ttyrwtXNj07Ds11>5JPWf?Hn@w)7B{vsSrE*r!=s#}n&Fy>TX30;!@S*lyos6y6$ zDc5=j+toOa99jTy%Pq7WP?mZo?b8y^JW%thU^0s;QsExj#Us`t4de8$*MP2#esN|I zp|whCW4MsmP{18FE+tD!Sn$`=y|X_~TjTno-XDkaI6^vZdwi$x6FjQzPfJKtxHBo{ zt;&-+n`5>yBK5w+DAwm>e8RcQaDad+`9j9pEi@X(_FOKbmI zxH+D~JC%{>E;;SU^!Gx@py8V0axB~H%2Q_LO5y9$A~y@c8@ZSF?eP&8%bV*rDuM^i z0?R-%M~n(BF_JNmBX6A=pAyZ<@5FkH?zlU|^Y@I)>fe~=FNx=xWZd9(%Rrw<^T|?I z<^Y+`_7w-F*(39pQ}x+xL>{)We>}ws1w4BY zI2ADf)q72zgq}!l8+#A-hpn>wy{bF`V_t@ALdZu6vE@5rU_E z@YVwe?Jzn+vJVFy-C-Ea?J96`1E+zOaY3AGM#2MhRVU)hFUD1K*(HbMRqtR=z!yh8 z-XES|LAU1k-qzSW)HU?DXYbWT%Jk5Fe7t9k@g{qeUn6l)S%XqWS%b(AcwZyYa2Jx= zQv*@TW3t+1v~;NHs5m1bo&(;{P)(x0a|I#zLH; zrk5z6<5Qtpu!@%=q9FPtvP6pWhg^WLas_lB5CKZ4t@kgkk%hX31DRmIym)B^92-0u zG-$zQPaLMWMc22+(2L{#&fKr-augSw-?p;doO^V{!SuRdFMMDN)?c94;&|K%Xkr5GXv9tz9XU-CZECsZ!rVUEyM>;M;2~(`~Fo|b#6{& z*7d{gx^e=mKSO^p-QA7j^0-y<gcr(-OeXR#z54OB@3A7@k95BvXIXO%b{J1Nc^)6*p-i zoA833~UQ;Bc+wSpzXk-5CXBJrAO4&2zHOXj@zZf3)SEFv#FtF+C)&rg_RT z#LHxzVbF&Fn|`2wBd~23s^ne)*Yge*PYQd$LEYHSyVjaH#Jly1tr*)smuHZ--Qp95 z5Felpx!H^MZK5m3uAY3vVxz~G3k%lWjZKd$Vrm!p;ElWI{2RWz#XtBj)IMG(5pMOFrgB=&+E74uV8f`$Q48 zl#MJoz#tP2DZa-axD6D|-(LlM$Kvak!~4oZdHb2XhNb)t$Nsrj{^VD-=qH`hD}nYy z5%G&bJ2s~fq{q11GjjgKO7xd2d|z!n*li(3PbszU0JCpI#vRVbyTM~CjjR63_7>TwyMmqFPQ zb&HwkQ6SG^}5|>nDbvZ()FJqafh==zIERQrQ{<9n_sB6TCi?nPTVysimgH^Tmf0U z7vw2mNGryfEnS4VwUgXkhM*}~+Zj(PWMtxLAYDq_MMzcAw(miIBpX|D2 zd%k^mcI+QH-;iG%)%dl3s%5J_)7)L@Hn@fHhm5-tfCY*gWW^1hl40E-6Y@y(3MNEq zC;9v*hLw{-5tCycl>ku78tT=M4Z<=4F`QUe%gWZuOY_C0MM5Y>U6cc|ELd!h8(hoS z+aC)rIXwt8kfY374wjk&hc8X(diRYf5DH>B&g2>`3jdsk2Q|;Iut0d*I>|c zDsf3WUw)g;8!0-ezdiwcxruvTM-z8}eB6DIFG!dl{Z{jltZR;mJ+L{Re{Wsm4$$~yHf%6WCQdh0_uwUugLHI?O8&4!+`Yu z+ZGF`E9C{9(<9x+N^HdW&mw_nIyM+Aa?LLJ37NB$x zKW`C#cP~i$84`TWJEkBm|5=2ntVZPSY~=ICwv)JhkgY-GgbMj2cTI(hcI;@a)4cG?8L6HgByEh94icy_|IakeJd;1K((OOFIr^Hprnk$J}OrFjaY}&54yD(uT3rK zWU_N`Jns(-@L;&Q5`i*6_2sxIvYCQbhXsk~)y8wR&Y&djq_m5lKE}kgMz# zvif2kSKRC)K4>Xds@k=CLN%W`RV&!)Rlnn>zrkU=U7I|U{(eVOT%onA^weZ%7GQn# zL^yiXoeH`-N)?v3i#8c9)~#8o23J_lM5e)PThBzs={yt{Bl5!i#I4v(#_MPFk<)OvFqCZ9Tnz+o6f9iMjz!s#SD zRbM=lx`v&(wm$_j;!l9GqGH|=kf*(?eLh2URq{TpY8yX*?jkd#EwlEwaU0otDI7+ZR2$zck9WbVILMo?`G!w9?-?WWZ&g zGGHH)m*MEFm6_nQ9HnLVAcIZ)FWw_Yd2O0-E?-~WWMIPmg?S{_PY5XWf0MRONp zy{GFV6SpjFMEED=u&cTrs&Cvh7(WH@rpCdzG}r zRzDsFV7%o3oO(I8*Y|qfl40T?Hl`BH^(@b_i7G5wF7|r=*=G*Y9F2%wbsVx2u-1Gy{x?0YwCH@b_8IkL4zF_<&Yi zy~K@vo^=TEq;-Owek*r>RKD?W9n8WZtP>2sUSl@`n%D{l zEJ9F<0XM~>A!pHS7+#ldY}F51h!rgYvJoZYjJ85J>AqtBH8s*wG~P|>HwBTL6glFZxnzng z3(kEvuHS`&X;#e>$USx=y?KH%x9}od3tv)g1hd81t;zP%Z}mjDvK|F(glB!kD$Q(L zW_gouc{6N$WZU`0!#?(ge2V_*5a2*Z%W^YhGWy-V=nh~NEoYQ-56_ATS2V)zFEeUZ zzvT}686DKV#UA`UisU|iK14K{^p<@O!foRXF}HZ*e~;~J$X&~l{@EQmKb^40FsKI5TLe$xpSJNThkWd9x-!|zcFia%`MkQL7^|2xHlS1 zA2ibuoT*&fAr+R%Z0(4WS&QOX+gzEHP`GC!cdt%4QnAk?t3qZ#t|B7bexX5@a7eY> z$$1tney{P0GH$c1LgUmjY*!|JyC`UAqVFXlzAG%FtHrFPb}ZM0^3I(KV@uONhB`Vl zk?qb-!9$e&G~inGbhvTfxszn}iHp}QrYt|Q-(~0?V&)wb@XPg7c*|(pJ=y$%$ry91 z0I_Gb?+0Xt#n*Gt#6b)+zv;4Qpr(NybWT1KXHd%1$q z=|RXP)6fimQYS;j_l4=+)q(bnk#&9|uB)N1Y2qui`XN@2Q_Qx#j7i)pOV=&kHrqo% zrtQ6R=>${d84~~0%sMN|cQiP&e3c_qa<5Pn@&!5FeCqR|lGeK8VS?=M>`nYlT8;zd zo+A~buV-M8-MUOEP-QKcsEkA;iIM3a0%|J_qCsvb+$MP5BwK4)flLk*jZ^01%q53Z z4j`rJjC6z9K@U@e(~J>vCaL;$>M_(uMCX58OatA}9Pb-bCksUdCsW#|{ZV0sCMtzx zYdK^VnutPE8%2dAn7#2r(+`Q_3*hp?8?Oz^*H;(~LLte!!K2Ei-naBiOnDw6#rzJy zqnQ+mKA&;I6|N`Irn|;Y+20p~%*`83-=S}rX>9_T28%m1rE;z);p&z;=${t2juu(x z4qx}Ya$9%RJdP|LA?`rw1j+$zq2@J&>u2zEwSV7qV_l(UHp5s9i4T!2?HYmeg(=In zR@F>?dMT?FPJ$+<}AYQ48rXo zNhdtZnJovBvpTlhft6EV&i9^mW8Qe>A}Wrm{JSdoNJPL z6WdQ`mIQ3e%+di&p1wWIfN~;@av@Em&f53sNok1!%q>zPZGmV<_4e8bzG8GJ%ZM;@M|P> ztKQ_}^=Am~DV8ynm+e)sV|7yz|FSA}3|M%Ps0QUcS9kj4D z`>)P`BjH)O|9|}#1vp08N^VIX*;ki!V`R`iHVYC~9vchjws0F6SOBb?9Kx4sp1-8I zy@m8cNcs!Tw_jL{FycN5?@JCduZ_kj8B=HR*=O#AVxU2?-CIUPYnK)kh|D)@jf;$VlZSUCV*tVUHZQHhO z+vY#EjgD<}Y}>YzuXlat;_UbAUA1b}x_K_2xn|8V=5GiPmh6IIA8?QXdGgl~hH)H` zZ7rhb|d_F72Vcp6(Eo=;Y;JR1%R;<$0Y3(nj=oBuU7>~IDZRHn>G zh*a2hIi$EN`7F$ZiUwy0__VIWT_O~$F+A%bgxv6{F4}rnQt3js&}vzFx&n7yA>$cG z*h+!RCUfmXsK9{+{+2f*ZY$bF7X!SsJcmiT;V<8?TaUQ7H8)yaq@7{QQ(_KdLNCDC zinClrp>8WPQiaY%eXBW-+UP}@qska^g+b!R5?U+A**R1m04NUp%}h`05!Xn~?j#T_ zsQNbcOsXZKMZu*#WTKX~bf-3dQGOc}$B7W6{^|x9H=U%avu^6ZJyy|WpGV{^<{kjI z+a06}{B-2rt%3O+@k8P1Ek|>WIDPz5a5!wvda^*5mpDy8*eHbrPM`~b``Lg3Zzh@0 z2C0!K2!_8pgjV3eTyK7$6LxteQahttuz(Mv3<=1q0=?O<*Z{YG0P=D0JU5ZWW#N?f z1GqOw-s_I}3pp1=Il~$`-g55;t7hxd`iWO+3=g~XMD@Q!ERc7rZx(qL(|e=^dP6Ns zYvyhK`t7kDTm#Oq%N&`4_Ph_%n*jefwvTO!q*K-dotQT^ln`6MkLK!p`Rt7QQXz2& zyECgl9NVq+7EABn-rpX2T{hJtB&I5*#GybKks55EXK9}k8qzq>0+L~@Q(ig!O34> zGxY`M506t|I+Z(8z@!JBT4~tR;vcPV`2Q~5D?eP7`lA5>AIm-9cQ`~SL_|ATZt ztO@Ota+Kkp%gMYW(*u>kC?Ej>EiPe(jEoG0Nlz3ogbNkf?|>P0D2)mDJCp&P9;H?x z-W^|=|5RLBW6@6{@-I9`&9;-bbxUvK+ReK4YTZtESAisvWhE@v+ zPRxyZ;&#KzfhPC1=lDDHB(pw0?LdhvMLTLDX^E3uM89s@7D=T{L1D@$YXK)3bNs!H zCsxhYMqNOhpzJpi>}`-eB+h+kmcu zp=PB#jEa9tCA7Q1LubS^6nc+ToPPOCs1p3g<0q~y^!706{oRqwK&x_rIf$YoRi72o zdry6GMqGCxUwXP=Rg|lySk+;!9_dW-QYBZ9;kJ6&622z1%3X{k(tr}#p7A+;U@Znf zR+44<#g%h@hJ1O$^h;#;pazHgs8DREPa{%zkNz%D%4*q?R~H8M20H8mzTq}JCwsmo z@Se@eFjI?C4=+9%XV40oL~WHk9Bm?L(#5JsR)K$Y#ayHVFfoH?Y)q!2v+lZ1>sL%x zINr7@rQT+NqwJ>T@LS9~)60mY4cWHVu#wn#hxfSRv zf`pwFBx#!|YLsm~Gys=dpAr~pxgz}+m?n4dU8%)i1tuhQ{06K*^z=ja5%yW{_``UO zU)zQo&~!crW~4qbH$a#tPV#SYQ=YLWaPG8@kKn>g4QeVw>vRZ~knU~&Ql7vSm?nuR zXOp1ZuI*r+HP75ZbewEy!F&ckruwM(7*f(LTzC&FYi3V>$6e z+_33L`n|_J$?_gdKA9M+mrmK?$gsBp3xtb08Fh;1crm5eI^rW)I|vv;LA*&AjFj+#Z>ps0Uvtmfh>3 zp2a)%D~=fXK>!!Gh;gcmuS8{o(V)gAJSThm4@|-!BqT_pbq(4@>U|b*V){T(H5cdF zT(|C~qb1ht%QcpEOQ+Eh5uB>2*uGekW|of~UUkc-G*RVqr`E6aGDUTh-cMGsJ&`Z8 zu|0G*sUANRUEZwkxnBAeb1!#sK(7Vsy=p}S2fm?V{E8o)Z13t_gZloZ+v=8&&RsK$ zrx;egsbalDA2zXmHQN{#kLcUctnW2md3AF)s13hnx`|FJhGVu*@r&9Oi*`t!8wn?V z3~1^4gFN8Urkky7X)2#RF+RQSs@+Spdfnsn!2LY21s8lA#ifnKA1;Y+Hv@-~EJNEJ z2C-zgnpB424kr8#aZJEkE*>e~S(b0$B{4_1PO^m2NZEp)=#5yzCm^+Qc)}um}IozORp`Y^T!j*>atbHVihR_@45NH`KVNV78yr=3ELkt>b=7_+g^iRRKc(BP zuFiXDZj?@L{8pc?tJJHnH=Emsji%3J^PWZ<{!W??#tXcU^3+bRq10CDG~G~L(dqU* za{{(5oo>Q>o{#83+ixwut}tx^FjTE^5Srd#P0ZLe5#VcyJdU9q_VI2DbdzxOrSQn49WDyU=C zDJ!u%w+ddVNg7rXTK??WSMwZj<^%HOPL`0VGWHC36!Xq)_qr&ZB8p60PQhmzU0fvD#h(rKv1Y5*5(9V#^JcJx2izBCV}T=vBm z2CQgl=@*;y--QJu+IvT7$m-!PnF&YQuG{3M8|Llr>%Y3lYuua}LM~(?7W6&zMsRyM zRPPZiH57Ynx{)kZf}mp!J2XkuJ3WhnZF4iEVA#SI$wK{Yk0jnHA8+XwS+;Y!^r<+- zYV8Z-TOA&OEgo8&R8IJog0UMg<@Ny6j_rwZr-Ml$RykV6tKh+eB%rd8%-20C`tIx` zucxfh(#DKah2z?|4}Lj_5l0lUtumEPJyzi;)bOO(iQ2ps3#xwIawpcWBnM^hcM1u! zGDA8sX||Q`m{DpmItz(%vu&NPViGBzR(7nt9G5~TW}c%v}REhafj9PF1RxqmfbksH2|`b+(KYtCls z@dcV(_>75;*W}&qiP9U>04`%ULLyO|Lp^6BtrdcPJ#0$i;n58%)~ad)bqBkJ&dD=w zj>L9ato*8cmAcj^^Xe&oAj|`E>Zjj5q+M&2@;{k-io0%x=G=9 zXcqY}PRd-&A)`Ya^82<(Bl+GWy0x) zT`^gI2(9H_G=DHdSSr5#qN{K{;_}6cyK0{n)Jn`=m~he!R&fVBQ|}u|C|pdt_U^BK zdsf1wD^_xf!e6!55?OIc;&kCaR=6h66BN=7Sait`tm_?M@5gb4Q9RP<1DN=}}ipn7{v(Moap}U?s0Sce@OtMVZ805oM;-ELVI)J+roWT!1ScmQu{oV}$lO(3sz(*5LP5LHA(*t$(ra>K@q2&b*(890chH zIbL5jY?Xd#m4Iaeqlo$e&u`zXQh{T*wqwCtP3h}}lmp@&tjz1AUQznYFW@N$BFvdt zV7T+T8&=W@pY+D9LB_C!Z0Q7=$L?@r0h zjO_Le?>b4JP2#w+eFH8RLaWgV?cJ}9fN`|l7CcJuKoN5-AKFsLlr5fn?i?z}n?FKN zxdFZj_{|JB`N7|xf?gh;{R`9@?%Kedqwg4fyA1$L58FgV+5#AleYlJJK*e>C@)mqq2c(=UgNzS>(Axpy(ih_m zXmbXBNERLhl(<1ZgVrJOrnca6+h>5tsmhS8b!?n}?Xm#|WLXL83TmlP($rPQOS z%@^`1gD_xa9ut+YLl&a#Pzw$rDA40dh!L~6cQsB)Qa}-LAtvC3`#1$L<;C~b3eIEa zrH3ShAnqmIxFW@z`I}3_Cpqd&Tf%uqIff!DTstQ89SD_XtUwdogd^C-NNiO~MlysK zP2d}kFNWFe^M_j1%2U(HQ`5>b<4;$`U#;y!M7Rc9PhdX!+YKbm=wH6z3O2)Ty_(rp zIn+Pge?Ji`w8-#FAOLE=Q|lBfzkl(48)rt->Pqs9l7C?p-kjXN{I;ZMbPL%Qs{TS? zdSc#cJ+S*krM9ial{HN}ELqDW&Ob}C zx(E*1p;<(`D8k@vfo-ltbfFSP-TCVgrkwhoj?uKPhYeo@H0So|MnOF? z+hWce=W;+wLmVD8L(Q}0l=3OQgs|9EKF1~oQz=?NOq5zLy>bz%vmMIMR_U} zD*3HBsj3`7HW8|036&fz$l4?Jzg{&kf(7&trs9s;(-){I$_|Fr>O>r%6#9i)C01=R z!B(kheYdfIIn=}CF+c2m9|7fJr1yY((*ViR!2+2<_rPd}>?8ji)>kKGP$&W!e=6oZ zq=}R^S018ehZw1j)7Q-|C@K0d3|)ZPo2I2BOmwI3fFnt(25wb#CrH~|B#|8+u!=5* zhv&K?cB`gg8`BZ>XunR6ZE${;Y$Vdz7|TEW`=uIN#biZv@-HaBIs@#urw1;1sJLnZ$euNJPntM{h`2*ZeioQAlaV-P~4H+>KDe7 z(kzcovQw_=gsQ?(f-!=9LL+-tg$>kEA!jsqEnMDBQ_coRBud<^d;ZSqPQBEn$sW~b z2vd(6TbQnbs2VTMxJyg4U7aQwOiGl%#iddIE?NV%MWHubMr&h)$)j>w+f=O0Y2fus zXX;7(lp`o7m03{|aJ0!R-)WUO-}x@5)GXLfOZ|Ep&C0*YzH%YWrkE9N1${HW6yI`Lu)DB2Z9I-G8nUWo0xhSw?v+D#RP;hSB>;x8qKU+{# ziA2^Klif-Fgdn+|mT*Q*IFKO=S zxC7U8`!4Ma+!*Y7Ukdnqai3oOQUW3C9~f=ke!1RJ%y%?gqvCH-@pRDfq~)goJPzlq zLW4kmONe8`0As2sjA4fkFxtHq#heEyz7$Gi74+!MvyRwU8k5pMPK0^vNcLE{4DlzT z->oJ5(I3yuNn*>YQ)}!vT3LS(fqQzsiC8rcSX~gf#QfzA5y1+?~%36>OTk>bkbQex$|He_O^AdT}(bu2qy9$4bofwZ?26G z>a%_RXmq4++kBmRe@I&IXolvgf zjafPPLO`$)oGvswp@c0(4c!?xis|`ATJZ^TdO@X%BUlrv@K5j_xuwt^Y2D%rWoG^J zFGQ#OU`-$5#?M(zOv06fuJgghjIdSL@u%RAg5qJXim+|+Fb<$py9i(YAnI;W)Ef&7 zRpZ8CuPhXAO~F1s3HlO&ZHRMh83s!UQz<%k^##ELMRhm!)?G6rIKdwPEL|yIegF$~DN4FxIEGao{dQ+pn z4YJbK3*a> z>jm=(xc}1JQ`kjKxa=wQ$_6)%ag(Fn~Gy7l^WA z`p(fAi3IoXWklI78nlSDvevb^EJ?A?#FL?XMYh))7!`m(;=QtLo&!%roJ(P zmxk@9iS+)lYP0WVTebA2vX&e!9A{JXI`%GI@agScs=W3nd9k$6JH0*IE5wBTD##yP05;_Ihc z$-%#rowc-(aaZ^oaBL;wHy8Rwlei)=9Oq99*w$v;Vey41$a~m~Lg%~LD(epQ@xU*P z1ove`e&?3%i7?y2X9DDd_R-s+TblpWAkf3HgLMOa4Kl(6C8Uq)M%ggd~^g@&Qf?KY!}h#_cmc0 zhWbRYrJN<~C7+s~;ofISHDs@i+sa0?Nt%C3xU$`E>@J8 z9F)LXMgQ!B7)*|DBKH_n_iR3*^>wP{S+~dqr(|U;+h`xjc?+Wvc5R~2P(l#@ojZ3nc z$0Yc0hN}WzL6LFR;q&OKomeZg##S6TI2lVZADE;lD^}$R-H>E6K}i<<(;|7pY!ZR6l6|m@3(AoVN8U&<9=)3v5j9@%x{AAt-ETV8{{C$g%5k|HYe*-bBFayErN}P z$ZRN^c-UrO8|ieK*q1uX9bRWi(`5Z|ay_jO>3>>V|3G4tXLm>^9oWG?kWW@DkVi(= zDJR1h{(ShnhS`i*!YduT90-CU#$0*Pl2%xgPVn)BRG_W|$byM(aAL+X9ZnYyTW~_w zV2UDL;9c*m7EsrU8)a1R)oQF8Az;og6_z%AOQ}jCGQ(u1!q1E3Ef#Z+uvy9hcx$VV zpb?g2wW#1POZ=P{IJs7hW8u9UAmt^nunnhAHj0GUAc`%FT1|vaob=^J#cy^f=Y9ea zJ8zpK_?I$wv)&gDr!u5)8c6Nb8VC=F(A%QWlHFOov&grC217bIDER zn-m6_6fe2pm2Ldca%IpoNe*TvISMQ;M5p-g_R3zdE)3&S?K;?P;h{&ksEkZQ2a>xs z7)izSp7$_3LT_|NP>idgFcu}u3-i2h9ny58E!fTNO8Kx}+13C<0le44)*iyI+UD9? zNLTTbL_7_T8!zA;i^k)Nzrx|=Y~|n;La*CWn?)>Z0bVmyrnZA;o6M9|-ZiUYC^rgi z{Y-knIkvWfC9N4U(@lL`H&+tyh$FO$$kJb{LrufA*5uGm_wwPD1epXIcy9+5e z;a+lzGgzOGhSa0cuPqVsZ+EGHa0Q(X>~ICIfE$GD{uyE|@PTG;c=Z{vc5I}L@9NN_ zOC%h!0+MnlPDEp`^6GQO%F&t>DwU=;O=%fd%4v=JwF?Dd8KZ^146Lk&w-hGcN7~Yx zNo=R8=}^w-r^|gpU{1zlTa2A)CA0G-s2_yG3=W3TkTkYC&ix6Ng5g#6)rWwlJHn_z z`d*rPjOzf_xGZ=t-x9v4neZ*Y7dcYv&+F?Eq@j32JN30SaR)gIR9JB&e9=Kg)-Y<< zvK`(ivw#1w4p46elh%P+q`&!FTjfx%x{gd2?yBb$ivfB~3@hOkKCfGGqjJ1jBtsla zwabk7ec&QH63rM%3(*RJWSi0Hs{IrB-pZbxh9f?Z7tD>Z&A%z`@8L&Mz_cU z@q)xcT}59_;?Lw6g{3YVR;h1g|EkJz!Z8a7n`48r@);LVPA#Z0`WIKE@4GVe!0@Z(_!G@S;UweizcfepP8NM7|JueJ*{V#rg`FczcO|1; z(=Ts(1Dalx1YZ=vxiOzUDheS1IfzQuh>DPi%E~*%Nj;*jJOec6tr;adhH2MBHLKAZ zcN}y){YxY|Z@jf0Nk#H^APqTV&&C7@R$K^{dbn!+_=MD9j+;)Cqy<{yWi8-QZY@#^vz;qT1^B zDDk={2Kp$&GE<}~sy;6&UQYgg6pAAfE-A4+Jp&O|H(|EXQq^3tli>_A?}*#&^AptY z1%rGszXydzDX!vrHn~n3v%+C(?qY>9yi z;jN3Suy=JMNVA$WNzqH3$&oE^A34_XKUmU&bLDr#eZawDJw&RTB`X5pk@Zd$q&p= zz?JSZ5gx=GZd-gyjr@$j4(>Sfpqp#_Qr*BWf%-1*6D6RFh=n-;CjnqrBGO_HN7^FL zDfk<$RQ$x`;XT)!@E%X`Q&qlr2>nQV!md{}k+lX5bS5o>??|PF+DZj%R@8c;MmWO? z(2id&pcsjMF|`8p_kU!iZ%!_!lb=osdNEi!wY3di)e4gtmQ{h9V`?46#?oL+_&?`zPJx9sknL4J={V?NvFN5r1J| zd{n~KGc7#yhBv29xWUxBK%No5_0qdCXuz$*>$wcQm;Eg5Ti^VXWdFnF@@nA4Jyp5(06!A$W)aCOkK&Sw|DyLB>pRH~$&g;1v! zNv5S5*Ot|&WUXYnM32tZ9G^jneG&ER{p9CApdO{FlZ2c9+*OJQKtS04Z^JKUX=CdA zf8iJYw~k-^%~^Q`?Yov#TZpG`)rK9SH(?|ZgV9kka}`0h9;|^*yS4_f9zs4d-}H66 zfP9ugwlxo-1R~kQs+-ip>f-zolruqZXIb{QnB|N6UAb(5fGdYcmguoly|D`#b5?hn zbBFgO`zHJ2bz^j;7Sv*xpxXi3#!-oidxQB%!%ccorWjGXCF5y;M8R=@!?Jl*%&Civ z*=rz%6XeK^n%!~)+$}6U;|UAed91$duixN=$wtL7>AWBfi2|110HzDGnp3ut{s0Hw zl!lp_fQ#cIO<4ilkyDHGKhP3q)j~ajA7`ih;QQyL zA3XM_X@Wog+e)<4g&;gm{aiEzuq>x_iI$1N7gWAv?jmhHTRl4?ys(mSUKsjix_VyB z0XdKRN`@_Zlye0(s`^dv*l^!noY7h3~Y>MgVR1Bg#5?c~`ve#Tc`&Rs~%tQJ3Fh(yd0uos? z<_7lJrTUS65Vg+c2#eEEbJUr8At%22<&chGkM-zs0afTSHn{O2&jqJRx%WHG7!Rf{ zW*``eK_(vIspKT%M5e&^KCSsQ9{!M-@eN*@`c_o_YsX0n0}D)WSQBR(>SU&5xkV{J zcbcuXCyeXlVkY)Tahw^BX4!AF))873dRPOY;7}BhZ^s2rksyHBJv}a7B1cPD$PiWQ z)L|P7k#S;DtDJPvHM06cV7EZCr=XOLijrtw{$4$GBL`L0J}Q;?0TEUh3o{%;HO!zc zNh@j?t=sFZsFO5e*g$~=Wx4o(ATRd$)e53}sBnkN_awHS3OKsDtQh`_s^_M3k`&2H zDe|1Y8PeIFg!v4%1Hp8Yb_jEZikSK;>oSR(j=5s-6VpB5L|d7DKXEKD8Jh8#4l~`7DN@qM50ytEk>i*OB8L?o2iRDV8f>b}`hMp#-Rzh)q@MR7ADQK!^KJaA^5~MR) zitJ!CWsHyh!*AHgmtJpiChmmW>DUw$B+6!HONN#?H$W+Z+J#sh0@**+Y!EZ zsLtbQSV=Lfs#D0XRkvk($KsW)wmw(}a}D~fv^?oN$tH7-k!G!#=*BD0Q|kR<@a9zl zm8C+Q#her?J0(|rA=YtFDha{)wHxE1dfn8PGaLH`Z^ojH{6kiA6F0|b^d7Oal$l9+ zAQ4;|H}QL)Pi%Awa%}V^vMw$2Zi@Qyb*Zg~(JC}iJ_Y+NyWFt}dy=C{1nsWH;VDW8 zTnKiRizoc5sT`@PyykYssP%Jht7)|fJP#oH1p+e2Ql2AhjNlzl-zWPOZZ@Ztjn^hc zh=IRnU*xnWIQD8Q0vc~Uguq&WKD8PQx*CtUev2IB0hFhtmM^>{+N#9?b7n)5m~Jq+ zWVS6bNwcfSGtv;~0B*d(ety@EZYz!dGJEpuumDLs>+*$cWp;Z89uh_q|F__u8ilaM z`FO;*>*s^*pDv~(G3be#3iGFi6SoY)@%{L2a~pU6818(hC*;Lkp=jvfrmz=C>h6#y ziM84%*9~@TqUII1)QLlPGjs6d=pI%_>AeKEC&^uqK2GjH1K0+^{082^j;)XNe4Quy zKg<#&oy$r^dkLcQO;O>rf|JV#agGMCMf4128Z6INOLJDWbvlrLj9L%M<%!B%yM*R(H@@anR-gH&aQA zZ&JG)J@v|^cTy>2;Q?yT9AEPaxlQb=)BMBIBUq7z$>xExbLd_*&2j|yivF`S=#TT! z4dronrJb@pz)6pPG&&g?U%&7~G;!FR*=6obw9nmqcN^o5rcHecd?Cp?lkeJg!oae6 z;2D>lm+1fWGDNNkBrO8-J5i#0ieR_&W0&>2J&bm$Gi_}Cm`K~?730h))JDOUkLZ9-s{Q=?E*8Qj~3x8Fe zy&oGG9V%rw%aIOl))$Yx>4lJc?Y1$`4dyhkrNv>tcYOM~W9S)5M-AL-h%SmGLJl188k9p5sSlhtZ zeS}lmA`~JQaW6k-+%6VdN4o2>^P*Qq2;YoQS09kR2&7)gu(c1{%md4_t5&wM;KoSw zD`P$gX}M~_z=@J!MeqsxG7BXwmR|!TU(gAHK72pkn{yxpY~{=M-p_wGeTv)N9azEx z0qqh0j{`y*Ll@KkXcztm%V&-zw1>(P+PA&gfDAbUvpyM{ZbfcQ(OVd{RW0+* zH=WKWQ-5*bjy{q+C%b>%X8hB<$-5r=jpacAqh?+TeF}CXMu{d5^;mJN?l{7C5q8-4 zZCK=b<@WPgBwjB0p2P33v3v``&~VAa3l7!olM*3M5*}GSd`66~Vapj#EW)PVUe@Uu zP~wnjaQ3SPr0C43Wh+z04v1&kX-xI(VbH=C>>-><{N^mSSq@el*zEG=02TZ0IBc_r zO6Ls>_GDEUqM;6>@a^BlyaZ8}5Fq=Ok@9+fFj7z~(aG7{w!eo`0JfLCiG6?{k zodoGY$S^DTl5)fH@)_Tm_LM*2MPetnvtA@~wp0i9@lR)oOI#JAFZTr-xNsEEC0l|% zPAfH8WLz&yLxQm!%2R4tNlk6}&d?3wYUQnG$Aa2Op+V8Q*<1qT{_B_|O2h znk)HoH(YSejLUh8w@lR}XOxNQHf*tnjUqN$CCi@Y)#jAd`kf&Z3m`6v z@0zI^neD*^`SD3fPxDragQ(B+$~T?m!ts;Mx%>G>b>P}lHSl*X5mB^IcOM*xXJYtc z3C4sgLLMeuB+0O6Vfmkh#MLtVu%ZWp3=)Ir|&b*hp0VD=Lj7Na$ui4U6_Qk5{tsN^|^Ayd5O`xuOV_4ap?>jJGd@)sKHpL zH#n|FJX4irXM%?ttXAxC>Bv)w2I@~u1{-Dy!%DaA6&t!$`SAwsoPp{bB?SNN-W(`n zy&RE+b43VrSQkdlz)cGED7*m8qE!ohvbFs*HT0z%3ev|V&5-8q6t0Qh0PV`;tJ{O^vVr-CeHsMSIqb&19^qZ& z9hmboj$Y!$^$7Qv_f;HBcOV!~WQ6LOImOn?YyO9*rG6qCFUBcXZF4bpVo&(}v77^=&Ax2rpWrN=Y0UB0LQN z^fs3hyi-zNiDW6o@q5Y*{(~r>%{4j*@##lnuyqYBlxj`TZkrw!>aJ+xqVwW>U z^83r=Kfr`1x5sK`I3Gh+eqS{&>p5JXv6iZR#{$nk%1{kKE=Paf_Ou`Kj^=mOpViX8 z(4#$QKXmqo6Nw!jKWoR*BRXCv)E7yZ0&9y&OV*BKqqIwQf@yh-gIz5N@faJyitVg- z*B<|K$<1aJ-Qu;=g3a+eg27jNkUMBFY|O!F)=z5HkaNS|nj^%JVEdmIc*k z^tQ5elyYV=X5+Ya&ke|W$jk8bU{?F<>BV_~9Glw6%%xn8g9)9CXekG&?RULh%q6bt z;xq?ptq>#9ZNn@phLm}KLLS?eJ4@B+YXejDSYMIBad57{pxMThZ)IuHxOcd($L-$&uY zw7a0eaBW#$HpAImi)!k^pLo6L@*Dcd~~kITgAVfZwO!r28xKi1cOP6*;k0M2Ao^9nEma>8m>S!ys^foc*Ed1 zAZ~F}L%5cKX)j1z?tjT}xg{x?^G?}*tr2prL>$bDsKYX1P#l0|2R)p@&Jdyx3{|Yg zEjX~rHtU4sAEhAgVLuKMmc1=Oz$L&1lTH$9IuOaoQxxnn0(bBj;M3;2J_*&qIzLvX zdR=i*cTXS~2+AK&(kC^Fx|y7zV+sE)-MEL_LKa`15^Pq3oJ&izFi+GmPe!$kFy^Ee zNDk?OQe{SK3ufaCWe$ADTd_WQ#goC1q<(bed2AWY zz)H|26CVQ#zYWJDjZDB)gd+;8Nx9;#M_M5^g#D2t8<*3>6K*88*;_Gv)i!-KU$Do2 ztP0^N$9k;8+J-TR%Fm-`v zaa}ri1aY4Fd)*=ob?Vm~98_i}F@_O7Z*^Y6`bPB)2VjWeRjv z2Q3Qsea098(BzQb?af+h8$}(o^ySuJmFd3C`l$PR(2@(OVpY3i-as~?(MiQP|16xIr91W>u1WLV=cE$DbA%#Y9?_okV@c4?a3k-%7GgxpKFka(m35#aS(upcAZ0{lYH)B(nxXTEee=dp+d z?gD~zNeWt0f0=l4W1mamWtA;5g}kE*Z3_NKHY4)|`vl(?Gm@~;wzb+gWI#{s4H&V} zpufE}4_zfh>f;_lzr&e+WnL=u%I4jy3h7oSM5~rZQ!N4`od?5o=>7qM{<2}e?pD3hO{c|7mFF{cND*T_t1g2Z1AiWZm*8}X){$Z7_|gS7N8Y5_F^V`xK6SdORjDug+{SOcSfLKC;|2*(Q0(#nhFn zhoMGp^r8^Hyom7@R`WXy{WpceQ41!R*e!|C>^=g!T6+$MO5apz zew6I6%zH=rF{892poHTuF~V?j7R?Z6n`H}cNZxTw9gT@r`tM3&KVz_7xVYU`P4iz> z!c7L{6Uv%}nZ_6i{Q2-<=9;SYX>}7@G;Z zP0oE75vWJ9@qH)pyAJHPQXXrZEq8SivHtcI87>Xkl9S4iV>(7>9&YunsG?gC=~2YS zGW~xdnvb?vc-zblFi~rOapFoXTVs7}Lrq7nQ7*$>Bo7W5m^A4Mb^rW}RUnU#2 z$5|rB_^4*hE((ZMyU;-61yy)vs>PN~U02DqXh)N~;V2 zMH1ev)K=3tpN%w5omAF^MM&%O@5!%FAOGiL3Y#og)oVEwl&)@+a%eto&%9D2-;s8W zios~PzE4hl7^`67n(Az7^CRQx0VygN2|0cbe6~yQtVk`>LbZ%?K5P^=PI5hRlseos zu%BMT(enB;&4XXwTU69G5c6%9#XNU+$%6dkaZmo~kGHOqt(~9mH+7(|HuJ)MfvTI15~+TcOenf*Qp`m(!B92h2M3;@X8yvs_5^1+)Kick%>Ka8Iz2ldNqR;v7O-5Q(+Toyaxv z(#C)z9c_W_xZJ2!W}2I!;t|dFGbU7A{2p)tx;k??W^9v8d+8WJgTrLB#K~m$QWdwW zr8=CY-gFJcX`_0ev7|eYk~c$_-DIA9w)vY_sjIb|>k&)Y6&6UkJ=7N20E$T5tm*-4 z&+<^JT6vyf(0`(4`E z)Lt+IlFE_0ff#?>;qrD_Q1bA>ZuEv%aA45WIA~kXSAO@oIXB7du_U&zhanqSkFZr3 ziB8b*Eu8ujcd7e>u(PZfUg9Rp5(i!EK1xIC>H6LzIViC2U2ox6OYS*a&eBF#9!iu) z1;wjfi*vFz!Cb)RswTvq^l~c5XdYScCOz0K(VRMJhaA5Lkf~Nj$JZk5ONd z%Zj8-;waSG31pFcMMgMTg03TvF*$v5-15ktNwX$^LNv)ckZ-gFvvaN=aiq(3w*|-9 zM8Az9bcig_iOVmq_KWT@$DghS=;iv#Ah%;*1iosEkSnG#O*mo@zW`qE z7P3YoA0hK1K~EkoK6X;suljUeDr9ypHrh(5F}xl1TKCBB>SEAQ#*F*K@#e(_gXN+;rmG0j`dQM9?c3jGaBhwmnU%=m(=FNO3COE`Xp=)bRH*a2f z@ejG5cQbXpzyJ}&aB{|7^{P~@mTT_ROR2S{nyJw4VLEwn4Z`PHFB4Omw9eG-&bwLq zHxN9sDwP)S{eO8VEj3Q1=d!ROQPXMGZ?5sM^Y(NAs^-AV+#|lNs?OR2JLnMi>h2E^ z;vJ}Ta4vJ)l{<5Ap^8UpaeKAjSCm4hEVHrrcwhDwErg;-;`(5y=J}vG%v{EV^AXcn z5&J1IVQ`onWV6~1I^GpMO@`hy%VMGxRcX}|l}DV71aM(rjmpNQZp^2ct}ey*o{~x) zKD`v~Gust>`^zj9E$c_?rvrN9+fO-_+6#%ur~J=doFq>G2(d&YiDDQEc~h=#IUanu zLOK{vjz2oxN{aZklO`w-Ge4kGm7M&mR)8>f4Bx8eZi_1jFX825vlMn;lU?J-u_A_z z5?jvu$UvGgH^VR&Pyj=C`i0vT{LdXS(hUl2ZY4X&w~~el9I$0i?ypC z$eooC8cO~<%rkf>+upanik>ZNk;xX#;8oS_l`8fz=t=abtn5ul_8u8!Mg5NZzU%Q-&;7Xiz3$g_=dbtseCGL_&pF?7 zd=nU7oM)Du(zJj038A4OA9uH?abrLeSy}Vmck?r8RwdpiXIc~=H*Sn3!QjbI;`XOBCMcXq?%JBNESrjd8+Qpy_j(34F; zj=1T@a*0R9=LP&us7tb5bG1_^x?%Szyob!OU5sJj+{-L^k<0I{2fAf+m1Uaf=9b>}B0)%P+4ZEPOaB2~2~wWn;PJEtzr+?49OPk!vx z$M^3|!oNE=+0O4C%pe~}Rqlj>r*)XYCiH=qCH~GJatKFPr$Z%?%*#zKn%Z>VU=EU< z>z(dgsT8MHts|qYmDH^{sFZWVDN>1_h;~hM8p}tg=U*1}WQo_)4{3q#E^~I9gqeii)m-^(xVgCi=en=6+@f$x(p>A_Y-|@@gT+zG z7ie{VTW<2^Ag4eS?qyYH`#(U&PbQ9^%aX)(LY zhRrK&;<8StQ?|j8=Tfe2#KHhrZ>#p8#@&-TWHmw*rikLR`rbO=FBOd(+1;i2IEHjcn_%EeJC{H>{#r&3Y7wm-Lh_}WL+L3~2|d|+yhuiS z@bzcN@|l^N0X|;K)Wi-PJv>8A?>BbyE6a$5YTGFUI>onyzQ*RVt*bSnF>Nc@I^rhg zC_M{`rmH$TN}NY|YlT?3XU6nvc^|Xj>dkkH?8Oohw9LgAcaF0ZkDkBp^}XPo%+lLw zBZ*dB1&2EmL=qP<>F@Nvy>^EAD)YvXx}q@`1neAR56fdGX$_XK2xO$7EnU$)qqnx2 zfsran5ey2i3>XTY%kRE!C#I21ckDeOr^jF(Ef+hV!tK!=0%gX#*kdL+J>Oq#6wz+cX&MG(jm1IMY(-mjEQ39 zr;Qu+>OLFs-${^_h}S9b@G8i=q!?x2_3V>tv>?t3u4-od!uP1Ti{qw`p-3(O6W^ZCyzq^A^3Zm11wTHC4;^pJK&@AT()Mi|^FZdu&E z9e?94)%6DaS{;^~cafF7(U|mC`p7gZ-Pe7A7Y9%gw*c z(&D*yw|qT%>VtEFU&U#?QzJZ2!`syxz8`qzY1E~{|2ud;$OhDk2cCJ_dpbzL0SR-p z|KDYzy~ZGT-jzgb@Q#qPO4pR+8J~|u{b}85JjBOW&~ToskFaV#y(m1J#*J8L)H}JN zb3)>Fdd<;g^??2Y%H+Z`BKcO9ZLwmdH@|(`CLBR)Bji5I52w3pe&zx5=dhXpM%h&< z;d5#hy0KjFvr@bSbrC)V)Xf(e>u}p{bt;kKZUrS>5fQWXB7f{ej-^Z0nEp`rZJrNj z_3E<`mk~b+`4^-ggU?c!tMp{uN-`a#QRFN&eIp*2G(bxF z%yV1x0^T;0Rl4h#1j+hs>GT^!RFiVG`2)qPVHc%jq7N%;dXBV% zLtzkRKDqofRxeQ)}y@4=3*X9+vwHe#>!5ZcR_cXhdr^HVRoOBQSG zIyO`Y2h$@;#7!)Gn5k8%H48Pl)nwZgUMiGIl^>m3q6l76HT*8|oT$Zddy_NsJcTxX zCLwpS!dKy5oZP$=-Fkm2>lW+53-;Bnl_@X_>6?7dD&LjLj%SefVe=MDdC>A1pSv(U ziNw-gYskHClhb19LnLjQ(ZZo3T)%EPIbBCqY_>NinF?s^Bij-)M4>~4NjkC zIIcE#UCv;RtX_%?hI3t- zVL~oadIP3qw`(!dPP(an)%^f_-^xHZsnWtrs3aUQ9v$Yzzo~S>GndR8qbJ?0*=@3j zfaWr_E_Sv*C8>z%7mGBx%PP0gHcWR*kDQ<1{S^a)y71s5jj0B-Eml|dsx*yJI=6$$&B8ZcImwU)8VK+7qH@I|rWaEljb@WKG>XjUk0Z;xM52m6ITw%Nz zQXWzCX06S-xV;ih^ohNpAEu6Q)jV1Q`*Z$7W#;%Nxq*fVLUmvVh-aa`I zF+Fqt_0frH+QgKY=*jf4EXwP6Da}UlwT+{+%e!~t7`Jr&^$WDAu5K;LCFb3B=<%HP zrXE%%T+7iM`+$=@Yb!M?sT)GhFY^& zl%=F!wH6c+UUy0xb4=heU&)UcInP!3&^^olOgTk6eL+TYErHpL2$!8G@zMlGrrBE` zOMe`)G{3@@r=&dLX69iq)>(YeR1I7zTR8UVcFm}nQ6X=Q+uMbw_Qw=nX~eFVGL!9^ zNM8#IT!07MxYMs{a5NAZ@$OCOiR1>a4%X!JY9<^XKUsFvzmq%3G%QY4?=M+l>YXbr zXug*ybsny=ft$p@|zPQ#mIh!QR( z*1D{2USC?FqRA_os4KA;s%i2RGAm0PZM>w{xZHbPonJ#~1m_;bC{yx`B=Pra{jYY9 zzfm{VFE2C1e!wEJ;Zf|pvaEQG_S5pRn2^8w3Ii6cDci>A4YOcn?NeXzcZIi+LO0cn zRlG?i@(SZiQ&YII$1p52`GUD>Lxr0^-M>AR-7I*MpEzG?@|J~RK?P@>(3|;1izEK* z_f`r9wpuEo2a^~gF2Ur$1CqX=!F^y2sjZ&cFOPGx~Fv@y2CGcWDE#Iu$c}?^X>(93&7~jDtp0hQ7;;FeC?6>2b^iknm>e`LqXH+kX z5EEb8+L6wocODs5%4&S~U#8YnzW({j(sKD5%PZuhk0_qz`V;J0QXh#Uu8vdrrWB+s z?p)`X3`3SlbHGDSEAbgz2nyy#A{=zOfSr2ZZ_mz#Jb#muN zk>dl$DC)}yy$o@)^Ta!3%oaWAuqwS8?^j=(X4Q=p4^+p2TgGmMA_+DB!ylCKHalGAaUXxe9W8{@p-wuE1P6GCD;w zgRl(Aq*s^aHQC)FPc+rgx;`N!x8YW0Zb|Pv<)&XErKkS{9~bk~kh8T?pjSYmZ`+aW zK$mT3x;B3;a5k{} z4%{*`!v9uPR`3*@@4jH7q1nz`8Ln~M&8a-}u>|oPrwWZmd}OM?L$>mW#R-2d7njQ% z93-3xk2mlpY#wivjVY8SIMd776qjamPU;$uQM6gFOMhv0OSJeNa_eH=!`vW*L2o-x zj={>H!`Nq!ap@CIZ(H<*g>wv~q@R54dO-8uw_GdUe)a8e-=&mMn2*ToyH}=hZ->F8 z36V+-?dpTM<>nE{7@u7s@d!O`eWI0sjnqQs2Mdlq!5VP{DR;Bh`JXU+2!Y+>cfQBJ zQVh1_Z7)jYhe^%!I294an8n7ODaN1jD}z5F-bFWU%T(lDyD{j>n!067FLySbiKo3o zi=IPJFq(^6eq>F$jq?HKdLbfwYcMvCp38{CFh^0dvq+p}(z1CcL@#f$LY9Ksr}W}W zDr@#n5ef-YkI}s}PcxtF3sY!oHl*PTR?H>3lx$BTWP2hY+}|8MF>_w4zFNCCo2H#4 z`XxE`07>-GljpWV&X2SV!e7W2*iz~fKkT)+(`ElV!A@Ak-hX(4_o~z;c%0a+LV1j`OhGu@2TIZmoN+%_H+P3@^v?RLXty za#{vmqWf5yjh~CW(&K8fBvX|ys*rfLt)KU~ZAK_~En-$dGWU&Eb?!~J5PbCZ`?U$! zSG&+&jM<#H>uGkazgZ_^<$_Q3cb)m?$qcyTWJli<8C_F9JCg43#7ZwPk%fxzy3+c! zvytvi{EXp={l}dL`NZu#)5=A@*eIO1du3>|aidG4*T`u#E4F9Z{zwYXIol>g`E63d zVSB}AEcbNEuswtyz1?6%T)LvD1 zIIia-z-|@2_$I_4T>O&b2-Z$i_yDX|KPtS?&Ze<4AO@WGT1#U~7Zz+u^?5vg?2bc{ zh1VUPjuK3onyL2@Ru-6N#&oca?+X*8nm6+3I@ESK6Uq=~BlHU*SgVlz(<>bn)ReIo z8=JE1ZK86T`(ftEcFs}4d<#0xvelpB9Uo6!ZV&kU{CTdHW=vrT_DOgXt?QbnyXo7; z0oGn3CFXW_SeU{au$^N}Sb*N;jB#@Hezf3VDfT!2*EY%Aw7Cnhu)2Y?%p011ooN?m zFDqKSnhdueF0y5zT^g@iS;G+jc7cBDb3@0okM?t!E1Ba&ON2}46T?1_HdYI6zqcpg=DJTZ;3;CG#X0OPeB^RI ze?|PXm&YoaD#O#*GpkEmWR^4DZ~i`tE3Lme_bl zwq{f4)nluK4?)KkKHpj$b+V(B;{AS_#r&$rLx!7^RAKcsrwLx}R&l~2ax(1fHwBev zjWAghl;lWj6}B%W@62b|)}E@sPVeDJNK^6Qdq0Tz@nk3d=*jmI8hLkYLc$XhjjAWO zlj4kP$6szvJ(QPgPO2hXR}xC`8GM)VHjKRfT`lKBDW8*E@7mHX>3xqu2+^o95J%1t z?O@RNB@tf_A!38;rEXmO@_@bE<4&~Z%-iGUisNW!;(a}$NJIJJ@^@6O=(jp5GgUtb zS@e04UGV<4&^@xokksI7qFTp|1XIeIJ$AbVgRrvDIT?qRvo&w1MaGUC?bRd9Smh>J zOxpUr{H#~b0I$+For zLc__{G;nIVZyVrBdj(XA>3Nn+B)g;Wp+vYGV_lrElt#5+ z%@I|PQnu?E0s@k`Hx|l6zjac6@oX$>?^aF1)?ni1z?bxohkX_6O>_wp z{&br;3rqINx7W7t$rHl(#&3oWM-3u(EKk;Nq^ob>J=Td`yjt^38$${NqipnyuXmtlWpxptvpZI*3MeGwRvyn1bc?yDK$U)t((v(cE%&S zm>x8jo`Qw|1GE{StD=0_)Xo*IW@>{t#P@8jT1Kkm5)@)m`1tdy+DDSm(J4zF|ESEmGw25uB z+E?y=+oY}{(V%I>jJwg-G8Ji15vg)9Ug@-6|7ou`h_W*O9C4+;8S$w_$JZQ_KsShkw5R`0xmTr;m=3EcZp@upZ*^G}S*2)w*36fk32eR&$kT`S;`V)i>T3G;63eo4lU76D!}AI-zk2r zRl{0FYigwT0#VziiH8W{uKMRwG)d=^#%>Ac-&&hu=jS=*WJ=sp$|>Af;E(ep)HyT6 zv0g@BmZUmfU@0OyaYjjIov2o{#f5sqHqY%eJ6@5YcpGnKRs#LgIjty_BSrEYsyBA- zFyDL3+@=;)Q!nqJfw*bLh=FBz`gzqv&lfQQ#%CenXfu|SnXkNrEX!G+o69{nSH2;a z%5Y(>i-^4O;^#QV_OgU+edVj2bRX+yh&ZRWH=Hjy=lBNIyooWoy;bQ$)fy_>!YebF zxgJhNE`y~L`O!NW+nP8pkPS}wAYkrvP>{wpzoo~-=k&kYq;2@_!;EShI`!X#Zru0%0GR_ zac$)2rh46J8s(yP3z3F}g{9`cje7Q5B8E}crwrLGkGVe0agO>NVW=W89B8Jq3 z$-88Jl8)N;oQs^5?U8+yu}{@>9kH^o$3F}%y>9k)uJLv_RvmxLZ=KevlSbnqLt_j_ z&$dEEWidy2Hb>g1x?V=V+yMQIs2yQXzbm(MTKjkR(oX@lb@NwdI)qo8J;PT8?!BU* zfQ6e#NeXsI5}Ax?Z5HPEU6FecPbu^r9Gy6V&VYdj6o!T-s$DDo*B}4<4;$_HKYx*+ z?Mm$ZiF9S3W5}p@DfM?Ckcwx`vtB!@84geZu9ACZoYorRPs!s7p< zw@Tf!Os#-w7Em!ks2(!@pxO&x4Y(x&?qdCGd2~3{IX67u3n2z-V?F3^ZN`bHf_zp;D1L}WUWls*?9IDDsKwayg zEl|@j2>e;u1Mn_z0e;jJg!9IKrV9rR z?K+6~;}Gy()!%@hLk-=ns)8&WtU}Vk@S!>DtL|^mrQv^dr%~e&_o3?x0Gba0o&@C> zH~tOBKOJz?ILy^(A|8pMp@o7`L*1y_9Lizm=x%A_Vl9R6bV53!Mq)HTvcv}xRRZ|Y zLQGMT1SJ905Zu&3)yx((g5(;4$TAQNGC)&M0?8C8fhQ6!>1t_->YUry{9%Lym>V73 zoJa$aK=T=dK+4qI8ormAP!r&KKx~35s3ZKr4~qXf1B$<=9|<$NpWk2~F4DNUhsd%( zATI!Sf-2}%=CAnLPAFSIRx+FF@m^vD1kh;n&4Cg)x;mg-jll4P-6Z!80Dwy?p~FY! zL(vg%3mfF##EP2!^*eDQYst~ja8Dh~MEF$)2vB$b?~Fb7@_}~_fK<&4aUQ1b-+;^L z|5dsv+qfW66QXbS+U#TCq}M@(1}#0#zW)u+Uj6x}H9@6f>I^jyi2;a22N8+qBb3S& zfdG@w-tiyQgsFucd5i;u!2`lTr=G-72!phwl%vDGlcR?V2;&s>szMOVGk;x!`eRkL zSE_GLLE*uD2dKw$$>z<7VGs%=VDu~y{Tx|?!oywEMw)oQkq0aT<#sKIw(Vw2$jH7x>o zs9R~!{sON7cX4z@n8Q(y!t0mXgI7V2mw+&#fEfK1BZNg!S{t?T7Y`mQ9Rp#(vZo>l z@@G~E@}7G3;+uunR>s50)M4Ky?cqX0)x3Gl060}A&=z!M$$tvMq;KQ&_p%b?E2OE7 z1FAL197Ro35+I5IL>v&27C0e93Jw5U%FfiqWluN|^?%f6C<^=kjcA)I@4GG zU~}L}Ju&v*Z`ZF3 zKl@Mn#5hFvX@k9_eilqhZ-A8K6GCE&$-T^lG(3){cZ z?5}hVK_f^UfW6nUQ~O04D~^Ao+26-G1dR!XG&&8Ssr`kfhU?#G_zrKIy-X8Bbk6N8 zsBkyg4?4gFo?mGk!4&(~j@LetLp1FwjP9wKfS8O09Z6`>_EzE-66t+6tsSluVVPst zUIJ=b0J$ETk&(&}cm+`Acqo8nIO-WW){z#^4w%CmI2W{MSE6=+WB=D4hZA61bgj!5 z1c)ynfYws(nhcBgIRSIjF||Sd=f;@BMZ}TT zfc9&ELJLqpO%5-HP)NgFkO)W5zgbWdiZy1qeV4N^)q+ zJPkz4zU4c}d1i0~>MhO_Gzn>iz|h;j_|l`#5CX85@Uy{*nxdwrGtln=cm}l$N{2A9MZg!R#q}57;B#Q|W zIdp9a`}#X7&^6!xG0Wks-ov;OLhl;F`>n3-3U`GA%b*(GZ#o2-c>p*Q zD4d`sxqS4u1Sl5-a&I{E_DZvBKu=JU3=sUvVDbCwBMzr6DWm9u5g<$yD9NG1h)_VN zel$2y-WCf%c60Kwfhg2DID0#TYHeQ>YRc%UnIgb33e+N`K~mk6of!>nO#a|fZyn6J z`|;I)#Sxwo4i?%@7AP+)EG46Qvq2FO0jgMNQ`^HFN~5m)GuHngY4sA)D?Cy{L(@$- zIC=QmLwT%C!A_qF9BJ){>Y;<7sakWe3`VO0VFER}C)j(~uQIrUg$mefknz~RFh0a8 zZ|JdNK|OFQd@w~pr@$|zPzHNbJG(!t`DtYEUJwHbZULVEoMPMCzoK{x<#0rxxQ*CU zC_bhEav~m35;TV(z#4qNf&et!0`(-N>oI(D2N2kS@k28qbv=aOuY+rQTZfLWDAys* z_yOq+v}kCN=MPHZ&;TL%`;Zsv^WVE?cJJkZ1ZW^vLDdv8d62-y!RmmT{_9~+5MlqE zCe&P8OuGpVr#<34NWcLqll^u;f>VB02P8NI0rV-z{d=Ih-yj6PanVD-Lm!^m55I(m zxqtk7@O!KI{S)dT@Szvg@5g5#{{{cRmggbhp?4|nhaWfrg+Fk!BA9y)0S~=XZ9hCO z>u=$q6X_uspm#3qXK>;84a313m<}ff^vaL@Bzk9{Bp{5T7l0g&0DAw!eu7NiUkLWk zo`=v7^o!#C*sld4*uVe2_;3P1KMUPYq9c5e|V3~r3<^}%aKLch4Sy1t#{T~qLM)v>! literal 246626 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

o9bfYO(QVoP~Hq;cyoy3 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�nw?(7cuE)hM%h94^*(XU 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%0Dlqe0Ym{02KYWBo5*_ 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�Q?Nabx#4J3E* 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

r!YP*h=jNj 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 bSYPw;{z?yK1F#(g{}`CT?*Tb5LE!uktZ0>a diff --git a/webapps/WEB-INF/shaft/app.properties b/webapps/WEB-INF/shaft/app.properties old mode 100644 new mode 100755 diff --git a/webapps/WEB-INF/shaft/load_db.sql b/webapps/WEB-INF/shaft/load_db.sql old mode 100644 new mode 100755 diff --git a/webapps/WEB-INF/shaft/server.properties b/webapps/WEB-INF/shaft/server.properties old mode 100644 new mode 100755 diff --git a/webapps/WEB-INF/web.xml b/webapps/WEB-INF/web.xml old mode 100644 new mode 100755 index 7025186..6111728 --- a/webapps/WEB-INF/web.xml +++ b/webapps/WEB-INF/web.xml @@ -1,88 +1,88 @@ - - - - - - Welcome to Caimito - - Welcome to Caimito - - - shf - org.shaft.ShaftFilter - - - shf - /* - - - - - Jersey Web Application - com.sun.jersey.spi.container.servlet.ServletContainer - - com.sun.jersey.config.property.packages - org.shaft.server.rest - - -5 - - - Jersey Web Application - /shaftrest/* - - - - - webdav - ngasi.caimito.CaimitoWebdavServlet - - debug - 0 - - - listings - true - - - readonly - false - - - - webdav - /* - - - - 404 - /ca/404.html - - - 401 - /ca/401.html - - - 500 - /ca/500.html - - + + + + + + Welcome to Caimito + + Welcome to Caimito + + + shf + org.shaft.ShaftFilter + + + shf + /* + + + + + Jersey Web Application + com.sun.jersey.spi.container.servlet.ServletContainer + + com.sun.jersey.config.property.packages + org.shaft.server.rest + + -5 + + + Jersey Web Application + /shaftrest/* + + + + + webdav + ngasi.caimito.CaimitoWebdavServlet + + debug + 0 + + + listings + true + + + readonly + false + + + + webdav + /* + + + + 404 + /ca/404.html + + + 401 + /ca/401.html + + + 500 + /ca/500.html + + diff --git a/webapps/build.xml b/webapps/build.xml old mode 100644 new mode 100755 index bcb2c2d..871daa7 --- a/webapps/build.xml +++ b/webapps/build.xml @@ -1,93 +1,93 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/webapps/ca/public/.gitattributes b/webapps/ca/public/.gitattributes old mode 100644 new mode 100755 diff --git a/webapps/ca/public/.gitignore b/webapps/ca/public/.gitignore old mode 100644 new mode 100755 diff --git a/webapps/ca/public/.htaccess b/webapps/ca/public/.htaccess old mode 100644 new mode 100755 diff --git a/webapps/ca/public/401.html b/webapps/ca/public/401.html old mode 100644 new mode 100755 diff --git a/webapps/ca/public/404.html b/webapps/ca/public/404.html old mode 100644 new mode 100755 diff --git a/webapps/ca/public/500.html b/webapps/ca/public/500.html old mode 100644 new mode 100755 diff --git a/webapps/ca/public/apple-touch-icon-114x114-precomposed.png b/webapps/ca/public/apple-touch-icon-114x114-precomposed.png old mode 100644 new mode 100755 diff --git a/webapps/ca/public/apple-touch-icon-57x57-precomposed.png b/webapps/ca/public/apple-touch-icon-57x57-precomposed.png old mode 100644 new mode 100755 diff --git a/webapps/ca/public/apple-touch-icon-72x72-precomposed.png b/webapps/ca/public/apple-touch-icon-72x72-precomposed.png old mode 100644 new mode 100755 diff --git a/webapps/ca/public/apple-touch-icon-precomposed.png b/webapps/ca/public/apple-touch-icon-precomposed.png old mode 100644 new mode 100755 diff --git a/webapps/ca/public/apple-touch-icon.png b/webapps/ca/public/apple-touch-icon.png old mode 100644 new mode 100755 diff --git a/webapps/ca/public/crossdomain.xml b/webapps/ca/public/crossdomain.xml old mode 100644 new mode 100755 diff --git a/webapps/ca/public/css/style.css b/webapps/ca/public/css/style.css old mode 100644 new mode 100755 diff --git a/webapps/ca/public/favicon.ico b/webapps/ca/public/favicon.ico old mode 100644 new mode 100755 diff --git a/webapps/ca/public/humans.txt b/webapps/ca/public/humans.txt old mode 100644 new mode 100755 diff --git a/webapps/ca/public/img/.gitignore b/webapps/ca/public/img/.gitignore old mode 100644 new mode 100755 diff --git a/webapps/ca/public/index.html b/webapps/ca/public/index.html old mode 100644 new mode 100755 diff --git a/webapps/ca/public/js/libs/jquery-1.7.1.js b/webapps/ca/public/js/libs/jquery-1.7.1.js old mode 100644 new mode 100755 diff --git a/webapps/ca/public/js/libs/jquery-1.7.1.min.js b/webapps/ca/public/js/libs/jquery-1.7.1.min.js old mode 100644 new mode 100755 diff --git a/webapps/ca/public/js/libs/modernizr-2.5.3.min.js b/webapps/ca/public/js/libs/modernizr-2.5.3.min.js old mode 100644 new mode 100755 diff --git a/webapps/ca/public/js/plugins.js b/webapps/ca/public/js/plugins.js old mode 100644 new mode 100755 diff --git a/webapps/ca/public/js/script.js b/webapps/ca/public/js/script.js old mode 100644 new mode 100755 diff --git a/webapps/ca/public/logo.png b/webapps/ca/public/logo.png old mode 100644 new mode 100755 diff --git a/webapps/ca/public/readme.md b/webapps/ca/public/readme.md old mode 100644 new mode 100755 diff --git a/webapps/ca/public/robots.txt b/webapps/ca/public/robots.txt old mode 100644 new mode 100755 diff --git a/webapps/ca/public/symbol.png b/webapps/ca/public/symbol.png old mode 100644 new mode 100755 diff --git a/webapps/ca/server/pathprivileges.db b/webapps/ca/server/pathprivileges.db old mode 100644 new mode 100755 diff --git a/webapps/ca/server/publicpaths.db b/webapps/ca/server/publicpaths.db old mode 100644 new mode 100755 diff --git a/webapps/favicon.ico b/webapps/favicon.ico old mode 100644 new mode 100755 diff --git a/webapps/index.jsp b/webapps/index.jsp old mode 100644 new mode 100755 index 19412f5..c24e751 --- a/webapps/index.jsp +++ b/webapps/index.jsp @@ -1,222 +1,222 @@ -<%-- -Licensed to the Apache Software Foundation (ASF) under one or more -contributor license agreements. See the NOTICE file distributed with -this work for additional information regarding copyright ownership. -The ASF licenses this file to You under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with -the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. ---%> - -<%@ page session="false" %> -<% -java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy"); -request.setAttribute("year", sdf.format(new java.util.Date())); -request.setAttribute("tomcat7Url", "http://tomcat.apache.org/"); -request.setAttribute("tomcat7DocUrl", "/docs/"); -request.setAttribute("tomcat7ExamplesUrl", "/examples/"); -%> - - - <%=request.getServletContext().getServerInfo() %> - - - - - - -

- -
-

${pageContext.servletContext.serverInfo}

-
-
-
-

If you're seeing this, you've successfully installed Tomcat. Congratulations!

-
- -
- - - -
- -
-
-
-

Developer Quick Start

- - -
-
-

Examples

-
-
- -
-
-
-
-
-

Managing Tomcat

-

For security, access to the manager webapp is restricted. - Users are defined in:

-
$CATALINA_HOME/conf/tomcat-users.xml
-

In Tomcat 7.0 access to the manager application is split between - different users.   Read more...

-
-

Release Notes

-

Changelog

-

Migration Guide

-

Security Notices

-
-
-
-
-

Documentation

-

Tomcat 7.0 Documentation

-

Tomcat 7.0 Configuration

-

Tomcat Wiki

-

Find additional important configuration information in:

-
$CATALINA_HOME/RUNNING.txt
-

Developers may be interested in:

- -
-
-
-
-

Getting Help

-

FAQ and Mailing Lists

-

The following mailing lists are available:

- -
-
-
-
- - -
- - - +<%-- +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--%> + +<%@ page session="false" %> +<% +java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy"); +request.setAttribute("year", sdf.format(new java.util.Date())); +request.setAttribute("tomcat7Url", "http://tomcat.apache.org/"); +request.setAttribute("tomcat7DocUrl", "/docs/"); +request.setAttribute("tomcat7ExamplesUrl", "/examples/"); +%> + + + <%=request.getServletContext().getServerInfo() %> + + + + + + +
+ +
+

${pageContext.servletContext.serverInfo}

+
+
+
+

If you're seeing this, you've successfully installed Tomcat. Congratulations!

+
+ +
+ + + +
+ +
+
+
+

Developer Quick Start

+ + +
+
+

Examples

+
+
+ +
+
+
+
+
+

Managing Tomcat

+

For security, access to the manager webapp is restricted. + Users are defined in:

+
$CATALINA_HOME/conf/tomcat-users.xml
+

In Tomcat 7.0 access to the manager application is split between + different users.   Read more...

+
+

Release Notes

+

Changelog

+

Migration Guide

+

Security Notices

+
+
+
+
+

Documentation

+

Tomcat 7.0 Documentation

+

Tomcat 7.0 Configuration

+

Tomcat Wiki

+

Find additional important configuration information in:

+
$CATALINA_HOME/RUNNING.txt
+

Developers may be interested in:

+ +
+
+
+
+

Getting Help

+

FAQ and Mailing Lists

+

The following mailing lists are available:

+ +
+
+
+
+ + +
+ + + diff --git a/webapps/tomcat.css b/webapps/tomcat.css old mode 100644 new mode 100755 index c3d934b..73d8fba --- a/webapps/tomcat.css +++ b/webapps/tomcat.css @@ -1,351 +1,351 @@ -/* - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ -body { - margin: 10px 20px; - text-align: center; - font-family: Arial, sans-serif; -} - -h1, h2, h3, h4, h5, h6, p, ul, ol { - margin: 0 0 0.5em; -} -h1 { - font-size: 18pt; - margin: 0.5em 0 0; -} -h2 { - font-size: 16pt; -} -h3 { - font-size: 13pt; -} -h4 { - font-size: 12pt; -} -h5 { - font-size: 11pt; -} -p { - font-size: 11pt -} - -ul { - margin: 0; - padding: 0 0 0 0.25em; - text-indent: 0; - list-style: none; -} -li { - margin: 0; - padding: 0 0 0.25em; - text-indent: 0; - font-size: 80%; -} - -pre { - text-indent: 0.25em; - width: 90%; - font-size: 90%; -} - -br.separator { - margin: 0; - padding: 0; - clear: both; -} - -a img { - border: 0 none; -} - -.container { - padding: 10px; - margin: 0 0 10px; -} - -.col20 { - float: left; - width: 20%; -} - -.col25 { - float: left; - width: 25%; -} - -#wrapper { - display: block; - margin: 0 auto; - text-align: left; - min-width: 720px; - max-width: 1000px; -} -.curved { - border-radius: 10px; - -moz-border-radius: 10px; - -webkit-border-radius: 10px; - -khtml-border-radius: 10px; -} - -#navigation { - background: #eee url(bg-nav.png) repeat-x top left; - margin: 0 0 10px; - padding: 0; -} -#navigation span { - float: left; -} -#navigation span a { - display: block; - padding: 10px; - font-weight: bold; - text-shadow: 1px 1px 1px #fff; -} -#navigation span a:link, -#navigation span a:visited, -#navigation span a:hover, -#navigation span a:active { - color: #666; - text-decoration: none; -} -#navigation span#nav-help { - float: right; - margin-right: 0; -} - -#asf-box { - height: 40px; - background: #fff url(asf-logo.png) no-repeat top right;} -#asf-box h1 { - padding: 0; - margin: 0; -} - -#upper { - background: #fff url(bg-upper.png) repeat-x top left; -} - -#congrats { - text-align: center; - padding: 10px; - margin: 0 40px 20px; - background-color: #9c9; -} -#congrats h2 { - font-size: 14pt; - padding: 0; - margin: 0; - color: #fff; -} - -#notice { - float: left; - width: 560px; - color: #696; -} -#notice a:link, -#notice a:visited, -#notice a:hover, -#notice a:active { - color: #090; - text-decoration: none; -} -#notice img, -#notice #tasks { - float: left; -} -#tasks a:link, -#tasks a:visited, -#tasks a:hover, -#tasks a:active { - text-decoration: underline; -} -#notice img { - margin-right: 20px; -} - -#actions { - float: right; - width: 140px; -} - -#actions .button { - display: block; - padding: 0; - height: 36px; - background: url(bg-button.png) no-repeat top left; -} - -#actions .button a { - display: block; - padding: 0; -} - -#actions .button a:link, -#actions .button a:visited, -#actions .button a:hover, -#actions .button a:active { - color: #696; - text-decoration: none; -} - -#actions .button a span { - display: block; - padding: 6px 10px; - color: #666; - text-shadow: 1px 1px 1px #fff; - font-size: 10pt; - font-weight: bold; -} - -#middle { - background: #eef url(bg-middle.png) repeat-x top left; - margin: 20px 0; - padding: 1px 10px; -} -#middle h3 { - margin: 0 0 10px; - color: #033; -} -#middle p { - font-size: 10pt; -} -#middle a:link, -#middle a:visited, -#middle a:hover, -#middle a:active { - color: #366; - font-weight: bold; -} -#middle .col25 .container { - padding: 0 0 1px; -} - -#developers { - float: left; - width: 40%; -} -#security { - float: right; - width: 50%; -} - -#lower { - padding: 0; -} - -#lower a:link, -#lower a:visited, -#lower a:hover, -#lower a:active { - color: #600; -} - -#lower strong a:link, -#lower strong a:visited, -#lower strong a:hover, -#lower strong a:active { - color: #c00; -} - -#lower h3 { - color: #963; - font-size: 14pt; -} -#lower h4 { - font-size: 12pt; -} -#lower ul { - padding: 0; - margin: 0.5em 0; -} -#lower p, -#lower li { - font-size: 9pt; - color: #753; - margin: 0 0 0.1em; -} -#lower li { - padding: 3px 5px; -} -#lower li strong { - color: #a53; -} -#lower li#list-announce { - border: 1px solid #f90; - background-color: #ffe8c8; -} -#lower p { - font-size: 10.5pt; -} - -#low-manage, -#low-docs, -#low-help { - float: left; - width: 32%; -} -#low-docs { - margin: 0 0 0 2.2%; -} -#low-help { - float: right; -} - -#low-manage div, -#low-docs div, -#low-help div { - min-height: 280px; - border: 3px solid #ffdc75; - background-color: #fff1c8; - padding: 10px; -} - -#footer { - padding: 0; - margin: 20px 0; - color: #999; - background-color: #eee; -} -#footer h4 { - margin: 0 0 10px; - font-size: 10pt; -} -#footer p { - margin: 0 0 10px; - font-size: 10pt; -} -#footer ul { - margin: 6px 0 1px; - padding: 0; -} -#footer li { - margin: 0; - font-size: 9pt; -} - -#footer a:link, -#footer a:visited, -#footer a:hover, -#footer a:active { - color: #666; -} - -.copyright { - font-size: 10pt; - color: #666; +/* + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +body { + margin: 10px 20px; + text-align: center; + font-family: Arial, sans-serif; +} + +h1, h2, h3, h4, h5, h6, p, ul, ol { + margin: 0 0 0.5em; +} +h1 { + font-size: 18pt; + margin: 0.5em 0 0; +} +h2 { + font-size: 16pt; +} +h3 { + font-size: 13pt; +} +h4 { + font-size: 12pt; +} +h5 { + font-size: 11pt; +} +p { + font-size: 11pt +} + +ul { + margin: 0; + padding: 0 0 0 0.25em; + text-indent: 0; + list-style: none; +} +li { + margin: 0; + padding: 0 0 0.25em; + text-indent: 0; + font-size: 80%; +} + +pre { + text-indent: 0.25em; + width: 90%; + font-size: 90%; +} + +br.separator { + margin: 0; + padding: 0; + clear: both; +} + +a img { + border: 0 none; +} + +.container { + padding: 10px; + margin: 0 0 10px; +} + +.col20 { + float: left; + width: 20%; +} + +.col25 { + float: left; + width: 25%; +} + +#wrapper { + display: block; + margin: 0 auto; + text-align: left; + min-width: 720px; + max-width: 1000px; +} +.curved { + border-radius: 10px; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + -khtml-border-radius: 10px; +} + +#navigation { + background: #eee url(bg-nav.png) repeat-x top left; + margin: 0 0 10px; + padding: 0; +} +#navigation span { + float: left; +} +#navigation span a { + display: block; + padding: 10px; + font-weight: bold; + text-shadow: 1px 1px 1px #fff; +} +#navigation span a:link, +#navigation span a:visited, +#navigation span a:hover, +#navigation span a:active { + color: #666; + text-decoration: none; +} +#navigation span#nav-help { + float: right; + margin-right: 0; +} + +#asf-box { + height: 40px; + background: #fff url(asf-logo.png) no-repeat top right;} +#asf-box h1 { + padding: 0; + margin: 0; +} + +#upper { + background: #fff url(bg-upper.png) repeat-x top left; +} + +#congrats { + text-align: center; + padding: 10px; + margin: 0 40px 20px; + background-color: #9c9; +} +#congrats h2 { + font-size: 14pt; + padding: 0; + margin: 0; + color: #fff; +} + +#notice { + float: left; + width: 560px; + color: #696; +} +#notice a:link, +#notice a:visited, +#notice a:hover, +#notice a:active { + color: #090; + text-decoration: none; +} +#notice img, +#notice #tasks { + float: left; +} +#tasks a:link, +#tasks a:visited, +#tasks a:hover, +#tasks a:active { + text-decoration: underline; +} +#notice img { + margin-right: 20px; +} + +#actions { + float: right; + width: 140px; +} + +#actions .button { + display: block; + padding: 0; + height: 36px; + background: url(bg-button.png) no-repeat top left; +} + +#actions .button a { + display: block; + padding: 0; +} + +#actions .button a:link, +#actions .button a:visited, +#actions .button a:hover, +#actions .button a:active { + color: #696; + text-decoration: none; +} + +#actions .button a span { + display: block; + padding: 6px 10px; + color: #666; + text-shadow: 1px 1px 1px #fff; + font-size: 10pt; + font-weight: bold; +} + +#middle { + background: #eef url(bg-middle.png) repeat-x top left; + margin: 20px 0; + padding: 1px 10px; +} +#middle h3 { + margin: 0 0 10px; + color: #033; +} +#middle p { + font-size: 10pt; +} +#middle a:link, +#middle a:visited, +#middle a:hover, +#middle a:active { + color: #366; + font-weight: bold; +} +#middle .col25 .container { + padding: 0 0 1px; +} + +#developers { + float: left; + width: 40%; +} +#security { + float: right; + width: 50%; +} + +#lower { + padding: 0; +} + +#lower a:link, +#lower a:visited, +#lower a:hover, +#lower a:active { + color: #600; +} + +#lower strong a:link, +#lower strong a:visited, +#lower strong a:hover, +#lower strong a:active { + color: #c00; +} + +#lower h3 { + color: #963; + font-size: 14pt; +} +#lower h4 { + font-size: 12pt; +} +#lower ul { + padding: 0; + margin: 0.5em 0; +} +#lower p, +#lower li { + font-size: 9pt; + color: #753; + margin: 0 0 0.1em; +} +#lower li { + padding: 3px 5px; +} +#lower li strong { + color: #a53; +} +#lower li#list-announce { + border: 1px solid #f90; + background-color: #ffe8c8; +} +#lower p { + font-size: 10.5pt; +} + +#low-manage, +#low-docs, +#low-help { + float: left; + width: 32%; +} +#low-docs { + margin: 0 0 0 2.2%; +} +#low-help { + float: right; +} + +#low-manage div, +#low-docs div, +#low-help div { + min-height: 280px; + border: 3px solid #ffdc75; + background-color: #fff1c8; + padding: 10px; +} + +#footer { + padding: 0; + margin: 20px 0; + color: #999; + background-color: #eee; +} +#footer h4 { + margin: 0 0 10px; + font-size: 10pt; +} +#footer p { + margin: 0 0 10px; + font-size: 10pt; +} +#footer ul { + margin: 6px 0 1px; + padding: 0; +} +#footer li { + margin: 0; + font-size: 9pt; +} + +#footer a:link, +#footer a:visited, +#footer a:hover, +#footer a:active { + color: #666; +} + +.copyright { + font-size: 10pt; + color: #666; } \ No newline at end of file